コード例 #1
0
    def sample(self, model, queries=None):
        """Sample one assignment to the queries of the given model.
        
        Returns a tuple containing:
            queries : list of pairs (name, value)
            facts: list of probabilistic facts with their sampled value (name, value)
            probability: overall probability of the assignment
        """

        engine = self
        db = engine.prepare(model)

        if queries == None:
            queries = [q[0] for q in engine.query(db, Term('query', None))]

        # if evidence == None :
        #     evidence = engine.query(db, Term( 'evidence', None, None ))

        target = LogicFormula()

        for query in queries:
            target = engine.ground(db, query, target, label=target.LABEL_QUERY)

        # for query in evidence :
        #     if str(query[1]) == 'true' :
        #         target = engine.ground(db, query[0], target, label=LABEL_EVIDENCE_POS)
        #     elif str(query[1]) == 'false' :
        #         target = engine.ground(db, query[0], target, label=LABEL_EVIDENCE_NEG)
        #     else :
        #         target = engine.ground(db, query[0], target, label=LABEL_EVIDENCE_MAYBE)

        # Take into account remaining probabilities of no-choice nodes for annotated disjunctions.
        for k, p in self.groups.items():
            if p != None:
                self.probability *= p

        translate = lambda x: (x[0], x[1] == 0)
        facts = []
        for f, v in self.facts.items():
            if v:
                if type(f) == tuple:
                    node = db.get_node(f[0])
                    args = f[1]
                else:
                    node = db.get_node(f)
                    args = node.args
                if node.functor != 'query':
                    if args:
                        facts.append('%s(%s)' %
                                     (node.functor, ', '.join(map(str, args))))
                    else:
                        facts.append('%s' % (node.functor))

        result = map(translate, target.queries()), facts, self.probability

        self.reset()

        return result
コード例 #2
0
    def verify(self, examples, engine):
        if self.parent.verifications is not None:
            verifications = self.parent.verifications
        else:
            self.parent.verify(examples, engine)
            verifications = self.parent.verifications

        # check whether the literal is a body or a head literal
        # body literals are negated
        rule_literal = abs(self.literal)
        if not self.literal.is_negated():
            head_literal = True
        else:
            head_literal = False

        verifies = False
        new_verifications = []

        for k, (example,
                verification) in enumerate(zip(examples, verifications)):
            #print("-----------------------------------------------------")
            #print("testing",self,"on example",k+1)
            if verification:
                if hasattr(example, '_ground'):
                    formula = example._ground
                    formula.clear_queries()
                else:
                    formula = LogicFormula()

                new_verification = []

                for subst in verification:
                    #print("rule_literal:",rule_literal)
                    #print("original subst:",subst)

                    if len(subst) < self.variable_count:
                        subst = subst + [None
                                         ] * (self.variable_count - len(subst))
                    #print("new subst:",subst)

                    literal = instantiate(rule_literal, subst)
                    #print("literal:",literal)

                    formula = engine.ground(example.database,
                                            literal,
                                            target=formula,
                                            label='query')
                    #print("formula:",formula)

                    for q, i in formula.queries():
                        subst_new = subst[:]
                        #print("q:",q)
                        try:
                            unify(q, rule_literal, subst_new)

                            #print("subst_new:",subst_new)
                            #if len(set(subst_new)) == len(subst_new):
                            if head_literal and i == 0:
                                if None in subst_new:
                                    get_logger('claudette').error(' '.join(
                                        map(str, (list(example.database), self,
                                                  failing, formula))))
                                    raise RuntimeError(
                                        'This shouldn\'t happen!')
                                #print("head query",q,"evaluated to true")
                                new_verification.append(subst_new)
                            # the body literal evaluated in true
                            elif not head_literal and i == 0:
                                new_verification.append(subst_new)
                                #print("body query",q,"evaluated to true")
                        except UnifyError:
                            # if we have a unify error then the literal is not unifyable with the query
                            #print("unify error")
                            pass
                        #print("==========")

                example._ground = formula
                if str(rule_literal)[0] == '#':
                    new_verifications.append([[]])
                else:
                    new_verifications.append(new_verification)
                #print("verification:",verification)
                #print("new_verification:",new_verification)

                if new_verification:
                    verifies = True

            else:
                new_verifications.append([])
        self.verifications = new_verifications

        return verifies
