def has_solution(self, *query: Union[Atom, Not]): var_store = {} if len(query) == 1: query = query[0] args = [_to_pygp(x, var_store) for x in query.get_arguments()] func = pygprolog.pygp_Find_Atom(query.get_predicate().get_name()) pygprolog.pygp_Query_Begin() q_Var1 = pygprolog.pygp_Query_Call(func, query.get_predicate().get_arity(), args) pygprolog.pygp_Query_End() return True if q_Var1 == 1 else False else: first_elem = _lit_to_pygp(query[0], var_store) rest = [ _lit_to_pygp(x, var_store) if isinstance(x, Atom) else _neg_to_pygp(x, var_store) for x in query[1:] ] rest = _conjoin_lits(rest) pygprolog.pygp_Query_Begin() conjf = pygprolog.pygp_Find_Atom(",") q_Var = pygprolog.pygp_Query_Call(conjf, 2, [first_elem, rest]) pygprolog.pygp_Query_End() return True if q_Var == 1 else False
def _neg_to_pygp(negation: Not, var_store=None): if var_store is None: var_store = {} inner = _lit_to_pygp(negation.get_atom(), var_store) ng_f = pygprolog.pygp_Find_Atom("\\+") return pygprolog.pygp_Mk_Compound(ng_f, 1, [inner])
def _functor_to_pygp(func: Functor): intKey = pygprolog.pygp_Find_Atom(func.get_name()) if intKey == -1: return pygprolog.pygp_Mk_Atom(func.get_name()) else: return intKey
def _lit_to_pygp(literal: Atom, var_store=None): if var_store is None: var_store = {} pred = pygprolog.pygp_Find_Atom(literal.get_predicate().get_name()) if pred < 0: pred = pygprolog.pygp_Create_Allocate_Atom(literal.get_predicate().get_name()) args = [_to_pygp(x, var_store) for x in literal.get_arguments()] return pygprolog.pygp_Mk_Compound(pred, literal.get_predicate().get_arity(), args)
def _retract_lit(self, literal: Atom): pl = _lit_to_pygp(literal) asa_p = pygprolog.pygp_Find_Atom("retract") pygprolog.pygp_Query_Begin() q_Var1 = pygprolog.pygp_Query_Call(asa_p, 1, [pl]) pygprolog.pygp_Query_End() return q_Var1
def consult(self, filename): consult = pygprolog.pygp_Find_Atom("consult") arg = pygprolog.pygp_Mk_String(filename) pygprolog.pygp_Query_Begin() q_Var1 = pygprolog.pygp_Query_Call(consult, 1, [arg]) pygprolog.pygp_Query_End() return q_Var1
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 = dict([(x, pygprolog.pygp_Mk_Variable()) for x in vars_of_interest]) pygprolog.pygp_Query_Begin() if len(query) == 1: query = query[0] f = pygprolog.pygp_Find_Atom(query.get_predicate().get_name()) args = [_to_pygp(x, var_store) for x in query.get_arguments()] res = pygprolog.pygp_Query_Call(f, len(args), args) else: first = _lit_to_pygp(query[0], var_store) rest = [ _lit_to_pygp(x, var_store) if isinstance(x, Atom) else _neg_to_pygp(x, var_store) for x in query[1:] ] rest = _conjoin_lits(rest) conjf = pygprolog.pygp_Find_Atom(",") res = pygprolog.pygp_Query_Call(conjf, 2, [first, rest]) # discover all solutions all_solutions = [] while res and max_solutions != 0: tmp_solution = {} for vn in var_store: tmp_solution[vn] = _read_pygp(var_store[vn]) res = pygprolog.pygp_Query_Next_Solution() max_solutions -= 1 all_solutions.append(tmp_solution) pygprolog.pygp_Query_End() return all_solutions
def _retract_cl(self, clause: Clause): clp = _cl_to_pygp(clause) asa_p = pygprolog.pygp_Find_Atom("retract") pygprolog.pygp_Query_Begin() q_Var1 = pygprolog.pygp_Query_Call(asa_p, 1, [clp]) pygprolog.pygp_Query_End() return q_Var1
def _pair_to_pygp(p: Pair, lit_var_store: Dict[Variable, int]): left = _to_pygp(p.get_left(), lit_var_store) right = _to_pygp(p.get_right(), lit_var_store) functor = pygprolog.pygp_Find_Atom('.') if functor < 0: functor = pygprolog.pygp_Create_Allocate_Atom('.') args = [left, right] return pygprolog.pygp_Mk_Compound(functor, 2, args)
def _cl_to_pygp(clause: Clause): var_store = {} head_pygp = _lit_to_pygp(clause.get_head(), var_store) body_pygp = [ _lit_to_pygp(x, var_store) if isinstance(x, Atom) else _neg_to_pygp(x, var_store) for x in clause.get_body().get_literals() ] # conj_f = pygprolog.pygp_Find_Atom(",") # body_pygp = reduce(lambda x, y: pygprolog.pygp_Mk_Compound(conj_f, 2, [x, y]), body_pygp) body_pygp = _conjoin_lits(body_pygp) cl_f = pygprolog.pygp_Find_Atom(":-") return pygprolog.pygp_Mk_Compound(cl_f, 2, [head_pygp, body_pygp])
def _conjoin_lits(pyg_literals): conj_f = pygprolog.pygp_Find_Atom(",") return reduce(lambda x, y: pygprolog.pygp_Mk_Compound(conj_f, 2, [x, y]), pyg_literals)