Commits

Carl Friedrich Bolz committed e9d1f00

fix findall: the copy of the goal should not do variable shunting

Comments (0)

Files changed (3)

prolog/builtin/allsolution.py

     def __init__(self, engine, template, heap, scont):
         # nextcont still needs to be set, for correct exception propagation
         continuation.Continuation.__init__(self, engine, scont)
-        self.resultvar = self.fullsolution = heap.newvar()
+        self.result = []
         self.template = template
         self.heap = heap
 
     def activate(self, fcont, _):
         m = memo.CopyMemo()
         clone = self.template.copy(self.heap, m)
-        newresultvar = self.heap.newvar()
-        result = term.Callable.build(".", [clone, newresultvar])
-        self.resultvar.setvalue(result, self.heap)
-        self.resultvar = newresultvar
+        self.result.append(clone)
         raise error.UnificationFailed()
 
 class DoneWithFindallContinuation(continuation.FailureContinuation):
 
     def fail(self, heap):
         heap = heap.revert_upto(self.undoheap)
-        result = term.Callable.build("[]")
-        resultvar = self.collector.resultvar
-        resultvar.setvalue(result, heap)
-        self.bag.unify(self.collector.fullsolution, heap)
+        self.bag.unify(helper.wrap_list(self.collector.result), heap)
         return self.nextcont, self.orig_fcont, heap
 
 

prolog/interpreter/term.py

             return result
 
     def copy(self, heap, memo):
-        self = self.dereference(heap)
+        self = self.dereference(None)
         if isinstance(self, Var):
             res = memo.get(self)
             if res is not None:
             for key, index in attmap.indexes.iteritems():
                 value = self.value_list[index]
                 if value is not None:
-                    attrs.append("%s=%s" % (key, value))
+                    attrs.append("%s" % (key, ))
         return "AttVar(%s, %s)" % (self.getbinding(), "[" + ", ".join(attrs) + "]")
 
     def copy(self, heap, memo):
-        self = self.dereference(heap)
+        self = self.dereference(None)
         if isinstance(self, AttVar):
             res = memo.get(self)
             if res is not None:

prolog/interpreter/test/test_coroutines.py

 
     assert_true("sat([[false-X]], [X]), X == false.", e)
     assert_true("sat([[true-X], [false-Y]], [X, Y]), X == true, Y == false.", e)
-    # XXX fix findall
-    #assert_true("findall(X, sat([[true-X, false-Y]], [X, Y]), L), L == [true, true, false].", e)
+    assert_true("findall(X, sat([[true-X, false-Y]], [X, Y]), L), L == [true, true, false].", e)
     assert_false("sat([[true-X], [true-Y], [true-Z], [false-Z]], [X, Y, Z]).", e)
     assert_false("sat([[true-X, false-Y], [true-Y], [true-X], [false-Y]], [X, Y, Z]).", e)
     assert_false("sat([[true-X], [false-X]], [X]).", e)
     assert_true("queens(X), X == [2, 4, 1, 3].", e)
     assert_true("queens(X), X == [3, 1, 4, 2].", e)
     assert_false("queens(X), X == [4, 2, 1, 3].", e)
-    # XXX make findall run
-    #assert_true("findall(X, queens(X), L), L == [[2, 4, 1, 3], [3, 1, 4, 2]].", e)
+    assert_true("findall(X, queens(X), L), L == [[2, 4, 1, 3], [3, 1, 4, 2]].", e)
 
-@py.test.mark.xfail
 def test_findall_when():
     e = get_engine("""
     f(X) :-