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

auc at codespeak.net auc at codespeak.net
Tue Jan 24 11:24:02 CET 2006


Author: auc
Date: Tue Jan 24 11:23:58 2006
New Revision: 22577

Modified:
   pypy/dist/pypy/lib/logic/constraint.py
   pypy/dist/pypy/lib/logic/test_unification.py
   pypy/dist/pypy/lib/logic/unification.py
Log:
(auc, ale)
* add constraints to the store
* twists to constraints to make them accept our variables


Modified: pypy/dist/pypy/lib/logic/constraint.py
==============================================================================
--- pypy/dist/pypy/lib/logic/constraint.py	(original)
+++ pypy/dist/pypy/lib/logic/constraint.py	Tue Jan 24 11:23:58 2006
@@ -1,11 +1,16 @@
 # a) new requirement : be able to postpone asking fo the
 # values of the domain
 
+#-- Exceptions ---------------------------------------
+
 class ConsistencyFailure(Exception):
     """The repository is not in a consistent state"""
     pass
 
-
+class DomainlessVariables(Exception):
+    """A constraint can't be defined on variables
+       without a domain"""
+    pass
 
 #-- Domains --------------------------------------------
 
@@ -110,15 +115,17 @@
 #-- Constraints ------------------------------------------
 
 class AbstractConstraint(object):
-    #__implements__ = ConstraintInterface
     
     def __init__(self, variables):
         """variables is a list of variables which appear in the formula"""
+        for var in variables:
+            if var.dom is None:
+                raise DomainlessVariables
         self._variables = variables
 
     def affectedVariables(self):
         """ Return a list of all variables affected by this constraint """
-        return self._variabl
+        return self._variables
 
     def isVariableRelevant(self, variable):
         return variable in self._variables
@@ -170,6 +177,14 @@
         return 1
 
 
+def make_lambda_head(vars):
+    var_ids = ','.join([var.name for var in vars])
+    return 'lambda ' + var_ids + ':'
+
+def expand_expr_template(expr, vars):
+    for var in vars:
+        expr.replace(var.name, var.name + '.val')
+    return expr
 
 class Expression(AbstractConstraint):
     """A constraint represented as a python expression."""
@@ -184,8 +199,8 @@
         try:
             self.filterFunc = Expression._FILTER_CACHE[formula]
         except KeyError:
-            self.filterFunc = eval('lambda %s: %s' % \
-                                        (','.join(variables), formula), {}, {})
+            self.filterFunc = eval(make_lambda_head(variables) \
+                                   + expand_expr_template(formula, variables), {}, {})
             Expression._FILTER_CACHE[formula] = self.filterFunc
 
     def _init_result_cache(self):

Modified: pypy/dist/pypy/lib/logic/test_unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/test_unification.py	(original)
+++ pypy/dist/pypy/lib/logic/test_unification.py	Tue Jan 24 11:23:58 2006
@@ -1,6 +1,6 @@
 import unification as u
 import variable as v
-from constraint import FiniteDomain
+import constraint as c
 from py.test import raises, skip
 from threading import Thread
 
@@ -192,8 +192,7 @@
     def test_set_var_domain(self):
         x = u.var('x')
         u.set_domain(x, [1, 3, 5])
-        assert x.dom == FiniteDomain([1, 3, 5])
-        assert u._store.domains[x] == FiniteDomain([1, 3, 5])
+        assert x.dom == c.FiniteDomain([1, 3, 5])
 
     def test_bind_with_domain(self):
         x = u.var('x')
@@ -222,4 +221,15 @@
         u.set_domain(z, [41, 42, 43])
         u.unify(x, y)
         assert z.val == 42
-        assert z.dom == FiniteDomain([41, 42, 43])
+        assert z.dom == c.FiniteDomain([41, 42, 43])
+
+    def test_add_constraint(self):
+        x,y,z = u.var('x'), u.var('y'), u.var('z')
+        raises(c.DomainlessVariables,
+               c.Expression, [x, y, z], 'x == y + z')
+        x.dom = c.FiniteDomain([1, 2])
+        y.dom = c.FiniteDomain([2, 3])
+        z.dom = c.FiniteDomain([3, 4])
+        k = c.Expression([x, y, z], 'x == y + z')
+        u.add_constraint(k)
+        assert k in u._store.constraints

Modified: pypy/dist/pypy/lib/logic/unification.py
==============================================================================
--- pypy/dist/pypy/lib/logic/unification.py	(original)
+++ pypy/dist/pypy/lib/logic/unification.py	Tue Jan 24 11:23:58 2006
@@ -172,10 +172,8 @@
         # mapping of names to vars (all of them)
         self.vars = set()
         self.names = set()
-        # mapping of vars to domains
-        self.domains = {}
-        # mapping of names to constraints (all...)
-        self.contraints = {}
+        # set of all constraints 
+        self.constraints = set()
         # consistency-preserving stuff
         self.in_transaction = False
         self.lock = threading.RLock()
@@ -197,7 +195,11 @@
         if var.is_bound():
             raise AlreadyBound
         var.dom = FiniteDomain(dom)
-        self.domains[var] = var.dom
+    
+    #-- Add constraints -------------------------
+
+    def add_constraint(self, constraint):
+        self.constraints.add(constraint)
 
     #-- BIND -------------------------------------------
 
@@ -418,6 +420,9 @@
 def set_domain(var, dom):
     return _store.set_domain(var, dom)
 
+def add_constraint(constraint):
+    return _store.add_constraint(constraint)
+
 def bind(var, val):
     return _store.bind(var, val)
 



More information about the Pypy-commit mailing list