{- | Approach: model a node with k predecessors as a function with k parameters -} module Numeric.Probability.Example.Bayesian where import qualified Numeric.Probability.Distribution as Dist import qualified Numeric.Probability.Transition as Trans import qualified Numeric.Probability.Monad as MonadExt import Numeric.Probability.Distribution ((??), (?=<<), ) -- * Abbreviations, smart constructors type Probability = Rational type Dist a = Dist.T Probability a type State a = [a] type PState a = Dist (State a) type STrans a = State a -> PState a type SPred a = a -> State a -> Bool event :: Probability -> a -> STrans a event p e0 = Trans.maybe p (e0:) happens :: Eq a => SPred a happens = elem network :: [STrans a] -> PState a network = flip MonadExt.compose [] source :: Probability -> a -> STrans a source = event bin :: Eq a => a -> a -> Probability -> Probability -> Probability -> Probability -> a -> STrans a bin x y a b c d z s | elem x s && elem y s = event a z s | elem x s = event b z s | elem y s = event c z s | otherwise = event d z s -- | Two possible causes for one effect data Nodes = A | B | E deriving (Eq,Ord,Show) g :: PState Nodes g = network [source 0.1 A, source 0.2 B, bin A B 1 1 0.5 0 E] -- * queries e, aE, bE :: Probability e = happens E ?? g aE = happens A ?? happens E ?=<< g bE = happens B ?? happens E ?=<< g {- data State = State {causeA :: Bool, causeB :: Bool, effect :: Bool} deriving (Eq,Ord,Show) nCauseA s = s{causeA=True} -} -- -- Wet grass example -- -- cloudy = true 0.5 -- -- sprinkler c = dep c 0.1 0.5 -- -- rain c = dep c 0.8 0.2 -- -- wetGrass s r = bin s r 0.99 0.9 0.9 0 -- -- c = cloudy -- s = sprinkler cloudy -- r = rain cloudy -- w = wetGrass s r -- alarm :: Prob -> Prob -> Prob -- alarm b e = cond b (pTrue 0.8) -- (cond e (pTrue 0.1) (pTrue 0.01)) -- -- john :: Prob -> Prob -- john a = cond a (pTrue 0.7) (pTrue 0.1) -- -- mary :: Prob -> Prob -- mary a = cond a (pTrue 0.6) (pTrue 0.2) -- -- -- maryWhenJohn = mary a ?? john a -- where a = alarm (pTrue 0.5) (pTrue 0.1)