Commit 677cc471e117983ee2977316deef68c1f084e621

Authored by Francisco Coelho
1 parent 9b8ebd89
Exists in master

Further progress in event_lattice.py

code/python/EventLattice.ipynb 0 → 100644
... ... @@ -0,0 +1,349 @@
  1 +{
  2 + "cells": [
  3 + {
  4 + "cell_type": "code",
  5 + "execution_count": 1,
  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": 2,
  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": 10,
  33 + "id": "cdd8c6d6",
  34 + "metadata": {},
  35 + "outputs": [
  36 + {
  37 + "name": "stdout",
  38 + "output_type": "stream",
  39 + "text": [
  40 + "{\n",
  41 + "\t'stable_models': {\n",
  42 + "\t\t A: 2,\n",
  43 + "\t\tab: 3,\n",
  44 + "\t\tac: 5 \n",
  45 + "\t}\n",
  46 + "\t'literals': { A,B,C,a,b,c } \n",
  47 + "}\n"
  48 + ]
  49 + }
  50 + ],
  51 + "source": [
  52 + "smodels = el.Lattice.parse({\n",
  53 + " \"A\": 2,\n",
  54 + " \"ab\": 3,\n",
  55 + " \"ac\": 5\n",
  56 + "})\n",
  57 + "\n",
  58 + "lattice = el.Lattice(smodels)\n",
  59 + "\n",
  60 + "print(lattice)"
  61 + ]
  62 + },
  63 + {
  64 + "cell_type": "code",
  65 + "execution_count": 11,
  66 + "id": "2b445339",
  67 + "metadata": {},
  68 + "outputs": [
  69 + {
  70 + "name": "stdout",
  71 + "output_type": "stream",
  72 + "text": [
  73 + "Event: abc\n",
  74 + "\tClass: <|ab,ac> \n",
  75 + "\tValue: 8\n",
  76 + "Event: a\n",
  77 + "\tClass: <ab,ac|> \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"
  88 + ]
  89 + }
  90 + ],
  91 + "source": [
  92 + "zoom_event(\"abc\", lattice)\n",
  93 + "zoom_event(\"a\", lattice)\n",
  94 + "zoom_event(\"b\", lattice)\n",
  95 + "zoom_event(\"bc\", lattice)\n",
  96 + "zoom_event(\"ac\", lattice)"
  97 + ]
  98 + },
  99 + {
  100 + "cell_type": "code",
  101 + "execution_count": 12,
  102 + "id": "f1b85255",
  103 + "metadata": {},
  104 + "outputs": [
  105 + {
  106 + "name": "stdout",
  107 + "output_type": "stream",
  108 + "text": [
  109 + "Event: \n",
  110 + "\tClass: <A,ab,ac|> \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: B\n",
  119 + "\tClass: <|> \n",
  120 + "\tValue: 0\n",
  121 + "Event: C\n",
  122 + "\tClass: <|> \n",
  123 + "\tValue: 0\n",
  124 + "Event: c\n",
  125 + "\tClass: <ac|> \n",
  126 + "\tValue: 5\n",
  127 + "Event: a\n",
  128 + "\tClass: <ab,ac|> \n",
  129 + "\tValue: 15\n",
  130 + "Event: Ab\n",
  131 + "\tClass: <|A> \n",
  132 + "\tValue: 2\n",
  133 + "Event: AB\n",
  134 + "\tClass: <|A> \n",
  135 + "\tValue: 2\n",
  136 + "Event: AC\n",
  137 + "\tClass: <|A> \n",
  138 + "\tValue: 2\n",
  139 + "Event: Ac\n",
  140 + "\tClass: <|A> \n",
  141 + "\tValue: 2\n",
  142 + "Event: Aa\n",
  143 + "\tClass: <|A> \n",
  144 + "\tValue: 0\n",
  145 + "Event: Bb\n",
  146 + "\tClass: <|> \n",
  147 + "\tValue: 0\n",
  148 + "Event: Cb\n",
  149 + "\tClass: <|> \n",
  150 + "\tValue: 0\n",
  151 + "Event: bc\n",
  152 + "\tClass: <|> \n",
  153 + "\tValue: 0\n",
  154 + "Event: ab\n",
  155 + "\tClass: <ab|ab> \n",
  156 + "\tValue: 3\n",
  157 + "Event: BC\n",
  158 + "\tClass: <|> \n",
  159 + "\tValue: 0\n",
  160 + "Event: Bc\n",
  161 + "\tClass: <|> \n",
  162 + "\tValue: 0\n",
  163 + "Event: Ba\n",
  164 + "\tClass: <|> \n",
  165 + "\tValue: 0\n",
  166 + "Event: Cc\n",
  167 + "\tClass: <|> \n",
  168 + "\tValue: 0\n",
  169 + "Event: Ca\n",
  170 + "\tClass: <|> \n",
  171 + "\tValue: 0\n",
  172 + "Event: ac\n",
  173 + "\tClass: <ac|ac> \n",
  174 + "\tValue: 5\n",
  175 + "Event: ABb\n",
  176 + "\tClass: <|A> \n",
  177 + "\tValue: 0\n",
  178 + "Event: ACb\n",
  179 + "\tClass: <|A> \n",
  180 + "\tValue: 2\n",
  181 + "Event: Abc\n",
  182 + "\tClass: <|A> \n",
  183 + "\tValue: 2\n",
  184 + "Event: Aab\n",
  185 + "\tClass: <|A,ab> \n",
  186 + "\tValue: 0\n",
  187 + "Event: ABC\n",
  188 + "\tClass: <|A> \n",
  189 + "\tValue: 2\n",
  190 + "Event: ABc\n",
  191 + "\tClass: <|A> \n",
  192 + "\tValue: 2\n",
  193 + "Event: ABa\n",
  194 + "\tClass: <|A> \n",
  195 + "\tValue: 0\n",
  196 + "Event: ACc\n",
  197 + "\tClass: <|A> \n",
  198 + "\tValue: 0\n",
  199 + "Event: ACa\n",
  200 + "\tClass: <|A> \n",
  201 + "\tValue: 0\n",
  202 + "Event: Aac\n",
  203 + "\tClass: <|A,ac> \n",
  204 + "\tValue: 0\n",
  205 + "Event: BCb\n",
  206 + "\tClass: <|> \n",
  207 + "\tValue: 0\n",
  208 + "Event: Bbc\n",
  209 + "\tClass: <|> \n",
  210 + "\tValue: 0\n",
  211 + "Event: Bab\n",
  212 + "\tClass: <|ab> \n",
  213 + "\tValue: 0\n",
  214 + "Event: Cbc\n",
  215 + "\tClass: <|> \n",
  216 + "\tValue: 0\n",
  217 + "Event: Cab\n",
  218 + "\tClass: <|ab> \n",
  219 + "\tValue: 3\n",
  220 + "Event: abc\n",
  221 + "\tClass: <|ab,ac> \n",
  222 + "\tValue: 8\n",
  223 + "Event: BCc\n",
  224 + "\tClass: <|> \n",
  225 + "\tValue: 0\n",
  226 + "Event: BCa\n",
  227 + "\tClass: <|> \n",
  228 + "\tValue: 0\n",
  229 + "Event: Bac\n",
  230 + "\tClass: <|ac> \n",
  231 + "\tValue: 5\n",
  232 + "Event: Cac\n",
  233 + "\tClass: <|ac> \n",
  234 + "\tValue: 0\n",
  235 + "Event: ABCb\n",
  236 + "\tClass: <|A> \n",
  237 + "\tValue: 0\n",
  238 + "Event: ABbc\n",
  239 + "\tClass: <|A> \n",
  240 + "\tValue: 0\n",
  241 + "Event: ABab\n",
  242 + "\tClass: <|A,ab> \n",
  243 + "\tValue: 0\n",
  244 + "Event: ACbc\n",
  245 + "\tClass: <|A> \n",
  246 + "\tValue: 0\n",
  247 + "Event: ACab\n",
  248 + "\tClass: <|A,ab> \n",
  249 + "\tValue: 0\n",
  250 + "Event: Aabc\n",
  251 + "\tClass: <|A,ab,ac> \n",
  252 + "\tValue: 0\n",
  253 + "Event: ABCc\n",
  254 + "\tClass: <|A> \n",
  255 + "\tValue: 0\n",
  256 + "Event: ABCa\n",
  257 + "\tClass: <|A> \n",
  258 + "\tValue: 0\n",
  259 + "Event: ABac\n",
  260 + "\tClass: <|A,ac> \n",
  261 + "\tValue: 0\n",
  262 + "Event: ACac\n",
  263 + "\tClass: <|A,ac> \n",
  264 + "\tValue: 0\n",
  265 + "Event: BCbc\n",
  266 + "\tClass: <|> \n",
  267 + "\tValue: 0\n",
  268 + "Event: BCab\n",
  269 + "\tClass: <|ab> \n",
  270 + "\tValue: 0\n",
  271 + "Event: Babc\n",
  272 + "\tClass: <|ab,ac> \n",
  273 + "\tValue: 0\n",
  274 + "Event: Cabc\n",
  275 + "\tClass: <|ab,ac> \n",
  276 + "\tValue: 0\n",
  277 + "Event: BCac\n",
  278 + "\tClass: <|ac> \n",
  279 + "\tValue: 0\n",
  280 + "Event: ABCbc\n",
  281 + "\tClass: <|A> \n",
  282 + "\tValue: 0\n",
  283 + "Event: ABCab\n",
  284 + "\tClass: <|A,ab> \n",
  285 + "\tValue: 0\n",
  286 + "Event: ABabc\n",
  287 + "\tClass: <|A,ab,ac> \n",
  288 + "\tValue: 0\n",
  289 + "Event: ACabc\n",
  290 + "\tClass: <|A,ab,ac> \n",
  291 + "\tValue: 0\n",
  292 + "Event: ABCac\n",
  293 + "\tClass: <|A,ac> \n",
  294 + "\tValue: 0\n",
  295 + "Event: BCabc\n",
  296 + "\tClass: <|ab,ac> \n",
  297 + "\tValue: 0\n",
  298 + "Event: ABCabc\n",
  299 + "\tClass: <|A,ab,ac> \n",
  300 + "\tValue: 0\n"
  301 + ]
  302 + }
  303 + ],
  304 + "source": [
  305 + "from itertools import *\n",
  306 + "\n",
  307 + "lits = lattice.literals()\n",
  308 + "for len_lit in range(len(lits)+1):\n",
  309 + " events = list(\"\".join(c) for c in combinations(lits, len_lit))\n",
  310 + " for event in events:\n",
  311 + " zoom_event(event, lattice)"
  312 + ]
  313 + },
  314 + {
  315 + "cell_type": "code",
  316 + "execution_count": null,
  317 + "id": "07973a47",
  318 + "metadata": {},
  319 + "outputs": [],
  320 + "source": []
  321 + }
  322 + ],
  323 + "metadata": {
  324 + "kernelspec": {
  325 + "display_name": "Python 3.9.13 ('base')",
  326 + "language": "python",
  327 + "name": "python3"
  328 + },
  329 + "language_info": {
  330 + "codemirror_mode": {
  331 + "name": "ipython",
  332 + "version": 3
  333 + },
  334 + "file_extension": ".py",
  335 + "mimetype": "text/x-python",
  336 + "name": "python",
  337 + "nbconvert_exporter": "python",
  338 + "pygments_lexer": "ipython3",
  339 + "version": "3.9.13"
  340 + },
  341 + "vscode": {
  342 + "interpreter": {
  343 + "hash": "a59afa236e16843183c59a167f072b6fa0409044b3c4938e82ac98aad91bf217"
  344 + }
  345 + }
  346 + },
  347 + "nbformat": 4,
  348 + "nbformat_minor": 5
  349 +}
