cpsa-4.4.6: src/CPSA/Db/Structs.hs
module CPSA.Db.Structs (Prot (..), Role (..), Skel (..),
matchTraces, mtwa) where
import Control.Monad
import qualified Data.List as L
import CPSA.Algebra
import CPSA.Signature (Sig)
import CPSA.Channel (cmMatch)
import CPSA.Protocol (Trace, Event (..))
import CPSA.Lib.SExpr
{--
import System.IO.Unsafe
z :: Show a => a -> b -> b
z x y = unsafePerformIO (print x >> return y)
zz :: Show a => a -> a
zz x = z x x
--}
data Role = Role
{ rname :: String, -- Role name
rvars :: ![Term], -- Set of role variables
rctx :: Context,
rtrace :: !Trace } -- Events in causal order
deriving Show
data Prot = Prot
{ pname :: String, -- Protocol name
pgen :: Gen, -- Generator for preskeletons
roles :: [Role], -- Protocol roles including listener role
psig :: Sig } -- the protocol's signature
deriving Show
data Skel = Skel
{ prot :: Prot,
kvars :: [Term], -- Skeleton vars
kctx :: Context,
kgen :: Gen,
ktraces :: [Trace], --Strands
label :: Int, -- Label from the input or generated
-- by the loader
parent :: Maybe Int, -- Parent from the input
-- Seen preskeletons isomorphic to cohort members
-- with their operation field
seen :: [(Int, [SExpr Pos], [Int])],
alist :: [SExpr Pos] }
deriving Show
homomorphism :: Skel -> Skel -> [Int] -> [Env]
homomorphism k k' mapping =
if L.length mapping == L.length (ktraces k)
then
let gg = gmerge (kgen k) (kgen k') in
let strandids = take (L.length (ktraces k)) [0..] in
let ge = foldM (matchStrand k k' mapping) (gg, emptyEnv) strandids in
map snd ge
else []
matchStrand :: Skel -> Skel -> [Int] -> (Gen, Env) -> Int -> [(Gen, Env)]
matchStrand k k' mapping env s =
matchTraces (ktraces k !! s) (ktraces k' !! s') env
where
s' = mapping !! s
matchTraces :: Trace -> Trace -> (Gen, Env) -> [(Gen, Env)]
matchTraces _ [] env = [env] -- Target can be shorter
matchTraces (In t : c) (In t' : c') env =
do
e <- cmMatch t t' env
matchTraces c c' e
matchTraces (Out t : c) (Out t' : c') env =
do
e <- cmMatch t t' env
matchTraces c c' e
matchTraces _ _ _ = []
mtwa :: Skel -> Skel -> [Int] -> Maybe [(SExpr (), SExpr ())]
mtwa k k' mapping =
case homomorphism k k' mapping of
[] -> Nothing
env : _ ->
Just (map (displayMaplet (kctx k) rangeCtx) maplets)
where
maplets = reify (kvars k) env
rangeCtx = addToContext (kctx k') (map snd maplets)
displayMaplet :: Context -> Context -> (Term, Term) ->
(SExpr (), SExpr ())
displayMaplet domain range (x, t) =
(displayTerm domain x, displayTerm range t)