def test_match_all_with_negation(self): # Find all actors who are not holding the revolver. self.assertMatchAll( [a(t('actor', t('?C'))), r(t('holding', t('?C'), t('revolver')))], [{ '?C': t('alice') }]) # Find all actors who are not holding a weapon. Or rather, all pairs # of (actor, weapon) where the actor is not holding that weapon. self.assertMatchAll([ a(t('actor', t('?C'))), a(t('weapon', t('?W'))), r(t('holding', t('?C'), t('?W'))) ], [ { '?W': t('club'), '?C': t('alice') }, { '?W': t('revolver'), '?C': t('alice') }, { '?W': t('club'), '?C': t('bob') }, { '?W': t('knife'), '?C': t('bob') }, ]) # Note that we can't say "Find all actors who aren't Alice". # We can say this: self.assertMatchAll( [a(t('actor', t('?C'))), r(t('actor', t('alice')))], []) # ... but what this is saying is "Find all actors if Alice doesn't exist." # For a one-off case, we can do something like this: self.database.append(t('is_alice', t('alice'))) self.assertMatchAll( [a(t('actor', t('?C'))), r(t('is_alice', t('?C')))], [{ '?C': t('bob') }]) # For the general case, we'll need to think about equality tests. # Note also that we can't search on negative clauses with free variables: with self.assertRaises(KeyError): match_all(self.database, [a(t('actor', t('?C'))), r(t('weapon', t('?W')))], {})
def get_candidate_rules(self): candidates = [] for rule in self.scenario.rules: for unifier in match_all(self.state, rule.pre.exprs, rule.pre.bindings): candidates.append((rule, unifier)) if self.debug and False: # FIXME sys.stderr.write("Candidate rules:") for rule, unifiers in candidates: sys.stderr.write(rule.format()) sys.stderr.write("->", unifiers) sys.stderr.write("") return candidates
def events_meet_goal(self, moves): matches = match_all(self.state, self.scenario.goal.exprs, self.scenario.goal.bindings) return len(matches) > 0
def assertMatchAll(self, query, result): self.assertEqual(match_all(self.database, query, {}), result)