[pypy-svn] r25072 - in pypy/dist/pypy/objspace: . test

auc at codespeak.net auc at codespeak.net
Tue Mar 28 12:04:37 CEST 2006


Author: auc
Date: Tue Mar 28 12:04:35 2006
New Revision: 25072

Modified:
   pypy/dist/pypy/objspace/logic.py
   pypy/dist/pypy/objspace/test/test_logicobjspace.py
Log:
* unify dicts
* misc fixes


Modified: pypy/dist/pypy/objspace/logic.py
==============================================================================
--- pypy/dist/pypy/objspace/logic.py	(original)
+++ pypy/dist/pypy/objspace/logic.py	Tue Mar 28 12:04:35 2006
@@ -3,6 +3,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.rpython.objectmodel import we_are_translated
 from pypy.objspace.std.listobject import W_ListObject, W_TupleObject
+from pypy.objspace.std.dictobject import W_DictObject
 
 USE_COROUTINES = True
 HAVE_GREENLETS = True
@@ -153,7 +154,7 @@
     app_uthread = gateway.interp2app(uthread, unwrap_spec=[baseobjspace.ObjSpace,
                                                            baseobjspace.W_Root,
                                                            argument.Arguments])
-
+    
 
 #-- VARIABLE ---------------------
 
@@ -247,7 +248,7 @@
 #-- PREDICATES --------------------
 
 def is_aliased(space, w_var): # FIXME: this appears to block
-    if space.is_true(space.is_nb_(w_var.w_bound_to, w_var)):
+    if space.is_true(space.is_nb_(deref(space, w_var), w_var)):
         return space.newbool(False)
     return space.newbool(True)
 app_is_aliased = gateway.interp2app(is_aliased)
@@ -336,28 +337,33 @@
     l = len(a_str) - 1
     return a_str[l-3:l]
 
+def _sleep(space, w_var, w_barrier):
+    wait(space, w_var)
+    bind(space, w_barrier, space.newint(1))
+#app_sleep = gateway.interp2app(sleep)
+
 def wait_two(space, w_1, w_2):
     """waits until one out of two logic variables
        becomes bound, then tells which one,
        with a bias toward the first if both are
        suddenly bound"""
-    w_V = newvar(space)
-    def sleep(space, w_var):
-        wait(space, w_var)
-        bind(space, w_V, space.newint(1))
-    uthread(sleep, space, w_1)
-    uthread(sleep, space, w_2)
-    wait(space, w_V)
+    w_barrier = newvar(space)
+    uthread(space, space.wrap(_sleep),
+            argument.Arguments(space, [w_1, w_barrier]))
+    uthread(space, space.wrap(_sleep),
+            argument.Arguments(space, [w_2, w_barrier]))
+    wait(space, w_barrier)
     if space.is_true(is_free(space, w_2)):
         return space.newint(1)
     return space.newint(2)
+app_wait_two = gateway.interp2app(wait_two)
 
 #-- BIND -----------------------------
 
 def bind(space, w_var, w_obj):
     """1. aliasing of unbound variables
-       2. assign unbound var to bound var
-       3. assign value to self
+       2. assign bound var to unbound var
+       3. assign value to unbound var
     """
     print " :bind", w_var, w_obj
     assert isinstance(w_var, W_Var)
@@ -367,8 +373,10 @@
                 return unify(space, 
                              deref(space, w_var),
                              deref(space, w_obj))
+            # 2. a (obj unbound, var bound)
             return _assign(space, w_obj, deref(space, w_var))
         elif space.is_true(is_bound(space, w_obj)):
+            # 2. b (var unbound, obj bound)
             return _assign(space, w_var, deref(space, w_obj))
         else: # 1. both are unbound
             return _alias(space, w_var, w_obj)
@@ -422,19 +430,14 @@
     w_tail = w_v1.w_bound_to
     w_v1.w_bound_to = w_v2
     w_v2.w_bound_to = w_tail
-    disp_aliases(space, w_v1)
-    disp_aliases(space, w_v2)
     return space.w_None
     
 def _merge_aliases(space, w_v1, w_v2):
     print "   :merge aliases", w_v1, w_v2
-    # first get the tail of both sets
     w_tail1 = get_ring_tail(space, w_v1)
     w_tail2 = get_ring_tail(space, w_v2)
     w_tail1.w_bound_to = w_v2
     w_tail2.w_bound_to = w_v1
-    disp_aliases(space, w_v1)
-    disp_aliases(space, w_v2)
     return space.w_None
 
 #-- UNIFY -------------------------