... ...
code/python/__pycache__/event_lattice.cpython-39.pyc
No preview for this file type
code/python/event_lattice.py
... ... @@ -4,9 +4,10 @@ from itertools import accumulate
4 4 import operator
5 5  
6 6  
  7 +
7 8 def uniform_op(x):
8 9 n = len(list(x))
9   - return 0.0 if n == 0 else 1.0/n
  10 + return 1.0 if n == 0 else 1.0/n
10 11  
11 12  
12 13 def max_op(x):
... ... @@ -21,53 +22,117 @@ def sum_op(x):
21 22 return sum(x)
22 23  
23 24  
24   -def prod_op(x):
  25 +def stableprod_op(x):
25 26 log_x = map(math.log, x)
26 27 return math.exp(sum(log_x))
27 28  
28 29  
29   -def co(x):
30   - if isinstance(x, float) or isinstance(x, int):
31   - return 1 - x
32   - elif isinstance(x, str):
33   - return x.swapcase()
34   - else:
35   - return x
  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 + @staticmethod
  38 + def parse(text):
  39 + return frozenset(text)
  40 +
  41 + @staticmethod
  42 + def from_str(text):
  43 + return Event(Event.parse(text))
  44 +
  45 +
  46 + def __init__(self, literals):
  47 + """Instantiate from a (frozen) set of literals.
  48 + For example: e = Event(frozenset("abc"))."""
  49 + self._literals = literals
  50 +
  51 +
  52 + def literals(self):
  53 + return self._literals
  54 +
  55 +
  56 + def __iter__(self):
  57 + 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 +
  65 + @cache
  66 + def is_consistent(self):
  67 + return all(x.swapcase() not in self._literals for x in self._literals)
  68 +
  69 + def __hash__(self) -> int:
  70 + return self._literals.__hash__()
  71 +
  72 +
  73 + def __eq__(self, other):
  74 + return self._literals.__eq__(other._literals)
  75 +
  76 +
  77 + def __repr__(self) -> str:
  78 + return ''.join(str(x) for x in sorted(self._literals))
