def test_full(): from prolog.interpreter.term import BindingVar, Atom, Term all = [] e = Engine() class CollectContinuation(object): rule = None cont_type_name = "CollectContinuation" module = e.modulewrapper.user_module def is_done(self): return False def discard(self): pass def activate(self, fcont, heap): all.append( (X.dereference(heap).name(), Y.dereference(heap).name())) raise error.UnificationFailed e.add_rule(Callable.build("f", [Callable.build("x")]), True) e.add_rule(Callable.build("f", [Callable.build("y")]), True) e.add_rule(Callable.build("g", [Callable.build("a")]), True) e.add_rule(Callable.build("g", [Callable.build("b")]), True) X = BindingVar() Y = BindingVar() query = Callable.build( ",", [Callable.build("f", [X]), Callable.build("g", [Y])]) py.test.raises(error.UnificationFailed, e.run_query, query, e.modulewrapper.user_module, CollectContinuation()) assert all == [("x", "a"), ("x", "b"), ("y", "a"), ("y", "b")]
def test_enumerate_vars_head_body(): from prolog.interpreter.memo import EnumerationMemo A = BindingVar() # single, head B = BindingVar() # double, head C = BindingVar() # both D = BindingVar() # single, body E = BindingVar() # double, body head = Callable.build("f", [A, B, B, C]) body = Callable.build("g", [C, D, E, E]) memo = EnumerationMemo() head = head.enumerate_vars(memo) memo.in_head = False body = body.enumerate_vars(memo) memo.assign_numbers() h1, h2, h3, h4 = head.arguments() assert h1.num == -1 assert h2 is h3 assert h2.num == 1 assert h4.num == 0 b1, b2, b3, b4 = body.arguments() assert b1 is h4 assert b2.num == -1 assert b3 is b4 assert b3.num == 1
def test_numeral(): from prolog.interpreter.term import Callable, Atom, BindingVar from prolog.interpreter.continuation import Engine t = parse_file(""" numeral(null). % end of line comment numeral(succ(X)) :- numeral(X). % another one add_numeral(X, null, X). add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z). greater_than(succ(null), null). greater_than(succ(X), null) :- greater_than(X, null). greater_than(succ(X), succ(Y)) :- greater_than(X, Y). """) builder = TermBuilder() facts = builder.build(t) e = Engine() m = e.modulewrapper for fact in facts: print fact e.add_rule(fact) assert m.modules["user"].lookup(Signature.getsignature("add_numeral", 3)).rulechain.head.argument_at(1).name() == "null" four = Callable.build("succ", [Callable.build("succ", [Callable.build("succ", [Callable.build("succ", [Callable.build("null")])])])]) e.run_query_in_current(parse_query_term("numeral(succ(succ(null))).")) term = parse_query_term( """add_numeral(succ(succ(null)), succ(succ(null)), X).""") e.run_query_in_current(term) hp = Heap() var = BindingVar().dereference(hp) # does not raise var.unify(four, hp) term = parse_query_term( """greater_than(succ(succ(succ(null))), succ(succ(null))).""") e.run_query_in_current(term)
def newvar(self, name=None): """ Make a new variable. Should return a Var instance, possibly with interesting attributes set that e.g. add_trail can inspect.""" if (name == None): raise Error("ERROR BindingVar has no name") result = BindingVar(name) result.created_after_choice_point = self return result
def test_term(): X = BindingVar() Y = BindingVar() t1 = Callable.build("f", [Callable.build("hallo"), X]) t2 = Callable.build("f", [Y, Callable.build("HALLO")]) heap = Heap() print t1, t2 t1.unify(t2, heap) assert X.dereference(heap).name()== "HALLO" assert Y.dereference(heap).name()== "hallo"
def _term_expand(self, term): if self.modulewrapper.system is not None: v = BindingVar() call = Callable.build("term_expand", [term, v]) try: self.run_query_in_current(call) except error.UnificationFailed: v = BindingVar() call = Callable.build("term_expand", [term, v]) self.run_query(call, self.modulewrapper.system) term = v.dereference(None) return term
def test_enumerate_vars(): from prolog.interpreter.memo import EnumerationMemo X = BindingVar() Y = BindingVar() t1 = Callable.build("f", [X, X, Callable.build("g", [Y, X])]) memo = EnumerationMemo() t2 = t1.enumerate_vars(memo) assert is_term(t2) assert t2.signature().eq(t1.signature()) assert t2.argument_at(0) is t2.argument_at(1) assert t2.argument_at(0).num == 0 assert t2.argument_at(2).argument_at(1).num == 0
def test_unify_and_standardize_apart(): heap = Heap() X = BindingVar() Y = BindingVar() Z = NumberedVar(0) t1 = Callable.build( "f", [Z, Callable.build("g", [Z, Callable.build("h")]), Z]) t2 = Callable.build("f", [Callable.build("i"), X, Y]) env = [None] t1.unify_and_standardize_apart(t2, heap, env) Z = NumberedVar(-1) Z.unify_and_standardize_apart(t2, heap, [])
def test_enumerate_vars_var_occurs_once(): from prolog.interpreter.memo import EnumerationMemo X = BindingVar() Y = BindingVar() Z = BindingVar() t1 = Callable.build("f", [X, Y, Y, Z, Z]) memo = EnumerationMemo() t2 = t1.enumerate_vars(memo) assert t2.argument_at(0).num == -1 assert t2.argument_at(1).num == 0 assert t2.argument_at(2).num == 0 assert t2.argument_at(3).num == 1 assert t2.argument_at(4).num == 1
def test_list(): f = formatting.TermFormatter(Engine(), quoted=False, ignore_ops=False) t = parse_query_term("[1, 2, 3, 4, 5 | X].") assert f.format(t) == "[1, 2, 3, 4, 5|_G0]" t = parse_query_term("[a, b, 'A$%%$$'|[]].") assert f.format(t) == "[a, b, A$%%$$]" t = parse_query_term("'.'(a, b, c).") assert f.format(t) == ".(a, b, c)" X = BindingVar() a = Callable.build('a') t = Callable.build(".", [a, X]) X.binding = Callable.build(".", [a, Callable.build("[]")]) assert f.format(t) == "[a, a]"
def test_ground_args(): e = Engine() m = e.modulewrapper r = Rule(C(1), C(2), m.user_module) assert r.groundargs is None head = Callable.build("f", [Number(1)]) r = Rule(head, C(2), m.user_module) assert r.groundargs == [True] head = Callable.build("f", [ Callable.build("g", [Number(1)]), BindingVar(), Callable.build("h", [Number(2), BindingVar()]) ]) r = Rule(head, C(2), m.user_module) assert r.groundargs == [True, False, False]
def test_run(): e = Engine() e.add_rule(Callable.build("f", [Callable.build("a"), Callable.build("b")])) X = BindingVar() Y = BindingVar() c = Callable.build("f", [X, X]) e.add_rule(c) c2 = Callable.build(":-", [Callable.build("f", [X, Y]), Callable.build("f", [Y, X])]) e.add_rule(c2) hp = Heap() X = hp.newvar() c3 = Callable.build("f", [Callable.build("b"), X]) e.run_query_in_current(c3) assert X.dereference(hp).name()== "b" query = Callable.build("f", [Callable.build("b"), Callable.build("a")]) e.run_query_in_current(query)
def test_run(): e = Engine() e.add_rule(Callable.build("f", [Callable.build("a"), Callable.build("b")])) X = BindingVar() Y = BindingVar() c = Callable.build("f", [X, X]) e.add_rule(c) c2 = Callable.build( ":-", [Callable.build("f", [X, Y]), Callable.build("f", [Y, X])]) e.add_rule(c2) hp = Heap() X = hp.newvar() c3 = Callable.build("f", [Callable.build("b"), X]) e.run_query_in_current(c3) assert X.dereference(hp).name() == "b" query = Callable.build("f", [Callable.build("b"), Callable.build("a")]) e.run_query_in_current(query)
def test_enumerate_vars_var_occurs_once(): from prolog.interpreter.memo import EnumerationMemo X = BindingVar() Y = BindingVar() Z = BindingVar() t1 = Callable.build("f", [X, Y, Y, Z, Z]) memo = EnumerationMemo() t2 = t1.enumerate_vars(memo) memo.assign_numbers() a1, a2, a3, a4, a5 = t2.arguments() assert a1.num == -1 if a2.num == 0: assert a3.num == 0 assert a4.num == 1 assert a5.num == 1 else: assert a2.num == a3.num == 1 assert a4.num == a5.num == 0
def test_quick_unify_check(): a = Callable.build("hallo", [NumberedVar(0), Number(10), Number(11)]) b = Callable.build( "hallo", [Callable.build("a"), Number(10), BindingVar()]) assert a.quick_unify_check(b) a = Callable.build( "hallo", [NumberedVar(0), Number(10), Callable.build("b")]) b = Callable.build("hallo", [Callable.build("a"), Number(10), Number(11)]) assert not a.quick_unify_check(b) a = Callable.build("hallo", [Callable.build("a"), Number(10), Number(11)]) b = Callable.build( "hallo", [BindingVar(), Number(10), Callable.build("b")]) assert a.quick_unify_check(a) assert b.quick_unify_check(b) assert not a.quick_unify_check(b)
def test_numeral(): from prolog.interpreter.term import Callable, Atom, BindingVar from prolog.interpreter.continuation import Engine t = parse_file(""" numeral(null). % end of line comment numeral(succ(X)) :- numeral(X). % another one add_numeral(X, null, X). add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z). greater_than(succ(null), null). greater_than(succ(X), null) :- greater_than(X, null). greater_than(succ(X), succ(Y)) :- greater_than(X, Y). """) builder = TermBuilder() facts = builder.build(t) e = Engine() m = e.modulewrapper for fact in facts: print fact e.add_rule(fact) assert m.modules["user"].lookup(Signature.getsignature( "add_numeral", 3)).rulechain.head.argument_at(1).name() == "null" four = Callable.build("succ", [ Callable.build("succ", [ Callable.build("succ", [Callable.build("succ", [Callable.build("null")])]) ]) ]) e.run_query_in_current(parse_query_term("numeral(succ(succ(null))).")) term = parse_query_term( """add_numeral(succ(succ(null)), succ(succ(null)), X).""") e.run_query_in_current(term) hp = Heap() var = BindingVar().dereference(hp) # does not raise var.unify(four, hp) term = parse_query_term( """greater_than(succ(succ(succ(null))), succ(succ(null))).""") e.run_query_in_current(term)
def test_dont_clone_ground_arg(): m = Engine().modulewrapper n = Number(1) n.unify_and_standardize_apart = None head = Callable.build("f", [n]) r = Rule(head, C(2), m.user_module) assert r.groundargs == [True] b = BindingVar() callhead = Callable.build("f", [b]) h = Heap() # should not fail, because ground args don't need cloning r.clone_and_unify_head(h, callhead)
def test_term(): X = BindingVar() Y = BindingVar() t1 = Callable.build("f", [Callable.build("hallo"), X]) t2 = Callable.build("f", [Y, Callable.build("HALLO")]) heap = Heap() print t1, t2 t1.unify(t2, heap) assert X.dereference(heap).name() == "HALLO" assert Y.dereference(heap).name() == "hallo"
def newvar(self): """ Make a new variable. Should return a Var instance, possibly with interesting attributes set that e.g. add_trail can inspect.""" result = BindingVar() result.created_after_choice_point = self return result
def test_var(): b = BindingVar() heap = Heap() b.unify(Callable.build("hallo"), heap) assert b.dereference(heap).name() == "hallo" a = BindingVar() b = BindingVar() a.unify(b, heap) a.unify(Callable.build("hallo"), heap) assert a.dereference(heap).name() == "hallo" assert b.dereference(heap).name() == "hallo"
def test_copy_dereferences(): from prolog.interpreter.memo import CopyMemo v1 = BindingVar() v1.binding = Number(10) v2 = v1.copy(None, CopyMemo()) assert v2.num == 10
def test_unify_var(): b = BindingVar() heap = Heap() b.unify(b, heap) b.unify(Callable.build("hallo"), heap) py.test.raises(UnificationFailed, b.unify, Callable.build("bye"), heap)
def test_recursive(): b = BindingVar() heap = Heap() b.unify(Callable.build("hallo", [b]), heap)
def test_var(): b = BindingVar() heap = Heap() b.unify(Callable.build("hallo"), heap) assert b.dereference(heap).name()== "hallo" a = BindingVar() b = BindingVar() a.unify(b, heap) a.unify(Callable.build("hallo"), heap) assert a.dereference(heap).name()== "hallo" assert b.dereference(heap).name()== "hallo"
def test_simple_hooks(): hp = Heap() v = BindingVar() a = AttVar() v.unify(a, hp) assert hp.hook is None v.unify(Number(1), hp) assert hp.hook.attvar == a hp = Heap() v1 = BindingVar() v2 = BindingVar() a1 = AttVar() a2 = AttVar() v1.unify(a1, hp) assert hp.hook is None v2.unify(a2, hp) assert hp.hook is None v1.unify(v2, hp) assert hp.hook.attvar == a1 hp = Heap() v1 = BindingVar() v2 = BindingVar() v3 = BindingVar() a1 = AttVar() a2 = AttVar() a3 = AttVar() v1.unify(a1, hp) v2.unify(a2, hp) v3.unify(a3, hp) v1.unify(v2, hp) v2.unify(v3, hp) assert hp.hook.attvar == a2 assert hp.hook.next.attvar == a1 assert hp.hook.next.next is None hp = Heap() v1 = BindingVar() v2 = BindingVar() a1 = AttVar() a2 = AttVar() v1.unify(a1, hp) v2.unify(a2, hp) assert hp.hook is None v1.unify(v2, hp) assert hp.hook.attvar == a1 v1.unify(Number(1), hp) assert hp.hook.attvar == a2 assert hp.hook.next.attvar == a1 assert hp.hook.next.next is None hp = Heap() v1 = BindingVar() v2 = BindingVar() a1 = AttVar() a2 = AttVar() v1.unify(a1, hp) v2.unify(a2, hp) t1 = Callable.build("f", [v1, v2]) t2 = Callable.build("f", [Atom("a"), Atom("b")]) t1.unify(t2, hp) assert hp.hook.attvar == a2 assert hp.hook.next.attvar == a1 assert hp.hook.next.next is None hp = Heap() v = BindingVar() av = AttVar() v.unify(av, hp) assert hp.hook is None a = Callable.build("a") v.unify(a, hp) assert hp.hook.attvar == av v.unify(a, hp) assert hp.hook.attvar == av assert hp.hook.next is None
def test_unwrap_list(): a = Callable.build("a") l = unwrap_list(Callable.build(".", [a, Callable.build("[]")])) assert len(l) == 1 assert l[0] is a v1 = BindingVar() a1 = Callable.build("a") l1 = unwrap_list(Callable.build(".", [v1, Callable.build(".", [a1, Callable.build("[]")])])) assert l1 == [v1, a1] empty = Callable.build("[]") v2 = BindingVar() l2 = Callable.build(".", [a, v2]) v2.unify(empty, Heap()) unwrapped = unwrap_list(l2) assert unwrapped == [a] v3 = BindingVar() v4 = BindingVar() b = Callable.build("b") h = Heap() l3 = Callable.build(".", [a, v3]) v3.unify(Callable.build(".", [b, v4]), h) v4.unify(Callable.build("[]"), h) unwrapped2 = unwrap_list(l3) assert unwrapped2 == [a, b]