diff doc/v2_planning/plugin_JB.py @ 1203:865936d8221b

v2planning plugin_JB - removed VM for clarity
author James Bergstra <bergstrj@iro.umontreal.ca>
date Mon, 20 Sep 2010 21:33:45 -0400
parents acfd5e747a75
children cbe1fb32686c
line wrap: on
line diff
--- a/doc/v2_planning/plugin_JB.py	Mon Sep 20 20:35:03 2010 -0400
+++ b/doc/v2_planning/plugin_JB.py	Mon Sep 20 21:33:45 2010 -0400
@@ -17,7 +17,7 @@
         FILT(pca.analyze)])
 
     # run the program
-    VirtualMachine(train_pca).run()
+    train_pca.run()
 
 The CALL, SEQ, FILT, and BUFFER_REPEAT are control-flow elements. The control-flow elements I
 defined so far are:
@@ -38,9 +38,11 @@
 
     - algorithms (including partially run ones) are COPYABLE, and SERIALIZABLE
 
-    - algorithms can be executed without seizing control of the python process (the VM is an
-      iterator) so your main loop (aka alternate VM implementation) can be checking for network
-      or filesystem events related to job management
+    - algorithms can be executed without seizing control of the python process (the run()
+      method does this, but if you look inside it you'll see it's a simple for loop)
+
+      - it is easy to execute an algorithm step by step in a main loop that also checks for
+        network or filesystem events related to e.g. job management.
 
     - the library can provide learning algorithms via control-flow templates, and the user can
       edit them (with search/replace calls) to include HOOKS, and DIAGNOSTIC plug-in
@@ -69,37 +71,6 @@
 import copy, sys, cPickle
 import numpy
 
-###################################################
-# Virtual Machine for executing programs
-
-class VirtualMachine(object):
-    def __init__(self, prog):
-        self.prog = prog
-        self.started = False
-        self.finished=False
-    def __iter__(self):
-        assert not self.started
-        self.prog.start(None)
-        self.started = True
-        return self
-    def next(self):
-        if self.finished:
-            raise StopIteration()
-        r = self.prog.step()
-        if r is INCOMPLETE:
-            return r
-        else:
-            self.finished=True
-            return r
-    def run(self,n_steps=float('inf')):
-        i = 0
-        for r in self:
-            i += 1
-            if i > n_steps:
-                break
-        return r
-
-
 ####################################################
 # CONTROL-FLOW CONSTRUCTS
 
@@ -108,7 +79,10 @@
 
 class ELEMENT(object):
     """
-    every execution block has a driver
+    Base class for control flow elements (e.g. CALL, REPEAT, etc.)
+
+    The design is that every element has a driver, that is another element, or the iterator
+    implementation in the ELEMENT class.
 
     the driver calls start when entering a new control element
        - this would be called once per e.g. outer loop iteration
@@ -118,11 +92,26 @@
        - which returns any other object to indicate completion
     """
 
+    # subclasses should override these methods:
     def start(self, arg):
         pass
     def step(self):
         pass
 
+    # subclasses should typically not override these:
+    def run(self, arg=None, n_steps=float('inf')):
+        self.start(arg)
+        i = 0
+        r = self.step()
+        while r is INCOMPLETE:
+            i += 1
+            #TODO make sure there is not an off-by-one error
+            if i > n_steps:
+                break
+            r = self.step()
+        return r
+
+
 class BUFFER_REPEAT(ELEMENT):
     """
     Accumulate a number of return values into one list / array.
@@ -223,6 +212,7 @@
         self.N = N
         self.elements = elements
         self.pass_rvals = pass_rvals
+
     #TODO: check for N being callable
     def start(self, arg):
         self.n = 0   #loop iteration
@@ -369,10 +359,10 @@
         l[0] += a
         return l[0]
 
-    print VirtualMachine(WEAVE([
+    print WEAVE([
         BUFFER_REPEAT(3,CALL(f,1)),
         BUFFER_REPEAT(5,CALL(f,1)),
-        ])).run()
+        ]).run()
 
 def main():
     # create components
@@ -434,7 +424,7 @@
     pkg = pkg2
 
     # running a program updates the variables in its package, but not the other package
-    VirtualMachine(pkg['prog']).run()
+    pkg['prog'].run()
     print pkg['kf'].scores