Sort the database of facts before accumulating matches on it.
Chris Pressey
3 years ago
17 | 17 | |
18 | 18 | from samovar.parser import Parser |
19 | 19 | from samovar.generator import Generator |
20 | ||
21 | ||
22 | class CannedRandomness(object): | |
23 | def __init__(self): | |
24 | self.counter = 0 | |
25 | ||
26 | def choice(self, iterable): | |
27 | length = len(iterable) | |
28 | index = self.counter % length | |
29 | selection = iterable[index] | |
30 | self.counter += 1 | |
31 | return selection | |
20 | from samovar.randomness import CannedRandomness | |
32 | 21 | |
33 | 22 | |
34 | 23 | def generate_fifty_thousand_words(): |
134 | 123 | jsonified_buckets = [jsonify_bucket(b) for b in event_buckets] |
135 | 124 | sys.stdout.write(json.dumps(jsonified_buckets, indent=4, sort_keys=True)) |
136 | 125 | elif options.output_type == 'scenarios-json': |
137 | raise NotImplementedError | |
126 | raise NotImplementedError("'scenarios-json' output-type not currently implemented") | |
138 | 127 | else: |
139 | raise NotImplementedError | |
128 | raise NotImplementedError('Not a valid output-type: {}'.format(options.output_type)) | |
140 | 129 | |
141 | 130 | |
142 | 131 | if __name__ == '__main__': |
214 | 214 | goal [holding(Ignatz,brick)]. |
215 | 215 | } |
216 | 216 | ===> Ignatz picks up the brick. |
217 | ===> Ignatz puts down the brick. | |
218 | 217 | ===> Ignatz picks up the oilcan. |
219 | ===> Ignatz picks up the brick. | |
218 | ===> Ignatz puts down the oilcan. | |
219 | ===> Ignatz picks up the oilcan. | |
220 | ===> Ignatz puts down the oilcan. | |
221 | ===> Ignatz picks up the oilcan. | |
222 | ===> Ignatz puts down the oilcan. | |
223 | ===> Ignatz picks up the oilcan. | |
220 | 224 | |
221 | 225 | Event rules |
222 | 226 | ----------- |
425 | 429 | |
426 | 430 | chairs |
427 | 431 | ------ |
432 | ||
433 | Somewhat uninteresting due to the deterministic randomness engine required | |
434 | to get the tests to be reproducible under both Python 2 and Python 3. | |
428 | 435 | |
429 | 436 | scenario Chairs { |
430 | 437 | |
455 | 462 | |
456 | 463 | goal []. |
457 | 464 | } |
458 | ===> Wembley sits down in the recliner. | |
459 | ===> Wembley leans back in the recliner. | |
460 | ===> Hastings sits down in the chair. | |
461 | ===> Petersen sits down in the sofa. | |
465 | ===> Hastings walks around the room. | |
466 | ===> Petersen walks around the room. | |
467 | ===> Hastings walks around the room. | |
468 | ===> Petersen walks around the room. | |
462 | 469 | |
463 | 470 | |
464 | 471 | no need for functions |
487 | 494 | goal []. |
488 | 495 | } |
489 | 496 | ===> Alice scratches her head. |
497 | ===> Bob scratches his head. | |
490 | 498 | ===> Alice scratches her head. |
491 | ===> Bob scratches his head. | |
492 | 499 | ===> Bob scratches his head. |
493 | 500 | |
494 | 501 | This loses the nice property of the function name being a readable |
509 | 516 | goal []. |
510 | 517 | } |
511 | 518 | ===> Alice scratches her head. |
519 | ===> Bob scratches his head. | |
512 | 520 | ===> Alice scratches her head. |
513 | 521 | ===> Bob scratches his head. |
514 | ===> Bob scratches his head. |
0 | scenario UntilHoldBrick { | |
1 | [actor(α),item(β),~holding(α,β)] α picks up the β. [holding(α,β)] | |
2 | [actor(α),item(β),holding(α,β)] α puts down the β. [~holding(α,β)] | |
3 | actor(Ignatz). | |
4 | item(brick). | |
5 | item(oilcan). | |
6 | goal [holding(Ignatz,brick)]. | |
7 | }⏎ |
14 | 14 | pattern = patterns[0] |
15 | 15 | |
16 | 16 | if isinstance(pattern, Assert): |
17 | for proposition in database: | |
17 | # While the construction and iteration of the database set in Python 2 seems to be | |
18 | # stable, when running under Python 3, we get an unpredictable order when iterating | |
19 | # here. So we sort the iterable before making matches, so that we can accumulate | |
20 | # them in a predictable order (for tests). TODO: if this hurts performance, provide | |
21 | # a command-line option to turn it off. | |
22 | for proposition in sorted(database): | |
18 | 23 | try: |
19 | 24 | unifier = pattern.term.match(proposition, env, unique_binding=True) |
20 | 25 | except ValueError: |
0 | # Sources of randomness, for Samovar. | |
1 | ||
2 | ||
3 | class CannedRandomness(object): | |
4 | def __init__(self): | |
5 | self.counter = 0 | |
6 | self.limit = 1 | |
7 | ||
8 | def advance(self): | |
9 | self.counter += 1 | |
10 | if self.counter > self.limit: | |
11 | self.counter = 0 | |
12 | self.limit += 1 | |
13 | ||
14 | def choice(self, iterable): | |
15 | length = len(iterable) | |
16 | index = self.counter % length | |
17 | selection = iterable[index] | |
18 | self.advance() | |
19 | return selection |
14 | 14 | class Term(AbstractTerm): |
15 | 15 | def __init__(self, constructor, *subterms): |
16 | 16 | self.t = tuple([constructor] + list(subterms)) |
17 | ||
18 | def __lt__(self, other): | |
19 | if isinstance(other, Term): | |
20 | return self.t < other.t | |
21 | else: | |
22 | raise TypeError("'<' not supported between instances of 'Term' and '{}'".format(other.__class__.__name__)) | |
17 | 23 | |
18 | 24 | @property |
19 | 25 | def constructor(self): |
179 | 179 | self.assertMatchAll( |
180 | 180 | [a(t('actor', t('?C'))), a(t('weapon', t('?W'))), r(t('holding', t('?C'), t('?W')))], |
181 | 181 | [ |
182 | {'?W': t('club'), '?C': t('alice')}, | |
182 | 183 | {'?W': t('revolver'), '?C': t('alice')}, |
183 | {'?W': t('club'), '?C': t('alice')}, | |
184 | {'?W': t('club'), '?C': t('bob')}, | |
184 | 185 | {'?W': t('knife'), '?C': t('bob')}, |
185 | {'?W': t('club'), '?C': t('bob')}, | |
186 | 186 | ] |
187 | 187 | ) |
188 | 188 | # Note that we can't say "Find all actors who aren't Alice". |