def create_0(cls, description, verbose): """ generated source for method create_0 """ print "Building propnet..." startTime = System.currentTimeMillis() description = GdlCleaner.run(description) description = DeORer.run(description) description = VariableConstrainer.replaceFunctionValuedVariables(description) description = Relationizer.run(description) description = CondensationIsolator.run(description) if verbose: for gdl in description: print gdl # We want to start with a rule graph and follow the rule graph. # Start by finding general information about the game model = SentenceDomainModelFactory.createWithCartesianDomains(description) # Restrict domains to values that could actually come up in rules. # See chinesecheckers4's "count" relation for an example of why this # could be useful. model = SentenceDomainModelOptimizer.restrictDomainsToUsefulValues(model) if verbose: print "Setting constants..." constantChecker = ConstantCheckerFactory.createWithForwardChaining(model) if verbose: print "Done setting constants" sentenceFormNames = SentenceForms.getNames(model.getSentenceForms()) usingBase = sentenceFormNames.contains("base") usingInput = sentenceFormNames.contains("input") # For now, we're going to build this to work on those with a # particular restriction on the dependency graph: # Recursive loops may only contain one sentence form. # This describes most games, but not all legal games. dependencyGraph = model.getDependencyGraph() if verbose: print "Computing topological ordering... ", System.out.flush() ConcurrencyUtils.checkForInterruption() topologicalOrdering = getTopologicalOrdering(model.getSentenceForms(), dependencyGraph, usingBase, usingInput) if verbose: print "done" roles = Role.computeRoles(description) components = HashMap() negations = HashMap() trueComponent = Constant(True) falseComponent = Constant(False) functionInfoMap = HashMap() completedSentenceFormValues = HashMap() for form in topologicalOrdering: ConcurrencyUtils.checkForInterruption() if verbose: print "Adding sentence form " + form, System.out.flush() if constantChecker.isConstantForm(form): if verbose: print " (constant)" # Only add it if it's important if form.__name__ == cls.LEGAL or form.__name__ == cls.GOAL or form.__name__ == cls.INIT: # Add it for trueSentence in constantChecker.getTrueSentences(form): trueProp.addInput(trueComponent) trueComponent.addOutput(trueProp) components.put(trueSentence, trueComponent) if verbose: print "Checking whether " + form + " is a functional constant..." addConstantsToFunctionInfo(form, constantChecker, functionInfoMap) addFormToCompletedValues(form, completedSentenceFormValues, constantChecker) continue if verbose: print # TODO: Adjust "recursive forms" appropriately # Add a temporary sentence form thingy? ... addSentenceForm(form, model, components, negations, trueComponent, falseComponent, usingBase, usingInput, Collections.singleton(form), temporaryComponents, temporaryNegations, functionInfoMap, constantChecker, completedSentenceFormValues) # TODO: Pass these over groups of multiple sentence forms if verbose and not temporaryComponents.isEmpty(): print "Processing temporary components..." processTemporaryComponents(temporaryComponents, temporaryNegations, components, negations, trueComponent, falseComponent) addFormToCompletedValues(form, completedSentenceFormValues, components) # if(verbose) # TODO: Add this, but with the correct total number of components (not just Propositions) # print " "+completedSentenceFormValues.get(form).size() + " components added"; # Connect "next" to "true" if verbose: print "Adding transitions..." addTransitions(components) # Set up "init" proposition if verbose: print "Setting up 'init' proposition..." setUpInit(components, trueComponent, falseComponent) # Now we can safely... removeUselessBasePropositions(components, negations, trueComponent, falseComponent) if verbose: print "Creating component set..." componentSet = HashSet(components.values()) # Try saving some memory here... components = None negations = None completeComponentSet(componentSet) ConcurrencyUtils.checkForInterruption() if verbose: print "Initializing propnet object..." # Make it look the same as the PropNetFactory results, until we decide # how we want it to look normalizePropositions(componentSet) propnet = PropNet(roles, componentSet) if verbose: print "Done setting up propnet; took " + (System.currentTimeMillis() - startTime) + "ms, has " + len(componentSet) + " components and " + propnet.getNumLinks() + " links" print "Propnet has " + propnet.getNumAnds() + " ands; " + propnet.getNumOrs() + " ors; " + propnet.getNumNots() + " nots" # print propnet; return propnet
def run(cls, description): """ generated source for method run """ # This class is not put together in any "optimal" way, so it's left in # an unpolished state for now. A better version would use estimates of # the impact of breaking apart rules. (It also needs to stop itself from # making multiple new relations with the same meaning.) # This version will be rather advanced. # In particular, it will try to incorporate # 1) More thorough scanning for condensations; # 2) Condensations that are only safe to perform because of mutexes. # TODO: Don't perform condensations on stuff like (add _ _ _)... # In general, don't perform condensations where the headroom is huge? # Better yet... DON'T perform condensations on recursive functions! # As for headroom... maybe make sure that # of vars eliminated > # "kept" # Or make sure none are kept? Use directional connected components? description = GdlCleaner.run(description) description = DeORer.run(description) description = VariableConstrainer.replaceFunctionValuedVariables(description) # How do we define a condensation, and what needs to be true in it? # Definition: A condensation set is a set of conjuncts of a # sentence. # Restrictions: # 1) There must be some variable not in the head of the sentence that # appears exclusively in the condensation set. (This means we can # easily find sets one of which must be a condensation set.) # 2) For any variable appearing in a distinct or not conjunct in the set, # there must be a positive conjunct in the set also containing that # variable. This does apply to variables found in the head. # 3) There must be at least one non-distinct literal outside the # condensation set. # How mutexes work: # Say we have a rule # (<= (r1 ?b) # (r2 ?a ?b ?c) # (r3 ?b ?c) # (r4 ?a) # (r5 ?c)) # If we wanted to factor out ?a, we'd normally have to do # (<= (r6 ?b ?c) # * (r2 ?a ?b ?c) # * (r4 ?a)) # * (<= (r1 ?b) # * (r6 ?b ?c) # * (r3 ?b ?c) # * (r5 ?c)) # * But if we know r2 is a mutex, instead we can do (notice r2 splitting): # * (<= (r6 ?b) # * (r2 ?a ?b ?c) # * (r4 ?a)) # * (<= (r1 ?b) # * (r2 ?a ?b ?c) # * (r6 ?b) # * (r3 ?b ?c) # * (r5 ?c)) # * Which in turn becomes: # * (<= (r6 ?b) # * (r2 ?a ?b ?c) # * (r4 ?a)) # * (<= (r7 ?b) # * (r2 ?a ?b ?c) # * (r3 ?b ?c) # * (r5 ?c)) # * (<= (r1 ?b) # * (r6 ?b) # * (r7 ?b)) # * Both r6 and r7 can be further condensed to ignore ?c and ?a, # * respectively. What just happened? # * 1) The condensation set for ?a included the mutex r2. # * 2) r2 (by itself) would have required ?c to be included as an # * argument passed back to the original rule, which is undesirable. # * Instead, as it's a mutex, we leave a copy in the original rule # * and don't include the ?c. # * # * So, what kind of algorithm can we find to solve this task? # newDescription = ArrayList() rulesToAdd = LinkedList() for gdl in description: if isinstance(gdl, (GdlRule, )): rulesToAdd.add(gdl) else: newDescription.add(gdl) # Don't use the model indiscriminately; it reflects the old description, # not necessarily the new one model = SentenceDomainModelFactory.createWithCartesianDomains(description) model = SentenceDomainModelOptimizer.restrictDomainsToUsefulValues(model) sentenceNameSource = UnusedSentenceNameSource.create(model) constantChecker = ConstantCheckerFactory.createWithForwardChaining(model) constantForms = model.getConstantSentenceForms() ConcurrencyUtils.checkForInterruption() curDescription = Lists.newArrayList(description) while not rulesToAdd.isEmpty(): if isRecursive(curRule): # Don't mess with it! newDescription.add(curRule) continue if SentenceModelUtils.inSentenceFormGroup(curRuleHead, constantForms): newDescription.add(curRule) continue ConcurrencyUtils.checkForInterruption() if condensationSet != None: rulesToAdd.addAll(newRules) # Since we're making only small changes, we can readjust # the model as we go, instead of recomputing it replacementDescription.removeAll(oldRules) replacementDescription.addAll(newRules) curDescription = replacementDescription model = augmentModelWithNewForm(model, newRules) else: newDescription.add(curRule) return newDescription