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

auc at codespeak.net auc at codespeak.net
Wed Jan 25 11:19:43 CET 2006


Author: auc
Date: Wed Jan 25 11:19:37 2006
New Revision: 22632

Modified:
   pypy/dist/pypy/lib/logic/computationspace.py
   pypy/dist/pypy/lib/logic/test_computationspace.py
   pypy/dist/pypy/lib/logic/unification.py
Log:
(ale, auc)
* add process method to narrow all domains of variables in a space
* tests


Modified: pypy/dist/pypy/lib/logic/computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computationspace.py	(original)
+++ pypy/dist/pypy/lib/logic/computationspace.py	Wed Jan 25 11:19:37 2006
@@ -141,22 +141,24 @@
 ## Choose
 ## ------
 
-## Y=choose(N) waits until te current space becomes stable, blocks the
-## current thread, and then creates a choice point with N alternatives in
-## the current space. The blocked choose call waits for an alternative to
-## be chosen by a commit operation on the space. The choose call only
-## defines how many alternatives tere are; it does not specify what toi
-## do for an alternative.Eventually, choose continues its execution with
-## Y=I when alternative I (1=<I=<N) is chosen. A maximum of one choice
-## point may exist in a space at any time.
+## Y=choose(N) waits until the current space becomes stable, blocks the
+## current thread, and then creates a choice point with N alternatives
+## in the current space. The blocked choose call waits for an
+## alternative to be chosen by a commit operation on the space. The
+## choose call only defines how many alternatives there are; it does
+## not specify what to do for an alternative. Eventually, choose
+## continues its execution with Y=I when alternative I (1=<I=<N) is
+## chosen. A maximum of one choice point may exist in a space at any
+## time.
 
 ## Ask
 ## ---
 
 ## A=Ask(s) asks the space s about its status. As soon as the space
-## becomes stable, A is bound. If s if failed (merged, succeeded), then
-## ask returns failed (merged, succeded). If s is distributable, then it
-## returns alternatives(N), where N is the number of alternatives.
+## becomes stable, A is bound. If s if failed (merged, succeeded),
+## then ask returns failed (merged, succeded). If s is distributable,
+## then it returns alternatives(N), where N is the number of
+## alternatives.
 
 ## An example specifying how to use a computation space :
 
@@ -175,8 +177,20 @@
 
 ## space = ComputationSpace(fun=my_problem)
 
+class Unprocessed:
+    pass
+
+class Failed:
+    pass
+
+class Merged:
+    pass
+
+class Succeeded:
+    pass
 
 from unification import Store, var
+from constraint import ConsistencyFailure
 
 class ComputationSpace(object):
 
@@ -184,12 +198,32 @@
         self.program = program
         self.parent = parent
         self.store = Store()
+        self.status = Unprocessed
         self.root = self.store.var('root')
         self.store.bind(self.root, program(self.store))
 
+    def ask(self):
+        # XXX: block on status being not stable for threads
+        if self._stable():
+            return self.status
+        else:
+            #TBD
+            return self.status
+
+    def _stable(self):
+        return self.status in (Failed, Succeeded, Merged)
+
+    def process(self):
+        try:
+            self.store.satisfy_all()
+        except ConsistencyFailure:
+            self.status = Failed
+        else:
+            self.status = Succeeded
+
+
     def branch(self):
         return ComputationSpace(self.program, parent=self)
 
+#    def choose(self, alternative):
 
-    def ask(self):
-        pass

Modified: pypy/dist/pypy/lib/logic/test_computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/test_computationspace.py	(original)
+++ pypy/dist/pypy/lib/logic/test_computationspace.py	Wed Jan 25 11:19:37 2006
@@ -4,29 +4,57 @@
 import computationspace as cs
 from py.test import raises
 
