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

auc at codespeak.net auc at codespeak.net
Fri Mar 10 12:52:03 CET 2006


Author: auc
Date: Fri Mar 10 12:51:56 2006
New Revision: 24212

Modified:
   pypy/dist/pypy/lib/logic/computation_space/computationspace.py
   pypy/dist/pypy/lib/logic/computation_space/constraint.py
   pypy/dist/pypy/lib/logic/computation_space/distributor.py
   pypy/dist/pypy/lib/logic/computation_space/strategies.py
   pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py
   pypy/dist/pypy/lib/logic/computation_space/variable.py
Log:
* killed distributor/propagator thread
* removed dead code


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	Fri Mar 10 12:51:56 2006
@@ -3,34 +3,14 @@
 # * [5] add a linear constraint solver (vital for fast
 #   constraint propagation over finite integer domains)
 #   and other kinds of specialized propagators
-# * [9] make all propagators live in their own threads and
-#   be awakened by variable/domains events
-
-
-# Gert Smolka in
-# http://www.cetic.be/moz2004/talks/MOZ2004.pdf :
-# * Abandon Logic Variables
-#  * can be bound everywhere
-#  * malicious consummer can bind tail variable of stream
-#  * break abstractions
-#  * unification not needed
-# * Have Futures instead
-#  * Multilisp [Halstead 85]
-#  * added to Mozart in 1998
-#  * refine logic variable into
-#   * consummer end (future)
-#   * producer end (promise)
-#  * dataflow synchronization + by-need synchronization
-
 
 from threading import Thread, Condition, RLock, local
 
-from state import Succeeded, Distributable, Failed, \
-     Unknown, Forsaken
+from state import Succeeded, Failed, Unknown
 
 from variable import EqSet, CsVar, NoValue, NoDom, \
      VariableException, NotAVariable, AlreadyInStore, \
-     AlreadyBound, SimpleVar
+     AlreadyBound
 from constraint import FiniteDomain, ConsistencyFailure, \
      Expression
 from distributor import DefaultDistributor
@@ -104,9 +84,6 @@
         self.bind_lock = RLock()
         self.var_lock = RLock()
         self.distributor = DefaultDistributor(self)
-        # parent/children
-        self.parent = parent
-        self.children = set()
         # mapping from domains to variables
         self.doms = {}
         # set of all constraints 
@@ -122,10 +99,7 @@
             self.root = self.var('__root__')
             # set up the problem
             self.bind(self.root, problem(self))
-            self._init_choose_commit()
-            self.distributor.start()
         else:
-            self.parent.children.add(self)
             # shared stuff
             self.vars = parent.vars
             self.names = parent.names
@@ -136,14 +110,6 @@
             # ...
             self.status = Unknown
             self.distributor = parent.distributor.__class__(self)
-            self._init_choose_commit()
-
-    def _init_choose_commit(self):
-        # create a unique choice point
-        # using two spaceless vars as channels betwen
-        # space and distributor threads
-        self.CHOOSE = SimpleVar()
-        self.STABLE = SimpleVar()
 
 #-- utilities & instrumentation -----------------------------
 
@@ -155,15 +121,6 @@
         ret.append(">")
         return ' '.join(ret)
 
