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

auc at codespeak.net auc at codespeak.net
Wed Apr 12 16:39:38 CEST 2006

```Author: auc
Date: Wed Apr 12 16:39:36 2006
New Revision: 25724

pypy/dist/pypy/objspace/constraint/applevel/
pypy/dist/pypy/objspace/constraint/applevel/problems.py
pypy/dist/pypy/objspace/constraint/applevel/solver.py
pypy/dist/pypy/objspace/constraint/test/test_solver.py
Modified:
pypy/dist/pypy/objspace/constraint/computationspace.py
pypy/dist/pypy/objspace/constraint/test/test_computationspace.py
Log:
solver instantiation

==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/constraint/applevel/problems.py	Wed Apr 12 16:39:36 2006
@@ -0,0 +1,108 @@
+
+def dummy_problem(computation_space):
+    ret = computation_space.var('__dummy__')
+    computation_space.set_dom(ret, c.FiniteDomain([]))
+    return (ret,)
+
+def send_more_money(computation_space):
+    cs = computation_space
+
+    variables = (s, e, n, d, m, o, r, y) = cs.make_vars('s', 'e', 'n', 'd', 'm', 'o', 'r', 'y')
+
+    digits = range(10)
+    for var in variables:
+        cs.set_dom(var, c.FiniteDomain(digits))
+
+    # use fd.AllDistinct
+    for v1 in variables:
+        for v2 in variables:
+            if v1 != v2:
+                                  '%s != %s' % (v1.name, v2.name))
+
+    # use fd.NotEquals
+    cs.add_constraint([s, e, n, d, m, o, r, y],
+                                   '1000*s+100*e+10*n+d+1000*m+100*o+10*r+e == 10000*m+1000*o+100*n+10*e+y')
+    cs.set_distributor(di.DichotomyDistributor(cs))
+    print cs.constraints
+    return (s, e, n, d, m, o, r, y)
+
+def conference_scheduling(computation_space):
+    cs = computation_space
+
+    dom_values = [(room,slot)
+          for room in ('room A','room B','room C')
+          for slot in ('day 1 AM','day 1 PM','day 2 AM',
+                       'day 2 PM')]
+
+    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))
+
+    for conf in ('c01','c05','c10'):
+        v = cs.find_var(conf)
+        cs.tell(make_expression([v], "%s[1].startswith('day 1')" % conf))
+
+    for conf in ('c02','c03','c04','c09'):
+        v = cs.find_var(conf)
+        cs.tell(make_expression([v], "%s[1].startswith('day 2')" % conf))
+
+    groups = (('c01','c02','c03','c10'),
+              ('c02','c06','c08','c09'),
+              ('c03','c05','c06','c07'),
+              ('c01','c03','c07','c08'))
+
+    for group in groups:
+        cs.tell(AllDistinct([cs.find_var(v) for v in group]))
+##                                       for v in group])))
+
+##     for g in groups:
+##         for conf1 in g:
+##             for conf2 in g:
+##                 v1, v2 = cs.find_vars(conf1, conf2)
+##                 if conf2 > conf1:
+##                     cs.add_constraint([v1,v2], '%s[1] != %s[1]'% (v1.name,v2.name))
+
+    for conf1 in variables:
+        for conf2 in variables:
+            if conf2 > conf1:
+                cs.tell(make_expression([conf1,conf2],
+                                        '%s != %s'%(conf1.name(),conf2.name())))
+    return variables
+
+def sudoku(computation_space):
+    cs = computation_space
+    import constraint as c
+
+    variables = [cs.var('v%i%i'%(x,y)) for x in range(1,10) for y in range(1,10)]
+
+    # Make the variables
+    for v in variables:
+        cs.set_dom(v, c.FiniteDomain(range(1,10)))
+    # Add constraints for rows (sum should be 45)
+    for i in range(1,10):
+        row = [ v for v in variables if v.name[1] == str(i)]
+        cs.add_constraint(row, 'sum([%s]) == 45' % ', '.join([v.name for v in row]))
+    # Add constraints for columns (sum should be 45)
+    for i in range(1,10):
+        row = [ v for v in variables if v.name[2] == str(i)]
+        cs.add_constraint(row, 'sum([%s]) == 45' % ', '.join([v.name for v in row]))
+    # Add constraints for subsquares (sum should be 45)
+    offsets = [(r,c) for r in [-1,0,1] for c in [-1,0,1]]
+    subsquares = [(r,c) for r in [2,5,8] for c in [2,5,8]]
+    for rc in subsquares:
+        sub = [cs.find_var('v%d%d'% (rc[0] + off[0],rc[1] + off[1])) for off in offsets]
+        cs.add_constraint(sub, 'sum([%s]) == 45' % ', '.join([v.name for v in sub]))
+        for v in sub:
+            for m in sub[sub.index(v)+1:]:
+                cs.add_constraint([v,m], '%s != %s' % (v.name, m.name))
+    #print cs.constraints
+    return tuple(variables)
+

==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/constraint/applevel/solver.py	Wed Apr 12 16:39:36 2006
@@ -0,0 +1,41 @@
+
+class StrategyDistributionMismatch(Exception):
+    pass
+
+
+from collections import deque
+
+class Depth: pass
+
+#-- pythonic lazy solve_all (takes space)
+
+def lazily_iter_solve_all(space, direction=Depth):
+
+    sp_stack = deque([])
+    sp_stack.append(space)
+
+    if direction == Depth:
+        def collect(space):
+            sp_stack.append(space)
+    else:
+        def collect(space):
+            sp_stack.appendleft(space)
+
+    while len(sp_stack):
+        space = sp_stack.pop()
+        print ' '*len(sp_stack), "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)
+
+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	Wed Apr 12 16:39:36 2006
@@ -19,8 +19,13 @@

def name_w(self):
return self._space.str_w(self.w_name)
+
+    def w_name(self):
+        return self.w_name

-W_Variable.typedef = typedef.TypeDef("W_Variable")
+W_Variable.typedef = typedef.TypeDef(
+    "W_Variable",
+    name = interp2app(W_Variable.w_name))

#-- Constraints -------------------------

@@ -120,14 +125,18 @@
def w_var(self, w_name, w_domain):
assert isinstance(w_name, W_StringObject)
assert isinstance(w_domain, W_AbstractDomain)
-        if w_name in self.name_var:
+        name = self._space.str_w(w_name)
+        if name in self.name_var:
raise OperationError(self._space.w_RuntimeError,
var = W_Variable(self._space, w_name)
self.var_dom[var] = w_domain
-        self.name_var[w_name] = var
+        self.name_var[name] = var
return var

+    def w_find_var(self, w_name):
+        return self.name_var[self._space.str_w(w_name)]
+
def w_dom(self, w_variable):
assert isinstance(w_variable, W_Variable)
return self.var_dom[w_variable]
@@ -147,6 +156,9 @@
print "there"
self.sol_set = self._space.call(w_problem, self)

+    def w_set_root(self, w_solution_list):
+        self.sol_set = w_solution_list
+
#-- everything else ---------------

def dependant_constraints(self, var):
@@ -191,13 +203,15 @@
W_ComputationSpace.typedef = typedef.TypeDef(
"W_ComputationSpace",
var = interp2app(W_ComputationSpace.w_var),
+    find_var = interp2app(W_ComputationSpace.w_find_var),
dom = interp2app(W_ComputationSpace.w_dom),
tell = interp2app(W_ComputationSpace.w_tell),
clone = interp2app(W_ComputationSpace.w_clone),
commit = interp2app(W_ComputationSpace.w_commit),
dependant_constraints = interp2app(W_ComputationSpace.w_dependant_constraints),
-    define_problem = interp2app(W_ComputationSpace.w_define_problem))
+    define_problem = interp2app(W_ComputationSpace.w_define_problem),
+    set_root = interp2app(W_ComputationSpace.w_set_root))

def newspace(object_space):

Modified: pypy/dist/pypy/objspace/constraint/test/test_computationspace.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/test/test_computationspace.py	(original)
+++ pypy/dist/pypy/objspace/constraint/test/test_computationspace.py	Wed Apr 12 16:39:36 2006
@@ -16,7 +16,6 @@
assert str(v).startswith('<W_Variable object at')
raises(Exception, cspace.var, "foo", FiniteDomain([1,2,3]))

-
def test_dom(self):
cspace = newspace()
domain = FiniteDomain([1,2,3])

==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/constraint/test/test_solver.py	Wed Apr 12 16:39:36 2006
@@ -0,0 +1,17 @@
+from pypy.conftest import gettestobjspace
+
+class AppTest_Solver(object):
+
+    def setup_class(cls):
+        cls.space = gettestobjspace('logic')
+
+    def test_instantiate(self):
+        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)
+
+        sols = solver.solve(spc)
+        assert str(type(sols)) == "<type 'generator'>"

```