[pypy-svn] r32848 - in pypy/dist/pypy/objspace/cclp: . constraint

auc at codespeak.net auc at codespeak.net
Tue Oct 3 17:48:08 CEST 2006


Author: auc
Date: Tue Oct  3 17:47:51 2006
New Revision: 32848

Modified:
   pypy/dist/pypy/objspace/cclp/constraint/distributor.py
   pypy/dist/pypy/objspace/cclp/space.py
   pypy/dist/pypy/objspace/cclp/thunk.py
Log:
unified cspace/distibutor thunks, preliminary support for cspace interpreted clone() support (for constraints)


Modified: pypy/dist/pypy/objspace/cclp/constraint/distributor.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/constraint/distributor.py	(original)
+++ pypy/dist/pypy/objspace/cclp/constraint/distributor.py	Tue Oct  3 17:47:51 2006
@@ -10,33 +10,34 @@
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.stringobject import W_StringObject
 
-from pypy.objspace.cclp.types import W_AbstractDistributor, Solution
-from pypy.objspace.cclp.thunk import DistributorThunk
+from pypy.objspace.cclp.types import W_AbstractDistributor, Solution, W_Var
 from pypy.objspace.cclp.misc import w, ClonableCoroutine, get_current_cspace
 from pypy.objspace.cclp.global_state import scheduler
-from pypy.objspace.cclp.interp_var import interp_free
-
-def spawn_distributor(space, distributor):
-    thread = ClonableCoroutine(space)
-    thread._cspace = get_current_cspace(space)
-    thunk = DistributorThunk(space, distributor, thread)
-    thread.bind(thunk)
-    if not we_are_translated():
-        w("DISTRIBUTOR THREAD", str(id(thread)))
-    scheduler[0].add_new_thread(thread)
-    scheduler[0].schedule()
+from pypy.objspace.cclp.interp_var import interp_free, interp_bind
 
 def distribute(space, w_strategy):
     assert isinstance(w_strategy, W_StringObject)
     strat = space.str_w(w_strategy)
-    if strat == 'naive':
-        pass
-    elif strat == 'dichotomy':
-        dist = make_split_distributor(space, space.newint(2))
-        spawn_distributor(space, dist)
+    cspace = get_current_cspace(space)
+    if strat == 'dichotomy':
+         cspace.distributor = make_split_distributor(space, space.newint(2))
     else:
         raise OperationError(space.w_RuntimeError,
                              space.wrap("please pick a strategy in (naive, dichotomy)"))
+
+    dist = cspace.distributor
+    # constraint distributor thread main loop
+    try:
+        while dist.distributable():
+            choice = cspace.choose(dist.fanout())
+            dist.w_distribute(choice)
+    except ConsistencyError, e:
+        w("-- DISTRIBUTOR thunk exited because", str(e))
+        cspace.fail()
+    except Exception, eek:
+        if not we_are_translated():
+            import traceback
+            traceback.print_exc()
 app_distribute = interp2app(distribute)
 
 

Modified: pypy/dist/pypy/objspace/cclp/space.py
==============================================================================
--- pypy/dist/pypy/objspace/cclp/space.py	(original)
+++ pypy/dist/pypy/objspace/cclp/space.py	Tue Oct  3 17:47:51 2006
@@ -8,13 +8,22 @@
 from pypy.objspace.cclp.thunk import CSpaceThunk, PropagatorThunk
 from pypy.objspace.cclp.global_state import scheduler
 from pypy.objspace.cclp.variable import newvar
-from pypy.objspace.cclp.types import ConsistencyError, Solution, W_Var
+from pypy.objspace.cclp.types import ConsistencyError, Solution, W_Var, \
+     W_CVar, W_AbstractDomain
 from pypy.objspace.cclp.interp_var import interp_bind, interp_free
 
+
+class DummyCallable(baseobjspace.W_Root):
+    def __call__(self): pass
+
+dummy_function = DummyCallable()
+dummy_args = argument.Arguments([])
+
 def newspace(space, w_callable, __args__):
     args = __args__.normalize()
     # coro init
     w_coro = ClonableCoroutine(space)
+    #w_callable : a logic or constraint script ????
     thunk = CSpaceThunk(space, w_callable, args, w_coro)
     w_coro.bind(thunk)
     if not we_are_translated():
