def test_numeral(): from prolog.interpreter.term import Callable, Atom, BindingVar from prolog.interpreter.continuation import Engine t = parse_file(""" numeral(null). % end of line comment numeral(succ(X)) :- numeral(X). % another one add_numeral(X, null, X). add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z). greater_than(succ(null), null). greater_than(succ(X), null) :- greater_than(X, null). greater_than(succ(X), succ(Y)) :- greater_than(X, Y). """) builder = TermBuilder() facts = builder.build(t) e = Engine() m = e.modulewrapper for fact in facts: print fact e.add_rule(fact) assert m.modules["user"].lookup(Signature.getsignature("add_numeral", 3)).rulechain.head.argument_at(1).name() == "null" four = Callable.build("succ", [Callable.build("succ", [Callable.build("succ", [Callable.build("succ", [Callable.build("null")])])])]) e.run_query_in_current(parse_query_term("numeral(succ(succ(null))).")) term = parse_query_term( """add_numeral(succ(succ(null)), succ(succ(null)), X).""") e.run_query_in_current(term) hp = Heap() var = BindingVar().dereference(hp) # does not raise var.unify(four, hp) term = parse_query_term( """greater_than(succ(succ(succ(null))), succ(succ(null))).""") e.run_query_in_current(term)
def get_rules_from_fact(engine, rule, rule_dist, query, heap, rules = None): module = engine.modulewrapper.current_module rule = rule.split('/') name = rule[0] nargs = int(rule[1]) sig = Signature.getsignature(name, nargs) function = module.lookup(sig) simchain = [] if (function.rulechain is None): return None #handle by UnificationFailed if rules is None: rules = [] #engine._print_rulechain(function.rulechain) #print('\n') startrulechain = jit.hint(function.rulechain, promote = True) if startrulechain is not None: rulechain, simchain = startrulechain.find_applicable_rule(query, heap, engine.similarity, simchain, module, nargs) # TODO similarity while rulechain is not None: rules.append(jit.hint(rulechain, promote = True)) rulechain, simchain = rulechain.find_next_applicable_rule(query, heap, engine.similarity, simchain, module, nargs) #print(rules) return rules
def test_traceback_in_if(): e = get_engine(""" h(y). g(a). g(_) :- throw(foo). f(X, Y) :- (g(X) -> X = 1 ; X = 2), h(Y). """) error = get_uncaught_error("f(1, Y).", e) sig_g = Signature.getsignature("g", 1) sig_f = Signature.getsignature("f", 2) m = e.modulewrapper rule_f = m.user_module.lookup(sig_f).rulechain rule_g = m.user_module.lookup(sig_g).rulechain.next tb = error.traceback assert tb.rule is rule_f assert tb.next.rule is rule_g
def build(term_name, args=None, signature=None, heap=None, cache=True): if args is None: args = [] if heap is not None: # perform variable shunting: # remove variables that are not needed because they are bound # already and cannot be backtracked for i in range(len(args)): arg = args[i] if (isinstance(arg, Var) and arg.getbinding() is not None and arg.created_after_choice_point is heap): args[i] = arg.getbinding() if len(args) == 0: if cache: return Atom.newatom(term_name, signature) return Atom(term_name, signature) else: if signature is None: if cache: signature = Signature.getsignature(term_name, len(args)) else: signature = Signature(term_name, len(args)) else: assert signature.numargs == len(args) assert isinstance(signature, Signature) cls = Callable._find_specialized_class(term_name, len(args)) if cls is not None: return cls(term_name, args, signature) cls = Callable._find_specialized_class('Term', len(args)) if cls is not None: return cls(term_name, args, signature) return Term(term_name, args, signature)
def generate_class(cname, fname, n_args): from rpython.rlib.unroll import unrolling_iterable arg_iter = unrolling_iterable(range(n_args)) parent = callables['Abstract', n_args] assert parent is not None signature = Signature.getsignature(fname, n_args) class specific_class(parent): if n_args == 0: TYPE_STANDARD_ORDER = Atom.TYPE_STANDARD_ORDER else: TYPE_STANDARD_ORDER = Term.TYPE_STANDARD_ORDER def __init__(self, term_name, args, signature): parent._init_values(self, args) assert self.name() == term_name assert args is None or len(args) == n_args def name(self): return fname def signature(self): return signature def _make_new(self, name, signature): cls = specific_class return cls(name, None, signature) specific_class.__name__ = cname return specific_class
def isFactInKB(factPredicate, factArgs, factQuery, prolog, predicateDict): sig = Signature.getsignature(str(factPredicate), len(factArgs)) isBuiltin = prolog.get_builtin(sig) assert (not isBuiltin), 'we should have already checked this' factInKB = False query = '{0}({1}).'.format( factPredicate, ','.join(['X_{0}'.format(i) for i in range(len(factArgs))])) if prologPath == '/testnet' or prologPath == '/proofspyrolog': proof = collect_all(prolog, query, [], [], [], []) elif prologPath == '/spyrolog': proof = collect_all(prolog, query, [], [], []) for vGrounding in proof: groundings = vGrounding[0] args = set() for variable, grounding in groundings.iteritems(): if hasattr(grounding, 'name'): args.add(grounding.name()) elif hasattr(grounding, 'num'): args.add(grounding.num) else: print 'dir:', dir(grounding) raise AttributeError if not set(factArgs).difference(args): factInKB = True break return factInKB
def newatom(name, signature=None): if signature is None: signature = Signature.getsignature(name, 0) result = Atom.cache.get(signature, None) if result is not None: return result Atom.cache[signature] = result = Atom(name, signature) return result
def add_module(self, name, exports = []): mod = Module(name) for export in exports: mod.exports.append(Signature.getsignature( *unwrap_predicate_indicator(export))) self.current_module = mod self.modules[name] = mod self.version = VersionTag()
def add_module(self, name, exports=[]): mod = Module(name) for export in exports: mod.exports.append( Signature.getsignature(*unwrap_predicate_indicator(export))) self.current_module = mod self.modules[name] = mod self.version = VersionTag()
def impl_use_module_with_importlist(engine, heap, module, path, imports): importlist = [] for sigatom in imports: importlist.append(Signature.getsignature( *unwrap_predicate_indicator(sigatom))) if isinstance(path, Atom): handle_use_module(engine, heap, module, path, importlist) else: handle_use_module_with_library(engine, heap, module, path, importlist)
def impl_use_module_with_importlist(engine, heap, module, path, imports): importlist = [] for sigatom in imports: importlist.append( Signature.getsignature(*unwrap_predicate_indicator(sigatom))) if isinstance(path, Atom): handle_use_module(engine, heap, module, path, importlist) else: handle_use_module_with_library(engine, heap, module, path, importlist)
def test_lookup(): e = get_engine(""" :- use_module(m). f(a) :- g(a, b). """, m=""" :- module(m, [g/2]). g(a, b). h(w). """) f_sig = Signature.getsignature("f", 1) g_sig = Signature.getsignature("g", 2) h_sig = Signature.getsignature("h", 1) user = e.modulewrapper.modules["user"] m = e.modulewrapper.modules["m"] assert user.lookup(g_sig) == m.functions[g_sig] assert user.lookup(h_sig).rulechain is None assert m.lookup(g_sig) == m.functions[g_sig] assert m.lookup(f_sig).rulechain is None assert m.lookup(h_sig) == m.functions[h_sig]
def test_lookup(): e = get_engine(""" :- use_module(m). f(a) :- g(a, b). """, m = """ :- module(m, [g/2]). g(a, b). h(w). """) f_sig = Signature.getsignature("f", 1) g_sig = Signature.getsignature("g", 2) h_sig = Signature.getsignature("h", 1) user = e.modulewrapper.modules["user"] m = e.modulewrapper.modules["m"] assert user.lookup(g_sig) == m.functions[g_sig] assert user.lookup(h_sig).rulechain is None assert m.lookup(g_sig) == m.functions[g_sig] assert m.lookup(f_sig).rulechain is None assert m.lookup(h_sig) == m.functions[h_sig]
def test_discard_useless_env_suffix(): e = get_engine(""" f(h(A), A, B, C) :- g(B), h(D), h1(D), h(E). """) # classes of variables: # just in head: A (needs index at the end of env) # both: B (needs index at the beginning of env) # singletons head: C (-1) # singletons body: E (-1, XXX currently not optimized) # just in body: D (needs index at end of env, appended after matching head) func = e.modulewrapper.current_module.lookup(Signature.getsignature( "f", 4))
def test_source_range(): e = get_engine(""" f(a) :- a. f(b) :- b. a. b. """) func = e.modulewrapper.current_module.lookup(Signature.getsignature("f", 1)) assert func.rulechain.line_range == [1, 2] assert func.rulechain.next.line_range == [2, 4] assert func.rulechain.file_name == "<unknown>" assert func.rulechain.source == "f(a) :- a." assert func.rulechain.next.source == "f(b) :-\n b."
def test_source_range(): e = get_engine(""" f(a) :- a. f(b) :- b. a. b. """) func = e.modulewrapper.current_module.lookup(Signature.getsignature( "f", 1)) assert func.rulechain.line_range == [1, 2] assert func.rulechain.next.line_range == [2, 4] assert func.rulechain.file_name == "<unknown>" assert func.rulechain.source == "f(a) :- a." assert func.rulechain.next.source == "f(b) :-\n b."
def impl_abolish(engine, heap, module, predicate): modname = None if predicate.signature().eq(prefixsig): modname, predicate = unpack_modname_and_predicate(predicate) name, arity = helper.unwrap_predicate_indicator(predicate) if arity < 0: error.throw_domain_error("not_less_than_zero", term.Number(arity)) signature = Signature.getsignature(name, arity) if signature.get_extra("builtin"): error.throw_permission_error("modify", "static_procedure", predicate) if modname is not None: module = engine.modulewrapper.get_module(modname, predicate) try: del module.functions[signature] except KeyError: pass
def find_applicable_rule(self, query, heap=None, similarity=None, simchain=[], module=None, nargs=0): # This method should do some quick filtering on the rules to filter out # those that cannot match query. Here is where e.g. indexing should # occur. while ((self is not None) or (simchain != [])): #print "Entering loop", self, "simchain", simchain # if self is None go to next rule in simchain if (self == None): #print("Moving to next rulechain in simchain...") name = simchain[0] simchain = simchain[1:] signature = Signature.getsignature(name, nargs) function = module.lookup(signature) self = function.rulechain if (self == None): continue #print(self.scores[0] * heap.predicate_score) #print(similarity.threshold) if (self.scores[0] * heap.predicate_score >= similarity.threshold): if self.headargs is not None: if (len(self.headargs) != query.argument_count()): self = self.next continue assert isinstance(query, Callable) for i in range(len(self.headargs)): arg2 = self.headargs[i] arg1 = query.argument_at(i) if not arg2.quick_unify_check(arg1, similarity=similarity): break else: return self, simchain else: return self, simchain self = self.next return None, []
def generate_class(cname, fname, n_args, immutable=True): from rpython.rlib.unroll import unrolling_iterable arg_iter = unrolling_iterable(range(n_args)) parent = callables['Abstract', n_args] if not immutable: parent = parent.mutable_version assert parent is not None signature = Signature.getsignature(fname, n_args) class specific_class(parent): if n_args == 0: TYPE_STANDARD_ORDER = Atom.TYPE_STANDARD_ORDER else: TYPE_STANDARD_ORDER = Term.TYPE_STANDARD_ORDER def __init__(self, term_name, args, signature): parent._init_values(self, args) assert self.name() == term_name assert args is None or len(args) == n_args def name(self): return fname def signature(self): return signature def _make_new(self, name, signature): cls = specific_class return cls(name, None, signature) if immutable: def _make_new_mutable(self, name, signature): cls = mutable_version return cls(name, None, signature) else: _make_new_mutable = _make_new if immutable: mutable_version = specific_class.mutable_version = generate_class( cname, fname, n_args, False) specific_class.__name__ = cname + "Mutable" * (not immutable) return specific_class
def test_numeral(): from prolog.interpreter.term import Callable, Atom, BindingVar from prolog.interpreter.continuation import Engine t = parse_file(""" numeral(null). % end of line comment numeral(succ(X)) :- numeral(X). % another one add_numeral(X, null, X). add_numeral(X, succ(Y), Z) :- add_numeral(succ(X), Y, Z). greater_than(succ(null), null). greater_than(succ(X), null) :- greater_than(X, null). greater_than(succ(X), succ(Y)) :- greater_than(X, Y). """) builder = TermBuilder() facts = builder.build(t) e = Engine() m = e.modulewrapper for fact in facts: print fact e.add_rule(fact) assert m.modules["user"].lookup(Signature.getsignature( "add_numeral", 3)).rulechain.head.argument_at(1).name() == "null" four = Callable.build("succ", [ Callable.build("succ", [ Callable.build("succ", [Callable.build("succ", [Callable.build("null")])]) ]) ]) e.run_query_in_current(parse_query_term("numeral(succ(succ(null))).")) term = parse_query_term( """add_numeral(succ(succ(null)), succ(succ(null)), X).""") e.run_query_in_current(term) hp = Heap() var = BindingVar().dereference(hp) # does not raise var.unify(four, hp) term = parse_query_term( """greater_than(succ(succ(succ(null))), succ(succ(null))).""") e.run_query_in_current(term)
def find_next_applicable_rule(self, query, heap=None, similarity=None, simchain=[], module=None, nargs=0): self = self.next if self is None: while (simchain != []): #print("Moving to next rulechain in simchain...") name = simchain[0] simchain = simchain[1:] signature = Signature.getsignature(name, nargs) function = module.lookup(signature) self = function.rulechain if (self is not None): return self.find_applicable_rule(query, heap, similarity, simchain, module, nargs) return None, [] return self.find_applicable_rule(query, heap, similarity, simchain, module, nargs)
""" Helper functions for dealing with prolog terms""" from prolog.interpreter import term from prolog.interpreter import error from prolog.interpreter.signature import Signature from rpython.rlib import jit from prolog.interpreter.stream import PrologOutputStream, PrologInputStream,\ PrologStream conssig = Signature.getsignature(".", 2) nilsig = Signature.getsignature("[]", 0) emptylist = term.Callable.build("[]") def wrap_list(python_list): curr = emptylist for i in range(len(python_list) - 1, -1, -1): curr = term.Callable.build(".", [python_list[i], curr]) return curr @jit.unroll_safe def unwrap_list(prolog_list): # Grrr, stupid JIT result = [None] used = 0 curr = prolog_list while isinstance(curr, term.Callable) and curr.signature().eq(conssig): if used == len(result): nresult = [None] * (used * 2) for i in range(used): nresult[i] = result[i]
def test_exception_knows_builtin_signature(): e = get_engine(""" f(X, Y) :- atom_length(X, Y). """) error = get_uncaught_error("f(1, Y).", e) assert error.sig_context == Signature.getsignature("atom_length", 2)
("mod", 2, "mod"), ("\\", 1, "not"), ("abs", 1, "abs"), ("max", 2, "max"), ("min", 2, "min"), ("round", 1, "round"), ("floor", 1, "floor"), #XXX ("ceiling", 1, "ceiling"), #XXX ("float_fractional_part", 1, "float_fractional_part"), #XXX ("float_integer_part", 1, "float_integer_part") ] for prolog_name, num_args, name in simple_functions: f = wrap_builtin_operation(name, num_args) signature = Signature.getsignature(prolog_name, num_args) signature.set_extra("arithmetic", f) for suffix in ["", "_number", "_bigint", "_float"]: def not_implemented_func(*args): raise NotImplementedError("abstract base class") setattr(term.Numeric, "arith_%s%s" % (name, suffix), not_implemented_func) @jit.elidable_promote('all') def get_arithmetic_function(signature): return signature.get_extra("arithmetic") def make_int(w_value): if isinstance(w_value, term.BigInt): try: num = w_value.value.toint()
from prolog.interpreter import helper, term, error, continuation from prolog.builtin.register import expose_builtin from prolog.interpreter.signature import Signature ifsig = Signature.getsignature("->", 2) cutsig = Signature.getsignature("!", 0) FAILATOM = term.Callable.build("fail") TRUEATOM = term.Callable.build("true") # ___________________________________________________________________ # control predicates @expose_builtin("fail", unwrap_spec=[]) def impl_fail(engine, heap): raise error.UnificationFailed() @expose_builtin("true", unwrap_spec=[]) def impl_true(engine, heap): return @expose_builtin("repeat", unwrap_spec=[], handles_continuation=True) def impl_repeat(engine, heap, scont, fcont): return scont, RepeatContinuation(engine, scont, fcont, heap), heap.branch() class RepeatContinuation(continuation.FailureContinuation): def fail(self, heap): heap = heap.revert_upto(self.undoheap) return self.nextcont, self, heap @expose_builtin("!", unwrap_spec=[], handles_continuation=True) def impl_cut(engine, heap, scont, fcont):
def get_printable_location(rule, sconttype): if rule: s = rule.signature.string() else: s = "No rule" return "%s %s" % (s, sconttype) def get_jitcell_at(where, rule): # XXX can be vastly simplified return rule.jit_cells.get(where, None) def set_jitcell_at(newcell, where, rule): # XXX can be vastly simplified rule.jit_cells[where] = newcell predsig = Signature.getsignature(":-", 2) callsig = Signature.getsignature(":-", 1) jitdriver = jit.JitDriver( greens=["rule", "sconttype"], reds=["scont", "fcont", "heap"], get_printable_location=get_printable_location, #get_jitcell_at=get_jitcell_at, #set_jitcell_at=set_jitcell_at, ) # ___________________________________________________________________ # end JIT stuff def driver(scont, fcont, heap):
""" Helper functions for dealing with prolog terms""" from prolog.interpreter import term from prolog.interpreter import error from prolog.interpreter.signature import Signature from rpython.rlib import jit from prolog.interpreter.stream import PrologOutputStream, PrologInputStream,\ PrologStream conssig = Signature.getsignature(".", 2) nilsig = Signature.getsignature("[]", 0) emptylist = term.Callable.build("[]") def wrap_list(python_list): curr = emptylist for i in range(len(python_list) - 1, -1, -1): curr = term.Callable.build(".", [python_list[i], curr]) return curr @jit.unroll_safe def unwrap_list(prolog_list): # Grrr, stupid JIT result = [None] used = 0 curr = prolog_list while isinstance(curr, term.Callable) and curr.signature().eq(conssig): if used == len(result): nresult = [None] * (used * 2)
else: s = "No rule" return "%s %s" % (s, sconttype) def get_jitcell_at(where, rule): # XXX can be vastly simplified return rule.jit_cells.get(where, None) def set_jitcell_at(newcell, where, rule): # XXX can be vastly simplified rule.jit_cells[where] = newcell predsig = Signature.getsignature(":-", 2) callsig = Signature.getsignature(":-", 1) jitdriver = jit.JitDriver( greens=["rule", "sconttype"], reds=["scont", "fcont", "heap"], get_printable_location=get_printable_location, #get_jitcell_at=get_jitcell_at, #set_jitcell_at=set_jitcell_at, ) # ___________________________________________________________________ # end JIT stuff def driver(scont, fcont, heap, engine):
import os import string from prolog.interpreter.term import Float, Number, Var, Atom, Callable, AttVar from prolog.interpreter import error, helper, parsing from prolog.builtin.register import expose_builtin from prolog.interpreter.signature import Signature from prolog.interpreter.stream import PrologStream conssig = Signature.getsignature(".", 2) nilsig = Signature.getsignature("[]", 0) tuplesig = Signature.getsignature(",", 2) class TermFormatter(object): def __init__(self, engine, quoted=False, max_depth=0, ignore_ops=False): self.engine = engine self.quoted = quoted self.max_depth = max_depth self.ignore_ops = ignore_ops self.curr_depth = 0 self._make_reverse_op_mapping() self.var_to_number = {} def from_option_list(engine, options): # XXX add numbervars support quoted = False max_depth = 0 ignore_ops = False number_vars = False
def make_wrapper(func, name, unwrap_spec=[], handles_continuation=False, translatable=True, needs_module=False, needs_rule=False): numargs = len(unwrap_spec) if isinstance(name, list): expose_as = name name = name[0] else: expose_as = [name] if not name.isalnum(): name = func.func_name orig_funcargs = inspect.getargs(func.func_code)[0] funcname = "wrap_%s_%s" % (name, numargs) code = ["def %s(engine, query, rule, scont, fcont, heap):" % (funcname, )] code.append(" module = rule.module") if not translatable: code.append(" if we_are_translated():") code.append( " raise error.UncatchableError('%s does not work in translated version')" % (name, )) subargs = ["engine", "heap"] assert orig_funcargs[0] == "engine" assert orig_funcargs[1] == "heap" code.append(" assert isinstance(query, term.Callable)") for i, spec in enumerate(unwrap_spec): varname = "var%s" % (i, ) subargs.append(varname) if spec in ("obj", "callable", "int", "atom", "arithmetic", "instream", "outstream", "stream", "list"): code.append(" %s = query.argument_at(%s).dereference(heap)" % (varname, i)) if spec in ("int", "atom", "arithmetic", "list", "instream", "outstream", "stream"): code.append(" if isinstance(%s, term.Var):" % (varname, )) code.append(" error.throw_instantiation_error()") if spec == "obj": pass elif spec == "callable": code.append(" if not isinstance(%s, term.Callable):" % (varname, )) code.append(" if isinstance(%s, term.Var):" % (varname, )) code.append(" error.throw_instantiation_error()") code.append(" error.throw_type_error('callable', %s)" % (varname, )) elif spec == "raw": code.append(" %s = query.argument_at(%s)" % (varname, i)) elif spec == "int": code.append(" %s = helper.unwrap_int(%s)" % (varname, varname)) elif spec == "atom": code.append(" %s = helper.unwrap_atom(%s)" % (varname, varname)) elif spec == "arithmetic": code.append(" %s = eval_arithmetic(engine, %s)" % (varname, varname)) elif spec == "list": code.append(" %s = helper.unwrap_list(%s)" % (varname, varname)) elif spec == "stream": code.append(" %s = helper.unwrap_stream(engine, %s)" % (varname, varname)) elif spec == "instream": code.append(" %s = helper.unwrap_instream(engine, %s)" % (varname, varname)) elif spec == "outstream": code.append(" %s = helper.unwrap_outstream(engine, %s)" % (varname, varname)) else: assert 0, "not implemented " + spec if needs_module: subargs.insert(2, "module") assert orig_funcargs[2] == "module" if needs_rule: subargs.insert(2, "rule") assert orig_funcargs[2] == "rule" if handles_continuation: subargs.append("scont") subargs.append("fcont") assert orig_funcargs[subargs.index("scont")] == "scont" assert orig_funcargs[subargs.index("fcont")] == "fcont" call = " result = %s(%s)" % (func.func_name, ", ".join(subargs)) code.append(call) if not handles_continuation: code.append(" return scont, fcont, heap") else: code.append(" return result") used_globals = ["helper", "error", "term", "eval_arithmetic"] miniglobals = {key: globals()[key] for key in used_globals} miniglobals[func.func_name] = func exec py.code.Source("\n".join(code)).compile() in miniglobals for name in expose_as: signature = Signature.getsignature(name, numargs) b = Builtin(miniglobals[funcname], funcname, numargs, signature) signature.set_extra("builtin", b) return func
import py from prolog.builtin.register import expose_builtin from prolog.interpreter.term import Atom, Callable, Var, Term, Number from prolog.interpreter import error from prolog.builtin.sourcehelper import get_source from prolog.interpreter import continuation from prolog.interpreter.helper import is_term, unwrap_predicate_indicator from prolog.interpreter.signature import Signature meta_args = list("0123456789:?+-") libsig = Signature.getsignature("library", 1) andsig = Signature.getsignature(",", 2) @expose_builtin("module", unwrap_spec=["atom", "list"]) def impl_module(engine, heap, name, exports): engine.modulewrapper.add_module(name, exports) def handle_use_module_with_library(engine, heap, module, path, imports=None): import os import os.path from prolog.builtin.sourcehelper import get_filehandle newpath = None if path.signature().eq(libsig): arg = path.argument_at(0) if isinstance(arg, Var) or not isinstance( arg, Atom): # XXX throw different errors error.throw_instantiation_error() modulename = arg.name()
from prolog.interpreter.term import Callable, Atom, Var from prolog.interpreter.memo import EnumerationMemo from prolog.interpreter.signature import Signature from rpython.rlib import jit, objectmodel, unroll from prolog.interpreter.helper import is_callable # XXX needs tests cutsig = Signature.getsignature("!", 0) prefixsig = Signature.getsignature(":", 2) class Rule(object): _immutable_ = True _immutable_fields_ = ["headargs[*]", "groundargs[*]"] _attrs_ = [ 'next', 'head', 'headargs', 'groundargs', 'contains_cut', 'body', 'env_size_shared', 'env_size_body', 'env_size_head', 'signature', 'module', 'file_name', 'line_range', 'source' ] unrolling_attrs = unroll.unrolling_iterable(_attrs_) def __init__(self, head, body, module, next=None): from prolog.interpreter import helper head = head.dereference(None) assert isinstance(head, Callable) memo = EnumerationMemo() self.head = h = head.enumerate_vars(memo) memo.in_head = False if h.argument_count() > 0: self.headargs = h.arguments() # an argument is ground if enumeration left it unchanged, because
def getDependencyTupleTraverse(analyzedStatement, namedEntities, prolog): def removeRepeats(lst): seen = set() seen_add = seen.add noRepeats = [x for x in lst if not (x in seen or seen_add(x))] return noRepeats predicate = '' arguments = [] statementObj = list(analyzedStatement.sents)[0] rootToken = statementObj.root if rootToken.pos_ == 'VERB': predicate = rootToken.lemma_.lower() hasVerb = 0 iterateArgs = ['', '', '', '', '', ''] for token in analyzedStatement: if token.pos_ == 'VERB': hasVerb = 1 if predicate == '': if token.pos_ == 'VERB' and token.dep_ != 'aux': predicate = token.lemma_.lower() if 'obj' in token.dep_: if iterateArgs[1] == '': iterateArgs[1] = token.text.lower() else: if token.dep_ == 'dobj': iterateArgs[1] = token.text.lower() elif 'subj' in token.dep_: iterateArgs[0] = token.text.lower() elif 'comp' in token.dep_: iterateArgs[2] = token.text.lower() elif 'mod' in token.dep_: iterateArgs[3] = token.text.lower() elif 'conj' in token.dep_: iterateArgs[4] = token.text.lower() elif 'oprd' in token.dep_: iterateArgs[5] = token.text.lower() if predicate == '': for token in analyzedStatement: if hasVerb and token.pos_ == 'VERB': predicate = token.lemma_.lower() break elif (not hasVerb) and token.dep_ == 'ROOT': predicate = token.text.lower() break for child in rootToken.children: if child.pos_ != 'PART' and child.pos_ not in ['PUNC', 'SPACE']: ctext = child.text.lower() arguments.append(ctext) else: pass spacyArguments = [] for chunk in analyzedStatement.noun_chunks: np = chunk.text.lower().replace(' ', '_') if chunk.root.head.text.lower() != predicate and \ chunk.root.head.pos_ != 'VERB' and \ chunk.root.head.text.lower() not in np: np = chunk.root.head.text.lower().replace(' ', '_') + '_' + np spacyArguments.append(np) for arg in iterateArgs: if arg != predicate and not any( [arg in sargs for sargs in spacyArguments]): spacyArguments.append(arg) spacyArguments = removeRepeats(spacyArguments) for ne in namedEntities: used = 0 for ind, arg in enumerate(spacyArguments): if arg in ne[0] or ne[0] in arg: used = 1 break if used == 0 and ne[0] not in spacyArguments: spacyArguments.append(ne[0].replace(' ', '_')) spacyArguments = removeRepeats(spacyArguments) if VERBOSE: print('spacyArguments: {0}'.format(spacyArguments)) logging.debug('spacyArguments: {0}'.format(spacyArguments)) sig = Signature.getsignature(str(predicate), len(spacyArguments)) isBuiltin = prolog.get_builtin(sig) if isBuiltin or str(predicate) == 'close' or str(predicate) == 'open': predicate = predicate + '_new' statementTupleSpacy = '{0}({1})'.format(predicate, ','.join(spacyArguments)) if VERBOSE: print 'statementTupleSpacy:', statementTupleSpacy statementTuple = '{0}({1})'.format(predicate, ','.join(arguments)) if predicate == '': logging.error('predicate name cannot be empty, debugging needed') assert predicate, 'predicate name cannot be empty, debugging needed' return [statementTupleSpacy, predicate, spacyArguments]
import py from prolog.interpreter import helper, term, error from prolog.interpreter.signature import Signature from prolog.builtin.register import expose_builtin # ___________________________________________________________________ # database prefixsig = Signature.getsignature(":", 2) implsig = Signature.getsignature(":-", 2) def unpack_modname_and_predicate(rule): if helper.is_numeric(rule.argument_at(0)): error.throw_domain_error("atom", rule.argument_at(0)) assert 0, "unreachable" mod = rule.argument_at(0) indicator = rule.argument_at(1) if not isinstance(mod, term.Atom): raise error.UnificationFailed() assert 0, "unreachable" return mod.name(), indicator @expose_builtin("abolish", unwrap_spec=["callable"], needs_module=True) def impl_abolish(engine, heap, module, predicate): modname = None if predicate.signature().eq(prefixsig): modname, predicate = unpack_modname_and_predicate(predicate) name, arity = helper.unwrap_predicate_indicator(predicate) if arity < 0:
import py from prolog.interpreter import helper, term, error from prolog.interpreter.signature import Signature from prolog.builtin.register import expose_builtin # ___________________________________________________________________ # database prefixsig = Signature.getsignature(":", 2) implsig = Signature.getsignature(":-", 2) def unpack_modname_and_predicate(rule): if helper.is_numeric(rule.argument_at(0)): error.throw_domain_error("atom", rule.argument_at(0)) assert 0, "unreachable" mod = rule.argument_at(0) indicator = rule.argument_at(1) if not isinstance(mod, term.Atom): raise error.UnificationFailed() assert 0, "unreachable" return mod.name(), indicator @expose_builtin("abolish", unwrap_spec=["callable"], needs_module=True) def impl_abolish(engine, heap, module, predicate): modname = None if predicate.signature().eq(prefixsig): modname, predicate = unpack_modname_and_predicate(predicate) name, arity = helper.unwrap_predicate_indicator(predicate) if arity < 0: error.throw_domain_error("not_less_than_zero", term.Number(arity)) signature = Signature.getsignature(name, arity)
import py from prolog.builtin.register import expose_builtin from prolog.interpreter.term import Atom, Callable, Var, Term, Number from prolog.interpreter import error from prolog.builtin.sourcehelper import get_source from prolog.interpreter import continuation from prolog.interpreter.helper import is_term, unwrap_predicate_indicator from prolog.interpreter.signature import Signature meta_args = list("0123456789:?+-") libsig = Signature.getsignature("library", 1) andsig = Signature.getsignature(",", 2) @expose_builtin("module", unwrap_spec=["atom", "list"]) def impl_module(engine, heap, name, exports): engine.modulewrapper.add_module(name, exports) def handle_use_module_with_library(engine, heap, module, path, imports=None): import os import os.path from prolog.builtin.sourcehelper import get_filehandle newpath = None if path.signature().eq(libsig): arg = path.argument_at(0) if isinstance(arg, Var) or not isinstance(arg, Atom): # XXX throw different errors error.throw_instantiation_error() modulename = arg.name() assert modulename is not None for libpath in engine.modulewrapper.libs: temppath = os.path.join(libpath, modulename) try:
def make_wrapper(func, name, unwrap_spec=[], handles_continuation=False, translatable=True, needs_module=False, needs_rule=False): numargs = len(unwrap_spec) if isinstance(name, list): expose_as = name name = name[0] else: expose_as = [name] if not name.isalnum(): name = func.func_name orig_funcargs = inspect.getargs(func.func_code)[0] funcname = "wrap_%s_%s" % (name, numargs) code = ["def %s(engine, query, rule, scont, fcont, heap):" % (funcname, )] code.append(" module = rule.module") if not translatable: code.append(" if we_are_translated():") code.append(" raise error.UncatchableError('%s does not work in translated version')" % (name, )) subargs = ["engine", "heap"] assert orig_funcargs[0] == "engine" assert orig_funcargs[1] == "heap" code.append(" assert isinstance(query, term.Callable)") for i, spec in enumerate(unwrap_spec): varname = "var%s" % (i, ) subargs.append(varname) if spec in ("obj", "callable", "int", "atom", "arithmetic", "instream", "outstream", "stream", "list"): code.append(" %s = query.argument_at(%s).dereference(heap)" % (varname, i)) if spec in ("int", "atom", "arithmetic", "list", "instream", "outstream", "stream"): code.append( " if isinstance(%s, term.Var):" % (varname,)) code.append( " error.throw_instantiation_error()") if spec == "obj": pass elif spec == "callable": code.append( " if not isinstance(%s, term.Callable):" % (varname,)) code.append( " if isinstance(%s, term.Var):" % (varname,)) code.append( " error.throw_instantiation_error()") code.append( " error.throw_type_error('callable', %s)" % (varname,)) elif spec == "raw": code.append(" %s = query.argument_at(%s)" % (varname, i)) elif spec == "int": code.append(" %s = helper.unwrap_int(%s)" % (varname, varname)) elif spec == "atom": code.append(" %s = helper.unwrap_atom(%s)" % (varname, varname)) elif spec == "arithmetic": code.append(" %s = eval_arithmetic(engine, %s)" % (varname, varname)) elif spec == "list": code.append(" %s = helper.unwrap_list(%s)" % (varname, varname)) elif spec == "stream": code.append(" %s = helper.unwrap_stream(engine, %s)" % (varname, varname)) elif spec == "instream": code.append(" %s = helper.unwrap_instream(engine, %s)" % (varname, varname)) elif spec == "outstream": code.append(" %s = helper.unwrap_outstream(engine, %s)" % (varname, varname)) else: assert 0, "not implemented " + spec if needs_module: subargs.insert(2, "module") assert orig_funcargs[2] == "module" if needs_rule: subargs.insert(2, "rule") assert orig_funcargs[2] == "rule" if handles_continuation: subargs.append("scont") subargs.append("fcont") assert orig_funcargs[subargs.index("scont")] == "scont" assert orig_funcargs[subargs.index("fcont")] == "fcont" call = " result = %s(%s)" % (func.func_name, ", ".join(subargs)) code.append(call) if not handles_continuation: code.append(" return scont, fcont, heap") else: code.append(" return result") used_globals = ["helper", "error", "term", "eval_arithmetic"] miniglobals = {key: globals()[key] for key in used_globals} miniglobals[func.func_name] = func exec py.code.Source("\n".join(code)).compile() in miniglobals for name in expose_as: signature = Signature.getsignature(name, numargs) b = Builtin(miniglobals[funcname], funcname, numargs, signature) signature.set_extra("builtin", b) return func
from prolog.builtin.register import expose_builtin from prolog.interpreter import continuation from prolog.interpreter.term import AttVar, Var, Callable, Atom from prolog.interpreter.error import UnificationFailed,\ throw_representation_error, throw_instantiation_error from prolog.interpreter.helper import wrap_list, is_term, unwrap_list from prolog.interpreter.signature import Signature from prolog.builtin.term_variables import term_variables conssig = Signature.getsignature(".", 2) @expose_builtin("attvar", unwrap_spec=["obj"]) def impl_attvar(engine, heap, obj): if not isinstance(obj, AttVar): raise UnificationFailed() if obj.is_empty(): raise UnificationFailed() @expose_builtin("put_attr", unwrap_spec=["obj", "atom", "obj"]) def impl_put_attr(engine, heap, var, attr, value): if isinstance(var, AttVar): old_value, _ = var.get_attribute(attr) var.add_attribute(attr, value) _, index = var.get_attribute(attr) heap.trail_new_attr(var, index, old_value) elif isinstance(var, Var): attvar = heap.new_attvar() attvar.add_attribute(attr, value) var.unify(attvar, heap) else: throw_representation_error("put_attr/3",