smcdel-1.1.0: src/SMCDEL/Examples/Prisoners.hs
module SMCDEL.Examples.Prisoners where
import Data.HasCacBDD hiding (Top,Bot)
import SMCDEL.Explicit.S5
import SMCDEL.Internal.TexDisplay
import SMCDEL.Language
import SMCDEL.Symbolic.S5
n :: Int
n = 3
light :: Form
light = PrpF (P 0)
-- P 0 -- light is on
-- P i -- agent i has been in the room (and switched on the light)
-- agents: 1 is the counter, 2 and 3 are the others
prisonExpStart :: KripkeModelS5
prisonExpStart =
KrMS5
[1]
[ ("1",[[1]]) ]
[ (1, [(P k,False) | k <- [0..n] ] ) ]
prisonGoal :: Form
prisonGoal = K "1" $ Conj [ PrpF $ P k | k <- [1..n] ]
prisonAction :: ActionModelS5
prisonAction = ActMS5 actions actRels where
p = PrpF . P
actions =
[ (0, (p 0 , [(P 0, Bot), (P 1, Top)]) ) -- interview 1 with light on
, (1, (Neg (p 0), [ (P 1, Top)]) ) -- interview 1 with light off
]
++
[ (k, (Top, [(P 0, p k `Impl` p 0), (P k, p 0 `Impl` p k)]) ) | k <- [2..n] ] -- interview k
actRels = [ ("1", [[0],[1],[2..n]]) ]
prisonInterview :: Int -> MultipointedActionModelS5
prisonInterview 1 = (prisonAction, [0,1])
prisonInterview k = (prisonAction, [k])
data Story a b = Story a [b]
endOf :: (Update a b, Optimizable a) => Story a b -> a
endOf (Story start actions) =
foldl (\cur a -> optimize (vocabOf start) $ cur `update` a) start actions
instance (Update a b, Optimizable a, TexAble a, TexAble b) => TexAble (Story a b) where
tex (Story start actions) = adjust (tex start) ++ loop start actions where
adjust thing = " \\raisebox{-.5\\height}{ \\begin{adjustbox}{max height=4cm, max width=0.3\\linewidth} $ " ++ thing ++ " $ \\end{adjustbox} } "
loop _ [] = ""
loop current (a:as) =
let
new = optimize (vocabOf start) $ current `update` a
in
" \\times " ++ adjust (tex a) ++ " = " ++ adjust (tex new) ++ "\\] \\[ " ++ loop new as
prisonExpStory :: Story PointedModelS5 MultipointedActionModelS5
prisonExpStory = Story (prisonExpStart,1) (map prisonInterview [2,1,3,1])
prisonSymStart :: MultipointedKnowScene
prisonSymStart = (KnS (map P [0..n]) law obs, actualStatesBdd) where
law = boolBddOf (Conj (Neg light : [ Neg $ wasInterviewed k | k <- [1..n] ]))
obs = [ ("1", []) ]
actualStatesBdd = top
wasInterviewed, isNowInterviewed :: Int -> Form
wasInterviewed = PrpF . P
isNowInterviewed k = PrpF (P (k + n))
lightSeenByOne :: Form
lightSeenByOne = PrpF (P (1 + (2*n)))
prisonSymEvent :: KnowTransformer
prisonSymEvent = KnTrf -- agent 1 is interviewed
(map P $ [ k+n | k <- [1..n] ] ++ [1+(2*n)] ) -- distinguish events
(Conj [ isNowInterviewed 1 `Impl` (lightSeenByOne `Equi` light)
, Disj [ Conj $ isNowInterviewed k : [Neg $ isNowInterviewed l | l <- [1..n], l /= k ] | k <- [1..n]]
] )
-- light might be switched and visits of the agents might be recorded
( [ (P 0, boolBddOf $
Conj $ isNowInterviewed 1 `Impl` Bot -- 1 turns off the light
: concat [ [ Conj [Neg $ wasInterviewed k, isNowInterviewed k] `Impl` Top
, Conj [ wasInterviewed k, isNowInterviewed k] `Impl` light ]
| k <- [2..n] ])
, (P 1, boolBddOf $ Disj [wasInterviewed 1, Conj [ isNowInterviewed 1]])
]
++
[ (P k, boolBddOf $ Disj [wasInterviewed k, Conj [Neg light, isNowInterviewed k]])
| k <- [2..n] ] )
-- agent 1 observes whether they are interviewed, and if so, also observes the light
[ ("1", let (PrpF px, PrpF py) = (isNowInterviewed 1, lightSeenByOne) in [px, py]) ]
prisonSymInterview :: Int -> MultipointedEvent
prisonSymInterview k = (prisonSymEvent, boolBddOf (isNowInterviewed k))
prisonSymStory :: Story MultipointedKnowScene MultipointedEvent
prisonSymStory = Story prisonSymStart (map prisonSymInterview [2,1,3,1])