module Numeric.Probability.Example.Alarm where

import qualified Numeric.Probability.Distribution as Dist
import Numeric.Probability.Distribution ((??), (?=<<), )


type Probability = Rational
type Dist a = Dist.T Probability a
type PBool  = Dist.T Probability Bool


flp :: Probability -> PBool
flp :: Probability -> PBool
flp Probability
p = forall prob a. Num prob => prob -> a -> a -> T prob a
Dist.choose Probability
p Bool
True Bool
False


-- * Numeric.Probability.Example.Alarm network

-- | prior burglary 1%
b :: PBool
b :: PBool
b = Probability -> PBool
flp Probability
0.01

-- | prior earthquake 0.1%
e :: PBool
e :: PBool
e = Probability -> PBool
flp Probability
0.001

-- | conditional probability of alarm given burglary and earthquake
a :: Bool -> Bool -> PBool
a :: Bool -> Bool -> PBool
a Bool
b0 Bool
e0 =
   case (Bool
b0,Bool
e0) of
      (Bool
False,Bool
False) -> Probability -> PBool
flp Probability
0.01
      (Bool
False,Bool
True)  -> Probability -> PBool
flp Probability
0.1
      (Bool
True,Bool
False)  -> Probability -> PBool
flp Probability
0.7
      (Bool
True,Bool
True)   -> Probability -> PBool
flp Probability
0.8


-- | conditional probability of john calling given alarm
j :: Bool -> PBool
j :: Bool -> PBool
j Bool
a0 = if Bool
a0 then Probability -> PBool
flp Probability
0.8 else Probability -> PBool
flp Probability
0.05

-- | conditional probability of mary calling given alarm
m :: Bool -> PBool
m :: Bool -> PBool
m Bool
a0 = if Bool
a0 then Probability -> PBool
flp Probability
0.9 else Probability -> PBool
flp Probability
0.1

-- | calculate the full joint distribution
data Burglary = B { 	Burglary -> Bool
burglary :: Bool,
			Burglary -> Bool
earthquake :: Bool,
			Burglary -> Bool
alarm :: Bool,
			Burglary -> Bool
john :: Bool,
			Burglary -> Bool
mary :: Bool }
	deriving (Burglary -> Burglary -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Burglary -> Burglary -> Bool
$c/= :: Burglary -> Burglary -> Bool
== :: Burglary -> Burglary -> Bool
$c== :: Burglary -> Burglary -> Bool
Eq, Eq Burglary
Burglary -> Burglary -> Bool
Burglary -> Burglary -> Ordering
Burglary -> Burglary -> Burglary
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Burglary -> Burglary -> Burglary
$cmin :: Burglary -> Burglary -> Burglary
max :: Burglary -> Burglary -> Burglary
$cmax :: Burglary -> Burglary -> Burglary
>= :: Burglary -> Burglary -> Bool
$c>= :: Burglary -> Burglary -> Bool
> :: Burglary -> Burglary -> Bool
$c> :: Burglary -> Burglary -> Bool
<= :: Burglary -> Burglary -> Bool
$c<= :: Burglary -> Burglary -> Bool
< :: Burglary -> Burglary -> Bool
$c< :: Burglary -> Burglary -> Bool
compare :: Burglary -> Burglary -> Ordering
$ccompare :: Burglary -> Burglary -> Ordering
Ord, Int -> Burglary -> ShowS
[Burglary] -> ShowS
Burglary -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Burglary] -> ShowS
$cshowList :: [Burglary] -> ShowS
show :: Burglary -> String
$cshow :: Burglary -> String
showsPrec :: Int -> Burglary -> ShowS
$cshowsPrec :: Int -> Burglary -> ShowS
Show)

bJoint :: Dist Burglary
bJoint :: Dist Burglary
bJoint = do Bool
b' <- PBool
b 		-- burglary
            Bool
e' <- PBool
e 		-- earthquake
            Bool
a' <- Bool -> Bool -> PBool
a Bool
b' Bool
e' 	-- alarm
	    Bool
j' <- Bool -> PBool
j Bool
a' 		-- john
	    Bool
m' <- Bool -> PBool
m Bool
a' 		-- mary
	    forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Bool -> Bool -> Bool -> Bool -> Burglary
B Bool
b' Bool
e' Bool
a' Bool
j' Bool
m')

-- | what is the probability that mary calls given that john calls?
pmj :: Probability
pmj :: Probability
pmj = Burglary -> Bool
mary forall prob a. Num prob => Event a -> T prob a -> prob
?? Burglary -> Bool
john forall prob a.
Fractional prob =>
(a -> Bool) -> T prob a -> T prob a
?=<< Dist Burglary
bJoint