def visit_atom(self, node: Node, children: List) -> 'Atom': from foil.models import Atom try: return Atom(children[0], children[1]) except IndexError: return Atom(children[0])
def test__get_arity(self): for i, entry in enumerate([ (Atom('func'), 0), (Atom('func', []), 0), (Atom('func', ['term']), 1), (Atom('func', ['term', 5.0]), 2), (Atom('func', ['term', 5.0, True]), 3), ]): atom, expected = entry with self.subTest(i=i, value=entry): result = atom.get_arity() assert_that(result, 'Atom.get_arity(self) -> int:') \ .is_equal_to(expected)
def find_literal( hypotheses: List['Clause'], target: 'Literal', body: List['Literal'], background: List['Clause'], masks: List['Literal'], constants: List['Value'], positives: List['Assignment'], negatives: List['Assignment'], ) -> Optional[Candidate]: from foil.models import Atom from foil.models import Clause from foil.models import Literal from foil.models import Program candidate, table, bound = None, get_table([target, *body]), max_gain( positives, negatives) for mask in masks: for items in itemize(table, mask.arity): literal = Literal(Atom(mask.functor, items), mask.negated) world = Program( [*hypotheses, Clause(target, [*body, literal]), *background]).ground() positives_i = extend(positives, literal, constants, world) negatives_i = extend(negatives, literal, constants, world) score = gain(positives, negatives, positives_i, negatives_i) if candidate and bound < candidate.score: break if candidate is None or score > candidate.score: candidate = Candidate(score, literal, positives_i, negatives_i) return candidate
def test__is_ground(self): for i, entry in enumerate([ (Atom('func'), True), (Atom('func', []), True), (Atom('func', ['term']), True), (Atom('func', ['term', 5.0]), True), (Atom('func', ['term', 5.0, True]), True), (Atom('func', ['term', 5.0, True, 'Var']), False), (Atom('func', ['term', 5.0, True, '_anon']), False), ]): atom, expected = entry with self.subTest(i=i, value=entry): result = atom.is_ground() assert_that(result, 'Atom.is_ground(self) -> bool:') \ .is_equal_to(expected)
def test__parse(self): for i, entry in enumerate([ ('func', Atom('func')), ('func()', Atom('func', [])), ('func(term)', Atom('func', ['term'])), ('func(term, 5.0)', Atom('func', ['term', 5.0])), ('func(term, 5.0, True)', Atom('func', ['term', 5.0, True])), ]): content, expected = entry with self.subTest(i=i, value=entry): result = Atom.parse(content) assert_that(result, 'Atom.parse(content: str) -> Atom:') \ .is_equal_to(expected)
def test__substitute(self): for i, entry in enumerate([ (Atom.parse('pred'), {}, Atom.parse('pred')), (Atom.parse('pred'), {'X': 'a'}, Atom.parse('pred')), (Atom.parse('pred'), {'Y': 'X'}, Atom.parse('pred')), (Atom.parse('pred(a)'), {}, Atom.parse('pred(a)')), (Atom.parse('pred(a)'), {'X': 'a'}, Atom.parse('pred(a)')), (Atom.parse('pred(a)'), {'Y': 'X'}, Atom.parse('pred(a)')), (Atom.parse('pred(X)'), {}, Atom.parse('pred(X)')), (Atom.parse('pred(X)'), {'X': 'a'}, Atom.parse('pred(a)')), (Atom.parse('pred(X)'), {'Y': 'X'}, Atom.parse('pred(X)')), (Atom.parse('pred(Y)'), {}, Atom.parse('pred(Y)')), (Atom.parse('pred(Y)'), {'X': 'a'}, Atom.parse('pred(Y)')), (Atom.parse('pred(Y)'), {'Y': 'X'}, Atom.parse('pred(X)')), (Atom.parse('pred(X, Y)'), {}, Atom.parse('pred(X, Y)')), (Atom.parse('pred(X, Y)'), {'X': 'a'}, Atom.parse('pred(a, Y)')), (Atom.parse('pred(X, Y)'), {'Y': 'X'}, Atom.parse('pred(X, X)')), ]): atom, subst, expected = entry with self.subTest(i=i, value=entry): result = atom.substitute(subst) assert_that(result, 'Atom.substitute(self, subst: Substitution) -> Atom:') \ .is_equal_to(expected)
def test__unify(self): for i, entry in enumerate([ (Atom('func'), Atom('pred'), None), (Atom('func'), Atom('func'), {}), (Atom('func', []), Atom('pred', []), None), (Atom('func', []), Atom('func', []), {}), (Atom('func', ['term', 5.0]), Atom('pred', ['term', 5.0]), None), (Atom('func', ['term', 5.0]), Atom('func', ['term', 5.0]), {}), (Atom('func', ['term', 5.0]), Atom('pred', ['term', 5.0]), None), (Atom('func', ['term', 5.0]), Atom('func', ['term', 5.0]), {}), (Atom('func', ['term', 5.0]), Atom('pred', [5.0, 'term']), None), (Atom('func', ['term', 5.0]), Atom('func', [5.0, 'term']), None), (Atom('func', ['term', 5.0]), Atom('pred', ['term']), None), (Atom('func', ['term', 5.0]), Atom('func', ['term']), None), (Atom('func', ['term', 5.0]), Atom('pred', [5.0]), None), (Atom('func', ['term', 5.0]), Atom('func', [5.0]), None), (Atom('func', ['term', 5.0]), Atom('pred', [True]), None), (Atom('func', ['term', 5.0]), Atom('func', [True]), None), (Atom('func', ['term', 'V1', 'V2']), Atom('pred', ['term', 5.0, True]), None), (Atom('func', ['term', 'V1', 'V2']), Atom('func', ['term', 5.0, True]), {'V1': 5.0, 'V2': True}), (Atom('func', ['term', 'V1', 'V2']), Atom('func', ['V0', 5.0, True]), {'V0': 'term', 'V1': 5.0, 'V2': True}), (Atom('func', ['term', 5.0, True]), Atom('func', ['term', 'V1', 'V2']), {'V1': 5.0, 'V2': True}), (Atom('func', ['term', 'V1', 'V2']), Atom('func', ['X', 'Y', 'Z']), {'X': 'term', 'Y': 'V1', 'Z': 'V2'}), ]): atom1, atom2, expected = entry with self.subTest(i=i, value=entry): result = atom1.unify(atom2) assert_that(result, 'Atom.unify(self, other: Atom) -> Optional[Substitution]:') \ .is_equal_to(expected)
def test__parse(self): for i, entry in enumerate([ ('func.', Clause(Literal(Atom('func')))), ('func().', Clause(Literal(Atom('func', [])))), ('func(Var).', Clause(Literal(Atom('func', ['Var'])))), ('func(term).', Clause(Literal(Atom('func', ['term'])))), ('func(term, 5.0).', Clause(Literal(Atom('func', ['term', 5.0])))), ('func(term, 5.0, True).', Clause(Literal(Atom('func', ['term', 5.0, True])))), ('~func.', Clause(Literal(Atom('func'), True))), ('~func().', Clause(Literal(Atom('func', []), True))), ('~func(Var).', Clause(Literal(Atom('func', ['Var']), True))), ('~func(term).', Clause(Literal(Atom('func', ['term']), True))), ('~func(term, 5.0).', Clause(Literal(Atom('func', ['term', 5.0]), True))), ('~func(term, 5.0, True).', Clause(Literal(Atom('func', ['term', 5.0, True]), True))), ('func :- pred.', Clause(Literal(Atom('func')), [Literal(Atom('pred'))])), ('func() :- pred.', Clause(Literal(Atom('func', [])), [Literal(Atom('pred'))])), ('func(Var) :- pred.', Clause(Literal(Atom('func', ['Var'])), [Literal(Atom('pred'))])), ('func(term) :- pred.', Clause(Literal(Atom('func', ['term'])), [Literal(Atom('pred'))])), ('func(term, 5.0) :- pred.', Clause(Literal(Atom('func', ['term', 5.0])), [Literal(Atom('pred'))])), ('func(term, 5.0, True) :- pred.', Clause(Literal(Atom('func', ['term', 5.0, True])), [Literal(Atom('pred'))])), ('~func :- pred.', Clause(Literal(Atom('func'), True), [Literal(Atom('pred'))])), ('~func() :- pred.', Clause(Literal(Atom('func', []), True), [Literal(Atom('pred'))])), ('~func(Var) :- pred.', Clause(Literal(Atom('func', ['Var']), True), [Literal(Atom('pred'))])), ('~func(term) :- pred.', Clause(Literal(Atom('func', ['term']), True), [Literal(Atom('pred'))])), ('~func(term, 5.0) :- pred.', Clause(Literal(Atom('func', ['term', 5.0]), True), [Literal(Atom('pred'))])), ('~func(term, 5.0, True) :- pred.', Clause(Literal(Atom('func', ['term', 5.0, True]), True), [Literal(Atom('pred'))])), ]): content, expected = entry with self.subTest(i=i, value=entry): result = Clause.parse(content) assert_that(result, 'Clause.parse(content: str) -> Clause:') \ .is_equal_to(expected)