+def satisfiable_problem(store):
+    s = store # i'm lazy
+    x, y, z, w = (s.var('x'), s.var('y'),
+                  s.var('z'), s.var('w'))
+    s.set_domain(x, c.FiniteDomain([2, 6]))
+    s.set_domain(y, c.FiniteDomain([2, 3]))
+    s.set_domain(z, c.FiniteDomain([4, 5]))
+    s.set_domain(w, c.FiniteDomain([1, 4, 5]))
+    s.add_constraint(c.Expression([x, y, z], 'x == y + z'))
+    s.add_constraint(c.Expression([z, w], 'z < w'))
+    # we don't know yet how to
+    # set up a distribution strategy
+    return (x, w, y)
+
+def unsatisfiable_problem(store):
+    s = store # i'm lazy
+    x, y, z, w = (s.var('x'), s.var('y'),
+                  s.var('z'), s.var('w'))
+    s.set_domain(x, c.FiniteDomain([2, 6]))
+    s.set_domain(y, c.FiniteDomain([2, 3]))
+    s.set_domain(z, c.FiniteDomain([4, 5]))
+    s.set_domain(w, c.FiniteDomain([1]))
+    s.add_constraint(c.Expression([x, y, z], 'x == y + z'))
+    s.add_constraint(c.Expression([z, w], 'z < w'))
+    # we don't know yet how to
+    # set up a distribution strategy
+    return (x, w, y)
+
 
 class TestComputationSpace:
 
-    def setUp(self):
+    def setup_method(self, meth):
         pass
 
     def test_bind_cs_root(self):
-
-        def dummy_problem(store):
-            s = store # i'm lazy
-            x, y, z, w = (s.var('x'), s.var('y'),
-                          s.var('z'), s.var('w'))
-            s.set_domain(x, c.FiniteDomain([2, 6]))
-            s.set_domain(y, c.FiniteDomain([2, 3]))
-            s.set_domain(z, c.FiniteDomain([4, 5]))
-            s.set_domain(w, c.FiniteDomain([1, 4, 5]))
-            s.add_constraint(c.Expression([x, y, z], 'x == y + z'))
-            s.add_constraint(c.Expression([z, w], 'z < w'))
-            # we don't know yet how to
-            # set up a distribution strategy
-            return (x, y, z) 
-
-        spc = cs.ComputationSpace(dummy_problem)
+        spc = cs.ComputationSpace(satisfiable_problem)
         assert 'root' in spc.store.names
-        assert ['x', 'y', 'z'] == [var.name for var
-                                   in spc.root.val]
+        assert set(['x', 'y', 'w']) == \
+               set([var.name for var in spc.root.val])
+
+    def test_process_and_ask_success(self):
+        spc = cs.ComputationSpace(satisfiable_problem)
+        assert spc.ask() == cs.Unprocessed
+        spc.process()
+        assert spc.ask() == cs.Succeeded
+        
+
+    def test_process_and_ask_failure(self):
+        spc = cs.ComputationSpace(unsatisfiable_problem)
+        assert spc.ask() == cs.Unprocessed
+        spc.process()
+        assert spc.ask() == cs.Failed
+        
+        

Modified: pypy/dist/pypy/lib/logic/unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/unification.py	(original)
+++ pypy/dist/pypy/lib/logic/unification.py	Wed Jan 25 11:19:37 2006
@@ -270,7 +270,16 @@
             except ConsistencyFailure:
                 restore_domains(old_domains)
                 raise
-        
+
+    def satisfy_all(self):
+        old_domains = collect_domains(self.vars)
+        for const in self.constraints:
+            try:
+                const.narrow()
+            except ConsistencyFailure:
+                restore_domains(old_domains)
+                raise
+                
         
     #-- BIND -------------------------------------------
 
@@ -436,7 +445,8 @@
     """
     dom = {}
     for var in varset:
-        dom[var] = FiniteDomain(var.dom)
+        if var.dom:
+            dom[var] = FiniteDomain(var.dom)
     return dom
 
 def restore_domains(domains):



More information about the Pypy-commit mailing list