Beispiel #1
0
    def convert(self):
        '''
        Performs a conversion from an MLN into a WCSP.
        '''
        # mln to be restored after inference
        self._weights = list(self.mrf.mln.weights)
        mln = self.mrf.mln
        logic = mln.logic
        # preprocess the formulas
        formulas = []
        for f in self.mrf.formulas:
            if f.weight == 0: 
                continue
            if f.weight < 0:
                f = logic.negate(f)
                f.weight = -f.weight
            formulas.append(f.nnf())
        # preprocess the ground formulas
#         grounder = DefaultGroundingFactory(self.mrf, formulas=formulas, simplify=True, unsatfailure=True, multicore=self.multicore, verbose=self.verbose)
        grounder = FastConjunctionGrounding(self.mrf, simplify=True, unsatfailure=True, formulas=formulas, multicore=self.multicore, verbose=self.verbose, cache=0)
        for gf in grounder.itergroundings():
            if isinstance(gf, Logic.TrueFalse):
                if gf.weight == HARD and gf.truth() == 0:
                    raise SatisfiabilityException('MLN is unsatisfiable: hard constraint %s violated' % self.mrf.mln.formulas[gf.idx])
                else:# formula is rendered true/false by the evidence -> equal in every possible world 
                    continue
            self.generate_constraint(gf)
        self.mrf.mln.weights = self._weights
        return self.wcsp
Beispiel #2
0
 def __init__(self, mrf, queries=ALL, state=None, **params):
     MCMCInference.__init__(self, mrf, queries, **params)
     if state is None:
         self.state = self.random_world(self.mrf.evidence)
     else:
         self.state = state
     self.sum = 0
     self.var2gf = defaultdict(set)
     self.weights = list(self.mrf.mln.weights)
     formulas = []
     for f in self.mrf.formulas:
         if f.weight < 0:
             f_ = self.mrf.mln.logic.negate(f)
             f_.weight = -f.weight
             formulas.append(f_.nnf())
     grounder = FastConjunctionGrounding(mrf,
                                         formulas=formulas,
                                         simplify=True,
                                         unsatfailure=True)
     for gf in grounder.itergroundings():
         if isinstance(gf, Logic.TrueFalse): continue
         vars_ = set(map(lambda a: self.mrf.variable(a).idx, gf.gndatoms()))
         for v in vars_:
             self.var2gf[v].add(gf)
         self.sum += (self.hardw if gf.weight == HARD else
                      gf.weight) * (1 - gf(self.state))
Beispiel #3
0
 def __init__(self, mrf, queries=ALL, **params):
     MCMCInference.__init__(self, mrf, queries, **params)
     self.var2gf = defaultdict(set)
     grounder = FastConjunctionGrounding(mrf, simplify=True, unsatfailure=True, cache=None)
     for gf in grounder.itergroundings():
         if isinstance(gf, Logic.TrueFalse): continue
         vars_ = set(map(lambda a: self.mrf.variable(a).idx, gf.gndatoms()))
         for v in vars_: self.var2gf[v].add(gf)
Beispiel #4
0
 def __init__(self, mrf, queries=ALL, **params):
     MCMCInference.__init__(self, mrf, queries, **params)
     self.var2gf = defaultdict(set)
     grounder = FastConjunctionGrounding(mrf, simplify=True, unsatfailure=True, cache=None)
     for gf in grounder.itergroundings():
         if isinstance(gf, Logic.TrueFalse): continue
         vars_ = set(map(lambda a: self.mrf.variable(a).idx, gf.gndatoms()))
         for v in vars_: self.var2gf[v].add(gf)
Beispiel #5
0
 def __init__(self, mrf, formulas=None, cache=None, **params):
     FastConjunctionGrounding.__init__(self,
                                       mrf,
                                       simplify=False,
                                       unsatfailure=False,
                                       formulas=formulas,
                                       cache=cache,
                                       **params)
     self._stat = {}
     self._varidx2fidx = defaultdict(set)
