[pypy-svn] r24361 - pypy/dist/pypy/lib/logic/computation_space

auc at codespeak.net auc at codespeak.net
Tue Mar 14 16:35:35 CET 2006


Author: auc
Date: Tue Mar 14 16:35:25 2006
New Revision: 24361

Modified:
   pypy/dist/pypy/lib/logic/computation_space/computationspace.py
   pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py
   pypy/dist/pypy/lib/logic/computation_space/test_variable.py
   pypy/dist/pypy/lib/logic/computation_space/variable.py
Log:
more simplification


Modified: pypy/dist/pypy/lib/logic/computation_space/computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/computationspace.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/computationspace.py	Tue Mar 14 16:35:25 2006
@@ -9,8 +9,7 @@
 from state import Succeeded, Failed, Unknown
 
 from variable import EqSet, CsVar, NoValue, NoDom, \
-     VariableException, NotAVariable, AlreadyInStore, \
-     AlreadyBound
+     VariableException, NotAVariable, AlreadyBound
 from constraint import FiniteDomain, ConsistencyFailure, \
      Expression
 from distributor import DefaultDistributor

Modified: pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py	Tue Mar 14 16:35:25 2006
@@ -30,12 +30,6 @@
 
 class TestStoreUnification:
     
-
-    def test_already_in_store(self):
-        sp = newspace()
-        x = sp.var('x')
-        raises(v.AlreadyInStore, sp.var, 'x')
-
     def test_get_by_name(self):
         sp = newspace()
         x = sp.var('x')

Modified: pypy/dist/pypy/lib/logic/computation_space/test_variable.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/test_variable.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/test_variable.py	Tue Mar 14 16:35:25 2006
@@ -3,7 +3,7 @@
 
 from py.test import raises
 
-from variable import var, NoValue, AlreadyBound
+from variable import var, NoValue, AlreadyBound, stream_repr
 
 #-- utilities ---------------------
 
@@ -45,40 +45,22 @@
         x.bind(42)
         raises(AlreadyBound, x.bind, 43)
 
-    def test_dataflow(self):
-        def fun(thread, var):
-            thread.state = 1
-            v = var.wait()
-            thread.state = v
-
+    def test_repr_stream(self):
+        var._vcount = 0 #ensure consistent numbering
         x = var()
-        t = FunThread(fun, x)
-        import time
-        t.start()
-        time.sleep(.5)
-        assert t.state == 1
-        x.bind(42)
-        t.join()
-        assert t.state == 42
-            
-    def test_stream(self):
-        def consummer(thread, S):
-            v = S.wait()
-            if v:
-                thread.res += v[0]
-                consummer(thread, v[1])
-
-        S = var()
-        t = FunThread(consummer, S)
-        t.res = 0
-        t.start()
-        for i in range(10):
-            tail = var()
-            S.bind((i, tail))
-            S = tail
-        S.bind(None)
-        t.join()
-        assert t.res == 45
+        it = x
+        for i in range(3):
+            it.bind((var(), var()))
+            it = it.wait()[1]
+        assert stream_repr(x) == '<?1>|<?3>|<?5>|<?6>'
+        it.bind(None)
+        assert stream_repr(x) == '<?1>|<?3>|<?5>|None'
+        it = x
+        for i in range(3):
+            it.wait()[0].bind(i)
+            it = it.wait()[1]
+        assert stream_repr(x) == '0|1|2|None'
+
 
 #-- concurrent streams and lists ----------------
 
@@ -110,11 +92,12 @@
            {DGenerate N+1 Xr}
         end
     end"""
-    print "GENERATOR in %s waits on Xs" % thread.getName()
+    print "generator in %s waits on Xs" % thread.getName()
     X_Xr = Xs.wait()      # destructure Xs
     if X_Xr == None: return
+    print "generator X_Xr", X_Xr
     X = X_Xr[0]          # ... into X
-    print "GENERATOR in %s binds X to %s" % (thread.getName(), n)
+    print "generator in %s binds X to %s" % (thread.getName(), n)
     X.bind(n)            # bind X to n
     Xr = X_Xr[1]         # ... and Xr
     dgenerate(thread, n+1, Xr)
@@ -132,10 +115,10 @@
         # fill Xs with an empty pair
         X = var()
         Xr = var()
-        print "CLIENT binds Xs to X|Xr"
         Xs.bind((X, Xr))
+        print "client binds Xs to X|Xr ", stream_repr(Xs)
         x = X.wait() # wait on the value of X
-        print "CLIENT got", x
+        print "client got", x
         dsum(thread, Xr, a+x, limit-1)
     else:
         print "CLIENT binds Xs to None and exits"
@@ -178,12 +161,12 @@
         r3 = FunThread(reduc, Xs, 0, operator.add)
         generator = FunThread(generate, Xs, 0, 42)
 
-        r1.start()
-        r2.start()
-        r3.start()
-        generator.start()
+        for r in (r1, r2, r3):
+            r.start()
 
+        generator.start()
         generator.join()
+
         for r in (r1, r2, r3):
             r.join()
             assert r.result == 861
@@ -236,18 +219,6 @@
            buffer between generator/consummer
            avoids inefficient step-wise progression
         """
-        def print_stream(S):
-            while S.is_bound():
-                v = S.wait()
-                if isinstance(v, tuple):
-                    v0 = v[0]
-                    if v0.is_bound(): print v0, '|',
-                    else: print '?' ; break
-                    S = v[1]
-                else:
-                    print v
-                    break
-
         def bounded_buffer(thread, n, Xs, Ys):
 
             def startup(n, Xs):