36 79  
  80 + def invert(self):
  81 + return self.co()
37 82  
38   -def parse(d):
39   - """Structures a string as an Event and a dict as a base of stable models."""
40   - if isinstance(d, str):
41   - return frozenset(d)
42   - elif isinstance(d, dict):
  83 +
  84 + def __eq__(self, other):
  85 + return self._literals.__eq__(other._literals)
  86 +
  87 + def __or__(self, other):
  88 + return Event(self._literals | other._literals)
  89 +
  90 +
  91 + def __le__(self, other):
  92 + return self._literals.__le__(other._literals)
  93 +
  94 +
  95 + def __lt__(self, other):
  96 + return self._literals.__lt__(other._literals)
  97 +
  98 +
  99 + def __ne__(self, other):
  100 + return self._literals.__ne__(other._literals)
  101 +
  102 +
  103 + def __ge__(self, other):
  104 + return self._literals.__ge__(other._literals)
  105 +
  106 +
  107 + def __gt__(self, other):
  108 + return self._literals.__gt__(other._literals)
  109 +
  110 +
  111 +class Lattice:
  112 +
  113 +
  114 + @staticmethod
  115 + def parse(d):
43 116 result = dict()
44 117 for k, v in d.items():
45   - key = parse(k)
  118 + key = Event.from_str(k)