Beispiel #6
0
 def __init__(self, mrf, queries, **params):
     Inference.__init__(self, mrf, queries, **params)
     self.grounder = FastConjunctionGrounding(mrf, simplify=False, unsatfailure=False, formulas=mrf.formulas, cache=auto, verbose=False, multicore=False)
     # self.grounder = DefaultGroundingFactory(mrf, simplify=False, unsatfailure=False, formulas=list(mrf.formulas), cache=auto, verbose=False)
     # check consistency of fuzzy and functional variables
     for variable in self.mrf.variables:
         variable.consistent(self.mrf.evidence, strict=isinstance(variable, FuzzyVariable))
Beispiel #7
0
 def __init__(self, mrf, queries=ALL, state=None, **params):
     MCMCInference.__init__(self, mrf, queries, **params)
     if state is None:
         self.state = self.random_world(self.mrf.evidence)
     else:
         self.state = state
     self.sum = 0
     self.var2gf = defaultdict(set)
     self.weights = list(self.mrf.mln.weights)
     formulas = []
     for f in self.mrf.formulas:
         if f.weight < 0:
             f_ = self.mrf.mln.logic.negate(f)
             f_.weight = - f.weight
             formulas.append(f_.nnf())
     grounder = FastConjunctionGrounding(mrf, formulas=formulas, simplify=True, unsatfailure=True)
     for gf in grounder.itergroundings():
         if isinstance(gf, Logic.TrueFalse): continue
         vars_ = set(map(lambda a: self.mrf.variable(a).idx, gf.gndatoms()))
         for v in vars_: self.var2gf[v].add(gf)
         self.sum += (self.hardw if gf.weight == HARD else gf.weight) * (1 - gf(self.state))
Beispiel #8
0
 def _run(self):
     """
     verbose: whether to print results (or anything at all, in fact)
     details: (given that verbose is true) whether to output additional
              status information
     debug:   (given that verbose is true) if true, outputs debug
              information, in particular the distribution over possible
              worlds
     debugLevel: level of detail for debug mode
     """
     # check consistency with hard constraints:
     self._watch.tag('check hard constraints', verbose=self.verbose)
     hcgrounder = FastConjunctionGrounding(self.mrf, simplify=False, unsatfailure=True, 
                                           formulas=[f for f in self.mrf.formulas if f.weight == HARD], 
                                           **(self._params + {'multicore': False, 'verbose': False}))
     for gf in hcgrounder.itergroundings():
         if isinstance(gf, Logic.TrueFalse) and gf.truth() == .0:
             raise SatisfiabilityException('MLN is unsatisfiable due to hard constraint violation by evidence: {} ({})'.format(str(gf), str(self.mln.formula(gf.idx))))
     self._watch.finish('check hard constraints')
     # compute number of possible worlds
     worlds = 1
     for variable in self.mrf.variables:
         values = variable.valuecount(self.mrf.evidence)
         worlds *= values
     numerators = [0.0 for i in range(len(self.queries))]
     denominator = 0.
     # start summing
     logger.debug("Summing over %d possible worlds..." % worlds)
     if worlds > 500000 and self.verbose:
         print colorize('!!! %d WORLDS WILL BE ENUMERATED !!!' % worlds, (None, 'red', True), True)
     k = 0
     self._watch.tag('enumerating worlds', verbose=self.verbose)
     global global_enumAsk
     global_enumAsk = self
     bar = None
     if self.verbose:
         bar = ProgressBar(width=100, steps=worlds, color='green')
     if self.multicore:
         pool = Pool()
         logger.debug('Using multiprocessing on {} core(s)...'.format(pool._processes))
         try:
             for num, denum in pool.imap(with_tracing(eval_queries), self.mrf.worlds()):
                 denominator += denum
                 k += 1
                 for i, v in enumerate(num):
                     numerators[i] += v
                 if self.verbose: bar.inc()
         except Exception as e:
             logger.error('Error in child process. Terminating pool...')
             pool.close()
             raise e
         finally:
             pool.terminate()
             pool.join()
     else:  # do it single core
         for world in self.mrf.worlds():
             # compute exp. sum of weights for this world
             num, denom = eval_queries(world)
             denominator += denom
             for i, _ in enumerate(self.queries):
                 numerators[i] += num[i]
             k += 1
             if self.verbose:
                 bar.update(float(k) / worlds)
     logger.debug("%d worlds enumerated" % k)
     self._watch.finish('enumerating worlds')
     if 'grounding' in self.grounder.watch.tags:
         self._watch.tags['grounding'] = self.grounder.watch['grounding']
     if denominator == 0:
         raise SatisfiabilityException(
             'MLN is unsatisfiable. All probability masses returned 0.')
     # normalize answers
     dist = map(lambda x: float(x) / denominator, numerators)
     result = {}
     for q, p in zip(self.queries, dist):
         result[str(q)] = p
     return result
