def has_not_previous_output_as_input(head: Atom, body: Body) -> bool: atom_list = [ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ] atom_list.insert(0, head) return not_previous_output_as_input_exists(atom_list)
def has_g1_same_vars_in_literal(head: Atom, body: Body) -> bool: """ Returns True if there exists a literal with all same vars """ return literal_exist_g1_same_variables([ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ])
def has_duplicated_var_set(head: Atom, body: Body) -> bool: """ Returns True if there exists a variable set that is also used in other literals in the body """ return duplicated_var_set_exists([ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ])
def max_pred_occurrences(head: Atom, body: Body, pred: Predicate, max_occurrence: int) -> bool: """ Returns True if the predicate pred does not appear more than max_occurrence times in the clause """ preds = [x for x in body.get_literals() if x.get_predicate() == pred] return len(preds) <= max_occurrence
def endless_recursion_exists(head: Atom, body: Body) -> bool: for literal in body.get_literals(): if head.get_predicate() == literal.get_predicate(): if literal.get_variables()[0] == head.get_variables()[0]: return True return False return False
def connected_body(head: Atom, body: Body) -> bool: """ Returns True if variables in the body cannot be partitioned in two non-overlapping sets """ if len(body) == 0: return True return are_variables_connected([ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ])
def max_var_occurrences(head: Atom, body: Body, max_occurrence: int) -> bool: """ Returns True if the predicate pred does not appear more than max_occurrence times in the clause """ if len(body.get_variables()) > 0: counter = Counter(body.get_variables()) if (body.get_literals()[-1].get_predicate().get_name() == 'copy1'): print(counter) return counter.most_common()[0][1] >= max_occurrence else: return False
def negation_at_the_end(head: Atom, body: Body) -> bool: """ Returns True is negations appear after all positive literals """ pos_location = -1 neg_location = -1 lits = body.get_literals() for ind in range(len(lits)): if isinstance(lits[ind], Atom): pos_location = ind elif neg_location < 0: neg_location = ind return False if (-1 < neg_location < pos_location) else True
def initialise(self, initial_clause: typing.Union[Clause, Body]) -> None: """ Initialises the search space. It is possible to provide an initial clause to initialize the hypothesis space with (instead of :-). """ if isinstance(self._head_constructor, (Predicate, FillerPredicate)): if isinstance(self._head_constructor, Predicate): # create possible heads head_variables = [chr(x) for x in range(ord("A"), ord("Z")) ][:self._head_constructor.get_arity()] possible_heads = [ self._head_constructor(*list(x)) for x in combinations_with_replacement( head_variables, self._head_constructor.get_arity()) ] else: possible_heads = self._head_constructor.all_possible_atoms() # create empty clause or use initial clause if initial_clause: clause = initial_clause if isinstance( initial_clause, Body) else initial_clause.get_body() else: clause = Body() if len(clause.get_literals()) > 0 and len(clause.get_variables( )) < self._head_constructor.get_arity(): raise AssertionError( "Cannot provide an initial clause with fewer distinct variables than the head predicate!" ) init_head_dict = { "ignored": False, "blocked": False, "visited": False } self._hypothesis_space.add_node(clause) self._hypothesis_space.nodes[clause]["heads"] = dict([ (x, init_head_dict.copy()) for x in possible_heads ]) self._hypothesis_space.nodes[clause]["visited"] = False self._pointers["main"] = clause self._root_node = clause else: raise Exception( f"Unknown head constructor ({self._head_constructor}")
def has_singleton_vars(head: Atom, body: Body) -> bool: """ Returns True is the clause has a singleton variable (appears only once) """ if len(body) == 0: return False vars = {} head_vars = head.get_variables() for ind in range(len(head_vars)): if head_vars[ind] not in vars: vars[head_vars[ind]] = head_vars.count(head_vars[ind]) bvars = body.get_variables() body_vars_flat = reduce(lambda x, y: x + y, [x.get_variables() for x in body.get_literals()], []) for ind in range(len(bvars)): if bvars[ind] in vars: vars[bvars[ind]] += body_vars_flat.count(bvars[ind]) else: vars[bvars[ind]] = body_vars_flat.count(bvars[ind]) return True if any([k for k, v in vars.items() if v == 1]) else False
def has_duplicated_literal(head: Atom, body: Body) -> bool: """ Returns True if there are duplicated literals in the body """ return len(body) != len(set(body.get_literals()))
def head_first(head: Atom, body: Body) -> bool: return len( set(body.get_literals()[0].get_variables()).intersection( set(head.get_variables()))) != 0
def has_unexplained_last_var_strict(head: Atom, body: Body) -> bool: return strict_unexplained_last_var_exists([ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ])
def only_1_pred_for_1_var(head: Atom, body: Body) -> bool: return only_1_pred_exists_for_1_var([ x.get_atom() if isinstance(x, Not) else x for x in body.get_literals() ])
def _get_body_predicates_list(body: Body): return [x.get_predicate() for x in body.get_literals()]
def has_duplicated_variable(head: Atom, body: Body) -> bool: return len(body.get_literals()[-1].get_variables()) != len( set(body.get_literals()[-1].get_variables()))