46 119 result[key] = v
47 120 return result
48   - else:
49   - return d
50   -
51   -
52   -def is_consistent(event):
53   - return all(x.swapcase() not in event for x in event)
54 121  
55 122  
56   -class EventsLattice:
57   -
58 123 @staticmethod
59   - def close_literals(base_literals):
60   - base_lits = list(accumulate(base_literals, func=operator.or_))[-1]
61   - lits = set([])
62   - for x in base_lits:
  124 + def close_literals(smodels):
  125 + base_lits = list(accumulate(smodels, func=operator.or_))[-1]
  126 + lits = set()
  127 + for x in base_lits.literals():
63 128 lits.add(x)
64 129 lits.add(x.swapcase())
65 130 return lits
66 131  
67   - def __init__(self, smodels):
  132 + def __init__(self, smodels_dict):
68 133 """Create base for Events Lattice."""
69   - self._smodels = smodels
70   - self._literals = EventsLattice.close_literals(self._smodels.keys())
  134 + self._smodels = smodels_dict
  135 + self._literals = Lattice.close_literals(self._smodels.keys())
71 136  
72 137 def literals(self):
73 138 return self._literals
... ... @@ -77,15 +142,22 @@ class EventsLattice:
77 142  
78 143 @cache
79 144 def lower_bound(self, event):
80   - return set(filter(lambda sm: sm <= event, self._smodels))
  145 + return list(set(filter(lambda sm: sm <= event, self._smodels)))
