{-# 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)