[pypy-svn] r32899 - pypy/dist/pypy/lib/constraint
auc at codespeak.net
auc at codespeak.net
Thu Oct 5 10:05:14 CEST 2006
Author: auc
Date: Thu Oct 5 10:04:59 2006
New Revision: 32899
Added:
pypy/dist/pypy/lib/constraint/
pypy/dist/pypy/lib/constraint/__init__.py (contents, props changed)
pypy/dist/pypy/lib/constraint/solver.py (contents, props changed)
Log:
solver belongs to lib
Added: pypy/dist/pypy/lib/constraint/__init__.py
==============================================================================
Added: pypy/dist/pypy/lib/constraint/solver.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/constraint/solver.py Thu Oct 5 10:04:59 2006
@@ -0,0 +1,87 @@
+
+class StrategyDistributionMismatch(Exception):
+ pass
+
+
+from collections import deque
+
+class Depth: pass
+class Breadth: pass
+
+#-- pythonic lazy solve_all (takes space)
+
+def lazily_iter_solve_all(space, direction=Depth):
+
+ sp_stack = deque([])
+ sp_stack.append(space)
+
+ if direction == Depth:
+ def collect(space):
+ sp_stack.append(space)
+ else:
+ def collect(space):
+ sp_stack.appendleft(space)
+
+ print "ready to find solution ..."
+ while sp_stack:
+ space = sp_stack.pop()
+ print ' '*len(sp_stack), "ask [depth = %s]" % len(sp_stack)
+ status = space.ask()
+ if status == 1:
+ print ' '*len(sp_stack), "solution !"
+ yield space.merge()
+ elif status > 1:
+ print ' '*len(sp_stack), "%s branches ..." % status
+ for i in xrange(status):
+ clone = space.clone()
+ clone.commit(status-i)
+ collect(clone)
+ elif status == 0:
+ print ' '*len(sp_stack), "dead-end"
+
+solve = lazily_iter_solve_all
+
+
+#-- dfs with recomputations
+
+
+def recompute(space, branches_list):
+ # branches_list contains the recomputation path,
+ # bottom-up
+ if branches_list == None:
+ return space.clone()
+ else:
+ head, tail = branches_list
+ C = recompute(space, tail)
+ C.ask()
+ C.commit(head)
+ return C
+
+def dfre(S, R, branches_list, distance, max_dist, solutions):
+ status = S.ask()
+ if status == 0:
+ return
+ elif status == 1:
+ solutions.append(S.merge())
+ return
+ else:
+ assert status == 2
+ if distance == max_dist:
+ C = S.clone()
+ S.commit(1)
+ dfre(S, C, (1,None), 1, max_dist, solutions)
+ C.commit(2)
+ dfre(C, C, None, max_dist, max_dist, solutions)
+ else:
+ S.commit(1)
+ dfre(S, R, (1, branches_list), distance+1, max_dist, solutions)
+ C = recompute(R, branches_list)
+ C.ask()
+ C.commit(2)
+ dfre(C, R, (2, branches_list), distance+1, max_dist, solutions)
+
+def solve_recomputing(space, recomputation_distance=5):
+ solutions = []
+ dfre(space, space, None, recomputation_distance, recomputation_distance, solutions)
+ return solutions
+
More information about the Pypy-commit
mailing list