[pypy-svn] r24212 - pypy/dist/pypy/lib/logic/computation_space
auc at codespeak.net
auc at codespeak.net
Fri Mar 10 12:52:03 CET 2006
Author: auc
Date: Fri Mar 10 12:51:56 2006
New Revision: 24212
Modified:
pypy/dist/pypy/lib/logic/computation_space/computationspace.py
pypy/dist/pypy/lib/logic/computation_space/constraint.py
pypy/dist/pypy/lib/logic/computation_space/distributor.py
pypy/dist/pypy/lib/logic/computation_space/strategies.py
pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py
pypy/dist/pypy/lib/logic/computation_space/variable.py
Log:
* killed distributor/propagator thread
* removed dead code
Modified: pypy/dist/pypy/lib/logic/computation_space/computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/computationspace.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/computationspace.py Fri Mar 10 12:51:56 2006
@@ -3,34 +3,14 @@
# * [5] add a linear constraint solver (vital for fast
# constraint propagation over finite integer domains)
# and other kinds of specialized propagators
-# * [9] make all propagators live in their own threads and
-# be awakened by variable/domains events
-
-
-# Gert Smolka in
-# http://www.cetic.be/moz2004/talks/MOZ2004.pdf :
-# * Abandon Logic Variables
-# * can be bound everywhere
-# * malicious consummer can bind tail variable of stream
-# * break abstractions
-# * unification not needed
-# * Have Futures instead
-# * Multilisp [Halstead 85]
-# * added to Mozart in 1998
-# * refine logic variable into
-# * consummer end (future)
-# * producer end (promise)
-# * dataflow synchronization + by-need synchronization
-
from threading import Thread, Condition, RLock, local
-from state import Succeeded, Distributable, Failed, \
- Unknown, Forsaken
+from state import Succeeded, Failed, Unknown
from variable import EqSet, CsVar, NoValue, NoDom, \
VariableException, NotAVariable, AlreadyInStore, \
- AlreadyBound, SimpleVar
+ AlreadyBound
from constraint import FiniteDomain, ConsistencyFailure, \
Expression
from distributor import DefaultDistributor
@@ -104,9 +84,6 @@
self.bind_lock = RLock()
self.var_lock = RLock()
self.distributor = DefaultDistributor(self)
- # parent/children
- self.parent = parent
- self.children = set()
# mapping from domains to variables
self.doms = {}
# set of all constraints
@@ -122,10 +99,7 @@
self.root = self.var('__root__')
# set up the problem
self.bind(self.root, problem(self))
- self._init_choose_commit()
- self.distributor.start()
else:
- self.parent.children.add(self)
# shared stuff
self.vars = parent.vars
self.names = parent.names
@@ -136,14 +110,6 @@
# ...
self.status = Unknown
self.distributor = parent.distributor.__class__(self)
- self._init_choose_commit()
-
- def _init_choose_commit(self):
- # create a unique choice point
- # using two spaceless vars as channels betwen
- # space and distributor threads
- self.CHOOSE = SimpleVar()
- self.STABLE = SimpleVar()
#-- utilities & instrumentation -----------------------------
@@ -155,15 +121,6 @@
ret.append(">")
return ' '.join(ret)
- def __del__(self):
- # try to break ref. cycles and help
- # threads terminate
- self.status = Forsaken
- self.parent = None
- self.children = None
- self.CHOOSE.bind(True)
- self.STABLE.bind(True)
-
def __eq__(self, spc):
"""space equality defined as :
* identity, or
@@ -207,12 +164,20 @@
print ' ', str(d.get_values())
print " -- domains --)"
+ def test_solution(self, sol):
+ res = True
+ for _const in self.constraints:
+ if not _const.test_solution(sol):
+ print "Solution", sol, "doesn't satisfy", _const
+ res = False
+ return res
+
#-- Computation Space -----------------------------------------
#-- space helpers -----------------------------------------
- def _process(self):
+ def _propagate(self):
"""wraps the propagator"""
if len(self.event_set):
try:
@@ -239,33 +204,19 @@
#-- space official API ------------------------------------
def ask(self):
- self.STABLE.get()
- status = self.status in (Failed, Succeeded)
- if status: return self.status
+ self._propagate()
+ if self.status in (Failed, Succeeded):
+ return self.status
if self._distributable():
return Alternative(self.distributor.nb_subdomains())
- # should be unreachable
- print "DOMS", [(var, self.doms[var])
- for var in self.vars
- if self.dom(var) != NoDom]
- raise NotImplementedError
-
def clone(self):
- # did you ask before ... ?
- assert self.STABLE.is_bound()
spc = ComputationSpace(NoProblem, parent=self)
print "-- cloning %s to %s --" % (self.id, spc.id)
self._notify(event.Clone)
- spc._process()
- spc.distributor.start()
+ spc._propagate()
return spc
- def inject(self, restricting_problem):
- """add additional entities into a space"""
- restricting_problem(self)
- self._process()
-
def commit(self, choice):
"""if self is distributable, causes the Choose call in the
space to complete and return some_number as a result. This
@@ -273,10 +224,7 @@
some_number must satisfy 1=<I=<N where N is the first arg
of the Choose call.
"""
- # did you ask before ... ?
- assert self.STABLE.is_bound()
- self.STABLE = SimpleVar()
- self.CHOOSE.bind(choice)
+ self.distributor.distribute(choice-1)
def choose(self, nb_choices):
"""
@@ -288,9 +236,7 @@
----
this is used by the distributor thread
"""
- choice = self.CHOOSE.get()
- return choice
-
+
def merge(self):
"""binds root vars to their singleton domains """
assert self.status == Succeeded
@@ -298,16 +244,19 @@
#for var in self.root.val:
# var.bind(self.dom(var).get_values()[0])
# shut down the distributor
- self.CHOOSE.bind(True)
- self.status = Forsaken
res = {}
for var in self.root.val:
res[var.name] = self.dom(var).get_values()[0]
- self.distributor.join()
return res
def set_distributor(self, dist):
self.distributor = dist
+
+ def inject(self, restricting_problem):
+ """add additional entities into a space"""
+ restricting_problem(self)
+ self._propagate()
+
#-- Constraint Store ---------------------------------------
@@ -434,71 +383,6 @@
#-- Constraint propagation ---------------
- def satisfiable(self, constraint):
- """ * satisfiable (k) checks that the constraint k
- can be satisfied wrt its variable domains
- and other constraints on these variables
- * does NOT mutate the store
- """
- # Satisfiability of one constraint entails
- # satisfiability of the transitive closure
- # of all constraints associated with the vars
- # of our given constraint.
- # We make a copy of the domains
- # then traverse the constraints & attached vars
- # to collect all (in)directly affected vars
- # then compute narrow() on all (in)directly
- # affected constraints.
- assert constraint in self.constraints
- varset = set()
- constset = set()
- self._compute_dependant_vars(constraint, varset, constset)
- old_domains = self.collect_domains(varset)
-
- for const in constset:
- try:
- const.revise3()
- except ConsistencyFailure:
- self.restore_domains(old_domains)
- return False
- self.restore_domains(old_domains)
- return True
-
- def get_satisfying_domains(self, constraint):
- """computes the smallest satisfying domains"""
- assert constraint in self.constraints
- varset = set()
- constset = set()
- self._compute_dependant_vars(constraint, varset, constset)
- old_domains = self.collect_domains(varset)
-
- for const in constset:
- try:
- const.revise3()
- except ConsistencyFailure:
- self.restore_domains(old_domains)
- return {}
- narrowed_domains = self.collect_domains(varset)
- self.restore_domains(old_domains)
- return narrowed_domains
-
- def satisfy(self, constraint):
- """prune the domains down to smallest satisfying domains"""
- assert constraint in self.constraints
- varset = set()
- constset = set()
- self._compute_dependant_vars(constraint, varset, constset)
- old_domains = self.collect_domains(varset)
-
- for const in constset:
- try:
- const.revise3()
- except ConsistencyFailure:
- self.restore_domains(old_domains)
- raise
-
- #-- real propagation begins there -------------------------
-
def add_distributed(self, var):
self.changelog.append(var)
Modified: pypy/dist/pypy/lib/logic/computation_space/constraint.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/constraint.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/constraint.py Fri Mar 10 12:51:56 2006
@@ -201,6 +201,14 @@
+ expand_expr_template(formula, variables), {}, {})
Expression._FILTER_CACHE[formula] = self.filterFunc
+ def test_solution(self, sol ):
+ """FOR TESTING: 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] )
+ return self.filterFunc( *args )
+
def copy_to(self, space):
return self.__class__(space, self._variables,
Modified: pypy/dist/pypy/lib/logic/computation_space/distributor.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/distributor.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/distributor.py Fri Mar 10 12:51:56 2006
@@ -1,8 +1,5 @@
import math, random
-from threading import Thread
-from state import Succeeded, Distributable, Failed, Forsaken
from event import Revise
-from variable import SimpleVar
def arrange_domains(cs, variables):
"""build a data structure from var to dom
@@ -12,11 +9,10 @@
new_doms[var] = cs.dom(var).copy()
return new_doms
-class AbstractDistributor(Thread):
+class AbstractDistributor(object):
"""_distribute is left unimplemented."""
def __init__(self, c_space, nb_subspaces=2):
- Thread.__init__(self)
self.nb_subspaces = nb_subspaces
self.cs = c_space
self.verbose = 0
@@ -137,32 +133,9 @@
else:
return self.cs.dom(self.__to_split).size()
- ### new threaded distributor
-
- def run(self):
- print "-- distributor started (%s) --" % self.cs.id
- assert not self.cs.STABLE.is_bound()
- #XXX: are the domains properly set up ?
- #self.cs._process() # propagate first
- #better let clone() do this call
- while self.cs._distributable():
- self.cs.STABLE.bind(True)
- choice = self.cs.choose(self.nb_subdomains())
- if self.cs.status == Forsaken:
- print "-- distributor (%s) ready for GC --" % self.cs.id
- break
- print "-- distribution & propagation (%s) --" % self.cs.id
- self.distribute(choice-1)
- self.cs._process()
- self.cs.CHOOSE = SimpleVar()
- self.cs.STABLE.bind(True) # unlocks Ask
- print "-- distributor terminated (%s) --" % self.cs.id
-
def distribute(self, choice):
variable = self.findSmallestDomain()
- #variables = self.cs.get_variables_with_a_domain()
- #domains = arrange_domains(self.cs, variables)
nb_subspaces = self.nb_subdomains()
values = self.cs.dom(variable).get_values()
nb_elts = max(1, len(values)*1./nb_subspaces)
Modified: pypy/dist/pypy/lib/logic/computation_space/strategies.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/strategies.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/strategies.py Fri Mar 10 12:51:56 2006
@@ -22,9 +22,8 @@
if outcome is None:
new_space.ask()
new_space.commit(2)
- return do_dfs(new_space)
- else:
- return outcome
+ outcome = do_dfs(new_space)
+ return outcome
else:
raise StrategyDistributionMismatch()
@@ -35,15 +34,24 @@
-#-- solve_all
+#-- solve_all, switchable direction
-def solve_all(problem):
+class Depth: pass
+class Breadth: pass
+
+def solve_all(problem, direction=Depth):
solutions = []
sp_stack = []
-
sp_stack.append(csp.ComputationSpace(problem))
+ if direction == Depth:
+ def collect(space):
+ sp_stack.append(space)
+ else:
+ def collect(space):
+ sp_stack.insert(0, space)
+
while len(sp_stack):
space = sp_stack.pop()
print ' '*len(sp_stack), "ask ..."
@@ -54,112 +62,40 @@
elif status == csp.Alternative(2):
print ' '*len(sp_stack), "branches ..."
sp1 = space.clone()
- sp1.ask()
sp1.commit(1)
- sp_stack.append(sp1)
+ collect(sp1)
sp2 = space.clone()
- sp2.ask()
sp2.commit(2)
- sp_stack.append(sp2)
+ collect(sp2)
return [sp.merge() for sp in solutions]
-
-## declare
-## % This version of SolveAll will do a depth-first or breadth-first
-## % traversal of the search space depending on the WhichFirst parameter.
-## fun {SolveAll WhichFirst Script}
-## {TouchAll {Solve WhichFirst Script}}
-## end
-
-## fun {TouchAll L}
-## case L of
-## nil then skip
-## [] _ | Rest then {TouchAll Rest _}
-## end
-## L
-## end
-
-## % Returns a lazy list of solutions for Script.
-## % The list is ordered depth-first or breadth-first
-## % depending on the WhichFirst parameter.
-## % The allowable values are depth and breadth.
-## fun {Solve WhichFirst Script}
-
-## % All the subsidiary function are declared within Solve so
-## % that we won't have to pass WhichFirst around.
-## % The body of Solve is at the bottom.
-
-## % Each of the elements in Ss is either a Space or a
-## % commitTo(<Space> <Int>) record. A commitTo(<Space> <Int>)
-## % record identifies a Space that is ready to commit to
-## % the Ith choice at a choice point.
-## % Returns all solutions using either depth-first or
-## % breadth-first depending on the value of WhichFirst.
-## fun lazy {SolveSpaces Ss}
-## case Ss of
-## nil then nil
-## [] S | SRest then
-## % S is either a Space or a commitTo(<Space> <Int>) record.
-## case S of
-## commitTo(S I) then
-## Clone = {Space.clone S}
-## in
-## % Start the Ith branch in the clone of S.
-## {Space.commit Clone I}
-## {SolveSpaces Clone|SRest}
-## else % S is a Space.
-## {SolveSpace {Space.ask S} S SRest}
-## end
-## end
-## end
-
-## % Deal with Space S, which is in state SpaceState
-## fun {SolveSpace SpaceState S SRest}
-## case SpaceState of
-## failed then {SolveSpaces SRest}
-## [] succeeded then {Space.merge S}|{SolveSpaces SRest}
-## [] alternatives(N) then
-## {SolveSpaces {NewSpaceList {Choices S N} SRest}}
-## end
-## end
-
-## % The choices are commitTo(<Space> <Int>) records. They
-## % keep track of the branch to which to commit.
-## fun {Choices S N}
-## {List.mapInd
-## {List.make N} % Generates N elements for Map to use.
-## % Keep track of which branch to commit to.
-## fun {$ I _} commitTo(S I) end}
-## end
-
-## % Put the Choices at the front or back of the existing list
-## % of pending Spaces depending on WhichFirst. For efficiency
-## % the lists could be replaced with difference lists.
-## fun {NewSpaceList Choices Ss}
-## % This is the only place where WhichFirst matters.
-## % In depth-first search, the list of pending spaces is a stack.
-## if WhichFirst == depth then {Append Choices Ss}
-## % In breadth-first search, the list of pending spaces is a queue.
-## elseif WhichFirst == breadth then {Append Ss Choices}
-## else {Raise traversalSpecificationError(WhichFirst)} nil
-## end
-## end
-
-## in
-## % The body of Solve
-## {SolveSpaces [{Space.new Script}]}
-## end
-
-## % ==============================================================
-## % Example to illustrate depth-first vs. breadth-first
-## fun {ABC} choice a [] b [] c end end
-
-## % The "problem" looks at all lists of length =< 3.
-## % The "Show" documents the order in which the lists
-## % are generated.
-## fun {Problem List}
-## if {Length List} > 3 then fail end
-## {Show List}
-## {Problem {Append List [{ABC}]}}
-## end
+#-- pythonic lazy solve_all
+
+def lazily_solve_all(space, direction=Depth):
+
+ sp_stack = []
+ sp_stack.append(space)
+
+ if direction == Depth:
+ def collect(space):
+ sp_stack.append(space)
+ else:
+ def collect(space):
+ sp_stack.insert(0, space)
+
+ while len(sp_stack):
+ space = sp_stack.pop()
+ print ' '*len(sp_stack), "ask ..."
+ status = space.ask()
+ if status == csp.Succeeded:
+ print ' '*len(sp_stack), "solution !"
+ yield space.merge()
+ elif status == csp.Alternative(2):
+ print ' '*len(sp_stack), "branches ..."
+ sp1 = space.clone()
+ sp1.commit(1)
+ collect(sp1)
+ sp2 = space.clone()
+ sp2.commit(2)
+ collect(sp2)
Modified: pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/test_computationspace.py Fri Mar 10 12:51:56 2006
@@ -5,7 +5,11 @@
import computationspace as space
import distributor as di
import problems
-from py.test import raises
+try:
+ from py.test import raises
+except ImportError:
+ def raises(*args):
+ pass
#-- utility ---------------------
@@ -341,133 +345,6 @@
assert varset == set([x, y, z, w])
assert constset == set([k1, k2])
- def test_store_satisfiable_success(self):
- sp = newspace()
- x,y,z = sp.var('x'), sp.var('y'), sp.var('z')
- sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- k = c.Expression(sp, [x, y, z], 'x == y + z')
- sp.add_expression(k)
- assert sp.satisfiable(k) == True
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
-
- def test_store_satisfiable_failure(self):
- sp = newspace()
- x,y,z = sp.var('x'), sp.var('y'), sp.var('z')
- sp.set_dom(x, c.FiniteDomain([1, 2]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- k = c.Expression(sp, [x, y, z], 'x == y + z')
- sp.add_expression(k)
- assert sp.satisfiable(k) == False
- assert sp.dom(x) == c.FiniteDomain([1, 2])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
-
- def test_satisfiable_many_const_success(self):
- sp = newspace()
- x,y,z,w = (sp.var('x'), sp.var('y'),
- sp.var('z'), sp.var('w'))
- sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- sp.set_dom(w, c.FiniteDomain([1, 4, 5]))
- k1 = c.Expression(sp, [x, y, z], 'x == y + z')
- k2 = c.Expression(sp, [z, w], 'z < w')
- sp.add_expression(k1)
- sp.add_expression(k2)
- assert sp.satisfiable(k1) == True
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1, 4, 5])
- assert sp.satisfiable(k2) == True
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1, 4, 5])
- narrowed_doms = sp.get_satisfying_domains(k1)
- assert narrowed_doms == {x:c.FiniteDomain([5]),
- y:c.FiniteDomain([2]),
- z:c.FiniteDomain([3]),
- w:c.FiniteDomain([4, 5])}
- narrowed_doms = sp.get_satisfying_domains(k2)
- assert narrowed_doms == {x:c.FiniteDomain([5]),
- y:c.FiniteDomain([2]),
- z:c.FiniteDomain([3]),
- w:c.FiniteDomain([4, 5])}
-
-
- def test_satisfiable_many_const_failure(self):
- sp = newspace()
- x,y,z,w = (sp.var('x'), sp.var('y'),
- sp.var('z'), sp.var('w'))
- sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- sp.set_dom(w, c.FiniteDomain([1]))
- k1 = c.Expression(sp, [x, y, z], 'x == y + z')
- k2 = c.Expression(sp, [z, w], 'z < w')
- sp.add_expression(k1)
- sp.add_expression(k2)
- assert sp.satisfiable(k1) == False
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1])
- assert sp.satisfiable(k2) == False
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1])
- narrowed_doms = sp.get_satisfying_domains(k1)
- assert narrowed_doms == {}
- narrowed_doms = sp.get_satisfying_domains(k2)
- assert narrowed_doms == {}
-
- def test_satisfy_many_const_failure(self):
- sp = newspace()
- x,y,z,w = (sp.var('x'), sp.var('y'),
- sp.var('z'), sp.var('w'))
- sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- sp.set_dom(w, c.FiniteDomain([1]))
- k1 = c.Expression(sp, [x, y, z], 'x == y + z')
- k2 = c.Expression(sp, [z, w], 'z < w')
- sp.add_expression(k1)
- sp.add_expression(k2)
- raises(space.ConsistencyFailure, sp.satisfy, k1)
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1])
- raises(space.ConsistencyFailure, sp.satisfy, k2)
- assert sp.dom(x) == c.FiniteDomain([1, 2, 5])
- assert sp.dom(y) == c.FiniteDomain([2, 3])
- assert sp.dom(z) == c.FiniteDomain([3, 4])
- assert sp.dom(w) == c.FiniteDomain([1])
-
- def test_satisfy_many_const_success(self):
- sp = newspace()
- x,y,z,w = (sp.var('x'), sp.var('y'),
- sp.var('z'), sp.var('w'))
- sp.set_dom(x, c.FiniteDomain([1, 2, 5]))
- sp.set_dom(y, c.FiniteDomain([2, 3]))
- sp.set_dom(z, c.FiniteDomain([3, 4]))
- sp.set_dom(w, c.FiniteDomain([1, 4, 5]))
- k1 = c.Expression(sp, [x, y, z], 'x == y + z')
- k2 = c.Expression(sp, [z, w], 'z < w')
- sp.add_expression(k1)
- sp.add_expression(k2)
- sp.satisfy(k2)
- assert sp.dom(x) == c.FiniteDomain([5])
- assert sp.dom(y) == c.FiniteDomain([2])
- assert sp.dom(z) == c.FiniteDomain([3])
- assert sp.dom(w) == c.FiniteDomain([4, 5])
#-- computation spaces -------------------------------
@@ -483,40 +360,11 @@
assert '__root__' in spc.names
assert set(['x', 'y', 'z']) == \
set([var.name for var in spc.root.val])
-
-# we need to carefully craft some noop problems
-# for these tests
-# also what is tested below is tested in other places
-# so me might want to just forget about it
-
-## def test_ask_success(self):
-## spc = newspace(problems.one_solution_problem)
-## assert spc.ask() == space.Succeeded
-## assert spc.ask() == space.Succeeded
-## def test_ask_failure(self):
-## spc = newspace(problems.unsatisfiable_problem)
-## assert spc.ask() == space.Failed
-
def test_ask_alternatives(self):
spc = newspace(problems.satisfiable_problem)
assert spc.ask() == space.Alternative(2)
-## def test_clone_and_process(self):
-## spc = newspace(problems.satisfiable_problem)
-## assert spc.ask() == space.Alternative(2)
-## new_spc = spc.clone()
-## #assert spc == new_spc
-## assert new_spc.parent == spc
-## # following couple of ops superceeded by inject()
-## x, y, z = new_spc.find_vars('x', 'y', 'z')
-## new_spc.add_constraint([x], 'x == 0')
-## new_spc.add_constraint([z, y], 'z == y')
-## new_spc.add_constraint([y], 'y < 2')
-## new_spc._process()
-## assert spc.ask() == space.Alternative(2)
-## assert new_spc.ask() == space.Succeeded
-
def test_clone(self):
"""checks that a chain of initially s1 = s2
s1 - commit(1) - commit(1) ...
@@ -536,8 +384,6 @@
#assert s1 == s2
temp = s2.clone()
temp.ask()
- assert temp.parent is s2
- assert temp in s2.children
s2 = temp
s1.commit(1)
s2.commit(1)
@@ -578,30 +424,37 @@
def test_scheduling_dfs_one_solution(self):
sol = strategies.dfs_one(problems.conference_scheduling)
- vars = sol.keys()
- vars.sort()
- sols = [ sol[k] for k in vars ]
- result = [('room A', 'day 1 PM'),
- ('room A', 'day 2 AM'),
- ('room C', 'day 2 PM'),
- ('room C', 'day 2 AM'),
- ('room C', 'day 1 AM'),
- ('room C', 'day 1 PM'),
- ('room B', 'day 2 AM'),
- ('room B', 'day 1 AM'),
- ('room B', 'day 2 PM'),
- ('room A', 'day 1 AM'),
- ]
-
- for v, r1, r2 in zip(vars, sols, result):
- print v, r1, r2
- assert sols == result
-
+ spc = space.ComputationSpace(problems.conference_scheduling)
+ assert spc.test_solution( sol )
+
- def test_scheduling_all_solutions(self):
+ def test_scheduling_all_solutions_dfs(self):
sols = strategies.solve_all(problems.conference_scheduling)
assert len(sols) == 64
- print sols
+ spc = space.ComputationSpace(problems.conference_scheduling)
+ for s in sols:
+ assert spc.test_solution( s )
+
+
+ def test_scheduling_all_solutions_lazily_dfs(self):
+ sp = space.ComputationSpace(problems.conference_scheduling)
+ for sol in strategies.lazily_solve_all(sp):
+ assert sp.test_solution(sol)
+
+ def test_scheduling_all_solutions_bfs(self):
+ sols = strategies.solve_all(problems.conference_scheduling,
+ direction=strategies.Breadth)
+ assert len(sols) == 64
+ spc = space.ComputationSpace(problems.conference_scheduling)
+ for s in sols:
+ assert spc.test_solution( s )
+
+
+ def test_scheduling_all_solutions_lazily_bfs(self):
+ sp = space.ComputationSpace(problems.conference_scheduling)
+ for sol in strategies.lazily_solve_all(sp, direction=strategies.Breadth):
+ assert sp.test_solution(sol)
+
def no_test_sudoku(self):
#spc = newspace(problems.sudoku)
@@ -625,16 +478,3 @@
sol2 = strategies.dfs_one(strategies.sudoku)
print "done dfs"
#sol2 = [var.val for var in sol]
- assert sol2 == [('room A', 'day 1 PM'),
- ('room B', 'day 2 PM'),
- ('room C', 'day 2 AM'),
- ('room C', 'day 2 PM'),
- ('room C', 'day 1 AM'),
- ('room C', 'day 1 PM'),
- ('room A', 'day 2 PM'),
- ('room B', 'day 1 AM'),
- ('room A', 'day 2 AM'),
- ('room A', 'day 1 AM')]
-
-
-
Modified: pypy/dist/pypy/lib/logic/computation_space/variable.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computation_space/variable.py (original)
+++ pypy/dist/pypy/lib/logic/computation_space/variable.py Fri Mar 10 12:51:56 2006
@@ -73,9 +73,9 @@
self._value_condition.acquire()
while not self.is_bound():
t1 = time.time()
- self._value_condition.wait(80)
+ self._value_condition.wait(120)
t2 = time.time()
- if t2-t1>80:
+ if t2-t1>120:
raise RuntimeError("possible deadlock??")
return self.val
finally:
More information about the Pypy-commit
mailing list