Beispiel #9
0
 def __init__(self, mrf, formulas=None, cache=None, **params):
     FastConjunctionGrounding.__init__(self, mrf, simplify=False, unsatfailure=False, formulas=formulas, cache=cache, **params)
     self._stat = {}
     self._varidx2fidx = defaultdict(set)
Beispiel #10
0
    def _initkb(self, verbose=False):
        '''
        Initialize the knowledge base to the required format and collect structural information for optimization purposes
        '''
        # convert the MLN ground formulas to CNF
        logger.debug("converting formulas to cnf...")
        #self.mln._toCNF(allPositive=True)
        self.formulas = []
        for f in self.mrf.formulas:
            if f.weight < 0:
                f.weight = -f.weight
                f = self.mln.logic.negate(f)
            self.formulas.append(f)


#         softweights = [1 - 1 / numpy.exp(w) for w in self.mln.weights if w != HARD]
#         stop(sorted(softweights, reverse=True))
#         w_mean = numpy.mean(softweights)
#         w_stdev = numpy.std(softweights)
#         for f in self.mrf.formulas:
#             if f.ishard: continue
#             f.weight  = min(w_stdev, f.weight)
        grounder = FastConjunctionGrounding(self.mrf,
                                            formulas=self.formulas,
                                            simplify=True,
                                            verbose=self.verbose)
        self.gndformulas = []
        for gf in grounder.itergroundings():
            if isinstance(gf, Logic.TrueFalse): continue
            self.gndformulas.append(gf.cnf())
        self._watch.tags.update(grounder.watch.tags)
        #         self.gndformulas, self.formulas = Logic.cnf(grounder.itergroundings(), self.mln.formulas, self.mln.logic, allpos=True)
        # get clause data
        logger.debug("gathering clause data...")
        self.gf2clauseidx = {
        }  # ground formula index -> tuple (idxFirstClause, idxLastClause+1) for use with range
        self.clauses = [
        ]  # list of clauses, where each entry is a list of ground literals
        #self.GAoccurrences = {} # ground atom index -> list of clause indices (into self.clauses)
        i_clause = 0
        # process all ground formulas
        for i_gf, gf in enumerate(self.gndformulas):
            # get the list of clauses
            if isinstance(gf, Logic.Conjunction):
                clauses = [
                    clause for clause in gf.children
                    if not isinstance(clause, Logic.TrueFalse)
                ]
            elif not isinstance(gf, Logic.TrueFalse):
                clauses = [gf]
            else:
                continue
            self.gf2clauseidx[i_gf] = (i_clause, i_clause + len(clauses))
            # process each clause
            for c in clauses:
                if hasattr(c, "children"):
                    lits = c.children
                else:  # unit clause
                    lits = [c]
                # add clause to list
                self.clauses.append(lits)
                # next clause index
                i_clause += 1
        # add clauses for soft evidence atoms
        for se in []:  #self.softEvidence:
            se["numTrue"] = 0.0
            formula = self.mln.logic.parseFormula(se["expr"])
            se["formula"] = formula.ground(self.mrf, {})
            cnf = formula.toCNF().ground(self.mrf, {})
            idxFirst = i_clause
            for clause in self._formulaClauses(cnf):
                self.clauses.append(clause)
                #print clause
                i_clause += 1
            se["idxClausePositive"] = (idxFirst, i_clause)
            cnf = self.mln.logic.negation([formula
                                           ]).toCNF().ground(self.mrf, {})
            idxFirst = i_clause
            for clause in self._formulaClauses(cnf):
                self.clauses.append(clause)
                #print clause
                i_clause += 1
            se["idxClauseNegative"] = (idxFirst, i_clause)
