def getVarsInLiveConjuncts(cls, rule, constantSentenceForms): """ generated source for method getVarsInLiveConjuncts """ result = HashSet() for literal in rule.getBody(): if isinstance(literal, (GdlRelation, )): if not SentenceModelUtils.inSentenceFormGroup(literal, constantSentenceForms): result.addAll(GdlUtils.getVariables(literal)) elif isinstance(literal, (GdlNot, )): if not SentenceModelUtils.inSentenceFormGroup(inner, constantSentenceForms): result.addAll(GdlUtils.getVariables(literal)) return result
def addSentenceForm(cls, form, model, components, negations, trueComponent, falseComponent, usingBase, usingInput, recursionForms, temporaryComponents, temporaryNegations, functionInfoMap, constantChecker, completedSentenceFormValues): """ generated source for method addSentenceForm """ alwaysTrueSentences = model.getSentencesListedAsTrue(form) rules = model.getRules(form) for alwaysTrueSentence in alwaysTrueSentences: if alwaysTrueSentence.__name__ == cls.LEGAL or alwaysTrueSentence.__name__ == cls.NEXT or alwaysTrueSentence.__name__ == cls.GOAL: trueComponent.addOutput(prop) prop.addInput(trueComponent) components.put(alwaysTrueSentence, trueComponent) negations.put(alwaysTrueSentence, falseComponent) continue if usingInput and form.__name__ == cls.DOES: for inputSentence in constantChecker.getTrueSentences(inputForm): components.put(doesSentence, prop) return if usingBase and form.__name__ == cls.TRUE: for baseSentence in constantChecker.getTrueSentences(baseForm): components.put(trueSentence, prop) return inputsToOr = HashMap() for rule in rules: varsInLiveConjuncts.addAll(GdlUtils.getVariables(rule.getHead())) while asnItr.hasNext(): if assignment == None: continue ConcurrencyUtils.checkForInterruption() for literal in rule.getBody(): if isinstance(literal, (GdlSentence, )): if constantChecker.isConstantForm(conjunctForm): if not constantChecker.isTrueConstant(transformed): asnItr.changeOneInNext(varsToChange, assignment) componentsToConnect.add(None) continue if conj == None: conj = temporaryComponents.get(transformed) if conj == None and SentenceModelUtils.inSentenceFormGroup(transformed, recursionForms): temporaryComponents.put(transformed, tempProp) conj = tempProp if conj == None or isThisConstant(conj, falseComponent): asnItr.changeOneInNext(varsInConjunct, assignment) componentsToConnect.add(None) continue componentsToConnect.add(conj) elif isinstance(literal, (GdlNot, )): if constantChecker.isConstantForm(conjunctForm): if constantChecker.isTrueConstant(transformed): asnItr.changeOneInNext(varsToChange, assignment) componentsToConnect.add(None) continue if isThisConstant(conj, falseComponent): asnItr.changeOneInNext(varsInConjunct, assignment) componentsToConnect.add(None) continue if conj == None: conj = temporaryNegations.get(transformed) if conj == None and SentenceModelUtils.inSentenceFormGroup(transformed, recursionForms): if positive == None: positive = temporaryComponents.get(transformed) if positive == None: temporaryComponents.put(transformed, tempProp) positive = tempProp not_.addInput(positive) positive.addOutput(not_) temporaryNegations.put(transformed, not_) conj = not_ if conj == None: if positive == None: continue if existingNotOutput != None: componentsToConnect.add(existingNotOutput) negations.put(transformed, existingNotOutput) continue not_.addInput(positive) positive.addOutput(not_) negations.put(transformed, not_) conj = not_ componentsToConnect.add(conj) elif isinstance(literal, (GdlDistinct, )): else: raise RuntimeException("Unwanted GdlLiteral type") if not componentsToConnect.contains(None): andify(componentsToConnect, andComponent, trueComponent) if not isThisConstant(andComponent, falseComponent): if not inputsToOr.containsKey(sentence): inputsToOr.put(sentence, HashSet()) inputsToOr.get(sentence).add(andComponent) if preventDuplicatesFromConstants: asnItr.changeOneInNext(varsInLiveConjuncts, assignment) for entry in inputsToOr.entrySet(): ConcurrencyUtils.checkForInterruption() for input in inputs: if isinstance(input, (Constant, )) or input.getInputs().size() == 0: realInputs.add(input) else: realInputs.add(input.getSingleInput()) input.getSingleInput().removeOutput(input) input.removeAllInputs() cls.orify(realInputs, prop, falseComponent) components.put(sentence, prop) if form.__name__ == cls.TRUE or form.__name__ == cls.DOES: for sentence in model.getDomain(form): ConcurrencyUtils.checkForInterruption() components.put(sentence, prop)
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