[pypy-svn] r42245 - in pypy/dist/pypy/lang/prolog: builtin interpreter interpreter/test

cfbolz at codespeak.net cfbolz at codespeak.net
Sun Apr 22 21:12:54 CEST 2007


Author: cfbolz
Date: Sun Apr 22 21:12:52 2007
New Revision: 42245

Modified:
   pypy/dist/pypy/lang/prolog/builtin/allsolution.py
   pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py
   pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py
   pypy/dist/pypy/lang/prolog/builtin/control.py
   pypy/dist/pypy/lang/prolog/builtin/database.py
   pypy/dist/pypy/lang/prolog/builtin/exception.py
   pypy/dist/pypy/lang/prolog/builtin/parseraccess.py
   pypy/dist/pypy/lang/prolog/builtin/register.py
   pypy/dist/pypy/lang/prolog/builtin/termconstruction.py
   pypy/dist/pypy/lang/prolog/builtin/unify.py
   pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py
   pypy/dist/pypy/lang/prolog/interpreter/choice.py
   pypy/dist/pypy/lang/prolog/interpreter/engine.py
   pypy/dist/pypy/lang/prolog/interpreter/interactive.py
   pypy/dist/pypy/lang/prolog/interpreter/parsing.py
   pypy/dist/pypy/lang/prolog/interpreter/term.py
   pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py
   pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py
   pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py
   pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py
   pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py
   pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py
   pypy/dist/pypy/lang/prolog/interpreter/test/tool.py
   pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py
Log:
some renamings, lots of cleanups. Re-implement unification, especially the way
terms are unified and standardized apart.


Modified: pypy/dist/pypy/lang/prolog/builtin/allsolution.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/allsolution.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/allsolution.py	Sun Apr 22 21:12:52 2007
@@ -11,23 +11,23 @@
         self.template = template
 
     def call(self, engine):
-        clone = self.template.getvalue(engine.frame)
+        clone = self.template.getvalue(engine.heap)
         self.found.append(clone)
         raise error.UnificationFailed()
 
 def impl_findall(engine, template, goal, bag):
-    oldstate = engine.frame.branch()
+    oldstate = engine.heap.branch()
     collector = FindallContinuation(template)
     try:
         engine.call(goal, collector)
     except error.UnificationFailed:
-        engine.frame.revert(oldstate)
+        engine.heap.revert(oldstate)
     result = term.Atom("[]")
     for i in range(len(collector.found) - 1, -1, -1):
         copy = collector.found[i]
         d = {}
-        copy = copy.clone_compress_vars(d, engine.frame.maxvar())
-        engine.frame.extend(len(d))
+        copy = copy.clone_compress_vars(d, engine.heap.maxvar())
+        engine.heap.extend(len(d))
         result = term.Term(".", [copy, result])
-    bag.unify(result, engine.frame)
+    bag.unify(result, engine.heap)
 expose_builtin(impl_findall, "findall", unwrap_spec=['raw', 'callable', 'raw'])

Modified: pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/arithmeticbuiltin.py	Sun Apr 22 21:12:52 2007
@@ -9,13 +9,13 @@
 def impl_between(engine, lower, upper, varorint, continuation):
     if isinstance(varorint, term.Var):
         for i in range(lower, upper):
-            oldstate = engine.frame.branch()
+            oldstate = engine.heap.branch()
             try:
-                varorint.unify(term.Number(i), engine.frame)
+                varorint.unify(term.Number(i), engine.heap)
                 return continuation.call(engine)
             except error.UnificationFailed:
-                engine.frame.revert(oldstate)
-        varorint.unify(term.Number(upper), engine.frame)
+                engine.heap.revert(oldstate)
+        varorint.unify(term.Number(upper), engine.heap)
         return continuation.call(engine)
     else:
         integer = helper.unwrap_int(varorint)
@@ -26,7 +26,7 @@
                handles_continuation=True)
 
 def impl_is(engine, var, num):
