예제 #1
0
    def process_expansions(
            self, examples: Task, exps: typing.Sequence[Clause],
            hypothesis_space: TopDownHypothesisSpace
    ) -> typing.Sequence[Clause]:
        # eliminate every clause with more body literals than allowed
        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)
            else:
                hypothesis_space.remove(cl)
        return new_exps
    def process_expansions(
            self, examples: Task, exps: typing.Sequence[Clause],
            hypothesis_space: TopDownHypothesisSpace
    ) -> typing.Sequence[Clause]:
        # eliminate every clause with more body literals than allowed
        exps = [cl for cl in exps if len(cl) <= self._max_body_literals]

        # check if every clause has solutions
        exps = [(cl, self._solver.has_solution(*cl.get_body().get_literals()))
                for cl in exps]
        new_exps = []

        for ind in range(len(exps)):
            if exps[ind][1]:
                # keep it if it has solutions
                new_exps.append(exps[ind][0])
            else:
                # remove from hypothesis space if it does not
                hypothesis_space.remove(exps[ind][0])

        return new_exps
예제 #3
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
예제 #4
0
    def process_expansions(self, current_cand: typing.Union[Clause, Procedure],
                           examples: Task, exps_raw: typing.Sequence[Clause],
                           primitives,
                           hypothesis_space: TopDownHypothesisSpace):
        # Encode current candidate to list
        encoded_current_cand = clause_to_list(current_cand,
                                              self.current_primitives.tolist())

        exps = []
        first = True
        for e in exps_raw:
            if isinstance(e, Recursion):
                if first:
                    # With the current hooks, only one recursive case is possible
                    exps.append(e.get_recursive_case()[0])
                    print("FOUND FOLLOWING RECURSIVE CASE AS EXTENSION: ")
                    print(e.get_recursive_case(), "\n")
                first = False
            else:
                exps.append(e)

        # eliminate every clause with more body literals than allowed
        exps = [cl for cl in exps if len(cl) <= self._max_body_literals]

        print("EXPANSIONS BEFORE FILTERING: ")
        self.exp_len.append(len(exps))
        print(exps, "\n")

        # check if every clause has solutions
        exps = [(cl, self._solver.has_solution(*cl.get_body().get_literals()))
                for cl in exps]
        new_exps = []

        for ind in range(len(exps)):
            if exps[ind][1]:
                current_exp = exps[ind][0]
                encoded_exp = clause_to_list(current_exp,
                                             self.current_primitives.tolist())
                prim_index = find_difference(encoded_current_cand, encoded_exp)
                if (not prim_index and self.rules != 0
                    ) or self.current_primitives[prim_index] in primitives:
                    # keep it if it has solutions and if it has an allowed primitive
                    pos, neg = self.evaluate_distinct(examples, current_exp)
                    new_exp = Triplet(current_exp, pos, neg)

                    if new_exp.func1() != new_exp.min_score:
                        new_exps.append(new_exp)

                    # TODO maybe at another place for better performance (currently not used)
                    self.set_example_weights(current_cand, current_exp,
                                             examples)
            else:
                # remove from hypothesis space if it does not
                hypothesis_space.remove(exps[ind][0])

        new_exps = sorted(new_exps,
                          key=cmp_to_key(Triplet.comparator),
                          reverse=True)[:self.filter_amount]
        new_exps_real = []

        for triplet in new_exps:
            new_exps_real.append(triplet.get_tuple())

        print("VIABLE EXTENSIONS: ")
        print(new_exps_real, "\n")
        return new_exps_real
예제 #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
        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]