Python 3 support seems complete (CAVEAT: random hash differently!)
Chris Pressey
6 years ago
53 | 53 | a given action has been taken previously or not. |
54 | 54 | * (+) Consider macros. |
55 | 55 | * Output scenarios to JSON. |
56 | * Python 3 support. | |
57 | 56 | * Consider a simple equality rule. |
58 | 57 | * Consider allowing `∨`. |
59 | 58 | * Take AST code from SixtyPical or ALPACA (or try to do better, perhaps with |
191 | 191 | item(oilcan). |
192 | 192 | goal [holding(Ignatz,brick)]. |
193 | 193 | } |
194 | ===> Ignatz picks up the brick. | |
195 | ===> Ignatz puts down the brick. | |
194 | 196 | ===> Ignatz picks up the oilcan. |
195 | ===> Ignatz puts down the oilcan. | |
196 | ===> Ignatz picks up the brick. | |
197 | ===> Ignatz picks up the oilcan. | |
197 | ===> Ignatz picks up the brick. | |
198 | 198 | |
199 | 199 | chairs |
200 | 200 | ------ |
228 | 228 | |
229 | 229 | goal []. |
230 | 230 | } |
231 | ===> Wembley sits down in the recliner. | |
232 | ===> Wembley leans back in the recliner. | |
231 | 233 | ===> Hastings sits down in the chair. |
232 | ===> Hastings leans back in the chair. | |
233 | 234 | ===> Petersen sits down in the sofa. |
234 | ===> Wembley sits down in the recliner. | |
235 | 235 | |
236 | 236 | |
237 | 237 | no need for functions |
259 | 259 | |
260 | 260 | goal []. |
261 | 261 | } |
262 | ===> Bob scratches his head. | |
263 | ===> Bob scratches his head. | |
264 | ===> Alice scratches her head. | |
265 | ===> Alice scratches her head. | |
262 | ===> Alice scratches her head. | |
263 | ===> Alice scratches her head. | |
264 | ===> Bob scratches his head. | |
265 | ===> Bob scratches his head. | |
266 | 266 | |
267 | 267 | This loses the nice property of the function name being a readable |
268 | 268 | placeholder in the sentence, but you can now use named variables |
281 | 281 | |
282 | 282 | goal []. |
283 | 283 | } |
284 | ===> Bob scratches his head. | |
285 | ===> Bob scratches his head. | |
286 | ===> Alice scratches her head. | |
287 | ===> Alice scratches her head. | |
284 | ===> Alice scratches her head. | |
285 | ===> Alice scratches her head. | |
286 | ===> Bob scratches his head. | |
287 | ===> Bob scratches his head. |
2 | 2 | from copy import deepcopy |
3 | 3 | from pprint import pprint |
4 | 4 | import random |
5 | ||
6 | ||
7 | # Python 2/3 | |
8 | try: | |
9 | unicode = unicode | |
10 | except NameError: | |
11 | unicode = str | |
5 | 12 | |
6 | 13 | |
7 | 14 | class AST(object): |
6 | 6 | from samovar.ast import Assert, Retract |
7 | 7 | from samovar.query import match_all |
8 | 8 | from samovar.terms import Term |
9 | ||
10 | ||
11 | # Python 2/3 | |
12 | try: | |
13 | xrange = xrange | |
14 | except NameError: | |
15 | xrange = range | |
9 | 16 | |
10 | 17 | |
11 | 18 | class Event(object): |
8 | 8 | |
9 | 9 | |
10 | 10 | class AbstractTerm(object): |
11 | ||
12 | def __ne__(self, other): | |
13 | return not self.__eq__(other) | |
14 | ||
15 | def __hash__(self): | |
16 | return hash(unicode(self)) | |
11 | pass | |
17 | 12 | |
18 | 13 | |
19 | 14 | class Term(AbstractTerm): |
20 | 15 | def __init__(self, constructor, *subterms): |
21 | self.constructor = constructor | |
22 | self.subterms = subterms | |
16 | self.t = tuple([constructor] + list(subterms)) | |
17 | ||
18 | @property | |
19 | def constructor(self): | |
20 | return self.t[0] | |
21 | ||
22 | @property | |
23 | def subterms(self): | |
24 | return self.t[1:] | |
23 | 25 | |
24 | 26 | def __str__(self): |
25 | 27 | if len(self.subterms) == 0: |
37 | 39 | ) |
38 | 40 | |
39 | 41 | def __eq__(self, other): |
40 | if not isinstance(other, Term): | |
41 | return False | |
42 | if self.constructor != other.constructor: | |
43 | return False | |
44 | if len(self.subterms) != len(other.subterms): | |
45 | return False | |
46 | for (st1, st2) in zip(self.subterms, other.subterms): | |
47 | if st1 != st2: | |
48 | return False | |
49 | return True | |
42 | return isinstance(other, Term) and self.t == other.t | |
43 | ||
44 | def __hash__(self): | |
45 | return hash(self.t) | |
50 | 46 | |
51 | 47 | def is_atom(self): |
52 | 48 | return len(self.subterms) == 0 |
92 | 88 | return "%s(%r)" % (self.__class__.__name__, self.name) |
93 | 89 | |
94 | 90 | def __eq__(self, other): |
95 | if not isinstance(other, Var): | |
96 | return False | |
97 | return self.name == other.name | |
91 | return isinstance(other, Var) and self.name == other.name | |
92 | ||
93 | def __hash__(self): | |
94 | return hash(self.name) | |
98 | 95 | |
99 | 96 | def is_atom(self): |
100 | 97 | return False |