-    var.unify(num, engine.frame)
+    var.unify(num, engine.heap)
 expose_builtin(impl_is, "is", unwrap_spec=["raw", "arithmetic"])
 
 for ext, prolog, python in [("eq", "=:=", "=="),

Modified: pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/atomconstruction.py	Sun Apr 22 21:12:52 2007
@@ -11,13 +11,13 @@
             # nondeterministic splitting of result
             r = helper.convert_to_str(result)
             for i in range(len(r) + 1):
-                oldstate = engine.frame.branch()
+                oldstate = engine.heap.branch()
                 try:
-                    a1.unify(term.Atom(r[:i]), engine.frame)
-                    a2.unify(term.Atom(r[i:]), engine.frame)
+                    a1.unify(term.Atom(r[:i]), engine.heap)
+                    a2.unify(term.Atom(r[i:]), engine.heap)
                     return continuation.call(engine)
                 except error.UnificationFailed:
-                    engine.frame.revert(oldstate)
+                    engine.heap.revert(oldstate)
             raise error.UnificationFailed()
         else:
             s2 = helper.convert_to_str(a2)
@@ -25,7 +25,7 @@
             if r.endswith(s2):
                 stop = len(r) - len(s2)
                 assert stop > 0
-                a1.unify(term.Atom(r[:stop]), engine.frame)
+                a1.unify(term.Atom(r[:stop]), engine.heap)
             else:
                 raise error.UnificationFailed()
     else:
@@ -33,12 +33,12 @@
         if isinstance(a2, term.Var):
             r = helper.convert_to_str(result)
             if r.startswith(s1):
-                a2.unify(term.Atom(r[len(s1):]), engine.frame)
+                a2.unify(term.Atom(r[len(s1):]), engine.heap)
             else:
                 raise error.UnificationFailed()
         else:
             s2 = helper.convert_to_str(a2)
-            result.unify(term.Atom(s1 + s2), engine.frame)
+            result.unify(term.Atom(s1 + s2), engine.heap)
     return continuation.call(engine)
 expose_builtin(impl_atom_concat, "atom_concat",
                unwrap_spec=["obj", "obj", "obj"],
@@ -47,7 +47,7 @@
 def impl_atom_length(engine, s, length):
     if not (isinstance(length, term.Var) or isinstance(length, term.Number)):
         error.throw_type_error("integer", length)
-    term.Number(len(s)).unify(length, engine.frame)
+    term.Number(len(s)).unify(length, engine.heap)
 expose_builtin(impl_atom_length, "atom_length", unwrap_spec = ["atom", "obj"])
 
 def impl_sub_atom(engine, s, before, length, after, sub, continuation):
@@ -70,7 +70,7 @@
         if startbefore < 0:
             startbefore = 0
             stopbefore = len(s) + 1
-    oldstate = engine.frame.branch()
+    oldstate = engine.heap.branch()
     if not isinstance(sub, term.Var):
         s1 = helper.unwrap_atom(sub)
         if len(s1) >= stoplength or len(s1) < startlength:
@@ -83,12 +83,12 @@
                     if b < 0:
                         break
                     start = b + 1
-                    before.unify(term.Number(b), engine.frame)
-                    after.unify(term.Number(len(s) - len(s1) - b), engine.frame)
-                    length.unify(term.Number(len(s1)), engine.frame)
+                    before.unify(term.Number(b), engine.heap)
+                    after.unify(term.Number(len(s) - len(s1) - b), engine.heap)
+                    length.unify(term.Number(len(s1)), engine.heap)
                     return continuation.call(engine)
                 except:
-                    engine.frame.revert(oldstate)
+                    engine.heap.revert(oldstate)
                     raise
             except error.UnificationFailed:
                 pass
@@ -100,13 +100,13 @@
                     continue
                 try:
                     try:
-                        before.unify(term.Number(b), engine.frame)
-                        after.unify(term.Number(len(s) - l - b), engine.frame)
-                        length.unify(term.Number(l), engine.frame)
-                        sub.unify(term.Atom(s[b:b + l]), engine.frame)
+                        before.unify(term.Number(b), engine.heap)
+                        after.unify(term.Number(len(s) - l - b), engine.heap)
+                        length.unify(term.Number(l), engine.heap)
+                        sub.unify(term.Atom(s[b:b + l]), engine.heap)
                         return continuation.call(engine)
                     except:
-                        engine.frame.revert(oldstate)
+                        engine.heap.revert(oldstate)
                         raise
                 except error.UnificationFailed:
                     pass
@@ -119,14 +119,14 @@
                 continue
             try:
                 try:
-                    before.unify(term.Number(b), engine.frame)
-                    after.unify(term.Number(a), engine.frame)
-                    length.unify(term.Number(l), engine.frame)
-                    sub.unify(term.Atom(s[b:b + l]), engine.frame)
+                    before.unify(term.Number(b), engine.heap)
+                    after.unify(term.Number(a), engine.heap)
+                    length.unify(term.Number(l), engine.heap)
+                    sub.unify(term.Atom(s[b:b + l]), engine.heap)
                     return continuation.call(engine)
                     return None
                 except:
-                    engine.frame.revert(oldstate)
+                    engine.heap.revert(oldstate)
                     raise
             except error.UnificationFailed:
                 pass

Modified: pypy/dist/pypy/lang/prolog/builtin/control.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/control.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/control.py	Sun Apr 22 21:12:52 2007
@@ -33,7 +33,7 @@
         self.continuation = continuation
 
     def call(self, engine):
-        next_call = self.next_call.dereference(engine.frame)
+        next_call = self.next_call.dereference(engine.heap)
         if isinstance(next_call, term.Var):
             error.throw_instantiation_error()
         next_call = helper.ensure_callable(next_call)
@@ -48,11 +48,11 @@
                handles_continuation=True)
 
 def impl_or(engine, call1, call2, continuation):
-    oldstate = engine.frame.branch()
+    oldstate = engine.heap.branch()
     try:
         return engine.call(call1, continuation)
     except error.UnificationFailed:
-        engine.frame.revert(oldstate)
+        engine.heap.revert(oldstate)
     return engine.call(call2, continuation)
 
 expose_builtin(impl_or, ";", unwrap_spec=["callable", "callable"],
@@ -70,11 +70,11 @@
 expose_builtin(impl_not, ["not", "\\+"], unwrap_spec=["callable"])
 
 def impl_if(engine, if_clause, then_clause, continuation):
-    oldstate = engine.frame.branch()
+    oldstate = engine.heap.branch()
     try:
         engine.call(if_clause)
     except error.UnificationFailed:
-        engine.frame.revert(oldstate)
+        engine.heap.revert(oldstate)
         raise
     return engine.call(helper.ensure_callable(then_clause), continuation)
 expose_builtin(impl_if, "->", unwrap_spec=["callable", "raw"],

Modified: pypy/dist/pypy/lang/prolog/builtin/database.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/database.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/database.py	Sun Apr 22 21:12:52 2007
@@ -19,11 +19,11 @@
 expose_builtin(impl_abolish, "abolish", unwrap_spec=["obj"])
 
 def impl_assert(engine, rule):
-    engine.add_rule(rule.getvalue(engine.frame))
+    engine.add_rule(rule.getvalue(engine.heap))
 expose_builtin(impl_assert, ["assert", "assertz"], unwrap_spec=["callable"])
 
 def impl_asserta(engine, rule):
-    engine.add_rule(rule.getvalue(engine.frame), end=False)
+    engine.add_rule(rule.getvalue(engine.heap), end=False)
 expose_builtin(impl_asserta, "asserta", unwrap_spec=["callable"])
 
 
@@ -46,14 +46,14 @@
     rulechain = function.rulechain
     while rulechain:
         rule = rulechain.rule
-        oldstate = engine.frame.branch()
+        oldstate = engine.heap.branch()
         # standardizing apart
         try:
-            deleted_body = rule.clone_and_unify_head(engine.frame, head)
+            deleted_body = rule.clone_and_unify_head(engine.heap, head)
             if body is not None:
-                body.unify(deleted_body, engine.frame)
+                body.unify(deleted_body, engine.heap)
         except error.UnificationFailed:
-            engine.frame.revert(oldstate)
+            engine.heap.revert(oldstate)
         else:
             if function.rulechain is rulechain:
                 if rulechain.next is None:

Modified: pypy/dist/pypy/lang/prolog/builtin/exception.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/exception.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/exception.py	Sun Apr 22 21:12:52 2007
@@ -8,24 +8,24 @@
 
 def impl_catch(engine, goal, catcher, recover, continuation):
     catching_continuation = enginemod.LimitedScopeContinuation(continuation)
-    old_state = engine.frame.branch()
+    old_state = engine.heap.branch()
     try:
         return engine.call(goal, catching_continuation)
     except error.CatchableError, e:
         if not catching_continuation.scope_active:
             raise
-        exc_term = e.term.getvalue(engine.frame)
-        engine.frame.revert(old_state)
+        exc_term = e.term.getvalue(engine.heap)
+        engine.heap.revert(old_state)
         d = {}
-        exc_term = exc_term.clone_compress_vars(d, engine.frame.maxvar())
-        engine.frame.extend(len(d))
+        exc_term = exc_term.clone_compress_vars(d, engine.heap.maxvar())
+        engine.heap.extend(len(d))
         try:
             impl_ground(engine, exc_term)
         except error.UnificationFailed:
             raise error.UncatchableError(
                 "not implemented: catching of non-ground terms")
         try:
-            catcher.unify(exc_term, engine.frame)
+            catcher.unify(exc_term, engine.heap)
         except error.UnificationFailed:
             if isinstance(e, error.UserError):
                 raise error.UserError(exc_term)

Modified: pypy/dist/pypy/lang/prolog/builtin/parseraccess.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/parseraccess.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/parseraccess.py	Sun Apr 22 21:12:52 2007
@@ -9,14 +9,14 @@
     for prec, allops in engine.getoperations():
         for form, ops in allops:
             for op in ops:
-                oldstate = engine.frame.branch()
+                oldstate = engine.heap.branch()
                 try:
-                    precedence.unify(term.Number(prec), engine.frame)
-                    typ.unify(term.Atom(form), engine.frame)
-                    name.unify(term.Atom(op), engine.frame)
+                    precedence.unify(term.Number(prec), engine.heap)
+                    typ.unify(term.Atom(form), engine.heap)
+                    name.unify(term.Atom(op), engine.heap)
                     return continuation.call(engine)
                 except error.UnificationFailed:
-                    engine.frame.revert(oldstate)
+                    engine.heap.revert(oldstate)
     raise error.UnificationFailed()
 expose_builtin(impl_current_op, "current_op", unwrap_spec=["obj", "obj", "obj"],
                handles_continuation=True)

Modified: pypy/dist/pypy/lang/prolog/builtin/register.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/register.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/register.py	Sun Apr 22 21:12:52 2007
@@ -25,10 +25,10 @@
         varname = "var%s" % (i, )
         subargs.append(varname)
         if spec in ("obj", "callable", "int", "atom", "arithmetic"):
-            code.append("    %s = query.args[%s].dereference(engine.frame)" %
+            code.append("    %s = query.args[%s].dereference(engine.heap)" %
                         (varname, i))
         elif spec in ("concrete", "list"):
-            code.append("    %s = query.args[%s].getvalue(engine.frame)" %
+            code.append("    %s = query.args[%s].getvalue(engine.heap)" %
                         (varname, i))
         if spec in ("callable", "int", "atom", "arithmetic", "list"):
             code.append(

Modified: pypy/dist/pypy/lang/prolog/builtin/termconstruction.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/termconstruction.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/termconstruction.py	Sun Apr 22 21:12:52 2007
@@ -7,11 +7,11 @@
 
 def impl_functor(engine, t, functor, arity):
     if helper.is_atomic(t):
-        functor.unify(t, engine.frame)
-        arity.unify(term.Number(0), engine.frame)
+        functor.unify(t, engine.heap)
+        arity.unify(term.Number(0), engine.heap)
     elif isinstance(t, term.Term):
-        functor.unify(term.Atom(t.name), engine.frame)
-        arity.unify(term.Number(len(t.args)), engine.frame)
+        functor.unify(term.Atom(t.name), engine.heap)
+        arity.unify(term.Number(len(t.args)), engine.heap)
     elif isinstance(t, term.Var):
         if isinstance(functor, term.Var):
             error.throw_instantiation_error()
@@ -23,15 +23,15 @@
         else:
             functor = helper.ensure_atomic(functor)
             if a == 0:
-                t.unify(helper.ensure_atomic(functor), engine.frame)
+                t.unify(helper.ensure_atomic(functor), engine.heap)
             else:
                 name = helper.unwrap_atom(functor)
-                start = engine.frame.needed_vars
-                engine.frame.extend(a)
+                start = engine.heap.needed_vars
+                engine.heap.extend(a)
                 t.unify(
                     term.Term(name,
                               [term.Var(i) for i in range(start, start + a)]),
-                    engine.frame)
+                    engine.heap)
 expose_builtin(impl_functor, "functor", unwrap_spec=["obj", "obj", "obj"])
 
 def impl_arg(engine, first, second, third, continuation):
@@ -44,13 +44,13 @@
     if isinstance(first, term.Var):
         for i in range(len(second.args)):
             arg = second.args[i]
-            oldstate = engine.frame.branch()
+            oldstate = engine.heap.branch()
             try:
-                third.unify(arg, engine.frame)
-                first.unify(term.Number(i + 1), engine.frame)
+                third.unify(arg, engine.heap)
+                first.unify(term.Number(i + 1), engine.heap)
                 return continuation.call(engine)
             except error.UnificationFailed:
-                engine.frame.revert(oldstate)
+                engine.heap.revert(oldstate)
         raise error.UnificationFailed()
     elif isinstance(first, term.Number):
         num = first.num
@@ -61,7 +61,7 @@
         if num > len(second.args):
             raise error.UnificationFailed()
         arg = second.args[num - 1]
-        third.unify(arg, engine.frame)
+        third.unify(arg, engine.heap)
     else:
         error.throw_type_error("integer", first)
     return continuation.call(engine)
@@ -76,9 +76,9 @@
             l = [first]
         u1 = helper.wrap_list(l)
         if not isinstance(second, term.Var):
-            u1.unify(second, engine.frame)
+            u1.unify(second, engine.heap)
         else:
-            u1.unify(second, engine.frame)
+            u1.unify(second, engine.heap)
     else:
         if isinstance(second, term.Var):
             error.throw_instantiation_error()
@@ -87,14 +87,14 @@
             head = l[0]
             if not isinstance(head, term.Atom):
                 error.throw_type_error("atom", head)
-            term.Term(head.name, l[1:]).unify(first, engine.frame)
+            term.Term(head.name, l[1:]).unify(first, engine.heap)
 expose_builtin(impl_univ, "=..", unwrap_spec=["obj", "obj"])
 
 def impl_copy_term(engine, interm, outterm):
     d = {}
-    copy = interm.clone_compress_vars(d, engine.frame.maxvar())
-    engine.frame.extend(len(d))
-    outterm.unify(copy, engine.frame)
+    copy = interm.clone_compress_vars(d, engine.heap.maxvar())
+    engine.heap.extend(len(d))
+    outterm.unify(copy, engine.heap)
 expose_builtin(impl_copy_term, "copy_term", unwrap_spec=["obj", "obj"])
 
 

Modified: pypy/dist/pypy/lang/prolog/builtin/unify.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/builtin/unify.py	(original)
+++ pypy/dist/pypy/lang/prolog/builtin/unify.py	Sun Apr 22 21:12:52 2007
@@ -8,17 +8,21 @@
 # comparison and unification of terms
 
 def impl_unify(engine, obj1, obj2):
-    obj1.unify(obj2, engine.frame)
+    obj1.unify(obj2, engine.heap)
 expose_builtin(impl_unify, "=", unwrap_spec=["raw", "raw"])
 
 def impl_unify_with_occurs_check(engine, obj1, obj2):
-    obj1.unify(obj2, engine.frame, occurs_check=True)
+    obj1.unify(obj2, engine.heap, occurs_check=True)
 expose_builtin(impl_unify_with_occurs_check, "unify_with_occurs_check",
                unwrap_spec=["raw", "raw"])
 
 def impl_does_not_unify(engine, obj1, obj2):
     try:
-        obj1.unify(obj2, engine.frame)
+        branch = engine.heap.branch()
+        try:
+            obj1.unify(obj2, engine.heap)
+        finally:
+            engine.heap.revert(branch)
     except error.UnificationFailed:
         return
     raise error.UnificationFailed()
@@ -33,7 +37,7 @@
                             ("ge", "@>=", "!= -1")]:
     exec py.code.Source("""
 def impl_standard_comparison_%s(engine, obj1, obj2):
-    c = term.cmp_standard_order(obj1, obj2, engine.frame)
+    c = term.cmp_standard_order(obj1, obj2, engine.heap)
     if not c %s:
         raise error.UnificationFailed()""" % (ext, python)).compile()
     expose_builtin(globals()["impl_standard_comparison_%s" % (ext, )], prolog,

Modified: pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/arithmetic.py	Sun Apr 22 21:12:52 2007
@@ -32,7 +32,7 @@
 wrap_builtin_operation._annspecialcase_ = 'specialize:memo'
 
 def eval_arithmetic(engine, query):
-    query = query.getvalue(engine.frame)
+    query = query.getvalue(engine.heap)
     if isinstance(query, term.Number):
         return query
     if isinstance(query, term.Float):

Modified: pypy/dist/pypy/lang/prolog/interpreter/choice.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/choice.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/choice.py	Sun Apr 22 21:12:52 2007
@@ -3,15 +3,15 @@
 
 from py.magic import greenlet
 from pypy.rlib.objectmodel import we_are_translated
-from pypy.rpython.rstack import yield_current_frame_to_caller
+from pypy.rpython.rstack import yield_current_heap_to_caller
 from pypy.translator.c.test.test_stackless import StacklessTest
 
 from pypy.lang.prolog.interpreter.error import UnificationFailed, CutException
 
-def make_llframe(choice_point, func, args):
-    llframe = yield_current_frame_to_caller()
+def make_llheap(choice_point, func, args):
+    llheap = yield_current_heap_to_caller()
     try:
-        choice_point.current = llframe
+        choice_point.current = llheap
         try:
             func(*args)
         except UnificationFailed:
@@ -22,14 +22,14 @@
     except:
         pass
     os.write(0, "bad\n")
-    return llframe # will nexer be executed, help the translator
-make_llframe._annspecialcase_ = "specialize:arg(1)"
+    return llheap # will nexer be executed, help the translator
+make_llheap._annspecialcase_ = "specialize:arg(1)"
 
 class ChoicePoint(object):
     def __init__(self, engine, continuation, stop_cut=False):
         self._init_current()
         self.engine = engine
-        self.oldstate = engine.frame.branch()
+        self.oldstate = engine.heap.branch()
         self.continuation = continuation
         self.stop_cut = stop_cut
         self.any_choice = True
@@ -50,7 +50,7 @@
             else:
                 self.exception = e
         except UnificationFailed:
-            self.engine.frame.revert(self.oldstate)
+            self.engine.heap.revert(self.oldstate)
             if last:
                 raise
             return
@@ -65,8 +65,8 @@
 
     def switch(self, func, *args):
         if we_are_translated():
-            llframe = make_llframe(self, func, args)
-            llframe.switch()
+            llheap = make_llheap(self, func, args)
+            llheap.switch()
         else:
             g = greenlet(func)
             try:

Modified: pypy/dist/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/engine.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/engine.py	Sun Apr 22 21:12:52 2007
@@ -24,7 +24,7 @@
 START_NUMBER_OF_VARS = 4096
 
 
-class Frame(object):
+class Heap(object):
     def __init__(self):
         self.vars = [None] * START_NUMBER_OF_VARS
         self.trail = []
@@ -141,7 +141,7 @@
 
 class Engine(object):
     def __init__(self):
-        self.frame = Frame()
+        self.heap = Heap()
         self.signature2function = {}
         self.parser = None
         self.operations = None
@@ -175,7 +175,7 @@
         if not isinstance(query, Callable):
             error.throw_type_error("callable", query)
         vars = query.get_max_var() + 1
-        self.frame.clear(vars)
+        self.heap.clear(vars)
         try:
             return self.call(query, continuation)
         except CutException, e:
@@ -215,27 +215,27 @@
         if function is None:
             error.throw_existence_error(
                 "procedure", query.get_prolog_signature())
-        unify_hash = query.get_deeper_unify_hash(self.frame)
+        unify_hash = query.get_deeper_unify_hash(self.heap)
         rulechain = function.rulechain.find_applicable_rule(query, unify_hash)
         if rulechain is None:
             # none of the rules apply
             raise UnificationFailed()
         rule = rulechain.rule
         rulechain = rulechain.next
-        oldstate = self.frame.branch()
+        oldstate = self.heap.branch()
         while rulechain:
             rulechain = rulechain.find_applicable_rule(query, unify_hash)
             if rulechain is None:
-                self.frame.discard(oldstate)
+                self.heap.discard(oldstate)
                 break
             if rule.contains_cut:
                 continuation = LimitedScopeContinuation(continuation)
                 try:
                     result = self.try_rule(rule, query, continuation)
-                    self.frame.discard(oldstate)
+                    self.heap.discard(oldstate)
                     return result
                 except UnificationFailed:
-                    self.frame.revert(oldstate)
+                    self.heap.revert(oldstate)
                 except CutException, e:
                     if continuation.scope_active:
                         return self.continue_after_cut(e.continuation,
@@ -244,10 +244,10 @@
             else:
                 try:
                     result = self.try_rule(rule, query, continuation)
-                    self.frame.discard(oldstate)
+                    self.heap.discard(oldstate)
                     return result
                 except UnificationFailed:
-                    self.frame.revert(oldstate)
+                    self.heap.revert(oldstate)
             rule = rulechain.rule
             rulechain = rulechain.next
         if rule.contains_cut:
@@ -262,16 +262,11 @@
 
     def try_rule(self, rule, query, continuation=DONOTHING):
         if DEBUG:
-            debug_print("trying rule", rule, query, self.frame.vars[:self.frame.needed_vars])
-        try:
-            # standardizing apart
-            nextcall = rule.clone_and_unify_head(self.frame, query)
-        except UnificationFailed:
-            if DEBUG:
-                debug_print("didn't work", rule, query, self.frame.vars[:self.frame.needed_vars])
-            raise
+            debug_print("trying rule", rule, query, self.heap.vars[:self.heap.needed_vars])
+        # standardizing apart
+        nextcall = rule.clone_and_unify_head(self.heap, query)
         if DEBUG:
-            debug_print("worked", rule, query, self.frame.vars[:self.frame.needed_vars])
+            debug_print("worked", rule, query, self.heap.vars[:self.heap.needed_vars])
         if nextcall is not None:
             return self.call(nextcall, continuation)
         return continuation.call(self)

Modified: pypy/dist/pypy/lang/prolog/interpreter/interactive.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/interactive.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/interactive.py	Sun Apr 22 21:12:52 2007
@@ -59,11 +59,11 @@
     f = TermFormatter(engine, quoted=True, max_depth=10)
     vars = var_to_pos.items()
     vars.sort()
-    frame = engine.frame
+    heap = engine.heap
     for var, real_var in vars:
         if var.startswith("_"):
             continue
-        val = real_var.getvalue(frame)
+        val = real_var.getvalue(heap)
         write("%s = %s\n" % (var, f.format(val)))
 
 class PrologConsole(code.InteractiveConsole):

Modified: pypy/dist/pypy/lang/prolog/interpreter/parsing.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/parsing.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/parsing.py	Sun Apr 22 21:12:52 2007
@@ -349,7 +349,7 @@
             name = unescape(node.additional_info[1:end])
         else:
             name = node.additional_info
-        return Atom.make_atom(name)
+        return Atom.newatom(name)
 
     def visit_VAR(self, node):
         from pypy.lang.prolog.interpreter.term import Var
@@ -399,7 +399,7 @@
         node = node.children[1]
         if len(node.children) == 1:
             l = self.build_list(node)
-            start = Atom.make_atom("[]")
+            start = Atom.newatom("[]")
         else:
             l = self.build_list(node.children[0])
             start = self.visit(node.children[2])

Modified: pypy/dist/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/term.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/term.py	Sun Apr 22 21:12:52 2007
@@ -2,6 +2,7 @@
 from pypy.rlib.objectmodel import we_are_translated, UnboxedValue
 from pypy.rlib.rarithmetic import intmask
 from pypy.lang.prolog.interpreter.error import UnificationFailed, UncatchableError
+from pypy.rlib.objectmodel import hint, specialize
 
 DEBUG = True
 
@@ -19,57 +20,54 @@
 
 class PrologObject(object):
     __slots__ = ()
-    def getvalue(self, frame):
+    def getvalue(self, heap):
         return self
 
-    def dereference(self, frame):
-        return self
+    def dereference(self, heap):
+        raise NotImplementedError("abstract base class")
 
     def get_max_var(self):
         return -1
 
-    def clone(self, offset):
-        return self
-
-    def clone_compress_vars(self, vars_new_indexes, offset):
-        return self
+    def copy(self, heap, memo):
+        raise NotImplementedError("abstract base class")
 
-    def make_template(self, vars_new_indexes):
-        return self
+    def copy_and_unify(self, other, heap, memo):
+        raise NotImplementedError("abstract base class")
 
-    def instantiate_template(self, template_frame):
+    def clone_compress_vars(self, vars_new_indexes, offset):
         return self
 
-    def get_unify_hash(self, frame=None):
+    def get_unify_hash(self, heap=None):
         # if two non-var objects return two different numbers
         # they must not be unifiable
         raise NotImplementedError("abstract base class")
 
-    def get_deeper_unify_hash(self, frame=None):
-        return [self.get_unify_hash(frame)]
-
-    def basic_unify(self, other, frame):
-        pass
+    def get_deeper_unify_hash(self, heap=None):
+        return [self.get_unify_hash(heap)]
 
-    def unify(self, other, frame, occurs_check=False):
-        pass
-    unify._annspecialcase_ = "specialize:arg(3)"
+    @specialize.arg(3)
+    def unify(self, other, heap, occurs_check=False):
+        raise NotImplementedError("abstract base class")
 
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
+    @specialize.arg(3)
+    def _unify(self, other, heap, occurs_check=False):
         raise NotImplementedError("abstract base class")
 
-    def contains_var(self, var, frame):
+    def contains_var(self, var, heap):
         return False
 
     def __eq__(self, other):
         # for testing
-        return self.__dict__ == other.__dict__
+        return (self.__class__ == other.__class__ and
+                self.__dict__ == other.__dict__)
 
     def __ne__(self, other):
+        # for testing
         return not (self == other)
 
 
-class Var(PrologObject):#, UnboxedValue):
+class Var(PrologObject):
     TAG = 0
     STANDARD_ORDER = 0
 
@@ -78,75 +76,59 @@
     def __init__(self, index):
         self.index = index
 
-    def unify(self, other, frame, occurs_check=False):
-        #debug_print("unify", self, other, frame.vars)
-        self, val = self.get_last_var_in_chain_and_val(frame)
-        if val is not None:
-            other.unify(val, frame, occurs_check)
-        elif isinstance(other, Var):
-            other, val = other.get_last_var_in_chain_and_val(frame)
-            if val is None:
-                if other.index != self.index:
-                    frame.setvar(self.index, other)
-            else:
-                self.unify(val, frame, occurs_check)
-        else:
-            if occurs_check and other.contains_var(self, frame):
-                raise UnificationFailed()
-            frame.setvar(self.index, other)
-    unify._annspecialcase_ = "specialize:arg(3)"
-
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        self, val = self.get_last_var_in_chain_and_val(frame)
-        if val is not None:
-            return val.unify_with_template(other, frame, template_frame,
-                                           to_instantiate)
-        if isinstance(other, Var):
-            other, otherval = other.get_last_var_in_chain_and_val(frame)
-            if otherval is None:
-                if other.index != self.index:
-                    return frame.setvar(self.index, other)
-            else:
-                return self.unify_with_template(otherval, frame,
-                                                template_frame, to_instantiate)
-        else:
-            if isinstance(other, TemplateVar):
-                return other.unify_with_template(self, frame, template_frame,
-                                                 to_instantiate)
-            if isinstance(other, Term):
-                to_instantiate.append((self.index, other))
-            frame.setvar(self.index, other)
-
-    def getvalue(self, frame):
-        var, res = self.get_last_var_in_chain_and_val(frame)
-        if res is not None:
-            return res.getvalue(frame)
-        return var
-
-    def dereference(self, frame):
-        var, res = self.get_last_var_in_chain_and_val(frame)
-        if res is not None:
-            return res
-        return var
-
-    def get_last_var_in_chain_and_val(self, frame):
-        next = frame.getvar(self.index)
-        if next is None or not isinstance(next, Var):
-            return self, next
-        # do path compression
-        last, val = next.get_last_var_in_chain_and_val(frame)
-        if val is None:
-            frame.setvar(self.index, last)
+    @specialize.arg(3)
+    def unify(self, other, heap, occurs_check=False):
+        return self.dereference(heap)._unify(other, heap, occurs_check)
+
+    @specialize.arg(3)
+    def _unify(self, other, heap, occurs_check=False):
+        other = other.dereference(heap)
+        if isinstance(other, Var) and other is self:
+            pass
+        elif occurs_check and other.contains_var(self, heap):
+            raise UnificationFailed()
+        else:
+            heap.setvar(self.index, other)
+
+    def dereference(self, heap):
+        next = heap.getvar(self.index)
+        if next is None:
+            return self
         else:
-            frame.setvar(self.index, val)
-        return last, val
+            result = next.dereference(heap)
+            # do path compression
+            heap.setvar(self.index, result)
+            return result
+
+    def getvalue(self, heap):
+        res = self.dereference(heap)
+        if not isinstance(res, Var):
+            return res.getvalue(heap)
+        return res
+
+    def copy(self, heap, memo):
+        hint(self, concrete=True)
+        try:
+            return memo[self.index]
+        except KeyError:
+            newvar = memo[self.index] = heap.newvar()
+            return newvar
+
+    def copy_and_unify(self, other, heap, memo):
+        hint(self, concrete=True)
+        try:
+            seen_value = memo[self.index]
+        except KeyError:
+            memo[self.index] = other
+            return other
+        else:
+            seen_value.unify(other, heap)
+            return seen_value
+
 
     def get_max_var(self):
         return self.index
 
-    def clone(self, offset):
-        return Var(self.index + offset)
-
     def clone_compress_vars(self, vars_new_indexes, offset):
         if self.index in vars_new_indexes:
             return Var(vars_new_indexes[self.index])
@@ -154,98 +136,74 @@
         vars_new_indexes[self.index] = index
         return Var(index)
     
-    def make_template(self, vars_new_indexes):
-        if self.index in vars_new_indexes:
-            return TemplateVar.make_templatevar(vars_new_indexes[self.index])
-        index = len(vars_new_indexes)
-        vars_new_indexes[self.index] = index
-        return TemplateVar.make_templatevar(index)
-
-    def get_unify_hash(self, frame=None):
-        if frame is None:
+    def get_unify_hash(self, heap=None):
+        if heap is None:
             return 0
-        self = self.dereference(frame)
+        self = self.dereference(heap)
         if isinstance(self, Var):
             return 0
-        return self.get_unify_hash(frame)
+        return self.get_unify_hash(heap)
 
-    def contains_var(self, var, frame):
-        self = self.dereference(frame)
+    def contains_var(self, var, heap):
+        self = self.dereference(heap)
         if self is var:
             return True
         if not isinstance(self, Var):
-            return self.contains_var(var, frame)
+            return self.contains_var(var, heap)
         return False
 
     def __repr__(self):
         return "Var(%s)" % (self.index, )
 
 
-class TemplateVar(PrologObject):
-    TAG = 0
-    STANDARD_ORDER = 0
-    __slots__ = 'index'
-    cache = []
-
-    def __init__(self, index):
-        self.index = index
-
-    def unify(self, other, frame, occurs_check=False):
-        raise UncatchableError("TemplateVar in wrong place")
-
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        val = template_frame[self.index]
-        if val is None:
-            template_frame[self.index] = other
-        else:
-            val.unify_with_template(other, frame, template_frame, to_instantiate)
-
-    def getvalue(self, frame):
-        raise UncatchableError("TemplateVar in wrong place")
-
-    def dereference(self, frame):
-        raise UncatchableError("TemplateVar in wrong place")
-
-    def get_max_var(self):
-        return self.index
+    def __eq__(self, other):
+        # for testing
+        return (self.__class__ == other.__class__ and
+                self.index == other.index)
 
-    def clone(self, offset):
-        return TemplateVar.make_template(self.index + offset)
+class NonVar(PrologObject):
 
-    def clone_compress_vars(self, vars_new_indexes, offset):
-        raise UncatchableError("TemplateVar in wrong place")
+    def dereference(self, heap):
+        return self
 
-    def make_template(self, vars_new_indexes):
-        raise UncatchableError("TemplateVar in wrong place")
+    @specialize.arg(3)
+    def unify(self, other, heap, occurs_check=False):
+        return self._unify(other, heap, occurs_check)
 
-    def instantiate_template(self, template_frame):
-        return template_frame[self.index]
 
-    def get_unify_hash(self, frame=None):
-        return 0
+    @specialize.arg(3)
+    def basic_unify(self, other, heap, occurs_check=False):
+        raise NotImplementedError("abstract base class")
 
-    def contains_var(self, var, frame):
-        raise UncatchableError("TemplateVar in wrong place")
+    @specialize.arg(3)
+    def _unify(self, other, heap, occurs_check=False):
+        other = other.dereference(heap)
+        if isinstance(other, Var):
+            other._unify(self, heap, occurs_check)
+        else:
+            self.basic_unify(other, heap, occurs_check)
 
-    def __repr__(self):
-        return "TemplateVar(%s)" % (self.index, )
+    def copy_and_unify(self, other, heap, memo):
+        other = other.dereference(heap)
+        if isinstance(other, Var):
+            copy = self.copy(heap, memo)
+            other._unify(copy, heap)
+            return copy
+        else:
+            return self.copy_and_basic_unify(other, heap, memo)
 
-    def make_templatevar(index):
-        l = len(TemplateVar.cache)
-        if index >= l:
-            TemplateVar.cache.extend(
-                [TemplateVar(i) for i in range(l, l + index + 1)])
-        return TemplateVar.cache[index]
-    make_templatevar = staticmethod(make_templatevar)
+    def copy_and_basic_unify(self, other, heap, memo):
+        raise NotImplementedError("abstract base class")
 
 
-class Callable(PrologObject):
+class Callable(NonVar):
     name = ""
     signature = ""
 
     def get_prolog_signature(self):
         raise NotImplementedError("abstract base")
 
+
 class Atom(Callable):
     TAG = tag()
     STANDARD_ORDER = 1
@@ -262,66 +220,60 @@
     def __repr__(self):
         return "Atom(%r)" % (self.name,)
 
-    def basic_unify(self, other, frame):
-        if isinstance(other, Atom):
-            if self is other or other.name == self.name:
-                return
+    @specialize.arg(3)
+    def basic_unify(self, other, heap, occurs_check=False):
+        if isinstance(other, Atom) and (self is other or
+                                        other.name == self.name):
+            return
         raise UnificationFailed
 
-    def unify(self, other, frame, occurs_check=False):
-        #debug_print("unify", self, other, type(other))
-        if isinstance(other, Var):
-            return other.unify(self, frame, occurs_check)
-        return self.basic_unify(other, frame)
-    unify._annspecialcase_ = "specialize:arg(3)"
+    def copy(self, heap, memo):
+        return self
 
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        if isinstance(other, Var):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, TemplateVar):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        return self.basic_unify(other, frame)
+    def copy_and_basic_unify(self, other, heap, memo):
+        hint(self, concrete=True)
+        if isinstance(other, Atom) and (self is other or
+                                        other.name == self.name):
+            return self
+        else:
+            raise UnificationFailed
 
-    def get_unify_hash(self, frame=None):
+    def get_unify_hash(self, heap=None):
         return intmask(hash(self.name) << TAGBITS | self.TAG)
 
     def get_prolog_signature(self):
         return Term("/", [self, Number(0)])
 
-    def make_atom(name):
+    def newatom(name):
         result = Atom.cache.get(name, None)
         if result is not None:
             return result
         Atom.cache[name] = result = Atom(name)
         return result
-    make_atom = staticmethod(make_atom)
+    newatom = staticmethod(newatom)
+
 
-class Number(PrologObject):
+class Number(NonVar):
     TAG = tag()
     STANDARD_ORDER = 2
     def __init__(self, num):
         self.num = num
 
-    def basic_unify(self, other, frame):
-        if isinstance(other, Number):
-            if other.num != self.num:
-                raise UnificationFailed
+    @specialize.arg(3)
+    def basic_unify(self, other, heap, occurs_check=False):
+        if isinstance(other, Number) and other.num == self.num:
             return
         raise UnificationFailed
 
-    def unify(self, other, frame, occurs_check=False):
-        #debug_print("unify", self, other, type(other))
-        if isinstance(other, Var):
-            return other.unify(self, frame, occurs_check)
-        return self.basic_unify(other, frame)
-    unify._annspecialcase_ = "specialize:arg(3)"
+    def copy(self, heap, memo):
+        return self
 
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        if isinstance(other, Var):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, TemplateVar):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        return self.basic_unify(other, frame)
+    def copy_and_basic_unify(self, other, heap, memo):
+        hint(self, concrete=True)
+        if isinstance(other, Number) and other.num == self.num:
+            return self
+        else:
+            raise UnificationFailed
 
     def __str__(self):
         return repr(self.num)
@@ -329,44 +281,33 @@
     def __repr__(self):
         return "Number(%r)" % (self.num, )
 
-    def get_unify_hash(self, frame=None):
+    def get_unify_hash(self, heap=None):
         return intmask(self.num << TAGBITS | self.TAG)
 
 
-class Float(PrologObject):
+class Float(NonVar):
     TAG = tag()
     STANDARD_ORDER = 2
     def __init__(self, num):
         self.num = num
 
-    def basic_unify(self, other, frame):
-        if isinstance(other, Float):
-            if other.num != self.num:
-                raise UnificationFailed
-            return
-        raise UnificationFailed
-
-    def basic_unify(self, other, frame):
-        if isinstance(other, Float):
-            if other.num != self.num:
-                raise UnificationFailed
+    @specialize.arg(3)
+    def basic_unify(self, other, heap, occurs_check=False):
+        if isinstance(other, Float) and other.num == self.num:
             return
         raise UnificationFailed
 
-    def unify(self, other, frame, occurs_check=False):
-        if isinstance(other, Var):
-            return other.unify(self, frame, occurs_check)
-        return self.basic_unify(other, frame)
-    unify._annspecialcase_ = "specialize:arg(3)"
+    def copy(self, heap, memo):
+        return self
 
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        if isinstance(other, Var):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        elif isinstance(other, TemplateVar):
-            return other.unify_with_template(self, frame, template_frame, to_instantiate)
-        return self.basic_unify(other, frame)
+    def copy_and_basic_unify(self, other, heap, memo):
+        hint(self, concrete=True)
+        if isinstance(other, Float) and other.num == self.num:
+            return self
+        else:
+            raise UnificationFailed
 
-    def get_unify_hash(self, frame=None):
+    def get_unify_hash(self, heap=None):
         #XXX no clue whether this is a good idea...
         m, e = math.frexp(self.num)
         m = intmask(int(m / 2 * 2 ** (32 - TAGBITS)))
@@ -387,14 +328,8 @@
 def _clone_compress_vars(obj, vars_new_indexes, offset):
     return obj.clone_compress_vars(vars_new_indexes, offset)
 
-def _make_template(obj, vars_new_indexes):
-    return obj.make_template(vars_new_indexes)
-
-def _instantiate_template(obj, template_frame):
-    return obj.instantiate_template(template_frame)
-
-def _getvalue(obj, frame):
-    return obj.getvalue(frame)
+def _getvalue(obj, heap):
+    return obj.getvalue(heap)
 
 class Term(Callable):
     TAG = tag()
@@ -413,31 +348,44 @@
     def __str__(self):
         return "%s(%s)" % (self.name, ", ".join([str(a) for a in self.args]))
 
-    def unify(self, other, frame, occurs_check=False):
-        if not isinstance(other, Term):
-            if isinstance(other, Var):
-                return other.unify(self, frame, occurs_check)
-            raise UnificationFailed
-        if (hash(self.name) != hash(other.name) or 
-            self.name != other.name or len(self.args) != len(other.args)):
+    @specialize.arg(3)
+    def basic_unify(self, other, heap, occurs_check=False):
+        if (isinstance(other, Term) and
+            self.name == other.name and
+            len(self.args) == len(other.args)):
+            for i in range(len(self.args)):
+                self.args[i].unify(other.args[i], heap, occurs_check)
+        else:
             raise UnificationFailed
-        for i in range(len(self.args)):
-            self.args[i].unify(other.args[i], frame, occurs_check)
-    unify._annspecialcase_ = "specialize:arg(3)"
 
-    def unify_with_template(self, other, frame, template_frame, to_instantiate):
-        if not isinstance(other, Term):
-            if isinstance(other, Var):
-                return other.unify_with_template(self, frame, template_frame, to_instantiate)
-            if isinstance(other, TemplateVar):
-                return other.unify_with_template(self, frame, template_frame, to_instantiate)
-            raise UnificationFailed
-        if (hash(self.name) != hash(other.name) or 
-            self.name != other.name or len(self.args) != len(other.args)):
+    def copy(self, heap, memo):
+        hint(self, concrete=True)
+        self = hint(self, deepfreeze=True)
+        newargs = []
+        i = 0
+        while i < len(self.args):
+            hint(i, concrete=True)
+            arg = self.args[i].copy(heap, memo)
+            newargs.append(arg)
+            i += 1
+        return Term(self.name, newargs)
+
+    def copy_and_basic_unify(self, other, heap, memo):
+        hint(self, concrete=True)
+        self = hint(self, deepfreeze=True)
+        if (isinstance(other, Term) and
+            self.name == other.name and
+            len(self.args) == len(other.args)):
+            newargs = [None] * len(self.args)
+            i = 0
+            while i < len(self.args):
+                hint(i, concrete=True)
+                arg = self.args[i].copy_and_unify(other.args[i], heap, memo)
+                newargs[i] = arg
+                i += 1
+            return Term(self.name, newargs)
+        else:
             raise UnificationFailed
-        for i in range(len(self.args)):
-            self.args[i].unify_with_template(other.args[i], frame,
-                                             template_frame, to_instantiate)
 
     def get_max_var(self):
         result = -1
@@ -445,20 +393,11 @@
             result = max(result, subterm.get_max_var())
         return result
     
-    def clone(self, offset):
-        return self._copy_term(_clone, offset)
-
     def clone_compress_vars(self, vars_new_indexes, offset):
         return self._copy_term(_clone_compress_vars, vars_new_indexes, offset)
 
-    def make_template(self, vars_new_indexes):
-        return self._copy_term(_make_template, vars_new_indexes)
-
-    def instantiate_template(self, template_frame):
-        return self._copy_term(_instantiate_template, template_frame)
-
-    def getvalue(self, frame):
-        return self._copy_term(_getvalue, frame)
+    def getvalue(self, heap):
+        return self._copy_term(_getvalue, heap)
 
     def _copy_term(self, copy_individual, *extraargs):
         args = [None] * len(self.args)
@@ -473,23 +412,22 @@
             return Term(self.name, args, self.signature)
         else:
             return self
-    _copy_term._annspecialcase_ = "specialize:arg(1)"
 
-    def get_unify_hash(self, frame=None):
+    def get_unify_hash(self, heap=None):
         return intmask(hash(self.signature) << TAGBITS | self.TAG)
 
-    def get_deeper_unify_hash(self, frame=None):
+    def get_deeper_unify_hash(self, heap=None):
         result = [0] * len(self.args)
         for i in range(len(self.args)):
-            result[i] = self.args[i].get_unify_hash(frame)
+            result[i] = self.args[i].get_unify_hash(heap)
         return result
 
     def get_prolog_signature(self):
-        return Term("/", [Atom.make_atom(self.name), Number(len(self.args))])
+        return Term("/", [Atom.newatom(self.name), Number(len(self.args))])
     
-    def contains_var(self, var, frame):
+    def contains_var(self, var, heap):
         for arg in self.args:
-            if arg.contains_var(var, frame):
+            if arg.contains_var(var, heap):
                 return True
         return False
         
@@ -498,12 +436,12 @@
     def __init__(self, head, body):
         from pypy.lang.prolog.interpreter import helper
         d = {}
-        head = head.make_template(d)
+        head = head.clone_compress_vars(d, 0)
         assert isinstance(head, Callable)
         self.head = head
         if body is not None:
             body = helper.ensure_callable(body)
-            self.body = body.make_template(d)
+            self.body = body.clone_compress_vars(d, 0)
         else:
             self.body = None
         self.numvars = len(d)
@@ -526,41 +464,19 @@
                 stack.extend(current.args)
         self.contains_cut = False
 
-    def clone(self, offset):
-        if self.body is None:
-            body = None
-        else:
-            body = self.body.clone(offset)
-        return Rule(self.head.clone(offset), body)
-
-    def clone_and_unify_head(self, frame, head):
-        template_frame = [None] * self.numvars
+    def clone_and_unify_head(self, heap, head):
+        memo = {}
         if isinstance(head, Term):
-            to_instantiate = []
             h2 = self.head
             assert isinstance(h2, Term)
             for i in range(len(h2.args)):
                 arg1 = h2.args[i]
                 arg2 = head.args[i]
-                if (isinstance(arg1, Term) or
-                    isinstance(arg1, TemplateVar)):
-                    h2.args[i].unify_with_template(
-                        head.args[i], frame, template_frame, to_instantiate)
-                else:
-                    h2.args[i].unify(head.args[i], frame)
-            extend_and_normalize_template_frame(template_frame, frame)
-            for index, obj in to_instantiate:
-                frame.vars[index] = obj.instantiate_template(template_frame)
-        else:
-            next_free = frame.maxvar()
-            for i in range(self.numvars):
-                template_frame[i] = Var(next_free)
-                next_free += 1
-            frame.extend(next_free - frame.maxvar())
+                arg1.copy_and_unify(arg2, heap, memo)
         body = self.body
         if body is None:
             return None
-        return body.instantiate_template(template_frame)
+        return body.copy(heap, memo)
 
     def __repr__(self):
         if self.body is None:
@@ -568,26 +484,15 @@
         return "%s :- %s." % (self.head, self.body)
 
 
-def extend_and_normalize_template_frame(template_frame, frame):
-    next_free = frame.maxvar()
-    for i in range(len(template_frame)):
-        val = template_frame[i]
-        if val is None:
-            template_frame[i] = Var(next_free)
-            next_free += 1
-        elif isinstance(val, TemplateVar):
-            template_frame[i] = template_frame[val.index]
-    frame.extend(next_free - frame.maxvar())
-
+ at specialize.argtype(0)
 def rcmp(a, b): # RPython does not support cmp...
     if a == b:
         return 0
     if a < b:
         return -1
     return 1
-rcmp._annspecialcase_ = "specialize:argtype(0)"
 
-def cmp_standard_order(obj1, obj2, frame):
+def cmp_standard_order(obj1, obj2, heap):
     c = rcmp(obj1.STANDARD_ORDER, obj2.STANDARD_ORDER)
     if c != 0:
         return c
@@ -606,9 +511,9 @@
         if c != 0:
             return c
         for i in range(len(obj1.args)):
-            a1 = obj1.args[i].dereference(frame)
-            a2 = obj2.args[i].dereference(frame)
-            c = cmp_standard_order(a1, a2, frame)
+            a1 = obj1.args[i].dereference(heap)
+            a2 = obj2.args[i].dereference(heap)
+            c = cmp_standard_order(a1, a2, heap)
             if c != 0:
                 return c
         return 0

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/dont_test_translate.py	Sun Apr 22 21:12:52 2007
@@ -39,7 +39,7 @@
     def run():
         e.run(t1)
         e.run(t2)
-        v0 = e.frame.getvar(0)
+        v0 = e.heap.getvar(0)
         if isinstance(v0, Atom):
             return v0.name
         return "no!"

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_arithmetic.py	Sun Apr 22 21:12:52 2007
@@ -2,7 +2,7 @@
 from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder
 from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine
 from pypy.lang.prolog.interpreter.error import UnificationFailed, CutException
-from pypy.lang.prolog.interpreter.engine import Frame, Engine
+from pypy.lang.prolog.interpreter.engine import Heap, Engine
 from pypy.lang.prolog.interpreter import error
 from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_false, assert_true
 

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_builtin.py	Sun Apr 22 21:12:52 2007
@@ -2,7 +2,7 @@
 from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder
 from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine
 from pypy.lang.prolog.interpreter.error import UnificationFailed
-from pypy.lang.prolog.interpreter.engine import Frame, Engine
+from pypy.lang.prolog.interpreter.engine import Heap, Engine
 from pypy.lang.prolog.interpreter import error
 from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_false, assert_true
 from pypy.lang.prolog.interpreter.test.tool import prolog_raises
@@ -13,8 +13,8 @@
         f(X) :- g(X), fail.
         f(a).
     """)
-    frames = collect_all(e, "f(X).")
-    assert len(frames) == 1
+    heaps = collect_all(e, "f(X).")
+    assert len(heaps) == 1
 
 def test_not():
     e = get_engine("""
@@ -36,8 +36,8 @@
     assert_false("\\+(g(a, a)).", e)
     assert_false("not(!).", e)
 
-    frames = collect_all(e, "sibling(a, X).")
-    assert len(frames) == 2
+    heaps = collect_all(e, "sibling(a, X).")
+    assert len(heaps) == 2
 
 def test_and():
     assert_false("fail, X.")
@@ -118,8 +118,8 @@
         g(c) :- assertz(g(d)).
         g(b).
     """)
-    frames = collect_all(e, "g(X).")
-    assert len(frames) == 3
+    heaps = collect_all(e, "g(X).")
+    assert len(heaps) == 3
     e = get_engine("""
         p :- assertz(p), fail.
         p :- fail.
@@ -155,6 +155,7 @@
     assert_false("X \\= Y.")
     assert_false("X \\= f(X).")
     assert_true("x \\= y.")
+    assert_true("f(X, b) \\= f(a, c), X = c.")
     assert_true("unify_with_occurs_check(X, Y).")
     assert_true("unify_with_occurs_check(X, X).")
     assert_false("unify_with_occurs_check(X, f(X)).")
@@ -177,8 +178,8 @@
         withcut(X) :- call(!), fail.
         withcut(a).
         """)
-    frames = collect_all(e, "g(X).")
-    assert len(frames) == 2
+    heaps = collect_all(e, "g(X).")
+    assert len(heaps) == 2
     assert_true("withcut(a).", e)
     assert_true("call((!, true)).")
 
@@ -212,8 +213,8 @@
         f(2, b).
         f(3, c).
     """)
-    frames = collect_all(e, "arg(X, g(a, b, c), A), f(X, A).")
-    assert len(frames) == 3
+    heaps = collect_all(e, "arg(X, g(a, b, c), A), f(X, A).")
+    assert len(heaps) == 3
     assert_true("arg(X, h(a, b, c), b), X = 2.")
     assert_true("arg(X, h(a, b, g(X, b)), g(3, B)), X = 3, B = b.")
     assert_true("copy_term(X, Y), X = 1, Y = 2.")
@@ -278,9 +279,9 @@
     assert_true("between(-5, 15, 0).")
     assert_false("between(12, 15, 6).")
     assert_false("between(12, 15, 16).")
-    frames = collect_all(Engine(), "between(1, 4, X).")
-    assert len(frames) == 4
-    assert frames[0].vars[0].num == 1
+    heaps = collect_all(Engine(), "between(1, 4, X).")
+    assert len(heaps) == 4
+    assert heaps[0].vars[0].num == 1
 
 def test_is():
     assert_true("5 is 1 + 1 + 1 + 1 + 1.")
@@ -333,10 +334,10 @@
     assert_true("atom_concat(ab, X, abcdef), X = cdef.")
     assert_true("atom_concat(X, cdef, abcdef), X = ab.")
     assert_true("atom_concat(1, Y, '1def'), Y = def.")
-    frames = collect_all(
+    heaps = collect_all(
         Engine(),
         "atom_concat(X, Y, abcd), atom(X), atom(Y).")
-    assert len(frames) == 5
+    assert len(heaps) == 5
 
 def test_sub_atom():
     assert_true("sub_atom(abc, B, L, A, bc), B=1, L=2, A=0.")

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_engine.py	Sun Apr 22 21:12:52 2007
@@ -5,6 +5,13 @@
 from pypy.lang.prolog.interpreter.test.tool import collect_all, assert_true, assert_false
 from pypy.lang.prolog.interpreter.test.tool import prolog_raises
 
+def test_trivial():
+    e = get_engine("""
+        f(a).
+    """)
+    e.run(parse_query_term("f(X)."))
+    assert e.heap.getvar(0).name == "a"
+
 def test_and():
     e = get_engine("""
         g(a, a).
@@ -14,8 +21,8 @@
     """)
     e.run(parse_query_term("f(a, c)."))
     e.run(parse_query_term("f(X, c)."))
-    print e.frame.vars
-    assert e.frame.getvar(0).name == "a"
+    print e.heap.vars[:10]
+    assert e.heap.getvar(0).name == "a"
 
 def test_and_long():
     e = get_engine("""
@@ -24,8 +31,8 @@
         h(d). h(e). h(f).
         f(X, Y, Z) :- f(X), g(Y), h(Z).
     """)
-    frames = collect_all(e, "f(X, Y, Z).")
-    assert len(frames) == 27  
+    heaps = collect_all(e, "f(X, Y, Z).")
+    assert len(heaps) == 27  
 
 def test_numeral():
     e = get_engine("""
@@ -46,7 +53,7 @@
     e.run(parse_query_term("num(0)."))
     e.run(parse_query_term("num(succ(0))."))
     e.run(parse_query_term("num(X)."))
-    assert e.frame.getvar(0).num == 0
+    assert e.heap.getvar(0).num == 0
     e.run(parse_query_term("add(0, 0, 0)."))
     py.test.raises(UnificationFailed, e.run, parse_query_term("""
         add(0, 0, succ(0))."""))
@@ -82,7 +89,7 @@
         f(X, Y, Z) :- (g(X, Z); g(X, Z); g(Z, Y)), a(Z).
         """)
     e.run(parse_query_term("f(a, b, Z)."))
-    assert e.frame.getvar(0).name == "a"
+    assert e.heap.getvar(0).name == "a"
     f = collect_all(e, "X = 1; X = 2.")
     assert len(f) == 2
 
@@ -118,11 +125,11 @@
         g(b).
         g(c).
     """)
-    frames = collect_all(e, "g(X).")
-    assert len(frames) == 3
-    assert frames[0].getvar(0).name == "a"
-    assert frames[1].getvar(0).name == "b"
-    assert frames[2].getvar(0).name == "c"
+    heaps = collect_all(e, "g(X).")
+    assert len(heaps) == 3
+    assert heaps[0].getvar(0).name == "a"
+    assert heaps[1].getvar(0).name == "b"
+    assert heaps[2].getvar(0).name == "c"
 
 def test_cut():
     e = get_engine("""
@@ -134,8 +141,8 @@
         f(x).
         f(y).
     """)
-    frames = collect_all(e, "f(X).")
-    assert len(frames) == 0
+    heaps = collect_all(e, "f(X).")
+    assert len(heaps) == 0
     assert_true("!.")
 
 def test_cut2():
@@ -146,8 +153,8 @@
         h(a, y).
         f(X, Y) :- g(X), !, !, !, !, !, h(X, Y).
     """)
-    frames = collect_all(e, "f(X, Y).")
-    assert len(frames) == 2
+    heaps = collect_all(e, "f(X, Y).")
+    assert len(heaps) == 2
 
 def test_cut3():
     e = get_engine("""
@@ -171,8 +178,8 @@
         g(X) :- f(X), !.
         g(a).
     """)
-    frames = collect_all(e, "g(X).")
-    assert len(frames) == 1
+    heaps = collect_all(e, "g(X).")
+    assert len(heaps) == 1
 
 def test_not_with_cut():
     e = get_engine("""
@@ -227,8 +234,8 @@
 
         sibling(X, Y) :- mother(Z, X), mother(Z, Y).
     """)
-    frames = collect_all(e, "sibling(m, X).")
-    assert len(frames) == 3
+    heaps = collect_all(e, "sibling(m, X).")
+    assert len(heaps) == 3
 
 def test_runstring():
     e = get_engine("foo(a, c).")

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_parsing.py	Sun Apr 22 21:12:52 2007
@@ -37,10 +37,10 @@
     term = parse_query_term(
         """add_numeral(succ(succ(null)), succ(succ(null)), X).""")
     e.run(term)
-    var = Var(0).getvalue(e.frame)
-    print var, e.frame
+    var = Var(0).getvalue(e.heap)
+    print var, e.heap
     # does not raise
-    var.unify(four, e.frame)
+    var.unify(four, e.heap)
     term = parse_query_term(
         """greater_than(succ(succ(succ(null))), succ(succ(null))).""")
     e.run(term)

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/test_unification.py	Sun Apr 22 21:12:52 2007
@@ -1,64 +1,65 @@
 import py
 from pypy.lang.prolog.interpreter.error import UnificationFailed
 from pypy.lang.prolog.interpreter.term import Atom, Var, Number, Term, Rule
-from pypy.lang.prolog.interpreter.engine import Frame, Engine
+from pypy.lang.prolog.interpreter.engine import Heap, Engine
 
 def test_atom():
-    a = Atom("hallo")
-    b = Atom("hallo")
+    a = Atom.newatom("hallo")
+    b = Atom.newatom("hallo")
     # does not raise
     a.unify(b, None)
-    py.test.raises(UnificationFailed, "a.unify(Atom('xxx'), None)")
+    py.test.raises(UnificationFailed, "a.unify(Atom.newatom('xxx'), None)")
 
 def test_var():
     b = Var(0)
-    frame = Frame()
-    frame.clear(1)
-    b.unify(Atom("hallo"), frame)
-    assert b.getvalue(frame).name == "hallo"
+    heap = Heap()
+    heap.clear(1)
+    b.unify(Atom.newatom("hallo"), heap)
+    assert b.getvalue(heap).name == "hallo"
     a = Var(0)
     b = Var(1)
-    frame.clear(2)
-    a.unify(b, frame)
-    a.unify(Atom("hallo"), frame)
-    assert a.getvalue(frame).name == "hallo"
-    assert b.getvalue(frame).name == "hallo"
+    heap.clear(2)
+    a.unify(b, heap)
+    a.unify(Atom.newatom("hallo"), heap)
+    assert a.getvalue(heap).name == "hallo"
+    assert b.getvalue(heap).name == "hallo"
 
 def test_unify_var():
     b = Var(0)
-    frame = Frame()
-    frame.clear(1)
-    b.unify(b, frame)
-    b.unify(Atom("hallo"), frame)
-    py.test.raises(UnificationFailed, b.unify, Atom("bye"), frame)
+    heap = Heap()
+    heap.clear(1)
+    b.unify(b, heap)
+    b.unify(Atom.newatom("hallo"), heap)
+    py.test.raises(UnificationFailed, b.unify, Atom.newatom("bye"), heap)
 
 def test_recursive():
     b = Var(0)
-    frame = Frame()
-    frame.clear(1)
-    b.unify(Term("hallo", [b]), frame)
+    heap = Heap()
+    heap.clear(1)
+    b.unify(Term("hallo", [b]), heap)
     
 
 def test_term():
     X = Var(0)
     Y = Var(1)
-    t1 = Term("f", [Atom("hallo"), X])
-    t2 = Term("f", [Y, Atom("HALLO")])
-    frame = Frame()
-    frame.clear(2)
+    t1 = Term("f", [Atom.newatom("hallo"), X])
+    t2 = Term("f", [Y, Atom.newatom("HALLO")])
+    heap = Heap()
+    heap.clear(2)
     print t1, t2
-    t1.unify(t2, frame)
-    assert X.getvalue(frame).name == "HALLO"
-    assert Y.getvalue(frame).name == "hallo"
+    t1.unify(t2, heap)
+    assert X.getvalue(heap).name == "HALLO"
+    assert Y.getvalue(heap).name == "hallo"
 
 def test_run():
     e = Engine()
-    e.add_rule(Term("f", [Atom("a"), Atom("b")]))
+    e.add_rule(Term("f", [Atom.newatom("a"), Atom.newatom("b")]))
     e.add_rule(Term("f", [Var(0), Var(0)]))
     e.add_rule(Term(":-", [Term("f", [Var(0), Var(1)]),
                            Term("f", [Var(1), Var(0)])]))
-    assert e.run(Term("f", [Atom("b"), Var(0)])) is None
-    assert e.frame.getvar(0).name == "b"
-    assert e.run(Term("f", [Atom("b"), Atom("a")])) is None
+    X = e.heap.newvar()
+    assert e.run(Term("f", [Atom.newatom("b"), X])) is None
+    assert X.dereference(e.heap).name == "b"
+    assert e.run(Term("f", [Atom.newatom("b"), Atom.newatom("a")])) is None
 
 

Modified: pypy/dist/pypy/lang/prolog/interpreter/test/tool.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/test/tool.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/test/tool.py	Sun Apr 22 21:12:52 2007
@@ -1,15 +1,15 @@
 import py
 from pypy.lang.prolog.interpreter.error import UnificationFailed, FunctionNotFound
 from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine
-from pypy.lang.prolog.interpreter.engine import Continuation, Frame, Engine
+from pypy.lang.prolog.interpreter.engine import Continuation, Heap, Engine
 
 def assert_true(query, e=None):
     if e is None:
         e = Engine()
     term = e.parse(query)[0][0]
     e.run(term)
-    f = Frame()
-    f.vars = e.frame.vars[:]
+    f = Heap()
+    f.vars = e.heap.vars[:]
     return f
 
 def assert_false(query, e=None):
@@ -24,12 +24,12 @@
 
 class CollectAllContinuation(Continuation):
     def __init__(self):
-        self.frames = []
+        self.heaps = []
 
     def call(self, engine):
-        f = Frame()
-        f.vars = engine.frame.vars[:]
-        self.frames.append(f)
+        f = Heap()
+        f.vars = engine.heap.vars[:]
+        self.heaps.append(f)
 #        import pdb; pdb.set_trace()
         print "restarting computation"
         raise UnificationFailed
@@ -39,5 +39,5 @@
     term = engine.parse(s)[0][0]
     py.test.raises(UnificationFailed, engine.run, term,
                    collector)
-    return collector.frames
+    return collector.heaps
 

Modified: pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py
==============================================================================
--- pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py	(original)
+++ pypy/dist/pypy/lang/prolog/interpreter/translatedmain.py	Sun Apr 22 21:12:52 2007
@@ -43,7 +43,7 @@
     for var, real_var in var_to_pos.iteritems():
         if var.startswith("_"):
             continue
-        val = f.format(real_var.getvalue(engine.frame))
+        val = f.format(real_var.getvalue(engine.heap))
         write("%s = %s\n" % (var, val))
 
 def getch():



More information about the Pypy-commit mailing list