[pypy-svn] r25792 - in pypy/dist/pypy/objspace/constraint: . applevel test

auc at codespeak.net auc at codespeak.net
Thu Apr 13 15:43:50 CEST 2006


Author: auc
Date: Thu Apr 13 15:43:48 2006
New Revision: 25792

Modified:
   pypy/dist/pypy/objspace/constraint/applevel/problems.py
   pypy/dist/pypy/objspace/constraint/applevel/solver.py
   pypy/dist/pypy/objspace/constraint/computationspace.py
   pypy/dist/pypy/objspace/constraint/constraint.py
   pypy/dist/pypy/objspace/constraint/test/test_solver.py
Log:
solver basically working - but beware AllDistinct weirdness


Modified: pypy/dist/pypy/objspace/constraint/applevel/problems.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/applevel/problems.py	(original)
+++ pypy/dist/pypy/objspace/constraint/applevel/problems.py	Thu Apr 13 15:43:48 2006
@@ -5,6 +5,8 @@
     return (ret,)
 
 def send_more_money(computation_space):
+    #FIXME: this problem needs propagators for integer finite domains
+    #       performance is terrible without it
     cs = computation_space
 
     variables = (s, e, n, d, m, o, r, y) = cs.make_vars('s', 'e', 'n', 'd', 'm', 'o', 'r', 'y')
@@ -40,7 +42,6 @@
     variables = [cs.var(v, FiniteDomain(dom_values))
                  for v in ('c01','c02','c03','c04','c05',
                            'c06','c07','c08','c09','c10')]
-
     for conf in ('c03','c04','c05','c06'):
         v = cs.find_var(conf)
         cs.tell(make_expression([v], "%s[0] == 'room C'" % conf))
@@ -58,11 +59,18 @@
               ('c03','c05','c06','c07'),
               ('c01','c03','c07','c08'))
 
-    for group in groups:
-        cs.tell(AllDistinct([cs.find_var(v) for v in group]))
+##     for group in groups:
+##         cs.tell(AllDistinct([cs.find_var(v) for v in group]))
 ##         cs.add_expression(AllDistinct(cs, tuple([cs.find_var(v)
 ##                                       for v in group])))
 
+    for group in groups:
+        for conf1 in group:
+            for conf2 in group:
+                v1, v2 = cs.find_vars((conf1, conf2))
+                if conf2 > conf1:
+                    cs.tell(make_expression([v1, v2], '%s[1] != %s[1]'% (v1.name(),v2.name())))
+
 ##     for g in groups:
 ##         for conf1 in g:
 ##             for conf2 in g:

Modified: pypy/dist/pypy/objspace/constraint/applevel/solver.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/applevel/solver.py	(original)
+++ pypy/dist/pypy/objspace/constraint/applevel/solver.py	Thu Apr 13 15:43:48 2006
@@ -22,20 +22,21 @@
         def collect(space):
             sp_stack.appendleft(space)
 
+    print "ready to find solution ..."
     while len(sp_stack):
         space = sp_stack.pop()
-        print ' '*len(sp_stack), "ask ..."
+        print ' '*len(sp_stack), "ask [depth = %s]" % len(sp_stack)
         status = space.ask()
         if status == 1:
             print ' '*len(sp_stack), "solution !"
             yield space.merge()
         elif status > 1:
-            print ' '*len(sp_stack), "branches ..."
-            sp1 = space.clone()
-            sp1.commit(1)
-            collect(sp1)
-            sp2 = space.clone()
-            sp2.commit(2)
-            collect(sp2)
+            print ' '*len(sp_stack), "%s branches ..." % status
+            for i in range(status):
+                clone = space.clone()
+                clone.commit(status-i)
+                collect(clone)
+        elif status == 0:
+            print ' '*len(sp_stack), "dead-end"
 
 solve = lazily_iter_solve_all

Modified: pypy/dist/pypy/objspace/constraint/computationspace.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/computationspace.py	(original)
+++ pypy/dist/pypy/objspace/constraint/computationspace.py	Thu Apr 13 15:43:48 2006
@@ -98,7 +98,6 @@
             self.distributor.find_distribution_variable(self)
         except: # FIXME: indexError ?
             self.status = self._space.newint(1)
-            self.w_print_state()
             return self.status
         self.status = self._space.newint(self.distributor.fanout)
         return self.status
@@ -112,11 +111,10 @@
         # keep track of constraint check-list
         for const in self.to_check:
             new.to_check[const] = True
-        # copy the var->const mapping
-        for var, const in self.var_const.items():
-            new.var_const[var] = const
         # share other stateless stuff
+        # this sharing will pose problems ...
         new.constraints = self.constraints
+        new.var_const = self.var_const
         new.name_var = self.name_var
         new.sol_set = self.sol_set
         return new