@@ -62,7 +71,9 @@
         assert (parent is None) or isinstance(parent, W_CSpace)
         self.space = space # the object space ;-)
         self.parent = parent
-        self.distributor = thread
+        self.dist_thread = thread
+        self.distributor = None
+        self.distributor_is_logic_script = True
         # choice mgmt
         self._choice = newvar(space)
         self._committed = newvar(space)
@@ -72,9 +83,47 @@
         self._failed = False
         # constraint store ...
         self._store = {} # name -> var
+        if not we_are_translated():
+            self._constraints = []
+            self._choose_count = 0
+            self._commit_count = 0
         
     def register_var(self, cvar):
         self._store[cvar.name] = cvar
+        self.distributor_is_logic_script = False
+
+    def clone(self):
+        if not we_are_translated():
+            print "<-CLONE !! -----------------------------------------------------------------------"            
+            # build fresh cspace & distributor thread
+            thread = ClonableCoroutine(self.space)
+            new_cspace = W_CSpace(self.space, thread, None)
+            thread._cspace = new_cspace
+            # new distributor
+            old_dist = self.dist_thread.thunk.dist
+            new_dist = old_dist.__class__(self.space, old_dist._fanout)
+            new_dist._cspace = new_cspace
+            # new distributor thunk
+            thunk = CSpaceThunk(self.space, self.space.wrap(dummy_function), dummy_args, thread)
+            thread.bind(thunk)
+            scheduler[0].add_new_thread(thread)
+            # copy the store
+            for var in self._store.values():
+                new_cspace.register_var(var.copy(self.space))
+            assert self.dist_thread.thunk.dist.distributable()
+            # rebuild propagators
+            for const in self._constraints:
+                new_cspace.tell(const)
+            # other attrs
+            new_cspace._solution = newvar(self.space)
+            self.space.unify(new_cspace._solution, self.space.newlist(self._store.values()))
+            if hasattr(self, '_last_choice'):
+                new_cspace._last_choice = self._last_choice
+            print "LOOOOK at that : ", new_cspace._committed, self._committed
+            return new_cspace
+        else:
+            raise NotImplementedError
+
 
     def w_ask(self):
         scheduler[0].wait_stable(self)
@@ -99,9 +148,14 @@
         return committed
 
     def w_commit(self, w_n):
+        self._commit_count += 1
+        #scheduler[0].wait_stable(self)
+        self._commit_count += 1
         assert isinstance(w_n, W_IntObject)
         n = w_n.intval
-        assert interp_free(self._committed)
+        if not interp_free(self._committed):
+            import pdb
+            pdb.set_trace()
         assert n > 0
         assert n <= self._last_choice
         interp_bind(self._committed, w_n)
@@ -114,6 +168,7 @@
         w_coro.bind(thunk)
         if not we_are_translated():
             w("PROPAGATOR in thread", str(id(w_coro)))
+            self._constraints.append(w_constraint)
         scheduler[0].add_new_thread(w_coro)
         scheduler[0].schedule()
 
@@ -125,6 +180,15 @@
 
     def w_merge(self):
         self._store = {}
+        # let's bind the solution variables
+        sol = self._solution.w_bound_to
+        if contains_cvar(sol.wrappeditems):
+            for var in sol.wrappeditems:
+                assert isinstance(var, W_CVar)
+                dom = var.w_dom
+                assert isinstance(dom, W_AbstractDomain)
+                assert dom.size() == 1
+                interp_bind(var, dom.get_values()[0])
         return self._solution
 
     def __ne__(self, other):
@@ -133,7 +197,15 @@
         return True
 
 
