Example #1
0
 def __parse_lpad(self, lpad):
     self.__weights = Weights()
     self.__logicProgram = LogicProgram()
     self.__constraints = []
     self.__rule_counter = 0
     for line in open(lpad):
         line = line.strip()
         self.__parse_AD(line)
Example #2
0
 def __call__(self,logic_program,weights,queries,evidence):
     self.__original_program = logic_program
     self.__original_weights = weights
     self.__new_program = LogicProgram()
     self.__new_weights = Weights()
     self.__built_rules = {}
     for lit in queries | evidence:
         self.__get_rule(lit)
     new_evidence = set([])
     for lit in evidence:
         if lit.truth_value:
             for (new_lit,_) in self.__built_rules[lit]:
                 new_evidence.add(new_lit)
         else:
             for (new_lit,_) in self.__built_rules[-lit]:
                 new_evidence.add(-new_lit)
     return self.__new_program, self.__new_weights, new_evidence 
Example #3
0
class GroundProbLogParser:
    def __call__(self, lpad, queries, evidence):
        self.__parse_queries(queries)
        self.__parse_evidence(evidence)
        self.__parse_lpad(lpad)
        return (self.__logicProgram, self.__constraints, self.__weights,
                self.__queries, self.__evidence)

    def __parse_queries(self, queries):
        self.__queries = set([])
        for line in open(queries):
            self.__queries.add(Literal.parse(line.strip()))

    def __parse_evidence(self, evidence):
        self.__evidence = set([])
        for line in open(evidence):
            atom = line.split()[0]
            truth = line.split()[1]
            if truth == 'true':
                self.__evidence.add(Literal(atom, True))
            elif truth == 'false':
                self.__evidence.add(Literal(atom, False))
            else:
                raise ParseError('The truth value for evidence: ' + atom +
                                 ' should be true/false')

    def __parse_lpad(self, lpad):
        self.__weights = Weights()
        self.__logicProgram = LogicProgram()
        self.__constraints = []
        self.__rule_counter = 0
        for line in open(lpad):
            line = line.strip()
            self.__parse_AD(line)

    def __parse_AD(self, ad):
        p = RuleParser()
        (head, body) = p(ad)
        head = self.__calculate_probabilities(head)
        choices = self.__get_choices(head)
        self.__make_rules(choices, body)
        self.__make_constraints(choices, body)

    def __calculate_probabilities(self, head):
        new_head = []
        for (prob, atom) in head:
            if '/' in prob:
                parts = prob, atom.split('/')
                new_head.append((float(parts[0]) / float(parts[1]), atom))
            else:
                new_head.append((float(prob), atom))
        return new_head

    def __get_choices(self, head):
        total_prob = 0
        result = []
        for i in range(0, len(head)):
            (prob, atom) = head[i]
            total_prob += prob
            self.__weights[atom] = 1.0
            self.__weights[-atom] = 1.0
            choice = Literal(
                'choice_node_' + str(self.__rule_counter) + '_' + str(i), True)
            self.__weights[choice] = prob
            self.__weights[-choice] = 1.0
            result.append((atom, choice))
        if total_prob > 1:
            raise ParseError(
                'the total probability of a rule is bigger than one: ' + head)
        nillChoice = Literal(
            'choice_node_' + str(self.__rule_counter) + '_' + str(len(head)),
            True)
        self.__weights[nillChoice] = round(1 - total_prob)
        self.__weights[-nillChoice] = 1.0
        result.append((None, nillChoice))
        self.__rule_counter += 1
        return result

    def __make_rules(self, choices, body):
        for (head, choice) in choices:
            if head:
                body_copy = [choice]
                for atom in body:
                    body_copy.append(atom)
                self.__logicProgram.add_rule(head, body_copy)

    def __make_constraints(self, choices, body):
        if len(choices) > 1:
            for i in range(0, len(choices) - 1):
                for j in range(i + 1, len(choices)):
                    self.__constraints.append([-choices[i][1], -choices[j][1]])
        constraint = []
        for (_, choice) in choices:
            constraint.append(choice)
        if body != ['true']:
            for atom in body:
                constraint.append(-atom)
                for (_, choice) in choices:
                    self.__constraints.append([-choice, atom])
            self.__constraints.append(constraint)
Example #4
0
class LoopBreaker:
    def __call__(self,logic_program,weights,queries,evidence):
        self.__original_program = logic_program
        self.__original_weights = weights
        self.__new_program = LogicProgram()
        self.__new_weights = Weights()
        self.__built_rules = {}
        for lit in queries | evidence:
            self.__get_rule(lit)
        new_evidence = set([])
        for lit in evidence:
            if lit.truth_value:
                for (new_lit,_) in self.__built_rules[lit]:
                    new_evidence.add(new_lit)
            else:
                for (new_lit,_) in self.__built_rules[-lit]:
                    new_evidence.add(-new_lit)
        return self.__new_program, self.__new_weights, new_evidence 
        
    def  __get_rule(self,lit,ancestors=set([])):
        if lit.truth_value:
            atom = lit
        else:
            atom = -lit
            ancestors = set([])
        for (new_atom,cycles) in self.__built_rules.get(atom,[]):
            if cycles <= ancestors:
                break
        else:
            (new_atom,cycles) = self.__build_rule(atom,ancestors)
        if lit.truth_value:
            return (new_atom,cycles)
        else:
            return (-new_atom,cycles)
        
        
    def __build_rule(self,atom,ancestors):
        if atom in self.__original_program:
            all_new_rules = []
            all_new_cycles = set([])
            for rule in self.__original_program[atom]:
                if not rule & ancestors:
                    new_cycles = set([])
                    new_rule = set([])
                    for lit in rule:
                        (new_lit,cycles) = self.__get_rule(lit,ancestors | set([atom]))
                        if new_lit:
                            new_cycles = new_cycles | cycles
                            new_rule.add(new_lit)
                        else:
                            new_cycles = cycles
                            break
                    else:
                        all_new_rules.append(new_rule)
                        all_new_cycles = all_new_cycles | new_cycles
                else:
                    all_new_cycles = all_new_cycles | (rule & ancestors)
            all_new_cycles = all_new_cycles - set([atom])
            if all_new_rules:
                if all_new_cycles:
                    new_atom = Literal(atom.atom + '_' + str(len(self.__built_rules.get(atom,[]))),True)
                else:
                    new_atom = atom
                self.__new_weights[new_atom] = self.__original_weights[atom]
                self.__new_weights[-new_atom] = self.__original_weights[-atom]
                for rule in all_new_rules:
                    self.__new_program.add_rule(new_atom, rule)
                result = (new_atom,all_new_cycles)
                if atom in self.__built_rules:
                    self.__built_rules[atom].append(result)
                else:
                    self.__built_rules[atom] = [result] 
                return result
            else:
                return (None,all_new_cycles)
                    
        else:
            self.__new_weights[atom] = self.__original_weights[atom]
            self.__new_weights[-atom] = self.__original_weights[-atom]
            result = (atom,set([]))
            self.__built_rules[atom] = [result]
            return result