-    def __del__(self):
-        # try to break ref. cycles and help
-        # threads terminate
-        self.status = Forsaken
-        self.parent = None
-        self.children = None
-        self.CHOOSE.bind(True)
-        self.STABLE.bind(True)
-
     def __eq__(self, spc):
         """space equality defined as :
            * identity, or
@@ -207,12 +164,20 @@
                 print ' ', str(d.get_values())
         print " -- domains --)"
 
+    def test_solution(self, sol):
+        res = True
+        for _const in self.constraints:
+            if not _const.test_solution(sol):
+                print "Solution", sol, "doesn't satisfy", _const
+                res = False
+        return res
+
            
 #-- Computation Space -----------------------------------------
 
     #-- space helpers -----------------------------------------
 
-    def _process(self):
+    def _propagate(self):
         """wraps the propagator"""
         if len(self.event_set):
             try:
@@ -239,33 +204,19 @@
     #-- space official API ------------------------------------
 
     def ask(self):
-        self.STABLE.get() 
-        status = self.status in (Failed, Succeeded)
-        if status: return self.status
+        self._propagate()
+        if self.status in (Failed, Succeeded):
+            return self.status
         if self._distributable():
             return Alternative(self.distributor.nb_subdomains())
 
-        # should be unreachable
-        print "DOMS", [(var, self.doms[var]) 
-                       for var in self.vars
-                       if self.dom(var) != NoDom]
-        raise NotImplementedError
-
     def clone(self):
-        # did you ask before ... ?
-        assert self.STABLE.is_bound()
         spc = ComputationSpace(NoProblem, parent=self)
         print "-- cloning %s to %s --" % (self.id, spc.id)
         self._notify(event.Clone)
-        spc._process()
-        spc.distributor.start()            
+        spc._propagate()
         return spc
 
-    def inject(self, restricting_problem):
-        """add additional entities into a space"""
-        restricting_problem(self)
-        self._process()
-
     def commit(self, choice):
         """if self is distributable, causes the Choose call in the
            space to complete and return some_number as a result. This
@@ -273,10 +224,7 @@
            some_number must satisfy 1=<I=<N where N is the first arg
            of the Choose call.
         """
-        # did you ask before ... ?
-        assert self.STABLE.is_bound()
-        self.STABLE = SimpleVar()
-        self.CHOOSE.bind(choice)
+        self.distributor.distribute(choice-1)
 
     def choose(self, nb_choices):
         """
@@ -288,9 +236,7 @@
         ----
         this is used by the distributor thread
         """
-        choice = self.CHOOSE.get()
-        return choice    
-
+    
     def merge(self):
         """binds root vars to their singleton domains """
         assert self.status == Succeeded
@@ -298,16 +244,19 @@
         #for var in self.root.val:
         #    var.bind(self.dom(var).get_values()[0])
         # shut down the distributor
-        self.CHOOSE.bind(True)
-        self.status = Forsaken
         res = {}
         for var in self.root.val:
             res[var.name] = self.dom(var).get_values()[0]
-        self.distributor.join()
         return res
 
     def set_distributor(self, dist):
         self.distributor = dist
+
+    def inject(self, restricting_problem):
+        """add additional entities into a space"""
+        restricting_problem(self)
+        self._propagate()
+
         
 #-- Constraint Store ---------------------------------------
 
@@ -434,71 +383,6 @@
 
     #-- Constraint propagation ---------------
 
-    def satisfiable(self, constraint):
-        """ * satisfiable (k) checks that the constraint k
-              can be satisfied wrt its variable domains
-              and other constraints on these variables
-            * does NOT mutate the store
-        """
-        # Satisfiability of one constraint entails
-        # satisfiability of the transitive closure
-        # of all constraints associated with the vars
-        # of our given constraint.
-        # We make a copy of the domains
-        # then traverse the constraints & attached vars
-        # to collect all (in)directly affected vars
-        # then compute narrow() on all (in)directly
-        # affected constraints.
-        assert constraint in self.constraints
-        varset = set()
-        constset = set()
-        self._compute_dependant_vars(constraint, varset, constset)
-        old_domains = self.collect_domains(varset)
-        
-        for const in constset:
-            try:
-                const.revise3()
-            except ConsistencyFailure:
-                self.restore_domains(old_domains)
-                return False
-        self.restore_domains(old_domains)
-        return True
-
-    def get_satisfying_domains(self, constraint):
-        """computes the smallest satisfying domains"""
-        assert constraint in self.constraints
-        varset = set()
-        constset = set()
-        self._compute_dependant_vars(constraint, varset, constset)
-        old_domains = self.collect_domains(varset)
-        
-        for const in constset:
-            try:
-                const.revise3()
-            except ConsistencyFailure:
-                self.restore_domains(old_domains)
-                return {}
-        narrowed_domains = self.collect_domains(varset)
-        self.restore_domains(old_domains)
-        return narrowed_domains
-
-    def satisfy(self, constraint):
-        """prune the domains down to smallest satisfying domains"""
-        assert constraint in self.constraints
-        varset = set()
-        constset = set()
-        self._compute_dependant_vars(constraint, varset, constset)
-        old_domains = self.collect_domains(varset)
-
-        for const in constset:
-            try:
-                const.revise3()
-            except ConsistencyFailure:
-                self.restore_domains(old_domains)
-                raise
-
-    #-- real propagation begins there -------------------------
-
     def add_distributed(self, var):
         self.changelog.append(var)
 

Modified: pypy/dist/pypy/lib/logic/computation_space/constraint.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/constraint.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/constraint.py	Fri Mar 10 12:51:56 2006
@@ -201,6 +201,14 @@
                                    + expand_expr_template(formula, variables), {}, {})
             Expression._FILTER_CACHE[formula] = self.filterFunc
 
+    def test_solution(self, sol ):
+        """FOR TESTING: test a solution against this constraint                                                                                
+        accept a mapping of variable names to value"""
+        args = []
+        for var in self._variables:
+            args.append( sol[var.name] )
+        return self.filterFunc( *args )
+
 
     def copy_to(self, space):
         return self.__class__(space, self._variables,

Modified: pypy/dist/pypy/lib/logic/computation_space/distributor.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/distributor.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/distributor.py	Fri Mar 10 12:51:56 2006
@@ -1,8 +1,5 @@
 import math, random
-from threading import Thread
-from state import Succeeded, Distributable, Failed, Forsaken
 from event import Revise
-from variable import SimpleVar
 
 def arrange_domains(cs, variables):
     """build a data structure from var to dom