81 146  
82 147 @cache
83 148 def upper_bound(self, event):
84   - return set(filter(lambda sm: event <= sm, self._smodels))
  149 + return list(set(filter(lambda sm: event <= sm, self._smodels)))
  150 +
  151 +
  152 + def event_class(self, event):
  153 + return EventsClass(
  154 + self.upper_bound(event),
  155 + self.lower_bound(event),
  156 + self)
85 157  
86 158 def related(self, u, v):
87   - u_consistent = is_consistent(u)
88   - v_consistent = is_consistent(v)
  159 + u_consistent = u.is_consistent()
  160 + v_consistent = v.is_consistent()
89 161 if u_consistent and (u_consistent == v_consistent):
90 162 return \
91 163 self.lower_bound(u) == self.lower_bound(v) and \
... ... @@ -94,52 +166,54 @@ class EventsLattice:
94 166 return u_consistent == v_consistent
95 167  
96 168 def factors(self, event):
97   - pass
  169 + return [self.lower_bound(event), self.upper_bound(event)]
98 170  
99   - def propagated_value(self, event, lower_op=sum_op, upper_op=prod_op):
100   - value = 0.0
  171 + def propagated_value(self, event:Event,
  172 + lower_op=sum_op,
  173 + upper_op=prod_op):
  174 + value = 0
  175 +
  176 + if not event.is_consistent():
  177 + return value
101 178  
102 179 lb = self.lower_bound(event)
103 180 len_lb = len(lb)
104 181 if len_lb > 1:
105 182 value = lower_op(map(lambda sm: self._smodels[sm], lb))
106 183 elif len_lb == 1:
107   - value = self._smodels[event]
  184 + value = self._smodels[lb[0]]
108 185 else:
109 186 ub = self.upper_bound(event)
110 187 len_ub = len(ub)
111 188 if len_ub > 1:
112 189 value = upper_op(map(lambda sm: self._smodels[sm], ub))
113 190 elif len_ub == 1:
114   - value = self._smodels[event]
  191 + value = self._smodels[ub[0]]
115 192  
116 193 return value
117 194  
  195 + def __repr__(self):
  196 + smodels_repr = ',\n\t\t'.join(f"{Event.from_str(k)}: {v:>5}" for k,v in self._smodels.items())
  197 + lits_repr = ','.join(sorted(self._literals))
118 198  
119   -def zoom_event(event_str, lattice, lower_op=sum_op, upper_op=prod_op):
120   - event = parse(event_str)
121   - lower_bound = lattice.lower_bound(event)
122   - upper_bound = lattice.upper_bound(event)
123   - propagated = lattice.propagated_value(
124   - event, lower_op=lower_op, upper_op=upper_op)
125   - print(
126   - f"Event: {event}\n\tLB: {lower_bound}\n\tUB: {upper_bound}\n\tProp: {propagated}")
127   -
128   -
129   -if __name__ == "__main__":
  199 + return "{\n" +\
  200 + f"\t'stable_models': {{\n\t\t {smodels_repr} \n\t}}\n" +\
  201 + f"\t'literals': {{ {lits_repr} }} \n" +\
  202 + "}"
