Ejemplo n.º 1
0
 def getCondensationSet(cls, rule, model, checker, sentenceNameSource):
     """ generated source for method getCondensationSet """
     varsInRule = GdlUtils.getVariables(rule)
     varsInHead = GdlUtils.getVariables(rule.getHead())
     varsNotInHead = ArrayList(varsInRule)
     varsNotInHead.removeAll(varsInHead)
     for var in varsNotInHead:
         ConcurrencyUtils.checkForInterruption()
         for literal in rule.getBody():
             if GdlUtils.getVariables(literal).contains(var):
                 minSet.add(literal)
         for literal in minSet:
             if isinstance(literal, (GdlRelation, )):
                 varsSupplied.addAll(GdlUtils.getVariables(literal))
             elif isinstance(literal, (GdlDistinct, )) or isinstance(literal, (GdlNot, )):
                 varsNeeded.addAll(GdlUtils.getVariables(literal))
         varsNeeded.removeAll(varsSupplied)
         if not varsNeeded.isEmpty():
             continue 
         for varNeeded in varsNeeded:
             for literal in rule.getBody():
                 if isinstance(literal, (GdlRelation, )):
                     if GdlUtils.getVariables(literal).contains(varNeeded):
                         suppliers.add(literal)
             candidateSuppliersList.add(suppliers)
         for suppliers in candidateSuppliersList:
             if Collections.disjoint(suppliers, literalsToAdd):
                 literalsToAdd.add(suppliers.iterator().next())
         minSet.addAll(literalsToAdd)
         if goodCondensationSetByHeuristic(minSet, rule, model, checker, sentenceNameSource):
             return minSet
     return None
