예제 #1
0
 def _run(self):
     result_ = {}
     with temporary_evidence(self.mrf):
         self.converter = WCSPConverter(self.mrf, multicore=self.multicore, verbose=self.verbose)
         result = self.result_dict(verbose=self.verbose)
         for query in self.queries:
             query = str(query)
             result_[query] = result[query] if query in result else self.mrf[query]
     return result_
예제 #2
0
 def _compute_statistics(self):
     '''
     computes the statistics upon which the optimization is based
     '''
     self._stat = {}
     self._varidx2fidx = defaultdict(set)
     grounder = DefaultGroundingFactory(self.mrf, simplify=False, unsatfailure=True, verbose=self.verbose, cache=0)
     for f in grounder.itergroundings():
         for gndatom in f.gndatoms():
             var = self.mrf.variable(gndatom)
             with temporary_evidence(self.mrf):
                 for validx, value in var.itervalues():
                     var.setval(value, self.mrf.evidence)
                     truth = f(self.mrf.evidence) 
                     if truth != 0:
                         self._varidx2fidx[var.idx].add(f.idx)
                         self._addstat(f.idx, var.idx, validx, truth)
예제 #3
0
파일: cll.py 프로젝트: Bovril/pracmln
    def _compute_stat_rec(self, literals, gndliterals, var_assign, formula, f_gndlit_parts=None, processed=None, isconj=False):
        '''
        TODO: make sure that there are no equality constraints in the conjunction!
        '''
        if len(literals) == 0:
            # at this point, we have a fully grounded conjunction in gndliterals
            # create a mapping from a partition to the ground literals in this formula
            # (criterion no. 1, applies to all kinds of formulas)
            part2gndlits = defaultdict(list)
            part_with_f_lit = None
            for gndlit in gndliterals:
                if isinstance(gndlit, Logic.Equality) or hasattr(self, 'qpreds') and gndlit.gndatom.predname not in self.qpreds: continue
                part = self.atomidx2partition[gndlit.gndatom.idx]
                part2gndlits[part].append(gndlit)
                if gndlit(self.mrf.evidence) == 0:
                    part_with_f_lit = part  
            # if there is a false ground literal we only need to take into account
            # the partition comprising this literal (criterion no. 2)
            # there is maximally one such partition with false literals in the conjunction
            # because of criterion no. 5
            if isconj and part_with_f_lit is not None:
                gndlits = part2gndlits[part_with_f_lit]
                part2gndlits = {part_with_f_lit: gndlits}
            if not isconj: # if we don't have a conjunction, ground the formula with the given variable assignment
                gndformula = formula.ground(self.mrf, var_assign)
            for partition, gndlits in part2gndlits.iteritems():
                # for each partition, select the ground atom truth assignments
                # in such a way that the conjunction is rendered true. There
                # is precisely one such assignment for each partition. (criterion 3/4)
                evidence = {}
                if isconj:
                    for gndlit in gndlits:
                        evidence[gndlit.gndatom.idx] = 0 if gndlit.negated else 1
                for world in partition.itervalues(evidence):
                    # update the sufficient statistics for the given formula, partition and world value
                    worldidx = partition.valueidx(world)
                    if isconj:
                        truth = 1
                    else:
                        # temporarily set the evidence in the MRF, compute the truth value of the 
                        # formula and remove the temp evidence
                        with temporary_evidence(self.mrf):
                            for atomidx, value in partition.value2dict(world).iteritems():
                                self.mrf[atomidx] = value
                            truth = gndformula(self.mrf.evidence)
                    if truth != 0:
                        self.partition2formulas[partition.idx].add(formula.idx)
                        self._addstat(formula.idx, partition.idx, worldidx, truth)
            return
            
        lit = literals[0]
        # ground the literal with the existing assignments
        gndlit = lit.ground(self.mrf, var_assign, partial=True)
        for assign in Logic.iter_eq_varassignments(gndlit, formula, self.mrf) if isinstance(gndlit, Logic.Equality) else gndlit.itervargroundings(self.mrf):
            # copy the arguments to avoid side effects
            # if f_gndlit_parts is None: f_gndlit_parts = set()
            # else: f_gndlit_parts = set(f_gndlit_parts)
            if processed is None: processed = []
            else: processed = list(processed)
            # ground with the remaining free variables
            gndlit_ = gndlit.ground(self.mrf, assign)
            truth = gndlit_(self.mrf.evidence)
            # treatment of equality constraints
            if isinstance(gndlit_, Logic.Equality):
                if isconj:
                    if truth == 1:
                        self._compute_stat_rec(literals[1:], gndliterals, dict_union(var_assign, assign), formula, f_gndlit_parts, processed, isconj)
                    else: continue
                else:
                    self._compute_stat_rec(literals[1:], gndliterals + [gndlit_], dict_union(var_assign, assign), formula, f_gndlit_parts, processed, isconj) 
                continue
            atom = gndlit_.gndatom

            if atom.idx in processed: continue
            
            # if we encounter a gnd literal that is false by the evidence
            # and there is already a false one in this grounding from a different
            # partition, we can stop the grounding process here. The gnd conjunction
            # will never ever be rendered true by any of this partitions values (criterion no. 5)
            isevidence = hasattr(self, 'qpreds') and gndlit_.gndatom.predname not in self.qpreds
            #assert isEvidence == False
            if isconj and truth == 0:
                if f_gndlit_parts is not None and atom not in f_gndlit_parts:
                    continue
                elif isevidence: continue
                else:
                    self._compute_stat_rec(literals[1:], gndliterals + [gndlit_], dict_union(var_assign, assign), formula, self.atomidx2partition[atom.idx], processed, isconj) 
                    continue
            elif isconj and isevidence:
                self._compute_stat_rec(literals[1:], gndliterals, dict_union(var_assign, assign), formula, f_gndlit_parts, processed, isconj) 
                continue
                 
            self._compute_stat_rec(literals[1:], gndliterals + [gndlit_], dict_union(var_assign, assign), formula, f_gndlit_parts, processed, isconj) 
