class BasicProcessTreeBuilder(object): def __init__(self, drivingEngine, exp): self.drivingEngine = drivingEngine self.tree = ProcessTree(exp) # The parts common to the basic and advanced supercompilers. # If beta `instOf` alpha, we generalize beta by introducing # a let-expression, in order to make beta the same as alpha # (modulo variable names). def loopBack(self, beta, alpha): subst = matchAgainst(alpha.exp, beta.exp) bindings = list(subst.items()) bindings.sort() letExp = Let(alpha.exp, bindings) self.tree.replaceSubtree(beta, letExp) # This function applies a driving step to the node's expression, # and, in general, adds children to the node. def expandNode(self, beta): branches = self.drivingEngine.drivingStep(beta.exp) self.tree.addChildren(beta, branches) # Basic supercompiler process tree builder def buildStep(self, beta): """ This method is overridden in the advanced version of the process tree builder. """ alpha = beta.findMoreGeneralAncestor() if alpha: self.loopBack(beta, alpha) else: self.expandNode(beta) def buildProcessTree(self, k): # Specifying k = -1 results in an unlimited building loop. while True: if k == 0: break k -= 1 beta = self.tree.findUnprocessedNode() if not beta: break self.buildStep(beta)