@@ -12,11 +9,10 @@
         new_doms[var] = cs.dom(var).copy()
     return new_doms
 
-class AbstractDistributor(Thread):
+class AbstractDistributor(object):
     """_distribute is left unimplemented."""
 
     def __init__(self, c_space, nb_subspaces=2):
-        Thread.__init__(self)
         self.nb_subspaces = nb_subspaces
         self.cs = c_space
         self.verbose = 0
@@ -137,32 +133,9 @@
         else:
             return self.cs.dom(self.__to_split).size() 
 
-    ### new threaded distributor
-
-    def run(self):
-        print "-- distributor started (%s) --" % self.cs.id
-        assert not self.cs.STABLE.is_bound()
-        #XXX: are the domains properly set up ?
-        #self.cs._process() # propagate first
-        #better let clone() do this call
-        while self.cs._distributable():
-            self.cs.STABLE.bind(True)
-            choice = self.cs.choose(self.nb_subdomains())
-            if self.cs.status == Forsaken:
-                print "-- distributor (%s) ready for GC --" % self.cs.id
-                break
-            print "-- distribution & propagation (%s) --" % self.cs.id
-            self.distribute(choice-1)
-            self.cs._process()
-            self.cs.CHOOSE = SimpleVar()
-            self.cs.STABLE.bind(True) # unlocks Ask
-        print "-- distributor terminated (%s) --" % self.cs.id
-
 
     def distribute(self, choice):
         variable = self.findSmallestDomain()
-        #variables = self.cs.get_variables_with_a_domain()
-        #domains = arrange_domains(self.cs, variables)
         nb_subspaces = self.nb_subdomains()
         values = self.cs.dom(variable).get_values()
         nb_elts = max(1, len(values)*1./nb_subspaces)

Modified: pypy/dist/pypy/lib/logic/computation_space/strategies.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/strategies.py	(original)
+++ pypy/dist/pypy/lib/logic/computation_space/strategies.py	Fri Mar 10 12:51:56 2006
@@ -22,9 +22,8 @@
             if outcome is None:
                 new_space.ask()
                 new_space.commit(2)
-                return do_dfs(new_space)
-            else:
-                return outcome
+                outcome = do_dfs(new_space)
+            return outcome
         else:
             raise StrategyDistributionMismatch()
                                                
@@ -35,15 +34,24 @@
 
 
 
