def eval_arithmetic(self, engine): from prolog.interpreter.arithmetic import get_arithmetic_function func = get_arithmetic_function(self.signature()) jit.promote(func) if func is None: error.throw_type_error("evaluable", self.get_prolog_signature()) return func(engine, self)
def eval_arithmetic(self, engine): #XXX beautify that if self.name() == "pi": return Float.pi if self.name() == "e": return Float.e error.throw_type_error("evaluable", self.get_prolog_signature())
def ensure_callable(var): if isinstance(var, term.Var): error.throw_instantiation_error() elif isinstance(var, term.Callable): return var else: error.throw_type_error("callable", var)
def impl_univ(engine, heap, first, second): if not isinstance(first, term.Var): if helper.is_term(first): assert isinstance(first, term.Callable) sig = first.signature().atom_signature l = [term.Callable.build(first.name(), signature=sig)] + first.arguments() else: l = [first] u1 = helper.wrap_list(l) if not isinstance(second, term.Var): u1.unify(second, heap) else: u1.unify(second, heap) else: if isinstance(second, term.Var): error.throw_instantiation_error() else: l = helper.unwrap_list(second) head = l[0].dereference(heap) if not isinstance(head, term.Atom): error.throw_type_error("atom", head) l2 = [None] * (len(l) - 1) for i in range(len(l2)): l2[i] = l[i + 1] name = jit.hint(head.signature(), promote=True).name term.Callable.build(name, l2).unify(first, heap)
def unwrap_predicate_indicator(predicate): if not isinstance(predicate, term.Callable): error.throw_type_error("predicate_indicator", predicate) assert 0, "unreachable" if not predicate.name()== "/" or predicate.argument_count() != 2: error.throw_type_error("predicate_indicator", predicate) name = unwrap_atom(predicate.argument_at(0)) arity = unwrap_int(predicate.argument_at(1)) return name, arity
def unwrap_predicate_indicator(predicate): if not isinstance(predicate, term.Callable): error.throw_type_error("predicate_indicator", predicate) assert 0, "unreachable" if not predicate.name() == "/" or predicate.argument_count() != 2: error.throw_type_error("predicate_indicator", predicate) name = unwrap_atom(predicate.argument_at(0)) arity = unwrap_int(predicate.argument_at(1)) return name, arity
def impl_put_char(engine, heap, stream, atom): length = len(atom) if length == 1: stream.write(atom) return elif length == 2: if ord(atom[0]) > 127: # not ASCII stream.write(atom) return error.throw_type_error("character", term.Callable.build(atom))
def unwrap_int(obj): if isinstance(obj, term.Number): return obj.num elif isinstance(obj, term.Float): f = obj.floatval; i = int(f) if f == i: return i elif isinstance(obj, term.Var): error.throw_instantiation_error() error.throw_type_error('integer', obj)
def make_rule(self, ruleterm, module): if helper.is_term(ruleterm): assert isinstance(ruleterm, Callable) if ruleterm.signature().eq(predsig): return Rule(ruleterm.argument_at(0), ruleterm.argument_at(1), module) else: return Rule(ruleterm, None, module) elif isinstance(ruleterm, Atom): return Rule(ruleterm, None, module) else: error.throw_type_error("callable", ruleterm)
def cons_to_atom(cons): atomlist = helper.unwrap_list(cons) result = [] for atom in atomlist: if not isinstance(atom, term.Atom): error.throw_type_error("text", atom) name = atom.name() if not len(name) == 1: error.throw_type_error("text", atom) result.append(atom.name()) return Callable.build("".join(result))
def unwrap_int(obj): if isinstance(obj, term.Number): return obj.num elif isinstance(obj, term.Float): f = obj.floatval i = int(f) if f == i: return i elif isinstance(obj, term.Var): error.throw_instantiation_error() error.throw_type_error('integer', obj)
def num_to_list(num): from prolog.interpreter.helper import wrap_list s = "" if isinstance(num, term.Number): s = str(num.num) elif isinstance(num, term.Float): s = str(num.floatval) elif isinstance(num, term.BigInt): s = num.value.str() else: error.throw_type_error("number", num) return wrap_list([Callable.build(c) for c in s])
def convert_to_str(obj): if isinstance(obj, term.Var): error.throw_instantiation_error() if isinstance(obj, term.Atom): return obj.name() elif isinstance(obj, term.Number): return str(obj.num) elif isinstance(obj, term.Float): return str(obj.floatval) elif isinstance(obj, term.BigInt): return obj.value.str() error.throw_type_error("atom", obj)
def impl_atom_chars(engine, heap, atom, charlist): if not isinstance(charlist, term.Var): if isinstance(atom, term.Atom): atom_to_cons(atom).unify(charlist, heap) else: cons_to_atom(charlist).unify(atom, heap) else: if isinstance(atom, term.Var): error.throw_instantiation_error() elif not isinstance(atom, term.Atom): error.throw_type_error("atom", atom) else: atom_to_cons(atom).unify(charlist, heap)
def impl_and(engine, heap, rule, call1, call2, scont, fcont, sister_rule = None): if not isinstance(call2, term.Var) and not isinstance(call2, term.Callable): return error.throw_type_error('callable', call2) scont = continuation.BodyContinuation(engine, rule, scont, call2) scont.parent_rule = rule scont.from_and = True return engine.call(call1, rule, scont, fcont, heap, 0, rule, sister_rule)
def call(self, query, rule, scont, fcont, heap): if isinstance(query, Var): query = query.dereference(heap) if not isinstance(query, Callable): if isinstance(query, Var): raise error.throw_instantiation_error() raise error.throw_type_error('callable', query) signature = query.signature() builtin = self.get_builtin(signature) if builtin is not None: return BuiltinContinuation(self, rule, scont, builtin, query), fcont, heap # do a real call module = rule.module function = self._get_function(signature, module, query) query = function.add_meta_prefixes(query, module.nameatom) startrulechain = jit.hint(function.rulechain, promote=True) rulechain = startrulechain.find_applicable_rule( query, heap, self.similarity) if rulechain is None: raise error.UnificationFailed if heap.depth > self.max_depth: raise error.UnificationFailed scont, fcont, heap = _make_rule_conts(self, scont, fcont, heap, query, rulechain) return scont, fcont, heap
def call(self, query, rule, scont, fcont, heap, k=0): if isinstance(query, Var): query = query.dereference(heap) if not isinstance(query, Callable): if isinstance(query, Var): raise error.throw_instantiation_error() raise error.throw_type_error('callable', query) signature = query.signature() builtin = self.get_builtin(signature) if builtin is not None: return BuiltinContinuation(self, rule, scont, builtin, query), fcont, heap # get embedding of querystring using charRNN query_string = self.get_query_string(query) query_embedding = self.get_query_embedding(querystring) # find kth most similar rule # TODO: figure out how to track k rule_index, rule_score = self.get_similar_rule(query_embedding, k) rule = self.index2rule[rule_index] if (k >= self.maxk): raise error.UnificationFailed else: k = k + 1 if heap.depth > self.max_depth: raise error.UnificationFailed scont, fcont, heap = _make_rule_conts(self, scont, fcont, heap, query, rule, k, rule_score) return scont, fcont, heap
def call(self, query, rule, scont, fcont, heap, k = 0, parent_rule = None, sister_rule = None, first = False): if isinstance(query, Var): query = query.dereference(heap) if not isinstance(query, Callable): if isinstance(query, Var): raise error.throw_instantiation_error() raise error.throw_type_error('callable', query) signature = query.signature() builtin = self.get_builtin(signature) rule1 = None try: rule1 = scont.rule except: pass log_sister = (rule1 == rule) and scont.from_and if builtin is not None: if (signature.name != ','): if (log_sister): scont.sister_rule = sister_rule scont = BuiltinContinuation(self, rule, scont, builtin, query, parent_rule, sister_rule) return scont, fcont, heap if first: return self.regularcall(query, rule, scont, fcont, heap) query_string = self.get_query_string(query) rule = (parent_rule, sister_rule) var_start = query_string.index('(') var_end = query_string.index(')') var = query_string[var_start+1:var_end] var = map(str.strip, var) if (len(var) < 4): var += [None] * (4-len(var)) rule_dist, term_dist = run_model(query_string, rule, var) print('TOP TEN RULES') self.get_top_ten(rule_dist) print('\n') rule, score, rule_dist = self.get_next_rule(rule_dist, heap) if (rule is None): k = self.maxk if (k < self.maxk): k = k+1 if heap.depth > self.max_depth: raise error.UnificationFailed scont, fcont, heap = _make_rule_conts(self, scont, fcont, heap,\ query, rule, k, rule_dist, score, \ parent_rule, sister_rule, log_sister) return scont, fcont, heap
def impl_open_options(engine, heap, srcpath, mode, stream, options): if not isinstance(stream, term.Var): error.throw_type_error("variable", stream) opts = make_option_dict(options) mode = rwa.get(mode, None) if mode is None: error.throw_domain_error("io_mode", term.Callable.build("mode not supported")) else: buffering = opts.get("buffer", "full") if buffering == "full": bufmode = -1 elif buffering == "line": bufmode = 1 elif buffering == "false": bufmode = 0 else: error.throw_domain_error("buffering", term.Callable.build(buffering)) assert 0, "unreachable" try: if mode == "r": prolog_stream = PrologInputStream( open_file_as_stream(srcpath, mode, bufmode)) else: prolog_stream = PrologOutputStream( open_file_as_stream(srcpath, mode, bufmode)) except OSError: error.throw_existence_error("source_sink", term.Callable.build(srcpath)) assert 0, "unreachable" engine.streamwrapper.streams[prolog_stream.fd()] = prolog_stream try: alias = opts["alias"] prolog_stream.alias = alias except KeyError: alias = "$stream_%d" % prolog_stream.fd() engine.streamwrapper.aliases[alias] = prolog_stream stream.unify(term.Callable.build(alias), heap)
def impl_open_options(engine, heap, srcpath, mode, stream, options): if not isinstance(stream, term.Var): error.throw_type_error("variable", stream) opts = make_option_dict(options) mode = rwa.get(mode, None) if mode is None: error.throw_domain_error("io_mode", term.Callable.build( "mode not supported")) else: buffering = opts.get("buffer", "full") if buffering == "full": bufmode = -1 elif buffering == "line": bufmode = 1 elif buffering == "false": bufmode = 0 else: error.throw_domain_error("buffering", term.Callable.build(buffering)) assert 0, "unreachable" try: if mode == "r": prolog_stream = PrologInputStream(open_file_as_stream( srcpath, mode, bufmode)) else: prolog_stream = PrologOutputStream(open_file_as_stream( srcpath, mode, bufmode)) except OSError: error.throw_existence_error("source_sink", term.Callable.build(srcpath)) assert 0, "unreachable" engine.streamwrapper.streams[prolog_stream.fd()] = prolog_stream try: alias = opts["alias"] prolog_stream.alias = alias except KeyError: alias = "$stream_%d" % prolog_stream.fd() engine.streamwrapper.aliases[alias] = prolog_stream stream.unify(term.Callable.build(alias), heap)
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] result = nresult result[used] = curr.argument_at(0) used += 1 curr = curr.argument_at(1) curr = curr.dereference(None) if isinstance(curr, term.Callable) and curr.signature().eq(nilsig): if used != len(result): nresult = [None] * used for i in range(used): nresult[i] = result[i] result = nresult return result error.throw_type_error("list", prolog_list)
def cons_to_num(charlist): from prolog.interpreter.helper import unwrap_list, unwrap_atom unwrapped = unwrap_list(charlist) numlist = [] saw_dot = False first = True i = 0 for elem in unwrapped: if not isinstance(elem, term.Atom): error.throw_type_error("text", charlist) digit = elem.name() if digit not in digits: if digit == ".": if saw_dot or first or (i == 1 and numlist[0] == "-"): error.throw_syntax_error("Illegal number") else: saw_dot = True elif digit == "-": if not first: error.throw_syntax_error("Illegal number") else: error.throw_syntax_error("Illegal number") numlist.append(digit) i += 1 first = False numstr = "".join(numlist) if numstr.find(".") == -1: # no float try: return term.Number(string_to_int(numstr)) except ParseStringOverflowError: return term.BigInt(rbigint.fromdecimalstr(numstr)) try: return term.Float(float(numstr)) except ValueError: error.throw_syntax_error("Illegal number")
def call(self, query, rule, scont, fcont, heap): if isinstance(query, Var): query = query.dereference(heap) if not isinstance(query, Callable): if isinstance(query, Var): raise error.throw_instantiation_error() raise error.throw_type_error('callable', query) signature = query.signature() builtin = self.get_builtin(signature) if builtin is not None: return BuiltinContinuation(self, rule, scont, builtin, query), fcont, heap # do a real call module = rule.module function = self._get_function(signature, module, query) query = function.add_meta_prefixes(query, module.nameatom) startrulechain = jit.hint(function.rulechain, promote=True) rulechain = startrulechain.find_applicable_rule(query) if rulechain is None: raise error.UnificationFailed scont, fcont, heap = _make_rule_conts(self, scont, fcont, heap, query, rulechain) return scont, fcont, heap
def impl_arg(engine, heap, rule, first, second, third, scont, fcont): if isinstance(second, term.Var): error.throw_instantiation_error() if isinstance(second, term.Atom): raise error.UnificationFailed() error.throw_type_error('compound', second) if not helper.is_term(second): error.throw_type_error("compound", second) assert isinstance(second, term.Callable) if isinstance(first, term.Var): return continue_arg(engine, scont, fcont, heap, first, 0, second, third, rule) elif isinstance(first, term.Number): num = first.num if num == 0: raise error.UnificationFailed if num < 0: error.throw_domain_error("not_less_than_zero", first) if num > second.argument_count(): raise error.UnificationFailed() arg = second.argument_at(num - 1) third.unify(arg, heap) else: error.throw_type_error("integer", first) return scont, fcont, heap
def impl_put_byte(engine, heap, stream, byte): if byte < 0: # XXX have to care about bigints error.throw_type_error("byte", term.Number(byte)) stream.write(chr(byte))
def ensure_atomic(obj): if not is_atomic(obj): error.throw_type_error('atomic', obj) return obj
def unwrap_atom(obj): if isinstance(obj, term.Atom): return obj.name() error.throw_type_error('atom', obj)
def eval_arithmetic(self, engine): error.throw_type_error("evaluable", self)
def arith_floordiv_number(self, other_num): error.throw_type_error("integer", self)
def arith_floordiv_bigint(self, other_value): error.throw_type_error("integer", self)
def arith_floordiv_float(self, other_float): error.throw_type_error("integer", other_float)
def impl_and(engine, heap, rule, call1, call2, scont, fcont): if not isinstance(call2, term.Var) and not isinstance(call2, term.Callable): return error.throw_type_error('callable', call2) scont = continuation.BodyContinuation(engine, rule, scont, call2) return engine.call(call1, rule, scont, fcont, heap)
def impl_atom_length(engine, heap, s, length): if not (isinstance(length, term.Var) or isinstance(length, term.Number)): error.throw_type_error("integer", length) term.Number(len(s)).unify(length, heap)
def impl_and(engine, heap, rule, call1, call2, scont, fcont): if not isinstance(call2, term.Var) and not isinstance( call2, term.Callable): return error.throw_type_error('callable', call2) scont = continuation.BodyContinuation(engine, rule, scont, call2) return engine.call(call1, rule, scont, fcont, heap)