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