Commit 353a8086aab8f46c7610ea1a544f7078e57f479f
1 parent
0ca70415
Exists in
master
alterações feitas pelo bruno à sub-secção 4.2
Showing
27 changed files
with
1180 additions
and
882 deletions
Show diff stats
code/drafts/.ipynb_checkpoints/EventLattice-checkpoint.ipynb
0 → 100644
... | ... | @@ -0,0 +1,113 @@ |
1 | +{ | |
2 | + "cells": [ | |
3 | + { | |
4 | + "cell_type": "code", | |
5 | + "execution_count": null, | |
6 | + "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", | |
7 | + "metadata": {}, | |
8 | + "outputs": [], | |
9 | + "source": [ | |
10 | + "import event_lattice as el" | |
11 | + ] | |
12 | + }, | |
13 | + { | |
14 | + "cell_type": "code", | |
15 | + "execution_count": null, | |
16 | + "id": "00f0eb68", | |
17 | + "metadata": {}, | |
18 | + "outputs": [], | |
19 | + "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", | |
22 | + " event_class = lattice.event_class(event)\n", | |
23 | + " propagated = lattice.propagated_value(\n", | |
24 | + " event, lower_op=lower_op, upper_op=upper_op)\n", | |
25 | + "\n", | |
26 | + " print(\n", | |
27 | + " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" | |
28 | + ] | |
29 | + }, | |
30 | + { | |
31 | + "cell_type": "code", | |
32 | + "execution_count": null, | |
33 | + "id": "cdd8c6d6", | |
34 | + "metadata": {}, | |
35 | + "outputs": [], | |
36 | + "source": [ | |
37 | + "smodels = el.Lattice.parse({\n", | |
38 | + " \"A\": 2,\n", | |
39 | + " \"ab\": 3,\n", | |
40 | + " \"ac\": 5\n", | |
41 | + "})\n", | |
42 | + "\n", | |
43 | + "lattice = el.Lattice(smodels)\n", | |
44 | + "\n", | |
45 | + "print(lattice)" | |
46 | + ] | |
47 | + }, | |
48 | + { | |
49 | + "cell_type": "code", | |
50 | + "execution_count": null, | |
51 | + "id": "2b445339", | |
52 | + "metadata": {}, | |
53 | + "outputs": [], | |
54 | + "source": [ | |
55 | + "zoom_event(\"abc\", lattice)\n", | |
56 | + "zoom_event(\"a\", lattice)\n", | |
57 | + "zoom_event(\"b\", lattice)\n", | |
58 | + "zoom_event(\"bc\", lattice)\n", | |
59 | + "zoom_event(\"ac\", lattice)" | |
60 | + ] | |
61 | + }, | |
62 | + { | |
63 | + "cell_type": "code", | |
64 | + "execution_count": null, | |
65 | + "id": "f1b85255", | |
66 | + "metadata": {}, | |
67 | + "outputs": [], | |
68 | + "source": [ | |
69 | + "from itertools import *\n", | |
70 | + "\n", | |
71 | + "lits = lattice.literals()\n", | |
72 | + "for len_lit in range(len(lits)+1):\n", | |
73 | + " events = list(\"\".join(c) for c in combinations(lits, len_lit))\n", | |
74 | + " for event in events:\n", | |
75 | + " zoom_event(event, lattice)" | |
76 | + ] | |
77 | + }, | |
78 | + { | |
79 | + "cell_type": "code", | |
80 | + "execution_count": null, | |
81 | + "id": "07973a47", | |
82 | + "metadata": {}, | |
83 | + "outputs": [], | |
84 | + "source": [] | |
85 | + } | |
86 | + ], | |
87 | + "metadata": { | |
88 | + "kernelspec": { | |
89 | + "display_name": "Python 3.9.13 ('base')", | |
90 | + "language": "python", | |
91 | + "name": "python3" | |
92 | + }, | |
93 | + "language_info": { | |
94 | + "codemirror_mode": { | |
95 | + "name": "ipython", | |
96 | + "version": 3 | |
97 | + }, | |
98 | + "file_extension": ".py", | |
99 | + "mimetype": "text/x-python", | |
100 | + "name": "python", | |
101 | + "nbconvert_exporter": "python", | |
102 | + "pygments_lexer": "ipython3", | |
103 | + "version": "3.9.13" | |
104 | + }, | |
105 | + "vscode": { | |
106 | + "interpreter": { | |
107 | + "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
108 | + } | |
109 | + } | |
110 | + }, | |
111 | + "nbformat": 4, | |
112 | + "nbformat_minor": 5 | |
113 | +} | ... | ... |
... | ... | @@ -0,0 +1,154 @@ |
1 | +{ | |
2 | + "cells": [ | |
3 | + { | |
4 | + "cell_type": "code", | |
5 | + "execution_count": 4, | |
6 | + "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", | |
7 | + "metadata": {}, | |
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 | + ], | |
18 | + "source": [ | |
19 | + "%load_ext autoreload\n", | |
20 | + "%autoreload 1\n", | |
21 | + "%aimport event_lattice" | |
22 | + ] | |
23 | + }, | |
24 | + { | |
25 | + "cell_type": "code", | |
26 | + "execution_count": 5, | |
27 | + "id": "00f0eb68", | |
28 | + "metadata": {}, | |
29 | + "outputs": [], | |
30 | + "source": [ | |
31 | + "def zoom_event(event_str, lattice):\n", | |
32 | + " event = event_lattice.Event.from_str(event_str)\n", | |
33 | + " event_class = lattice.event_class(event)\n", | |
34 | + " propagated = lattice.extended_value(\n", | |
35 | + " event)\n", | |
36 | + "\n", | |
37 | + " print(\n", | |
38 | + " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" | |
39 | + ] | |
40 | + }, | |
41 | + { | |
42 | + "cell_type": "code", | |
43 | + "execution_count": 6, | |
44 | + "id": "cdd8c6d6", | |
45 | + "metadata": {}, | |
46 | + "outputs": [ | |
47 | + { | |
48 | + "name": "stdout", | |
49 | + "output_type": "stream", | |
50 | + "text": [ | |
51 | + "{\n", | |
52 | + "\t'stable_models': {\n", | |
53 | + "\t\t A: 2,\n", | |
54 | + "\t\tab: 3,\n", | |
55 | + "\t\tac: 5 \n", | |
56 | + "\t}\n", | |
57 | + "\t'literals': { A,B,C,a,b,c } \n", | |
58 | + "}\n" | |
59 | + ] | |
60 | + } | |
61 | + ], | |
62 | + "source": [ | |
63 | + "smodels = event_lattice.Lattice.parse({\n", | |
64 | + " \"A\": 2,\n", | |
65 | + " \"ab\": 3,\n", | |
66 | + " \"ac\": 5\n", | |
67 | + "})\n", | |
68 | + "\n", | |
69 | + "lattice = event_lattice.Lattice(smodels)\n", | |
70 | + "\n", | |
71 | + "print(lattice)" | |
72 | + ] | |
73 | + }, | |
74 | + { | |
75 | + "cell_type": "code", | |
76 | + "execution_count": 7, | |
77 | + "id": "2b445339", | |
78 | + "metadata": {}, | |
79 | + "outputs": [ | |
80 | + { | |
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'" | |
91 | + ] | |
92 | + } | |
93 | + ], | |
94 | + "source": [ | |
95 | + "zoom_event(\"abc\", lattice)\n", | |
96 | + "zoom_event(\"a\", lattice)\n", | |
97 | + "zoom_event(\"b\", lattice)\n", | |
98 | + "zoom_event(\"bc\", lattice)\n", | |
99 | + "zoom_event(\"ac\", lattice)" | |
100 | + ] | |
101 | + }, | |
102 | + { | |
103 | + "cell_type": "code", | |
104 | + "execution_count": null, | |
105 | + "id": "f1b85255", | |
106 | + "metadata": {}, | |
107 | + "outputs": [], | |
108 | + "source": [ | |
109 | + "from itertools import *\n", | |
110 | + "\n", | |
111 | + "lits = lattice.literals()\n", | |
112 | + "events = []\n", | |
113 | + "for len_lit in range(len(lits)+1):\n", | |
114 | + " events = events + list(\"\".join(c) for c in combinations(lits, len_lit))\n", | |
115 | + "for event in events:\n", | |
116 | + " zoom_event(event, lattice)" | |
117 | + ] | |
118 | + }, | |
119 | + { | |
120 | + "cell_type": "code", | |
121 | + "execution_count": null, | |
122 | + "id": "07973a47", | |
123 | + "metadata": {}, | |
124 | + "outputs": [], | |
125 | + "source": [] | |
126 | + } | |
127 | + ], | |
128 | + "metadata": { | |
129 | + "kernelspec": { | |
130 | + "display_name": "Python 3 (ipykernel)", | |
131 | + "language": "python", | |
132 | + "name": "python3" | |
133 | + }, | |
134 | + "language_info": { | |
135 | + "codemirror_mode": { | |
136 | + "name": "ipython", | |
137 | + "version": 3 | |
138 | + }, | |
139 | + "file_extension": ".py", | |
140 | + "mimetype": "text/x-python", | |
141 | + "name": "python", | |
142 | + "nbconvert_exporter": "python", | |
143 | + "pygments_lexer": "ipython3", | |
144 | + "version": "3.9.15" | |
145 | + }, | |
146 | + "vscode": { | |
147 | + "interpreter": { | |
148 | + "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
149 | + } | |
150 | + } | |
151 | + }, | |
152 | + "nbformat": 4, | |
153 | + "nbformat_minor": 5 | |
154 | +} | ... | ... |
No preview for this file type
... | ... | @@ -0,0 +1,30 @@ |
1 | +from itertools import combinations, product | |
2 | + | |
3 | +def fmt(expr): | |
4 | + """Doc string""" | |
5 | + return ",".join(f"{x:>2}" for x in expr) | |
6 | + | |
7 | +def c(expr): | |
8 | + """Doc string""" | |
9 | + def litcomp(x): | |
10 | + if x == "⊤": | |
11 | + return "⊥" | |
12 | + elif x == "⊥": | |
13 | + return "⊤" | |
14 | + elif x[0] == "¬": | |
15 | + return x[1:] | |
16 | + else: | |
17 | + return f"¬{x}" | |
18 | + return [litcomp(x) for x in expr] | |
19 | + | |
20 | +def domain(symbols, unary="¬"): | |
21 | + """Doc string""" | |
22 | + atoms = list(symbols) | |
23 | + literals = [ | |
24 | + [f"{u}{a}" for u in unary] + | |
25 | + [a, "⊤", "⊥"] for a in atoms ] | |
26 | + return product(*literals) | |
27 | + | |
28 | +d = sorted(domain("abc")) | |
29 | +for x in d: | |
30 | + print(f"{fmt(x)} | {fmt(c(x))}") | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +from clingo.symbol import Number | |
2 | +from clingo.control import Control | |
3 | + | |
4 | +class Context: | |
5 | + def inc(self, x): | |
6 | + return Number(x.number + 1) | |
7 | + | |
8 | + def seq(self, x, y): | |
9 | + return [x, y] | |
10 | + | |
11 | +def on_model(m): | |
12 | + print(m) | |
13 | + | |
14 | +ctl = Control() | |
15 | +ctl.add("base", [], """\ | |
16 | +p(@inc(10)). | |
17 | +q(@seq(1,2)). | |
18 | +""") | |
19 | + | |
20 | +ctl.ground( | |
21 | + [("base", [])], | |
22 | + context=Context()) | |
23 | + | |
24 | +s = ctl.solve(on_model=on_model) | |
25 | + | |
26 | +print(s) | |
0 | 27 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,301 @@ |
1 | +import math | |
2 | +from functools import cache | |
3 | +from itertools import accumulate, combinations, chain, groupby | |
4 | +import operator | |
5 | + | |
6 | + | |
7 | + | |
8 | +def uniform_op(x): | |
9 | + n = len(list(x)) | |
10 | + return 1.0 if n == 0 else 1.0/n | |
11 | + | |
12 | + | |
13 | +def max_op(x): | |
14 | + return max(x) | |
15 | + | |
16 | + | |
17 | +def min_op(x): | |
18 | + return min(x) | |
19 | + | |
20 | + | |
21 | +def sum_op(x): | |
22 | + return sum(x) | |
23 | + | |
24 | + | |
25 | +def stableprod_op(x): | |
26 | + log_x = map(math.log, x) | |
27 | + return math.exp(sum(log_x)) | |
28 | + | |
29 | + | |
30 | +def prod_op(x): | |
31 | + return list(accumulate(x, func=lambda a,b: a*b))[-1] | |
32 | + | |
33 | + | |
34 | +class Event: | |
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 | + """ | |
42 | + | |
43 | + @staticmethod | |
44 | + def _parse(text): | |
45 | + return frozenset(text) | |
46 | + | |
47 | + @staticmethod | |
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)) | |
54 | + | |
55 | + | |
56 | + def __init__(self, literals): | |
57 | + """Instantiate from a (frozen) set of literals. | |
58 | + For example: e = Event(frozenset("abc")).""" | |
59 | + self._literals = frozenset(literals) | |
60 | + | |
61 | + | |
62 | + def literals(self): | |
63 | + return self._literals | |
64 | + | |
65 | + | |
66 | + def __iter__(self): | |
67 | + return self._literals.__iter__() | |
68 | + | |
69 | + @cache | |
70 | + def is_consistent(self): | |
71 | + """True if this event is consistent.""" | |
72 | + return all(x.swapcase() not in self._literals for x in self._literals) | |
73 | + | |
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) | |
80 | + | |
81 | + def invert(self): | |
82 | + """Negation of this event. | |
83 | + | |
84 | + See the method "co" | |
85 | + """ | |
86 | + return self.co() | |
87 | + | |
88 | + def __repr__(self) -> str: | |
89 | + return ''.join(str(x) for x in sorted(self._literals)) if len(self._literals) > 0 else '0' | |
90 | + | |
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__() | |
104 | + | |
105 | + | |
106 | + def __eq__(self, other): | |
107 | + """Event equality test.""" | |
108 | + return self._literals.__eq__(other._literals) | |
109 | + | |
110 | + def __or__(self, other): | |
111 | + """Event union operation.""" | |
112 | + return Event(self._literals | other._literals) | |
113 | + | |
114 | + def __le__(self, other): | |
115 | + """Event subset test.""" | |
116 | + return self._literals.__le__(other._literals) | |
117 | + | |
118 | + | |
119 | + def __lt__(self, other): | |
120 | + """Event strict subset test.""" | |
121 | + return self._literals.__lt__(other._literals) | |
122 | + | |
123 | + | |
124 | + def __ne__(self, other): | |
125 | + """Event not-equal test.""" | |
126 | + return self._literals.__ne__(other._literals) | |
127 | + | |
128 | + | |
129 | + def __ge__(self, other): | |
130 | + """Event superset test.""" | |
131 | + return self._literals.__ge__(other._literals) | |
132 | + | |
133 | + | |
134 | + def __gt__(self, other): | |
135 | + """Event strict superset test.""" | |
136 | + return self._literals.__gt__(other._literals) | |
137 | + | |
138 | + | |
139 | +class Lattice: | |
140 | + | |
141 | + @staticmethod | |
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 | + """ | |
156 | + result = dict() | |
157 | + for k, v in d.items(): | |
158 | + key = Event.parse(k) | |
159 | + result[key] = v | |
160 | + return result | |
161 | + | |
162 | + | |
163 | + @staticmethod | |
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] | |
169 | + lits = set() | |
170 | + for x in base_lits.literals(): | |
171 | + lits.add(x) | |
172 | + lits.add(x.swapcase()) | |
173 | + return sorted(lits) | |
174 | + | |
175 | + def __init__(self, smodels_dict): | |
176 | + """Create an Events lattice.""" | |
177 | + self._smodels = smodels_dict | |
178 | + self._literals = Lattice.close_literals(self._smodels.keys()) | |
179 | + | |
180 | + def literals(self): | |
181 | + """The literals in this lattice.""" | |
182 | + return self._literals | |
183 | + | |
184 | + @cache | |
185 | + def stable_models(self): | |
186 | + """The stable models that generate this lattice.""" | |
187 | + return self._smodels.keys() | |
188 | + | |
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)) | |
193 | + | |
194 | + @cache | |
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) | |
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 | |
220 | + | |
221 | + | |
222 | + def related(self, u, v): | |
223 | + """Tests if two events are related.""" | |
224 | + u_consistent = u.is_consistent() | |
225 | + v_consistent = v.is_consistent() | |
226 | + if u_consistent and (u_consistent == v_consistent): | |
227 | + return self.stable_core(u) == self.stable_core(v) | |
228 | + else: | |
229 | + return u_consistent == v_consistent | |
230 | + | |
231 | + def extended_value(self, event:Event, | |
232 | + op=prod_op): | |
233 | + """TODO: well...""" | |
234 | + value = 0 | |
235 | + # | |
236 | + # INCONSISTENT EVENTS | |
237 | + # | |
238 | + if not event.is_consistent(): | |
239 | + return value | |
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]] | |
250 | + else: | |
251 | + value = op(map(lambda sm: self._smodels[sm], score)) | |
252 | + | |
253 | + return value | |
254 | + | |
255 | + def __repr__(self): | |
256 | + smodels_repr = ',\n\t\t'.join(f"{k}: {v:<}" for k,v in self._smodels.items()) | |
257 | + lits_repr = ','.join(sorted(self._literals)) | |
258 | + | |
259 | + return "{\n" +\ | |
260 | + f"\t'stable_models': {{\n\t\t {smodels_repr} \n\t}}\n" +\ | |
261 | + f"\t'literals': {{ {lits_repr} }} \n" +\ | |
262 | + "}" | |
263 | + | |
264 | +# class EventsClass: | |
265 | +# def __init__(self, core, lattice:Lattice): | |
266 | +# self._core = core | |
267 | +# self._lattice = lattice | |
268 | + | |
269 | +# def __repr__(self): | |
270 | +# core_repr = "" if len(self._core) == 0 else ",".join(str(x) for x in self._core) | |
271 | +# return f"<{core_repr}>" | |
272 | + | |
273 | +# def __contains__(self, event:Event): | |
274 | +# return self.lattice.stable_core(event) == self._core | |
275 | + | |
276 | +if __name__ == "__main__": | |
277 | + def zoom_event(event_str, lattice): | |
278 | + event = Event.parse(event_str) | |
279 | + event_class = lattice.event_class(event) | |
280 | + propagated = lattice.extended_value( | |
281 | + event) | |
282 | + | |
283 | + print( | |
284 | + f"Event: {event}\n\tClass: {event_class} \n\tValue: {propagated}") | |
285 | + | |
286 | + smodels = Lattice.parse({ | |
287 | + "A": 2, | |
288 | + "ab": 3, | |
289 | + "ac": 5 | |
290 | + }) | |
291 | + | |
292 | + lattice = Lattice(smodels) | |
293 | + | |
294 | + ev_classes = lattice.classes() | |
295 | + for k,g in ev_classes.items(): | |
296 | + print(f"{tuple(s.latex() for s in k)} {set(e.latex() for e in g)}") | |
297 | + # zoom_event("abc", lattice) | |
298 | + # zoom_event("a", lattice) | |
299 | + # zoom_event("b", lattice) | |
300 | + # zoom_event("bc", lattice) | |
301 | + # zoom_event("ac", lattice) | |
0 | 302 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +from clingo.control import Control | |
2 | +from clingox.program import Program, ProgramObserver, Remapping | |
3 | + | |
4 | +prg = Program() | |
5 | +ctl_a = Control() | |
6 | +ctl_a.register_observer(ProgramObserver(prg)) | |
7 | +print(f"<1>\n{prg}\n</1>") | |
8 | + | |
9 | +prog = "code/asp/alarm.lp" | |
10 | +ctl_a.load(prog) | |
11 | +ctl_a.ground([('base', [])]) | |
12 | +print(f"<2>\n{prg}\n</2>") | |
13 | + | ... | ... |
... | ... | @@ -0,0 +1,101 @@ |
1 | +event | |
2 | +b | |
3 | +b | |
4 | +b | |
5 | +C | |
6 | +λ | |
7 | +BC | |
8 | +C | |
9 | +λ | |
10 | +bC | |
11 | +BC | |
12 | +Ac | |
13 | +λ | |
14 | +λ | |
15 | +abC | |
16 | +λ | |
17 | +BC | |
18 | +abC | |
19 | +A | |
20 | +a | |
21 | +B | |
22 | +b | |
23 | +abc | |
24 | +λ | |
25 | +B | |
26 | +λ | |
27 | +AC | |
28 | +C | |
29 | +Ac | |
30 | +C | |
31 | +B | |
32 | +Bc | |
33 | +c | |
34 | +aB | |
35 | +Ab | |
36 | +λ | |
37 | +C | |
38 | +aC | |
39 | +λ | |
40 | +a | |
41 | +aBC | |
42 | +abc | |
43 | +Ac | |
44 | +λ | |
45 | +c | |
46 | +c | |
47 | +λ | |
48 | +Bc | |
49 | +B | |
50 | +bc | |
51 | +aB | |
52 | +aB | |
53 | +ABc | |
54 | +C | |
55 | +λ | |
56 | +B | |
57 | +λ | |
58 | +ac | |
59 | +Ac | |
60 | +b | |
61 | +Abc | |
62 | +b | |
63 | +C | |
64 | +a | |
65 | +ab | |
66 | +C | |
67 | +ab | |
68 | +λ | |
69 | +A | |
70 | +bc | |
71 | +AC | |
72 | +λ | |
73 | +C | |
74 | +ABc | |
75 | +AC | |
76 | +ac | |
77 | +BC | |
78 | +c | |
79 | +Ac | |
80 | +ab | |
81 | +ABC | |
82 | +A | |
83 | +aB | |
84 | +bc | |
85 | +λ | |
86 | +aB | |
87 | +ABc | |
88 | +Ac | |
89 | +Ac | |
90 | +B | |
91 | +aB | |
92 | +Ac | |
93 | +c | |
94 | +λ | |
95 | +λ | |
96 | +b | |
97 | +c | |
98 | +Ab | |
99 | +BC | |
100 | +A | |
101 | +BC | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +neg(a) = islowercase(a) ? uppercase(a) : lowercase(a) | |
2 | + | |
3 | +function sample(atoms) | |
4 | + result = Char[] | |
5 | + for a in atoms | |
6 | + if rand(Bool) | |
7 | + push!(result, rand(Bool) ? a : neg(a)) | |
8 | + end | |
9 | + end | |
10 | + return length(result) > 0 ? join(result) : "λ" | |
11 | +end | |
12 | + | |
13 | +function sample(n::Int, atoms) | |
14 | + result = String[] | |
15 | + for _ in 1:n | |
16 | + push!(result, sample(atoms)) | |
17 | + end | |
18 | + return result | |
19 | +end | |
20 | + | |
21 | +using DelimitedFiles | |
22 | + | |
23 | +abc_atoms = [ 'a', 'b', 'c'] | |
24 | + | |
25 | +open("sample.csv", "w") do io | |
26 | + writedlm(io, [ "event" ]) | |
27 | + writedlm(io, sample(100, abc_atoms), ) | |
28 | +end | |
0 | 29 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,41 @@ |
1 | +from unicodedata import numeric | |
2 | +from sympy import * | |
3 | +from sympy.plotting import plot | |
4 | + | |
5 | +def variants(expr, with_plot=False): | |
6 | + print(f"Expr: {latex(expr)}") | |
7 | + print(f"Simplify: {latex(simplify(expr))}") | |
8 | + print(f"Expand: {latex(expand(expr))}") | |
9 | + print(f"Factor: {latex(factor(expr))}") | |
10 | + if with_plot: | |
11 | + plot(expr, (d, 0, 1, 10),ylabel="$\\mathrm{P(expr \\mid \\alpha = 0.3)}$") | |
12 | + | |
13 | +init_printing(use_unicode=True) | |
14 | + | |
15 | +a, d = symbols('a d') | |
16 | +A = 1 - a | |
17 | +D = 1 - d | |
18 | + | |
19 | +wab = a * d | |
20 | +wac = a * D | |
21 | +wA = A | |
22 | + | |
23 | +wabc = wab * wac | |
24 | +wAb = wA | |
25 | +wa = wab + wac | |
26 | +wb = wab | |
27 | +wc = wac | |
28 | +wE = wab + wab + wA | |
29 | + | |
30 | +z = wabc + 9 * wA + wab + wac + wa + wb +wc + wE | |
31 | +pabc = wabc/z | |
32 | + | |
33 | +z_03 = z.subs(a, 0.3) | |
34 | +wabc_03 = wabc.subs(a, 0.3) | |
35 | +pabc_03 = pabc.subs(a, 0.3) | |
36 | + | |
37 | +variants(z_03) | |
38 | +variants(wabc_03) | |
39 | +variants(pabc_03) | |
40 | +print(solve(wabc_03 - 0.0015 * z_03, d)) | |
41 | + | ... | ... |
... | ... | @@ -0,0 +1,116 @@ |
1 | +{ | |
2 | + "cells": [ | |
3 | + { | |
4 | + "cell_type": "code", | |
5 | + "execution_count": 1, | |
6 | + "metadata": {}, | |
7 | + "outputs": [ | |
8 | + { | |
9 | + "data": { | |
10 | + "text/plain": [ | |
11 | + "4" | |
12 | + ] | |
13 | + }, | |
14 | + "execution_count": 1, | |
15 | + "metadata": {}, | |
16 | + "output_type": "execute_result" | |
17 | + } | |
18 | + ], | |
19 | + "source": [ | |
20 | + "2+2" | |
21 | + ] | |
22 | + }, | |
23 | + { | |
24 | + "cell_type": "code", | |
25 | + "execution_count": 3, | |
26 | + "metadata": {}, | |
27 | + "outputs": [], | |
28 | + "source": [ | |
29 | + "import matplotlib.pyplot as plt\n", | |
30 | + "import numpy as np" | |
31 | + ] | |
32 | + }, | |
33 | + { | |
34 | + "cell_type": "code", | |
35 | + "execution_count": 4, | |
36 | + "metadata": {}, | |
37 | + "outputs": [], | |
38 | + "source": [ | |
39 | + "x = np.linspace(-6, 6)" | |
40 | + ] | |
41 | + }, | |
42 | + { | |
43 | + "cell_type": "code", | |
44 | + "execution_count": 5, | |
45 | + "metadata": {}, | |
46 | + "outputs": [], | |
47 | + "source": [ | |
48 | + "y = np.sin(x)" | |
49 | + ] | |
50 | + }, | |
51 | + { | |
52 | + "cell_type": "code", | |
53 | + "execution_count": 6, | |
54 | + "metadata": {}, | |
55 | + "outputs": [ | |
56 | + { | |
57 | + "data": { | |
58 | + "text/plain": [ | |
59 | + "[<matplotlib.lines.Line2D at 0x7f2d55566b50>]" | |
60 | + ] | |
61 | + }, | |
62 | + "execution_count": 6, | |
63 | + "metadata": {}, | |
64 | + "output_type": "execute_result" | |
65 | + }, | |
66 | + { | |
67 | + "data": { | |
68 | + "image/png": "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", | |
69 | + "text/plain": [ | |
70 | + "<Figure size 640x480 with 1 Axes>" | |
71 | + ] | |
72 | + }, | |
73 | + "metadata": {}, | |
74 | + "output_type": "display_data" | |
75 | + } | |
76 | + ], | |
77 | + "source": [ | |
78 | + "plt.plot(x,y)" | |
79 | + ] | |
80 | + }, | |
81 | + { | |
82 | + "cell_type": "code", | |
83 | + "execution_count": null, | |
84 | + "metadata": {}, | |
85 | + "outputs": [], | |
86 | + "source": [] | |
87 | + } | |
88 | + ], | |
89 | + "metadata": { | |
90 | + "kernelspec": { | |
91 | + "display_name": "Python 3.9.15 ('base')", | |
92 | + "language": "python", | |
93 | + "name": "python3" | |
94 | + }, | |
95 | + "language_info": { | |
96 | + "codemirror_mode": { | |
97 | + "name": "ipython", | |
98 | + "version": 3 | |
99 | + }, | |
100 | + "file_extension": ".py", | |
101 | + "mimetype": "text/x-python", | |
102 | + "name": "python", | |
103 | + "nbconvert_exporter": "python", | |
104 | + "pygments_lexer": "ipython3", | |
105 | + "version": "3.9.15" | |
106 | + }, | |
107 | + "orig_nbformat": 4, | |
108 | + "vscode": { | |
109 | + "interpreter": { | |
110 | + "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
111 | + } | |
112 | + } | |
113 | + }, | |
114 | + "nbformat": 4, | |
115 | + "nbformat_minor": 2 | |
116 | +} | ... | ... |
code/python/.ipynb_checkpoints/EventLattice-checkpoint.ipynb
... | ... | @@ -1,113 +0,0 @@ |
1 | -{ | |
2 | - "cells": [ | |
3 | - { | |
4 | - "cell_type": "code", | |
5 | - "execution_count": null, | |
6 | - "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", | |
7 | - "metadata": {}, | |
8 | - "outputs": [], | |
9 | - "source": [ | |
10 | - "import event_lattice as el" | |
11 | - ] | |
12 | - }, | |
13 | - { | |
14 | - "cell_type": "code", | |
15 | - "execution_count": null, | |
16 | - "id": "00f0eb68", | |
17 | - "metadata": {}, | |
18 | - "outputs": [], | |
19 | - "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", | |
22 | - " event_class = lattice.event_class(event)\n", | |
23 | - " propagated = lattice.propagated_value(\n", | |
24 | - " event, lower_op=lower_op, upper_op=upper_op)\n", | |
25 | - "\n", | |
26 | - " print(\n", | |
27 | - " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" | |
28 | - ] | |
29 | - }, | |
30 | - { | |
31 | - "cell_type": "code", | |
32 | - "execution_count": null, | |
33 | - "id": "cdd8c6d6", | |
34 | - "metadata": {}, | |
35 | - "outputs": [], | |
36 | - "source": [ | |
37 | - "smodels = el.Lattice.parse({\n", | |
38 | - " \"A\": 2,\n", | |
39 | - " \"ab\": 3,\n", | |
40 | - " \"ac\": 5\n", | |
41 | - "})\n", | |
42 | - "\n", | |
43 | - "lattice = el.Lattice(smodels)\n", | |
44 | - "\n", | |
45 | - "print(lattice)" | |
46 | - ] | |
47 | - }, | |
48 | - { | |
49 | - "cell_type": "code", | |
50 | - "execution_count": null, | |
51 | - "id": "2b445339", | |
52 | - "metadata": {}, | |
53 | - "outputs": [], | |
54 | - "source": [ | |
55 | - "zoom_event(\"abc\", lattice)\n", | |
56 | - "zoom_event(\"a\", lattice)\n", | |
57 | - "zoom_event(\"b\", lattice)\n", | |
58 | - "zoom_event(\"bc\", lattice)\n", | |
59 | - "zoom_event(\"ac\", lattice)" | |
60 | - ] | |
61 | - }, | |
62 | - { | |
63 | - "cell_type": "code", | |
64 | - "execution_count": null, | |
65 | - "id": "f1b85255", | |
66 | - "metadata": {}, | |
67 | - "outputs": [], | |
68 | - "source": [ | |
69 | - "from itertools import *\n", | |
70 | - "\n", | |
71 | - "lits = lattice.literals()\n", | |
72 | - "for len_lit in range(len(lits)+1):\n", | |
73 | - " events = list(\"\".join(c) for c in combinations(lits, len_lit))\n", | |
74 | - " for event in events:\n", | |
75 | - " zoom_event(event, lattice)" | |
76 | - ] | |
77 | - }, | |
78 | - { | |
79 | - "cell_type": "code", | |
80 | - "execution_count": null, | |
81 | - "id": "07973a47", | |
82 | - "metadata": {}, | |
83 | - "outputs": [], | |
84 | - "source": [] | |
85 | - } | |
86 | - ], | |
87 | - "metadata": { | |
88 | - "kernelspec": { | |
89 | - "display_name": "Python 3.9.13 ('base')", | |
90 | - "language": "python", | |
91 | - "name": "python3" | |
92 | - }, | |
93 | - "language_info": { | |
94 | - "codemirror_mode": { | |
95 | - "name": "ipython", | |
96 | - "version": 3 | |
97 | - }, | |
98 | - "file_extension": ".py", | |
99 | - "mimetype": "text/x-python", | |
100 | - "name": "python", | |
101 | - "nbconvert_exporter": "python", | |
102 | - "pygments_lexer": "ipython3", | |
103 | - "version": "3.9.13" | |
104 | - }, | |
105 | - "vscode": { | |
106 | - "interpreter": { | |
107 | - "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
108 | - } | |
109 | - } | |
110 | - }, | |
111 | - "nbformat": 4, | |
112 | - "nbformat_minor": 5 | |
113 | -} |
code/python/EventLattice.ipynb
... | ... | @@ -1,154 +0,0 @@ |
1 | -{ | |
2 | - "cells": [ | |
3 | - { | |
4 | - "cell_type": "code", | |
5 | - "execution_count": 4, | |
6 | - "id": "57fc5921-9d6b-4b43-a8f6-743a03650d63", | |
7 | - "metadata": {}, | |
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 | - ], | |
18 | - "source": [ | |
19 | - "%load_ext autoreload\n", | |
20 | - "%autoreload 1\n", | |
21 | - "%aimport event_lattice" | |
22 | - ] | |
23 | - }, | |
24 | - { | |
25 | - "cell_type": "code", | |
26 | - "execution_count": 5, | |
27 | - "id": "00f0eb68", | |
28 | - "metadata": {}, | |
29 | - "outputs": [], | |
30 | - "source": [ | |
31 | - "def zoom_event(event_str, lattice):\n", | |
32 | - " event = event_lattice.Event.from_str(event_str)\n", | |
33 | - " event_class = lattice.event_class(event)\n", | |
34 | - " propagated = lattice.extended_value(\n", | |
35 | - " event)\n", | |
36 | - "\n", | |
37 | - " print(\n", | |
38 | - " f\"Event: {event}\\n\\tClass: {event_class} \\n\\tValue: {propagated}\")" | |
39 | - ] | |
40 | - }, | |
41 | - { | |
42 | - "cell_type": "code", | |
43 | - "execution_count": 6, | |
44 | - "id": "cdd8c6d6", | |
45 | - "metadata": {}, | |
46 | - "outputs": [ | |
47 | - { | |
48 | - "name": "stdout", | |
49 | - "output_type": "stream", | |
50 | - "text": [ | |
51 | - "{\n", | |
52 | - "\t'stable_models': {\n", | |
53 | - "\t\t A: 2,\n", | |
54 | - "\t\tab: 3,\n", | |
55 | - "\t\tac: 5 \n", | |
56 | - "\t}\n", | |
57 | - "\t'literals': { A,B,C,a,b,c } \n", | |
58 | - "}\n" | |
59 | - ] | |
60 | - } | |
61 | - ], | |
62 | - "source": [ | |
63 | - "smodels = event_lattice.Lattice.parse({\n", | |
64 | - " \"A\": 2,\n", | |
65 | - " \"ab\": 3,\n", | |
66 | - " \"ac\": 5\n", | |
67 | - "})\n", | |
68 | - "\n", | |
69 | - "lattice = event_lattice.Lattice(smodels)\n", | |
70 | - "\n", | |
71 | - "print(lattice)" | |
72 | - ] | |
73 | - }, | |
74 | - { | |
75 | - "cell_type": "code", | |
76 | - "execution_count": 7, | |
77 | - "id": "2b445339", | |
78 | - "metadata": {}, | |
79 | - "outputs": [ | |
80 | - { | |
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'" | |
91 | - ] | |
92 | - } | |
93 | - ], | |
94 | - "source": [ | |
95 | - "zoom_event(\"abc\", lattice)\n", | |
96 | - "zoom_event(\"a\", lattice)\n", | |
97 | - "zoom_event(\"b\", lattice)\n", | |
98 | - "zoom_event(\"bc\", lattice)\n", | |
99 | - "zoom_event(\"ac\", lattice)" | |
100 | - ] | |
101 | - }, | |
102 | - { | |
103 | - "cell_type": "code", | |
104 | - "execution_count": null, | |
105 | - "id": "f1b85255", | |
106 | - "metadata": {}, | |
107 | - "outputs": [], | |
108 | - "source": [ | |
109 | - "from itertools import *\n", | |
110 | - "\n", | |
111 | - "lits = lattice.literals()\n", | |
112 | - "events = []\n", | |
113 | - "for len_lit in range(len(lits)+1):\n", | |
114 | - " events = events + list(\"\".join(c) for c in combinations(lits, len_lit))\n", | |
115 | - "for event in events:\n", | |
116 | - " zoom_event(event, lattice)" | |
117 | - ] | |
118 | - }, | |
119 | - { | |
120 | - "cell_type": "code", | |
121 | - "execution_count": null, | |
122 | - "id": "07973a47", | |
123 | - "metadata": {}, | |
124 | - "outputs": [], | |
125 | - "source": [] | |
126 | - } | |
127 | - ], | |
128 | - "metadata": { | |
129 | - "kernelspec": { | |
130 | - "display_name": "Python 3 (ipykernel)", | |
131 | - "language": "python", | |
132 | - "name": "python3" | |
133 | - }, | |
134 | - "language_info": { | |
135 | - "codemirror_mode": { | |
136 | - "name": "ipython", | |
137 | - "version": 3 | |
138 | - }, | |
139 | - "file_extension": ".py", | |
140 | - "mimetype": "text/x-python", | |
141 | - "name": "python", | |
142 | - "nbconvert_exporter": "python", | |
143 | - "pygments_lexer": "ipython3", | |
144 | - "version": "3.9.15" | |
145 | - }, | |
146 | - "vscode": { | |
147 | - "interpreter": { | |
148 | - "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
149 | - } | |
150 | - } | |
151 | - }, | |
152 | - "nbformat": 4, | |
153 | - "nbformat_minor": 5 | |
154 | -} |
code/python/__init__.py
code/python/__pycache__/event_lattice.cpython-39.pyc
No preview for this file type
code/python/algebra.py
... | ... | @@ -1,30 +0,0 @@ |
1 | -from itertools import combinations, product | |
2 | - | |
3 | -def fmt(expr): | |
4 | - """Doc string""" | |
5 | - return ",".join(f"{x:>2}" for x in expr) | |
6 | - | |
7 | -def c(expr): | |
8 | - """Doc string""" | |
9 | - def litcomp(x): | |
10 | - if x == "⊤": | |
11 | - return "⊥" | |
12 | - elif x == "⊥": | |
13 | - return "⊤" | |
14 | - elif x[0] == "¬": | |
15 | - return x[1:] | |
16 | - else: | |
17 | - return f"¬{x}" | |
18 | - return [litcomp(x) for x in expr] | |
19 | - | |
20 | -def domain(symbols, unary="¬"): | |
21 | - """Doc string""" | |
22 | - atoms = list(symbols) | |
23 | - literals = [ | |
24 | - [f"{u}{a}" for u in unary] + | |
25 | - [a, "⊤", "⊥"] for a in atoms ] | |
26 | - return product(*literals) | |
27 | - | |
28 | -d = sorted(domain("abc")) | |
29 | -for x in d: | |
30 | - print(f"{fmt(x)} | {fmt(c(x))}") |
code/python/api_01.py
... | ... | @@ -1,26 +0,0 @@ |
1 | -from clingo.symbol import Number | |
2 | -from clingo.control import Control | |
3 | - | |
4 | -class Context: | |
5 | - def inc(self, x): | |
6 | - return Number(x.number + 1) | |
7 | - | |
8 | - def seq(self, x, y): | |
9 | - return [x, y] | |
10 | - | |
11 | -def on_model(m): | |
12 | - print(m) | |
13 | - | |
14 | -ctl = Control() | |
15 | -ctl.add("base", [], """\ | |
16 | -p(@inc(10)). | |
17 | -q(@seq(1,2)). | |
18 | -""") | |
19 | - | |
20 | -ctl.ground( | |
21 | - [("base", [])], | |
22 | - context=Context()) | |
23 | - | |
24 | -s = ctl.solve(on_model=on_model) | |
25 | - | |
26 | -print(s) | |
27 | 0 | \ No newline at end of file |
code/python/event_lattice.py
... | ... | @@ -1,301 +0,0 @@ |
1 | -import math | |
2 | -from functools import cache | |
3 | -from itertools import accumulate, combinations, chain, groupby | |
4 | -import operator | |
5 | - | |
6 | - | |
7 | - | |
8 | -def uniform_op(x): | |
9 | - n = len(list(x)) | |
10 | - return 1.0 if n == 0 else 1.0/n | |
11 | - | |
12 | - | |
13 | -def max_op(x): | |
14 | - return max(x) | |
15 | - | |
16 | - | |
17 | -def min_op(x): | |
18 | - return min(x) | |
19 | - | |
20 | - | |
21 | -def sum_op(x): | |
22 | - return sum(x) | |
23 | - | |
24 | - | |
25 | -def stableprod_op(x): | |
26 | - log_x = map(math.log, x) | |
27 | - return math.exp(sum(log_x)) | |
28 | - | |
29 | - | |
30 | -def prod_op(x): | |
31 | - return list(accumulate(x, func=lambda a,b: a*b))[-1] | |
32 | - | |
33 | - | |
34 | -class Event: | |
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 | - """ | |
42 | - | |
43 | - @staticmethod | |
44 | - def _parse(text): | |
45 | - return frozenset(text) | |
46 | - | |
47 | - @staticmethod | |
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)) | |
54 | - | |
55 | - | |
56 | - def __init__(self, literals): | |
57 | - """Instantiate from a (frozen) set of literals. | |
58 | - For example: e = Event(frozenset("abc")).""" | |
59 | - self._literals = frozenset(literals) | |
60 | - | |
61 | - | |
62 | - def literals(self): | |
63 | - return self._literals | |
64 | - | |
65 | - | |
66 | - def __iter__(self): | |
67 | - return self._literals.__iter__() | |
68 | - | |
69 | - @cache | |
70 | - def is_consistent(self): | |
71 | - """True if this event is consistent.""" | |
72 | - return all(x.swapcase() not in self._literals for x in self._literals) | |
73 | - | |
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) | |
80 | - | |
81 | - def invert(self): | |
82 | - """Negation of this event. | |
83 | - | |
84 | - See the method "co" | |
85 | - """ | |
86 | - return self.co() | |
87 | - | |
88 | - def __repr__(self) -> str: | |
89 | - return ''.join(str(x) for x in sorted(self._literals)) if len(self._literals) > 0 else '0' | |
90 | - | |
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__() | |
104 | - | |
105 | - | |
106 | - def __eq__(self, other): | |
107 | - """Event equality test.""" | |
108 | - return self._literals.__eq__(other._literals) | |
109 | - | |
110 | - def __or__(self, other): | |
111 | - """Event union operation.""" | |
112 | - return Event(self._literals | other._literals) | |
113 | - | |
114 | - def __le__(self, other): | |
115 | - """Event subset test.""" | |
116 | - return self._literals.__le__(other._literals) | |
117 | - | |
118 | - | |
119 | - def __lt__(self, other): | |
120 | - """Event strict subset test.""" | |
121 | - return self._literals.__lt__(other._literals) | |
122 | - | |
123 | - | |
124 | - def __ne__(self, other): | |
125 | - """Event not-equal test.""" | |
126 | - return self._literals.__ne__(other._literals) | |
127 | - | |
128 | - | |
129 | - def __ge__(self, other): | |
130 | - """Event superset test.""" | |
131 | - return self._literals.__ge__(other._literals) | |
132 | - | |
133 | - | |
134 | - def __gt__(self, other): | |
135 | - """Event strict superset test.""" | |
136 | - return self._literals.__gt__(other._literals) | |
137 | - | |
138 | - | |
139 | -class Lattice: | |
140 | - | |
141 | - @staticmethod | |
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 | - """ | |
156 | - result = dict() | |
157 | - for k, v in d.items(): | |
158 | - key = Event.parse(k) | |
159 | - result[key] = v | |
160 | - return result | |
161 | - | |
162 | - | |
163 | - @staticmethod | |
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] | |
169 | - lits = set() | |
170 | - for x in base_lits.literals(): | |
171 | - lits.add(x) | |
172 | - lits.add(x.swapcase()) | |
173 | - return sorted(lits) | |
174 | - | |
175 | - def __init__(self, smodels_dict): | |
176 | - """Create an Events lattice.""" | |
177 | - self._smodels = smodels_dict | |
178 | - self._literals = Lattice.close_literals(self._smodels.keys()) | |
179 | - | |
180 | - def literals(self): | |
181 | - """The literals in this lattice.""" | |
182 | - return self._literals | |
183 | - | |
184 | - @cache | |
185 | - def stable_models(self): | |
186 | - """The stable models that generate this lattice.""" | |
187 | - return self._smodels.keys() | |
188 | - | |
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)) | |
193 | - | |
194 | - @cache | |
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) | |
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 | |
220 | - | |
221 | - | |
222 | - def related(self, u, v): | |
223 | - """Tests if two events are related.""" | |
224 | - u_consistent = u.is_consistent() | |
225 | - v_consistent = v.is_consistent() | |
226 | - if u_consistent and (u_consistent == v_consistent): | |
227 | - return self.stable_core(u) == self.stable_core(v) | |
228 | - else: | |
229 | - return u_consistent == v_consistent | |
230 | - | |
231 | - def extended_value(self, event:Event, | |
232 | - op=prod_op): | |
233 | - """TODO: well...""" | |
234 | - value = 0 | |
235 | - # | |
236 | - # INCONSISTENT EVENTS | |
237 | - # | |
238 | - if not event.is_consistent(): | |
239 | - return value | |
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]] | |
250 | - else: | |
251 | - value = op(map(lambda sm: self._smodels[sm], score)) | |
252 | - | |
253 | - return value | |
254 | - | |
255 | - def __repr__(self): | |
256 | - smodels_repr = ',\n\t\t'.join(f"{k}: {v:<}" for k,v in self._smodels.items()) | |
257 | - lits_repr = ','.join(sorted(self._literals)) | |
258 | - | |
259 | - return "{\n" +\ | |
260 | - f"\t'stable_models': {{\n\t\t {smodels_repr} \n\t}}\n" +\ | |
261 | - f"\t'literals': {{ {lits_repr} }} \n" +\ | |
262 | - "}" | |
263 | - | |
264 | -# class EventsClass: | |
265 | -# def __init__(self, core, lattice:Lattice): | |
266 | -# self._core = core | |
267 | -# self._lattice = lattice | |
268 | - | |
269 | -# def __repr__(self): | |
270 | -# core_repr = "" if len(self._core) == 0 else ",".join(str(x) for x in self._core) | |
271 | -# return f"<{core_repr}>" | |
272 | - | |
273 | -# def __contains__(self, event:Event): | |
274 | -# return self.lattice.stable_core(event) == self._core | |
275 | - | |
276 | -if __name__ == "__main__": | |
277 | - def zoom_event(event_str, lattice): | |
278 | - event = Event.parse(event_str) | |
279 | - event_class = lattice.event_class(event) | |
280 | - propagated = lattice.extended_value( | |
281 | - event) | |
282 | - | |
283 | - print( | |
284 | - f"Event: {event}\n\tClass: {event_class} \n\tValue: {propagated}") | |
285 | - | |
286 | - smodels = Lattice.parse({ | |
287 | - "A": 2, | |
288 | - "ab": 3, | |
289 | - "ac": 5 | |
290 | - }) | |
291 | - | |
292 | - lattice = Lattice(smodels) | |
293 | - | |
294 | - ev_classes = lattice.classes() | |
295 | - for k,g in ev_classes.items(): | |
296 | - print(f"{tuple(s.latex() for s in k)} {set(e.latex() for e in g)}") | |
297 | - # zoom_event("abc", lattice) | |
298 | - # zoom_event("a", lattice) | |
299 | - # zoom_event("b", lattice) | |
300 | - # zoom_event("bc", lattice) | |
301 | - # zoom_event("ac", lattice) | |
302 | 0 | \ No newline at end of file |
code/python/explore_01.py
... | ... | @@ -1,13 +0,0 @@ |
1 | -from clingo.control import Control | |
2 | -from clingox.program import Program, ProgramObserver, Remapping | |
3 | - | |
4 | -prg = Program() | |
5 | -ctl_a = Control() | |
6 | -ctl_a.register_observer(ProgramObserver(prg)) | |
7 | -print(f"<1>\n{prg}\n</1>") | |
8 | - | |
9 | -prog = "code/asp/alarm.lp" | |
10 | -ctl_a.load(prog) | |
11 | -ctl_a.ground([('base', [])]) | |
12 | -print(f"<2>\n{prg}\n</2>") | |
13 | - |
code/python/symbops.py
... | ... | @@ -1,41 +0,0 @@ |
1 | -from unicodedata import numeric | |
2 | -from sympy import * | |
3 | -from sympy.plotting import plot | |
4 | - | |
5 | -def variants(expr, with_plot=False): | |
6 | - print(f"Expr: {latex(expr)}") | |
7 | - print(f"Simplify: {latex(simplify(expr))}") | |
8 | - print(f"Expand: {latex(expand(expr))}") | |
9 | - print(f"Factor: {latex(factor(expr))}") | |
10 | - if with_plot: | |
11 | - plot(expr, (d, 0, 1, 10),ylabel="$\\mathrm{P(expr \\mid \\alpha = 0.3)}$") | |
12 | - | |
13 | -init_printing(use_unicode=True) | |
14 | - | |
15 | -a, d = symbols('a d') | |
16 | -A = 1 - a | |
17 | -D = 1 - d | |
18 | - | |
19 | -wab = a * d | |
20 | -wac = a * D | |
21 | -wA = A | |
22 | - | |
23 | -wabc = wab * wac | |
24 | -wAb = wA | |
25 | -wa = wab + wac | |
26 | -wb = wab | |
27 | -wc = wac | |
28 | -wE = wab + wab + wA | |
29 | - | |
30 | -z = wabc + 9 * wA + wab + wac + wa + wb +wc + wE | |
31 | -pabc = wabc/z | |
32 | - | |
33 | -z_03 = z.subs(a, 0.3) | |
34 | -wabc_03 = wabc.subs(a, 0.3) | |
35 | -pabc_03 = pabc.subs(a, 0.3) | |
36 | - | |
37 | -variants(z_03) | |
38 | -variants(wabc_03) | |
39 | -variants(pabc_03) | |
40 | -print(solve(wabc_03 - 0.0015 * z_03, d)) | |
41 | - |
code/python/teste.ipynb
... | ... | @@ -1,116 +0,0 @@ |
1 | -{ | |
2 | - "cells": [ | |
3 | - { | |
4 | - "cell_type": "code", | |
5 | - "execution_count": 1, | |
6 | - "metadata": {}, | |
7 | - "outputs": [ | |
8 | - { | |
9 | - "data": { | |
10 | - "text/plain": [ | |
11 | - "4" | |
12 | - ] | |
13 | - }, | |
14 | - "execution_count": 1, | |
15 | - "metadata": {}, | |
16 | - "output_type": "execute_result" | |
17 | - } | |
18 | - ], | |
19 | - "source": [ | |
20 | - "2+2" | |
21 | - ] | |
22 | - }, | |
23 | - { | |
24 | - "cell_type": "code", | |
25 | - "execution_count": 3, | |
26 | - "metadata": {}, | |
27 | - "outputs": [], | |
28 | - "source": [ | |
29 | - "import matplotlib.pyplot as plt\n", | |
30 | - "import numpy as np" | |
31 | - ] | |
32 | - }, | |
33 | - { | |
34 | - "cell_type": "code", | |
35 | - "execution_count": 4, | |
36 | - "metadata": {}, | |
37 | - "outputs": [], | |
38 | - "source": [ | |
39 | - "x = np.linspace(-6, 6)" | |
40 | - ] | |
41 | - }, | |
42 | - { | |
43 | - "cell_type": "code", | |
44 | - "execution_count": 5, | |
45 | - "metadata": {}, | |
46 | - "outputs": [], | |
47 | - "source": [ | |
48 | - "y = np.sin(x)" | |
49 | - ] | |
50 | - }, | |
51 | - { | |
52 | - "cell_type": "code", | |
53 | - "execution_count": 6, | |
54 | - "metadata": {}, | |
55 | - "outputs": [ | |
56 | - { | |
57 | - "data": { | |
58 | - "text/plain": [ | |
59 | - "[<matplotlib.lines.Line2D at 0x7f2d55566b50>]" | |
60 | - ] | |
61 | - }, | |
62 | - "execution_count": 6, | |
63 | - "metadata": {}, | |
64 | - "output_type": "execute_result" | |
65 | - }, | |
66 | - { | |
67 | - "data": { | |
68 | - "image/png": "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", | |
69 | - "text/plain": [ | |
70 | - "<Figure size 640x480 with 1 Axes>" | |
71 | - ] | |
72 | - }, | |
73 | - "metadata": {}, | |
74 | - "output_type": "display_data" | |
75 | - } | |
76 | - ], | |
77 | - "source": [ | |
78 | - "plt.plot(x,y)" | |
79 | - ] | |
80 | - }, | |
81 | - { | |
82 | - "cell_type": "code", | |
83 | - "execution_count": null, | |
84 | - "metadata": {}, | |
85 | - "outputs": [], | |
86 | - "source": [] | |
87 | - } | |
88 | - ], | |
89 | - "metadata": { | |
90 | - "kernelspec": { | |
91 | - "display_name": "Python 3.9.15 ('base')", | |
92 | - "language": "python", | |
93 | - "name": "python3" | |
94 | - }, | |
95 | - "language_info": { | |
96 | - "codemirror_mode": { | |
97 | - "name": "ipython", | |
98 | - "version": 3 | |
99 | - }, | |
100 | - "file_extension": ".py", | |
101 | - "mimetype": "text/x-python", | |
102 | - "name": "python", | |
103 | - "nbconvert_exporter": "python", | |
104 | - "pygments_lexer": "ipython3", | |
105 | - "version": "3.9.15" | |
106 | - }, | |
107 | - "orig_nbformat": 4, | |
108 | - "vscode": { | |
109 | - "interpreter": { | |
110 | - "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217" | |
111 | - } | |
112 | - } | |
113 | - }, | |
114 | - "nbformat": 4, | |
115 | - "nbformat_minor": 2 | |
116 | -} |
... | ... | @@ -0,0 +1,100 @@ |
1 | +c | |
2 | +a | |
3 | +B | |
4 | +c | |
5 | +ab | |
6 | +Ac | |
7 | +aBC | |
8 | +BC | |
9 | +Ab | |
10 | +b | |
11 | +c | |
12 | +AB | |
13 | +Ac | |
14 | +B | |
15 | +bC | |
16 | +Ab | |
17 | + | |
18 | +aB | |
19 | +B | |
20 | +a | |
21 | +aC | |
22 | +B | |
23 | +AB | |
24 | +B | |
25 | + | |
26 | +C | |
27 | +bc | |
28 | + | |
29 | +B | |
30 | +bc | |
31 | +AC | |
32 | +ABC | |
33 | +a | |
34 | +b | |
35 | +ac | |
36 | +AC | |
37 | +B | |
38 | +bC | |
39 | +b | |
40 | +C | |
41 | + | |
42 | +aC | |
43 | +AbC | |
44 | + | |
45 | +C | |
46 | +AC | |
47 | +bc | |
48 | + | |
49 | + | |
50 | +C | |
51 | +b | |
52 | + | |
53 | +b | |
54 | +abc | |
55 | +a | |
56 | +abc | |
57 | + | |
58 | +B | |
59 | +a | |
60 | +C | |
61 | +aB | |
62 | + | |
63 | +A | |
64 | +Bc | |
65 | +C | |
66 | +AB | |
67 | +aBc | |
68 | +A | |
69 | +b | |
70 | + | |
71 | +a | |
72 | +a | |
73 | +c | |
74 | +b | |
75 | +a | |
76 | +A | |
77 | +Ab | |
78 | +aC | |
79 | + | |
80 | +B | |
81 | +C | |
82 | +Ab | |
83 | +Bc | |
84 | +A | |
85 | +Ac | |
86 | +c | |
87 | +B | |
88 | +AC | |
89 | +ABC | |
90 | +Ab | |
91 | +aC | |
92 | +bC | |
93 | + | |
94 | + | |
95 | +C | |
96 | +a | |
97 | + | |
98 | +ABC | |
99 | +b | |
100 | +aB | ... | ... |
students/amartins/tarefas/tarefa2.py
... | ... | @@ -26,13 +26,20 @@ if __name__ == "__main__": |
26 | 26 | parents = model.get_parents(node) |
27 | 27 | s = "" |
28 | 28 | if len(parents) == 0: |
29 | - s += str(yes_prob) + " :: " + str(node) | |
29 | + s += str(yes_prob) + " :: " + str(node) +"\n" | |
30 | 30 | print(s) |
31 | 31 | elif len(parents) == 1: |
32 | - s += str(yes_prob[0]) + " :: " + str(node) + " <- " + str(parents) + "\n" | |
33 | - s += str(yes_prob[1]) + " :: " + str(node) + " <- -" + str(parents) + "\n" | |
32 | + p = parents[0] | |
33 | + s += str(yes_prob[0]) + " :: " + str(node) + " <- " + str(p) + "\n" | |
34 | + s += str(yes_prob[1]) + " :: " + str(node) + " <- -" + str(p) + "\n" | |
34 | 35 | print(s) |
35 | 36 | else: |
36 | - print("Node:", node) | |
37 | - print("Probability of 'yes':", yes_prob) | |
38 | - print() | |
37 | + yes1 = yes_prob[0] | |
38 | + yes2 = yes_prob[1] | |
39 | + p0 = parents[0] | |
40 | + p1 = parents[1] | |
41 | + s += str(yes1[0]) + " :: " + str(node) + " <- " + str(p0) + ", " + str(p1) + "\n" | |
42 | + s += str(yes2[0]) + " :: " + str(node) + " <- -" + str(p0) + ", " + str(p1) + "\n" | |
43 | + s += str(yes1[1]) + " :: " + str(node) + " <- " + str(p0) + ", -" + str(p1) + "\n" | |
44 | + s += str(yes2[1]) + " :: " + str(node) + " <- -" + str(p0) + ", -" + str(p1) + "\n" | |
45 | + print(s) | ... | ... |
text/paper_01/pre-paper.pdf
No preview for this file type
text/paper_01/pre-paper.tex
... | ... | @@ -17,7 +17,7 @@ proptc/.style = {-latex, dashed}, |
17 | 17 | propsm/.style = {-latex, thick}, |
18 | 18 | doubt/.style = {gray} |
19 | 19 | } |
20 | -\usetikzlibrary{calc, positioning} | |
20 | +\usetikzlibrary{calc, positioning, patterns} | |
21 | 21 | |
22 | 22 | \usepackage{hyperref} |
23 | 23 | \hypersetup{ |
... | ... | @@ -93,16 +93,18 @@ citecolor=blue, |
93 | 93 | \acrodef{SC}[SC]{stable core} |
94 | 94 | \acrodef{KL}[KL]{Kullback-Leibler} |
95 | 95 | |
96 | -\title{Zugzwang\\\emph{Logic and Artificial Intelligence}\\{\bruno Why this title?}} | |
96 | +\title{An Algebraic Approach to Stochastic ASP | |
97 | + %Zugzwang\\\emph{Logic and Artificial Intelligence}\\{\bruno Why this title?} | |
98 | + } | |
97 | 99 | |
98 | 100 | \author{ |
99 | 101 | \begin{tabular}{ccc} |
100 | 102 | Francisco Coelho |
101 | - \footnote{Universidade de Évora} | |
103 | + \footnote{Universidade de Évora, NOVALINCS, High Performance Computing Chair} | |
102 | 104 | & Bruno Dinis |
103 | - \footnote{Universidade de Évora} | |
105 | + \footnote{Universidade de Évora, CIMA, CMAFcIO} | |
104 | 106 | & Salvador Abreu |
105 | - \footnote{Universidade de Évora} | |
107 | + \footnote{Universidade de Évora, NOVALINCS} | |
106 | 108 | \\ |
107 | 109 | \texttt{fc@uevora.pt} |
108 | 110 | & \texttt{bruno.dinis@uevora.pt} |
... | ... | @@ -148,8 +150,9 @@ Our idea to extend probabilities starts with the stance that a specification des |
148 | 150 | Extending probability from \acp{TC} to \acp{SM} faces a critical problem, illustrated by the example in \cref{sec:example.1}, concerning situations where multiple \acp{SM}, $ab$ and $ac$, result from a single \ac{TC}, $a$, but there is not enough information (in the specification) to assign a single probability to each \ac{SM}. We propose to address this issue by using algebraic variables to describe that lack of information and then estimate the value of those variables from empirical data. |
149 | 151 | |
150 | 152 | In a related work, \cite{verreet2022inference}, epistemic uncertainty (or model uncertainty) is considered as a lack of knowledge about the underlying model, that may be mitigated via further observations. This seems to presuppose a Bayesian approach to imperfect knowledge in the sense that having further observations allows to improve/correct the model. Indeed, the approach in that work uses Beta distributions in order to be able to learn the full distribution. This approach seems to be specially fitted to being able to tell when some probability lies beneath some given value. \todo{Our approach seems to be similar in spirit. If so, we should mention this in the introduction.} |
153 | +\todo{Also remark that our apporach remains algebraic in the way that we address the problems concerning the extension of probabilities.} | |
151 | 154 | |
152 | -\todo{cite \cite{sympy} \franc{--- why here? but cite \cite{cozman2020joy} and relate with our work.}} | |
155 | +\todo{cite \citetitle{sympy} \franc{--- why here? but cite \citetitle{cozman2020joy} and relate with our work.}} | |
153 | 156 | |
154 | 157 | \todo{Discuss the least informed strategy and the corolary that \aclp{SM} should be conditionally independent on the \acl{TC}.} |
155 | 158 | |
... | ... | @@ -239,6 +242,8 @@ The \aclp{SM} $ab, ac$ from \cref{running.example} result from the clause $b \v |
239 | 242 | |
240 | 243 | \draw[doubt] (ac) to[bend right] (abc); |
241 | 244 | \draw[doubt] (ac) to[bend left] (aBc); |
245 | + | |
246 | + \draw[doubt, dash dot] (Ac) to (Abc); | |
242 | 247 | |
243 | 248 | \draw[doubt] (A) to (Ac); |
244 | 249 | \draw[doubt] (A) to (Abc); |
... | ... | @@ -251,10 +256,10 @@ The \aclp{SM} $ab, ac$ from \cref{running.example} result from the clause $b \v |
251 | 256 | \draw[doubt] (ac) to (c); |
252 | 257 | % \draw[doubt] (ab) to[bend left] (a); |
253 | 258 | % \draw[doubt] (ac) to[bend right] (a); |
254 | - \draw[doubt] (c) to[bend right] (bc); | |
255 | - \draw[doubt] (abc) to[bend left] (bc); | |
256 | - \draw[doubt] (Abc) to (bc); | |
257 | - \draw[doubt] (c) to[bend right] (Ac); | |
259 | + \draw[doubt, dash dot] (c) to[bend right] (bc); | |
260 | + \draw[doubt, dash dot] (abc) to[bend left] (bc); | |
261 | + \draw[doubt, dash dot] (bc) to (Abc); | |
262 | + \draw[doubt, dash dot] (c) to[bend right] (Ac); | |
258 | 263 | \end{tikzpicture} |
259 | 264 | \end{center} |
260 | 265 | |
... | ... | @@ -287,7 +292,7 @@ The diagram in \cref{fig:running.example} illustrates the problem of extending p |
287 | 292 | \node[event, above = of A] (Ac) {$\co{a}c$}; |
288 | 293 | \node[event, above right = of Ac] (Abc) {$\co{a}bc$}; |
289 | 294 | % ---- |
290 | - \path[draw, rounded corners, fill=cyan, fill opacity=0.1] | |
295 | + \path[draw, rounded corners, pattern=north west lines, opacity=0.2] | |
291 | 296 | (ab.west) -- |
292 | 297 | (ab.north west) -- |
293 | 298 | % |
... | ... | @@ -316,7 +321,7 @@ The diagram in \cref{fig:running.example} illustrates the problem of extending p |
316 | 321 | (ab.west) |
317 | 322 | ; |
318 | 323 | % ---- |
319 | - \path[draw, rounded corners, fill=magenta, fill opacity=0.1] | |
324 | + \path[draw, rounded corners, pattern=north east lines, opacity=0.2] | |
320 | 325 | (ac.south west) -- |
321 | 326 | (ac.west) -- |
322 | 327 | (ac.north west) -- |
... | ... | @@ -346,7 +351,7 @@ The diagram in \cref{fig:running.example} illustrates the problem of extending p |
346 | 351 | (ac.south west) |
347 | 352 | ; |
348 | 353 | % ---- |
349 | - \path[draw, rounded corners, fill=yellow, fill opacity=0.1] | |
354 | + \path[draw, rounded corners, pattern=horizontal lines, opacity=0.2] | |
350 | 355 | % (A.north west) -- |
351 | 356 | % |
352 | 357 | (Ac.north west) -- |
... | ... | @@ -373,7 +378,7 @@ The diagram in \cref{fig:running.example} illustrates the problem of extending p |
373 | 378 | \end{tikzpicture} |
374 | 379 | \end{center} |
375 | 380 | |
376 | - \caption{Classes (of consistent events) related to the \aclp{SM} of \cref{running.example} are defined through inclusions. \todo{write the caption}} | |
381 | + \caption{Classes (of consistent events) related to the \aclp{SM} of \cref{running.example} are defined through intersections and inclusions. \todo{write the caption}} | |
377 | 382 | \label{fig:running.example.classes} |
378 | 383 | \end{figure} |
379 | 384 | |
... | ... | @@ -559,7 +564,7 @@ The ``extension'' phase, traced by equations (\ref{eq:prob.total.choice}) and (\ |
559 | 564 | \pw{\class{e}} := \sum_{t \in \fml{T}} \pw{\class{e}, t}\pw{t}. |
560 | 565 | \label{eq:weight.class.unconditional} |
561 | 566 | \end{equation} |
562 | - \remark{}{Changed from $\prod$ to $\sum$ to represent ``either'' instead of ``both'' since the later is not consistent with the ``only one stable model at a time'' assumption.} | |
567 | + | |
563 | 568 | \end{description} |
564 | 569 | % |
565 | 570 | \item[Events.] \label{item:event.cases} Each (general) event $e$ is in the class defined by its \acl{SC}, $\stablecore{e}$. So, we set: |
... | ... | @@ -618,9 +623,9 @@ We continue with the specification from Equation \eqref{eq:example.1}. |
618 | 623 | \item[\Aclp{SM}.] The $\theta_{s,t}$ parameters in this example are |
619 | 624 | $$ |
620 | 625 | \theta_{ab,\co{a}} = \theta_{ac,\co{a}} = \theta_{\co{a}, a} = 0 |
621 | - $$ | |
622 | - and | |
623 | - $$ | |
626 | + % | |
627 | + \text{~and~} | |
628 | + % | |
624 | 629 | \theta_{\co{a}, \co{a}} = 1, \theta_{ab, a} = \theta, \theta_{ac, a} = \co{\theta} |
625 | 630 | $$ |
626 | 631 | with $\theta \in \intcc{0, 1}$. |
... | ... | @@ -675,7 +680,7 @@ We continue with the specification from Equation \eqref{eq:example.1}. |
675 | 680 | & 1 |
676 | 681 | \end{array} |
677 | 682 | \end{equation*} |
678 | - \item[Normalization.] To get a weight that sums up to one, we compute the \emph{normalization factor}. Since $\pw{\cdot}$ is constant on classes, | |
683 | + \item[Normalization.] To get a weight that sums up to one, we compute the \emph{normalization factor}. Since $\pw{\cdot}$ is constant on classes,\todo{prove that we get a probability.} | |
679 | 684 | \begin{equation*} |
680 | 685 | Z := \sum_{e\in\fml{E}} \pw{e} |
681 | 686 | = \sum_{\class{e} \in\class{\fml{E}}} \frac{\pw{\class{e}}}{\#\class{e}}, |
... | ... | @@ -704,95 +709,81 @@ We continue with the specification from Equation \eqref{eq:example.1}. |
704 | 709 | & 0 |
705 | 710 | & 0 |
706 | 711 | & 0 |
707 | - \\ | |
712 | + \\[4pt] | |
708 | 713 | % |
709 | 714 | \indepclass |
710 | 715 | & 9 |
711 | 716 | & 0 |
712 | 717 | & 0 |
713 | 718 | & 0 |
714 | - \\ | |
719 | + \\[4pt] | |
715 | 720 | % |
716 | 721 | \co{a} |
717 | 722 | & 9 |
718 | - & \lfrac{7}{10} | |
719 | - & \lfrac{7}{90} | |
720 | - & \lfrac{7}{792} | |
721 | - \\ | |
723 | + & \frac{7}{10} | |
724 | + & \frac{7}{90} | |
725 | + & \frac{7}{792} | |
726 | + \\[4pt] | |
722 | 727 | % |
723 | 728 | ab |
724 | 729 | & 3 |
725 | - & \lfrac{3\theta}{10} | |
726 | - & \lfrac{\theta}{10} | |
727 | - & \lfrac{\theta}{88} | |
728 | - \\ | |
730 | + & \frac{3\theta}{10} | |
731 | + & \frac{\theta}{10} | |
732 | + & \frac{\theta}{88} | |
733 | + \\[4pt] | |
729 | 734 | % |
730 | 735 | ac |
731 | 736 | & 3 |
732 | - & \lfrac{3\co{\theta}}{10} | |
733 | - & \lfrac{\co{\theta}}{10} | |
734 | - & \lfrac{\co{\theta}}{88} | |
735 | - \\ | |
737 | + & \frac{3\co{\theta}}{10} | |
738 | + & \frac{\co{\theta}}{10} | |
739 | + & \frac{\co{\theta}}{88} | |
740 | + \\[4pt] | |
736 | 741 | % |
737 | 742 | \co{a}, ab |
738 | 743 | & 0 |
739 | - & | |
740 | - & | |
741 | - & | |
742 | - \\ | |
744 | + & \frac{7 + 3\theta}{10} | |
745 | + & 0 | |
746 | + & 0 | |
747 | + \\[4pt] | |
743 | 748 | % |
744 | 749 | \co{a}, ac |
745 | 750 | & 0 |
746 | - & | |
747 | - & | |
748 | - & | |
751 | + & \frac{7 + 3\co{\theta}}{10} | |
752 | + & 0 | |
753 | + & 0 | |
749 | 754 | % |
750 | - \\ | |
755 | + \\[4pt] | |
751 | 756 | % |
752 | 757 | ab, ac |
753 | 758 | & 2 |
754 | - & \lfrac{3}{10} | |
755 | - & \lfrac{3}{20} | |
756 | - & \lfrac{3}{176} | |
757 | - \\ | |
759 | + & \frac{3}{10} | |
760 | + & \frac{3}{20} | |
761 | + & \frac{3}{176} | |
762 | + \\[4pt] | |
758 | 763 | % |
759 | 764 | \co{a}, ab, ac |
760 | 765 | & 1 |
761 | 766 | & 1 |
762 | 767 | & 1 |
763 | - & \lfrac{5}{176} | |
764 | - \\ | |
768 | + & \frac{5}{176} | |
769 | + \\[4pt] | |
765 | 770 | % |
766 | 771 | \hline |
767 | 772 | & |
768 | - & Z = 8.8 | |
773 | + & Z = \frac{44}{5} | |
769 | 774 | \end{array} |
770 | 775 | \end{equation*} |
771 | 776 | \end{description} |
777 | + | |
778 | +\todo{Continue this example with a set of observations to estimate $\theta$ and try to show some more. For example, that the resulting distribution is not very good when $t = \co{a}$. Also gather a sample following the specification.} | |
772 | 779 | % |
773 | 780 | % |
774 | 781 | % |
775 | -\subsection{A Not So Simple Example} | |
776 | - | |
777 | -\todo{this subsection} | |
778 | - | |
779 | -In this section we see how the classical example of the Burglary, Earthquake, Alarm \cite{Judea88} works in our setting. This example is a commonly used example in Bayesian networks because it illustrates reasoning under uncertainty. The gist of example is given in \cref{Figure_Alarm}. It involves a simple network of events and conditional probabilities. | |
780 | - | |
781 | -The events are: Burglary ($B$), Earthquake ($E$), Alarm ($A$), Mary calls ($M$) and John calls ($J$). The initial events $B$ and $E$ are assumed to be independent events that occur with probabilities $P(B)$ and $P(E)$, respectively. There is an alarm system that can be triggered by either of the initial events $B$ and $E$. The probability of the alarm going off is a conditional probability depending on whether $B$, or $E$ as occurred. One denotes these probabilities, as per usual, by $P(A|B)$, and $P(A|E)$. There are two neighbours, Mary and John who have agreed to call if they hear the alarm. The probability that they do actually call is also a conditional probability denoted by $P(M|A)$ and $P(J|A)$, respectively. | |
782 | - | |
783 | -Considering the probabilities given in \cref{Figure_Alarm} we obtain the following specification | |
784 | - | |
785 | -\begin{equation*} | |
786 | - \begin{aligned} | |
787 | - \probfact{0.001}{B}&,\cr | |
788 | - \probfact{0.002}{E}&,\cr | |
789 | - \probfact{??}{A}&,\cr | |
790 | - ... &. \cr | |
791 | - \end{aligned} | |
792 | - \label{eq:not_so_simple_example} | |
793 | -\end{equation*} | |
782 | +\subsection{An example involving Bayesian networks} | |
794 | 783 | |
784 | +As it turns out, our framework is suitable to deal with more sophisticated cases, for example cases involving Bayesian networks. In order to illustrate this, in this section we see how the classical example of the Burglary, Earthquake, Alarm \cite{Judea88} works in our setting. This example is a commonly used example in Bayesian networks because it illustrates reasoning under uncertainty. The gist of example is given in \cref{Figure_Alarm}. It involves a simple network of events and conditional probabilities. | |
795 | 785 | |
786 | +The events are: Burglary ($B$), Earthquake ($E$), Alarm ($A$), Mary calls ($M$) and John calls ($J$). The initial events $B$ and $E$ are assumed to be independent events that occur with probabilities $P(B)$ and $P(E)$, respectively. There is an alarm system that can be triggered by either of the initial events $B$ and $E$. The probability of the alarm going off is a conditional probability given that $B$ and $E$ have occurred. One denotes these probabilities, as per usual, by $P(A|B)$, and $P(A|E)$. There are two neighbours, Mary and John who have agreed to call if they hear the alarm. The probability that they do actually call is also a conditional probability denoted by $P(M|A)$ and $P(J|A)$, respectively. | |
796 | 787 | |
797 | 788 | |
798 | 789 | |
... | ... | @@ -808,8 +799,8 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
808 | 799 | \node[tchoice, below right of=A] (J) {J}; |
809 | 800 | |
810 | 801 | % Edges |
811 | - \draw[->] (B) to[bend left] (A) node[right,xshift=1.1cm,yshift=0.8cm] {\footnotesize{$P(B)=0,001$}} ; | |
812 | - \draw[->] (E) to[bend right] (A) node[left, xshift=-1.4cm,yshift=0.8cm] {\footnotesize{$P(E)=0,002$}} ; | |
802 | + \draw[->] (B) to[bend left] (A) node[right,xshift=1.1cm,yshift=0.8cm] {\footnotesize{$P(B)=0.001$}} ; | |
803 | + \draw[->] (E) to[bend right] (A) node[left, xshift=-1.4cm,yshift=0.8cm] {\footnotesize{$P(E)=0.002$}} ; | |
813 | 804 | \draw[->] (A) to[bend right] (M) node[left,xshift=0.2cm,yshift=0.7cm] {\footnotesize{$P(M|A)$}}; |
814 | 805 | \draw[->] (A) to[bend left] (J) node[right,xshift=-0.2cm,yshift=0.7cm] {\footnotesize{$P(J|A)$}} ; |
815 | 806 | \end{tikzpicture} |
... | ... | @@ -822,10 +813,10 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
822 | 813 | \begin{split} |
823 | 814 | &P(M|A)\\ |
824 | 815 | & \begin{array}{c|cc} |
825 | - A & T & F \ | |
816 | + & m & \neg m \ | |
826 | 817 | \hline |
827 | - T & 0,9 & 0,1\\ | |
828 | - F& 0,05 & 0,95 | |
818 | + a & 0.9 & 0.1\\ | |
819 | + \neg a& 0.05 & 0.95 | |
829 | 820 | \end{array} |
830 | 821 | \end{split} |
831 | 822 | \end{equation*} |
... | ... | @@ -836,10 +827,10 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
836 | 827 | \begin{split} |
837 | 828 | &P(J|A)\\ |
838 | 829 | & \begin{array}{c|cc} |
839 | - A & T & F \ | |
830 | + & j & \neg j \ | |
840 | 831 | \hline |
841 | - T & 0,7 & 0,3\\ | |
842 | - F& 0,01 & 0,99 | |
832 | + a & 0.7 & 0.3\\ | |
833 | + \neg a& 0.01 & 0.99 | |
843 | 834 | \end{array} |
844 | 835 | \end{split} |
845 | 836 | \end{equation*} |
... | ... | @@ -847,14 +838,14 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
847 | 838 | \footnotesize{ |
848 | 839 | \begin{equation*} |
849 | 840 | \begin{split} |
850 | - P(A|B \vee E)\ | |
841 | + P(A|B \wedge E)\ | |
851 | 842 | \begin{array}{c|c|cc} |
852 | - B & E& T & F \ | |
843 | + & & a & \neg a \ | |
853 | 844 | \hline |
854 | - T & T & 0,95 & 0,05\\ | |
855 | - T & F & 0,94 & 0,06\\ | |
856 | - F & T & 0,29 & 0,71\\ | |
857 | - F & F & 0,001 & 0,999 | |
845 | + b & e & 0.95 & 0.05\\ | |
846 | + b & \neg e & 0.94 & 0.06\\ | |
847 | + \neg b & e & 0.29 & 0.71\\ | |
848 | + \neg b & \neg e & 0.001 & 0.999 | |
858 | 849 | \end{array} |
859 | 850 | \end{split} |
860 | 851 | \end{equation*} |
... | ... | @@ -865,6 +856,64 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
865 | 856 | \end{figure} |
866 | 857 | |
867 | 858 | |
859 | +Considering the probabilities given in \cref{Figure_Alarm} we obtain the following specification | |
860 | + | |
861 | +\begin{equation*} | |
862 | + \begin{aligned} | |
863 | + \probfact{0.001}{b}&,\cr | |
864 | + \probfact{0.002}{e}&,\cr | |
865 | + \end{aligned} | |
866 | + \label{eq:not_so_simple_example} | |
867 | +\end{equation*} | |
868 | + | |
869 | +For the table giving the probability $P(M|A)$ we obtain the specification: | |
870 | + | |
871 | + | |
872 | +\begin{equation*} | |
873 | + \begin{aligned} | |
874 | + &\probfact{0.9}{pm\_a},\cr | |
875 | + &\probfact{0.05}{pm\_na},\cr | |
876 | + m & \leftarrow a, pm\_a,\cr | |
877 | + \neg m & \leftarrow a, \neg pm\_a. | |
878 | + \end{aligned} | |
879 | +\end{equation*} | |
880 | + | |
881 | +This latter specification can be simplified by writing $\probfact{0.9}{m \leftarrow a}$ and $\probfact{0.05}{m \leftarrow \neg a}$. | |
882 | + | |
883 | +Similarly, for the probability $P(J|A)$ we obtain | |
884 | + | |
885 | +\begin{equation*} | |
886 | + \begin{aligned} | |
887 | + &\probfact{0.7}{pj\_a},\cr | |
888 | + &\probfact{0.01}{pj\_na},\cr | |
889 | + j & \leftarrow a, pj\_a,\cr | |
890 | + \neg j & \leftarrow a, \neg pj\_a.\cr | |
891 | + \end{aligned} | |
892 | +\end{equation*} | |
893 | + | |
894 | +Again, this can be simplified by writing $\probfact{0.7}{j \leftarrow a}$ and $\probfact{0.01}{j \leftarrow \neg a}$. | |
895 | + | |
896 | +Finally, for the probability $P(A|B \wedge E)$ we obtain | |
897 | + | |
898 | +\begin{equation*} | |
899 | + \begin{aligned} | |
900 | + &\probfact{0.95}{a\_be},\cr | |
901 | + &\probfact{0.94}{a\_bne},\cr | |
902 | + &\probfact{0.29}{a\_nbe},\cr | |
903 | + &\probfact{0.001}{a\_nbne},\cr | |
904 | + a & \leftarrow b, e, a\_be,\cr | |
905 | + \neg a & \leftarrow b,e, \neg a\_be, \cr | |
906 | + a & \leftarrow b,e, a\_bne,\cr | |
907 | + \neg a & \leftarrow b,e, \neg a\_bne, \cr | |
908 | + a & \leftarrow b,e, a\_nbe,\cr | |
909 | + \neg a & \leftarrow b,e, \neg a\_nbe, \cr | |
910 | + a & \leftarrow b,e, a\_nbne,\cr | |
911 | + \neg a & \leftarrow b,e, \neg a\_nbne. \cr | |
912 | + \end{aligned} | |
913 | +\end{equation*} | |
914 | + | |
915 | +One can then proceed as in the previous subsection and analyse this example. The details of such analysis are not given here since they are analogous, albeit admittedly more cumbersome. | |
916 | + | |
868 | 917 | |
869 | 918 | \section{Discussion} |
870 | 919 | |
... | ... | @@ -906,6 +955,14 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
906 | 955 | % |
907 | 956 | % ================================================================ |
908 | 957 | % |
958 | + \begin{itemize} | |
959 | + \item Changed from $\prod$ to $\sum$ to represent ``either'' instead of ``both'' since the later is not consistent with the ``only one stable model at a time'' assumption. | |
960 | + \item \todo{The `up and down' choice in the equivalence relation and the possibility of describing any probability distribution.} | |
961 | + \item \todo{Remark that no benchmark was done with other SOTA efforts.} | |
962 | + \item \todo{The possibility to `import' bayesian theory and tools to this study.} | |
963 | + \end{itemize} | |
964 | + | |
965 | + | |
909 | 966 | \subsection{Dependence} |
910 | 967 | \label{subsec:dependence} |
911 | 968 | |
... | ... | @@ -963,7 +1020,7 @@ Considering the probabilities given in \cref{Figure_Alarm} we obtain the followi |
963 | 1020 | Prove the four world cases (done), support the product (done) and sum (tbd) options, with the independence assumptions. |
964 | 1021 | \end{quotation} |
965 | 1022 | |
966 | - \section{Final Remarks} | |
1023 | + \subsection{Future Work} | |
967 | 1024 | |
968 | 1025 | \todo{develop this section.} |
969 | 1026 | ... | ... |