Commit d080b40076ecd7ebad3d03e24b0358a15c5bc21b

Authored by Francisco Coelho
1 parent e43d9d3b
Exists in master

Paper draft: Extending Probabilities;

Support code: Event and Lattice look fine.
.vscode/launch.json
@@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 "version": "0.2.0", 5 "version": "0.2.0",
6 "configurations": [ 6 "configurations": [
  7 +
  8 +
7 { 9 {
8 "name": "Python: Current File", 10 "name": "Python: Current File",
9 "type": "python", 11 "type": "python",
code/python/EventLattice.ipynb
@@ -2,26 +2,37 @@ @@ -2,26 +2,37 @@
2 "cells": [ 2 "cells": [
3 { 3 {
4 "cell_type": "code", 4 "cell_type": "code",
5 - "execution_count": 7, 5 + "execution_count": 4,
6 "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", 6 "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63",
7 "metadata": {}, 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 "source": [ 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 "cell_type": "code", 25 "cell_type": "code",
15 - "execution_count": 8, 26 + "execution_count": 5,
16 "id": "00f0eb68", 27 "id": "00f0eb68",
17 "metadata": {}, 28 "metadata": {},
18 "outputs": [], 29 "outputs": [],
19 "source": [ 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 " event_class = lattice.event_class(event)\n", 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 "\n", 36 "\n",
26 " print(\n", 37 " print(\n",
27 " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" 38 " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")"
@@ -29,7 +40,7 @@ @@ -29,7 +40,7 @@
29 }, 40 },
30 { 41 {
31 "cell_type": "code", 42 "cell_type": "code",
32 - "execution_count": 9, 43 + "execution_count": 6,
33 "id": "cdd8c6d6", 44 "id": "cdd8c6d6",
34 "metadata": {}, 45 "metadata": {},
35 "outputs": [ 46 "outputs": [
@@ -49,42 +60,34 @@ @@ -49,42 +60,34 @@
49 } 60 }
50 ], 61 ],
51 "source": [ 62 "source": [
52 - "smodels = el.Lattice.parse({\n", 63 + "smodels = event_lattice.Lattice.parse({\n",
53 " \"A\": 2,\n", 64 " \"A\": 2,\n",
54 " \"ab\": 3,\n", 65 " \"ab\": 3,\n",
55 " \"ac\": 5\n", 66 " \"ac\": 5\n",
56 "})\n", 67 "})\n",
57 "\n", 68 "\n",
58 - "lattice = el.Lattice(smodels)\n", 69 + "lattice = event_lattice.Lattice(smodels)\n",
59 "\n", 70 "\n",
60 "print(lattice)" 71 "print(lattice)"
61 ] 72 ]
62 }, 73 },
63 { 74 {
64 "cell_type": "code", 75 "cell_type": "code",
65 - "execution_count": 10, 76 + "execution_count": 7,
66 "id": "2b445339", 77 "id": "2b445339",
67 "metadata": {}, 78 "metadata": {},
68 "outputs": [ 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,209 +101,10 @@
98 }, 101 },
99 { 102 {
100 "cell_type": "code", 103 "cell_type": "code",
101 - "execution_count": 11, 104 + "execution_count": null,
102 "id": "f1b85255", 105 "id": "f1b85255",
103 "metadata": {}, 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 "source": [ 108 "source": [
305 "from itertools import *\n", 109 "from itertools import *\n",
306 "\n", 110 "\n",
code/python/__pycache__/event_lattice.cpython-39.pyc
No preview for this file type
code/python/event_lattice.py
1 import math 1 import math
2 from functools import cache 2 from functools import cache
3 -from itertools import accumulate 3 +from itertools import accumulate, combinations, chain, groupby
4 import operator 4 import operator
5 5
6 6
@@ -32,21 +32,31 @@ def prod_op(x): @@ -32,21 +32,31 @@ def prod_op(x):
32 32
33 33
34 class Event: 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 @staticmethod 43 @staticmethod
38 - def parse(text): 44 + def _parse(text):
39 return frozenset(text) 45 return frozenset(text)
40 46
41 @staticmethod 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 def __init__(self, literals): 56 def __init__(self, literals):
47 """Instantiate from a (frozen) set of literals. 57 """Instantiate from a (frozen) set of literals.
48 For example: e = Event(frozenset("abc")).""" 58 For example: e = Event(frozenset("abc"))."""
49 - self._literals = literals 59 + self._literals = frozenset(literals)
50 60
51 61
52 def literals(self): 62 def literals(self):
@@ -55,56 +65,74 @@ class Event: @@ -55,56 +65,74 @@ class Event:
55 65
56 def __iter__(self): 66 def __iter__(self):
57 return self._literals.__iter__() 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 @cache 69 @cache
66 def is_consistent(self): 70 def is_consistent(self):
  71 + """True if this event is consistent."""
67 return all(x.swapcase() not in self._literals for x in self._literals) 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 def __repr__(self) -> str: 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 def __eq__(self, other): 106 def __eq__(self, other):
  107 + """Event equality test."""
85 return self._literals.__eq__(other._literals) 108 return self._literals.__eq__(other._literals)
86 109
87 def __or__(self, other): 110 def __or__(self, other):
  111 + """Event union operation."""
88 return Event(self._literals | other._literals) 112 return Event(self._literals | other._literals)
89 113
90 -  
91 def __le__(self, other): 114 def __le__(self, other):
  115 + """Event subset test."""
92 return self._literals.__le__(other._literals) 116 return self._literals.__le__(other._literals)
93 117
94 118
95 def __lt__(self, other): 119 def __lt__(self, other):
  120 + """Event strict subset test."""
96 return self._literals.__lt__(other._literals) 121 return self._literals.__lt__(other._literals)
97 122
98 123
99 def __ne__(self, other): 124 def __ne__(self, other):
  125 + """Event not-equal test."""
100 return self._literals.__ne__(other._literals) 126 return self._literals.__ne__(other._literals)
101 127
102 128
103 def __ge__(self, other): 129 def __ge__(self, other):
  130 + """Event superset test."""
104 return self._literals.__ge__(other._literals) 131 return self._literals.__ge__(other._literals)
105 132
106 133
107 def __gt__(self, other): 134 def __gt__(self, other):
  135 + """Event strict superset test."""
108 return self._literals.__gt__(other._literals) 136 return self._literals.__gt__(other._literals)
109 137
110 138
@@ -112,87 +140,120 @@ class Lattice: @@ -112,87 +140,120 @@ class Lattice:
112 140
113 @staticmethod 141 @staticmethod
114 def parse(d): 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 result = dict() 156 result = dict()
116 for k, v in d.items(): 157 for k, v in d.items():
117 - key = Event.from_str(k) 158 + key = Event.parse(k)
118 result[key] = v 159 result[key] = v
119 return result 160 return result
120 161
121 162
122 @staticmethod 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 lits = set() 169 lits = set()
126 for x in base_lits.literals(): 170 for x in base_lits.literals():
127 lits.add(x) 171 lits.add(x)
128 lits.add(x.swapcase()) 172 lits.add(x.swapcase())
129 - return lits 173 + return sorted(lits)
130 174
131 def __init__(self, smodels_dict): 175 def __init__(self, smodels_dict):
132 - """Create base for Events Lattice.""" 176 + """Create an Events lattice."""
133 self._smodels = smodels_dict 177 self._smodels = smodels_dict
134 self._literals = Lattice.close_literals(self._smodels.keys()) 178 self._literals = Lattice.close_literals(self._smodels.keys())
135 179
136 def literals(self): 180 def literals(self):
  181 + """The literals in this lattice."""
137 return self._literals 182 return self._literals
138 183
  184 + @cache
139 def stable_models(self): 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 @cache 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 def related(self, u, v): 222 def related(self, u, v):
  223 + """Tests if two events are related."""
158 u_consistent = u.is_consistent() 224 u_consistent = u.is_consistent()
159 v_consistent = v.is_consistent() 225 v_consistent = v.is_consistent()
160 if u_consistent and (u_consistent == v_consistent): 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 else: 228 else:
165 return u_consistent == v_consistent 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 value = 0 234 value = 0
174 - 235 + #
  236 + # INCONSISTENT EVENTS
  237 + #
175 if not event.is_consistent(): 238 if not event.is_consistent():
176 return value 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 else: 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 return value 253 return value
193 254
194 def __repr__(self): 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 lits_repr = ','.join(sorted(self._literals)) 257 lits_repr = ','.join(sorted(self._literals))
197 258
198 return "{\n" +\ 259 return "{\n" +\
@@ -200,19 +261,41 @@ class Lattice: @@ -200,19 +261,41 @@ class Lattice:
200 f"\t'literals': {{ {lits_repr} }} \n" +\ 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 \ No newline at end of file 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 \ No newline at end of file 303 \ No newline at end of file
students/amartins/tarefas/.ipynb_checkpoints/Untitled-checkpoint.ipynb 0 โ†’ 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +{
  2 + "cells": [],
  3 + "metadata": {},
  4 + "nbformat": 4,
  5 + "nbformat_minor": 5
  6 +}
students/amartins/tarefas/.ipynb_checkpoints/Untitled1-checkpoint.ipynb 0 โ†’ 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +{
  2 + "cells": [],
  3 + "metadata": {},
  4 + "nbformat": 4,
  5 + "nbformat_minor": 5
  6 +}
students/amartins/tarefas/.ipynb_checkpoints/tarefa1b-checkpoint.py 0 โ†’ 100644
@@ -0,0 +1,35 @@ @@ -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')
students/amartins/tarefas/Untitled.ipynb 0 โ†’ 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +{
  2 + "cells": [],
  3 + "metadata": {},
  4 + "nbformat": 4,
  5 + "nbformat_minor": 5
  6 +}
students/amartins/tarefas/notas.md 0 โ†’ 100644
@@ -0,0 +1,67 @@ @@ -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 \ No newline at end of file 68 \ No newline at end of file
students/amartins/tarefas/tarefa1.py 0 โ†’ 100644
@@ -0,0 +1,81 @@ @@ -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 \ No newline at end of file 82 \ No newline at end of file
students/amartins/tarefas/tarefa1a.py
@@ -32,7 +32,7 @@ for x in nos: @@ -32,7 +32,7 @@ for x in nos:
32 print("Nรณs ascendentes: ", asc) 32 print("Nรณs ascendentes: ", asc)
33 print("Nรณs descendentes: ", des) 33 print("Nรณs descendentes: ", des)
34 # resposta ร  pergunta "qual รฉ o nรบmero mรฉdio de arestas "in"? e "out"?" 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 print("Nรบmero mรฉdio de arestas in: ", nos_in) 37 print("Nรบmero mรฉdio de arestas in: ", nos_in)
38 print("Nรบmero mรฉdio de arestas out: ", nos_out) 38 print("Nรบmero mรฉdio de arestas out: ", nos_out)
39 \ No newline at end of file 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,6 +246,8 @@ The stable models $ab, ac$ from \cref{running.example} result from the clause $b
246 246
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. 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 Given an ASP specification 251 Given an ASP specification
250 % DONE: {\bruno This should be defined somewhere (maybe in the introduction).} 252 % DONE: {\bruno This should be defined somewhere (maybe in the introduction).}
251 \remark{{\bruno Introduce also the sets mentioned below}}{how?} 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,24 +279,24 @@ This focus on the \acp{SM} leads to the following definition:
277 % \lset{e} = \set{s \in \fml{S} \given e \supseteq s}, \label{eq:lset} 279 % \lset{e} = \set{s \in \fml{S} \given e \supseteq s}, \label{eq:lset}
278 % \end{equation} 280 % \end{equation}
279 % \begin{equation} 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 % \end{equation} 283 % \end{equation}
282 \begin{equation} 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 \end{equation} 286 \end{equation}
285 287
286 \end{definition} 288 \end{definition}
287 289
288 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. 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 For a given specification, let $u, v \in \fml{E}$. The equivalence relation $\sim$ is defined by 293 For a given specification, let $u, v \in \fml{E}$. The equivalence relation $\sim$ is defined by
292 \begin{equation} 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 \end{equation} 296 \end{equation}
295 \end{definition} 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 % \begin{definition}\label{def:smodel.events} 301 % \begin{definition}\label{def:smodel.events}
300 % For $\set{s_1, \ldots, s_n} \subseteq \fml{S}$ define 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,21 +323,21 @@ This relation defines a partition of the events space, where each class holds a
321 \set{u \in \fml{W} \given \stablecore{u} = \stablecore{e}} &\text{if~} e \in \fml{W}, \\ 323 \set{u \in \fml{W} \given \stablecore{u} = \stablecore{e}} &\text{if~} e \in \fml{W}, \\
322 % \lclass{\uset{e}} &\text{if~} \uset{e} \not= \emptyset, \\ 324 % \lclass{\uset{e}} &\text{if~} \uset{e} \not= \emptyset, \\
323 % \uclass{\lset{e}} &\text{otherwise}. 325 % \uclass{\lset{e}} &\text{otherwise}.
324 - \end{cases} 326 + \end{cases}\label{eq:event.class}
325 \end{equation} 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 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}}:$ 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 \begin{equation} 343 \begin{equation}
@@ -388,19 +390,21 @@ For example, @@ -388,19 +390,21 @@ For example,
388 % \item The extended probability \emph{events} are the \emph{classes}. 390 % \item The extended probability \emph{events} are the \emph{classes}.
389 \end{itemize} 391 \end{itemize}
390 392
  393 +\subsection{From Total Choices to Events}\label{subsec:from.tchoices.to.events}
  394 +
391 \todo{Check adaptation} Our path to set a probability measure on $\fml{E}$ has two phases: 395 \todo{Check adaptation} Our path to set a probability measure on $\fml{E}$ has two phases:
392 \begin{itemize} 396 \begin{itemize}
393 \item Extending the probabilities, \emph{as weights}, of the total choices to events. 397 \item Extending the probabilities, \emph{as weights}, of the total choices to events.
394 \item Normalization of the weights. 398 \item Normalization of the weights.
395 \end{itemize} 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 \begin{description} 403 \begin{description}
400 % 404 %
401 \item[Total Choices.] Using \eqref{eq:prob.total.choice}, this case is given by 405 \item[Total Choices.] Using \eqref{eq:prob.total.choice}, this case is given by
402 \begin{equation} 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 \label{eq:weight.tchoice} 408 \label{eq:weight.tchoice}
405 \end{equation} 409 \end{equation}
406 % 410 %
@@ -409,7 +413,7 @@ The ``extension&#39;&#39; phase, traced by equations (\ref{eq:prob.total.choice}) and (\ @@ -409,7 +413,7 @@ The ``extension&#39;&#39; phase, traced by equations (\ref{eq:prob.total.choice}) and (\
409 Given a stable model $s \in \fml{S}$, a total choice $c$, and variables/values $\theta_{s,c} \in \intcc{0, 1}$, 413 Given a stable model $s \in \fml{S}$, a total choice $c$, and variables/values $\theta_{s,c} \in \intcc{0, 1}$,
410 \begin{equation} 414 \begin{equation}
411 \pw{s, c} := \begin{cases} 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 0&\text{otherwise} 417 0&\text{otherwise}
414 \end{cases} 418 \end{cases}
415 \label{eq:weight.stablemodel} 419 \label{eq:weight.stablemodel}
@@ -425,29 +429,141 @@ The ``extension&#39;&#39; phase, traced by equations (\ref{eq:prob.total.choice}) and (\ @@ -425,29 +429,141 @@ The ``extension&#39;&#39; phase, traced by equations (\ref{eq:prob.total.choice}) and (\
425 \end{equation} 429 \end{equation}
426 \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: 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 \begin{equation} 431 \begin{equation}
428 - \pw{\emptyset, c} := 0. 432 + \pw{\class{e}, c} := 0,~\text{if}~\stablecore{e} = \emptyset.
429 \label{eq:weight.class.independent} 433 \label{eq:weight.class.independent}
430 \end{equation} 434 \end{equation}
431 \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}: 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 \begin{equation} 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 \end{equation} 439 \end{equation}
436 \end{itemize} 440 \end{itemize}
437 % 441 %
438 \item[Events.] \label{item:event.cases} Each (general) event $e$ is in the class defined by its stable core, $\stablecore{e}$. So, we set: 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 \begin{equation} 443 \begin{equation}
440 - \pw{e, c} := \pw{\stablecore{e}, c}. 444 + \pw{e, c} := \pw{\class{e}, c}.
441 \label{eq:weight.events} 445 \label{eq:weight.events}
442 \end{equation} 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 \end{description} 452 \end{description}
444 453
445 % PARAMETERS FOR UNCERTAINTY 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 % SUPERSET 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 % % SUBSET 568 % % SUBSET
453 % \hrule 569 % \hrule
@@ -543,55 +659,6 @@ $$ @@ -543,55 +659,6 @@ $$
543 659
544 Prove the four world cases (done), support the product (done) and sum (tbd) options, with the independence assumptions. 660 Prove the four world cases (done), support the product (done) and sum (tbd) options, with the independence assumptions.
545 \end{quotation} 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 \section{Final Remarks} 663 \section{Final Remarks}
597 664
@@ -600,8 +667,13 @@ We continue with the specification from Equation \eqref{eq:example.1}. @@ -600,8 +667,13 @@ We continue with the specification from Equation \eqref{eq:example.1}.
600 \begin{itemize} 667 \begin{itemize}
601 \item The measure of the inconsistent events doesn't need to be set to $0$ and, maybe, in some cases, it shouldn't. 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 \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}. 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 \end{itemize} 674 \end{itemize}
604 675
  676 +
605 \section*{Acknowledgements} 677 \section*{Acknowledgements}
606 678
607 This work is supported by NOVA\textbf{LINCS} (UIDB/04516/2020) with the financial support of FCT.IP. 679 This work is supported by NOVA\textbf{LINCS} (UIDB/04516/2020) with the financial support of FCT.IP.