130 203  
131   - smodels = parse({
132   - "A": 0.7,
133   - "ab": 2 * 3,
134   - "ac": 5 * 7
135   - })
136 204  
137   - lattice = EventsLattice(smodels)
138 205  
139   - print(
140   - f"Literals: {lattice.literals()}\nStable Models: {lattice.stable_models()}")
  206 +class EventsClass:
  207 + def __init__(self, upper, lower, lattice:Lattice):
  208 + self._upper = upper
  209 + self._lower = lower
  210 + self._lattice = lattice
141 211  
142   - zoom_event("abc", lattice, upper_op=min_op, lower_op=max_op)
  212 + def __repr__(self):
  213 + upper_repr = "" if len(self._upper) == 0 else ",".join(str(x) for x in self._upper)
  214 + lower_repr = "" if len(self._lower) == 0 else ",".join(str(x) for x in self._lower)
  215 + return f"<{upper_repr}|{lower_repr}>"
143 216  
144   - print(is_consistent(parse("aBacc")))
145   - print(is_consistent(parse("aBabc")))
  217 + def __contains__(self, event:Event):
  218 + return self.lattice.lower_bound(event) == self._lower and \
  219 + self.lattice.upper_bound(event) == self._upper
146 220 \ No newline at end of file
... ...
meetings.md 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +## Zugzwang Meetings
  2 +
  3 +### 2022-12-12
  4 +
  5 +- Is the project proposal ok? How long/detailed should it be?
  6 +- Initial exploratory code `event_lattice.py` and `EventLattice.ipynb` done.
  7 +- Start writing paper: Introduction, state of the art, motivation, _etc._
  8 +- Next task for prototype:
  9 + - Get stable models from potassco/s(casp)
  10 + - other?
  11 +
  12 +
  13 +### 2022-12-05
  14 +
  15 +- Created shared folder (gdrive:zugzwang) <https://drive.google.com/drive/folders/1xs-cjxWJzn2JxqeNgh9LX5xWN50BW-Be?usp=share_link>
  16 +- Refine project tasks, for Bachelor, M.Sc., Ph.D. students and for researchers.
0 17 \ No newline at end of file
... ...
task_01/proposal.md
... ... @@ -6,7 +6,7 @@
6 6  
7 7 Answer Set Programming (ASP) is a logic programming paradigm based on the Stable Model semantics of Normal Logic Programs (NP) that can be implemented using the latest advances in SAT solving technology. ASP is a truly declarative language that supports language constructs such as disjunction in the head of a clause, choice rules, and hard and weak constraints.
8 8  
9   -The Distribution Semantics (DS) is a key approach to extend logical representations with probabilistic reasoning. Probabilistic Facts (PF) are the most basic stochastic DS primitive and they take the form of logical facts labeled with a probability $p$; Each probabilistic fact represents a boolean random variable that is true with probability $p$ and false with probability $1 − p$.
  9 +The Distribution Semantics (DS) is a key approach to extend logical representations with probabilistic reasoning. Probabilistic Facts (PF) are the most basic stochastic DS primitive and they take the form of logical facts labelled with a probability $p$; Each probabilistic fact represents a boolean random variable that is true with probability $p$ and false with probability $1 − p$.
10 10  
11 11 Crucially, a joint distribution of atoms derived from an ASP specification can be used to _quantitatively measure the performance of that specification_ given data observed from the system it is intended to describe. Then, given competing specifications to describe a certain system, these performance measures can be applied in various optimization techniques in order to obtain one that best describes the target system.
12 12  
... ...