smcdel-1.0.0: src/SMCDEL/Explicit/K/Change.hs
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
module SMCDEL.Explicit.K.Change where
import Control.Arrow ((&&&))
import Control.Monad
import Data.List (delete,intercalate)
import qualified Data.Map.Strict as M
import Data.Map.Strict ((!),fromList)
import Test.QuickCheck
import SMCDEL.Explicit.K
import SMCDEL.Explicit.S5 (World)
import SMCDEL.Internal.TexDisplay
import SMCDEL.Language
type PostCondition = M.Map Prp Form
type Action = Int
data Change = Ch {pre :: Form, post :: PostCondition, rel :: M.Map Agent [Action]}
deriving (Eq,Ord,Show)
-- | Extend `post` to all propositions
safepost :: Change -> Prp -> Form
safepost ch p | p `elem` M.keys (post ch) = post ch ! p
| otherwise = PrpF p
newtype ChangeModel = ChM (M.Map Action Change)
deriving (Eq,Ord,Show)
type PointedChangeModel = (ChangeModel, Action)
type MultipointedChangeModel = (ChangeModel, [Action])
instance HasAgents ChangeModel where
agentsOf (ChM cm) = M.keys $ rel (head (M.elems cm))
instance HasAgents PointedChangeModel where
agentsOf = agentsOf . fst
instance HasPrecondition PointedChangeModel where
preOf (ChM cm, actual) = pre (cm ! actual)
productChangeWithMap :: KripkeModel -> ChangeModel -> (KripkeModel, M.Map (World, Action) World)
productChangeWithMap (KrM m) (ChM cm)
| agentsOf (KrM m) /= agentsOf (ChM cm) = error "productChange failed: agentsOf differs!"
| otherwise = (KrM $ fromList (map annotate statePairs), fromList statePairs) where
statePairs = zip (concat [ [ (s, a) | eval (KrM m, s) (pre $ cm ! a) ] | s <- M.keys m, a <- M.keys cm ]) [0..]
annotate ((s,a),news) = (news , (newval, fromList (map reachFor (agentsOf (KrM m))))) where
newval = M.mapWithKey applyPC (fst $ m ! s)
applyPC p oldbit
| p `elem` M.keys (post (cm ! a)) = eval (KrM m,s) (post (cm ! a) ! p)
| otherwise = oldbit
reachFor i = (i, [ news' | ((s',a'),news') <- statePairs, s' `elem` snd (m ! s) ! i, a' `elem` rel (cm ! a) ! i ])
productChange :: PointedModel -> PointedChangeModel -> PointedModel
productChange (m, cur) (ChM cm, act)
| not $ eval (m, cur) (pre $ cm ! act) = error "productChange failed: false actual precondition!"
| otherwise = (newm, newcur) where
(newm, stateMap) = productChangeWithMap m (ChM cm)
newcur = stateMap ! (cur,act)
productChangePointless :: KripkeModel -> ChangeModel -> KripkeModel
productChangePointless (KrM m) (ChM cm) = fst $ productChangeWithMap (KrM m) (ChM cm)
productChangeMulti :: PointedModel -> MultipointedChangeModel -> PointedModel
productChangeMulti pm (ChM cm, as) = productChange pm (ChM cm, a) where
[a] = filter (\x -> eval pm (pre $ cm ! x)) as
publicMakeFalseChM :: [Agent] -> Prp -> PointedChangeModel
publicMakeFalseChM ags p = (ChM $ fromList [ (1::Action, Ch myPre myPost myRel) ], 0) where
myPre = Top
myPost = fromList [(p,Bot)]
myRel = fromList [(i,[1]) | i <- ags]
instance Arbitrary ChangeModel where
arbitrary = do
let allactions = [0..3]
[BF f, BF g, BF h, BF l] <- replicateM 4 (sized $ randomboolformWith [P 0 .. P 4])
let myPres = map simplify [f,g,h,l]
myPosts <- mapM (\_ -> do
proptochange <- elements [P 0 .. P 4]
postconcon <- elements $ [Top,Bot] ++ map PrpF [P 0 .. P 4]
return $ fromList [ (proptochange, postconcon) ]
) allactions
myRels <- mapM (\k -> do
reachList <- sublistOf allactions
return $ fromList $ ("0",[k]) : [(show i,reachList) | i <- [1..5::Int]]
) allactions
return $ ChM $ fromList
[ (k::Action, Ch (myPres !! k) (myPosts !! k) (myRels !! k)) | k <- allactions ]
shrink (ChM cm) = [ ChM $ removeFromRels k $ M.delete k cm | k <- M.keys cm, k /= 0 ] where
removeFromRels = M.map . removeFrom where
removeFrom k c = c { rel = M.map (delete k) (rel c) }
instance KripkeLike ChangeModel where
directed = const True
getNodes (ChM cm) = map (show &&& labelOf) (M.keys cm) where
labelOf a = concat
[ "$\\begin{array}{c} ? " , tex (pre (cm ! a)) , "\\\\"
, intercalate "\\\\" (map showPost (M.toList $ post (cm ! a)))
, "\\end{array}$" ]
showPost (p,f) = tex p ++ " := " ++ tex f
getEdges (ChM cm) =
concat [ [ (i, show a, show b) | b <- rel (cm ! a) ! i ] | a <- M.keys cm, i <- agentsOf (ChM cm) ]
getActuals = const [ ]
instance TexAble ChangeModel where
tex = tex.ViaDot
texTo = texTo.ViaDot
texDocumentTo = texDocumentTo.ViaDot
instance KripkeLike PointedChangeModel where
directed = directed . fst
getNodes = getNodes . fst
getEdges = getEdges . fst
getActuals (_, a) = [show a]
instance TexAble PointedChangeModel where
tex = tex.ViaDot
texTo = texTo.ViaDot
texDocumentTo = texDocumentTo.ViaDot
instance KripkeLike MultipointedChangeModel where
directed = directed . fst
getNodes = getNodes . fst
getEdges = getEdges . fst
getActuals (_, as) = map show as
instance TexAble MultipointedChangeModel where
tex = tex.ViaDot
texTo = texTo.ViaDot
texDocumentTo = texDocumentTo.ViaDot