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)
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 _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
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
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
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
def train_task(task_id: string, pos_multiplier: int, neg_example_offset: int, nn_amount: int, pos=None, neg=None): # Load needed files bk, predicates = createKnowledge( "../inputfiles/StringTransformations_BackgroundKnowledge.pl", task_id) if pos is None and neg is None: pos, neg = generate_examples(task_id, pos_multiplier, neg_example_offset) task = Task(positive_examples=pos, negative_examples=neg) # Calculate predicates total_predicates = [] filtered_predicates = [] for predicate in predicates: if predicate.name not in ["s", task_id ] and predicate not in filtered_predicates: total_predicates.append(lambda x, pred=predicate: plain_extension( x, pred, connected_clauses=True)) filtered_predicates.append(predicate) # create the hypothesis space hs = TopDownHypothesisSpace( primitives=total_predicates, head_constructor=c_pred("test_task", 1), recursive_procedures=True, expansion_hooks_keep=[ lambda x, y: connected_clause(x, y), lambda x, y: only_1_pred_for_1_var(x, y), lambda x, y: head_first(x, y) ], expansion_hooks_reject=[ # lambda x, y: has_singleton_vars(x, y), # Singleton-vars constraint is reduced to this constraint lambda x, y: has_not_previous_output_as_input(x, y), # Strict # lambda x, y: has_new_input(x, y), # Not as strict # lambda x, y: has_unexplained_last_var(x, y), # For the 'write' predicate lambda x, y: has_unexplained_last_var_strict( x, y), # Strict version of above lambda x, y: has_duplicated_literal(x, y), lambda x, y: has_g1_same_vars_in_literal(x, y), lambda x, y: has_duplicated_var_set(x, y), lambda x, y: has_double_recursion(x, y), lambda x, y: has_endless_recursion(x, y) ]) learner = NeuralSearcher1(solver_instance=prolog, primitives=filtered_predicates, model_location="../utility/Saved_model_covered", max_body_literals=10, amount_chosen_from_nn=nn_amount, filter_amount=30, threshold=0.1) # Try to learn the program program, ss = learner.learn( task, "../inputfiles/StringTransformations_BackgroundKnowledge.pl", hs) print(program) return ss
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
father("e", "f"), father("f", "g"), mother("h", "i"), mother("i", "j")) # positive examples pos = {grandparent("a", "c"), grandparent("e", "g"), grandparent("h", "j")} # negative examples neg = {grandparent("a", "b"), grandparent("a", "g"), grandparent("i", "j")} task = Task(positive_examples=pos, negative_examples=neg) # create Prolog instance prolog = SWIProlog() learner = SimpleBreadthFirstLearner(prolog, max_body_literals=3) # create the hypothesis space hs = TopDownHypothesisSpace(primitives=[ lambda x: plain_extension(x, father, connected_clauses=True), lambda x: plain_extension(x, mother, connected_clauses=True) ], head_constructor=grandparent, expansion_hooks_reject=[ lambda x, y: has_singleton_vars(x, y), lambda x, y: has_duplicated_literal(x, y) ]) program = learner.learn(task, background, hs) print(program)
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
prolog = SWIProlog() # create the hypothesis space hs = TopDownHypothesisSpace(primitives=[ lambda x: plain_extension(x, not_space, connected_clauses=True), lambda x: plain_extension(x, mk_uppercase, connected_clauses=True), lambda x: plain_extension(x, mk_lowercase, connected_clauses=True), lambda x: plain_extension(x, is_empty, connected_clauses=True), lambda x: plain_extension(x, is_space, connected_clauses=True), lambda x: plain_extension(x, is_uppercase, connected_clauses=True), lambda x: plain_extension(x, not_uppercase, connected_clauses=True), lambda x: plain_extension(x, is_lowercase, connected_clauses=True), lambda x: plain_extension(x, not_lowercase, connected_clauses=True), lambda x: plain_extension(x, is_letter, connected_clauses=True), lambda x: plain_extension(x, not_letter, connected_clauses=True), lambda x: plain_extension(x, is_number, connected_clauses=True), lambda x: plain_extension(x, not_number, connected_clauses=True), lambda x: plain_extension(x, skip1, connected_clauses=True), lambda x: plain_extension(x, copy1, connected_clauses=True), lambda x: plain_extension(x, write1, connected_clauses=True), lambda x: plain_extension(x, copyskip1, connected_clauses=True) ], head_constructor=b45, expansion_hooks_reject=[ lambda x, y: has_singleton_vars(x, y), lambda x, y: has_duplicated_literal(x, y) ], recursive_procedures=True) primitives = [ b45(c_var('X')), b45(c_var('Y')),
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
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]
# # create the hypothesis space # hs = TopDownHypothesisSpace(primitives=[lambda x: plain_extension(x, father, connected_clauses=True), # lambda x: plain_extension(x, mother, connected_clauses=True)], # head_constructor=grandparent, # expansion_hooks_reject=[lambda x, y: has_singleton_vars(x, y), # lambda x, y: has_duplicated_literal(x, y)]) totalextension = [] filtered_predicates = [] for predicate in predicates: if predicate.name not in ["s", chosen_pred ] and predicate not in filtered_predicates: totalextension.append( lambda x, predicate=predicate: plain_extension( x, predicate, connected_clauses=True)) filtered_predicates.append(predicate) # create the hypothesis space hs = TopDownHypothesisSpace(primitives=totalextension, head_constructor=c_pred("train_task", 1), expansion_hooks_reject=[ lambda x, y: has_singleton_vars(x, y), lambda x, y: has_duplicated_literal(x, y) ]) program = learner.learn(task, background, hs) print(program)