+def contains_cvar(lst):
+    for elt in lst:
+        if isinstance(elt, W_CVar):
+            return True
+    return False
+
+
 W_CSpace.typedef = typedef.TypeDef("W_CSpace",
     ask = gateway.interp2app(W_CSpace.w_ask),
     commit = gateway.interp2app(W_CSpace.w_commit),
+    clone = gateway.interp2app(W_CSpace.clone),
     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	Tue Oct  3 17:47:51 2006
@@ -9,6 +9,7 @@
      interp_bind, interp_free, interp_wait_or
 
 from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_TupleObject
 from pypy.rpython.objectmodel import we_are_translated
 
 def logic_args(args):
@@ -80,33 +81,42 @@
         _AppThunk.__init__(self, space, coro.costate, w_callable, args)
         self._coro = coro
 
-    def is_distributor(self):
-        return self._coro == self._coro._cspace.distributor
-
     def call(self):
         w("-- initial thunk CALL in", str(id(self._coro)))
         scheduler[0].trace_vars(self._coro, logic_args(self.args.unpack()))
         cspace = self._coro._cspace
-        cspace.distributor = self._coro
         space = self.space
         try:
             try:
+                #if self.runs_a_logic_script():
                 _AppThunk.call(self)
             except Exception, exc:
-                # maybe app_level sent something ...
-                w("-- exceptional EXIT of cspace", str(id(self._coro)), "with", str(exc))
+                # maybe app_level let something buble up ...
+                w("-- exceptional EXIT of cspace DISTRIBUTOR", str(id(self._coro)), "with", str(exc))
                 failed_value = W_FailedValue(exc)
                 scheduler[0].dirty_traced_vars(self._coro, failed_value)
-                self._coro._dead = True
-                if self.is_distributor():
-                    cspace.fail()
                 interp_bind(cspace._solution, failed_value)
+                cspace.fail()
             else:
-                w("-- clean (valueless) EXIT of cspace", str(id(self._coro)))
-                interp_bind(cspace._solution, self.costate.w_tempval)
-                if self.is_distributor():
-                    interp_bind(cspace._choice, space.newint(1))
+                w("-- clean EXIT of DISTRIBUTOR (success)", str(id(self._coro)))
+                try:
+                    sol = cspace._solution
+                    assert isinstance(sol, W_Var)
+                    interp_bind(sol, self.costate.w_tempval)
+                    outcome = sol.w_bound_to
+                    if not (isinstance(outcome, W_ListObject) or \
+                            isinstance(outcome, W_TupleObject)):
+                        w("WARINING: return value type of the script was not a list or tuple, we do nothing ...")
+                        return
+                    assert interp_free(cspace._choice)
+                    interp_bind(cspace._choice, self.space.newint(1))
+                except Exception, foo:
+                    print "WE DIED BECAUSE", str(foo)
+                    import pdb
+                    pdb.set_trace()
+                
         finally:
+            interp_bind(cspace._finished, self.space.w_True)
             scheduler[0].remove_thread(self._coro)
             scheduler[0].schedule()
 
@@ -150,44 +160,3 @@
             scheduler[0].remove_thread(self.coro)
             scheduler[0].schedule()
 
-
-class DistributorThunk(AbstractThunk):
-    def __init__(self, space, w_distributor, coro):
-        self.space = space
-        self.coro = coro
-        self.dist = w_distributor
-
-    def call(self):
-        coro = self.coro
-        cspace = coro._cspace
-        try:
-            cspace.distributor = coro
-            dist = self.dist
-            try:
-                while dist.distributable():
-                    choice = cspace.choose(dist.fanout())
-                    dist.w_distribute(choice)
-            except ConsistencyError, e:
-                w("-- DISTRIBUTOR thunk exited because", str(e))
-                interp_bind(cspace._choice, self.space.newint(0))
-            else:
-                w("-- DISTRIBUTOR thunk exited because a solution was found")
-                #XXX assert that all propagators are entailed
-                sol = cspace._solution
-                assert isinstance(sol, W_Var)
-                varset = sol.w_bound_to
-                assert isinstance(varset, W_ListObject)
-                for var in varset.wrappeditems:
-                    assert isinstance(var, W_CVar)
-                    dom = var.w_dom
-                    assert isinstance(dom, W_AbstractDomain)
-                    assert dom.size() == 1
-                    interp_bind(var, dom.get_values()[0])
-                assert interp_free(cspace._choice)
-                interp_bind(cspace._choice, self.space.newint(1))
-        finally:
-            interp_bind(cspace._finished, self.space.w_True)
-            coro._dead = True
-            scheduler[0].remove_thread(coro)
-            scheduler[0].schedule()
-        



More information about the Pypy-commit mailing list