smcdel-1.2.0: src/SMCDEL/Symbolic/S5.hs
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, ScopedTypeVariables #-}
module SMCDEL.Symbolic.S5 where
import Control.Arrow (first,second,(***))
import Data.Char (isSpace)
import Data.Dynamic
import Data.HasCacBDD hiding (Top,Bot)
import Data.HasCacBDD.Visuals
import Data.List ((\\),delete,dropWhileEnd,intercalate,intersect,nub,sort)
import Data.Tagged
import System.Directory (findExecutable)
import System.IO (hPutStr, hGetContents, hClose)
import System.IO.Unsafe (unsafePerformIO)
import System.Process (runInteractiveCommand)
import Test.QuickCheck
import SMCDEL.Internal.Help ((!),alleqWith,apply,applyPartial,lfp,powerset,rtc,seteq)
import SMCDEL.Internal.TaggedBDD
import SMCDEL.Internal.TexDisplay
import SMCDEL.Language
import SMCDEL.Other.BDD2Form
boolBddOf :: Form -> Bdd
boolBddOf Top = top
boolBddOf Bot = bot
boolBddOf (PrpF (P n)) = var n
boolBddOf (Neg form) = neg$ boolBddOf form
boolBddOf (Conj forms) = conSet $ map boolBddOf forms
boolBddOf (Disj forms) = disSet $ map boolBddOf forms
boolBddOf (Xor forms) = xorSet $ map boolBddOf forms
boolBddOf (Impl f g) = imp (boolBddOf f) (boolBddOf g)
boolBddOf (Equi f g) = equ (boolBddOf f) (boolBddOf g)
boolBddOf (Forall ps f) = forallSet (map fromEnum ps) (boolBddOf f)
boolBddOf (Exists ps f) = existsSet (map fromEnum ps) (boolBddOf f)
boolBddOf _ = error "boolBddOf failed: Not a boolean formula."
boolEvalViaBdd :: [Prp] -> Form -> Bool
boolEvalViaBdd truths = bddEval truths . boolBddOf
bddEval :: [Prp] -> Bdd -> Bool
bddEval truths querybdd = evaluateFun querybdd (\n -> P n `elem` truths)
relabelWith :: [(Prp,Prp)] -> Bdd -> Bdd
relabelWith r = relabel (sort $ map (fromEnum *** fromEnum) r)
data KnowStruct = KnS [Prp] -- vocabulary
Bdd -- state law
[(Agent,[Prp])] -- observational variables
deriving (Eq,Show)
type State = [Prp]
instance Pointed KnowStruct State
type KnowScene = (KnowStruct,State)
instance Pointed KnowStruct Bdd
type MultipointedKnowScene = (KnowStruct,Bdd)
statesOf :: KnowStruct -> [State]
statesOf (KnS props lawbdd _) = map (sort.translate) resultlists where
resultlists :: [[(Prp, Bool)]]
resultlists = map (map (first toEnum)) $ allSatsWith (map fromEnum props) lawbdd
translate l = map fst (filter snd l)
instance HasAgents KnowStruct where
agentsOf (KnS _ _ obs)= map fst obs
instance HasVocab KnowStruct where
vocabOf (KnS props _ _) = props
numberOfStates :: KnowStruct -> Int
numberOfStates (KnS props lawbdd _) = satCountWith (map fromEnum props) lawbdd
shareknow :: KnowStruct -> [[Prp]] -> [(State,State)]
shareknow kns sets = filter rel [ (s,t) | s <- statesOf kns, t <- statesOf kns ] where
rel (x,y) = or [ seteq (x `intersect` set) (y `intersect` set) | set <- sets ]
comknow :: KnowStruct -> [Agent] -> [(State,State)]
comknow kns@(KnS _ _ obs) ags = rtc $ shareknow kns (map (apply obs) ags)
eval :: KnowScene -> Form -> Bool
eval _ Top = True
eval _ Bot = False
eval (_,s) (PrpF p) = p `elem` s
eval (kns,s) (Neg form) = not $ eval (kns,s) form
eval (kns,s) (Conj forms) = all (eval (kns,s)) forms
eval (kns,s) (Disj forms) = any (eval (kns,s)) forms
eval (kns,s) (Xor forms) = odd $ length (filter id $ map (eval (kns,s)) forms)
eval scn (Impl f g) = not (eval scn f) || eval scn g
eval scn (Equi f g) = eval scn f == eval scn g
eval scn (Forall ps f) = eval scn (foldl singleForall f ps) where
singleForall g p = Conj [ SMCDEL.Language.substit p Top g, SMCDEL.Language.substit p Bot g ]
eval scn (Exists ps f) = eval scn (foldl singleExists f ps) where
singleExists g p = Disj [ SMCDEL.Language.substit p Top g, SMCDEL.Language.substit p Bot g ]
eval (kns@(KnS _ _ obs),s) (K i form) = all (\s' -> eval (kns,s') form) theres where
theres = filter (\s' -> seteq (s' `intersect` oi) (s `intersect` oi)) (statesOf kns)
oi = obs ! i
eval (kns@(KnS _ _ obs),s) (Kw i form) = alleqWith (\s' -> eval (kns,s') form) theres where
theres = filter (\s' -> seteq (s' `intersect` oi) (s `intersect` oi)) (statesOf kns)
oi = obs ! i
eval (kns,s) (Ck ags form) = all (\s' -> eval (kns,s') form) theres where
theres = [ s' | (s0,s') <- comknow kns ags, s0 == s ]
eval (kns,s) (Ckw ags form) = alleqWith (\s' -> eval (kns,s') form) theres where
theres = [ s' | (s0,s') <- comknow kns ags, s0 == s ]
eval scn (PubAnnounce form1 form2) =
not (eval scn form1) || eval (update scn form1) form2
eval (kns,s) (PubAnnounceW form1 form2) =
if eval (kns, s) form1
then eval (update kns form1, s) form2
else eval (update kns (Neg form1), s) form2
eval scn (Announce ags form1 form2) =
not (eval scn form1) || eval (announceOnScn scn ags form1) form2
eval scn (AnnounceW ags form1 form2) =
if eval scn form1
then eval (announceOnScn scn ags form1 ) form2
else eval (announceOnScn scn ags (Neg form1)) form2
eval scn (Dia (Dyn dynLabel d) f) = case fromDynamic d of
Just event -> eval scn (preOf (event :: Event))
&& eval (scn `update` event) f
Nothing -> error $ "cannot update knowledge structure with '" ++ dynLabel ++ "':\n " ++ show d
announce :: KnowStruct -> [Agent] -> Form -> KnowStruct
announce kns@(KnS props lawbdd obs) ags psi = KnS newprops newlawbdd newobs where
proppsi@(P k) = freshp props
newprops = sort $ proppsi : props
newlawbdd = con lawbdd (equ (var k) (bddOf kns psi))
newobs = [(i, obs ! i ++ [proppsi | i `elem` ags]) | i <- map fst obs]
announceOnScn :: KnowScene -> [Agent] -> Form -> KnowScene
announceOnScn (kns@(KnS props _ _),s) ags psi
| eval (kns,s) psi = (announce kns ags psi, sort $ freshp props : s)
| otherwise = error "Liar!"
bddOf :: KnowStruct -> Form -> Bdd
bddOf _ Top = top
bddOf _ Bot = bot
bddOf _ (PrpF (P n)) = var n
bddOf kns (Neg form) = neg $ bddOf kns form
bddOf kns (Conj forms) = conSet $ map (bddOf kns) forms
bddOf kns (Disj forms) = disSet $ map (bddOf kns) forms
bddOf kns (Xor forms) = xorSet $ map (bddOf kns) forms
bddOf kns (Impl f g) = imp (bddOf kns f) (bddOf kns g)
bddOf kns (Equi f g) = equ (bddOf kns f) (bddOf kns g)
bddOf kns (Forall ps f) = forallSet (map fromEnum ps) (bddOf kns f)
bddOf kns (Exists ps f) = existsSet (map fromEnum ps) (bddOf kns f)
bddOf kns@(KnS allprops lawbdd obs) (K i form) =
forallSet otherps (imp lawbdd (bddOf kns form)) where
otherps = map (\(P n) -> n) $ allprops \\ obs ! i
bddOf kns@(KnS allprops lawbdd obs) (Kw i form) =
disSet [ forallSet otherps (imp lawbdd (bddOf kns f)) | f <- [form, Neg form] ] where
otherps = map (\(P n) -> n) $ allprops \\ obs ! i
bddOf kns@(KnS allprops lawbdd obs) (Ck ags form) = gfp lambda where
lambda z = conSet $ bddOf kns form : [ forallSet (otherps i) (imp lawbdd z) | i <- ags ]
otherps i = map (\(P n) -> n) $ allprops \\ obs ! i
bddOf kns (Ckw ags form) = dis (bddOf kns (Ck ags form)) (bddOf kns (Ck ags (Neg form)))
bddOf kns@(KnS props _ _) (Announce ags form1 form2) =
imp (bddOf kns form1) (restrict bdd2 (k,True)) where
bdd2 = bddOf (announce kns ags form1) form2
(P k) = freshp props
bddOf kns@(KnS props _ _) (AnnounceW ags form1 form2) =
ifthenelse (bddOf kns form1) bdd2a bdd2b where
bdd2a = restrict (bddOf (announce kns ags form1) form2) (k,True)
bdd2b = restrict (bddOf (announce kns ags form1) form2) (k,False)
(P k) = freshp props
bddOf kns (PubAnnounce form1 form2) =
imp (bddOf kns form1) (bddOf (update kns form1) form2)
bddOf kns (PubAnnounceW form1 form2) =
ifthenelse (bddOf kns form1) newform2a newform2b where
newform2a = bddOf (update kns form1) form2
newform2b = bddOf (update kns (Neg form1)) form2
bddOf kns (Dia (Dyn dynLabel d) f) =
con (bddOf kns preCon) -- 5. Prefix with "precon AND ..." (diamond!)
. relabelWith copyrelInverse -- 4. Copy back changeProps V_-^o to V_-
. simulateActualEvents -- 3. Simulate actual event(s) [see below]
. substitSimul [ (k, changeLaw ! p) -- 2. Replace changeProps V_ with postcons
| p@(P k) <- changeProps] -- (no "relabelWith copyrel", undone in 4)
. bddOf (kns `update` trf) -- 1. boolean equivalent wrt new struct
$ f
where
changeProps = map fst changeLaw
copychangeProps = [(freshp $ vocabOf kns ++ addProps)..]
copyrelInverse = zip copychangeProps changeProps
(trf@(KnTrf addProps addLaw changeLaw _), shiftrel) = shiftPrepare kns trfUnshifted
(preCon,trfUnshifted,simulateActualEvents) =
case fromDynamic d of
-- 3. For a single event, simulate actual event x outof V+
Just ((t,x) :: Event) -> ( preOf (t,x), t, (`restrictSet` actualAss) )
where actualAss = [(newK, P k `elem` x) | (P k, P newK) <- shiftrel]
Nothing -> case fromDynamic d of
-- 3. For a multipointed event, simulate a set of actual events by ...
Just ((t,xsBdd) :: MultipointedEvent) ->
( preOf (t,xsBdd), t
, existsSet (map fromEnum addProps) -- ... replacing addProps with assigments
. con actualsBdd -- ... that satisfy actualsBdd
. con (bddOf kns addLaw) -- ... and a precondition.
) where actualsBdd = relabelWith shiftrel xsBdd
Nothing -> error $ "cannot update knowledge structure with '" ++ dynLabel ++ "':\n " ++ show d
evalViaBdd :: KnowScene -> Form -> Bool
evalViaBdd (kns,s) f = evaluateFun (bddOf kns f) (\n -> P n `elem` s)
instance Semantics KnowStruct where
isTrue = validViaBdd
instance Semantics KnowScene where
isTrue = evalViaBdd
instance Semantics MultipointedKnowScene where
isTrue (kns@(KnS _ lawBdd _),statesBdd) f =
let a = lawBdd `imp` (statesBdd `imp` bddOf kns f)
in a == top
instance Update KnowStruct Form where
checks = [ ] -- unpointed structures can be updated with anything
unsafeUpdate kns@(KnS props lawbdd obs) psi =
KnS props (lawbdd `con` bddOf kns psi) obs
instance Update KnowScene Form where
unsafeUpdate (kns,s) psi = (unsafeUpdate kns psi,s)
validViaBdd :: KnowStruct -> Form -> Bool
validViaBdd kns@(KnS _ lawbdd _) f = top == lawbdd `imp` bddOf kns f
whereViaBdd :: KnowStruct -> Form -> [State]
whereViaBdd kns@(KnS props lawbdd _) f =
map (sort . map (toEnum . fst) . filter snd) $
allSatsWith (map fromEnum props) $ con lawbdd (bddOf kns f)
determinedVocabOf :: KnowStruct -> [Prp]
determinedVocabOf strct =
filter (\p -> validViaBdd strct (PrpF p) || validViaBdd strct (Neg $ PrpF p)) (vocabOf strct)
nonobsVocabOf :: KnowStruct -> [Prp]
nonobsVocabOf (KnS vocab _ obs) = filter (`notElem` concatMap snd obs) vocab
equivExtraVocabOf :: [Prp] -> KnowStruct -> [(Prp,Prp)]
equivExtraVocabOf mainVocab kns =
[ (p,q) | p <- vocabOf kns \\ mainVocab, q <- vocabOf kns, p > q, validViaBdd kns (PrpF p `Equi` PrpF q) ]
replaceWithIn :: (Prp,Prp) -> KnowStruct -> KnowStruct
replaceWithIn (p,q) (KnS oldProps oldLaw oldObs) =
KnS
(delete p oldProps)
(Data.HasCacBDD.substit (fromEnum p) (var (fromEnum q)) oldLaw)
[(i, if p `elem` os then sort $ nub (q : delete p os) else os) | (i,os) <- oldObs]
replaceEquivExtra :: [Prp] -> KnowStruct -> (KnowStruct,[(Prp,Prp)])
replaceEquivExtra mainVocab startKns = lfp step (startKns,[]) where
step (kns,replRel) = case equivExtraVocabOf mainVocab kns of
[] -> (kns,replRel)
((p,q):_) -> (replaceWithIn (p,q) kns, (p,q):replRel)
withoutProps :: [Prp] -> KnowStruct -> KnowStruct
withoutProps propsToDel (KnS oldProps oldLawBdd oldObs) =
KnS
(oldProps \\ propsToDel)
(existsSet (map fromEnum propsToDel) oldLawBdd)
[(i,os \\ propsToDel) | (i,os) <- oldObs]
instance Optimizable KnowStruct where
optimize myVocab oldKns = newKns where
intermediateKns = withoutProps (determinedVocabOf oldKns \\ myVocab) oldKns
newKns = fst $ replaceEquivExtra myVocab intermediateKns
instance Optimizable KnowScene where
optimize myVocab (oldKns,oldState) = (newKns,newState) where
intermediateKns = withoutProps (determinedVocabOf oldKns \\ myVocab) oldKns
removedProps = vocabOf oldKns \\ vocabOf intermediateKns
intermediateState = oldState \\ removedProps
(newKns,replRel) = replaceEquivExtra myVocab intermediateKns
newState = sort $ (intermediateState \\ map fst replRel) ++ [ q | (p,q) <- replRel, p `elem` intermediateState ]
instance Optimizable MultipointedKnowScene where
optimize myVocab (oldKns,oldStatesBdd) = (newKns,newStatesBdd) where
intermediateKns = withoutProps (determinedVocabOf oldKns \\ myVocab) oldKns
removedProps = vocabOf oldKns \\ vocabOf intermediateKns
intermediateStatesBdd = existsSet (map fromEnum removedProps) oldStatesBdd
(newKns,replRel) = replaceEquivExtra myVocab intermediateKns
newStatesBdd = foldr (uncurry Data.HasCacBDD.substit) intermediateStatesBdd [ (fromEnum p, var (fromEnum q)) | (p,q) <-replRel ]
generatedSubstructure :: MultipointedKnowScene -> MultipointedKnowScene
generatedSubstructure kns@(KnS props oldLaw obs, curBdd) = (KnS props newLaw obs, curBdd) where
extend this = disSet (this : [ existsSet (map fromEnum $ props \\ obs ! i) this | i <- agentsOf kns ])
reachable = lfp extend curBdd
newLaw = oldLaw `con` reachable
type Propulation = Tagged Quadrupel Bdd
($$) :: Monad m => ([a] -> b) -> [m a] -> m b
($$) f xs = f <$> sequence xs
checkPropu :: Propulation -> KnowStruct -> KnowStruct -> [Prp] -> Bool
checkPropu propu kns1@(KnS _ law1 obs1) kns2@(KnS _ law2 obs2) voc =
pure top == (imp <$> lhs <*> rhs) where
lhs = conSet $$ [mv law1, cp law2, propu]
rhs = conSet $$ [propAgree, forth, back]
propAgree = allsamebdd voc
forth = conSet $$ [ forallSet (nonObs i obs1) <$>
(imp <$> mv law1 <*> (existsSet (nonObs i obs2) <$> (con <$> cp law2 <*> propu)))
| i <- agentsOf kns1 ]
back = conSet $$ [ forallSet (nonObs i obs1) <$>
(imp <$> mv law2 <*> (existsSet (nonObs i obs1) <$> (con <$> cp law1 <*> propu)))
| i <- agentsOf kns2 ]
nonObs i obs = map (\(P n) -> n) $ voc \\ obs ! i
data KnowTransformer = KnTrf
[Prp] -- addProps
Form -- addLaw
[(Prp,Bdd)] -- changeLaw
[(Agent,[Prp])] -- addObs
deriving (Eq,Show)
noChange :: ([Prp] -> Form -> [(Prp,Bdd)] -> [(Agent,[Prp])] -> KnowTransformer)
-> [Prp] -> Form -> [(Agent,[Prp])] -> KnowTransformer
noChange kntrf addprops addlaw = kntrf addprops addlaw []
instance HasAgents KnowTransformer where
agentsOf (KnTrf _ _ _ obdds) = map fst obdds
instance HasPrecondition KnowTransformer where
preOf _ = Top
instance Pointed KnowTransformer State
type Event = (KnowTransformer,State)
instance HasPrecondition Event where
preOf (KnTrf addprops addlaw _ _, x) = simplify $ substitOutOf x addprops addlaw
instance Pointed KnowTransformer Bdd
type MultipointedEvent = (KnowTransformer,Bdd)
instance HasPrecondition MultipointedEvent where
preOf (KnTrf addprops addlaw _ _, xsBdd) =
simplify $ Exists addprops (Conj [ formOf xsBdd, addlaw ])
publicAnnounce :: [Agent] -> Form -> Event
publicAnnounce agents f = (noChange KnTrf [] f myobs, []) where
myobs = [ (i,[]) | i <- agents ]
-- | shift addprops to ensure that props and newprops are disjoint:
shiftPrepare :: KnowStruct -> KnowTransformer -> (KnowTransformer, [(Prp,Prp)])
shiftPrepare (KnS props _ _) (KnTrf addprops addlaw changelaw eventObs) =
(KnTrf shiftaddprops addlawShifted changelawShifted eventObsShifted, shiftrel) where
shiftrel = sort $ zip addprops [(freshp props)..]
shiftaddprops = map snd shiftrel
-- apply the shifting to addlaw, changelaw and eventObs:
addlawShifted = replPsInF shiftrel addlaw
changelawShifted = map (second (relabelWith shiftrel)) changelaw
eventObsShifted = map (second (map (apply shiftrel))) eventObs
instance Update KnowScene Event where
unsafeUpdate (kns@(KnS props _ _),s) (ctrf, eventFactsUnshifted) = (KnS newprops newlaw newobs, news) where
-- PART 1: SHIFTING addprops to ensure props and newprops are disjoint
(KnTrf addprops _ changelaw _, shiftrel) = shiftPrepare kns ctrf
-- the actual event:
eventFacts = map (apply shiftrel) eventFactsUnshifted
-- PART 2: COPYING the modified propositions
changeprops = map fst changelaw
copyrel = zip changeprops [(freshp $ props ++ addprops)..]
-- do the pointless update and calculate new actual state
KnS newprops newlaw newobs = unsafeUpdate kns ctrf
news = sort $ concat
[ s \\ changeprops
, map (apply copyrel) $ s `intersect` changeprops
, eventFacts
, filter (\ p -> bddEval (s ++ eventFacts) (changelaw ! p)) changeprops ]
instance Update KnowStruct KnowTransformer where
checks = [haveSameAgents]
unsafeUpdate kns ctrf = KnS newprops newlaw newobs where
(KnS newprops newlaw newobs, _) = unsafeUpdate (kns,undefined::Bdd) (ctrf,undefined::Bdd) -- using laziness!
instance Update MultipointedKnowScene MultipointedEvent where
unsafeUpdate (kns@(KnS props law obs),statesBdd) (ctrf,eventsBddUnshifted) =
(KnS newprops newlaw newobs, newStatesBDD) where
(KnTrf addprops addlaw changelaw eventObs, shiftrel) = shiftPrepare kns ctrf
-- apply the shifting to eventsBdd:
eventsBdd = relabelWith shiftrel eventsBddUnshifted
-- PART 2: COPYING the modified propositions
changeprops = map fst changelaw
copyrel = zip changeprops [(freshp $ props ++ addprops)..]
copychangeprops = map snd copyrel
newprops = sort $ props ++ addprops ++ copychangeprops -- V u V^+ u V^o
newlaw = conSet $ relabelWith copyrel (con law (bddOf kns addlaw))
: [var (fromEnum q) `equ` relabelWith copyrel (changelaw ! q) | q <- changeprops]
newobs = [ (i , sort $ map (applyPartial copyrel) (obs ! i) ++ eventObs ! i) | i <- map fst obs ]
newStatesBDD = conSet [ relabelWith copyrel statesBdd, eventsBdd ]
texBddWith :: (Int -> String) -> Bdd -> String
texBddWith myShow b = unsafePerformIO $ do
haveDot2tex <- findExecutable "dot2tex"
case haveDot2tex of
Nothing -> error "Please install dot2tex which is needed to show BDDs."
Just d2t -> do
(i,o,_,_) <- runInteractiveCommand $ d2t ++ " --figpreamble=\"\\huge\" --figonly -traw"
hPutStr i (genGraphWith myShow b ++ "\n")
hClose i
result <- hGetContents o
return $ dropWhileEnd isSpace $ dropWhile isSpace result
texBDD :: Bdd -> String
texBDD = texBddWith show
newtype WrapBdd = Wrap Bdd
instance TexAble WrapBdd where
tex (Wrap b) = texBDD b
instance TexAble KnowStruct where
tex (KnS props lawbdd obs) = concat
[ " \\left( \n"
, tex props ++ ", "
, " \\begin{array}{l} \\scalebox{0.4}{"
, texBDD lawbdd
, "} \\end{array}\n "
, ", \\begin{array}{l}\n"
, intercalate " \\\\\n " (map (\(_,os) -> tex os) obs)
, "\\end{array}\n"
, " \\right)" ]
instance TexAble KnowScene where
tex (kns, state) = tex kns ++ " , " ++ tex state
instance TexAble MultipointedKnowScene where
tex (kns, statesBdd) = concat
[ " \\left( \n"
, tex kns ++ ", "
, " \\begin{array}{l} \\scalebox{0.4}{"
, texBDD statesBdd
, "} \\end{array}\n "
, " \\right)" ]
instance TexAble KnowTransformer where
tex (KnTrf addprops addlaw changelaw eventObs) = concat
[ " \\left( \n"
, tex addprops, ", \\ "
, tex addlaw, ", \\ "
, intercalate ", " $ map texChange changelaw
, ", \\ \\begin{array}{l}\n"
, intercalate " \\\\\n " (map (\(_,os) -> tex os) eventObs)
, "\\end{array}\n"
, " \\right) \n"
] where
texChange (prop,changebdd) = concat
[ tex prop ++ " := "
, " \\begin{array}{l} \\scalebox{0.4}{"
, texBDD changebdd
, "} \\end{array}\n " ]
instance TexAble Event where
tex (trf, eventFacts) = concat
[ " \\left( \n", tex trf, ", \\ ", tex eventFacts, " \\right) \n" ]
instance TexAble MultipointedEvent where
tex (trf, eventsBdd) = concat
[ " \\left( \n"
, tex trf ++ ", \\ "
, " \\begin{array}{l} \\scalebox{0.4}{"
, texBDD eventsBdd
, "} \\end{array}\n "
, " \\right)" ]
reduce :: Event -> Form -> Maybe Form
reduce _ Top = Just Top
reduce e Bot = pure $ Neg (preOf e)
reduce e (PrpF p) = Impl (preOf e) <$> Just (PrpF p) -- FIXME use change!
reduce e (Neg f) = Impl (preOf e) <$> (Neg <$> reduce e f)
reduce e (Conj fs) = Conj <$> mapM (reduce e) fs
reduce e (Disj fs) = Disj <$> mapM (reduce e) fs
reduce e (Xor fs) = Impl (preOf e) <$> (Xor <$> mapM (reduce e) fs)
reduce e (Impl f1 f2) = Impl <$> reduce e f1 <*> reduce e f2
reduce e (Equi f1 f2) = Equi <$> reduce e f1 <*> reduce e f2
reduce _ (Forall _ _) = Nothing
reduce _ (Exists _ _) = Nothing
reduce event@(trf@(KnTrf addprops _ _ obs), x) (K a f) =
Impl (preOf event) <$> (Conj <$> sequence
[ K a <$> reduce (trf,y) f | y <- powerset addprops
, (x `intersect` (obs ! a)) `seteq` (y `intersect` (obs ! a))
])
reduce e (Kw a f) = reduce e (Disj [K a f, K a (Neg f)])
reduce _ Ck {} = Nothing
reduce _ Ckw {} = Nothing
reduce _ PubAnnounce {} = Nothing
reduce _ PubAnnounceW {} = Nothing
reduce _ Announce {} = Nothing
reduce _ AnnounceW {} = Nothing
reduce _ Dia {} = Nothing
instance Arbitrary KnowStruct where
arbitrary = do
numExtraVars <- choose (0,2)
let myVocabulary = defaultVocabulary ++ take numExtraVars [freshp defaultVocabulary ..]
(BF statelaw) <- sized (randomboolformWith myVocabulary) `suchThat` (\(BF bf) -> boolBddOf bf /= bot)
obs <- mapM (\i -> do
obsVars <- sublistOf myVocabulary
return (i,obsVars)
) defaultAgents
return $ KnS myVocabulary (boolBddOf statelaw) obs
shrink kns = [ withoutProps [p] kns | length (vocabOf kns) > 1, p <- vocabOf kns \\ defaultVocabulary ]