def use_module(self, module_name: str, **kwargs): if module_name.startswith('library'): # create library functor library_term = swipy.swipy_new_atom("library") library_funct = swipy.swipy_new_functor(library_term, 1) # create inner module name: library([name]) module_inner_name = module_name[:-1].replace('library(', '') inner_name = swipy.swipy_new_term_ref() swipy.swipy_put_atom_chars(inner_name, module_inner_name) # construct library(name) full_module = swipy.swipy_new_term_ref() swipy.swipy_cons_functor(full_module, library_funct, inner_name) else: full_module = swipy.swipy_new_term_ref() swipy.swipy_put_atom_chars(full_module, module_name) # load module use_module = swipy.swipy_predicate("use_module", 1, None) query = swipy.swipy_open_query(use_module, full_module) r = swipy.swipy_next_solution(query) swipy.swipy_close_query(query) if r == 0: raise Exception(f"could not load module {module_name}") return r
def _swipy_to_pair(term): head = swipy.swipy_new_term_ref() tail = swipy.swipy_new_term_ref() swipy.swipy_get_head(term, head) swipy.swipy_get_tail(term, tail) return Pair(_read_swipy(head), _read_swipy(tail))
def _pair_to_swipy_ref(item: Pair, swipy_ref, lit_var_store: Dict[Variable, int]): head = swipy.swipy_new_term_ref() tail = swipy.swipy_new_term_ref() _to_swipy_ref(item.get_left(), head, lit_var_store) _to_swipy_ref(item.get_right(), tail, lit_var_store) swipy.swipy_cons_list(swipy_ref, head, tail)
def _list_to_swipy(item: List, lit_var_store: Dict[Variable, int]): list_term = swipy.swipy_new_term_ref() clist_term = swipy.swipy_new_term_ref() swipy.swipy_put_nil(list_term) args = item.get_arguments() for ind in range(len(args) - 1, -1, -1): _to_swipy_ref(args[ind], clist_term, lit_var_store) swipy.swipy_cons_list(list_term, clist_term, list_term) return list_term
def _var_to_swipy(var: Variable, lit_var_store: Dict[Variable, int]): if var in lit_var_store: return lit_var_store[var] else: tmpV = swipy.swipy_new_term_ref() swipy.swipy_put_variable(tmpV) lit_var_store[var] = tmpV return tmpV
def _num_to_swipy(num: Union[int, float]): n = swipy.swipy_new_term_ref() if isinstance(num, int): swipy.swipy_put_integer(n, num) else: swipy.swipy_put_float(n, num) return n
def _neg_to_swipy(clause: Not, lit_var_store: Dict[Variable, int]): lit = _lit_to_swipy(clause.get_atom(), lit_var_store) neg_atom = swipy.swipy_new_atom("\\+") neg_functor = swipy.swipy_new_functor(neg_atom, 1) entire_negation = swipy.swipy_new_term_ref() swipy.swipy_cons_functor(entire_negation, neg_functor, lit) return entire_negation
def query(self, *query, **kwargs): if 'max_solutions' in kwargs: max_solutions = kwargs['max_solutions'] else: max_solutions = -1 vars_of_interest = [[y for y in x.get_arguments() if isinstance(y, Variable)] for x in query] vars_of_interest = reduce(lambda x, y: x + y, vars_of_interest, []) vars_of_interest = reduce(lambda x, y: x + [y] if y not in x else x, vars_of_interest, []) var_store = {} for v in vars_of_interest: tmp_v = swipy.swipy_new_term_ref() swipy.swipy_put_variable(tmp_v) var_store[v] = tmp_v if len(query) == 1: query = query[0] predicate_name = query.get_predicate().get_name() query_args = swipy.swipy_new_term_refs(query.get_predicate().get_arity()) for ind, arg in enumerate(query.get_arguments()): _to_swipy_ref(arg, query_args + ind, var_store) pred = swipy.swipy_predicate(predicate_name, query.get_predicate().get_arity(), None) query = swipy.swipy_open_query(pred, query_args) else: swipy_objs = [_lit_to_swipy(x, var_store) if isinstance(x, Atom) else _neg_to_swipy(x, var_store) for x in query] first = swipy_objs[0] rest = _conjoin_literals(swipy_objs[1:]) compound_arg = swipy.swipy_new_term_refs(2) swipy.swipy_put_term(compound_arg, first) swipy.swipy_put_term(compound_arg + 1, rest) predicate = swipy.swipy_predicate(",", 2, None) query = swipy.swipy_open_query(predicate, compound_arg) r = swipy.swipy_next_solution(query) all_solutions = [] var_index_var = dict([(var_store[v], v) for v in var_store]) while r and max_solutions != 0: max_solutions -= 1 tmp_solution = {} for var in var_store: tmp_solution[var] = _read_swipy(var_store[var], swipy_term_to_var=var_index_var) all_solutions.append(tmp_solution) r = swipy.swipy_next_solution(query) swipy.swipy_close_query(query) return all_solutions
def _swipy_to_list(term): elements = [] list = swipy.swipy_copy_term_ref(term) head = swipy.swipy_new_term_ref() while swipy.swipy_get_list(list, head, list): elements.append(_read_swipy(head)) return List(elements)
def _structure_to_swipy(item: Structure, lit_var_store: Dict[Variable, int]): func = _functor_to_swipy(item.get_functor()) compound_arg = swipy.swipy_new_term_refs(item.get_functor().get_arity()) struct_args = item.get_arguments() _to_swipy_ref(struct_args[0], compound_arg, lit_var_store) for i in range(1, item.get_functor().get_arity()): _to_swipy_ref(struct_args[i], compound_arg + i, lit_var_store) structure = swipy.swipy_new_term_ref() swipy.swipy_cons_functor(structure, func, compound_arg) return structure
def _list_to_swipy_ref(item: List, swipy_ref, lit_var_store: Dict[Variable, int]): if len(item.get_arguments()) == 0: # if empty swipy.swipy_put_nil(swipy_ref) else: # if not empty clist_term = swipy.swipy_new_term_ref() swipy.swipy_put_nil(swipy_ref) args = item.get_arguments() for ind in range(len(args) - 1, -1, -1): _to_swipy_ref(args[ind], clist_term, lit_var_store) swipy.swipy_cons_list(swipy_ref, clist_term, swipy_ref)
def consult(self, filename: str): string_term = swipy.swipy_new_term_ref() swipy.swipy_put_string_chars(string_term, filename) consult_pred = swipy.swipy_predicate("consult", 1, None) query = swipy.swipy_open_query(consult_pred, string_term) r = swipy.swipy_next_solution(query) swipy.swipy_close_query(query) if r == 0: raise Exception(f"something wrong when consulting file {filename}") return r
def _swipy_to_structure(term): name, arity = swipy.swipy_get_name_arity(term) name = swipy.swipy_atom_chars(name) functor = c_functor(name, arity) structure_elements = [] for arg_ind in range(1, arity + 1): elem = swipy.swipy_new_term_ref() swipy.swipy_get_arg(arg_ind, term, elem) structure_elements.append(_read_swipy(elem)) return functor(*structure_elements)
def _conjoin_literals(lits: Sequence[int]): if len(lits) == 1: return lits[0] else: f_atm = swipy.swipy_new_atom(",") conj_functor = swipy.swipy_new_functor(f_atm, 2) compound_arg = swipy.swipy_new_term_refs(2) conj = swipy.swipy_new_term_ref() swipy.swipy_put_term(compound_arg, lits[0]) swipy.swipy_put_term(compound_arg + 1, _conjoin_literals(lits[1:])) swipy.swipy_cons_functor(conj, conj_functor, compound_arg) return conj
def _lit_to_swipy(clause: Atom, lit_var_store: Dict[Variable, int]): if clause.get_predicate().get_arity() == 0: functor = _const_to_swipy(clause.get_predicate()) return functor else: functor = _functor_to_swipy(clause.get_predicate()) compound_arg = swipy.swipy_new_term_refs(clause.get_predicate().get_arity()) args = clause.get_arguments() _to_swipy_ref(args[0], compound_arg, lit_var_store) for i in range(1, clause.get_predicate().get_arity()): _to_swipy_ref(args[i], compound_arg+i, lit_var_store) literal = swipy.swipy_new_term_ref() swipy.swipy_cons_functor(literal, functor, compound_arg) return literal
def _wrap_in_call_time(self, query, time): """ Wraps the query in call_with_time_limit. Assumes that query is already translated to swipy :param query: :param time: :return: """ func_atm = swipy.swipy_new_atom("call_with_time_limit") func = swipy.swipy_new_functor(func_atm, 2) compound_arg = swipy.swipy_new_term_refs(2) _num_to_swipy_ref(time, compound_arg) swipy.swipy_put_term(compound_arg + 1, query) final_term = swipy.swipy_new_term_ref() swipy.swipy_cons_functor(final_term, func, compound_arg) return final_term
def _cl_to_swipy(clause: Clause, lit_var_store: Dict[Variable, int]): body: typing.Sequence[Union[Atom, Not]] = clause.get_body().get_literals() head: Atom = clause.get_head() body: typing.List[int] = [_lit_to_swipy(x, lit_var_store) if isinstance(x, Atom) else _neg_to_swipy(x, lit_var_store) for x in body] head = _lit_to_swipy(head, lit_var_store) body = _conjoin_literals(body) clause_atom = swipy.swipy_new_atom(":-") clause_functor = swipy.swipy_new_functor(clause_atom, 2) entire_clause = swipy.swipy_new_term_ref() compound_arg = swipy.swipy_new_term_refs(2) swipy.swipy_put_term(compound_arg, head) swipy.swipy_put_term(compound_arg + 1, body) swipy.swipy_cons_functor(entire_clause, clause_functor, compound_arg) return entire_clause
def query(self, *query, **kwargs): if 'max_solutions' in kwargs: max_solutions = kwargs['max_solutions'] else: max_solutions = -1 if 'time_limit' in kwargs: time_limit = kwargs['time_limit'] else: time_limit = None if 'depth_limit' in kwargs: depth_limit = kwargs['depth_limit'] else: depth_limit = None if 'inference_limit' in kwargs: inference_limit = kwargs['inference_limit'] else: inference_limit = None vars_of_interest = [[y for y in x.get_arguments() if isinstance(y, Variable)] for x in query] vars_of_interest = reduce(lambda x, y: x + y, vars_of_interest, []) vars_of_interest = reduce(lambda x, y: x + [y] if y not in x else x, vars_of_interest, []) var_store = {} for v in vars_of_interest: tmp_v = swipy.swipy_new_term_ref() swipy.swipy_put_variable(tmp_v) var_store[v] = tmp_v # if len(query) == 1: # query = query[0] # predicate_name = query.get_predicate().get_name() # query_args = swipy.swipy_new_term_refs(query.get_predicate().get_arity()) # # for ind, arg in enumerate(query.get_arguments()): # _to_swipy_ref(arg, query_args + ind, var_store) # # pred = swipy.swipy_predicate(predicate_name, query.get_predicate().get_arity(), None) # query = swipy.swipy_open_query(pred, query_args) # else: # swipy_objs = [_lit_to_swipy(x, var_store) if isinstance(x, Atom) else _neg_to_swipy(x, var_store) for x # in query] # first = swipy_objs[0] # rest = _conjoin_literals(swipy_objs[1:]) # # compound_arg = swipy.swipy_new_term_refs(2) # swipy.swipy_put_term(compound_arg, first) # swipy.swipy_put_term(compound_arg + 1, rest) # # predicate = swipy.swipy_predicate(",", 2, None) # query = swipy.swipy_open_query(predicate, compound_arg) pred, compound_arg = self._prepare_query(var_store, *query, max_time=time_limit, max_depth=inference_limit, max_inference=inference_limit) query = swipy.swipy_open_query(pred, compound_arg) r = swipy.swipy_next_solution(query) all_solutions = [] var_index_var = dict([(var_store[v], v) for v in var_store]) while r and max_solutions != 0: max_solutions -= 1 tmp_solution = {} for var in var_store: tmp_solution[var] = _read_swipy(var_store[var], swipy_term_to_var=var_index_var) all_solutions.append(tmp_solution) r = swipy.swipy_next_solution(query) swipy.swipy_close_query(query) return all_solutions
def _const_to_swipy(const: Union[Constant, Predicate]): c = swipy.swipy_new_term_ref() swipy.swipy_put_atom_chars(c, const.get_name()) return c