def test_copy_standardize_apart(): h = Heap() t = Callable.build("a", [Callable.build("b"), NumberedVar(0)]) res = t.copy_standardize_apart(h, [None]) assert res.argument_at(1).parent_or_binding is res assert not res.argument_at(1).bound assert res.argument_at(1).__class__.__name__ == "VarInTerm1"
def test_varinterm_bind_again(): h = Heap() t = Callable.build("a", [Callable.build("b"), NumberedVar(0)]) res = t.copy_standardize_apart(h, [None]) v = res.argument_at(1) v.unify(Callable.build("c"), h) py.test.raises(UnificationFailed, v.unify, Callable.build("d"), h)
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_cache_atoms(): a1 = Callable.build('foo', cache=False) a2 = Callable.build('foo', cache=False) assert a1 is not a2 a1 = Callable.build('foo') a2 = Callable.build('foo') assert a1 is a2
def term_variables(engine, heap, prolog_term, variables, consider_attributes=False): varlist = [] varc = variables seen = {} todo = [prolog_term] cls = Var if consider_attributes: cls = AttVar while todo: t = todo.pop() value = t.dereference(heap) if isinstance(value, cls): if consider_attributes and value.is_empty(): continue if value not in seen: varlist.append(value) seen[value] = None X = heap.newvar() prolog_list = Callable.build(".", [value, X]) prolog_list.unify(varc, heap) varc = X elif isinstance(value, Callable): numargs = value.argument_count() for i in range(numargs - 1, -1, -1): todo.append(value.argument_at(i)) varc.unify(Callable.build("[]"), heap)
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_convert_to_str(): assert "a" == convert_to_str(Callable.build("a")) assert "100" == convert_to_str(Callable.build("100")) assert "1000.111" == convert_to_str(Callable.build("1000.111")) assert ("100000000000000000000" == convert_to_str(Callable.build("100000000000000000000"))) assert "1" == convert_to_str(BigInt(rbigint.fromint(1))) assert ("-1000000000000000" == convert_to_str(BigInt(rbigint.fromdecimalstr("-1000000000000000"))))
def test_callable_factory_for_cons(): r = Callable.build('.', [1, Callable.build('[]')]) assert isinstance(r, specialized_term_classes['.', 2]) assert r.signature().string() == './2' assert r.name() == '.' assert r.argument_count() == 2 assert r.arguments() == [1, Callable.build('[]')] assert r.argument_at(0) == 1 assert r.argument_at(1) == Callable.build('[]')
def test_varinterm_bind(): h = Heap() t = Callable.build("a", [Callable.build("b"), NumberedVar(0)]) res = t.copy_standardize_apart(h, [None]) v = res.argument_at(1) v.unify(Callable.build("c"), h) assert res.argument_at(1).name() == "c" assert v.parent_or_binding.name() == "c" assert v.bound
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 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 test_enumerate_vars_of_bound_var(): from prolog.interpreter.memo import EnumerationMemo h = Heap() X = h.newvar() X.setvalue(Callable.build("a"), h) t1 = Callable.build("f", [X]) memo = EnumerationMemo() t2 = t1.enumerate_vars(memo) assert is_term(t2) assert t2.signature().eq(t1.signature()) assert t1.argument_at(0).dereference(None) is t2.argument_at(0)
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_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_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_cyclic_term(): h = Heap() X = h.newvar() t = Callable.build("f", [X], heap=h) t.unify(X, h) Y = h.newvar() t2 = Callable.build("f", [Y], heap=h) t2.unify(Y, h) t.unify(t2, h) # does not crash X.unify(Y, h) # does not crash
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 _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_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_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_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_several_attvars_same_map(): a = AttVar() b = AttVar() assert a.attmap is b.attmap val1 = Callable.build("1") val2 = Callable.build("2") a.add_attribute("x", val1) assert a.attmap is not b.attmap b.add_attribute("x", val2) assert a.attmap is b.attmap a.add_attribute("y", val1) a.add_attribute("z", val2) assert a.attmap is not b.attmap
def _process_hooks(scont, fcont, heap, engine): if heap.hook: e = engine #e = scont.engine hookcell = heap.hook heap.hook = None while hookcell: attvar = hookcell.attvar att = attvar.getbinding() attmap = jit.hint(attvar.attmap, promote=True) for i in range(len(attvar.value_list)): val = attvar.value_list[i] if val is None: continue module = attmap.get_attname_at_index(i) query = Callable.build("attr_unify_hook", [val, att]) try: mod = e.modulewrapper.get_module(module, query) except error.CatchableError, err: scont, fcont, heap = scont.engine.throw( err, scont, fcont, heap) break scont, fcont, heap = e.call_in_module(query, mod, scont, fcont, heap) heap.add_trail_atts(attvar, module) hookcell = hookcell.next attvar.value_list = None # XXX?
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 impl_copy_term_3(engine, heap, prolog_term, copy, goals): from prolog.interpreter.memo import CopyMemo gs = [] memo = CopyMemo() X = heap.newvar() impl_term_attvars(engine, heap, prolog_term, X) attvars = unwrap_list(X.dereference(heap)) for attvar in attvars: V = heap.newvar() memo.set(attvar, V) assert isinstance(attvar, AttVar) for module, index in attvar.attmap.indexes.iteritems(): val = attvar.value_list[index] put_attr = Callable.build("put_attr", [V, Callable.build(module), val]) gs.append(put_attr) prolog_term.copy(heap, memo).unify(copy, heap) goals.unify(wrap_list(gs), heap)
def test_varinterm_bind_later(): h = Heap() t = Callable.build("a", [Callable.build("b"), NumberedVar(0)]) res = t.copy_standardize_apart(h, [None]) h2 = h.branch() v = res.argument_at(1) assert v.dereference(h2) is v v.unify(Callable.build("c"), h2) assert res.argument_at(1).dereference(h2).name() == "c" h2.revert_upto(h) v2 = res.argument_at(1) assert v2.dereference(h2) is v2 v.dereference(h2) is v2 v.unify(Callable.build("d"), h2) assert res.argument_at(1).dereference(h2).name() == "d"
def test_copy_standardize_apart_term(): heap = Heap() Z = NumberedVar(0) t = Callable.build("f", [Z, Z]) t2 = t.copy_standardize_apart(heap, [None]) assert isinstance(t2.argument_at(0), Var) assert t2.argument_at(0) is t2.argument_at(1) t2 = t.copy_standardize_apart(heap, [Number(1)]) assert isinstance(t2.argument_at(0), Number) assert t2.argument_at(0) is t2.argument_at(1) Z = NumberedVar(-1) t = Callable.build("f", [Z, Z]) t2 = t.copy_standardize_apart(heap, [None]) assert isinstance(t2.argument_at(0), Var) assert isinstance(t2.argument_at(1), Var) assert t2.argument_at(0) is not t2.argument_at(1)
def add_meta_prefixes(self, query, current_module): if not self.meta_args: return query numargs = query.argument_count() args = [None] * numargs for i in range(numargs): args[i] = self._prefix_argument(query.argument_at(i), self.meta_args[i], current_module) return Callable.build(query.name(), args)
def test_attvars_with_maps(): a = AttVar() assert a.attmap is AttVar.attmap assert a.attmap.indexes == {} assert a.value_list == [] val1 = Callable.build("1") a.add_attribute("x", val1) assert a.attmap is not AttVar.attmap assert a.attmap.indexes == {"x": 0} assert a.value_list == [val1] m1 = a.attmap a.del_attribute("x") assert m1 is a.attmap assert a.value_list == [None] a.add_attribute("x", val1) assert a.attmap is m1 assert a.value_list == [val1] val2 = Callable.build("2") a.add_attribute("y", val2) m2 = a.attmap assert m2.indexes == {"x": 0, "y": 1} assert a.value_list == [val1, val2] a.del_attribute("x") assert a.attmap is m2 assert a.value_list == [None, val2] a.del_attribute("y") assert a.attmap is m2 assert a.value_list == [None, None] val3 = Callable.build("3") a.add_attribute("z", val3) m3 = a.attmap assert m3.indexes == {"x": 0, "y": 1, "z": 2} assert a.value_list == [None, None, val3] a.add_attribute("x", val1) assert a.attmap is m3 assert a.value_list == [val1, None, val3]
def test_callable_mutable(): for name in [".", "f"]: t = Callable.build(name, [NumberedVar(0), NumberedVar(1)]) res = t.copy_standardize_apart(Heap(), [None, None]) assert isinstance(res, MutableCallable) res.set_argument_at(0, 1) assert res.argument_at(0) == 1 res.set_argument_at(1, 7) assert res.argument_at(0) == 1 assert res.argument_at(1) == 7
def impl_add_library_dir(engine, heap, path): from os.path import isdir assert path is not None if not isdir(path): error.throw_existence_error("source_sink", Callable.build(path)) libs = engine.modulewrapper.libs for lib in libs: if lib == path: return engine.modulewrapper.libs.append(path)
def test_callable_build_for_term1_from_factory(): t2 = Callable.build('foo', [Atom('bar')]) assert not isinstance(t2, Term) assert isinstance(t2, Callable) assert t2.name() == 'foo' assert t2.signature().string() == 'foo/1' assert len(t2.arguments()) == 1 assert t2.arguments()[0] is not None assert t2.argument_at(0).name() == 'bar' assert t2.argument_count() == 1
def test_attvars_get(): a = AttVar() t1 = a.get_attribute("x") assert t1[0] is None assert t1[1] == -1 val1 = Callable.build("1") a.add_attribute("x", val1) t2 = a.get_attribute("x") assert t2[0] is val1 assert t2[1] == 0
def cons_to_atom(cons): atomlist = helper.unwrap_list(cons) result = [] for atom in atomlist: if not isinstance(atom, term.Atom): error.throw_type_error("text", atom) name = atom.name() if not len(name) == 1: error.throw_type_error("text", atom) result.append(atom.name()) return Callable.build("".join(result))
def test_callable_build_removes_unneeded_vars(): h1 = Heap() v1 = h1.newvar() v1.binding = 1 h2 = h1.branch() v2 = h2.newvar() v2.binding = 2 t = Callable.build("hello", [v1, v2], heap=h2) assert t.argument_at(0) is v1 assert t.argument_at(1) == 2
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 get_source(filename): try: assert isinstance(filename, str) fd, actual_filename = get_filehandle(filename, True) except OSError: throw_existence_error("source_sink", Callable.build(filename)) assert 0, "unreachable" # make the flow space happy try: content = [] while 1: s = os.read(fd, 4096) if not s: break content.append(s) file_content = "".join(content) finally: os.close(fd) return file_content, actual_filename
def _process_hooks(scont, fcont, heap): if heap.hook: e = scont.engine hookcell = heap.hook heap.hook = None while hookcell: attvar = hookcell.attvar attmap = jit.hint(attvar.attmap, promote=True) for i in range(len(attvar.value_list)): val = attvar.value_list[i] if val is None: continue module = attmap.get_attname_at_index(i) query = Callable.build("attr_unify_hook", [val, attvar]) try: mod = e.modulewrapper.get_module(module, query) except error.CatchableError, err: scont, fcont, heap = scont.engine.throw(err, scont, fcont, heap) break scont, fcont, heap = e.call_in_module(query, mod, scont, fcont, heap) heap.add_trail_atts(attvar, module) hookcell = hookcell.next attvar.value_list = None # XXX?
def impl_this_module(engine, heap, module): name = engine.modulewrapper.current_module.name Callable.build(name).unify(module, heap)