@@ -143,6 +141,12 @@
     def w_find_var(self, w_name):
         return self.name_var[self._space.str_w(w_name)]
 
+    def w_find_vars(self, w_vars):
+        res = []
+        for var in w_vars.wrappeditems:
+            res.append(self.w_find_var(var))
+        return self._space.newlist(res)
+
     def w_dom(self, w_variable):
         assert isinstance(w_variable, W_Variable)
         return self.var_dom[w_variable]
@@ -167,6 +171,18 @@
             res.append(self.var_dom[var].get_values()[0])
         return self._space.newtuple(res)
 
+    def w_test_solution(self, w_sol):
+        varset = {}
+        for var, val in zip(self.sol_set.wrappeditems,
+                            w_sol.wrappeditems):
+            varset[var.w_name] = val
+        for _const in self.constraints:
+            if not _const.test_solution(varset):
+                print "Solution", sol, "doesn't satisfy", _const
+                return self._space.newbool(False)
+        return self._space.newbool(True)
+
+
     def w_print_state(self):
         print "VARS  :", self.name_var.keys()
         print "CONST :", self.var_const.values()
@@ -218,6 +234,7 @@
     "W_ComputationSpace",
     var = interp2app(W_ComputationSpace.w_var),
     find_var = interp2app(W_ComputationSpace.w_find_var),
+    find_vars = interp2app(W_ComputationSpace.w_find_vars),
     dom = interp2app(W_ComputationSpace.w_dom),
     tell = interp2app(W_ComputationSpace.w_tell),
     ask = interp2app(W_ComputationSpace.w_ask),
@@ -226,6 +243,7 @@
     merge = interp2app(W_ComputationSpace.w_merge),
     dependant_constraints = interp2app(W_ComputationSpace.w_dependant_constraints),
     define_problem = interp2app(W_ComputationSpace.w_define_problem),
+    test_solution = interp2app(W_ComputationSpace.w_test_solution),
     print_state = interp2app(W_ComputationSpace.w_print_state))
 
 def newspace(object_space):

Modified: pypy/dist/pypy/objspace/constraint/constraint.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/constraint.py	(original)
+++ pypy/dist/pypy/objspace/constraint/constraint.py	Thu Apr 13 15:43:48 2006
@@ -85,7 +85,7 @@
         assert isinstance(w_cs, W_ComputationSpace)
         return self.__cost
 
-    def test_solution(self, sol):
+    def test_solution(self, w_sol):
         """test a solution against this constraint
         accept a mapping of variable names to value"""
         values = sol.items()
@@ -103,7 +103,7 @@
         # then the value must be removed from the other domains
         for size, var, dom in variables:
             if self._space.eq_w(dom.w_size(), self._space.newint(1)):
-                print "AllDistinct removes values"
+                #print "AllDistinct removes values"
                 for _siz, _var, _dom in variables:
                     if not self._space.eq_w(_var, var):
                         try:
@@ -119,7 +119,7 @@
             for val in dom.w_get_values().wrappeditems:
                 values[val] = 0
         if len(values) < len(variables):
-            print "AllDistinct failed"
+            #print "AllDistinct failed"
             raise OperationError(self._space.w_RuntimeError,
                                  self._space.wrap("Consistency Failure"))
 
@@ -163,13 +163,13 @@
         self.formula = self._space.str_w(w_formula)
         self.filter_func = make_filter(self._space, w_variables, w_formula)
 
-    def test_solution(self, sol ):
+    def test_solution(self, sol_dict):
         """test a solution against this constraint 
         accept a mapping of variable names to value"""
         args = []
         for var in self._variables:
-            args.append( sol[var.w_name] )
-        return self.filterFunc( *args )
+            args.append(sol_dict[var.w_name])
+        return self.filter_func(*args)
 
     def _init_result_cache(self):
         """key = (variable,value), value = [has_success,has_failure]"""

Modified: pypy/dist/pypy/objspace/constraint/test/test_solver.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/test/test_solver.py	(original)
+++ pypy/dist/pypy/objspace/constraint/test/test_solver.py	Thu Apr 13 15:43:48 2006
@@ -9,9 +9,19 @@
         from pypy.objspace.constraint.applevel import solver, problems
         spc = newspace()
 
-        spc.set_root(problems.conference_scheduling(spc))
-        #FIXME: that 'interation over non-sequence' kills me ...
-        #spc.define_problem(problems.conference_scheduling)
+        spc.define_problem(problems.conference_scheduling)
         
         sols = solver.solve(spc)
         assert str(type(sols)) == "<type 'generator'>"
+
+    def test_solve(self):
+        from pypy.objspace.constraint.applevel import solver, problems
+        spc = newspace()
+
+        spc.define_problem(problems.conference_scheduling)
+        
+        sols = solver.solve(spc)
+        count = 0
+        for sol in sols:
+            count += 1
+        assert count == 64



More information about the Pypy-commit mailing list