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 mcUpdate :: McModel -> McFormula -> McModel mcUpdate (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 = mcUpdate (mcModel s) (Qf some) step s n = mcUpdate (step s (n-1)) nobodyknows showme :: State -> IO () showme s@(_,m) = mapM_ (\n -> putStrLn $ show n ++ ": " ++ show (step s n)) [0..(m-1)]