-#-- solve_all
+#-- solve_all, switchable direction
 
-def solve_all(problem):
+class Depth: pass
+class Breadth: pass
+
+def solve_all(problem, direction=Depth):
 
     solutions = []
     sp_stack = []
-
     sp_stack.append(csp.ComputationSpace(problem))
 
+    if direction == Depth:
+        def collect(space):
+            sp_stack.append(space)
+    else:
+        def collect(space):
+            sp_stack.insert(0, space)
+
     while len(sp_stack):
         space = sp_stack.pop()
         print ' '*len(sp_stack), "ask ..."
@@ -54,112 +62,40 @@
         elif status == csp.Alternative(2):
             print ' '*len(sp_stack), "branches ..."
             sp1 = space.clone()
-            sp1.ask()
             sp1.commit(1)
-            sp_stack.append(sp1)
+            collect(sp1)
             sp2 = space.clone()
-            sp2.ask()
             sp2.commit(2)
-            sp_stack.append(sp2)
+            collect(sp2)
 
     return [sp.merge() for sp in solutions]
-    
-## declare
 
-## % This version of SolveAll will do a depth-first or breadth-first 
-## % traversal of the search space depending on the WhichFirst parameter.
-## fun {SolveAll WhichFirst Script} 
-##    {TouchAll {Solve WhichFirst Script}} 
-## end
-
-## fun {TouchAll L}
-##    case L of
-##       nil then skip
-##    [] _ | Rest then {TouchAll Rest _}
-##    end
-##    L
-## end
-
-## % Returns a lazy list of solutions for Script.
-## % The list is ordered depth-first or breadth-first
-## % depending on the WhichFirst parameter.
-## % The allowable values are depth and breadth.
-## fun {Solve WhichFirst Script}
-
-## % All the subsidiary function are declared within Solve so
-## % that we won't have to pass WhichFirst around.
-## % The body of Solve is at the bottom.
-
-##    % Each of the elements in Ss is either a Space or a 
-##    % commitTo(<Space> <Int>) record. A commitTo(<Space> <Int>) 
-##    % record identifies a Space that is ready to commit to
-##    % the Ith choice at a choice point.
-##    % Returns all solutions using either depth-first or
-##    % breadth-first depending on the value of WhichFirst.
-##    fun lazy {SolveSpaces Ss}
-##       case Ss of
-##          nil then nil
-##       [] S | SRest then
-##          % S is either a Space or a commitTo(<Space> <Int>) record.
-##          case S of
-## 	     commitTo(S I) then
-## 	     Clone = {Space.clone S} 
-##          in
-## 	     % Start the Ith branch in the clone of S.
-## 	     {Space.commit Clone I}
-## 	     {SolveSpaces Clone|SRest}
-##          else % S is a Space.
-##              {SolveSpace {Space.ask S} S SRest}
-##          end
-##       end
-##    end
-
-##    % Deal with Space S, which is in state SpaceState
-##    fun {SolveSpace SpaceState S SRest}
-##       case SpaceState of
-##          failed then {SolveSpaces SRest}  
-##       [] succeeded then {Space.merge S}|{SolveSpaces SRest}  
-##       [] alternatives(N) then
-##          {SolveSpaces {NewSpaceList {Choices S N} SRest}}
-##       end
-##    end
-
-##    % The choices are commitTo(<Space> <Int>) records. They
-##    % keep track of the branch to which to commit.
-##    fun {Choices S N}
-##       {List.mapInd
-##        {List.make N} % Generates N elements for Map to use.
-##        % Keep track of which branch to commit to.
-##        fun {$ I _} commitTo(S I) end}
-##    end
-
-##    % Put the Choices at the front or back of the existing list
-##    % of pending Spaces depending on WhichFirst.  For efficiency 
-##    % the lists could be replaced with difference lists.
-##    fun {NewSpaceList Choices Ss}
-##       % This is the only place where WhichFirst matters.
-##       % In depth-first search, the list of pending spaces is a stack.
-##       if WhichFirst == depth then {Append Choices Ss}
-##       % In breadth-first search, the list of pending spaces is a queue.
-##       elseif WhichFirst == breadth then {Append Ss Choices}
-##       else {Raise traversalSpecificationError(WhichFirst)} nil
-##       end
-##    end
-
-## in
-## % The body of Solve
-##    {SolveSpaces [{Space.new Script}]} 
-## end
-
-## % ==============================================================
-## % Example to illustrate depth-first vs. breadth-first
-## fun {ABC} choice a [] b [] c end end
-
-## % The "problem" looks at all lists of length =< 3.
-## % The "Show" documents the order in which the lists
-## % are generated.
-## fun {Problem List}
-##    if {Length List} > 3 then fail end
-##    {Show List}
-##    {Problem {Append List [{ABC}]}}
-## end
+#-- pythonic lazy solve_all
+
+def lazily_solve_all(space, direction=Depth):
+
+    sp_stack = []
+    sp_stack.append(space)
+
+    if direction == Depth:
+        def collect(space):
+            sp_stack.append(space)
+    else:
+        def collect(space):
+            sp_stack.insert(0, space)
+
+    while len(sp_stack):
+        space = sp_stack.pop()
+        print ' '*len(sp_stack), "ask ..."
+        status = space.ask()
+        if status == csp.Succeeded:
+            print ' '*len(sp_stack), "solution !"
+            yield space.merge()
+        elif status == csp.Alternative(2):
+            print ' '*len(sp_stack), "branches ..."
+            sp1 = space.clone()
+            sp1.commit(1)
+            collect(sp1)
+            sp2 = space.clone()
+            sp2.commit(2)
+            collect(sp2)

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	Fri Mar 10 12:51:56 2006
@@ -5,7 +5,11 @@
 import computationspace as space
 import distributor as di
 import problems
