[pypy-svn] r22745 - in pypy/dist/pypy/lib/logic: . basic_store store_without_cs
auc at codespeak.net
auc at codespeak.net
Fri Jan 27 17:37:12 CET 2006
Author: auc
Date: Fri Jan 27 17:37:08 2006
New Revision: 22745
Added:
pypy/dist/pypy/lib/logic/basic_store/
- copied from r22714, pypy/dist/pypy/lib/logic/store_without_cs/
pypy/dist/pypy/lib/logic/state.py
Removed:
pypy/dist/pypy/lib/logic/store_without_cs/
Modified:
pypy/dist/pypy/lib/logic/computationspace.py
pypy/dist/pypy/lib/logic/distributor.py
pypy/dist/pypy/lib/logic/test_computationspace.py
pypy/dist/pypy/lib/logic/variable.py
Log:
(ale, auc)
* basic choose / commit implementation (cooperation between space and distributor)
* lot of fixes
* rename store_without_cs basic_store
Modified: pypy/dist/pypy/lib/logic/computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/computationspace.py (original)
+++ pypy/dist/pypy/lib/logic/computationspace.py Fri Jan 27 17:37:08 2006
@@ -179,30 +179,16 @@
from threading import Thread, Condition, RLock, local
+from state import Succeeded, Distributable, Failed, Merged
+
from variable import EqSet, Var, \
VariableException, NotAVariable, AlreadyInStore
from constraint import FiniteDomain, ConsistencyFailure
+from distributor import DefaultDistributor
-EmptyDom = FiniteDomain([])
-
-class Succeeded:
- """It contains no choice points but a solution to
- the logic program.
- """
- pass
-
-class Distributable:
- pass
-class Failed(Exception):
- pass
+EmptyDom = FiniteDomain([])
-class Merged:
- """Its constraint store has been added to a parent.
- Any further operation operation on the space is
- an error.
- """
- pass
class Alternatives(object):
@@ -262,6 +248,9 @@
other but not to any other variables.
* variables bound to a number, record or procedure
(also called determined variables)."""
+
+ _nb_choices = 0
+
def __init__(self, problem, parent=None):
# consistency-preserving stuff
@@ -269,6 +258,7 @@
self.bind_lock = RLock()
self.status = None
self.status_condition = Condition()
+ self.distributor = DefaultDistributor(self)
if parent is None:
self.vars = set()
@@ -283,6 +273,8 @@
self.bind(self.root, problem(self))
# check satisfiability of the space
self._process()
+ if self.status == Distributable:
+ self.distributor.start()
else:
self.vars = parent.vars
self.names = parent.names
@@ -290,6 +282,13 @@
self.constraints = parent.constraints
self.root = parent.root
+ # create a unique choice point
+ self.CHOICE = self._make_choice_var()
+
+ def __del__(self):
+ self.status = Failed
+ self.bind(self.CHOICE, 0)
+
#-- Store ------------------------------------------------
#-- Variables ----------------------------
@@ -615,6 +614,7 @@
def _distributable(self):
if self.status not in (Failed, Succeeded, Merged):
return self._distributable_domains()
+ return False
# in The Book : "the space has one thread that is
# suspended on a choice point with two or more alternatives.
# A space canhave at most one choice point; attempting to
@@ -645,11 +645,44 @@
spc = ComputationSpace(NoProblem, parent=self)
for var in spc.vars:
var.cs_set_dom(spc, var.cs_get_dom(self).copy())
+ # check satisfiability of the space
+ spc._process()
+ if spc.status == Distributable:
+ spc.distributor.start()
return spc
def inject(self, restricting_problem):
+ """add additional stuff into a space"""
pass
+ 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
+ may cause the spzce to resume execution.
+ some_number must satisfy 1=<I=<N where N is the first arg
+ of the Choose call.
+ """
+ self.bind(self.CHOICE, choice)
+
+ def choose(self, nb_choices):
+ """
+ waits for stability
+ blocks until commit provides a value
+ between 0 and nb_choices
+ at most one choose running in a given space
+ at a given time
+ ----
+ this is used by the distributor thread
+ """
+ self.ask()
+ choice = self.CHOICE.get()
+ self.CHOICE = self._make_choice_var()
+ return choice
+
+ def _make_choice_var(self):
+ ComputationSpace._nb_choices += 1
+ return self.var('__choice__'+str(self._nb_choices))
+
def make_children(self):
for dommap in self.distributor.distribute():
cs = ComputationSpace(lambda cs : True,
@@ -658,16 +691,6 @@
for var, dom in dommap.items():
var.cs_set_dom(cs, dom)
-
- def commit(self, some_number):
- """if self is distributable, causes the Choose call in the
- space ot complete and return some_number as a result. This
- may cause the spzce to resume execution.
- some_number must satisfy 1=<I=<N where N is the first arg
- of the Choose call.
- """
- pass
-
def solve_all(self):
"""recursively solves the problem
"""
Modified: pypy/dist/pypy/lib/logic/distributor.py
==============================================================================
--- pypy/dist/pypy/lib/logic/distributor.py (original)
+++ pypy/dist/pypy/lib/logic/distributor.py Fri Jan 27 17:37:08 2006
@@ -1,16 +1,20 @@
import math, random
+from threading import Thread
+from state import Succeeded, Distributable, Failed, Merged
-def make_new_domains(cs, variables):
- """updates variables with copied domains indexed by computation space"""
+def arrange_domains(cs, variables):
+ """build a data structure from var to dom
+ that satisfies distribute & friends"""
new_doms = {}
for var in variables:
new_doms[var] = var.cs_get_dom(cs).copy()
return new_doms
-class AbstractDistributor(object):
+class AbstractDistributor(Thread):
"""_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
@@ -47,7 +51,7 @@
def nb_subdomains(self):
"""return number of sub domains to explore"""
return self.nb_subspaces
-
+
def distribute(self, verbose=0):
"""do the minimal job and let concrete class distribute variables
"""
@@ -55,7 +59,7 @@
variables = self.cs.get_variables_with_a_domain()
replicas = []
for i in range(self.nb_subdomains()):
- replicas.append(make_new_domains(self.cs, variables))
+ replicas.append(arrange_domains(self.cs, variables))
modified_domains = self._distribute(*replicas)
for domain in modified_domains:
domain.reset_flags()
@@ -122,7 +126,34 @@
return min(self.nb_subspaces, self.__to_split.cs_get_dom(self.cs).size()) #domains[self.__to_split].size())
else:
return self.__to_split.cs_get_dom(self.cs).size() # domains[self.__to_split].size()
-
+
+ ### new threaded distributor
+
+ def run(self):
+ while self.cs.status == Distributable:
+ choice = self.cs.choose(self.nb_subdomains())
+ if self.cs.status == Failed:
+ return
+ self.new_distribute(choice)
+ self.cs._process()
+
+ def new_distribute(self, choice):
+ """See AbstractDistributor"""
+ variable = self.findSmallestDomain()
+ #variables = self.cs.get_variables_with_a_domain()
+ #domains = arrange_domains(self.cs, variables)
+ nb_subspaces = self.nb_subdomains()
+ values = variable.cs_get_dom(self.cs).get_values()
+ nb_elts = max(1, len(values)*1./nb_subspaces)
+ start, end = (int(math.floor(index * nb_elts)),
+ int(math.floor((index + 1) * nb_elts)))
+ variable.cs_get_dom(self.cs).remove_values(values[:start])
+ variable.cs_get_dom(self.cs).remove_values(values[end:])
+
+
+ ### current tests rely on this old
+ ### do_everything-at-once version
+
def _distribute(self, *args):
"""See AbstractDistributor"""
variable = self.__to_split
Added: pypy/dist/pypy/lib/logic/state.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/logic/state.py Fri Jan 27 17:37:08 2006
@@ -0,0 +1,19 @@
+
+class Succeeded:
+ """It contains no choice points but a solution to
+ the logic program.
+ """
+ pass
+
+class Distributable:
+ pass
+
+class Failed(Exception):
+ pass
+
+class Merged:
+ """Its constraint store has been added to a parent.
+ Any further operation operation on the space is
+ an error.
+ """
+ pass
Modified: pypy/dist/pypy/lib/logic/test_computationspace.py
==============================================================================
--- pypy/dist/pypy/lib/logic/test_computationspace.py (original)
+++ pypy/dist/pypy/lib/logic/test_computationspace.py Fri Jan 27 17:37:08 2006
@@ -474,8 +474,5 @@
assert new_spc.ask() == cs.Succeeded
assert w.cs_get_dom(spc) == c.FiniteDomain([5, 6, 7])
assert w.cs_get_dom(new_spc) == c.FiniteDomain([5])
-
-## with-space(spc):
-## assert w.dom == ... [5, 6, 7]
-## with-space(new_spc):
-## assert w.dom == ... [5]
+ spc.commit(0)
+ new_spc.commit(0)
Modified: pypy/dist/pypy/lib/logic/variable.py
==============================================================================
--- pypy/dist/pypy/lib/logic/variable.py (original)
+++ pypy/dist/pypy/lib/logic/variable.py Fri Jan 27 17:37:08 2006
@@ -103,6 +103,7 @@
self._doms[cs] = dom
def cs_get_dom(self, cs):
+ self._doms.setdefault(cs, FiniteDomain([]))
return self._doms[cs]
#---- Concurrent public ops --------------------------
More information about the Pypy-commit
mailing list