예제 #4
0
    def _compute_stat_rec(self,
                          literals,
                          gndliterals,
                          var_assign,
                          formula,
                          f_gndlit_parts=None,
                          processed=None,
                          isconj=False):
        '''
        TODO: make sure that there are no equality constraints in the conjunction!
        '''

        if len(literals) == 0:
            # at this point, we have a fully grounded conjunction in gndliterals
            # create a mapping from a partition to the ground literals in this formula
            # (criterion no. 1, applies to all kinds of formulas)
            part2gndlits = defaultdict(list)
            part_with_f_lit = None
            for gndlit in gndliterals:
                if isinstance(gndlit, Logic.Equality) or hasattr(
                        self, 'qpreds'
                ) and gndlit.gndatom.predname not in self.qpreds:
                    continue
                part = self.atomidx2partition[gndlit.gndatom.idx]
                part2gndlits[part].append(gndlit)
                if gndlit(self.mrf.evidence) == 0:
                    part_with_f_lit = part

            # if there is a false ground literal we only need to take into account
            # the partition comprising this literal (criterion no. 2)
            # there is maximally one such partition with false literals in the conjunction
            # because of criterion no. 5
            if isconj and part_with_f_lit is not None:
                gndlits = part2gndlits[part_with_f_lit]
                part2gndlits = {part_with_f_lit: gndlits}
            if not isconj:  # if we don't have a conjunction, ground the formula with the given variable assignment
                # print 'formula', formula
                gndformula = formula.ground(self.mrf, var_assign)
                # print 'gndformula', gndformula
                # stop()
            for partition, gndlits in part2gndlits.iteritems():
                # for each partition, select the ground atom truth assignments
                # in such a way that the conjunction is rendered true. There
                # is precisely one such assignment for each partition. (criterion 3/4)
                evidence = {}
                if isconj:
                    for gndlit in gndlits:
                        evidence[
                            gndlit.gndatom.idx] = 0 if gndlit.negated else 1
                for world in partition.itervalues(evidence):
                    # update the sufficient statistics for the given formula, partition and world value
                    worldidx = partition.valueidx(world)
                    if isconj:
                        truth = 1
                    else:
                        # temporarily set the evidence in the MRF, compute the truth value of the
                        # formula and remove the temp evidence
                        with temporary_evidence(self.mrf):
                            for atomidx, value in partition.value2dict(
                                    world).iteritems():
                                self.mrf.set_evidence({atomidx: value},
                                                      erase=True)
                            truth = gndformula(self.mrf.evidence)
                            if truth is None:
                                print gndformula
                                print gndformula.print_structure(
                                    self.mrf.evidence)

                    if truth != 0:
                        self.partition2formulas[partition.idx].add(formula.idx)
                        self._addstat(formula.idx, partition.idx, worldidx,
                                      truth)
            return

        lit = literals[0]
        # ground the literal with the existing assignments
        gndlit = lit.ground(self.mrf, var_assign, partial=True)
        for assign in Logic.iter_eq_varassignments(
                gndlit, formula, self.mrf) if isinstance(
                    gndlit, Logic.Equality) else gndlit.itervargroundings(
                        self.mrf):
            # copy the arguments to avoid side effects
            # if f_gndlit_parts is None: f_gndlit_parts = set()
            # else: f_gndlit_parts = set(f_gndlit_parts)
            if processed is None: processed = []
            else: processed = list(processed)
            # ground with the remaining free variables
            gndlit_ = gndlit.ground(self.mrf, assign)
            truth = gndlit_(self.mrf.evidence)
            # treatment of equality constraints
            if isinstance(gndlit_, Logic.Equality):
                if isconj:
                    if truth == 1:
                        self._compute_stat_rec(literals[1:], gndliterals,
                                               dict_union(var_assign, assign),
                                               formula, f_gndlit_parts,
                                               processed, isconj)
                    else:
                        continue
                else:
                    self._compute_stat_rec(literals[1:],
                                           gndliterals + [gndlit_],
                                           dict_union(var_assign,
                                                      assign), formula,
                                           f_gndlit_parts, processed, isconj)
                continue
            atom = gndlit_.gndatom

            if atom.idx in processed: continue

            # if we encounter a gnd literal that is false by the evidence
            # and there is already a false one in this grounding from a different
            # partition, we can stop the grounding process here. The gnd conjunction
            # will never ever be rendered true by any of this partitions values (criterion no. 5)
            isevidence = hasattr(
                self, 'qpreds') and gndlit_.gndatom.predname not in self.qpreds
            #assert isEvidence == False
            if isconj and truth == 0:
                if f_gndlit_parts is not None and atom not in f_gndlit_parts:
                    continue
                elif isevidence:
                    continue
                else:
                    self._compute_stat_rec(literals[1:],
                                           gndliterals + [gndlit_],
                                           dict_union(var_assign,
                                                      assign), formula,
                                           self.atomidx2partition[atom.idx],
                                           processed, isconj)
                    continue
            elif isconj and isevidence:
                self._compute_stat_rec(literals[1:], gndliterals,
                                       dict_union(var_assign, assign), formula,
                                       f_gndlit_parts, processed, isconj)
                continue

            self._compute_stat_rec(literals[1:], gndliterals + [gndlit_],
                                   dict_union(var_assign, assign), formula,
                                   f_gndlit_parts, processed, isconj)