[pypy-svn] r44126 - in pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sun Jun 10 19:43:40 CEST 2007
Author: cfbolz
Date: Sun Jun 10 19:43:40 2007
New Revision: 44126
Modified:
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/portal.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py
pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_jit.py
Log:
attemps to get the prolog interpreter to work with the jit again. Kind of
works, but I seem to be getting strange segfaults for reasonably-sized prolog
programs :-(.
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/compiler.py Sun Jun 10 19:43:40 2007
@@ -24,6 +24,7 @@
Code.dynamic_code.maxlocalvar = 1
Code.dynamic_code.opcode_head = "l\x00\x00"
Code.dynamic_code.opcode = "l\x00\x00D"
+Code.dynamic_code.can_contain_cut = True
def compile(head, body, engine):
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/engine.py Sun Jun 10 19:43:40 2007
@@ -4,9 +4,9 @@
from pypy.lang.prolog.interpreter.error import UnificationFailed, \
FunctionNotFound, CutException
from pypy.lang.prolog.interpreter import error, helper
-from pypy.rlib.jit import hint, we_are_jitted, _is_early_constant, purefunction
-from pypy.rlib.objectmodel import specialize
+from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.jit import purefunction, hint
DEBUG = False
@@ -31,29 +31,49 @@
self.scope_active = False
return self.continuation
+class TrailChunk(object):
+ def __init__(self, last=None):
+ self.last = last
+ self.trail = []
+
+ def __str__(self):
+ return "TrailChunk(%s, %s)" % (self.last, self.trail)
+
class Heap(object):
+ _virtualizable_ = True
def __init__(self):
- self.trail = []
+ self.current_chunk = TrailChunk()
def reset(self):
- self.trail = []
- self.last_branch = 0
+ self.current_chunk = TrailChunk()
def add_trail(self, var):
- self.trail.append((var, var.binding))
+ self.current_chunk.trail.append((var, var.binding))
def branch(self):
- return len(self.trail)
+ result = TrailChunk(self.current_chunk)
+ self.current_chunk = result
+ return result
- def revert(self, state):
- trails = state
- for i in range(len(self.trail) - 1, trails - 1, -1):
- var, val = self.trail[i]
- var.binding = val
- del self.trail[trails:]
+ def revert(self, chunk):
+ curr = self.current_chunk
+ while curr is not None:
+ i = len(curr.trail) - 1
+ while i >= 0:
+ var, val = curr.trail[i]
+ var.binding = val
+ i -= 1
+ if curr is chunk:
+ break
+ curr = curr.last
+ else:
+ self.current_chunk = TrailChunk()
+ return
+ self.current_chunk = chunk
+ chunk.trail = []
def newvar(self):
- result = Var(self)
+ result = Var()
return result
class LinkedRules(object):
@@ -107,8 +127,9 @@
self.parser = None
self.operations = None
#XXX circular imports hack
- from pypy.lang.prolog.builtin import builtins_list
- globals()['unrolling_builtins'] = unrolling_iterable(builtins_list)
+ if not we_are_translated():
+ from pypy.lang.prolog.builtin import builtins_list
+ globals()['unrolling_builtins'] = unrolling_iterable(builtins_list)
def add_rule(self, rule, end=True):
from pypy.lang.prolog import builtin
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/interpreter.py Sun Jun 10 19:43:40 2007
@@ -6,6 +6,7 @@
LimitedScopeContinuation, DONOTHING
from pypy.lang.prolog.interpreter.prologopcode import unrolling_opcode_descs, \
HAVE_ARGUMENT
+from pypy.rlib.jit import hint, we_are_jitted, _is_early_constant, purefunction
class FrameContinuation(Continuation):
def __init__(self, frame, pc, continuation):
@@ -14,7 +15,7 @@
self.continuation = continuation
def _call(self, engine):
- return self.frame.run(self.frame.code.opcode, self.pc,
+ return self.frame.run(self.frame.code, False, self.pc,
self.continuation)
class Rule(object):
@@ -42,15 +43,6 @@
return "%s." % (self.head, )
return "%s :- %s." % (self.head, self.body)
-class Query(object):
- def __init__(self, body, engine):
- from pypy.lang.prolog.interpreter.compiler import compile_query
- self.code = compile_query(body, engine)
- self.engine = engine
-
- def make_frame(self):
- return Frame(self.engine, self.code)
-
def dynamic_call_frame(engine, query):
from pypy.lang.prolog.interpreter.compiler import Code
@@ -60,31 +52,81 @@
class Frame(object):
- #_immutable_ = True # XXX?
+ _virtualizable_ = True
def __init__(self, engine, code):
self.engine = engine
+ self.heap = engine.heap
self.code = code
self.localvarcache = [None] * code.maxlocalvar
- self.stack = None
+ self.result = None
+
+ def getcode(self):
+ return hint(hint(self.code, promote=True), deepfreeze=True)
def unify_head(self, head):
- self.run(self.code.opcode_head, 0, None)
- self.stack[0].unify(head, self.engine.heap)
- self.stack = None
+ self.run(self.getcode(), True, 0, None)
+ self.result.unify(head, self.heap)
+ self.result = None
def run_directly(self, continuation, choice_point=True):
- if self.code.opcode:
- continuation = self.run(self.code.opcode, 0, continuation)
if not choice_point:
+ if self.getcode().opcode:
+ continuation = FrameContinuation(self, 0, continuation)
return continuation
+ if self.getcode().opcode:
+ continuation = self.run(self.getcode(), False, 0, continuation)
while continuation is not DONOTHING:
continuation = continuation._call(self.engine)
return DONOTHING
- def run(self, bytecode, pc, continuation):
+ def run(self, codeobject, head, pc, continuation):
+ from pypy.lang.prolog.interpreter.compiler import Code
+ if codeobject is Code.dynamic_code:
+ return self._run(codeobject, head, pc, continuation)
+ if head:
+ return self._run(codeobject, head, pc, continuation)
+ if not we_are_jitted():
+ assert codeobject is not None
+ return self.run_jit(self.heap, codeobject, head, pc, continuation)
+ return self.opaque_run(codeobject, head, pc, continuation)
+
+ def opaque_run(self, codeobject, head, pc, continuation):
+ return self.run_jit(self.heap, codeobject, head, pc, continuation)
+ opaque_run._look_inside_me = False
+
+ def jit_enter_function(self):
+ # funnyness
+ code = self.getcode()
+ localvarcache = [None] * code.maxlocalvar
+ i = code.maxlocalvar
+ while True:
+ i -= 1
+ if i < 0:
+ break
+ hint(i, concrete=True)
+ obj = self.localvarcache[i]
+ localvarcache[i] = obj
+ self.localvarcache = localvarcache
+
+ def run_jit(self, heap, codeobject, head, pc, continuation):
+ hint(None, global_merge_point=True)
+ hint(codeobject, concrete=True)
+ codeobject = hint(codeobject, deepfreeze=True)
+ hint(head, concrete=True)
+ if head:
+ bytecode = codeobject.opcode_head
+ pc = 0
+ else:
+ bytecode = codeobject.opcode
+ pc = hint(pc, promote=True)
+ self.code = codeobject
+ self.heap = heap
+
+ self.jit_enter_function()
stack = []
while pc < len(bytecode):
+ hint(None, global_merge_point=True)
opcode = ord(bytecode[pc])
pc += 1
if opcode >= HAVE_ARGUMENT:
@@ -94,43 +136,98 @@
oparg = (hi << 8) | lo
else:
oparg = 0
+ hint(opcode, concrete=True)
+ hint(oparg, concrete=True)
#import pdb; pdb.set_trace()
- for opdesc in unrolling_opcode_descs:
- if opcode == opdesc.index:
- # dispatch to the opcode method
- meth = getattr(self, opdesc.name)
- if opdesc.hascontinuation:
- cont = FrameContinuation(self, pc, continuation)
- if opdesc.hasargument:
- res = meth(stack, oparg, cont)
- else:
- res = meth(stack, cont)
+ res = self.dispatch_bytecode(opcode, oparg, bytecode, pc,
+ stack, continuation)
+ if res is not None:
+ continuation = res
+ while continuation is not DONOTHING:
+ if isinstance(continuation, FrameContinuation):
+ self = continuation.frame
+ bytecode = self.getcode().opcode
+ pc = hint(continuation.pc, promote=True)
+ continuation = continuation.continuation
+ stack = []
+ break
else:
- if opdesc.hasargument:
- res = meth(stack, oparg)
- else:
- res = meth(stack)
- break
+ continuation = continuation._call(self.engine)
+ if head:
+ self.result = stack[0]
+ return continuation
+
+ def _run(self, codeobject, head, pc, continuation):
+ codeobject = hint(codeobject, promote=True)
+ codeobject = hint(codeobject, deepfreeze=True)
+ hint(head, concrete=True)
+ if head:
+ bytecode = codeobject.opcode_head
+ pc = 0
+ else:
+ bytecode = codeobject.opcode
+ pc = hint(pc, promote=True)
+ stack = []
+ while pc < len(bytecode):
+ opcode = ord(bytecode[pc])
+ pc += 1
+ if opcode >= HAVE_ARGUMENT:
+ hi = ord(bytecode[pc])
+ lo = ord(bytecode[pc+1])
+ pc += 2
+ oparg = (hi << 8) | lo
else:
- raise error.UncatchableError("bytecode corruption")
+ oparg = 0
+ hint(opcode, concrete=True)
+ hint(oparg, concrete=True)
+ #import pdb; pdb.set_trace()
+ res = self.dispatch_bytecode(opcode, oparg, bytecode, pc,
+ stack, continuation)
if res is not None:
continuation = res
while continuation is not DONOTHING:
if isinstance(continuation, FrameContinuation):
self = continuation.frame
- pc = continuation.pc
- bytecode = self.code.opcode
+ bytecode = self.getcode().opcode
+ pc = hint(continuation.pc, promote=True)
continuation = continuation.continuation
stack = []
break
else:
continuation = continuation._call(self.engine)
- if len(stack) != 0:
- self.stack = stack
+ if head:
+ self.result = stack[0]
return continuation
+
+ def dispatch_bytecode(self, opcode, oparg, bytecode, pc, stack,
+ continuation):
+ hint(opcode, concrete=True)
+ hint(oparg, concrete=True)
+ for opdesc in unrolling_opcode_descs:
+ if opcode == opdesc.index:
+ # dispatch to the opcode method
+ meth = getattr(self, opdesc.name)
+ if opdesc.hascontinuation:
+ if pc >= len(bytecode):
+ cont = continuation
+ else:
+ cont = FrameContinuation(self, pc, continuation)
+ if opdesc.hasargument:
+ return meth(stack, oparg, cont)
+ else:
+ return meth(stack, cont)
+ else:
+ if opdesc.hasargument:
+ return meth(stack, oparg)
+ else:
+ return meth(stack)
+ break
+ else:
+ raise error.UncatchableError("bytecode corruption")
+
def PUTCONSTANT(self, stack, number):
- stack.append(self.code.constants[number])
+ stack.append(self.getcode().constants[number])
def MAKELOCALVAR(self, stack, number):
result = self.localvarcache[number] = LocalVar()
@@ -143,15 +240,17 @@
def ACTIVATE_LOCAL(self, stack, number):
var = self.localvarcache[number]
- if isinstance(var, LocalVar):
- self.localvarcache[number] = var.dereference(self.engine.heap)
- var.active = True
+ assert var.__class__ == LocalVar
+ self.localvarcache[number] = result = var.dereference(self.heap)
+ hint(result.__class__, promote=True)
+ var.active = True
def MAKETERM(self, stack, number):
- name, numargs, signature = self.code.term_info[number]
+ name, numargs, signature = self.getcode().term_info[number]
args = [None] * numargs
i = numargs - 1
while i >= 0:
+ hint(i, concrete=True)
args[i] = stack.pop()
i -= 1
stack.append(Term(name, args, signature))
@@ -166,7 +265,7 @@
def STATIC_CALL(self, stack, number, continuation):
query = stack.pop()
- function = self.code.functions[number]
+ function = self.getcode().functions[number]
return self.user_call(function, query, continuation)
def DYNAMIC_CALL(self, stack, continuation):
@@ -184,24 +283,28 @@
self.localvarcache[number] = None
def UNIFY(self, stack):
- stack.pop().unify(stack.pop(), self.engine.heap)
+ stack.pop().unify(stack.pop(), self.heap)
def user_call(self, function, query, continuation):
assert isinstance(query, Callable)
rulechain = function.rulechain
+ rulechain = hint(rulechain, promote=True)
if rulechain is None:
error.throw_existence_error(
"procedure", query.get_prolog_signature())
- oldstate = self.engine.heap.branch()
+ oldstate = self.heap.branch()
while rulechain is not None:
rule = rulechain.rule
+ choice_point = rulechain.next is not None
+ hint(rule, concrete=True)
if rule.code.can_contain_cut:
continuation = LimitedScopeContinuation(continuation)
try:
frame = rule.make_frame(query)
- return frame.run_directly(continuation)
+ result = frame.run_directly(continuation)
+ return result
except error.UnificationFailed:
- self.engine.heap.revert(oldstate)
+ self.heap.revert(oldstate)
except error.CutException, e:
if continuation.scope_active:
return self.engine.continue_after_cut(e.continuation,
@@ -210,8 +313,10 @@
else:
try:
frame = rule.make_frame(query)
- return frame.run_directly(continuation)
+ result = frame.run_directly(continuation, choice_point)
+ return result
except error.UnificationFailed:
- self.engine.heap.revert(oldstate)
+ self.heap.revert(oldstate)
+ if not choice_point:
+ raise
rulechain = rulechain.next
- raise error.UnificationFailed
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/portal.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/portal.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/portal.py Sun Jun 10 19:43:40 2007
@@ -1,7 +1,7 @@
import py
-py.test.skip("jit doesn't work")
from pypy.jit.hintannotator.policy import ManualGraphPolicy
-from pypy.lang.prolog.interpreter import term, engine, helper
+from pypy.lang.prolog.interpreter import term, engine, helper, interpreter, \
+ prologopcode
from pypy.translator.translator import graphof
from pypy.annotation.specialize import getuniquenondirectgraph
@@ -14,11 +14,13 @@
}
-PORTAL = engine.Engine.portal_try_rule.im_func
+PORTAL = interpreter.Frame.run_jit.im_func
class PyrologHintAnnotatorPolicy(ManualGraphPolicy):
PORTAL = PORTAL
def look_inside_graph_of_module(self, graph, func, mod):
+ if "unify__" in graph.name:
+ return True
if mod in forbidden_modules:
return False
if mod in good_modules:
@@ -29,38 +31,38 @@
def fill_timeshift_graphs(self, portal_graph):
import pypy
- for cls in [term.Var, term.Term, term.Number, term.Atom]:
- self.seegraph(cls.copy)
+ for cls in [term.Var, term.Term, term.Number, term.Atom, term.LocalVar]:
self.seegraph(cls.__init__)
- self.seegraph(cls.copy_and_unify)
- for cls in [term.Term, term.Number, term.Atom]:
- self.seegraph(cls.copy_and_basic_unify)
+ for cls in [term.Var, term.LocalVar]:
+ self.seegraph(cls.setvalue)
+ for cls in [term.Term, term.Number, term.Atom, term.Var]:
self.seegraph(cls.dereference)
- self.seegraph(cls.copy_and_basic_unify)
for cls in [term.Var, term.Term, term.Number, term.Atom]:
- self.seegraph(cls.get_unify_hash)
self.seegraph(cls.eval_arithmetic)
for cls in [term.Callable, term.Atom, term.Term]:
self.seegraph(cls.get_prolog_signature)
- self.seegraph(cls.unify_hash_of_children)
self.seegraph(PORTAL)
self.seegraph(engine.Heap.newvar)
- self.seegraph(term.Rule.clone_and_unify_head)
- self.seegraph(engine.Engine.call)
- self.seegraph(engine.Engine._call)
- self.seegraph(engine.Engine.user_call)
- self.seegraph(engine.Engine._user_call)
- self.seegraph(engine.Engine.try_rule)
- self.seegraph(engine.Engine._try_rule)
- self.seegraph(engine.Engine.main_loop)
- self.seegraph(engine.Engine.dispatch_bytecode)
- self.seegraph(engine.LinkedRules.find_applicable_rule)
- for method in "branch revert discard newvar extend maxvar".split():
+ self.seegraph(engine.TrailChunk.__init__)
+ self.seegraph(interpreter.Rule.make_frame)
+ for method in "branch revert newvar add_trail".split():
self.seegraph(getattr(engine.Heap, method))
+ for method in ("unify_head run_directly run user_call "
+ "dispatch_bytecode getcode jit_enter_function "
+ "__init__ _run").split():
+ self.seegraph(getattr(interpreter.Frame, method))
+ for num in prologopcode.allopcodes:
+ method = prologopcode.opname[num]
+ if method == "DYNAMIC_CALL":
+ continue
+ self.seegraph(getattr(interpreter.Frame, method))
self.seegraph(engine.Continuation.call)
for cls in [engine.Continuation, engine.LimitedScopeContinuation,
- pypy.lang.prolog.builtin.control.AndContinuation]:
+ pypy.lang.prolog.builtin.control.AndContinuation,
+ interpreter.FrameContinuation
+ ]:
self.seegraph(cls._call)
+ self.seegraph(interpreter.FrameContinuation.__init__)
for function in "".split():
self.seegraph(getattr(helper, function))
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/term.py Sun Jun 10 19:43:40 2007
@@ -5,7 +5,7 @@
from pypy.lang.prolog.interpreter import error
from pypy.rlib.jit import hint
from pypy.rlib.objectmodel import specialize
-from pypy.rlib.jit import we_are_jitted, hint, purefunction
+from pypy.rlib.jit import we_are_jitted, hint, purefunction, _is_early_constant
DEBUG = False
@@ -61,7 +61,7 @@
__slots__ = ('binding', )
cache = {}
- def __init__(self, heap=None):
+ def __init__(self):
self.binding = None
@specialize.arg(3)
@@ -82,11 +82,17 @@
next = self.binding
if next is None:
return self
- else:
- result = next.dereference(heap)
- # do path compression
+ if isinstance(next, Var):
+ if _is_early_constant(next):
+ result = next.dereference(heap)
+ else:
+ result = next.opaque_dereference(heap)
self.setvalue(result, heap)
return result
+ return next
+
+ def opaque_dereference(self, heap):
+ return self.dereference(heap)
def getvalue(self, heap):
res = self.dereference(heap)
@@ -95,11 +101,11 @@
return res
def setvalue(self, value, heap):
- heap.add_trail(self)
- self.binding = value
+ if value is not self.binding:
+ heap.add_trail(self)
+ self.binding = value
def copy(self, heap, memo):
- hint(self, concrete=True)
try:
return memo[self]
except KeyError:
@@ -259,6 +265,7 @@
if isinstance(other, Float) and other.floatval == self.floatval:
return
raise UnificationFailed
+ basic_unify._look_inside_me_ = False
def copy(self, heap, memo):
return self
@@ -320,18 +327,17 @@
if (isinstance(other, Term) and
self.name == other.name and
len(self.args) == len(other.args)):
- for i in range(len(self.args)):
+ i = 0
+ while i < len(self.args):
self.args[i].unify(other.args[i], heap, occurs_check)
+ i += 1
else:
raise UnificationFailed
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
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_interpreter.py Sun Jun 10 19:43:40 2007
@@ -10,13 +10,13 @@
frame = r.make_frame(query)
assert frame.localvarcache[0].dereference(e.heap).name == "a"
cont = object()
- c2 = frame.run(frame.code.opcode, 0, cont)
+ c2 = frame.run(frame.code, False, 0, cont)
assert cont is c2
query, vars = get_query_and_vars("f(X).")
frame = r.make_frame(query)
cont = object()
- c2 = frame.run(frame.code.opcode, 0, cont)
+ c2 = frame.run(frame.code, False, 0, cont)
assert cont is c2
assert vars['X'].dereference(e.heap).name == 'a'
@@ -26,7 +26,7 @@
r = Rule(head, body, e)
frame = Frame(e, r.code)
- frame.run(frame.code.opcode_head, 0, None)
- frame.run(frame.code.opcode, 0, None)
- assert frame.stack[0].args[0].dereference(e.heap).name == "a"
- assert frame.stack[0].args[1].dereference(e.heap).name == "b"
+ frame.run(frame.code, True, 0, None)
+ frame.run(frame.code, False, 0, None)
+ assert frame.result.args[0].dereference(e.heap).name == "a"
+ assert frame.result.args[1].dereference(e.heap).name == "b"
Modified: pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_jit.py
==============================================================================
--- pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_jit.py (original)
+++ pypy/branch/prolog-bytecode/pypy/lang/prolog/interpreter/test/test_jit.py Sun Jun 10 19:43:40 2007
@@ -2,12 +2,11 @@
from pypy.jit.timeshifter.test.test_portal import PortalTest, P_NOVIRTUAL
from pypy.lang.prolog.interpreter import portal
from pypy.lang.prolog.interpreter import engine, term
-from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine
+from pypy.lang.prolog.interpreter.parsing import parse_query_term, get_engine, \
+ get_query_and_vars
POLICY = portal.PyrologHintAnnotatorPolicy()
-py.test.skip()
-
class TestPortal(PortalTest):
small = False
@@ -80,16 +79,20 @@
def test_append(self):
e = get_engine("""
+ a(X, Y, Z) :- append(X, Y, Z).
+ a(X, Y, Z) :- append(X, Y, Z).
append([], L, L).
append([X|Y], L, [X|Z]) :- append(Y, L, Z).
""")
- t = parse_query_term("append([a, b, c], [d, f, g], X).")
- X = e.heap.newvar()
+ t, vars = get_query_and_vars("a([a, b, c], [d, f, g], X).")
def main(n):
+ e.heap = engine.Heap()
+
if n == 0:
e.call(t)
- return isinstance(X.dereference(e.heap), term.Term)
+ assert isinstance(vars['X'].dereference(e.heap), term.Term)
+ return True
else:
return False
@@ -133,15 +136,15 @@
def test_loop(self):
e = get_engine("""
- f(X) :- h(X, _).
+ f(X) :- h(X).
f(50).
- h(0, _).
- h(X, Y) :- Y is X - 1, h(Y, _).
+ h(0).
+ h(X) :- Y is X - 1, h(Y).
""")
num = term.Number(50)
def main(n):
- e.heap.reset()
+ e.heap = engine.Heap()
if n == 0:
e.call(term.Term("f", [num]))
return True
More information about the Pypy-commit
mailing list