smcdel-1.0.0: src/SMCDEL/Other/MCTRIANGLE.hs
module SMCDEL.Other.MCTRIANGLE where
data Kind = Muddy | Clean
type State = (Int,Int)
data McModel = McM [State] [State] State deriving Show
mcModel :: State -> McModel
mcModel cur@(c,m) = McM ostates fstates cur where
total = c + m
ostates = [ ((total-1)-m',m') | m'<-[0..(total-1)] ] -- observational states
fstates = [ (total-m', m') | m'<-[0..total ] ] -- factual states
posFrom :: McModel -> State -> [State]
posFrom (McM _ fstates _) (oc,om) = filter (`elem` fstates) [ (oc+1,om), (oc,om+1) ]
obsFor :: McModel -> Kind -> State
obsFor (McM _ _ (curc,curm)) Clean = (curc-1,curm)
obsFor (McM _ _ (curc,curm)) Muddy = (curc,curm-1)
posFor :: McModel -> Kind -> [State]
posFor m status = posFrom m $ obsFor m status
type Quantifier = State -> Bool
some :: Quantifier
some (_,b) = b > 0
data McFormula = Neg McFormula -- negations
| Conj [McFormula] -- conjunctions
| Qf Quantifier -- quantifiers
| KnowSelf Kind -- all b agents DO know their status
| NotKnowSelf Kind -- all b agents DON'T know their status
nobodyknows,everyoneKnows :: McFormula
nobodyknows = Conj [ NotKnowSelf Clean, NotKnowSelf Muddy ]
everyoneKnows = Conj [ KnowSelf Clean, KnowSelf Muddy ]
eval :: McModel -> McFormula -> Bool
eval m (Neg f) = not $ eval m f
eval m (Conj fs) = all (eval m) fs
eval (McM _ _ s) (Qf q) = q s
eval m@(McM _ _ (_,curm)) (KnowSelf Muddy) = curm==0 || length (posFor m Muddy) == 1
eval m@(McM _ _ (curc,_)) (KnowSelf Clean) = curc==0 || length (posFor m Clean) == 1
eval m@(McM _ _ (_,curm)) (NotKnowSelf Muddy) = curm==0 || length (posFor m Muddy) == 2
eval m@(McM _ _ (curc,_)) (NotKnowSelf Clean) = curc==0 || length (posFor m Clean) == 2
update :: McModel -> McFormula -> McModel
update (McM ostates fstates cur) f =
McM ostates' fstates' cur where
fstates' = filter (\s -> eval (McM ostates fstates s) f) fstates
ostates' = filter (not . null . posFrom (McM [] fstates' cur)) ostates
step :: State -> Int -> McModel
step s 0 = update (mcModel s) (Qf some)
step s n = update (step s (n-1)) nobodyknows
showme :: State -> IO ()
showme s@(_,m) = mapM_ (\n -> putStrLn $ show n ++ ": " ++ show (step s n)) [0..(m-1)]