smcdel-1.2.0: src/SMCDEL/Symbolic/S5_CUDD.hs
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
module SMCDEL.Symbolic.S5_CUDD where
import SMCDEL.Internal.MyHaskCUDD
import Data.List ((\\), sort)
import SMCDEL.Internal.Help (apply)
import SMCDEL.Language
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) = boolBddOf (foldl singleForall f ps) where
singleForall g p = Conj [ substit p Top g, substit p Bot g ]
boolBddOf (Exists ps f) = boolBddOf (foldl singleExists f ps) where
singleExists g p = Disj [ substit p Top g, substit p Bot g ]
boolBddOf _ = error "boolBddOf failed: Not a boolean formula."
data KnowStruct = KnS [Prp] Bdd [(Agent,[Prp])] deriving (Eq,Show)
type KnState = [Prp]
type KnowScene = (KnowStruct,KnState)
instance HasVocab KnowStruct where
vocabOf (KnS props _ _) = props
instance Pointed KnowStruct KnState
pubAnnounce :: KnowStruct -> Form -> KnowStruct
pubAnnounce kns@(KnS props lawbdd obs) psi = KnS props newlawbdd obs where
newlawbdd = con lawbdd (bddOf kns psi)
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, apply obs i ++ [proppsi | i `elem` ags]) | i <- map fst obs]
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 \\ apply 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 \\ apply 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 \\ apply 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) newform2 where
newform2 = bddOf (pubAnnounce kns form1) form2
bddOf kns (PubAnnounceW form1 form2) =
ifthenelse (bddOf kns form1) newform2a newform2b where
newform2a = bddOf (pubAnnounce kns form1) form2
newform2b = bddOf (pubAnnounce kns (Neg form1)) form2
bddOf _ (Dia _ _) = error "Dynamic operators are not implemented for CUDD."
evalViaBdd :: KnowScene -> Form -> Bool
evalViaBdd (kns@(KnS allprops _ _),s) f = bool where
bool | b==top = True
| b==bot = False
| otherwise = error ("evalViaBdd failed: BDD leftover:\n" ++ show b)
b = restrictSet (bddOf kns f) list
list = [ (n, P n `elem` s) | (P n) <- allprops ]
instance Semantics KnowScene where
isTrue = evalViaBdd
validViaBdd :: KnowStruct -> Form -> Bool
validViaBdd kns@(KnS _ lawbdd _) f = top == lawbdd `imp` bddOf kns f
whereViaBdd :: KnowStruct -> Form -> [KnState]
whereViaBdd kns@(KnS props lawbdd _) f =
map (sort . map (toEnum . fst) . filter snd) $
allSatsWith (map fromEnum props) $ con lawbdd (bddOf kns f)