@@ -454,48 +457,41 @@
             return unify(space, deref(space, w_x), w_y)            
         return bind(space, w_x, w_y)
     # x, y are vars
-    elif space.is_true(is_bound(space, w_x)) and \
-         space.is_true(is_bound(space, w_x)):
-        return _unify_values(space,
-                             deref(space, w_x), 
-                             deref(space, w_y))
     elif space.is_true(is_bound(space, w_x)):
+        if space.is_true(is_bound(space, w_y)):
+            return _unify_values(space,
+                                 deref(space, w_x), 
+                                 deref(space, w_y))
         return bind(space, w_y, w_x)
     # aliasing x & y ?
     else:
         return bind(space, w_x, w_y) # aliasing
-        #XXX: really do what's below :
-        #return _unify_unbound(space, w_x, w_y)
     reset_memo()
 app_unify = gateway.interp2app(unify)
 
-
-def _unify_unbound(space, w_x, w_y):
-    """sleeps until one of the two is bound
-       then bind the other to its value"""
-    w_bound = wait_two(space, w_x, w_y)
-    if space.eq_w(w_bound, space.newint(1)):
-        return bind(space, w_y, w_x)
-    return bind(space, w_x, w_y)
-
+    
 def _unify_values(space, w_v1, w_v2):
-    #print " :unify values", w_v1, w_v2
+    print " :unify values", w_v1, w_v2
     # unify object of the same type ... FIXME
     if not space.is_w(space.type(w_v1),
                       space.type(w_v2)):
         fail(space, w_v1, w_v2)
     # ... elements of a list/tuple ...
-    if isinstance(w_v1, W_ListObject) or \
-       isinstance(w_v1, W_TupleObject):
+    if (isinstance(w_v1, W_ListObject) and \
+        isinstance(w_v2, W_ListObject)) or \
+        (isinstance(w_v1, W_TupleObject) and \
+         isinstance(w_v1, W_TupleObject)):
         _unify_iterables(space, w_v1, w_v2)
-    else:
+    elif isinstance(w_v1, W_DictObject) and \
+        isinstance(w_v1, W_DictObject):
+        _unify_mappings(space, w_v1, w_v2)
         # ... token equality
         if not space.eq_w(w_v1, w_v2):
             fail(space, w_v1, w_v2)
         return space.w_None
 
 def _unify_iterables(space, w_i1, w_i2):
-    #print " :unify iterables", w_i1, w_i2
+    print " :unify iterables", w_i1, w_i2
     # assert lengths
     if len(w_i1.wrappeditems) != len(w_i2.wrappeditems):
         fail(space, w_i1, w_i2)
@@ -509,6 +505,19 @@
             continue
         unify(space, w_xi, w_yi)
 
+def _unify_mappings(space, w_m1, w_m2):
+    print "  :unify mappings", w_m1, w_m2
+##     if len(w_m1.wrappeditems) != len(w_m2.wrappeditems):
+##         fail(space, w_i1, w_i2)
+    for w_xk in w_m1.content.keys():
+        w_xi = space.getitem(w_m1, w_xk)
+        w_yi = space.getitem(w_m2, w_xk)
+        if space.is_true(space.is_nb_(w_xi, w_yi)):
+            continue
+        unify(space, w_xi, w_yi)
+        
+        
+
 # multimethod version of unify
 ## def unify__W_Var_W_Var(space, w_v1, w_v2):
 ##     return bind(space, w_v1, w_v2)
@@ -685,6 +694,8 @@
                      space.wrap(app_uthread))
         space.setitem(space.builtin.w_dict, space.wrap('wait'),
                      space.wrap(app_wait))
+##         space.setitem(space.builtin.w_dict, space.wrap('wait_two'),
+##                      space.wrap(app_wait_two))
         space.setitem(space.builtin.w_dict, space.wrap('wait_needed'),
                       space.wrap(app_wait_needed))
     return space

Modified: pypy/dist/pypy/objspace/test/test_logicobjspace.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_logicobjspace.py	(original)
+++ pypy/dist/pypy/objspace/test/test_logicobjspace.py	Tue Mar 28 12:04:35 2006
@@ -20,15 +20,12 @@
         #         FailureException
         raises(Exception, bind, X, 2)
 
-    def test_unify_tuple(self):
-        X = newvar()
-        unify(X, (1, (2, None)))
-        assert X == (1, (2, None))
-
     def test_bind_to_self(self):
         X = newvar()
         assert is_free(X)
         bind(X, X)
+        assert is_free(X)
+        assert alias_of(X, X)
         bind(X, 1)
         assert X == 1
 
