예제 #1
0
    def bottom_up(self):
        a = c_pred("a", 2)
        b = c_pred("b", 2)
        c = c_pred("c", 1)
        h = c_pred("h", 2)

        cl = h("X", "Y") <= a("X", "Z") & b("Z", "Y") & c("X")

        bc = BottomClauseExpansion(cl)

        hs = TopDownHypothesisSpace(primitives=[lambda x: bc.expand(x)],
                                    head_constructor=h)

        cls = hs.get_current_candidate()
        assert len(cls) == 3

        exps = hs.expand(cls[1])
        assert len(exps) == 2

        exps2 = hs.expand(exps[0])
        assert len(exps2) == 4
예제 #2
0
    def top_down_plain(self):
        grandparent = c_pred("grandparent", 2)
        father = c_pred("father", 2)
        mother = c_pred("mother", 2)

        hs = TopDownHypothesisSpace(primitives=[
            lambda x: plain_extension(x, father),
            lambda x: plain_extension(x, mother)
        ],
                                    head_constructor=grandparent)

        current_cand = hs.get_current_candidate()
        assert len(current_cand) == 3

        expansions = hs.expand(current_cand[0])
        assert len(expansions) == 6

        expansions_2 = hs.expand(expansions[0])
        assert len(expansions_2) == 10

        expansions3 = hs.expand(expansions[1])
        assert len(expansions3) == 32

        hs.block(expansions[2])
        expansions4 = hs.expand(expansions[2])
        assert len(expansions4) == 0

        hs.remove(expansions[3])
        expansions5 = hs.get_successors_of(current_cand[0])
        assert len(expansions5) == 5

        hs.move_pointer_to(expansions[1])
        current_cand = hs.get_current_candidate()
        assert current_cand[0] == expansions[1]

        hs.ignore(expansions[4])
        hs.move_pointer_to(expansions[4])
        expansions6 = hs.get_current_candidate()
        assert len(expansions6) == 0
예제 #3
0
    def top_down_limited(self):
        grandparent = c_pred("grandparent", 2)
        father = c_pred("father", 2)
        mother = c_pred("mother", 2)

        hs = TopDownHypothesisSpace(
            primitives=[
                lambda x: plain_extension(x, father, connected_clauses=False),
                lambda x: plain_extension(x, mother, connected_clauses=False)
            ],
            head_constructor=grandparent,
            expansion_hooks_keep=[lambda x, y: connected_clause(x, y)],
            expansion_hooks_reject=[lambda x, y: has_singleton_vars(x, y)])

        current_cand = hs.get_current_candidate()
        assert len(current_cand) == 3

        expansions = hs.expand(current_cand[1])
        assert len(expansions) == 6

        expansion2 = hs.expand(expansions[1])
        assert len(expansion2) == 16
예제 #4
0
    def recursions(self):
        parent = c_pred("parent", 2)
        ancestor = c_pred("ancestor", 2)

        hs = TopDownHypothesisSpace(primitives=[
            lambda x: plain_extension(x, parent, connected_clauses=True)
        ],
                                    head_constructor=ancestor,
                                    recursive_procedures=True)

        cls = hs.get_current_candidate()
        cls2 = hs.expand(cls[1])
        print(cls2)
예제 #5
0
    def _learn_one_clause(self, examples: Task,
                          hypothesis_space: TopDownHypothesisSpace) -> Clause:
        """
        Learns a single clause

        Returns a clause
        """
        # reset the search space
        hypothesis_space.reset_pointer()

        # empty the pool just in case
        self.initialise_pool()

        # put initial candidates into the pool
        self.put_into_pool(hypothesis_space.get_current_candidate())
        current_cand = None
        score = -100

        while current_cand is None or (
                len(self._candidate_pool) > 0
                and not self.stop_inner_search(score, examples, current_cand)):
            # get first candidate from the pool
            current_cand = self.get_from_pool()

            # expand the candidate
            _ = hypothesis_space.expand(current_cand)
            # this is important: .expand() method returns candidates only the first time it is called;
            #     if the same node is expanded the second time, it returns the empty list
            #     it is safer than to use the .get_successors_of method
            exps = hypothesis_space.get_successors_of(current_cand)
            exps = self.process_expansions(examples, exps, hypothesis_space)
            # add into pool
            self.put_into_pool(exps)

            score = self.evaluate(examples, current_cand, hypothesis_space)

        if self._print:
            print(f"- New clause: {current_cand}")
            print(
                f"- Candidates has value {round(score,2)} for metric '{self._eval_fn.name()}'"
            )
        return current_cand
