Commit d080b40076ecd7ebad3d03e24b0358a15c5bc21b
1 parent
e43d9d3b
Exists in
master
Paper draft: Extending Probabilities;
Support code: Event and Lattice look fine.
Showing
13 changed files
with
547 additions
and
385 deletions
Show diff stats
.vscode/launch.json
code/python/EventLattice.ipynb
... | ... | @@ -2,26 +2,37 @@ |
2 | 2 | "cells": [ |
3 | 3 | { |
4 | 4 | "cell_type": "code", |
5 | - "execution_count": 7, | |
5 | + "execution_count": 4, | |
6 | 6 | "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", |
7 | 7 | "metadata": {}, |
8 | - "outputs": [], | |
8 | + "outputs": [ | |
9 | + { | |
10 | + "name": "stdout", | |
11 | + "output_type": "stream", | |
12 | + "text": [ | |
13 | + "The autoreload extension is already loaded. To reload it, use:\n", | |
14 | + " %reload_ext autoreload\n" | |
15 | + ] | |
16 | + } | |
17 | + ], | |
9 | 18 | "source": [ |
10 | - "import event_lattice as el" | |
19 | + "%load_ext autoreload\n", | |
20 | + "%autoreload 1\n", | |
21 | + "%aimport event_lattice" | |
11 | 22 | ] |
12 | 23 | }, |
13 | 24 | { |
14 | 25 | "cell_type": "code", |
15 | - "execution_count": 8, | |
26 | + "execution_count": 5, | |
16 | 27 | "id": "00f0eb68", |
17 | 28 | "metadata": {}, |
18 | 29 | "outputs": [], |
19 | 30 | "source": [ |
20 | - "def zoom_event(event_str, lattice, lower_op=el.sum_op, upper_op=el.prod_op):\n", | |
21 | - " event = el.Event.from_str(event_str)\n", | |
31 | + "def zoom_event(event_str, lattice):\n", | |
32 | + " event = event_lattice.Event.from_str(event_str)\n", | |
22 | 33 | " event_class = lattice.event_class(event)\n", |
23 | - " propagated = lattice.propagated_value(\n", | |
24 | - " event, lower_op=lower_op, upper_op=upper_op)\n", | |
34 | + " propagated = lattice.extended_value(\n", | |
35 | + " event)\n", | |
25 | 36 | "\n", |
26 | 37 | " print(\n", |
27 | 38 | " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" |
... | ... | @@ -29,7 +40,7 @@ |
29 | 40 | }, |
30 | 41 | { |
31 | 42 | "cell_type": "code", |
32 | - "execution_count": 9, | |
43 | + "execution_count": 6, | |
33 | 44 | "id": "cdd8c6d6", |
34 | 45 | "metadata": {}, |
35 | 46 | "outputs": [ |
... | ... | @@ -49,42 +60,34 @@ |
49 | 60 | } |
50 | 61 | ], |
51 | 62 | "source": [ |
52 | - "smodels = el.Lattice.parse({\n", | |
63 | + "smodels = event_lattice.Lattice.parse({\n", | |
53 | 64 | " \"A\": 2,\n", |
54 | 65 | " \"ab\": 3,\n", |
55 | 66 | " \"ac\": 5\n", |
56 | 67 | "})\n", |
57 | 68 | "\n", |
58 | - "lattice = el.Lattice(smodels)\n", | |
69 | + "lattice = event_lattice.Lattice(smodels)\n", | |
59 | 70 | "\n", |
60 | 71 | "print(lattice)" |
61 | 72 | ] |
62 | 73 | }, |
63 | 74 | { |
64 | 75 | "cell_type": "code", |
65 | - "execution_count": 10, | |
76 | + "execution_count": 7, | |
66 | 77 | "id": "2b445339", |
67 | 78 | "metadata": {}, |
68 | 79 | "outputs": [ |
69 | 80 | { |
70 | - "name": "stdout", | |
71 | - "output_type": "stream", | |
72 | - "text": [ | |
73 | - "Event: abc\n", | |
74 | - "\tClass: <|ac,ab> \n", | |
75 | - "\tValue: 8\n", | |
76 | - "Event: a\n", | |
77 | - "\tClass: <ac,ab|> \n", | |
78 | - "\tValue: 15\n", | |
79 | - "Event: b\n", | |
80 | - "\tClass: <ab|> \n", | |
81 | - "\tValue: 3\n", | |
82 | - "Event: bc\n", | |
83 | - "\tClass: <|> \n", | |
84 | - "\tValue: 0\n", | |
85 | - "Event: ac\n", | |
86 | - "\tClass: <ac|ac> \n", | |
87 | - "\tValue: 5\n" | |
81 | + "ename": "TypeError", | |
82 | + "evalue": "__init__() missing 1 required positional argument: 'lattice'", | |
83 | + "output_type": "error", | |
84 | + "traceback": [ | |
85 | + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | |
86 | + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", | |
87 | + "\u001b[0;32m/tmp/ipykernel_361713/2581811254.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"abc\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"a\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"b\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"bc\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ac\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
88 | + "\u001b[0;32m/tmp/ipykernel_361713/1675915232.py\u001b[0m in \u001b[0;36mzoom_event\u001b[0;34m(event_str, lattice)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mzoom_event\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevent_str\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mevent\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mevent_lattice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEvent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_str\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevent_str\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mevent_class\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlattice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mevent_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m propagated = lattice.extended_value(\n\u001b[1;32m 5\u001b[0m event)\n", | |
89 | + "\u001b[0;32m~/sci/projetos/zugzwang/code/python/event_lattice.py\u001b[0m in \u001b[0;36mevent_class\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m 146\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mcache\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 147\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mevent_class\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mevent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 148\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mEventsClass\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstable_core\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 149\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrelated\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
90 | + "\u001b[0;31mTypeError\u001b[0m: __init__() missing 1 required positional argument: 'lattice'" | |
88 | 91 | ] |
89 | 92 | } |
90 | 93 | ], |
... | ... | @@ -98,209 +101,10 @@ |
98 | 101 | }, |
99 | 102 | { |
100 | 103 | "cell_type": "code", |
101 | - "execution_count": 11, | |
104 | + "execution_count": null, | |
102 | 105 | "id": "f1b85255", |
103 | 106 | "metadata": {}, |
104 | - "outputs": [ | |
105 | - { | |
106 | - "name": "stdout", | |
107 | - "output_type": "stream", | |
108 | - "text": [ | |
109 | - "Event: \n", | |
110 | - "\tClass: <A,ac,ab|> \n", | |
111 | - "\tValue: 30\n", | |
112 | - "Event: A\n", | |
113 | - "\tClass: <A|A> \n", | |
114 | - "\tValue: 2\n", | |
115 | - "Event: b\n", | |
116 | - "\tClass: <ab|> \n", | |
117 | - "\tValue: 3\n", | |
118 | - "Event: a\n", | |
119 | - "\tClass: <ac,ab|> \n", | |
120 | - "\tValue: 15\n", | |
121 | - "Event: B\n", | |
122 | - "\tClass: <|> \n", | |
123 | - "\tValue: 0\n", | |
124 | - "Event: c\n", | |
125 | - "\tClass: <ac|> \n", | |
126 | - "\tValue: 5\n", | |
127 | - "Event: C\n", | |
128 | - "\tClass: <|> \n", | |
129 | - "\tValue: 0\n", | |
130 | - "Event: Ab\n", | |
131 | - "\tClass: <|A> \n", | |
132 | - "\tValue: 2\n", | |
133 | - "Event: Aa\n", | |
134 | - "\tClass: <|A> \n", | |
135 | - "\tValue: 0\n", | |
136 | - "Event: AB\n", | |
137 | - "\tClass: <|A> \n", | |
138 | - "\tValue: 2\n", | |
139 | - "Event: Ac\n", | |
140 | - "\tClass: <|A> \n", | |
141 | - "\tValue: 2\n", | |
142 | - "Event: AC\n", | |
143 | - "\tClass: <|A> \n", | |
144 | - "\tValue: 2\n", | |
145 | - "Event: ab\n", | |
146 | - "\tClass: <ab|ab> \n", | |
147 | - "\tValue: 3\n", | |
148 | - "Event: Bb\n", | |
149 | - "\tClass: <|> \n", | |
150 | - "\tValue: 0\n", | |
151 | - "Event: bc\n", | |
152 | - "\tClass: <|> \n", | |
153 | - "\tValue: 0\n", | |
154 | - "Event: Cb\n", | |
155 | - "\tClass: <|> \n", | |
156 | - "\tValue: 0\n", | |
157 | - "Event: Ba\n", | |
158 | - "\tClass: <|> \n", | |
159 | - "\tValue: 0\n", | |
160 | - "Event: ac\n", | |
161 | - "\tClass: <ac|ac> \n", | |
162 | - "\tValue: 5\n", | |
163 | - "Event: Ca\n", | |
164 | - "\tClass: <|> \n", | |
165 | - "\tValue: 0\n", | |
166 | - "Event: Bc\n", | |
167 | - "\tClass: <|> \n", | |
168 | - "\tValue: 0\n", | |
169 | - "Event: BC\n", | |
170 | - "\tClass: <|> \n", | |
171 | - "\tValue: 0\n", | |
172 | - "Event: Cc\n", | |
173 | - "\tClass: <|> \n", | |
174 | - "\tValue: 0\n", | |
175 | - "Event: Aab\n", | |
176 | - "\tClass: <|A,ab> \n", | |
177 | - "\tValue: 0\n", | |
178 | - "Event: ABb\n", | |
179 | - "\tClass: <|A> \n", | |
180 | - "\tValue: 0\n", | |
181 | - "Event: Abc\n", | |
182 | - "\tClass: <|A> \n", | |
183 | - "\tValue: 2\n", | |
184 | - "Event: ACb\n", | |
185 | - "\tClass: <|A> \n", | |
186 | - "\tValue: 2\n", | |
187 | - "Event: ABa\n", | |
188 | - "\tClass: <|A> \n", | |
189 | - "\tValue: 0\n", | |
190 | - "Event: Aac\n", | |
191 | - "\tClass: <|A,ac> \n", | |
192 | - "\tValue: 0\n", | |
193 | - "Event: ACa\n", | |
194 | - "\tClass: <|A> \n", | |
195 | - "\tValue: 0\n", | |
196 | - "Event: ABc\n", | |
197 | - "\tClass: <|A> \n", | |
198 | - "\tValue: 2\n", | |
199 | - "Event: ABC\n", | |
200 | - "\tClass: <|A> \n", | |
201 | - "\tValue: 2\n", | |
202 | - "Event: ACc\n", | |
203 | - "\tClass: <|A> \n", | |
204 | - "\tValue: 0\n", | |
205 | - "Event: Bab\n", | |
206 | - "\tClass: <|ab> \n", | |
207 | - "\tValue: 0\n", | |
208 | - "Event: abc\n", | |
209 | - "\tClass: <|ac,ab> \n", | |
210 | - "\tValue: 8\n", | |
211 | - "Event: Cab\n", | |
212 | - "\tClass: <|ab> \n", | |
213 | - "\tValue: 3\n", | |
214 | - "Event: Bbc\n", | |
215 | - "\tClass: <|> \n", | |
216 | - "\tValue: 0\n", | |
217 | - "Event: BCb\n", | |
218 | - "\tClass: <|> \n", | |
219 | - "\tValue: 0\n", | |
220 | - "Event: Cbc\n", | |
221 | - "\tClass: <|> \n", | |
222 | - "\tValue: 0\n", | |
223 | - "Event: Bac\n", | |
224 | - "\tClass: <|ac> \n", | |
225 | - "\tValue: 5\n", | |
226 | - "Event: BCa\n", | |
227 | - "\tClass: <|> \n", | |
228 | - "\tValue: 0\n", | |
229 | - "Event: Cac\n", | |
230 | - "\tClass: <|ac> \n", | |
231 | - "\tValue: 0\n", | |
232 | - "Event: BCc\n", | |
233 | - "\tClass: <|> \n", | |
234 | - "\tValue: 0\n", | |
235 | - "Event: ABab\n", | |
236 | - "\tClass: <|A,ab> \n", | |
237 | - "\tValue: 0\n", | |
238 | - "Event: Aabc\n", | |
239 | - "\tClass: <|A,ac,ab> \n", | |
240 | - "\tValue: 0\n", | |
241 | - "Event: ACab\n", | |
242 | - "\tClass: <|A,ab> \n", | |
243 | - "\tValue: 0\n", | |
244 | - "Event: ABbc\n", | |
245 | - "\tClass: <|A> \n", | |
246 | - "\tValue: 0\n", | |
247 | - "Event: ABCb\n", | |
248 | - "\tClass: <|A> \n", | |
249 | - "\tValue: 0\n", | |
250 | - "Event: ACbc\n", | |
251 | - "\tClass: <|A> \n", | |
252 | - "\tValue: 0\n", | |
253 | - "Event: ABac\n", | |
254 | - "\tClass: <|A,ac> \n", | |
255 | - "\tValue: 0\n", | |
256 | - "Event: ABCa\n", | |
257 | - "\tClass: <|A> \n", | |
258 | - "\tValue: 0\n", | |
259 | - "Event: ACac\n", | |
260 | - "\tClass: <|A,ac> \n", | |
261 | - "\tValue: 0\n", | |
262 | - "Event: ABCc\n", | |
263 | - "\tClass: <|A> \n", | |
264 | - "\tValue: 0\n", | |
265 | - "Event: Babc\n", | |
266 | - "\tClass: <|ac,ab> \n", | |
267 | - "\tValue: 0\n", | |
268 | - "Event: BCab\n", | |
269 | - "\tClass: <|ab> \n", | |
270 | - "\tValue: 0\n", | |
271 | - "Event: Cabc\n", | |
272 | - "\tClass: <|ac,ab> \n", | |
273 | - "\tValue: 0\n", | |
274 | - "Event: BCbc\n", | |
275 | - "\tClass: <|> \n", | |
276 | - "\tValue: 0\n", | |
277 | - "Event: BCac\n", | |
278 | - "\tClass: <|ac> \n", | |
279 | - "\tValue: 0\n", | |
280 | - "Event: ABabc\n", | |
281 | - "\tClass: <|A,ac,ab> \n", | |
282 | - "\tValue: 0\n", | |
283 | - "Event: ABCab\n", | |
284 | - "\tClass: <|A,ab> \n", | |
285 | - "\tValue: 0\n", | |
286 | - "Event: ACabc\n", | |
287 | - "\tClass: <|A,ac,ab> \n", | |
288 | - "\tValue: 0\n", | |
289 | - "Event: ABCbc\n", | |
290 | - "\tClass: <|A> \n", | |
291 | - "\tValue: 0\n", | |
292 | - "Event: ABCac\n", | |
293 | - "\tClass: <|A,ac> \n", | |
294 | - "\tValue: 0\n", | |
295 | - "Event: BCabc\n", | |
296 | - "\tClass: <|ac,ab> \n", | |
297 | - "\tValue: 0\n", | |
298 | - "Event: ABCabc\n", | |
299 | - "\tClass: <|A,ac,ab> \n", | |
300 | - "\tValue: 0\n" | |
301 | - ] | |
302 | - } | |
303 | - ], | |
107 | + "outputs": [], | |
304 | 108 | "source": [ |
305 | 109 | "from itertools import *\n", |
306 | 110 | "\n", | ... | ... |
code/python/__pycache__/event_lattice.cpython-39.pyc
No preview for this file type
code/python/event_lattice.py
1 | 1 | import math |
2 | 2 | from functools import cache |
3 | -from itertools import accumulate | |
3 | +from itertools import accumulate, combinations, chain, groupby | |
4 | 4 | import operator |
5 | 5 | |
6 | 6 | |
... | ... | @@ -32,21 +32,31 @@ def prod_op(x): |
32 | 32 | |
33 | 33 | |
34 | 34 | class Event: |
35 | - """"Events.""" | |
35 | + """Events. | |
36 | + | |
37 | + An event is a set of literals - atoms and negated atoms. | |
38 | + | |
39 | + The convention is that atoms are represented by lower case single letters | |
40 | + and a negated atom by upper case single letters. | |
41 | + """ | |
36 | 42 | |
37 | 43 | @staticmethod |
38 | - def parse(text): | |
44 | + def _parse(text): | |
39 | 45 | return frozenset(text) |
40 | 46 | |
41 | 47 | @staticmethod |
42 | - def from_str(text): | |
43 | - return Event(Event.parse(text)) | |
48 | + def parse(text): | |
49 | + """Convert a string to an event. | |
50 | + | |
51 | + Each letter in the string represents a literal. | |
52 | + """ | |
53 | + return Event(Event._parse(text)) | |
44 | 54 | |
45 | 55 | |
46 | 56 | def __init__(self, literals): |
47 | 57 | """Instantiate from a (frozen) set of literals. |
48 | 58 | For example: e = Event(frozenset("abc")).""" |
49 | - self._literals = literals | |
59 | + self._literals = frozenset(literals) | |
50 | 60 | |
51 | 61 | |
52 | 62 | def literals(self): |
... | ... | @@ -55,56 +65,74 @@ class Event: |
55 | 65 | |
56 | 66 | def __iter__(self): |
57 | 67 | return self._literals.__iter__() |
58 | - | |
59 | - | |
60 | - def co(self): | |
61 | - """Negation is case based: A = not a; a = not A.""" | |
62 | - return Event(x.swapcase() for x in self._literals) | |
63 | - | |
64 | 68 | |
65 | 69 | @cache |
66 | 70 | def is_consistent(self): |
71 | + """True if this event is consistent.""" | |
67 | 72 | return all(x.swapcase() not in self._literals for x in self._literals) |
68 | 73 | |
69 | - def __hash__(self) -> int: | |
70 | - return self._literals.__hash__() | |
71 | 74 | |
75 | + def co(self): | |
76 | + """Negation of this event. | |
77 | + | |
78 | + Negation is case based: A = not a; a = not A.""" | |
79 | + return Event(x.swapcase() for x in self._literals) | |
72 | 80 | |
73 | - def __eq__(self, other): | |
74 | - return self._literals.__eq__(other._literals) | |
81 | + def invert(self): | |
82 | + """Negation of this event. | |
75 | 83 | |
84 | + See the method "co" | |
85 | + """ | |
86 | + return self.co() | |
76 | 87 | |
77 | 88 | def __repr__(self) -> str: |
78 | - return ''.join(str(x) for x in sorted(self._literals)) | |
89 | + return ''.join(str(x) for x in sorted(self._literals)) if len(self._literals) > 0 else '0' | |
79 | 90 | |
80 | - def invert(self): | |
81 | - return self.co() | |
91 | + def latex(self): | |
92 | + """LaTeX representation of this even. | |
93 | + | |
94 | + Negation is represented by overline and the empty event by | |
95 | + | |
96 | + """ | |
97 | + return ''.join( | |
98 | + (str(x) if x.islower() else f"\co{{{x.lower()}}}") \ | |
99 | + for x in sorted(self._literals) | |
100 | + ) if len(self._literals) > 0 else "\set{}" | |
101 | + | |
102 | + def __hash__(self) -> int: | |
103 | + return self._literals.__hash__() | |
82 | 104 | |
83 | 105 | |
84 | 106 | def __eq__(self, other): |
107 | + """Event equality test.""" | |
85 | 108 | return self._literals.__eq__(other._literals) |
86 | 109 | |
87 | 110 | def __or__(self, other): |
111 | + """Event union operation.""" | |
88 | 112 | return Event(self._literals | other._literals) |
89 | 113 | |
90 | - | |
91 | 114 | def __le__(self, other): |
115 | + """Event subset test.""" | |
92 | 116 | return self._literals.__le__(other._literals) |
93 | 117 | |
94 | 118 | |
95 | 119 | def __lt__(self, other): |
120 | + """Event strict subset test.""" | |
96 | 121 | return self._literals.__lt__(other._literals) |
97 | 122 | |
98 | 123 | |
99 | 124 | def __ne__(self, other): |
125 | + """Event not-equal test.""" | |
100 | 126 | return self._literals.__ne__(other._literals) |
101 | 127 | |
102 | 128 | |
103 | 129 | def __ge__(self, other): |
130 | + """Event superset test.""" | |
104 | 131 | return self._literals.__ge__(other._literals) |
105 | 132 | |
106 | 133 | |
107 | 134 | def __gt__(self, other): |
135 | + """Event strict superset test.""" | |
108 | 136 | return self._literals.__gt__(other._literals) |
109 | 137 | |
110 | 138 | |
... | ... | @@ -112,87 +140,120 @@ class Lattice: |
112 | 140 | |
113 | 141 | @staticmethod |
114 | 142 | def parse(d): |
143 | + """Input stable models. | |
144 | + | |
145 | + The input format is a dictionary associating a stable model in string form to an weight. | |
146 | + | |
147 | + For example: | |
148 | + | |
149 | + input_dict = { | |
150 | + "A": 0.3, | |
151 | + "ab": 0.2, | |
152 | + "ac": 0.5 | |
153 | + } | |
154 | + smodels = Lattice.parse(input_dict) | |
155 | + """ | |
115 | 156 | result = dict() |
116 | 157 | for k, v in d.items(): |
117 | - key = Event.from_str(k) | |
158 | + key = Event.parse(k) | |
118 | 159 | result[key] = v |
119 | 160 | return result |
120 | 161 | |
121 | 162 | |
122 | 163 | @staticmethod |
123 | - def close_literals(smodels): | |
124 | - base_lits = list(accumulate(smodels, func=operator.or_))[-1] | |
164 | + def close_literals(events): | |
165 | + """Closed set of literals entailed by a set of events. | |
166 | + | |
167 | + Includes the literals in the set of events and any missing negation.""" | |
168 | + base_lits = list(accumulate(events, func=operator.or_))[-1] | |
125 | 169 | lits = set() |
126 | 170 | for x in base_lits.literals(): |
127 | 171 | lits.add(x) |
128 | 172 | lits.add(x.swapcase()) |
129 | - return lits | |
173 | + return sorted(lits) | |
130 | 174 | |
131 | 175 | def __init__(self, smodels_dict): |
132 | - """Create base for Events Lattice.""" | |
176 | + """Create an Events lattice.""" | |
133 | 177 | self._smodels = smodels_dict |
134 | 178 | self._literals = Lattice.close_literals(self._smodels.keys()) |
135 | 179 | |
136 | 180 | def literals(self): |
181 | + """The literals in this lattice.""" | |
137 | 182 | return self._literals |
138 | 183 | |
184 | + @cache | |
139 | 185 | def stable_models(self): |
140 | - return list(map(set, self._smodels.keys())) | |
186 | + """The stable models that generate this lattice.""" | |
187 | + return self._smodels.keys() | |
141 | 188 | |
142 | - @cache | |
143 | - def lower_bound(self, event): | |
144 | - return list(set(filter(lambda sm: sm <= event, self._smodels))) | |
189 | + #@cache | |
190 | + def events(self): | |
191 | + """All the events of this lattice.""" | |
192 | + return chain.from_iterable(map(Event, combinations(self._literals, r)) for r in range(len(self._literals)+1)) | |
145 | 193 | |
146 | 194 | @cache |
147 | - def upper_bound(self, event): | |
148 | - return list(set(filter(lambda sm: event <= sm, self._smodels))) | |
195 | + def stable_core(self, event): | |
196 | + """The stable core of an event in this lattice.""" | |
197 | + return set(filter(lambda sm: sm <= event or event <= sm, self.stable_models())) | |
198 | + | |
199 | + # @cache | |
200 | + # def event_class(self, event): | |
201 | + # """The equivalence class of an event.""" | |
202 | + # return EventsClass(self.stable_core(event), self) | |
149 | 203 | |
204 | + @cache | |
205 | + def classes(self): | |
206 | + """The classes of this lattice. | |
207 | + | |
208 | + Each class is presented as a key:value pair where the "key" is the stable core of the elements in "value".""" | |
209 | + map_ev_classes = [(e, tuple(self.stable_core(e))) for e in self.events() if e.is_consistent()] | |
210 | + groups = dict() | |
211 | + for e,c in map_ev_classes: | |
212 | + if c in groups.keys(): | |
213 | + groups[c].add(e) | |
214 | + else: | |
215 | + groups[c] = set([e]) | |
216 | + inconsistent = list(e for e in self.events() if not e.is_consistent()) | |
217 | + inconsistent_repr = inconsistent[0] | |
218 | + groups[(inconsistent_repr,)] = set(inconsistent) | |
219 | + return groups | |
150 | 220 | |
151 | - def event_class(self, event): | |
152 | - return EventsClass( | |
153 | - self.upper_bound(event), | |
154 | - self.lower_bound(event), | |
155 | - self) | |
156 | 221 | |
157 | 222 | def related(self, u, v): |
223 | + """Tests if two events are related.""" | |
158 | 224 | u_consistent = u.is_consistent() |
159 | 225 | v_consistent = v.is_consistent() |
160 | 226 | if u_consistent and (u_consistent == v_consistent): |
161 | - return \ | |
162 | - self.lower_bound(u) == self.lower_bound(v) and \ | |
163 | - self.upper_bound(u) == self.upper_bound(v) | |
227 | + return self.stable_core(u) == self.stable_core(v) | |
164 | 228 | else: |
165 | 229 | return u_consistent == v_consistent |
166 | 230 | |
167 | - def factors(self, event): | |
168 | - return [self.lower_bound(event), self.upper_bound(event)] | |
169 | - | |
170 | - def propagated_value(self, event:Event, | |
171 | - lower_op=sum_op, | |
172 | - upper_op=prod_op): | |
231 | + def extended_value(self, event:Event, | |
232 | + op=prod_op): | |
233 | + """TODO: well...""" | |
173 | 234 | value = 0 |
174 | - | |
235 | + # | |
236 | + # INCONSISTENT EVENTS | |
237 | + # | |
175 | 238 | if not event.is_consistent(): |
176 | 239 | return value |
177 | - | |
178 | - lb = self.lower_bound(event) | |
179 | - len_lb = len(lb) | |
180 | - if len_lb > 1: | |
181 | - value = lower_op(map(lambda sm: self._smodels[sm], lb)) | |
182 | - elif len_lb == 1: | |
183 | - value = self._smodels[lb[0]] | |
240 | + # | |
241 | + # CONSISTENT EVENTS | |
242 | + # | |
243 | + score = self.stable_core(event) | |
244 | + len_score = len(score) | |
245 | + # CONSISTENT, INDEPENDENT | |
246 | + if len_score == 0: | |
247 | + value = 0 | |
248 | + elif len_score == 1: | |
249 | + value = self._smodels[score[0]] | |
184 | 250 | else: |
185 | - ub = self.upper_bound(event) | |
186 | - len_ub = len(ub) | |
187 | - if len_ub > 1: | |
188 | - value = upper_op(map(lambda sm: self._smodels[sm], ub)) | |
189 | - elif len_ub == 1: | |
190 | - value = self._smodels[ub[0]] | |
251 | + value = op(map(lambda sm: self._smodels[sm], score)) | |
191 | 252 | |
192 | 253 | return value |
193 | 254 | |
194 | 255 | def __repr__(self): |
195 | - smodels_repr = ',\n\t\t'.join(f"{Event.from_str(k)}: {v:>5}" for k,v in self._smodels.items()) | |
256 | + smodels_repr = ',\n\t\t'.join(f"{k}: {v:<}" for k,v in self._smodels.items()) | |
196 | 257 | lits_repr = ','.join(sorted(self._literals)) |
197 | 258 | |
198 | 259 | return "{\n" +\ |
... | ... | @@ -200,19 +261,41 @@ class Lattice: |
200 | 261 | f"\t'literals': {{ {lits_repr} }} \n" +\ |
201 | 262 | "}" |
202 | 263 | |
203 | - | |
204 | - | |
205 | -class EventsClass: | |
206 | - def __init__(self, upper, lower, lattice:Lattice): | |
207 | - self._upper = upper | |
208 | - self._lower = lower | |
209 | - self._lattice = lattice | |
210 | - | |
211 | - def __repr__(self): | |
212 | - upper_repr = "" if len(self._upper) == 0 else ",".join(str(x) for x in self._upper) | |
213 | - lower_repr = "" if len(self._lower) == 0 else ",".join(str(x) for x in self._lower) | |
214 | - return f"<{upper_repr}|{lower_repr}>" | |
215 | - | |
216 | - def __contains__(self, event:Event): | |
217 | - return self.lattice.lower_bound(event) == self._lower and \ | |
218 | - self.lattice.upper_bound(event) == self._upper | |
219 | 264 | \ No newline at end of file |
265 | +# class EventsClass: | |
266 | +# def __init__(self, core, lattice:Lattice): | |
267 | +# self._core = core | |
268 | +# self._lattice = lattice | |
269 | + | |
270 | +# def __repr__(self): | |
271 | +# core_repr = "" if len(self._core) == 0 else ",".join(str(x) for x in self._core) | |
272 | +# return f"<{core_repr}>" | |
273 | + | |
274 | +# def __contains__(self, event:Event): | |
275 | +# return self.lattice.stable_core(event) == self._core | |
276 | + | |
277 | +if __name__ == "__main__": | |
278 | + def zoom_event(event_str, lattice): | |
279 | + event = Event.parse(event_str) | |
280 | + event_class = lattice.event_class(event) | |
281 | + propagated = lattice.extended_value( | |
282 | + event) | |
283 | + | |
284 | + print( | |
285 | + f"Event: {event}\n\tClass: {event_class} \n\tValue: {propagated}") | |
286 | + | |
287 | + smodels = Lattice.parse({ | |
288 | + "A": 2, | |
289 | + "ab": 3, | |
290 | + "ac": 5 | |
291 | + }) | |
292 | + | |
293 | + lattice = Lattice(smodels) | |
294 | + | |
295 | + ev_classes = lattice.classes() | |
296 | + for k,g in ev_classes.items(): | |
297 | + print(f"{tuple(s.latex() for s in k)} {set(e.latex() for e in g)}") | |
298 | + # zoom_event("abc", lattice) | |
299 | + # zoom_event("a", lattice) | |
300 | + # zoom_event("b", lattice) | |
301 | + # zoom_event("bc", lattice) | |
302 | + # zoom_event("ac", lattice) | |
220 | 303 | \ No newline at end of file | ... | ... |
students/amartins/tarefas/.ipynb_checkpoints/Untitled-checkpoint.ipynb
0 โ 100644
students/amartins/tarefas/.ipynb_checkpoints/Untitled1-checkpoint.ipynb
0 โ 100644
students/amartins/tarefas/.ipynb_checkpoints/tarefa1b-checkpoint.py
0 โ 100644
... | ... | @@ -0,0 +1,35 @@ |
1 | +import bnlearn as bn | |
2 | +import networkx as nx | |
3 | +import pydot | |
4 | +from networkx.drawing.nx_pydot import graphviz_layout | |
5 | + | |
6 | +asia = bn.import_DAG("asia2.bif") | |
7 | +model = asia['model'] | |
8 | + | |
9 | +# DiGraph do networkx | |
10 | +G = nx.DiGraph() | |
11 | + | |
12 | +for node in model.nodes: | |
13 | + G.add_node(node) | |
14 | + | |
15 | +for edge in model.edges: | |
16 | + G.add_edge(edge[0], edge[1]) | |
17 | + | |
18 | +# objeto pydot | |
19 | +dot = pydot.Dot(graph_type='digraph') | |
20 | + | |
21 | +for node in model.nodes: | |
22 | + dot.add_node(pydot.Node(node)) | |
23 | + | |
24 | +for edge in model.edges: | |
25 | + dot.add_edge(pydot.Edge(edge[0], edge[1])) | |
26 | + | |
27 | +# defina o layout do grafo | |
28 | +pos = graphviz_layout(G, prog='dot') | |
29 | + | |
30 | +# desenhe o grafo usando o networkx | |
31 | +nx.draw(G, pos, with_labels=True) | |
32 | + | |
33 | +# renderize o grafo com o pydot | |
34 | +graph = pydot.graph_from_dot_data(dot.to_string())[0] | |
35 | +graph.write_png('graph_asia2.png') | ... | ... |
... | ... | @@ -0,0 +1,67 @@ |
1 | +# Notas com Alice Martins | |
2 | + | |
3 | +## 2023-05-04 | |
4 | + | |
5 | +### Problemas | |
6 | + | |
7 | +#### Tarefa 1A | |
8 | + | |
9 | +1. Estรก a contar os nรณs "in" e os nรณs "out" ao contrรกrio, certo? `len(children)` diz quantas arestas saem de `x`. | |
10 | +2. Em | |
11 | + ```python | |
12 | + if len(parents) != 0: | |
13 | + asc += 1 | |
14 | + if len(children) != 0: | |
15 | + des += 1 | |
16 | + ``` | |
17 | + deve ser | |
18 | + ```python | |
19 | + if len(parents) != 0: | |
20 | + des += 1 | |
21 | + if len(children) != 0: | |
22 | + asc += 1 | |
23 | + ``` | |
24 | + porque o nรณ `x` รฉ (mais) um descendente se tem ascendentes (e igualmente para ascendente). | |
25 | + | |
26 | +#### Tarefa 1B | |
27 | + | |
28 | +1. Nรฃo deve misturar o cรณdigo para definir o grafo `G` com o cรณdigo para o grafo `dot`. **Exceto** se quiser percorrer apenas uma vez `model.nodes` e `model.edges`. | |
29 | + | |
30 | +### Sugestรตes | |
31 | + | |
32 | +- **Use sempre, e sรณ, o inglรชs no seu cรณdigo**, nรฃo sรณ porque nรฃo se podem usar acentos, como `nรณs_in`, mas tambรฉm porque misturar portuguรชs com inglรชs fica estranho (isto รฉ, _feio_!). ร melhor `nodes_in` do que `nos_in`. | |
33 | +- Use nomes descritivos nas suas variรกveis: `node` em vez de `x`. | |
34 | +- Em vez de `asia = bn.import_DAG("asia2.bif")` talvez `dag = bn.import_DAG("asia2.bif")` seja melhor (**porquรช?**) | |
35 | +- O cรณdigo tambรฉm fica mais simples se usar "f-strings": Em vez de | |
36 | + ```python | |
37 | + print("Nรบmero de nรณs:", len(nos)) | |
38 | + ``` | |
39 | + use | |
40 | + ```python | |
41 | + print(f"Nรบmero de nรณs: {len(nos)}") | |
42 | + ``` | |
43 | +### Desafios | |
44 | + | |
45 | +1. **Torne o seu cรณdigo geral.** | |
46 | + 1. Coloque a parte essencial da tarefa 1A numa funรงรฃo, `summary_dag(filename)`, que tem argumento uma `string` com o nome do ficheiro e devolve um `dict` com chaves `dag_file`, `nodes`, `count_parents`, `count_children`, `count_in_edges`, `count_out_edges`. | |
47 | + 2. Use uma funรงรฃo `summary_str(d)` que tem argumento um `dict` como acima e devolve uma `string` com as perguntas e as respostas "bem formatadas". Por exemplo: | |
48 | + ```text | |
49 | + DAG file: asia2.bif | |
50 | + Number of nodes: 8 | |
51 | + Number of parents: 6 | |
52 | + Number of children: 6 | |
53 | + Average in-degree: 1.0 | |
54 | + Average out-degree: 1.0 | |
55 | + Nodes: | |
56 | + asia | |
57 | + tub | |
58 | + ... | |
59 | + ``` | |
60 | + 3. Por fim, combine as duas funรงรตes: | |
61 | + ```python | |
62 | + summary = summary_dag("asia2.bif") | |
63 | + message = summary_str(summary) | |
64 | + print(message) | |
65 | + ``` | |
66 | + 4. Coloque a parte essencial da tarefa 1B em funรงรตes `show_dag(model)` e `save_dag(model, target_filename)`. | |
67 | +2. **A biblioteca `bnlearn` รฉ excessiva para estas tarefas.** Nรฃo sรณ precisa de vรกrias dependรชncias irrelevantes para o que pretendemos, por exemplo o `pytorch`, como demora imenso tempo a ler o ficheiro. _Procure uma alternativa mais simples._ (**n.b.** nรฃo sei se existe!) | |
0 | 68 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,81 @@ |
1 | +from pgmpy.readwrite import BIFReader | |
2 | +import networkx as nx | |
3 | +import pydot | |
4 | +from networkx.drawing.nx_pydot import graphviz_layout | |
5 | + | |
6 | +def summary_dag(filename): | |
7 | + file = BIFReader(filename) | |
8 | + model = file.get_model() # Cria um objeto BayesianModel | |
9 | + nodes = model.nodes() | |
10 | + | |
11 | + asc = 0 | |
12 | + des = 0 | |
13 | + nodes_in = 0 | |
14 | + nodes_out = 0 | |
15 | + | |
16 | + for x in nodes: | |
17 | + # Obtem os nรณs pais e filhos de cada nรณs | |
18 | + parents = model.get_parents(x) | |
19 | + children = model.get_children(x) | |
20 | + | |
21 | + if len(parents) != 0: | |
22 | + des += 1 | |
23 | + if len(children) != 0: | |
24 | + asc += 1 | |
25 | + nodes_in += len(children) | |
26 | + nodes_out += len(parents) | |
27 | + | |
28 | + return {'dag_file': filename, 'nodes': nodes, 'count_parents': des, 'count_children': asc, 'count_in_edges': nodes_in, 'count_out_edges': nodes_out} | |
29 | + | |
30 | +def summary_str(d): | |
31 | + s = "DAG file: " + d["dag_file"] + "\n" | |
32 | + s += " Number of nodes: " + str(len(d["nodes"])) + "\n" | |
33 | + s += " Number of parents: " + str(d["count_parents"]) + "\n" | |
34 | + s += " Number of children: " + str(d["count_children"]) + "\n" | |
35 | + s += " Average in-degree: " + str(d["count_in_edges"]/len(d["nodes"])) + "\n" | |
36 | + s += " Average out-degree: " + str(d["count_out_edges"]/len(d["nodes"])) + "\n" | |
37 | + s += " Nodes:" + "\n" | |
38 | + nodes = d["nodes"] | |
39 | + for x in nodes: | |
40 | + s += " " + str(x) + "\n" | |
41 | + return s | |
42 | + | |
43 | +def show_dag(model): | |
44 | + G = nx.DiGraph() | |
45 | + for node in model.nodes: | |
46 | + G.add_node(node) | |
47 | + for edge in model.edges: | |
48 | + G.add_edge(edge[0], edge[1]) | |
49 | + # objeto pydot | |
50 | + dot = pydot.Dot(graph_type='digraph') | |
51 | + for node in model.nodes: | |
52 | + dot.add_node(pydot.Node(node)) | |
53 | + for edge in model.edges: | |
54 | + dot.add_edge(pydot.Edge(edge[0], edge[1])) | |
55 | + # defina o layout do grafo | |
56 | + pos = graphviz_layout(G, prog='dot') | |
57 | + # desenhe o grafo usando o networkx | |
58 | + nx.draw(G, pos, with_labels=True) | |
59 | + | |
60 | +def save_dag(model, target_filename): | |
61 | + G = nx.DiGraph() | |
62 | + for node in model.nodes: | |
63 | + G.add_node(node) | |
64 | + for edge in model.edges: | |
65 | + G.add_edge(edge[0], edge[1]) | |
66 | + # objeto pydot | |
67 | + dot = pydot.Dot(graph_type='digraph') | |
68 | + for node in model.nodes: | |
69 | + dot.add_node(pydot.Node(node)) | |
70 | + for edge in model.edges: | |
71 | + dot.add_edge(pydot.Edge(edge[0], edge[1])) | |
72 | + # defina o layout do grafo | |
73 | + pos = graphviz_layout(G, prog='dot') | |
74 | + # renderize o grafo com o pydot | |
75 | + graph = pydot.graph_from_dot_data(dot.to_string())[0] | |
76 | + graph.write_png(target_filename) | |
77 | + | |
78 | + | |
79 | +summary = summary_dag("asia2.bif") | |
80 | +message = summary_str(summary) | |
81 | +print(message) | |
0 | 82 | \ No newline at end of file | ... | ... |
students/amartins/tarefas/tarefa1a.py
... | ... | @@ -32,7 +32,7 @@ for x in nos: |
32 | 32 | print("Nรณs ascendentes: ", asc) |
33 | 33 | print("Nรณs descendentes: ", des) |
34 | 34 | # resposta ร pergunta "qual รฉ o nรบmero mรฉdio de arestas "in"? e "out"?" |
35 | -nos_in = nos_in/len(nos) | |
36 | -nos_out = nos_out/len(nos) | |
35 | +nos_in = float(nos_in/len(nos)) | |
36 | +nos_out = float(nos_out/len(nos)) | |
37 | 37 | print("Nรบmero mรฉdio de arestas in: ", nos_in) |
38 | 38 | print("Nรบmero mรฉdio de arestas out: ", nos_out) |
39 | 39 | \ No newline at end of file | ... | ... |
text/paper_01/pre-paper.pdf
No preview for this file type
text/paper_01/pre-paper.tex
... | ... | @@ -246,6 +246,8 @@ The stable models $ab, ac$ from \cref{running.example} result from the clause $b |
246 | 246 | |
247 | 247 | The diagram in \cref{F:stableexample} illustrates the problem of extending probabilities from total choice nodes to stable models and then to general events in a \emph{node-wise} process. This quickly leads to coherence problems concerning probability, with no clear systematic approach --- Instead, weight extension can be based in the relation an event has with the stable models. |
248 | 248 | |
249 | +\subsection{An Equivalence Relation}\label{subsec:equivalence.relation} | |
250 | + | |
249 | 251 | Given an ASP specification |
250 | 252 | % DONE: {\bruno This should be defined somewhere (maybe in the introduction).} |
251 | 253 | \remark{{\bruno Introduce also the sets mentioned below}}{how?} |
... | ... | @@ -277,24 +279,24 @@ This focus on the \acp{SM} leads to the following definition: |
277 | 279 | % \lset{e} = \set{s \in \fml{S} \given e \supseteq s}, \label{eq:lset} |
278 | 280 | % \end{equation} |
279 | 281 | % \begin{equation} |
280 | - % \stablecore{e} = \uset{e} \cup \lset{e} \label{eq:xset} | |
282 | + % \stablecore{e} = \uset{e} \cup \lset{e} \label{def:stable.core} | |
281 | 283 | % \end{equation} |
282 | 284 | \begin{equation} |
283 | - \stablecore{e} := \set{s \in \fml{S} \given e \subseteq s \vee s \subseteq e} \label{eq:xset} | |
285 | + \stablecore{e} := \set{s \in \fml{S} \given e \subseteq s \vee s \subseteq e} \label{eq:stable.core} | |
284 | 286 | \end{equation} |
285 | 287 | |
286 | 288 | \end{definition} |
287 | 289 | |
288 | 290 | We now define an equivalence relation, $\sim$, so that two events are related if they are either both inconsistent or both consistent with the same stable core. |
289 | 291 | |
290 | -\begin{definition}\label{D:equiv.rel} | |
292 | +\begin{definition}\label{def:equiv.rel} | |
291 | 293 | For a given specification, let $u, v \in \fml{E}$. The equivalence relation $\sim$ is defined by |
292 | 294 | \begin{equation} |
293 | - u \sim v :\iff u,v \not\in\fml{W} \vee \del{u,v \in \fml{W} \wedge \stablecore{u} = \stablecore{v}}.\label{eq:rel.events} | |
295 | + u \sim v :\iff u,v \not\in\fml{W} \vee \del{u,v \in \fml{W} \wedge \stablecore{u} = \stablecore{v}}.\label{eq:equiv.rel} | |
294 | 296 | \end{equation} |
295 | 297 | \end{definition} |
296 | 298 | |
297 | -Observe that the minimality of stable models implies that, in \cref{eq:xset}, either $e$ is a stable model or one of $e \subseteq s, s \subseteq e$ is never true. | |
299 | +Observe that the minimality of stable models implies that, in \cref{def:stable.core}, either $e$ is a stable model or one of $e \subseteq s, s \subseteq e$ is never true. | |
298 | 300 | % |
299 | 301 | % \begin{definition}\label{def:smodel.events} |
300 | 302 | % For $\set{s_1, \ldots, s_n} \subseteq \fml{S}$ define |
... | ... | @@ -321,21 +323,21 @@ This relation defines a partition of the events space, where each class holds a |
321 | 323 | \set{u \in \fml{W} \given \stablecore{u} = \stablecore{e}} &\text{if~} e \in \fml{W}, \\ |
322 | 324 | % \lclass{\uset{e}} &\text{if~} \uset{e} \not= \emptyset, \\ |
323 | 325 | % \uclass{\lset{e}} &\text{otherwise}. |
324 | - \end{cases} | |
326 | + \end{cases}\label{eq:event.class} | |
325 | 327 | \end{equation} |
326 | 328 | |
327 | -The stable core defines a \emph{canonical} representative of each class: | |
328 | -\begin{theorem} | |
329 | - Let $e\in\fml{E}$ and $\stablecore{e} = \set{s_1, \ldots, s_n} \subseteq \fml{S}$. Then | |
330 | - \begin{equation} | |
331 | - \class{e} = \class{s_1 \cup \cdots \cup s_n}. | |
332 | - \end{equation} | |
333 | - We simplify the notation with $\class{s_1, \ldots, s_n} := \class{s_1 \cup \cdots \cup s_n}$. | |
334 | - \todo{This only works for consistent $s_1, \ldots, s_n$: $\set{\set{}} = \class{\co{a}, ab, ac} \not= \class{a\co{a}bc} = \inconsistent$.} | |
335 | -\end{theorem} | |
336 | -\begin{proof} | |
337 | -\todo{tbd} | |
338 | -\end{proof} | |
329 | +% The stable core defines a \emph{canonical} representative of each class: | |
330 | +% \begin{theorem} | |
331 | +% Let $e\in\fml{E}$ and $\stablecore{e} = \set{s_1, \ldots, s_n} \subseteq \fml{S}$. Then | |
332 | +% \begin{equation} | |
333 | +% \class{e} = \class{s_1 \cup \cdots \cup s_n}. | |
334 | +% \end{equation} | |
335 | +% We simplify the notation with $\class{s_1, \ldots, s_n} := \class{s_1 \cup \cdots \cup s_n}$. | |
336 | +% \todo{This only works for consistent $s_1, \ldots, s_n$: $\set{\set{}} = \class{\co{a}, ab, ac} \not= \class{a\co{a}bc} = \inconsistent$.} | |
337 | +% \end{theorem} | |
338 | +% \begin{proof} | |
339 | +% \todo{tbd} | |
340 | +% \end{proof} | |
339 | 341 | |
340 | 342 | The subsets of the stable models, together with $\inconsistent$, form a set of representatives. Consider again Example~\ref{running.example}. As previously mentioned, the stable models are $\fml{S} = \co{a}, ab, ac$ so the quotient set of this relation is $\class{\fml{E}}:$ |
341 | 343 | \begin{equation} |
... | ... | @@ -388,19 +390,21 @@ For example, |
388 | 390 | % \item The extended probability \emph{events} are the \emph{classes}. |
389 | 391 | \end{itemize} |
390 | 392 | |
393 | +\subsection{From Total Choices to Events}\label{subsec:from.tchoices.to.events} | |
394 | + | |
391 | 395 | \todo{Check adaptation} Our path to set a probability measure on $\fml{E}$ has two phases: |
392 | 396 | \begin{itemize} |
393 | 397 | \item Extending the probabilities, \emph{as weights}, of the total choices to events. |
394 | 398 | \item Normalization of the weights. |
395 | 399 | \end{itemize} |
396 | 400 | |
397 | -The ``extension'' phase, traced by equations (\ref{eq:prob.total.choice}) and (\ref{eq:weight.tchoice} --- \ref{eq:weight.events}), starts with the weight (probability) of total choices, $\pw{c} = \pr{C = c}$, expands it to stable models, $\pw{s}$, and then, within the equivalence relation from Equation \eqref{eq:rel.events}, to (general) events, $\pw{e}$, including (consistent) worlds. | |
401 | +The ``extension'' phase, traced by equations (\ref{eq:prob.total.choice}) and (\ref{eq:weight.tchoice} --- \ref{eq:weight.events}), starts with the weight (probability) of total choices, $\pw{c} = \pr{C = c}$, expands it to stable models, $\pw{s}$, and then, within the equivalence relation from Equation \eqref{eq:equiv.rel}, to (general) events, $\pw{e}$, including (consistent) worlds. | |
398 | 402 | |
399 | 403 | \begin{description} |
400 | 404 | % |
401 | 405 | \item[Total Choices.] Using \eqref{eq:prob.total.choice}, this case is given by |
402 | 406 | \begin{equation} |
403 | - \pw{c} = \pr{C = c}= \prod_{a\in c} p \prod_{a \not\in c} \co{p} | |
407 | + \pw{c} := \pr{C = c}= \prod_{a\in c} p \prod_{a \not\in c} \co{p} | |
404 | 408 | \label{eq:weight.tchoice} |
405 | 409 | \end{equation} |
406 | 410 | % |
... | ... | @@ -409,7 +413,7 @@ The ``extension'' phase, traced by equations (\ref{eq:prob.total.choice}) and (\ |
409 | 413 | Given a stable model $s \in \fml{S}$, a total choice $c$, and variables/values $\theta_{s,c} \in \intcc{0, 1}$, |
410 | 414 | \begin{equation} |
411 | 415 | \pw{s, c} := \begin{cases} |
412 | - \theta_{s,c} & \text{if~} s \in S_c\cr | |
416 | + \pw{c}\theta_{s,c} & \text{if~} s \in S_c\cr | |
413 | 417 | 0&\text{otherwise} |
414 | 418 | \end{cases} |
415 | 419 | \label{eq:weight.stablemodel} |
... | ... | @@ -425,29 +429,141 @@ The ``extension'' phase, traced by equations (\ref{eq:prob.total.choice}) and (\ |
425 | 429 | \end{equation} |
426 | 430 | \item \textbf{Independent Class.} A world that neither contains nor is contained in a stable model describes a case that, according to the specification, should never be observed. So the respective weight is set to zero: |
427 | 431 | \begin{equation} |
428 | - \pw{\emptyset, c} := 0. | |
432 | + \pw{\class{e}, c} := 0,~\text{if}~\stablecore{e} = \emptyset. | |
429 | 433 | \label{eq:weight.class.independent} |
430 | 434 | \end{equation} |
431 | 435 | \item \textbf{Other Classes.} The extension must be constant within a class, its value should result from the elements in the stable core, and respect the assumption \ref{assumption:smodels.independence}: |
432 | 436 | \begin{equation} |
433 | - \pw{\stablecore{s_1, \ldots, s_n}, c} := \prod_{k}\pw{s_k, c}. | |
434 | - \label{eq:weight.class.upper} | |
437 | + \pw{\class{e}, c} := \prod_{k=1}^{n}\pw{s_k, c},~\text{if}~\stablecore{e} = \set{s_1, \ldots, s_n}. | |
438 | + \label{eq:weight.class.other} | |
435 | 439 | \end{equation} |
436 | 440 | \end{itemize} |
437 | 441 | % |
438 | 442 | \item[Events.] \label{item:event.cases} Each (general) event $e$ is in the class defined by its stable core, $\stablecore{e}$. So, we set: |
439 | 443 | \begin{equation} |
440 | - \pw{e, c} := \pw{\stablecore{e}, c}. | |
444 | + \pw{e, c} := \pw{\class{e}, c}. | |
441 | 445 | \label{eq:weight.events} |
442 | 446 | \end{equation} |
447 | + and | |
448 | + \begin{equation} | |
449 | + \pw{e} := \sum_{c\in\fml{C}} \pw{e, c}. | |
450 | + \label{eq:weight.events.unconditional} | |
451 | + \end{equation} | |
443 | 452 | \end{description} |
444 | 453 | |
445 | 454 | % PARAMETERS FOR UNCERTAINTY |
455 | +\begin{itemize} | |
456 | + \item \todo{Remark that $\pw{\inconsistent, c} = 0$ is independent of the total choice.} | |
457 | + \item \todo{Remark the example $bc$ for equation \ref{eq:weight.class.independent}.} | |
458 | + \item \todo{Remark that equation \eqref{eq:weight.events.unconditional}, together with observations, can be used to learn about the \emph{initial} probabilities of the atoms, in the specification.} | |
459 | +\end{itemize} | |
446 | 460 | |
447 | -Equation \eqref{eq:weight.stablemodel} expresses the \emph{specification's} lack of knowledge about the weight assignment, when a single total choice entails more than one stable model. In this case, how to distribute the respective weights? Our \replace{answer}{proposal} to \replace{}{address} this problem consists in assigning an unknown weight, $\theta_{s,c}$, conditional {\bruno depending???} on the total choice, $c$, to each stable model $s$. This approach allows the expression of an unknown quantity and future estimation, given observed data. | |
461 | + | |
462 | +The $\theta_{s,c}$ parameters in equation \eqref{eq:weight.stablemodel} express the \emph{specification's} lack of knowledge about the weight assignment, when a single total choice entails more than one stable model. In that case, how to distribute the respective weights? Our \replace{answer}{proposal} to \replace{}{address} this problem consists in assigning an unknown weight, $\theta_{s,c}$, conditional {\bruno depending???} on the total choice, $c$, to each stable model $s$. This approach allows the expression of an unknown quantity and future estimation, given observed data. | |
448 | 463 | |
449 | 464 | % SUPERSET |
450 | -Equation \eqref{eq:weight.class.upper} results from conditional independence of stable models. | |
465 | +Equation \eqref{eq:weight.class.other} results from conditional independence of stable models. | |
466 | + | |
467 | + | |
468 | +\section{Developed Examples} | |
469 | + | |
470 | +\subsection{The SBF Example} | |
471 | + | |
472 | +We continue with the specification from Equation \eqref{eq:example.1}. | |
473 | + | |
474 | +\textbf{Total Choices.} The total choices, and respective stable models, are | |
475 | +\begin{center} | |
476 | + \begin{tabular}{l|r|r} | |
477 | + Total Choice ($c$) & $\pw{c}$ & Stable Models ($s$)\\ | |
478 | + \hline | |
479 | + $a$ & $0.3$ & $ab$ and $ac$.\\ | |
480 | + $\co{a} = \neg a$ & $\co{0.3} = 0.7$ & $\co{a}$. | |
481 | + \end{tabular} | |
482 | +\end{center} | |
483 | + | |
484 | +\textbf{Stable Models.} The weights from equation \eqref{eq:weight.stablemodel} can be tabulated by a matrix where a column represents a total choice and a row a stable model. We get: | |
485 | +\begin{multline*} | |
486 | + \pw{s, c} = | |
487 | + \begin{pmatrix} | |
488 | + \pw{ab, a} & \pw{ab, \co{a}} \\ | |
489 | + \pw{ac, a} & \pw{ac, \co{a}} \\ | |
490 | + \pw{\co{a}, a} & \pw{\co{a}, \co{a}} | |
491 | + \end{pmatrix} | |
492 | + = | |
493 | + \begin{pmatrix} | |
494 | + \pw{a} \theta_{ab, a} & \pw{\co{a}} \theta_{ab, \co{a}} \\ | |
495 | + \pw{a} \theta_{ac, a} & \pw{\co{a}} \theta_{ac, \co{a}} \\ | |
496 | + \pw{a} \theta_{\co{a}, a} & \pw{\co{a}} \theta_{\co{a}, \co{a}} | |
497 | + \end{pmatrix} | |
498 | + \\ | |
499 | + = | |
500 | + \begin{pmatrix} | |
501 | + 0.3 \times \theta_{ab, a} & 0.7 \times 0.0 \\ | |
502 | + 0.3 \times \theta_{ac, a} & 0.7 \times 0.0 \\ | |
503 | + 0.3 \times 0.0 & 0.7 \times 1.0 | |
504 | + \end{pmatrix} | |
505 | + = | |
506 | + \begin{pmatrix} | |
507 | + 0.3\theta & 0.0 \\ | |
508 | + 0.3\co{\theta} & 0.0 \\ | |
509 | + 0.0 & 7.0 | |
510 | + \end{pmatrix} | |
511 | +\end{multline*} | |
512 | +where we set $\theta = \theta_{ab, a}$ to simplify the notation. | |
513 | + | |
514 | +\textbf{Classes.} Following the definitions in \cref{eq:stable.core,eq:equiv.rel,eq:event.class} and in \cref{eq:weight.class.inconsistent,eq:weight.class.independent,eq:weight.class.other} we get the following quotient set, and weights: | |
515 | +\begin{equation*} | |
516 | + \begin{array}{ll|rr} | |
517 | + \text{\textbf{Core}} & \text{\textbf{Class}} & \text{\textbf{Parameters}} & \text{\textbf{Weights}}\\ | |
518 | + \hline | |
519 | + % | |
520 | + \inconsistent | |
521 | + & \text{inconsistent events} | |
522 | + & 0.0 | |
523 | + \\ | |
524 | + % | |
525 | + \emptyset | |
526 | + & \co{b}, \co{c}, bc, \co{b}a, \co{b}c, \co{b}\co{c}, \co{c}a, \co{c}b, \co{b}\co{c}a | |
527 | + & 0.0 | |
528 | + \\ | |
529 | + % | |
530 | + \co{a} | |
531 | + & \co{a}, \co{a}b, \co{a}c, \co{a}\co{b}, \co{a}\co{c}, \co{a}bc, \co{a}b\co{c}, \co{a}\co{b}c, \co{a}\co{b}\co{c} | |
532 | + & 1.0 | |
533 | + & 0.7 | |
534 | + \\ | |
535 | + % | |
536 | + ab | |
537 | + & b, ab, ab\co{c} | |
538 | + & \theta | |
539 | + & 0.3 | |
540 | + \\ | |
541 | + % | |
542 | + ac | |
543 | + & c, ac, a\co{b}c | |
544 | + & \co{\theta} | |
545 | + & 0.3 | |
546 | + \\ | |
547 | + % | |
548 | + ab, ac | |
549 | + & a, abc | |
550 | + & \co{\theta}\theta | |
551 | + & 0.3 | |
552 | + \\ | |
553 | + % | |
554 | + \co{a}, ab, ac | |
555 | + & \set{} | |
556 | + & \co{\theta}\theta, 1.0 | |
557 | + & 0.3, 0.7 | |
558 | + \end{array} | |
559 | +\end{equation*} | |
560 | +\remark{fc}{I really don't like those squares} | |
561 | + | |
562 | +\subsection{A Not So Simple Example} | |
563 | + | |
564 | +\todo{this subsection} | |
565 | + | |
566 | +\section{Discussion} | |
451 | 567 | |
452 | 568 | % % SUBSET |
453 | 569 | % \hrule |
... | ... | @@ -543,55 +659,6 @@ $$ |
543 | 659 | |
544 | 660 | Prove the four world cases (done), support the product (done) and sum (tbd) options, with the independence assumptions. |
545 | 661 | \end{quotation} |
546 | - | |
547 | -\section{Developed Example} | |
548 | - | |
549 | -We continue with the specification from Equation \eqref{eq:example.1}. | |
550 | - | |
551 | -\textbf{Step 1: Total Choices.} The total choices, and respective stable models, are | |
552 | -\begin{center} | |
553 | - \begin{tabular}{l|r|r} | |
554 | - Total Choice ($c$) & $\pr{C = c}$ & Stable Models ($s$)\\ | |
555 | - \hline | |
556 | - $a$ & $0.3$ & $ab$ and $ac$.\\ | |
557 | - $\co{a} = \neg a$ & $\co{0.3} = 0.7$ & $\co{a}$. | |
558 | - \end{tabular} | |
559 | -\end{center} | |
560 | - | |
561 | -\textbf{Step 2: Stable Models.} Suppose now that | |
562 | -\begin{center} | |
563 | - \begin{tabular}{l|c|r} | |
564 | - Stable Models ($s$) & Total Choice ($c$) & $\pr{S = c \given C = c}$\\ | |
565 | - \hline | |
566 | - $\co{a}$ & $1.0$ & $\co{a}$. \\ | |
567 | - $ab$ & $0.8$ & $a$. \\ | |
568 | - $ac$ & $0.2 = \co{0.8}$ & $a$. | |
569 | - \end{tabular} | |
570 | -\end{center} | |
571 | - | |
572 | -\textbf{Step 3: Worlds.} Following equations \ref{eq:world.fold.stablemodel} --- \ref{eq:world.fold.independent} we get: | |
573 | -\begin{center} | |
574 | - \begin{tabular}{l|c|l|c|r} | |
575 | - Occ. ($o$) & S.M. ($s$) & Relation & T.C. ($c$) & $\pr{W = w}$\\ | |
576 | - \hline | |
577 | - $\emptyset$ & all & contained & $a$, $\co{a}$ & $1.0$ \\ | |
578 | - $a$ & $ab$, $ac$ & contained & $a$ & $0.8\times 0.3 + 0.2\times 0.3 = 0.3$ \\ | |
579 | - $b$ & $ab$ & contained & $a$ & $0.8\times 0.3 = 0.24$ \\ | |
580 | - $c$ & $ac$ & contained & $a$ & $0.2\times 0.3 = 0.06$ \\ | |
581 | - $\co{a}$ & $\co{a}$ & stable model & $\co{a}$ & $1.0\times 0.3 = 0.3$ \\ | |
582 | - $\co{b}$ & none & independent & none & $0.0$ \\ | |
583 | - $\co{c}$ & none & \ldots & & \\ | |
584 | - $ab$ & $ab$ & stable model & $a$ & $0.24$ \\ | |
585 | - $ac$ & $ac$ & stable model & $a$ & $0.06$ \\ | |
586 | - $a\co{b}$ & none & \ldots & & \\ | |
587 | - $a\co{c}$ & none & \ldots & & \\ | |
588 | - $\co{a}b$ & $\co{a}$ & contains & $\co{a}$ & $1.0$ \\ | |
589 | - $\co{a}c$ & $\co{a}$ & \ldots & & \\ | |
590 | - $\co{a}\co{b}$ & $\co{a}$ & \ldots & & \\ | |
591 | - $\co{a}\co{c}$ & $\co{a}$ & \ldots & & \\ | |
592 | - $abc$ & $ab$, $ac$ & contains & $a$ & $0.8\times 0.2 = 0.016$ \\ | |
593 | - \end{tabular} | |
594 | -\end{center} | |
595 | 662 | |
596 | 663 | \section{Final Remarks} |
597 | 664 | |
... | ... | @@ -600,8 +667,13 @@ We continue with the specification from Equation \eqref{eq:example.1}. |
600 | 667 | \begin{itemize} |
601 | 668 | \item The measure of the inconsistent events doesn't need to be set to $0$ and, maybe, in some cases, it shouldn't. |
602 | 669 | \item The physical system might have \emph{latent} variables, possibly also represented in the specification. These variables are never observed, so observations should be concentrated \emph{somewhere else}. |
670 | + \item Comment on the possibility of extending equation \eqref{eq:weight.events.unconditional} with parameters expressing further uncertainties, enabling a tuning of the model's total choices, given observations. | |
671 | + \begin{equation*} | |
672 | + \pw{e} := \sum_{c\in\fml{C}} \pw{e, c}\theta_c. | |
673 | + \end{equation*} | |
603 | 674 | \end{itemize} |
604 | 675 | |
676 | + | |
605 | 677 | \section*{Acknowledgements} |
606 | 678 | |
607 | 679 | This work is supported by NOVA\textbf{LINCS} (UIDB/04516/2020) with the financial support of FCT.IP. | ... | ... |