@@ -36,19 +33,17 @@
         X = newvar()
         assert is_free(X)
         unify(X, X)
+        assert is_free(X)
+        assert alias_of(X, X)
         unify(X, 1)
         assert X == 1
 
-    def test_unify_alias(self):
-        X = newvar()
-        Y = newvar()
-        unify(X, Y)
-        assert alias_of(X, Y)
-        assert alias_of(Y, X)
-        bind(X, 1)
-        # what about is_alias, then ?
-        assert X == 1
-        assert Y == 1
+    def test_unify_circular(self):
+        X, Y = newvar(), newvar()
+        unify(X, [Y])
+        unify(Y, [X])
+        assert X == [Y]
+        assert Y == [X]
 
     def test_unify_alias(self):
         X = newvar()
@@ -142,7 +137,7 @@
     def test_eq_unifies_simple(self):
         X = newvar()
         Y = newvar()
-        unify(X, Y)
+        bind(X, Y)
         assert alias_of(Y, X)
         unify(X, 1)
         assert X == 1
@@ -154,13 +149,18 @@
     def test_ne_of_unified_unbound_vars(self):
         X = newvar()
         Y = newvar()
-        unify(X, Y)
+        bind(X, Y)
         assert is_free(X)
         assert is_free(Y)
         assert alias_of(X, Y)
         assert X == Y
         assert not X != Y
 
+    def test_unify_tuple(self):
+        X = newvar()
+        unify(X, (1, (2, None)))
+        assert X == (1, (2, None))
+
     def test_unify_list(self):
         X = newvar()
         x = (newvar(), newvar())
@@ -171,8 +171,16 @@
         assert X[1] == x[1]
         unify(X, (1, (2, None)))
         assert X == (1, (2, None))
+        unify(X, (1, (2, None)))
         raises(Exception, unify, X, (1, 2))
 
+    def test_unify_dict(self):
+        Z, W = newvar(), newvar()
+        unify({'a': 42, 'b': Z},
+              {'a':  Z, 'b': W})
+        assert Z == W == 42
+
+
 class AppTest_LogicThreads(object):
 
     def setup_class(cls):
@@ -197,13 +205,13 @@
     def test_eager_producer_consummer(self):
 
         def generate(n, limit):
-            print "generate", n, limit
+            #print "generate", n, limit
             if n < limit:
                 return (n, generate(n + 1, limit))
             return None
 
         def sum(L, a):
-            print "sum", a
+            #print "sum", a
             Head, Tail = newvar(), newvar()
             unify(L, (Head, Tail))
             if Tail != None:
@@ -213,7 +221,7 @@
         X = newvar()
         S = newvar()
         
-        bind(S, uthread(sum, X, 0))
+        unify(S, uthread(sum, X, 0))
         unify(X, uthread(generate, 0, 10))
 
         assert S == 45
@@ -223,35 +231,52 @@
 
         def lgenerate(n, L):
             """wait-needed version of generate"""
-            print "-- generator waits on L being needed"
             wait_needed(L)
             Tail = newvar()
             bind(L, (n, Tail))
-            print "generator bound L"
             lgenerate(n+1, Tail)
 
         def lsum(L, a, limit):
             """this summer controls the generator"""
             if limit > 0:
-                print "sum : ", a
                 Head, Tail = newvar(), newvar()
-                print "-- sum waiting on L"
                 wait(L)
                 unify(L, (Head, Tail))
                 return lsum(Tail, a+Head, limit-1)
             else:
                 return a
 
-        print "lazy producer consummer"
-        print "before"
         Y = newvar()
         T = newvar()
-        disp(Y)
-        disp(T)
+
         uthread(lgenerate, 0, Y)
         unify(T, uthread(lsum, Y, 0, 10))
-        print "after"
 
         wait(T)
         assert T == 45
-        print T
+        
+    def notest_wait_two(self):
+        def sleep(X, Barrier):
+            print "sleep"
+            wait(X)
+            bind(Barrier, True)
+        
+        def wait_two(X, Y):
+            print "wait two"
+            Z = newvar()
+            uthread(sleep, X, Z)
+            uthread(sleep, Y, Z)
+            print "on barrier"
+            wait(Z)
+            if is_free(Y):
+                return 1
+            return 2
+        
+        X, Y = newvar(), newvar()
+        disp(X)
+        disp(Y)
+        o = uthread(wait_two, X, Y)
+        unify(X, Y)
+        unify(Y, 42)
+        assert X == Y == 42
+        assert o == 2



More information about the Pypy-commit mailing list