[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