[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