-from py.test import raises
+try:
+    from py.test import raises
+except ImportError:
+    def raises(*args):
+        pass
 
 #-- utility ---------------------
 
@@ -341,133 +345,6 @@
         assert varset == set([x, y, z, w])
         assert constset == set([k1, k2])
 
-    def test_store_satisfiable_success(self):
-        sp = newspace()
-        x,y,z = sp.var('x'), sp.var('y'), sp.var('z')
-        sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        k = c.Expression(sp, [x, y, z], 'x == y + z')
-        sp.add_expression(k)
-        assert sp.satisfiable(k) == True
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        
-    def test_store_satisfiable_failure(self):
-        sp = newspace()
-        x,y,z = sp.var('x'), sp.var('y'), sp.var('z')
-        sp.set_dom(x, c.FiniteDomain([1, 2]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        k = c.Expression(sp, [x, y, z], 'x == y + z')
-        sp.add_expression(k)
-        assert sp.satisfiable(k) == False
-        assert sp.dom(x) == c.FiniteDomain([1, 2])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-
-    def test_satisfiable_many_const_success(self):
-        sp = newspace()
-        x,y,z,w = (sp.var('x'), sp.var('y'),
-                   sp.var('z'), sp.var('w'))
-        sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        sp.set_dom(w, c.FiniteDomain([1, 4, 5]))
-        k1 = c.Expression(sp, [x, y, z], 'x == y + z')
-        k2 = c.Expression(sp, [z, w], 'z < w')
-        sp.add_expression(k1)
-        sp.add_expression(k2)
-        assert sp.satisfiable(k1) == True
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1, 4, 5])
-        assert sp.satisfiable(k2) == True
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1, 4, 5])
-        narrowed_doms = sp.get_satisfying_domains(k1)
-        assert narrowed_doms == {x:c.FiniteDomain([5]),
-                                 y:c.FiniteDomain([2]),
-                                 z:c.FiniteDomain([3]),
-                                 w:c.FiniteDomain([4, 5])}
-        narrowed_doms = sp.get_satisfying_domains(k2)
-        assert narrowed_doms == {x:c.FiniteDomain([5]),
-                                 y:c.FiniteDomain([2]),
-                                 z:c.FiniteDomain([3]),
-                                 w:c.FiniteDomain([4, 5])}
-
-
-    def test_satisfiable_many_const_failure(self):
-        sp = newspace()
-        x,y,z,w = (sp.var('x'), sp.var('y'),
-                   sp.var('z'), sp.var('w'))
-        sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        sp.set_dom(w, c.FiniteDomain([1]))
-        k1 = c.Expression(sp, [x, y, z], 'x == y + z')
-        k2 = c.Expression(sp, [z, w], 'z < w')
-        sp.add_expression(k1)
-        sp.add_expression(k2)
-        assert sp.satisfiable(k1) == False
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1])
-        assert sp.satisfiable(k2) == False
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1])
-        narrowed_doms = sp.get_satisfying_domains(k1)
-        assert narrowed_doms == {}
-        narrowed_doms = sp.get_satisfying_domains(k2)
-        assert narrowed_doms == {}
-
-    def test_satisfy_many_const_failure(self):
-        sp = newspace()
-        x,y,z,w = (sp.var('x'), sp.var('y'),
-                   sp.var('z'), sp.var('w'))
-        sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        sp.set_dom(w, c.FiniteDomain([1]))
-        k1 = c.Expression(sp, [x, y, z], 'x == y + z')
-        k2 = c.Expression(sp, [z, w], 'z < w')
-        sp.add_expression(k1)
-        sp.add_expression(k2)
-        raises(space.ConsistencyFailure, sp.satisfy, k1)
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1])
-        raises(space.ConsistencyFailure, sp.satisfy, k2)
-        assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
-        assert sp.dom(y) == c.FiniteDomain([2, 3])
-        assert sp.dom(z) == c.FiniteDomain([3, 4])
-        assert sp.dom(w) == c.FiniteDomain([1])
-        
-    def test_satisfy_many_const_success(self):
-        sp = newspace()
-        x,y,z,w = (sp.var('x'), sp.var('y'),
-                   sp.var('z'), sp.var('w'))
-        sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
-        sp.set_dom(y, c.FiniteDomain([2, 3]))
-        sp.set_dom(z, c.FiniteDomain([3, 4]))
-        sp.set_dom(w, c.FiniteDomain([1, 4, 5]))
-        k1 = c.Expression(sp, [x, y, z], 'x == y + z')
-        k2 = c.Expression(sp, [z, w], 'z < w')
-        sp.add_expression(k1)
-        sp.add_expression(k2)
-        sp.satisfy(k2)
-        assert sp.dom(x) == c.FiniteDomain([5])
-        assert sp.dom(y) == c.FiniteDomain([2])
-        assert sp.dom(z) == c.FiniteDomain([3])
-        assert sp.dom(w) == c.FiniteDomain([4, 5])
 
 #-- computation spaces -------------------------------
 