@@ -257,11 +228,10 @@
                     else Xr in Xs=_|Xr {Startup N-1 Xr} end
                 end
                 """
-                if n==0: return Xs
-                print "startup n = ", n,
-                print_stream(Xs)
+                if n==0: return Xs # will be End
                 Xr = var()
                 Xs.bind((var(), Xr))
+                print "startup n = ", n, stream_repr(Xs)
                 return startup(n-1, Xr)
 
             def ask_loop(Ys, Xs, End):
@@ -274,14 +244,9 @@
                     end
                 end
                 """
-                print "Ask_loop ..."
-                print_stream(Xs)
-                print_stream(Ys)
                 Y_Yr = Ys.wait()   # destructure Ys
                 if Y_Yr != None: 
                     Y, Yr = Y_Yr
-                    print "Ask_loop in thread %s got %s %s " % \
-                          (thread.getName(), Y, Yr)
                     X, Xr = Xs.wait()
                     Y.bind(X.wait())
                     End2 = var()
@@ -290,10 +255,11 @@
                 else:
                     End.bind(None)
 
+            print "buffer initial Ys, Xs ", stream_repr(Ys, Xs)
             End = var()
             End.bind(startup(n, Xs))
-            print "BUFFER starts"
-            ask_loop(Ys, Xs, End)
+            print "buffer starts", stream_repr(Xs, End)
+            ask_loop(Ys, Xs, End.val)
 
         Xs = var()
         Ys = var()

Modified: pypy/dist/pypy/lib/logic/computation_space/variable.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/variable.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/variable.py	Tue Mar 14 16:35:25 2006
@@ -6,19 +6,15 @@
     def __init__(self, name):
         self.name = name
 
-class AlreadyInStore(VariableException):
-    def __str__(self):
-        return "%s already in store" % self.name
-
 class AlreadyBound(Exception):
     def __init__(self, var, val):
+        print "can't bind %s to %s" % (var, val)
         self.var = var
         self.val = val
     
     def __str__(self):
-        return "%s:%s already bound to %s" % (self.var.name,
-                                              self.var.val,
-                                              self.val)
+        var, val = self.var, self.val
+        return "can't bind %s to %s" % (var, val)
 
 class NotAVariable(VariableException):
     def __str__(self):
@@ -31,30 +27,30 @@
 
 class NoDom: pass
 
-def var():
-    return SimpleVar()
-
-class SimpleVar(object):
+class Var(object):
     """Spaceless dataflow variable"""
+    _count_lock = threading.Lock()
+    _vcount = 0
     
-    def __init__(self):
-        self.name = str(id(self))
-        self._val = NoValue
-        # a condition variable for concurrent access
+    def __init__(self, value=NoValue):
+        try:
+            Var._count_lock.acquire()
+            self.name = str(Var._vcount)
+        finally:
+            Var._count_lock.release()
+        Var._vcount += 1
+        self._val = value
+        # a condition variable for Wait
         self._value_condition = threading.Condition()
+        # for WaitNeeded
         self._need_condition = threading.Condition()
 
     # value accessors
     def _set_val(self, val):
-        self._value_condition.acquire()
-        try:
-            if self._val != NoValue:
-                if val != self._val:
-                    raise AlreadyBound(self, val)
-            self._val = val
-            self._value_condition.notifyAll()
-        finally:
-            self._value_condition.release()
+        if self._val != NoValue:
+            if val != self._val:
+                raise AlreadyBound(self, val)
+        self._val = val
         
     def _get_val(self):
         return self._val
@@ -62,8 +58,8 @@
 
     def __str__(self):
         if self.is_bound():
-            return "%s = %s" % (self.name, self.val)
-        return "%s" % self.name
+            return "<%s>" % str(self._val)
+        return "<?%s>" % self.name
 
     def __repr__(self):
         return self.__str__()
@@ -73,9 +69,17 @@
     def is_bound(self):
         return self.val != NoValue
 
+    def is_free(self):
+        return not self.isbound()
+        
     def bind(self, val):
-        self.val = val
-
+        self._value_condition.acquire()
+        try:
+            self.val = val
+            self._value_condition.notifyAll()
+        finally:
+            self._value_condition.release()
+            
     def wait(self):
         try:
             self._need_condition.acquire()
@@ -101,11 +105,39 @@
         finally:
             self._need_condition.release()
 
-class CsVar(SimpleVar):
+var = Var
+
+#-- utility ---------
+
+def stream_repr(*args):
+    """represent streams of variables whose
+       last element might be unbound"""
+    repr_ = []
+    for S in args:
+        while S.is_bound():
+            v = S.val
+            if isinstance(v, tuple):
+                v0 = v[0]
+                if v0.is_bound():
+                    repr_ += [str(v0.val), '|']
+                else: repr_ += [str(v0), '|']
+                S = v[1]
+            else:
+                repr_.append(str(v))
+                break
+        else:
+            repr_.append(str(S))
+        repr_.append(' ')
+    repr_.pop()
+    return ''.join(repr_)
+
+#-- to be killed soon ----
+
+class CsVar(Var):
     """Dataflow variable linked to a space"""
 
     def __init__(self, name, cs):
-        SimpleVar.__init__(self)
+        Var.__init__(self)
         if name in cs.names:
             raise AlreadyInStore(name)
         self.name = name
@@ -157,3 +189,4 @@
         self._cs.bind(self, val)
 
     is_bound = _is_bound
+



More information about the Pypy-commit mailing list