[pypy-svn] r25490 - in pypy/dist/pypy/objspace/constraint: . test
afayolle at codespeak.net
afayolle at codespeak.net
Fri Apr 7 12:46:05 CEST 2006
Author: afayolle
Date: Fri Apr 7 12:46:04 2006
New Revision: 25490
Added:
pypy/dist/pypy/objspace/constraint/test/test_constraint.py (contents, props changed)
Modified:
pypy/dist/pypy/objspace/constraint/constraint.py
Log:
can now call AllDistinct.affected_variables
Modified: pypy/dist/pypy/objspace/constraint/constraint.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/constraint.py (original)
+++ pypy/dist/pypy/objspace/constraint/constraint.py Fri Apr 7 12:46:04 2006
@@ -1,4 +1,14 @@
-from variable import NoDom
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter import baseobjspace, typedef, gateway
+from pypy.interpreter.gateway import interp2app
+
+from pypy.objspace.std.listobject import W_ListObject
+
+
+from pypy.objspace.constraint.computationspace import W_ComputationSpace
+
+#from variable import NoDom
import operator
#-- Exceptions ---------------------------------------
@@ -14,29 +24,60 @@
#-- Constraints ------------------------------------------
-class AbstractConstraint(object):
+class W_Constraint(Wrappable):
+ def __init__(self, object_space, computation_space):
+ self._space = object_space
+ assert isinstance(computation_space, W_ComputationSpace)
+ self.cs = computation_space
+
+ def w_affected_variables(self):
+ pass
+
+ def w_is_variable_relevant(self, w_var):
+ pass
+
+ def w_estimate_cost(self):
+ pass
+
+ def w_copy_to(self, w_computation_space):
+ pass
+
+ def w_revise(self):
+ pass
+
+W_Constraint.typedef = typedef.TypeDef(
+ "W_Constraint",
+ affected_variables = interp2app(W_Constraint.w_affected_variables),
+ is_variable_relevant = interp2app(W_Constraint.w_is_variable_relevant),
+ estimate_cost = interp2app(W_Constraint.w_estimate_cost),
+ copy_to = interp2app(W_Constraint.w_copy_to),
+ revise = interp2app(W_Constraint.w_revise)
+ )
+
+
+class W_AbstractConstraint(W_Constraint):
- def __init__(self, c_space, variables):
+ def __init__(self, object_space, c_space, w_variables):
"""variables is a list of variables which appear in the formula"""
- self.cs = c_space
+ W_Constraint.__init__(self, object_space, c_space)
+ assert isinstance(w_variables, W_ListObject)
+ assert self._space.is_true(self._space.gt(self._space.len(w_variables), self._space.newint(1)))
self._names_to_vars = {}
- for var in variables:
- if self.cs.dom(var) == NoDom:
- raise DomainlessVariables
+ for var in w_variables.wrappeditems:
self._names_to_vars[var.name] = var
- self._variables = variables
+ self._variables = w_variables
- def affected_variables(self):
+ def w_affected_variables(self):
""" Return a list of all variables affected by this constraint """
return self._variables
- def isVariableRelevant(self, variable):
+ def w_is_variable_relevant(self, w_variable):
return variable in self._variables
- def estimate_cost(self):
+ def w_estimate_cost(self):
"""Return an estimate of the cost of the narrowing of the constraint"""
return reduce(operator.mul,
- [self.cs.dom(var).size() for var in self._variables])
+ [self.cs.w_dom(var).size() for var in self._variables])
def copy_to(self, space):
return self.__class__(space, self._variables)
@@ -45,15 +86,22 @@
if not isinstance(other, self.__class__): return False
return self._variables == other._variables
-
-class W_BasicConstraint(object):
+W_AbstractConstraint.typedef = typedef.TypeDef("W_AbstractConstraint",
+ affected_variables = interp2app(W_AbstractConstraint.w_affected_variables),
+ is_variable_relevant = interp2app(W_AbstractConstraint.w_is_variable_relevant),
+ estimate_cost = interp2app(W_AbstractConstraint.w_estimate_cost),
+ copy_to = interp2app(W_AbstractConstraint.w_copy_to),
+ revise = interp2app(W_AbstractConstraint.w_revise)
+)
+class W_BasicConstraint(W_Constraint):
"""A BasicConstraint, which is never queued by the Repository
A BasicConstraint affects only one variable, and will be entailed
on the first call to narrow()"""
- def __init__(self, variable, reference, operator):
+ def __init__(self, object_space, variable, reference, operator):
"""variables is a list of variables on which
the constraint is applied"""
+ W_Constraint.__init__(self, object_space)
self._variable = variable
self._reference = reference
self._operator = operator
@@ -61,22 +109,22 @@
def __repr__(self):
return '<%s %s %s>'% (self.__class__, self._variable, self._reference)
- def copy_to(self, space):
+ def w_copy_to(self, w_computation_space):
raise NotImplementedError
- def isVariableRelevant(self, variable):
+ def w_is_variable_relevant(self, w_variable):
return variable == self._variable
- def estimateCost(self, domains):
+ def w_estimate_cost(self):
return 0 # get in the first place in the queue
- def affectedVariables(self):
+ def w_affected_variables(self):
return [self._variable]
def getVariable(self):
return self._variable
- def revise(self, domains):
+ def w_revise(self, w_domains):
domain = domains[self._variable]
operator = self._operator
ref = self._reference
@@ -92,6 +140,15 @@
def __eq__(self, other):
raise NotImplementedError
+W_BasicConstraint.typedef = typedef.TypeDef(
+ "W_BasicConstraint",
+ affected_variables = interp2app(W_BasicConstraint.w_affected_variables),
+ is_variable_relevant = interp2app(W_BasicConstraint.w_is_variable_relevant),
+ estimate_cost = interp2app(W_BasicConstraint.w_estimate_cost),
+ copy_to = interp2app(W_BasicConstraint.w_copy_to),
+ revise = interp2app(W_BasicConstraint.w_revise)
+ )
+
def make_lambda_head(vars):
var_ids = ','.join([var.name for var in vars])
return 'lambda ' + var_ids + ':'
@@ -102,22 +159,22 @@
return expr
-class AllDistinct(AbstractConstraint):
+class W_AllDistinct(W_AbstractConstraint):
"""Contraint: all values must be distinct"""
- def __init__(self, c_space, variables):
- assert len(variables)>1
- AbstractConstraint.__init__(self, c_space, variables)
+ def __init__(self, object_space, w_c_space, w_variables):
+ W_AbstractConstraint.__init__(self, object_space, w_c_space, w_variables)
+ assert len(w_variables.wrappeditems)>1
# worst case complexity
- self.__cost = len(variables) * (len(variables) - 1) / 2
+ self.__cost = len(w_variables.wrappeditems) * (len(w_variables.wrappeditems) - 1) / 2
def __repr__(self):
return '<AllDistinct %s>' % str(self._variables)
- def copy_to(self, space):
+ def w_copy_to(self, w_computation_space):
return self.__class__(space, self._variables)
- def estimateCost(self, domains):
+ def w_estimate_cost(self):
return self.__cost
def test_solution(self, sol):
@@ -127,9 +184,9 @@
value_set = set(values)
return len(value_set) == len(sol)
- def revise(self):
- variables = [(self.cs.dom(variable).size(),
- variable, self.cs.dom(variable))
+ def w_revise(self):
+ variables = [(self.cs.w_dom(variable).size(),
+ variable, self.cs.w_dom(variable))
for variable in self._variables]
variables.sort()
@@ -166,8 +223,18 @@
return 1
+W_AllDistinct.typedef = typedef.TypeDef(
+ "W_AllDistinct", W_AbstractConstraint.typedef,
+ estimate_cost = interp2app(W_AllDistinct.w_estimate_cost),
+ revise = interp2app(W_Constraint.w_revise)
+ )
+
+# function bolted into the space to serve as constructor
+def make_alldistinct(objectspace, w_computationspace, w_variables):
+ return objectspace.wrap(W_AllDistinct(objectspace, w_computationspace, w_variables))
+app_make_alldistinct = gateway.interp2app(make_alldistinct)
-class Expression(AbstractConstraint):
+class W_Expression(W_AbstractConstraint):
"""A constraint represented as a python expression."""
_FILTER_CACHE = {}
@@ -209,9 +276,9 @@
variables = []
kwargs = {}
for variable in self._variables:
- domain = self.cs.dom(variable)
- values = domain.get_values()
- variables.append((domain.size(), [variable, values, 0, len(values)]))
+ domain = self.cs.w_dom(variable)
+ values = domain.w_get_values()
+ variables.append((domain.w_size(), [variable, values, 0, len(values)]))
kwargs[variable.name] = values[0]
# sort variables to instanciate those with fewer possible values first
variables.sort()
@@ -253,7 +320,7 @@
try:
for var, keep in result_cache.iteritems():
- domain = self.cs.dom(self._names_to_vars[var])
+ domain = self.cs.w_dom(self._names_to_vars[var])
domain.remove_values([val for val in domain if val not in keep])
except ConsistencyFailure:
@@ -275,7 +342,11 @@
def __repr__(self):
return '<%s>' % self.formula
-class BinaryExpression(Expression):
+W_Expression.typedef = typedef.TypeDef("W_Expression",
+ W_AbstractConstraint.typedef)
+
+
+class BinaryExpression(W_Expression):
"""A binary constraint represented as a python expression
This implementation uses a narrowing algorithm optimized for
Added: pypy/dist/pypy/objspace/constraint/test/test_constraint.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/constraint/test/test_constraint.py Fri Apr 7 12:46:04 2006
@@ -0,0 +1,19 @@
+from pypy.conftest import gettestobjspace
+
+class AppTest_AllDistinct(object):
+
+ def setup_class(cls):
+ cls.space = gettestobjspace('logic')
+
+
+ def test_instantiate(self):
+ cspace = newspace()
+ v1 = cspace.var('v1', FiniteDomain([1,2]))
+ v2 = cspace.var('v2', FiniteDomain([1,2]))
+ cstr = AllDistinct(cspace, [v1, v2])
+ variables = cstr.affected_variables()
+ assert variables is not None
+ print variables
+ assert len(variables) == 2
+ assert v1 in variables
+ assert v2 in variables
More information about the Pypy-commit
mailing list