コード例 #3
0
    def evaluate(self, examples, engine):
        # UITLEG subst
        # bij elke refinement wordt er 1 predicaat toegevoegd aan de body of head (in ons geval enkel aan de body, aangezien we enkel in de modes '\+' gebruiken)
        # het toegevoegde predicaat zit vervat in 'rule_literal'
        # elke failing bevat een aantal lijsten, subst is telkens een pointer naar een van deze lijsten
        # het i-de element van subst is telkens de waarde van parameter Ai
        # Bv example: p(a). p(b). q(a,b)
        # huidige hypothese: p(A1) -> false
        #    ----> rule_literal is dus p(A1)!!
        # de originele failing zou dan zijn [[]] (zie evaluate van EmptyClause)
        # de nieuwe failing is nu [[a],[b]] aangezien er in het voorbeeld twee keer p(A1) voorkomt
        # aangezien de body nu true en de head false (want die is altijd false in dit voorbeeld) dekt dit het voorbeeld niet
        # daarom staat er een 'if not head_literal and i == None' wat betekent dat als de rule_literal een body_literal is en als die true is in het voorbeeld
        # dan wordt het voorbeeld niet gedekt

        # gather the failings from the parent
        # the failings list contains for every example information about that example
        # if a failing element is just an empty list ([]) then the clause covers that example
        if self.parent.failings is not None:
            failings = self.parent.failings
        else:
            self.parent.evaluate(examples, engine)
            failings = self.parent.failings

        # check whether the literal is a body or a head literal
        # body literals are negated
        rule_literal = abs(self.literal)
        if not self.literal.is_negated():
            head_literal = True
        else:
            head_literal = False

        # boolean indicating whether there is an example which is not covered by this clause
        fails = False

        # the list that will contain the updated failings
        # later on self.failings will be set to this list
        new_failings = []

        # boolean indicating whether this clause is an improvement of its parent clause
        improvement = False
        if head_literal:
            improvement = True
        # loop through the examples and failings at the same time
        # 'example' contains the example and 'failing' contains information about coverage of the example by the parent
        for k, (example, failing) in enumerate(zip(examples, failings)):
            #print("-----------------------------------------------------")
            #print("testing",self,"on example",k+1)
            if failing:  # equivalent to if 'failing != []' so if this if succeeds, the parent does not cover the example

                # TODO: find out why this is necessary
                if hasattr(example, '_ground'):
                    formula = example._ground
                    formula.clear_queries()
                else:
                    formula = LogicFormula()  # Load from cache
                # formula = LogicFormula()

                # construct a new list to store the failing information for this example
                # later on 'failing' will be replaced by 'new_failing'
                new_failing = []

                # calculate the contents of new_failing
                for subst in failing:
                    #print("rule_literal:",rule_literal)
                    #print("original subst:",subst)
                    # for every new variable this clause introduces, add a None element to the substances
                    if len(subst) < self.variable_count:
                        subst = subst + [None
                                         ] * (self.variable_count - len(subst))
                        improvement = True  # adds a variable
                    #print("new subst:",subst)
                    # subst now contains a list where the ith element contains the value for the ith parameter of the rule_literal
                    # bv. instantiate(pred(A1,A2,A3),[a,b,None]) would result in pred(a,b,_)
                    literal = instantiate(rule_literal, subst)
                    #print("literal:",literal)

                    # formula contains a list queries
                    # this list contains all the facts in the example of the literal
                    # bv example: pred1(a). pred1(b). pred2(b). pred3(a,b).
                    #  literal = pred1(_)
                    #   queries: [pred1(a),pred1(b)]
                    formula = engine.ground(example.database,
                                            literal,
                                            target=formula,
                                            label='query')
                    #print("formula:",formula)
                    # q is the query
                    # if i == 0, the query is true
                    # if i == None, the query is false
                    # de uitbreiding van een clause dekt het positieve voorbeeld als rule_literal een body_literal is die naar false evalueert of
                    # of als rule_literal een head_literal is die naar true evalueert
                    for q, i in formula.queries():
                        # create a copy of the subst_new
                        subst_new = subst[:]
                        #print("q:",q)
                        try:
                            # try to unify the query with the rule literal and put the unifications in subst_new
                            unify(q, rule_literal, subst_new)

                            #print("subst_new:",subst_new)
                            if len(set(subst_new)) == len(subst_new):
                                # TODO check subst_new is all different
                                # the head_literal evaluated to false
                                if head_literal and i is None:
                                    if None in subst_new:
                                        get_logger('claudette').error(' '.join(
                                            map(str,
                                                (list(example.database), self,
                                                 failing, formula))))
                                        raise RuntimeError(
                                            'This shouldn\'t happen!')
                                    #print("head query",q,"evaluated to false")
                                    new_failing.append(subst_new)
                                # the body literal evaluated in true
                                elif not head_literal and i == 0:
                                    new_failing.append(subst_new)
                                    #print("body query",q,"evaluated to true")
                        except UnifyError:
                            # if we have a unify error then the literal is not unifyable with the query
                            #print("unify error")
                            pass
                        #print("==========")

                example._ground = formula
                new_failings.append(new_failing)
                #print("failing:",failing)
                #print("new_failing:",new_failing)
                # we check whether new_failing contains any items
                # if it doesn't then we know that the refinement covers the example
                if new_failing:
                    # if new_failing contains less items than failing than this clause covers it 'more' than the parent so there is an improvement
                    if len(new_failing) < len(
                            failing
                    ) or self.variable_count == 0:  # the last statement is needed for terminal (otherwise terminal gives no contribution)
                        improvement = True
                    fails = True
                else:  # new_failing == [] thus this example is now covered
                    assert failing
                    improvement = True  # failing eliminated
            else:
                # the parent covers this example, so the refinement covers this to
                new_failings.append([])
        self.failings = new_failings
        self.improvement = improvement

        # if fails is set to True, then the clause didn't cover a positive example so it is not a valid one and needs to be refined
        return not fails