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 4 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 5 "version": "0.2.0",
6 6 "configurations": [
  7 +
  8 +
7 9 {
8 10 "name": "Python: Current File",
9 11 "type": "python",
... ...
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
... ... @@ -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 @@
  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 @@
  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 @@
  1 +{
  2 + "cells": [],
  3 + "metadata": {},
  4 + "nbformat": 4,
  5 + "nbformat_minor": 5
  6 +}
... ...
students/amartins/tarefas/notas.md 0 โ†’ 100644
... ... @@ -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
... ...
students/amartins/tarefas/tarefa1.py 0 โ†’ 100644
... ... @@ -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&#39;&#39; 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&#39;&#39; 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.
... ...