Ejemplo n.º 2
0
 def getFunctionAddedChildren(self, analyticFunctionOrdering):
     """ generated source for method getFunctionAddedChildren """
     # We can't just add those functions that
     # are "ready" to be added. We should be adding all those variables
     # "leading up to" the functions and then applying the functions.
     # We can even take this one step further by only adding one child
     # per remaining constant function; we choose as our function output the
     # variable that is a candidate for functionhood that has the
     # largest domain, or one that is tied for largest.
     # New criterion: Must also NOT be in preassignment.
     children = ArrayList()
     # It would be really nice here to just analytically choose
     # the set of functions we're going to use.
     # Here's one approach for doing that:
     # For each variable, get a list of the functions that could
     # potentially produce it.
     # For all the variables with no functions, add them.
     # Then repeatedly find the function with the fewest
     # number of additional variables (hopefully 0!) needed to
     # specify it and add it as a function.
     # The goal here is not to be optimal, but to be efficient!
     # Certain games (e.g. Pentago) break the old complete search method!
     # TODO: Eventual possible optimization here:
     # If something is dependent on a connected component that it is
     # not part of, wait until the connected component is resolved
     # (or something like that...)
     if analyticFunctionOrdering and len(self.functionalSentencesInfo) > 8:
         # For each variable, a list of functions
         # (refer to functions by their indices)
         # and the set of outstanding vars they depend on...
         # We start by adding to the varOrdering the vars not produced by functions
         # First, we have to find them
         while i < len(self.functionalSentencesInfo):
             for producibleVar in producibleVars:
                 if not functionsProducingVars.containsKey(producibleVar):
                     functionsProducingVars.put(producibleVar, HashSet())
                 functionsProducingVars.get(producibleVar).add(i)
             i += 1
         # Non-producible vars get iterated over before we start
         # deciding which functions to add
         for var in varsToAssign:
             if not self.varOrdering.contains(var):
                 if not functionsProducingVars.containsKey(var):
                     # Add var to the ordering
                     self.varOrdering.add(var)
                     self.functionalConjunctIndices.add(-1)
                     self.varSources.add(-1)
         # Map is from potential set of dependencies to function indices
         # Create this map...
         while i < len(self.functionalSentencesInfo):
             # Variables already in varOrdering don't go in dependents list
             producibleVars.removeAll(self.varOrdering)
             allVars.removeAll(self.varOrdering)
             for producibleVar in producibleVars:
                 dependencies.addAll(allVars)
                 dependencies.remove(producibleVar)
                 if not functionsHavingDependencies.containsKey(dependencies):
                     functionsHavingDependencies.put(dependencies, HashSet())
                 functionsHavingDependencies.get(dependencies).add(i)
             i += 1
         # Now, we can keep creating functions to generate the remaining variables
         while len(self.varOrdering) < len(self.varsToAssign):
             if functionsHavingDependencies.isEmpty():
                 raise RuntimeException("We should not run out of functions we could use")
             # Find the smallest set of dependencies
             if functionsHavingDependencies.containsKey(Collections.emptySet()):
                 dependencySetToUse = Collections.emptySet()
             else:
                 for dependencySet in functionsHavingDependencies.keySet():
                     if len(dependencySet) < smallestSize:
                         smallestSize = len(dependencySet)
                         dependencySetToUse = dependencySet
             # See if any of the functions are applicable
             for function_ in functions:
                 producibleVars.removeAll(dependencySetToUse)
                 producibleVars.removeAll(self.varOrdering)
                 if not producibleVars.isEmpty():
                     functionToUse = function_
                     varProduced = producibleVars.iterator().next()
                     break
             if functionToUse == -1:
                 # None of these functions were actually useful now?
                 # Dump the dependency set
                 functionsHavingDependencies.remove(dependencySetToUse)
             else:
                 # Apply the function
                 # 1) Add the remaining dependencies as iterated variables
                 for var in dependencySetToUse:
                     self.varOrdering.add(var)
                     self.functionalConjunctIndices.add(-1)
                     self.varSources.add(-1)
                 # 2) Add the function's produced variable (varProduced)
                 self.varOrdering.add(varProduced)
                 self.functionalConjunctIndices.add(functionToUse)
                 self.varSources.add(-1)
                 # 3) Remove all vars added this way from all dependency sets
                 addedVars.addAll(dependencySetToUse)
                 addedVars.add(varProduced)
                 # Tricky, because we have to merge sets
                 # Easier to use a new map
                 for entry in functionsHavingDependencies.entrySet():
                     newKey.removeAll(addedVars)
                     if not newFunctionsHavingDependencies.containsKey(newKey):
                         newFunctionsHavingDependencies.put(newKey, HashSet())
                     newFunctionsHavingDependencies.get(newKey).addAll(entry.getValue())
                 functionsHavingDependencies = newFunctionsHavingDependencies
                 # 4) Remove this function from the lists?
                 for functionSet in functionsHavingDependencies.values():
                     functionSet.remove(functionToUse)
         # Now we need to actually return the ordering in a list
         # Here's the quick way to do that...
         # (since we've added all the new stuff to ourself already)
         return Collections.singletonList(IterationOrderCandidate(self))
     else:
         # Let's try a new technique for restricting the space of possibilities...
         # We already have an ordering on the functions
         # Let's try to constrain things to that order
         # Namely, if i<j and constant form j is already used as a function,
         # we cannot use constant form i UNLESS constant form j supplies
         # as its variable something used by constant form i.
         # We might also try requiring that c.f. i NOT provide a variable
         # used by c.f. j, though there may be multiple possibilities as
         # to what it could provide.
         if not self.functionalConjunctIndices.isEmpty():
             lastFunctionUsedIndex = Collections.max(self.functionalConjunctIndices)
         while i < len(self.functionalConjunctIndices):
             if self.functionalConjunctIndices.get(i) != -1:
                 varsProducedByFunctions.add(self.varOrdering.get(i))
             i += 1
         while i < len(self.functionalSentencesInfo):
             if i < lastFunctionUsedIndex:
                 # We need to figure out whether i could use any of the
                 # vars we're producing with functions
                 # TODO: Try this with a finer grain
                 # i.e., see if i needs a var from a function that is after
                 # it, not one that might be before it
                 if Collections.disjoint(varsInSentence, varsProducedByFunctions):
                     continue 
             # What is the best variable to grab from this form, if there are any?
             if bestVariable == None:
                 continue 
             children.add(newCandidate)
             i += 1
         # If there are no more functions to add, add the completed version
         if children.isEmpty():
             children.add(IterationOrderCandidate(self))
         return children