module Lang.LamIf.Monads where
import FP
import MAAM
import Lang.LamIf.Stamp
import Lang.LamIf.Semantics
import Lang.LamIf.Values
import Lang.LamIf.Domains
newtype InjectLamIf val a = InjectLamIf { runInjectLamIf ∷ (a,LamIfState val) }
isoInjectLamIf ∷ InjectLamIf val a ⇄ (a,LamIfState val)
isoInjectLamIf = Iso runInjectLamIf InjectLamIf
newtype PathSensitiveΣᵇ val a = PathSensitiveΣᵇ { runPathSensitiveΣᵇ ∷ PolyStateΠ (LamIfState val) (NondetJoinΠ ID) a }
isoPathSensitiveΣᵇ ∷ PathSensitiveΣᵇ val a ⇄ PolyStateΠ (LamIfState val) (NondetJoinΠ ID) a
isoPathSensitiveΣᵇ = Iso runPathSensitiveΣᵇ PathSensitiveΣᵇ
isoPathSensitiveΣᵇ2 ∷ PathSensitiveΣᵇ val ↝⇄ PolyStateΠ (LamIfState val) (NondetJoinΠ ID)
isoPathSensitiveΣᵇ2 = iso2FromIso isoPathSensitiveΣᵇ
instance Inject (InjectLamIf val) (PathSensitiveΣᵇ val) where
inject = isoInject (iso2FromIso $ sym $ sym isoInjectLamIf ⌾ isoID ⌾ isoStateI) isoPathSensitiveΣᵇ2
newtype PathSensitiveΣ val a = PathSensitiveΣ { runPathSensitiveΣ ∷ 𝒫 (a,LamIfState val) }
deriving (POrd,Bot,Join,JoinLattice,Difference,Pretty)
isoPathSensitiveΣ ∷ (Ord val,Ord a) ⇒ PathSensitiveΣ val a ⇄ PathSensitiveΣᵇ val a
isoPathSensitiveΣ = Iso
(PathSensitiveΣᵇ ∘ PolyStateΠ ∘ NondetJoinΠ ∘ ID ∘ lazySet ∘ runPathSensitiveΣ)
(PathSensitiveΣ ∘ set ∘ runID ∘ runNondetJoinΠ ∘ runPolyStateΠ ∘ runPathSensitiveΣᵇ)
newtype PathSensitiveM val a = PathSensitiveM { runPathSensitiveM ∷ PolyStateT (LamIfState val) (NondetJoinT ID) a }
deriving
(Functor,Monad,MonadBot,MonadJoin,MonadJoinLattice,MonadState (LamIfState val))
isoPathSensitiveM ∷ PathSensitiveM val a ⇄ PolyStateT (LamIfState val) (NondetJoinT ID) a
isoPathSensitiveM = Iso runPathSensitiveM PathSensitiveM
isoPathSensitiveM2 ∷ PathSensitiveM val ↝⇄ PolyStateT (LamIfState val) (NondetJoinT ID)
isoPathSensitiveM2 = iso2FromIso isoPathSensitiveM
instance GaloisTransformer (PathSensitiveΣᵇ val) (PathSensitiveM val) where
αGT = isoαGT isoPathSensitiveΣᵇ2 isoPathSensitiveM2
γGT = isoγGT isoPathSensitiveΣᵇ2 isoPathSensitiveM2
instance (POrd val,JoinLattice val,Val val) ⇒
MonadLamIf val (PathSensitiveM val)
instance (Ord val,POrd val,JoinLattice val,Val val) ⇒
ExecutionLamIf val
(InjectLamIf val)
(PathSensitiveΣᵇ val)
(PathSensitiveM val)
data LamIfContext val = LamIfContext
{ ctxEnv ∷ Env
, ctxΚAddr ∷ Maybe ExpAddr
, ctxTime ∷ Time
} deriving (Eq,Ord)
makePrettyRecord ''LamIfContext
data LamIfStores val = LamIfStores
{ storesStore ∷ Store val
, storesΚStore ∷ KStore val
} deriving (Eq,Ord)
makePrettyRecord ''LamIfStores
instance (POrd val) ⇒ POrd (LamIfStores val) where
(⊑⊒) = poCompareFromLte $ \ (LamIfStores σ₁ κσ₁) (LamIfStores σ₂ κσ₂) → meets [σ₁ ⊑ σ₂,κσ₁ ⊑ κσ₂]
instance Bot (LamIfStores val) where
bot = LamIfStores bot bot
instance (Join val) ⇒ Join (LamIfStores val) where
LamIfStores σ₁ κσ₁ ⊔ LamIfStores σ₂ κσ₂ = LamIfStores (σ₁ ⊔ σ₂) (κσ₁ ⊔ κσ₂)
instance (Join val) ⇒ JoinLattice (LamIfStores val)
instance (Difference val) ⇒ Difference (LamIfStores val) where
LamIfStores σ₁ κσ₁ ⊟ LamIfStores σ₂ κσ₂ = LamIfStores (σ₁ ⊟ σ₂) (κσ₁ ⊟ κσ₂)
splitLamIfState ∷ LamIfState val → (LamIfContext val,LamIfStores val)
splitLamIfState (LamIfState ρ κl τ σ κσ) = (LamIfContext ρ κl τ,LamIfStores σ κσ)
combineLamIfState ∷ (LamIfContext val,LamIfStores val) → LamIfState val
combineLamIfState (LamIfContext ρ κl τ,LamIfStores σ κσ) = LamIfState ρ κl τ σ κσ
isoSplitLamIfState ∷ LamIfState val ⇄ (LamIfContext val,LamIfStores val)
isoSplitLamIfState = Iso splitLamIfState combineLamIfState
isoCombineLamIfState ∷ (a,LamIfState val) ⇄ ((a,LamIfContext val),LamIfStores val)
isoCombineLamIfState = Iso
(\ (x,splitLamIfState → (ctx,stores)) → ((x,ctx),stores))
(\ ((x,ctx),stores) → (x,combineLamIfState (ctx,stores)))
newtype FlowSensitiveΣᵇ val a = FlowSensitiveΣᵇ
{ runFlowSensitiveΣᵇ ∷
PolyStateΠ (LamIfContext val)
(FlowJoinΠ (LamIfStores val)
ID) a
}
isoFlowSensitiveΣᵇ ∷ FlowSensitiveΣᵇ val a ⇄ PolyStateΠ (LamIfContext val) (FlowJoinΠ (LamIfStores val) ID) a
isoFlowSensitiveΣᵇ = Iso runFlowSensitiveΣᵇ FlowSensitiveΣᵇ
isoFlowSensitiveΣ2ᵇ ∷ FlowSensitiveΣᵇ val ↝⇄ PolyStateΠ (LamIfContext val) (FlowJoinΠ (LamIfStores val) ID)
isoFlowSensitiveΣ2ᵇ = iso2FromIso isoFlowSensitiveΣᵇ
instance Inject (InjectLamIf val) (FlowSensitiveΣᵇ val) where
inject = isoInject
(iso2FromIso $ sym (sym isoCombineLamIfState ⌾ isoID ⌾ isoStateI ⌾ isoStateI) ⌾ isoInjectLamIf)
isoFlowSensitiveΣ2ᵇ
newtype FlowSensitiveΣ val a = FlowSensitiveΣ { runFlowSensitiveΣ ∷ (a,LamIfContext val) ⇰ LamIfStores val }
deriving (POrd,Bot,Join,JoinLattice,Difference,Pretty)
isoFlowSensitiveΣ ∷ (Ord a,Join val) ⇒ FlowSensitiveΣ val a ⇄ FlowSensitiveΣᵇ val a
isoFlowSensitiveΣ = Iso
(FlowSensitiveΣᵇ ∘ PolyStateΠ ∘ FlowJoinΠ ∘ ID ∘ lazyDictJoin ∘ runFlowSensitiveΣ)
(FlowSensitiveΣ ∘ dictJoin ∘ runID ∘ runFlowJoinΠ ∘ runPolyStateΠ ∘ runFlowSensitiveΣᵇ)
newtype FlowSensitiveM val a = FlowSensitiveM
{ runFlowSensitiveM ∷
PolyStateT (LamIfContext val)
(FlowJoinT (LamIfStores val)
ID) a
}
deriving (Functor,Monad,MonadBot,MonadJoin,MonadJoinLattice)
isoFlowSensitiveM ∷ FlowSensitiveM val a ⇄ PolyStateT (LamIfContext val) (FlowJoinT (LamIfStores val) ID) a
isoFlowSensitiveM = Iso runFlowSensitiveM FlowSensitiveM
isoFlowSensitiveM2 ∷ FlowSensitiveM val ↝⇄ PolyStateT (LamIfContext val) (FlowJoinT (LamIfStores val) ID)
isoFlowSensitiveM2 = iso2FromIso isoFlowSensitiveM
instance (Join val) ⇒ MonadState (LamIfState val) (FlowSensitiveM val) where
stateE ∷ StateT (LamIfState val) (FlowSensitiveM val) ↝ FlowSensitiveM val
stateE =
FlowSensitiveM
∘ PolyStateT
∘ fmap stateE
∘ stateE
∘ fmap stateCommute
∘ splitState
∘ mapState isoSplitLamIfState
∘ fmap (runPolyStateT ∘ runFlowSensitiveM)
stateI ∷ FlowSensitiveM val ↝ StateT (LamIfState val) (FlowSensitiveM val)
stateI =
fmap (FlowSensitiveM ∘ PolyStateT)
∘ mapState (sym isoSplitLamIfState)
∘ mergeState
∘ fmap stateCommute
∘ stateI
∘ fmap stateI
∘ runPolyStateT
∘ runFlowSensitiveM
instance (Join val) ⇒ GaloisTransformer (FlowSensitiveΣᵇ val) (FlowSensitiveM val) where
αGT = isoαGT isoFlowSensitiveΣ2ᵇ isoFlowSensitiveM2
γGT = isoγGT isoFlowSensitiveΣ2ᵇ isoFlowSensitiveM2
instance (POrd val,JoinLattice val,Val val) ⇒
MonadLamIf val (FlowSensitiveM val)
instance (Ord val,POrd val,JoinLattice val,Difference val,Val val,Pretty val) ⇒
ExecutionLamIf val
(InjectLamIf val)
(FlowSensitiveΣᵇ val)
(FlowSensitiveM val)
newtype FlowInsensitiveΣᵇ val a = FlowInsensitiveΣᵇ
{ runFlowInsensitiveΣᵇ ∷
PolyStateΠ (LamIfContext val)
(NondetJoinΠ
(StateΠ (LamIfStores val)
ID)) a
}
isoFlowInsensitiveΣᵇ
∷ FlowInsensitiveΣᵇ val a
⇄ PolyStateΠ (LamIfContext val) (NondetJoinΠ (StateΠ (LamIfStores val) ID)) a
isoFlowInsensitiveΣᵇ = Iso runFlowInsensitiveΣᵇ FlowInsensitiveΣᵇ
isoFlowInsensitiveΣᵇ2
∷ FlowInsensitiveΣᵇ val
↝⇄ PolyStateΠ (LamIfContext val) (NondetJoinΠ (StateΠ (LamIfStores val) ID))
isoFlowInsensitiveΣᵇ2 = iso2FromIso isoFlowInsensitiveΣᵇ
instance Inject (InjectLamIf val) (FlowInsensitiveΣᵇ val) where
inject = isoInject
(iso2FromIso $ sym (sym isoCombineLamIfState ⌾ isoID ⌾ isoStateI ⌾ isoStateI) ⌾ isoInjectLamIf)
isoFlowInsensitiveΣᵇ2
newtype FlowInsensitiveΣ val a = FlowInsensitiveΣ { runFlowInsensitiveΣ ∷ (𝒫(a,LamIfContext val),LamIfStores val) }
deriving (POrd,Bot,Join,JoinLattice,Difference,Pretty)
isoFlowInsensitiveΣ ∷ (Ord a) ⇒ FlowInsensitiveΣ val a ⇄ FlowInsensitiveΣᵇ val a
isoFlowInsensitiveΣ = Iso
(FlowInsensitiveΣᵇ ∘ PolyStateΠ ∘ NondetJoinΠ ∘ StateΠ ∘ ID ∘ mapFst lazySet ∘ runFlowInsensitiveΣ)
(FlowInsensitiveΣ ∘ mapFst set ∘ runID ∘ runStateΠ ∘ runNondetJoinΠ ∘ runPolyStateΠ ∘ runFlowInsensitiveΣᵇ)
newtype FlowInsensitiveM val a = FlowInsensitiveM
{ runFlowInsensitiveM ∷
PolyStateT (LamIfContext val)
(NondetJoinT
(StateT (LamIfStores val)
ID)) a
}
deriving (Functor,Monad,MonadBot,MonadJoin,MonadJoinLattice)
isoFlowInsensitiveM
∷ FlowInsensitiveM val a
⇄ PolyStateT (LamIfContext val) (NondetJoinT (StateT (LamIfStores val) ID)) a
isoFlowInsensitiveM = Iso runFlowInsensitiveM FlowInsensitiveM
isoFlowInsensitiveM2
∷ FlowInsensitiveM val
↝⇄ PolyStateT (LamIfContext val) (NondetJoinT (StateT (LamIfStores val) ID))
isoFlowInsensitiveM2 = iso2FromIso isoFlowInsensitiveM
instance (Join val) ⇒ MonadState (LamIfState val) (FlowInsensitiveM val) where
stateE ∷ StateT (LamIfState val) (FlowInsensitiveM val) ↝ FlowInsensitiveM val
stateE =
FlowInsensitiveM
∘ PolyStateT
∘ fmap stateE
∘ stateE
∘ fmap stateCommute
∘ splitState
∘ mapState isoSplitLamIfState
∘ fmap (runPolyStateT ∘ runFlowInsensitiveM)
stateI ∷ FlowInsensitiveM val ↝ StateT (LamIfState val) (FlowInsensitiveM val)
stateI =
fmap (FlowInsensitiveM ∘ PolyStateT)
∘ mapState (sym isoSplitLamIfState)
∘ mergeState
∘ fmap stateCommute
∘ stateI
∘ fmap stateI
∘ runPolyStateT
∘ runFlowInsensitiveM
instance (Join val) ⇒ GaloisTransformer (FlowInsensitiveΣᵇ val) (FlowInsensitiveM val) where
αGT = isoαGT isoFlowInsensitiveΣᵇ2 isoFlowInsensitiveM2
γGT = isoγGT isoFlowInsensitiveΣᵇ2 isoFlowInsensitiveM2
instance (POrd val,JoinLattice val,Val val) ⇒
MonadLamIf val (FlowInsensitiveM val)
instance (Ord val,POrd val,JoinLattice val,Difference val,Val val,Pretty val) ⇒
ExecutionLamIf val
(InjectLamIf val)
(FlowInsensitiveΣᵇ val)
(FlowInsensitiveM val)
data MonadParam where
MonadParam ∷
∀ val ς' ς m.
P m
→ ς Exp ⇄ ς' Exp
→ (ς Exp → Doc)
→ W (ExecutionLamIf val (InjectLamIf val) ς' m,LFPLamIf ς)
→ MonadParam
pathSensitive ∷ DomainParam → MonadParam
pathSensitive (DomainParam (P ∷ P val) W) =
MonadParam (P ∷ P (PathSensitiveM val)) isoPathSensitiveΣ (pretty ∘ mapKeyJoin varAddrName ∘ joins ∘ mapSet (store ∘ snd) ∘ runPathSensitiveΣ) W
flowSensitive ∷ DomainParam → MonadParam
flowSensitive (DomainParam (P ∷ P val) W) =
MonadParam (P ∷ P (FlowSensitiveM val)) isoFlowSensitiveΣ (pretty ∘ mapKeyJoin varAddrName ∘ storesStore ∘ joins ∘ values ∘ runFlowSensitiveΣ) W
flowInsensitive ∷ DomainParam → MonadParam
flowInsensitive (DomainParam (P ∷ P val) W) =
MonadParam (P ∷ P (FlowInsensitiveM val)) isoFlowInsensitiveΣ (pretty ∘ mapKeyJoin varAddrName ∘ storesStore ∘ snd ∘ runFlowInsensitiveΣ) W