Exemple #1
0
def toCNF(gndFormulas, formulas, allPositive=False):
    '''
    convert the given ground formulas to CNF
    if allPositive=True, then formulas with negative weights are negated to make all weights positive
    @return a new pair (gndFormulas, formulas)
    '''
    # get list of formula indices where we must negate
    newFormulas = []
    negate = []
    if allPositive:
        for idxFormula, formula in enumerate(formulas):
            f = formula
            if formula.weight < 0:
                negate.append(idxFormula)
                if isinstance(formula, FOL.Negation):
                    f = formula.children[0]
                else:
                    f = FOL.Negation([formula])
                f.weight = -formula.weight
                f.idxFormula = idxFormula
            newFormulas.append(f)
    # get CNF version of each ground formula
    newGndFormulas = []
    for gf in gndFormulas:
        # non-logical constraint
        if not gf.isLogical(
        ):  # don't apply any transformations to non-logical constraints
            if gf.idxFormula in negate:
                gf.negate()
            newGndFormulas.append(gf)
            continue
        # logical constraint
        if gf.idxFormula in negate:
            cnf = FOL.Negation([gf]).toCNF()
        else:
            cnf = gf.toCNF()
        if type(
                cnf
        ) == FOL.TrueFalse:  # formulas that are always true or false can be ignored
            continue
        cnf.idxFormula = gf.idxFormula
        newGndFormulas.append(cnf)
    # return modified formulas
    return (newGndFormulas, newFormulas)
Exemple #2
0
 def _expandQueries(self, queries):
     ''' expands the list of queries where necessary, e.g. queries that are just predicate names are expanded to the corresponding list of atoms '''
     equeries = []
     for query in queries:
         #print "got query '%s' of type '%s'" % (str(query), str(type(query)))
         if type(query) == str:
             prevLen = len(equeries)
             if "(" in query: # a fully or partially grounded formula
                 f = FOL.parseFormula(query)
                 for gndFormula in f.iterGroundings(self.mln):
                     equeries.append(gndFormula[0])
             else: # just a predicate name
                 try:
                     for gndPred in self.mln._getPredGroundings(query):
                         equeries.append(FOL.parseFormula(gndPred).ground(self.mln, {}))
                 except:
                     raise #Exception("Could not expand query '%s'" % query)
             if len(equeries) - prevLen == 0:
                 raise Exception("String query '%s' could not be expanded." % query)
         elif isinstance(query, FOL.Formula):
             equeries.append(query)
         else:
             raise Exception("Received query of unsupported type '%s'" % str(type(query)))
     return equeries
Exemple #3
0
    def _groundAtoms(self, cur, predName, domNames, verbose=False):
        # if there are no more parameters to ground, we're done
        # and we cann add the ground atom to the MRF
        mrf = self.mrf
        assert len(mrf.gndFormulas) == 0
        if domNames == []:
            atom = FOL.GroundAtom(predName, cur)
            mrf.addGroundAtom(atom)
            return

        # create ground atoms for each way of grounding the first of the 
        # remaining variables whose domains are given in domNames
        dom = mrf.domains.get(domNames[0])
        if dom is None or len(dom) == 0:
            raise Exception("Domain '%s' is empty!" % domNames[0])
        for value in dom:
            self._groundAtoms(cur + [value], predName, domNames[1:])
Exemple #4
0
    def _infer(self, verbose=True, details=False, fittingMethod=InferenceMethods.Exact, fittingThreshold=1e-3, fittingSteps=100, fittingParams=None, maxThreshold=None, greedy=False, **args):
        # add formulas to the model whose weights we can then fit
        if verbose: print "extending model with %d formulas whose weights will be fit..." % len(self.mrf.softEvidence)
        for req in self.mrf.softEvidence:            
            formula = FOL.parseFormula(req["expr"])
            idxFormula = self.mrf._addFormula(formula, 0.0)                        
            gndFormula = formula.ground(self.mrf, {})
            self.mrf._addGroundFormula(gndFormula, idxFormula)
            req["gndExpr"] = req["expr"]
            req["gndFormula"] = gndFormula
            req["idxFormula"] = idxFormula     

        # do fitting
        if fittingParams is None: fittingParams = {}
        fittingParams.update(args)
        results, self.data = self.mrf._fitProbabilityConstraints(self.mrf.softEvidence, fittingMethod=fittingMethod, fittingThreshold=fittingThreshold, fittingSteps=fittingSteps, given=self.given, queries=self.queries, verbose=details, fittingParams=fittingParams, maxThreshold=maxThreshold, greedy=greedy)
        
        return results
Exemple #5
0
 def getValidVariableAssignments(self, conjunction, trueOrFalse, gndAtoms):
     variableAssignments = []
     gndAtomIndices = []
     for lit in conjunction.children:
         assignments = []
         atomIndices = []
         for gndAtom in gndAtoms:
             try:
                 if gndAtom.predName != lit.predName: 
                     continue
                 assignment = []
                 for (p1, p2) in zip(lit.params, gndAtom.params):
                     if FOL.isVar(p1):
                         assignment.append((p1, p2))
                     elif p1 != p2: raise
                 assignments.append(tuple(assignment))
                 atomIndices.append(gndAtom.idx)
             except: pass
         variableAssignments.append(assignments)
         gndAtomIndices.append(atomIndices)
     return variableAssignments, gndAtomIndices
Exemple #6
0
 def getAdmissibleVarAssignments(self, f, trueGndAtoms):
     if not type(f) is Conjunction:
         return None
     cwPred = False
     assignments = []
     for child in f.children:
         if not isinstance(child, Lit) and not isinstance(child, GroundLit) and not isinstance(child, GroundAtom):
             return None
         if child.predName in self.mrf.mln.closedWorldPreds and not cwPred:
             cwPred = True
             for gndAtom in trueGndAtoms:
                 if gndAtom.predName != child.predName: 
                     continue
                 assignment = []
                 try:
                     for (p1, p2) in zip(child.params, gndAtom.params):
                         if FOL.isVar(p1):
                             assignment.append((p1, p2))
                         elif p1 != p2: raise
                     assignments.append(tuple(assignment))
                 except: pass
     return assignments
Exemple #7
0
 def getValidVariableAssignments(self, conjunction, trueOrFalse, gndAtoms):
     variableAssignments = []
     gndAtomIndices = []
     for lit in conjunction.children:
         assignments = []
         atomIndices = []
         for gndAtom in gndAtoms:
             try:
                 if gndAtom.predName != lit.predName:
                     continue
                 assignment = []
                 for (p1, p2) in zip(lit.params, gndAtom.params):
                     if FOL.isVar(p1):
                         assignment.append((p1, p2))
                     elif p1 != p2:
                         raise
                 assignments.append(tuple(assignment))
                 atomIndices.append(gndAtom.idx)
             except:
                 pass
         variableAssignments.append(assignments)
         gndAtomIndices.append(atomIndices)
     return variableAssignments, gndAtomIndices