[pypy-svn] r22511 - pypy/dist/pypy/lib/logic

auc at codespeak.net auc at codespeak.net
Mon Jan 23 13:31:33 CET 2006


Author: auc
Date: Mon Jan 23 13:31:31 2006
New Revision: 22511

Modified:
   pypy/dist/pypy/lib/logic/test_unification.py
   pypy/dist/pypy/lib/logic/unification.py
Log:
check
* concurrent unification
* values unification


Modified: pypy/dist/pypy/lib/logic/test_unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/test_unification.py	(original)
+++ pypy/dist/pypy/lib/logic/test_unification.py	Mon Jan 23 13:31:31 2006
@@ -45,6 +45,21 @@
         assert y.val == 42
         assert z.val == 3.14
 
+    def test_unify_same(self):
+        x,y,z = (u.var('x'), u.var('y'), u.var('z'))
+        u.bind(x, [42, z])
+        u.bind(y, [z, 42])
+        u.unify(x, y)
+        assert z.val == 42
+
+    def test_unify_values(self):
+        x, y = u.var('x'), u.var('y')
+        u.bind(x, [1, 2, 3])
+        u.bind(y, [1, 2, 3])
+        u.unify(x, y)
+        assert x.val == [1, 2, 3]
+        assert y.val == [1, 2, 3]
+
     def test_unify_lists_success(self):
         x,y,z,w = (u.var('x'), u.var('y'),
                    u.var('z'), u.var('w'))
@@ -159,6 +174,32 @@
                (t1.raised and not t2.raised)
     
 
+    def test_threads_unifying_vars(self):
+        x, y, z = u.var('x'), u.var('y'), u.var('z')
+        l1 = range(999)
+        l2 = range(999)
+        l1[-1] = z
+        l2[0] = z
+        l2[-1] = 0
+        u.bind(x, l1)
+        u.bind(y, l2)
 
+        def do_unify(thread, v1, v2):
+            thread.raised = False
+            print thread
+            try:
+                u.unify(v1, v2)
+            except u.UnificationFailure:
+                thread.raised = True
+            print thread
 
+        t1, t2 = (FunThread(do_unify, x, y),
+                  FunThread(do_unify, x, y))
+        t1.start()
+        t2.start()
+        t1.join()
+        t2.join()
+        assert z.val == 0
+        assert (t2.raised and not t1.raised) or \
+               (t1.raised and not t2.raised)
             

Modified: pypy/dist/pypy/lib/logic/unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/unification.py	(original)
+++ pypy/dist/pypy/lib/logic/unification.py	Mon Jan 23 13:31:31 2006
@@ -230,14 +230,13 @@
             self.in_transaction = False
 
     def _really_unify(self, x, y):
-        #FIXME in case of failure, the store state is not
-        #      properly restored ...
-        print "unify %s with %s" % (x,y)
+        # print "unify %s with %s" % (x,y)
         if not _unifiable(x, y): raise UnificationFailure(x, y)
         # dispatch to the apropriate unifier
         if not x in self.vars:
             if not y in self.vars:
                 if x != y: raise UnificationFailure(x, y)
+                else: return
             self._unify_var_val(y, x)
         elif not y in self.vars:
             self._unify_var_val(x, y)
@@ -249,12 +248,15 @@
             self.bind(y,x)
 
     def _unify_var_val(self, x, y):
-        if x._is_bound(): raise UnificationFailure(x, y)
-        if x != y:
-            self.bind(x, y)
+        #if x._is_bound(): raise UnificationFailure(x, y)
+        if x.val != y:
+            try:
+                self.bind(x, y)
+            except AlreadyBound:
+                raise UnificationFailure(x, y)
         
     def _unify_bound(self, x, y):
-        print "unify bound %s %s" % (x, y)
+        # print "unify bound %s %s" % (x, y)
         vx, vy = (x.val, y.val)
         if type(vx) in [list, set] and isinstance(vy, type(vx)):
             self._unify_iterable(x, y)
@@ -264,7 +266,7 @@
             raise UnificationFailure(x, y)
 
     def _unify_iterable(self, x, y):
-        print "unify sequences %s %s" % (x, y)
+        # print "unify sequences %s %s" % (x, y)
         vx, vy = (x.val, y.val)
         idx, top = (0, len(vx))
         while (idx < top):
@@ -272,7 +274,7 @@
             idx += 1
 
     def _unify_mapping(self, x, y):
-        print "unify mappings %s %s" % (x, y)
+        # print "unify mappings %s %s" % (x, y)
         vx, vy = (x.val, y.val)
         for xk in vx.keys():
             self._really_unify(vx[xk], vy[xk])
@@ -298,7 +300,7 @@
     """Checks wether two terms can be unified"""
     if ((id(term1), id(term2))) in _unifiable_memo: return False
     _unifiable_memo.add((id(term1), id(term2)))
-    print "unifiable ? %s %s" % (term1, term2)
+    # print "unifiable ? %s %s" % (term1, term2)
     if _iterable(term1):
         if _iterable(term2):
             return _iterable_unifiable(term1, term2)
@@ -311,7 +313,7 @@
         
 def _iterable_unifiable(c1, c2):
    """Checks wether two iterables can be unified"""
-   print "unifiable sequences ? %s %s" % (c1, c2)
+   # print "unifiable sequences ? %s %s" % (c1, c2)
    if len(c1) != len(c2): return False
    idx, top = (0, len(c1))
    while(idx < top):
@@ -322,7 +324,7 @@
 
 def _mapping_unifiable(m1, m2):
     """Checks wether two mappings can be unified"""
-    print "unifiable mappings ? %s %s" % (m1, m2)
+    # print "unifiable mappings ? %s %s" % (m1, m2)
     if len(m1) != len(m2): return False
     if m1.keys() != m2.keys(): return False
     v1, v2 = (m1.items(), m2.items())



More information about the Pypy-commit mailing list