[pypy-svn] r31207 - in pypy/dist/pypy/objspace: . cclp cclp/constraint test
auc at codespeak.net
auc at codespeak.net
Wed Aug 9 17:38:20 CEST 2006
Author: auc
Date: Wed Aug 9 17:38:15 2006
New Revision: 31207
Added:
pypy/dist/pypy/objspace/cclp/constraint/
pypy/dist/pypy/objspace/cclp/constraint/__init__.py
pypy/dist/pypy/objspace/cclp/constraint/constraint.py
pypy/dist/pypy/objspace/cclp/constraint/domain.py
Modified:
pypy/dist/pypy/objspace/cclp/misc.py
pypy/dist/pypy/objspace/cclp/scheduler.py
pypy/dist/pypy/objspace/cclp/space.py
pypy/dist/pypy/objspace/cclp/thunk.py
pypy/dist/pypy/objspace/cclp/types.py
pypy/dist/pypy/objspace/cclp/variable.py
pypy/dist/pypy/objspace/logic.py
pypy/dist/pypy/objspace/test/test_logicobjspace.py
Log:
tell (to declare cosntraints)
Added: pypy/dist/pypy/objspace/cclp/constraint/__init__.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/cclp/constraint/__init__.py Wed Aug 9 17:38:15 2006
@@ -0,0 +1 @@
+# pass
Added: pypy/dist/pypy/objspace/cclp/constraint/constraint.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/cclp/constraint/constraint.py Wed Aug 9 17:38:15 2006
@@ -0,0 +1,214 @@
+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.interpreter.function import Function
+
+from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.stringobject import W_StringObject
+
+from pypy.objspace.constraint.computationspace import W_ComputationSpace
+
+from pypy.objspace.cclp.types import W_Constraint, W_CVar as W_Variable
+
+from pypy.objspace.std.model import StdObjSpaceMultiMethod
+
+from pypy.objspace.constraint.btree import BTree
+from pypy.objspace.constraint.util import sort, reverse
+
+import operator
+
+all_mms = {}
+
+
+#-- 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
+
+#-- Constraints ------------------------------------------
+
+class W_AbstractConstraint(W_Constraint):
+
+ def __init__(self, object_space, w_variables):
+ """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)))
+ self._names_to_vars = {}
+ for var in w_variables.wrappeditems:
+ 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._space.newlist(self._variables)
+
+ def affected_variables(self):
+ return self._variables
+
+ def w_knows_var(self, w_variable):
+ assert isinstance(w_variable, W_Variable)
+ return self._space.newbool(w_variable in self._variables)
+
+ def w_revise(self):
+ return self._space.newbool(self.space.revise())
+
+
+## def __eq__(self, other): #FIXME and parent
+## if not isinstance(other, self.__class__): return False
+## return self._variables == other._variables
+
+W_AbstractConstraint.typedef = typedef.TypeDef(
+ "W_AbstractConstraint",
+ W_Constraint.typedef,
+ affected_variables = interp2app(W_AbstractConstraint.w_affected_variables),
+ knows_var = interp2app(W_AbstractConstraint.w_knows_var),
+ revise = interp2app(W_AbstractConstraint.w_revise))
+
+
+
+from pypy.module.__builtin__.compiling import eval as ev
+def make_filter__List_String(object_space, w_variables, w_formula):
+ """NOT RPYTHON"""
+ assert isinstance(w_variables, W_ListObject)
+ assert isinstance(w_formula, W_StringObject)
+ items = object_space.unpackiterable(w_variables)
+ for it in items:
+ assert isinstance(it, W_Variable)
+ var_ids = ','.join([var.name_w()
+ for var in items])
+ func_head = 'lambda ' + var_ids + ':'
+ expr = func_head + object_space.str_w(w_formula)
+ func_obj = ev(object_space, object_space.wrap(expr), object_space.newdict([]),
+ object_space.newdict([]))
+ assert isinstance(func_obj, Function)
+ return func_obj
+
+make_filter_mm = StdObjSpaceMultiMethod('make_filter', 2)
+make_filter_mm.register(make_filter__List_String, W_ListObject, W_StringObject)
+all_mms['make_filter'] = make_filter_mm
+
+class W_Expression(W_AbstractConstraint):
+ """A constraint represented as a python expression."""
+
+ 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"""
+ W_AbstractConstraint.__init__(self, object_space, w_variables)
+ self.formula = self._space.str_w(w_formula)
+ # self.filter_func is a function taking keyword arguments and returning a boolean
+ self.filter_func = self._space.make_filter(w_variables, w_formula)
+
+ 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:
+ assert isinstance(var, W_Variable)
+ 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]"""
+ result_cache = self._space.newdict([])
+ for var in self._variables:
+ assert isinstance(var, W_Variable)
+ result_cache.content[var.w_name()] = self._space.newdict([])
+ return result_cache
+
+ def _assign_values(self):
+ variables = []
+ kwargs = self._space.newdict([])
+ for variable in self._variables:
+ assert isinstance(variable, W_Variable)
+ domain = variable.w_dom
+ values = domain.w_get_values()
+ variables.append((domain.size(),
+ [variable, values, self._space.newint(0),
+ self._space.len(values)]))
+ kwargs.content[variable.w_name()] = values.wrappeditems[0]
+ # sort variables to instanciate those with fewer possible values first
+ sort(variables)
+ res_kwargs = []
+ go_on = 1
+ while go_on:
+# res_kwargs.append( kwargs)
+ yield kwargs
+ # try to instanciate the next variable
+
+ for size, curr in variables:
+ assert isinstance(curr[0], W_Variable)
+ w_name = curr[0].w_name()
+ assert isinstance(w_name, W_StringObject)
+ if self._space.int_w(curr[2]) + 1 < self._space.int_w(curr[-1]):
+ curr[2] = self._space.add(curr[2], self._space.newint(1))
+ kwargs.content[w_name] = curr[1].wrappeditems[self._space.int_w(curr[2])]
+ break
+ else:
+ curr[2] = self._space.newint(0)
+ kwargs.content[w_name] = curr[1].wrappeditems[0]
+ else:
+ # it's over
+ go_on = 0
+# return res_kwargs
+
+ def revise(self):
+ """generic propagation algorithm for n-ary expressions"""
+ maybe_entailed = True
+ ffunc = self.filter_func
+ result_cache = self._init_result_cache()
+ for kwargs in self._assign_values():
+ if maybe_entailed:
+ for varname, val in kwargs.content.iteritems():
+ if val not in result_cache.content[varname].content:
+ break
+ else:
+ continue
+ if self._space.is_true(self._space.call(self._space.wrap(ffunc),
+ self._space.newlist([]), kwargs)):
+ for var, val in kwargs.content.items():
+ result_cache.content[var].content[val] = self._space.w_True
+ else:
+ maybe_entailed = False
+
+ try:
+ for varname, keep in result_cache.content.items():
+ domain = self._names_to_vars[self._space.str_w(varname)].w_dom
+ domain.w_remove_values(self._space.newlist([val
+ for val in domain._values.content.keys()
+ if val not in keep.content]))
+
+ except ConsistencyFailure:
+ raise ConsistencyFailure('Inconsistency while applying %s' % \
+ repr(self))
+ except KeyError:
+ # There are no more value in result_cache
+ pass
+
+ return maybe_entailed
+
+
+ def __repr__(self):
+ return '<%s>' % self.formula
+
+W_Expression.typedef = typedef.TypeDef("W_Expression",
+ W_AbstractConstraint.typedef)
+# revise = interp2app(W_Expression.w_revise))
+
+
+
+def make_expression(o_space, w_variables, w_formula):
+ """create a new constraint of type Expression or BinaryExpression
+ The chosen class depends on the number of variables in the constraint"""
+ assert len(w_variables.wrappeditems) > 0
+ return W_Expression(o_space, w_variables, w_formula)
+app_make_expression = gateway.interp2app(make_expression)
+
Added: pypy/dist/pypy/objspace/cclp/constraint/domain.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/cclp/constraint/domain.py Wed Aug 9 17:38:15 2006
@@ -0,0 +1,124 @@
+from pypy.interpreter.error import OperationError
+
+from pypy.interpreter import typedef, gateway
+from pypy.interpreter.gateway import interp2app
+
+from pypy.objspace.std.listobject import W_ListObject, W_TupleObject
+
+from pypy.objspace.std.model import StdObjSpaceMultiMethod
+
+from pypy.objspace.cclp.types import W_AbstractDomain
+
+all_mms = {}
+
+class ConsistencyFailure(Exception):
+ """The repository is not in a consistent state"""
+ pass
+
+
+class W_FiniteDomain(W_AbstractDomain):
+ """
+ Variable Domain with a finite set of possible values
+ """
+
+ def __init__(self, space, w_values):
+ """values is a list of values in the domain
+ This class uses a dictionnary to make sure that there are
+ no duplicate values"""
+ W_AbstractDomain.__init__(self, space)
+ #XXX a pure dict used to work there (esp. in revise)
+ self._values = space.newdict([])
+ 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._space.setitem(self._values, w_v, self._space.w_True)
+
+ def w_remove_value(self, w_value):
+ """Remove value of domain and check for consistency"""
+ self._space.delitem(self._values, w_value)
+ self._value_removed()
+
+ def w_remove_values(self, w_values):
+ """Remove values of domain and check for consistency"""
+ assert isinstance(w_values, W_ListObject)
+ self.remove_values(w_values.wrappeditems)
+
+ def remove_values(self, values):
+ assert isinstance(values, list)
+ try:
+ if len(values) > 0:
+ for w_val in values:
+ del self._values.content[w_val]
+ self._value_removed()
+ except KeyError:
+ raise OperationError(self._space.w_RuntimeError,
+ self._space.wrap("attempt to remove unkown value from domain"))
+
+ def w_size(self):
+ return self._space.newint(self.size())
+
+ def size(self):
+ """computes the size of a finite domain"""
+ return self._space.len(self._values).intval
+ __len__ = size
+
+ def w_get_values(self):
+ """return all the values in the domain
+ in an indexable sequence"""
+ return self._space.newlist(self.get_values())
+
+ def get_values(self):
+ return [x for x in self._values.content.keys()]
+
+ def __repr__(self):
+ return '<FD %s>' % str(self.w_get_values())
+
+ def __eq__(self, w_other):
+ if not isinstance(w_other, W_FiniteDomain):
+ return self._space.newbool(False)
+ return self._space.newbool(self._space.eq_w(self._values, w_other._values))
+
+ def __ne__(self, w_other):
+ return not self == w_other
+
+
+# function bolted into the space to serve as constructor
+def make_fd(space, w_values):
+ assert isinstance(w_values, W_ListObject)
+ return space.wrap(W_FiniteDomain(space, w_values))
+app_make_fd = gateway.interp2app(make_fd)
+
+
+def intersection(space, w_fd1, w_fd2):
+ assert isinstance(w_fd1, W_FiniteDomain)
+ assert isinstance(w_fd2, W_FiniteDomain)
+ return space.intersection(w_fd1, w_fd2)
+app_intersection = gateway.interp2app(intersection)
+
+
+def intersection__FiniteDomain_FiniteDomain(space, w_fd1, w_fd2):
+ w_v1 = w_fd1._values.content
+ res = [w_v for w_v in w_fd2._values.content
+ if w_v in w_v1]
+ return make_fd(space, space.newlist(res))
+
+intersection_mm = StdObjSpaceMultiMethod('intersection', 2)
+intersection_mm.register(intersection__FiniteDomain_FiniteDomain,
+ W_FiniteDomain, W_FiniteDomain)
+all_mms['intersection'] = intersection_mm
+
+W_FiniteDomain.typedef = typedef.TypeDef(
+ "W_FiniteDomain",
+ W_AbstractDomain.typedef,
+ remove_value = interp2app(W_FiniteDomain.w_remove_value),
+ remove_values = interp2app(W_FiniteDomain.w_remove_values),
+ get_values = interp2app(W_FiniteDomain.w_get_values),
+ __eq__ = interp2app(W_FiniteDomain.__eq__),
+ __ne__ = interp2app(W_FiniteDomain.__ne__),
+ size = interp2app(W_FiniteDomain.w_size))
+
Modified: pypy/dist/pypy/objspace/cclp/misc.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/misc.py (original)
+++ pypy/dist/pypy/objspace/cclp/misc.py Wed Aug 9 17:38:15 2006
@@ -29,4 +29,3 @@
NO_DEBUG_INFO[0] = not NO_DEBUG_INFO[0]
app_switch_debug_info = gateway.interp2app(switch_debug_info)
-
Modified: pypy/dist/pypy/objspace/cclp/scheduler.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/scheduler.py (original)
+++ pypy/dist/pypy/objspace/cclp/scheduler.py Wed Aug 9 17:38:15 2006
@@ -76,7 +76,10 @@
assert isinstance(thread, ClonableCoroutine)
w(".. REMOVING", str(id(thread)))
assert thread not in self._blocked
- del self._traced[thread]
+ try:
+ del self._traced[thread]
+ except KeyError:
+ w(".. removing non-traced thread")
l = thread._prev
r = thread._next
l._next = r
Modified: pypy/dist/pypy/objspace/cclp/space.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/space.py (original)
+++ pypy/dist/pypy/objspace/cclp/space.py Wed Aug 9 17:38:15 2006
@@ -5,7 +5,7 @@
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.cclp.misc import ClonableCoroutine, w
-from pypy.objspace.cclp.thunk import CSpaceThunk
+from pypy.objspace.cclp.thunk import CSpaceThunk, PropagatorThunk
from pypy.objspace.cclp.global_state import scheduler
from pypy.objspace.cclp.variable import newvar
@@ -42,6 +42,13 @@
app_choose = gateway.interp2app(choose)
+from pypy.objspace.cclp.constraint import constraint
+
+def tell(space, w_constraint):
+ assert isinstance(w_constraint, constraint.W_AbstractConstraint)
+ ClonableCoroutine.w_getcurrent(space)._cspace.tell(w_constraint)
+app_tell = gateway.interp2app(tell)
+
class W_CSpace(baseobjspace.Wrappable):
@@ -54,8 +61,8 @@
# choice mgmt
self._choice = newvar(space)
self._committed = newvar(space)
- # constraint store ...
-
+ # merging
+ self._merged = newvar(space)
def w_ask(self):
scheduler[0].wait_stable(self)
@@ -82,24 +89,23 @@
def tell(self, w_constraint):
- pass
-
-W_CSpace.typedef = typedef.TypeDef("W_CSpace",
- ask = gateway.interp2app(W_CSpace.w_ask),
- commit = gateway.interp2app(W_CSpace.w_commit))
-
+ space = self.space
+ w_coro = ClonableCoroutine(space)
+ thunk = PropagatorThunk(space, w_constraint, w_coro, self._merged)
+ w_coro.bind(thunk)
+ if not we_are_translated():
+ w("PROPAGATOR, thread", str(id(w_coro)))
+ w_coro._cspace = self
+ scheduler[0].add_new_thread(w_coro)
+ scheduler[0].schedule()
+ def w_merge(self):
+ self.space.bind(self._merged, self.space.w_True)
-## def clone(self):
-## if self.is_top_level():
-## raise OperationError(self.space.w_RuntimeError,
-## self.space.wrap("Clone"+forbidden_boilerplate))
-## new = CSpace(self.distributor.clone(), parent=self)
-## new.distributor.cspace = new
-## for thread in self.threads:
-## tclone = thread.clone()
-## tclone.cspace = new
-## new.threads[tclone] = True
+W_CSpace.typedef = typedef.TypeDef("W_CSpace",
+ ask = gateway.interp2app(W_CSpace.w_ask),
+ commit = gateway.interp2app(W_CSpace.w_commit),
+ merge = gateway.interp2app(W_CSpace.w_merge))
Modified: pypy/dist/pypy/objspace/cclp/thunk.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/thunk.py (original)
+++ pypy/dist/pypy/objspace/cclp/thunk.py Wed Aug 9 17:38:15 2006
@@ -1,10 +1,23 @@
from pypy.module._stackless.coroutine import _AppThunk
-from pypy.objspace.cclp.misc import w
+from pypy.objspace.cclp.misc import w
from pypy.objspace.cclp.global_state import scheduler
from pypy.objspace.cclp.types import W_Var, W_Future, W_FailedValue
+
+def logic_args(args):
+ "returns logic vars found in unpacked normalized args"
+ assert isinstance(args, tuple)
+ pos = args[0]
+ kwa = args[1]
+ pos_l = [arg for arg in pos
+ if isinstance(arg, W_Var)]
+ kwa_l = [arg for arg in kwa.keys()
+ if isinstance(arg, W_Var)]
+ return pos_l + kwa_l
+
#-- Thunk -----------------------------------------
+
class ProcedureThunk(_AppThunk):
def __init__(self, space, w_callable, args, coro):
_AppThunk.__init__(self, space, coro.costate, w_callable, args)
@@ -82,16 +95,30 @@
scheduler[0].schedule()
+from pypy.interpreter.argument import Arguments
+from pypy.module._stackless.interp_coroutine import AbstractThunk
+class PropagatorThunk(AbstractThunk):
+ def __init__(self, space, w_constraint, coro, Merged):
+ self.space = space
+ self.coro = coro
+ self.const = w_constraint
+ self.Merged = Merged
-def logic_args(args):
- "returns logic vars found in unpacked normalized args"
- assert isinstance(args, tuple)
- pos = args[0]
- kwa = args[1]
- pos_l = [arg for arg in pos
- if isinstance(arg, W_Var)]
- kwa_l = [arg for arg in kwa.keys()
- if isinstance(arg, W_Var)]
- return pos_l + kwa_l
+ def call(self):
+ try:
+ while 1:
+ entailed = self.const.revise()
+ if entailed:
+ break
+ Obs = W_Var(self.space)
+ self.space.entail(self.Merged, Obs)
+ for Sync in [var.w_dom.give_synchronizer()
+ for var in self.const._variables]:
+ self.space.entail(Sync, Obs)
+ self.space.wait(Obs)
+ finally:
+ self.coro._dead = True
+ scheduler[0].remove_thread(self.coro)
+ scheduler[0].schedule()
Modified: pypy/dist/pypy/objspace/cclp/types.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/types.py (original)
+++ pypy/dist/pypy/objspace/cclp/types.py Wed Aug 9 17:38:15 2006
@@ -1,7 +1,6 @@
from pypy.interpreter import baseobjspace, gateway, typedef
from pypy.objspace.cclp.misc import w, ClonableCoroutine
-#from pypy.objspace.constraint.domain import W_FiniteDomain
W_Root = baseobjspace.W_Root
@@ -32,15 +31,19 @@
class W_CVar(W_Var):
- def __init__(w_self, space, w_dom): #, w_name):
- assert isinstance(w_dom, W_FiniteDomain)
+ def __init__(w_self, space, w_dom, w_name):
+ assert isinstance(w_dom, W_AbstractDomain)
W_Var.__init__(w_self, space)
w_self.w_dom = w_dom
- #w_self.name = space.str_w(w_name)
+ w_self.name = space.str_w(w_name)
+ w_self.w_nam = w_name
def name_w(w_self):
return w_self.name
+ def w_name(w_self):
+ return w_self.w_nam
+
def domain_of(space, w_v):
assert isinstance(w_v, W_CVar)
return w_v.w_dom
@@ -57,12 +60,44 @@
#-- Constraint ---------------------------------------------
-## class W_Constraint(baseobjspace.Wrappable):
-## def __init__(self, object_space):
-## self._space = object_space
+class W_Constraint(baseobjspace.Wrappable):
+ def __init__(self, object_space):
+ self._space = object_space
+
+W_Constraint.typedef = typedef.TypeDef(
+ "W_Constraint")
+
+class W_AbstractDomain(baseobjspace.Wrappable):
+ """Implements the functionnality related to the changed flag.
+ Can be used as a starting point for concrete domains"""
+
+ def __init__(self, space):
+ self._space = space
+ self.__changed = W_Var(self._space)
+
+ def clear_change(self):
+ #XXX called after revise ?
+ assert self._space.is_true(self._space.is_bound(self.__changed))
+ self.__changed = W_Var(self._space)
+
+ def give_synchronizer(self):
+ return self.__changed
+
+ def _value_removed(self):
+ """The implementation of remove_value should call this method"""
+ self._space.bind(self.__changed, self._space.newbool(True))
+ self.clear_change()
+
+ if self.size() == 0: # self._space.eq_w(self.w_size(), self._space.newint(0)):
+ raise OperationError(self._space.w_RuntimeError,
+ self._space.wrap('ConsistencyFailure'))
+
+ def w__del__(self):
+ self._space.bind(self.__changed, self._space.newbool(False))
+
+W_AbstractDomain.typedef = typedef.TypeDef("W_AbstractDomain")
+## has_changed = interp2app(W_AbstractDomain.w_has_changed))
-## W_Constraint.typedef = typedef.TypeDef(
-## "W_Constraint")
#-- Misc ---------------------------------------------------
Modified: pypy/dist/pypy/objspace/cclp/variable.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/variable.py (original)
+++ pypy/dist/pypy/objspace/cclp/variable.py Wed Aug 9 17:38:15 2006
@@ -9,7 +9,7 @@
from pypy.objspace.cclp.global_state import scheduler
from pypy.objspace.cclp.types import deref, W_Var, W_CVar, W_Future, W_FailedValue
-from pypy.objspace.constraint.domain import W_FiniteDomain
+from pypy.objspace.cclp.constraint.domain import W_FiniteDomain
W_Root = baseobjspace.W_Root
all_mms = {}
@@ -20,11 +20,11 @@
return w_v
app_newvar = gateway.interp2app(newvar)
-def domain(space, w_values):#, w_name):
+def domain(space, w_values, w_name):
assert isinstance(w_values, W_ListObject)
- #assert isinstance(w_name, W_StringObject)
+ assert isinstance(w_name, W_StringObject)
w_dom = W_FiniteDomain(space, w_values)
- w_var = W_CVar(space, w_dom)#, w_name)
+ w_var = W_CVar(space, w_dom, w_name)
w("CVAR", str(w_var))
return w_var
app_domain = gateway.interp2app(domain)
@@ -202,7 +202,7 @@
def bind__CVar_Root(space, w_cvar, w_obj):
#XXX we should (want to) be able to test membership
# in a wrapped against wrappeds into a non-wrapped dict
- if [True for elt in w_cvar.w_dom._values
+ if [True for elt in w_cvar.w_dom._values.content
if space.is_true(space.eq(w_obj, elt))]:
return bind__Var_Root(space, w_cvar, w_obj)
raise_unification_failure(space, "value not in variable domain")
@@ -317,7 +317,7 @@
def _assign(space, w_var, w_val):
assert isinstance(w_var, W_Var)
if isinstance(w_var, W_CVar):
- if not w_val in w_var.w_dom._values:
+ if not w_val in w_var.w_dom._values.content:
raise_unification_failure(space, "assignment out of domain")
w_var.w_bound_to = w_val
Modified: pypy/dist/pypy/objspace/logic.py
==============================================================================
--- pypy/dist/pypy/objspace/logic.py (original)
+++ pypy/dist/pypy/objspace/logic.py Wed Aug 9 17:38:15 2006
@@ -23,7 +23,7 @@
#-- COMP. SPACE --------------------------------------------
-from pypy.objspace.cclp.space import app_newspace, app_choose, W_CSpace #app_tell
+from pypy.objspace.cclp.space import app_newspace, app_choose, W_CSpace, app_tell
#-- VARIABLE ------------------------------------------------
@@ -37,8 +37,8 @@
#-- CONSTRAINTS ----------------------------------------------
-## #------ domains ------------------
-from pypy.objspace.constraint import domain
+## #------ domains ------------------
+from pypy.objspace.cclp.constraint import domain
all_mms.update(domain.all_mms)
W_FiniteDomain = domain.W_FiniteDomain
@@ -50,8 +50,8 @@
## W_ComputationSpace = computationspace.W_ComputationSpace
## # ---- constraints ----------------
-## from pypy.objspace.constraint import constraint
-## all_mms.update(constraint.all_mms)
+from pypy.objspace.cclp.constraint import constraint
+all_mms.update(constraint.all_mms)
## #----- distributors ---------------
## from pypy.objspace.constraint import distributor
@@ -246,8 +246,8 @@
space.setitem(space.builtin.w_dict, space.wrap('intersection'),
space.wrap(domain.app_intersection))
## #-- constraints ----
-## 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_expression'),
+ space.wrap(constraint.app_make_expression))
## space.setitem(space.builtin.w_dict, space.wrap('AllDistinct'),
## space.wrap(constraint.app_make_alldistinct))
## #-- distributor --
@@ -281,8 +281,8 @@
space.wrap(app_newspace))
space.setitem(space.builtin.w_dict, space.wrap('choose'),
space.wrap(app_choose))
-## space.setitem(space.builtin.w_dict, space.wrap('tell'),
-## space.wrap(app_tell))
+ space.setitem(space.builtin.w_dict, space.wrap('tell'),
+ space.wrap(app_tell))
#-- misc -----
space.setitem(space.builtin.w_dict, space.wrap('interp_id'),
Modified: pypy/dist/pypy/objspace/test/test_logicobjspace.py
==============================================================================
--- pypy/dist/pypy/objspace/test/test_logicobjspace.py (original)
+++ pypy/dist/pypy/objspace/test/test_logicobjspace.py Wed Aug 9 17:38:15 2006
@@ -665,7 +665,7 @@
def test_cvar(self):
- d = domain([1, 2, 4])
+ d = domain([1, 2, 4], '')
raises(UnificationError, bind, d, 42)
bind(d, 2)
@@ -675,31 +675,31 @@
pass
f = Foo()
- d = domain([Foo(), f, Foo()])
+ d = domain([Foo(), f, Foo()], '')
raises(UnificationError, bind, d, Foo())
bind(d, f)
assert d == f
- d1 = domain([1, 2, 3])
- d2 = domain([2, 3, 4])
- d3 = domain([5, 6])
+ d1 = domain([1, 2, 3], '')
+ d2 = domain([2, 3, 4], '')
+ d3 = domain([5, 6], '')
raises(UnificationError, unify, d1, d3)
unify(d1, d2)
assert alias_of(d1, d2)
assert domain_of(d1) == domain_of(d2) == FiniteDomain([2, 3])
- d1 = domain([1, 2, 3])
- d4 = domain([3, 4])
+ d1 = domain([1, 2, 3], '')
+ d4 = domain([3, 4], '')
unify(d1, d4)
assert d1 == d4 == 3
- d1 = domain([1, 2])
+ d1 = domain([1, 2], '')
x = newvar()
unify(d1, x)
assert alias_of(x, d1)
raises(UnificationError, unify, x, 42)
- d1 = domain([1, 2])
+ d1 = domain([1, 2], '')
x = newvar()
unify(d1, x)
assert alias_of(x, d1)
@@ -778,26 +778,22 @@
def test_tell(self):
- skip("not finished ...")
-
def problem():
X, Y = domain([1, 2], 'X'), domain([1, 2, 3], 'Y')
tell(make_expression([X, Y], 'X + Y > 4'))
-
def solve(spc, X):
while 1:
status = spc.ask()
if status == 1:
unify(X, status)
break
+ spc.merge()
- switch_debug_info()
s = newspace(problem)
Finished = newvar()
stacklet(solve, s, Finished)
-
wait(Finished)
- assert domain_of(X) == FiniteDomain([2])
- assert domain_of(Y) == FiniteDomain([3])
+ schedule()
+ assert len(sched_all()['threads']) == 1
More information about the Pypy-commit
mailing list