-
Notifications
You must be signed in to change notification settings - Fork 0
/
Alarm.curry
129 lines (106 loc) · 2.72 KB
/
Alarm.curry
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
{-
Values used from ProbLog2 Tutorial:
https://dtai.cs.kuleuven.be/problog/tutorial.html
The same model is used in different languages as well:
BLOG: http://patmos.banatao.berkeley.edu:8080
(here: "my values" yield different results in BLOG -- weird?)
-}
module Alarm where
import BayesianNetwork
import PFLP
earthquake :: Dist Bool
earthquake = bernoulli 0.2
burglary :: Dist Bool
burglary = bernoulli 0.7
alarm :: Dist Bool -> Dist Bool -> Dist Bool
alarm vBurglary vEarthquake =
vBurglary |> \b ->
vEarthquake |> \e -> bernoulli $ f b e
where
f True True = 0.9
f True False = 0.8
f False True = 0.1
f False False = 0.0
-- P(B=T | A=T) = { True 98.97%, False 1.03% }
query1 =
let b' = burglary
e' = earthquake
a' = alarm b' e' =: True
in (b', True) `given` [a',e']
-- P(E=T | A=T) = { False 77.24%, True 22.76% }
query2 =
let b' = burglary
e' = earthquake
a' = alarm b' e' =: True
in (e', True) `given` [b',a']
-- -----------------
-- Second version
-- -----------------
alarm' :: Bool -> Bool -> Dist Bool
alarm' True True = bernoulli 0.9
alarm' True False = bernoulli 0.8
alarm' False True = bernoulli 0.1
alarm' False False = bernoulli 0.0
query1' =
burglary >>>= \b ->
earthquake >>>= \e ->
(alarm' b e =: True) >>>= \_ ->
pure b
query2' =
burglary >>>= \b ->
earthquake >>>= \e ->
alarm' b e >>>= \a ->
guard a >>>= \_ ->
pure e
-- -----------------
-- Extension
-- -----------------
data Person = Mary | John
calls :: Person -> Dist Bool -> Dist Bool
calls Mary vAlarm = vAlarm |> (bernoulli . f)
where
f True = 0.9
f False = 0.05
calls John vAlarm = vAlarm |> (bernoulli . f)
where
f True = 0.9
f False = 0.05
-- P (B=T | calls John = T, calls Mary = T) = { True 98.19%, False 1.81% }
query3 =
let b' = burglary
e' = earthquake
a' = alarm b' e'
c1 = calls John a' =: True
c2 = calls Mary a' =: True
in (b',True) `given` [e',a',c1,c2]
-- P (E=T | calls John = T, calls Mary = T) = { False 77.31%, True 22.69% }
query4 =
let b' = burglary
e' = earthquake
a' = alarm b' e'
c1 = calls John a' =: True
c2 = calls Mary a' =: True
in (e',True) `given` [a',c1,c2,b']
-- -----------------
-- Second version
-- -----------------
calls' :: Person -> Bool -> Dist Bool
calls' _ True = bernoulli 0.8
calls' _ False = bernoulli 0.1
query3' =
burglary >>>= \b ->
earthquake >>>= \e ->
alarm' b e >>>= \a ->
calls' John a >>>= \c1 ->
calls' Mary a >>>= \c2 ->
guard c1 >>>= \_ ->
guard c2 >>>= \_ ->
pure b
query4' =
burglary >>>= \b ->
earthquake >>>= \e ->
alarm' b e >>>= \a ->
calls' John a >>>= \c1 ->
calls' Mary a >>>= \c2 ->
guard (c1 && c2) >>>= \_ ->
pure e