[pypy-svn] r25658 - in pypy/dist/pypy/objspace: . constraint constraint/test
auc at codespeak.net
auc at codespeak.net
Mon Apr 10 12:23:45 CEST 2006
Author: auc
Date: Mon Apr 10 12:23:42 2006
New Revision: 25658
Modified:
pypy/dist/pypy/objspace/constraint/computationspace.py
pypy/dist/pypy/objspace/constraint/constraint.py
pypy/dist/pypy/objspace/constraint/domain.py
pypy/dist/pypy/objspace/constraint/test/test_constraint.py
pypy/dist/pypy/objspace/constraint/test/test_fd.py
pypy/dist/pypy/objspace/logic.py
Log:
tries to avoid too much un/wrapping
Modified: pypy/dist/pypy/objspace/constraint/computationspace.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/computationspace.py (original)
+++ pypy/dist/pypy/objspace/constraint/computationspace.py Mon Apr 10 12:23:42 2006
@@ -15,10 +15,12 @@
class W_Variable(Wrappable):
def __init__(self, obj_space, w_name):
self._space = obj_space
- self.name = w_name
+ self.w_name = w_name
-W_Variable.typedef = typedef.TypeDef("W_Variable")
+ def name_w(self):
+ return self._space.str_w(self.w_name)
+W_Variable.typedef = typedef.TypeDef("W_Variable")
#-- Constraints -------------------------
@@ -35,9 +37,6 @@
def w_estimate_cost(self, w_cs):
pass
- def w_copy_to(self, w_computation_space):
- pass
-
def w_revise(self, w_cs):
pass
@@ -46,9 +45,7 @@
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)
- )
+ revise = interp2app(W_Constraint.w_revise))
#-- Computation space -------------------
@@ -69,7 +66,7 @@
def w_dom(self, w_variable):
assert isinstance(w_variable, W_Variable)
- return self.domains.content[w_variable.name]
+ return self.domains.content[w_variable.w_name]
def w_tell(self, w_constraint):
assert isinstance(w_constraint, W_Constraint)
Modified: pypy/dist/pypy/objspace/constraint/constraint.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/constraint.py (original)
+++ pypy/dist/pypy/objspace/constraint/constraint.py Mon Apr 10 12:23:42 2006
@@ -32,18 +32,19 @@
"""variables is a list of variables which appear in the formula"""
W_Constraint.__init__(self, object_space)
assert isinstance(w_variables, W_ListObject)
- assert self._space.is_true(self._space.ge(self._space.len(w_variables), self._space.newint(1)))
+ assert self._space.is_true(self._space.ge(self._space.len(w_variables),
+ self._space.newint(1)))
self._names_to_vars = {}
for var in w_variables.wrappeditems:
- self._names_to_vars[var.name] = var
- self._variables = w_variables
+ self._names_to_vars[var.name_w()] = var
+ self._variables = w_variables.wrappeditems #unwrap once ...
def w_affected_variables(self):
""" Return a list of all variables affected by this constraint """
- return self._variables
+ return self._space.newlist(self._variables)
- def w_is_variable_relevant(self, w_variable):
- return variable in self._variables
+ def w_knows_var(self, w_variable):
+ return self._space.newbool(variable in self._variables)
def w_estimate_cost(self, w_cs):
"""Return an estimate of the cost of the narrowing of the constraint"""
@@ -58,23 +59,9 @@
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),
+ knows_var = interp2app(W_AbstractConstraint.w_knows_var),
estimate_cost = interp2app(W_AbstractConstraint.w_estimate_cost),
- copy_to = interp2app(W_AbstractConstraint.w_copy_to),
- revise = interp2app(W_AbstractConstraint.w_revise)
-)
-
-
-
-def make_lambda_head(space, w_vars):
- var_ids = ','.join([space.str_w(var.name) for var in w_vars.wrappeditems])
- return 'lambda ' + var_ids + ':'
-
-def expand_expr_template(space, w_expr, w_vars):
- return space.str_w(w_expr)
- for w_var in w_vars.wrappeditems:
- expr.replace(w_var.name, w_var.name + '.val')
- return expr
+ revise = interp2app(W_AbstractConstraint.w_revise))
class W_AllDistinct(W_AbstractConstraint):
@@ -82,13 +69,9 @@
def __init__(self, object_space, w_variables):
W_AbstractConstraint.__init__(self, object_space, w_variables)
- assert len(w_variables.wrappeditems)>1
# worst case complexity
self.__cost = len(w_variables.wrappeditems) * (len(w_variables.wrappeditems) - 1) / 2
- def w__repr__(self):
- return self._space.newstring('<AllDistinct %s>' % str(self._variables))
-
def w_estimate_cost(self, w_cs):
assert isinstance(w_cs, W_ComputationSpace)
return self._space.newint(self.__cost)
@@ -104,7 +87,7 @@
assert isinstance(w_cs, W_ComputationSpace)
variables = [(self._space.int_w(w_cs.w_dom(variable).w_size()),
variable, w_cs.w_dom(variable))
- for variable in self._variables.wrappeditems]
+ for variable in self._variables]
variables.sort()
# if a domain has a size of 1,
@@ -145,53 +128,58 @@
W_AllDistinct.typedef = typedef.TypeDef(
"W_AllDistinct", W_AbstractConstraint.typedef,
estimate_cost = interp2app(W_AllDistinct.w_estimate_cost),
- revise = interp2app(W_AllDistinct.w_revise),
- __repr__ = interp2app(W_AllDistinct.w__repr__)
- )
+ revise = interp2app(W_AllDistinct.w_revise))
# function bolted into the space to serve as constructor
-def make_alldistinct(objectspace, w_variables):
- return objectspace.wrap(W_AllDistinct(objectspace, w_variables))
+def make_alldistinct(object_space, w_variables):
+ return object_space.wrap(W_AllDistinct(object_space, w_variables))
app_make_alldistinct = gateway.interp2app(make_alldistinct)
+
+def make_filter(object_space, w_variables, w_formula):
+ """NOT RPYTHON"""
+ var_ids = ','.join([object_space.str_w(var.w_name)
+ for var in w_variables.wrappeditems])
+ func_head = 'lambda ' + var_ids + ':'
+ func_obj = eval(func_head + object_space.str_w(w_formula), {}, {})
+ return func_obj
+app_make_filter = gateway.interp2app(make_filter)
+
class W_Expression(W_AbstractConstraint):
"""A constraint represented as a python expression."""
- _FILTER_CACHE = {}
- def __init__(self, o_space, w_variables, w_formula):
+ def __init__(self, object_space, w_variables, w_formula):
"""variables is a list of variables which appear in the formula
formula is a python expression that will be evaluated as a boolean"""
- self.formula = w_formula
- W_AbstractConstraint.__init__(self, o_space, w_variables)
- self.filter_func = eval(make_lambda_head(self._space, w_variables) \
- + self._space.str_w(w_formula), {}, {})
+ W_AbstractConstraint.__init__(self, object_space, w_variables)
+ self.formula = self._space.str_w(w_formula)
+ self.filter_func = make_filter(self._space, w_variables, w_formula)
def test_solution(self, sol ):
"""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] )
+ args.append( sol[var.w_name] )
return self.filterFunc( *args )
def _init_result_cache(self):
"""key = (variable,value), value = [has_success,has_failure]"""
result_cache = {}
- for var_name in self._variables.wrappeditems:
- result_cache[self._space.str_w(var_name.name)] = {}
+ for var in self._variables:
+ result_cache[var.name_w()] = {}
return result_cache
-
def _assign_values(self, w_cs):
variables = []
kwargs = {}
- for variable in self._variables.wrappeditems:
+ for variable in self._variables:
domain = w_cs.w_dom(variable)
values = domain.w_get_values()
variables.append((self._space.int_w(domain.w_size()),
[variable, values, 0,
self._space.len(values)]))
- kwargs[self._space.str_w(variable.name)] = values.wrappeditems[0]
+ kwargs[variable.name_w()] = values.wrappeditems[0]
# sort variables to instanciate those with fewer possible values first
variables.sort()
@@ -224,6 +212,8 @@
break
else:
continue
+ print kwargs.items()
+ print ffunc, kwargs.items()
if ffunc(**kwargs):
for var, val in kwargs.items():
result_cache[var][val] = 1
@@ -264,9 +254,6 @@
assert len(variables) == 2
Expression.__init__(self, variables, formula, type)
- def copy_to(self, space):
- raise NotImplementedError
-
def w_revise(self, domains):
"""specialized narrowing algorithm for binary expressions
Runs much faster than the generic version"""
@@ -321,89 +308,5 @@
return W_BinaryExpression(o_space, w_variables, w_formula)
else:
return W_Expression(o_space, w_variables, w_formula)
-
-
app_make_expression = gateway.interp2app(make_expression)
-# have a look at this later ... (really needed ?)
-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, 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
-
- def __repr__(self):
- return '<%s %s %s>'% (self.__class__, self._variable, self._reference)
-
- def w_is_variable_relevant(self, w_variable):
- return variable == self._variable
-
- def w_estimate_cost(self):
- return self._space.newint(0) # get in the first place in the queue
-
- def w_affected_variables(self):
- return [self._variable]
-
- def getVariable(self):
- return self._variable
-
- def w_revise(self, w_domains):
- domain = domains[self._variable]
- operator = self._operator
- ref = self._reference
- try:
- for val in domain.get_values() :
- if not operator(val, ref) :
- domain.remove_value(val)
- except ConsistencyFailure:
- raise ConsistencyFailure('inconsistency while applying %s' % \
- repr(self))
- return 1
-
- 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)
- )
-class W_Equals(W_BasicConstraint):
- """A basic constraint variable == constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.eq)
-
-class W_NotEquals(W_BasicConstraint):
- """A basic constraint variable != constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.ne)
-
-class W_LesserThan(W_BasicConstraint):
- """A basic constraint variable < constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.lt)
-
-class W_LesserOrEqual(W_BasicConstraint):
- """A basic constraint variable <= constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.le)
-
-class W_GreaterThan(W_BasicConstraint):
- """A basic constraint variable > constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.gt)
-
-class W_GreaterOrEqual(W_BasicConstraint):
- """A basic constraint variable >= constant value"""
- def __init__(self, variable, reference):
- W_BasicConstraint.__init__(self, variable, reference, operator.ge)
Modified: pypy/dist/pypy/objspace/constraint/domain.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/domain.py (original)
+++ pypy/dist/pypy/objspace/constraint/domain.py Mon Apr 10 12:23:42 2006
@@ -22,20 +22,20 @@
def __init__(self, space):
self._space = space
- self.__changed = self._space.newbool(False)
+ self.__changed = False
def w_reset_flags(self):
- self.__changed = self._space.newbool(False)
+ self.__changed = False
def w_has_changed(self):
- return self.__changed
+ return self._space.newbool(self.__changed)
def w_size(self):
pass
def _value_removed(self):
"""The implementation of remove_value should call this method"""
- self.__changed = self._space.newbool(True)
+ self.__changed = True
if self._space.eq_w(self.w_size(), self._space.newint(0)):
raise OperationError(self._space.w_RuntimeError,
self._space.wrap('ConsistencyFailure'))
@@ -54,16 +54,20 @@
This class uses a dictionnary to make sure that there are
no duplicate values"""
W_AbstractDomain.__init__(self, space)
- self._values = space.newdict([])
+ self._values = {}
self.set_values(w_values)
def set_values(self, w_values):
+ """Objects in the value set can't be unwrapped unless we
+ specialize on specific types - this might need speccialization
+ of revise & friends
+ """
for w_v in w_values.wrappeditems:
- self._values.content[w_v] = self._space.w_True
+ self._values[w_v] = self._space.w_True
def w_remove_value(self, w_value):
"""Remove value of domain and check for consistency"""
- del self._values.content[w_value]
+ del self._values[w_value]
self._value_removed()
def w_remove_values(self, w_values):
@@ -71,19 +75,19 @@
if self._space.is_true(self._space.gt(self._space.len(w_values),
self._space.newint(0))) :
for w_val in w_values.wrappeditems :
- del self._values.content [w_val]
+ del self._values[w_val]
self._value_removed()
__delitem__ = w_remove_value
def w_size(self):
"""computes the size of a finite domain"""
- return self._space.newint(len(self._values.content))
+ return self._space.newint(len(self._values))
__len__ = w_size
def w_get_values(self):
"""return all the values in the domain
in an indexable sequence"""
- return self._space.newlist([x for x in self._values.content])
+ return self._space.newlist([x for x in self._values])
def __iter__(self):
return iter(self._values)
@@ -98,7 +102,7 @@
def __eq__(self, w_other):
if not isinstance(w_other, W_FiniteDomain):
return self._space.newbool(False)
- return self._space.eq(self._values, w_other._values)
+ return self._space.newbool(self._values == w_other._values)
def __ne__(self, w_other):
@@ -118,8 +122,8 @@
def intersection__FiniteDomain_FiniteDomain(space, w_fd1, w_fd2):
- w_v1 = w_fd1._values.content
- w_res = [w_v for w_v in w_fd2.w_get_values().wrappeditems
+ w_v1 = w_fd1._values
+ w_res = [w_v for w_v in w_fd2._values
if w_v in w_v1]
return make_fd(space, space.newlist(w_res))
Modified: pypy/dist/pypy/objspace/constraint/test/test_constraint.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/test/test_constraint.py (original)
+++ pypy/dist/pypy/objspace/constraint/test/test_constraint.py Mon Apr 10 12:23:42 2006
@@ -71,8 +71,7 @@
cstr = make_expression([v1], '2*v1==2')
assert str(cstr).startswith('<W_Expression object at')
-
- def notest_revise(self):
+ def test_revise(self):
csp = newspace()
v1 = csp.var('v1', FiniteDomain([1, 2]))
cstr = make_expression([v1], '2*v1==2')
Modified: pypy/dist/pypy/objspace/constraint/test/test_fd.py
==============================================================================
--- pypy/dist/pypy/objspace/constraint/test/test_fd.py (original)
+++ pypy/dist/pypy/objspace/constraint/test/test_fd.py Mon Apr 10 12:23:42 2006
@@ -56,7 +56,5 @@
"""not used for now"""
fd1 = FiniteDomain([1, 2, 3])
fd2 = FiniteDomain([2, 3, 4])
- assert intersection(fd1, fd2) == FiniteDomain([2, 3])
- assert intersection(fd2, fd1) == FiniteDomain([3, 2])
-
-
+ assert intersection(fd1, fd2) == FiniteDomain([2, 3])
+ assert intersection(fd2, fd1) == FiniteDomain([3, 2])
Modified: pypy/dist/pypy/objspace/logic.py
==============================================================================
--- pypy/dist/pypy/objspace/logic.py (original)
+++ pypy/dist/pypy/objspace/logic.py Mon Apr 10 12:23:42 2006
@@ -801,7 +801,7 @@
return func_with_new_name(boundmethod, 'boundmethod_'+name)
boundmethod = make_boundmethod()
setattr(space, name, boundmethod) # store into 'space' instance
- # /multimethod hack
+ # /multimethods hack
# provide a UnificationError exception
space.ExceptionTable.append('UnificationError')
@@ -821,12 +821,6 @@
space.wrap(app_alias_of))
space.setitem(space.builtin.w_dict, space.wrap('is_aliased'),
space.wrap(app_is_aliased))
- space.setitem(space.builtin.w_dict, space.wrap('newspace'),
- space.wrap(computationspace.app_newspace))
- space.setitem(space.builtin.w_dict, space.wrap('AllDistinct'),
- space.wrap(constraint.app_make_alldistinct))
- space.setitem(space.builtin.w_dict, space.wrap('make_expression'),
- space.wrap(constraint.app_make_expression))
space.setitem(space.builtin.w_dict, space.wrap('bind'),
space.wrap(app_bind))
space.setitem(space.builtin.w_dict, space.wrap('unify'),
@@ -839,6 +833,14 @@
space.wrap(domain.app_make_fd))
space.setitem(space.builtin.w_dict, space.wrap('intersection'),
space.wrap(domain.app_intersection))
+ #-- contraint ----
+ space.setitem(space.builtin.w_dict, space.wrap('make_expression'),
+ space.wrap(constraint.app_make_expression))
+ space.setitem(space.builtin.w_dict, space.wrap('make_filter'),
+ space.wrap(constraint.app_make_filter))
+ space.setitem(space.builtin.w_dict, space.wrap('AllDistinct'),
+ space.wrap(constraint.app_make_alldistinct))
+
if USE_COROUTINES:
import os
def exitfunc():
More information about the Pypy-commit
mailing list