def get_refined_query_generator(tilde_query: TILDEQuery, language: TypeModeLanguage, debug_printing: bool = False): # generating the refined queries to test refinement_generator = language.refine_conjunction_one_literal(tilde_query) for refinement in refinement_generator: # type: Term refined_query = TILDEQuery(tilde_query, refinement) yield refined_query
def get_initial_query(query_head_if_keys_format: Optional[Term] = None): if query_head_if_keys_format is not None: initial_tilde_query = TILDEQueryHiddenLiteral(query_head_if_keys_format) else: initial_tilde_query = TILDEQuery(None, None) wrapper_initial_tilde_query = FLGGQueryWrapper(initial_tilde_query, build_hypothesis(initial_tilde_query)) return wrapper_initial_tilde_query
def build_hypothesis(tilde_query: TILDEQuery) -> HypothesisWrapper: clause = ClauseWrapper(clause_id=None) literals = tilde_query.get_literals_of_body() # NOTE: only of query body for literal in literals: clause.add_literal_to_body(literal) clause.lock_adding_to_clause() clause.add_problog_clause(tilde_query) hypothesis = HypothesisWrapper(clause) return hypothesis
def get_refined_queries_of(tilde_query: TILDEQuery, language: TypeModeLanguage, debug_printing: bool = False) -> \ Iterable[TILDEQuery]: # generating the refined queries to test refinement_generator = language.refine_conjunction_one_literal(tilde_query) refined_queries = [] # type: List[TILDEQuery] for refinement in refinement_generator: # type: Term refined_query = TILDEQuery(tilde_query, refinement) refined_queries.append(refined_query) if debug_printing: print('generated refined queries of: ', str(tilde_query)) print('refined queries:', list(map(str, refined_queries))) return refined_queries
def evaluate(self, instance: Example, test: TILDEQuery) -> bool: query_conj = test.to_conjunction() db_to_query = self.db.extend() for statement in instance.data: db_to_query += statement # TODO: remove ugly hack if hasattr(instance, 'classification_term'): db_to_query += instance.classification_term db_to_query += (self.to_query << query_conj) query_result = problog.get_evaluatable().create_from(db_to_query, engine=self.engine).evaluate() return query_result[self.to_query] > 0.5
def refine_conjunction_one_literal(self, query: TILDEQuery) -> Iterator[Term]: # 1. we need to know how many variables are in the already existing rule. # We also need to know the types of these variables. # This is important information when adding new literals. nb_of_vars_in_query = len(query.get_variables()) variables_in_query_by_type = self.get_variable_types(*query.get_literals()) # type: Dict[TypeName, List[Term]] #TODO: check if this is okay # if key_output: # add variables of head to variables_in_query_by_type # We check the most recently added body literal. # If there is a most recently added body literal, # then we check whether its functor is '_recursive' # If its most recently added body literal is '_recursive', # we cannot extend the body any further, # so the function returns. # Else, we get the set of already generated literals from the last added literal # If there is no recently added body literal, # we will have to start from scratch, from an empty set if query.get_literal() is not None: already_generated_literals = query.get_literal().refine_state else: already_generated_literals = set() # We need to generate a literal to refine the body of the clause # # 1) a positive refinement # We have defined which literals can be added in _refinement_modes, # as their functor and the mode of each of the arguments. # We will consider each functor as a possible candidate for refinement # # SO for each functor in MODES for functor, argument_mode_indicators in self._refinement_modes: # e.g. 'parent', ['+', '+'] # for each possible combination of arguments: # create a term using the functor and the arguments. # IF the term hasn't already been generated in the past: # IF we want to break symmetries # add the term to the set of already generated terms # Substitute each of the '#'-vars for a new variable # add the term t as the prototype of the substuted term # We know want to be return the substituted term # But before returning, # we want to save the state of this function, # so we can generate new terms next time we call this function. # To do this, we add the set of generated terms to the new literal. # IF we want to break symmetry, # save a shallow copy of the set of generated literals # ELSE # save the UNION of the seg of generated literals and {t, -t, t_i, -t_i} # for args in product(*arguments): # t = Term(functor, *args) possible_term_generator = self.__get_possible_terms_for(functor, argument_mode_indicators, variables_in_query_by_type) for t in possible_term_generator: if t not in already_generated_literals: if self._symmetry_breaking: already_generated_literals.add(t) t_i = t.apply(TypeModeLanguage.ReplaceNew(nb_of_vars_in_query)) t_i.prototype = t if self._symmetry_breaking: t_i.refine_state = already_generated_literals.copy() else: t_i.refine_state = already_generated_literals | {t, -t, t_i, -t_i} yield t_i
for statement in instance.data: db_to_query += statement # TODO: remove ugly hack if hasattr(instance, 'classification_term'): db_to_query += instance.classification_term db_to_query += (self.to_query << query_conj) query_result = problog.get_evaluatable().create_from(db_to_query, engine=self.engine).evaluate() return query_result[self.to_query] > 0.5 if __name__ == '__main__': instance = PrologString(""" color(blue). taste(sweet). texture(fruity). """) query = TILDEQuery(None, Term('color')(Var('X'))) evaluator = SimpleProgramQueryEvaluator() result = evaluator.evaluate(instance, query) print(result)
def build_hypothesis(tilde_query: TILDEQuery) -> str: return literals_to_flgg_clause_string( tilde_query.get_literals_as_subsumption_list())
def get_initial_query(query_head_if_keys_format: Optional[Term] = None): if query_head_if_keys_format is not None: initial_query = TILDEQueryHiddenLiteral(query_head_if_keys_format) else: initial_query = TILDEQuery(None, None) return initial_query