예제 #6
0
    def _learn_one_clause(self, examples: Task, hypothesis_space: TopDownHypothesisSpace) -> Clause:
        """
        Learns a single clause

        Returns a clause
        """
        # reset the search space
        hypothesis_space.reset_pointer()

        # empty the pool just in case
        self.initialise_pool()

        # put initial candidates into the pool
        self.put_into_pool([Triplet(hypothesis_space.get_current_candidate()[0]).get_tuple()])
        current_cand = None
        first = True
        score = -100

        while current_cand is None or (
                self._candidate_pool.qsize() > 0 and not self.stop_inner_search(score, examples, current_cand)):
            # get first candidate from the pool
            current_cand = self.get_from_pool()

            if first:
                self.example_weights[current_cand] = self.get_initial_weights(examples)
                first = False

            print("-------------------------------------------------------")
            print("CURRENT CANDIDATE: ")
            print("\t ", current_cand)
            print("STATS: ")
            score = self.evaluate(examples, current_cand)
            print("\t length: ", len(current_cand))
            print("\t Pool size: ", self._candidate_pool.qsize(), "\n")
            self.exp_count += 1
            self.max_queue_len = max(self.max_queue_len, self._candidate_pool.qsize())

            if self.exp_count == 101:
                self.stopped_early = True
                break
                
            if not current_cand.is_recursive():
                # expand the candidate and get possible expansions
                _ = hypothesis_space.expand(current_cand)
                exps = hypothesis_space.get_successors_of(current_cand)

                # Get scores for primitives using current candidate and each example
                primitives = self.get_best_primitives(examples, current_cand)
                exps = self.process_expansions(current_cand, examples, exps, primitives, hypothesis_space)

                # add into pool
                self.put_into_pool(exps)

                if self._candidate_pool.qsize() == 0:
                    self.stopped_early = True
                    break

        if self.stopped_early:
            return None

        self._solver.asserta(current_cand)
        return current_cand
예제 #7
0
    def _learn_one_clause(self, examples: Task,
                          hypothesis_space: TopDownHypothesisSpace) -> Clause:
        """
        Learns a single clause

        Returns a clause
        """
        # reset the search space
        hypothesis_space.reset_pointer()

        # empty the pool just in case
        self.initialise_pool()

        # put initial candidates into the pool
        self.put_into_pool(hypothesis_space.get_current_candidate())
        current_cand = None
        score = -100
        self._expansionOneClause = 0
        best = None

        while current_cand is None or (len(self._candidate_pool) >
                                       0) and self._expansionOneClause < 40000:
            # get first candidate from the pool
            current_cand = self.get_from_pool()
            print(self._expansion)

            # expand the candidate
            _ = hypothesis_space.expand(current_cand)
            # this is important: .expand() method returns candidates only the first time it is called;
            #     if the same node is expanded the second time, it returns the empty list
            #     it is safer than to use the .get_successors_of method
            exps = hypothesis_space.get_successors_of(current_cand)
            exps = [cl for cl in exps if len(cl) <= self._max_body_literals]

            new_exps = []
            # check if every clause has solutions
            for cl in exps:
                y = self.evaluate(task, cl)

                if y[0] > 0:
                    new_exps.append(cl)
                    if best == None:
                        best = (y[0], cl)
                    if (y[1] == 0):
                        self._expansion += 1
                        self._expansionOneClause += 1
                        self._result.append((self._expansion, y[1]))
                        return cl
                    self._expansion += 1
                    self._expansionOneClause += 1

                    self._result.append((self._expansion, y[0]))
                    if y[0] > best[0]:
                        best = (y[0], cl)
                    else:
                        if (y[0] == best[0]) & (len(cl.get_literals()) < len(
                                best[1].get_literals())):
                            best = (y[0], cl)
                else:
                    hypothesis_space.remove(cl)

            # add into pull
            self.put_into_pool(new_exps)

        print(best)
        return best[1]