Beispiel #11
0
    def _initkb(self, verbose=False):
        '''
        Initialize the knowledge base to the required format and collect structural information for optimization purposes
        '''
        # convert the MLN ground formulas to CNF
        logger.debug("converting formulas to cnf...")
        #self.mln._toCNF(allPositive=True)
        self.formulas = []
        for f in self.mrf.formulas:
            if f.weight < 0:
                f.weight = -f.weight
                f = self.mln.logic.negate(f)
            self.formulas.append(f)
#         softweights = [1 - 1 / numpy.exp(w) for w in self.mln.weights if w != HARD]
#         stop(sorted(softweights, reverse=True))
#         w_mean = numpy.mean(softweights)
#         w_stdev = numpy.std(softweights)
#         for f in self.mrf.formulas:
#             if f.ishard: continue
#             f.weight  = min(w_stdev, f.weight)
        grounder = FastConjunctionGrounding(self.mrf, formulas=self.formulas, simplify=True, verbose=self.verbose)
        self.gndformulas = []
        for gf in grounder.itergroundings():
            if isinstance(gf, Logic.TrueFalse): continue
            self.gndformulas.append(gf.cnf())
        self._watch.tags.update(grounder.watch.tags)
#         self.gndformulas, self.formulas = Logic.cnf(grounder.itergroundings(), self.mln.formulas, self.mln.logic, allpos=True)
        # get clause data
        logger.debug("gathering clause data...")
        self.gf2clauseidx = {} # ground formula index -> tuple (idxFirstClause, idxLastClause+1) for use with range
        self.clauses = [] # list of clauses, where each entry is a list of ground literals
        #self.GAoccurrences = {} # ground atom index -> list of clause indices (into self.clauses)
        i_clause = 0
        # process all ground formulas
        for i_gf, gf in enumerate(self.gndformulas):
            # get the list of clauses
            if isinstance(gf, Logic.Conjunction):
                clauses = [clause for clause in gf.children if not isinstance(clause, Logic.TrueFalse)]
            elif not isinstance(gf, Logic.TrueFalse):
                clauses = [gf]
            else: continue
            self.gf2clauseidx[i_gf] = (i_clause, i_clause + len(clauses))
            # process each clause
            for c in clauses:
                if hasattr(c, "children"):
                    lits = c.children
                else: # unit clause
                    lits = [c]
                # add clause to list
                self.clauses.append(lits)
                # next clause index
                i_clause += 1
        # add clauses for soft evidence atoms
        for se in []:#self.softEvidence:
            se["numTrue"] = 0.0
            formula = self.mln.logic.parseFormula(se["expr"])
            se["formula"] = formula.ground(self.mrf, {})
            cnf = formula.toCNF().ground(self.mrf, {}) 
            idxFirst = i_clause
            for clause in self._formulaClauses(cnf):                
                self.clauses.append(clause)
                #print clause
                i_clause += 1
            se["idxClausePositive"] = (idxFirst, i_clause)
            cnf = self.mln.logic.negation([formula]).toCNF().ground(self.mrf, {})
            idxFirst = i_clause
            for clause in self._formulaClauses(cnf):                
                self.clauses.append(clause)
                #print clause
                i_clause += 1
            se["idxClauseNegative"] = (idxFirst, i_clause)