@@ -483,40 +360,11 @@
         assert '__root__' in spc.names
         assert set(['x', 'y', 'z']) == \
                set([var.name for var in spc.root.val])
-
-# we need to carefully craft some noop problems
-# for these tests
-# also what is tested below is tested in other places
-# so me might want to just forget about it
-
-##     def test_ask_success(self):
-##         spc = newspace(problems.one_solution_problem)
-##         assert spc.ask() == space.Succeeded
-##         assert spc.ask() == space.Succeeded
         
-##     def test_ask_failure(self):
-##         spc = newspace(problems.unsatisfiable_problem)
-##         assert spc.ask() == space.Failed
-
     def test_ask_alternatives(self):
         spc = newspace(problems.satisfiable_problem)
         assert spc.ask() == space.Alternative(2)
 
-##     def test_clone_and_process(self):
-##         spc = newspace(problems.satisfiable_problem)
-##         assert spc.ask() == space.Alternative(2)
-##         new_spc = spc.clone()
-##         #assert spc == new_spc
-##         assert new_spc.parent == spc
-##         # following couple of ops superceeded by inject()
-##         x, y, z = new_spc.find_vars('x', 'y', 'z')
-##         new_spc.add_constraint([x], 'x == 0')
-##         new_spc.add_constraint([z, y], 'z == y')
-##         new_spc.add_constraint([y], 'y < 2')
-##         new_spc._process()
-##         assert spc.ask() == space.Alternative(2)
-##         assert new_spc.ask() == space.Succeeded
-
     def test_clone(self):
         """checks that a chain of initially s1 = s2
            s1 - commit(1) - commit(1) ...
@@ -536,8 +384,6 @@
             #assert s1 == s2
             temp = s2.clone()
             temp.ask()
-            assert temp.parent is s2
-            assert temp in s2.children
             s2 = temp
             s1.commit(1)
             s2.commit(1)
@@ -578,30 +424,37 @@
     def test_scheduling_dfs_one_solution(self):
         sol = strategies.dfs_one(problems.conference_scheduling)
 
-        vars = sol.keys()
-        vars.sort()
-        sols = [ sol[k] for k in vars ]
-        result = [('room A', 'day 1 PM'),
-                  ('room A', 'day 2 AM'),
-                  ('room C', 'day 2 PM'),
-                  ('room C', 'day 2 AM'),
-                  ('room C', 'day 1 AM'),
-                  ('room C', 'day 1 PM'),
-                  ('room B', 'day 2 AM'),
-                  ('room B', 'day 1 AM'),
-                  ('room B', 'day 2 PM'),
-                  ('room A', 'day 1 AM'),
-                  ]
-
-        for v, r1, r2 in zip(vars, sols, result):
-            print v, r1, r2
-        assert sols == result
-
+        spc = space.ComputationSpace(problems.conference_scheduling)
+        assert spc.test_solution( sol )
+        
 
-    def test_scheduling_all_solutions(self):
+    def test_scheduling_all_solutions_dfs(self):
         sols = strategies.solve_all(problems.conference_scheduling)
         assert len(sols) == 64
-        print sols
+        spc = space.ComputationSpace(problems.conference_scheduling)
+        for s in sols:
+            assert spc.test_solution( s )
+            
+
+    def test_scheduling_all_solutions_lazily_dfs(self):
+        sp = space.ComputationSpace(problems.conference_scheduling)
+        for sol in strategies.lazily_solve_all(sp):
+            assert sp.test_solution(sol)
+
+    def test_scheduling_all_solutions_bfs(self):
+        sols = strategies.solve_all(problems.conference_scheduling,
+                                    direction=strategies.Breadth)
+        assert len(sols) == 64
+        spc = space.ComputationSpace(problems.conference_scheduling)
+        for s in sols:
+            assert spc.test_solution( s )
+            
+
+    def test_scheduling_all_solutions_lazily_bfs(self):
+        sp = space.ComputationSpace(problems.conference_scheduling)
+        for sol in strategies.lazily_solve_all(sp, direction=strategies.Breadth):
+            assert sp.test_solution(sol)
+
 
     def no_test_sudoku(self):
         #spc = newspace(problems.sudoku)
@@ -625,16 +478,3 @@
         sol2 = strategies.dfs_one(strategies.sudoku)
         print "done dfs"
         #sol2 = [var.val for var in sol]
-        assert sol2 == [('room A', 'day 1 PM'),
-                        ('room B', 'day 2 PM'),
-                        ('room C', 'day 2 AM'),
-                        ('room C', 'day 2 PM'),
-                        ('room C', 'day 1 AM'),
-                        ('room C', 'day 1 PM'),
-                        ('room A', 'day 2 PM'),
-                        ('room B', 'day 1 AM'),
-                        ('room A', 'day 2 AM'),
-                        ('room A', 'day 1 AM')]
-
-
-        

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	Fri Mar 10 12:51:56 2006
@@ -73,9 +73,9 @@
             self._value_condition.acquire()
             while not self.is_bound():
                 t1 = time.time()
-                self._value_condition.wait(80)
+                self._value_condition.wait(120)
                 t2 = time.time()
-                if t2-t1>80:
+                if t2-t1>120:
                     raise RuntimeError("possible deadlock??")
             return self.val
         finally:



More information about the Pypy-commit mailing list