def impl_arg(engine, first, second, third, continuation): if isinstance(second, term.Var): error.throw_instantiation_error() if isinstance(second, term.Atom): raise error.UnificationFailed() if not isinstance(second, term.Term): error.throw_type_error("compound", second) if isinstance(first, term.Var): for i in range(len(second.args)): arg = second.args[i] oldstate = engine.heap.branch() try: third.unify(arg, engine.heap) first.unify(term.Number(i + 1), engine.heap) return continuation.call(engine, choice_point=True) except error.UnificationFailed: engine.heap.revert(oldstate) raise error.UnificationFailed() 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 > len(second.args): raise error.UnificationFailed() arg = second.args[num - 1] third.unify(arg, engine.heap) else: error.throw_type_error("integer", first) return continuation.call(engine, choice_point=False)
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 run(self, query, continuation=DONOTHING): if not isinstance(query, Callable): error.throw_type_error("callable", query) try: return self.call(query, continuation, choice_point=True) except CutException, e: return self.continue_after_cut(e.continuation)
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 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 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 error.throw_type_error('integer', obj)
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 error.throw_type_error('integer', obj)
def unwrap_predicate_indicator(predicate): if not isinstance(predicate, term.Term): error.throw_type_error("predicate_indicator", predicate) assert 0, "unreachable" if not predicate.name == "/" or len(predicate.args) != 2: error.throw_type_error("predicate_indicator", predicate) name = unwrap_atom(predicate.args[0]) arity = unwrap_int(predicate.args[1]) return name, arity
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) error.throw_type_error("atomic", obj)
def unwrap_list(prolog_list): result = [] curr = prolog_list while isinstance(curr, term.Term): if not curr.name == ".": error.throw_type_error("list", prolog_list) result.append(curr.args[0]) curr = curr.args[1] if isinstance(curr, term.Atom) and curr.name == "[]": return result error.throw_type_error("list", prolog_list)
def eval_arithmetic(self, engine): from pypy.lang.prolog.interpreter.arithmetic import arithmetic_functions from pypy.lang.prolog.interpreter.arithmetic import arithmetic_functions_list if we_are_jitted(): signature = hint(self.signature, promote=True) func = None for sig, func in arithmetic_functions_list: if sig == signature: break else: func = arithmetic_functions.get(self.signature, None) if func is None: error.throw_type_error("evaluable", self.get_prolog_signature()) return func(engine, self)
def impl_univ(engine, first, second): if not isinstance(first, term.Var): if isinstance(first, term.Term): l = [term.Atom(first.name)] + first.args else: l = [first] u1 = helper.wrap_list(l) if not isinstance(second, term.Var): u1.unify(second, engine.heap) else: u1.unify(second, engine.heap) else: if isinstance(second, term.Var): error.throw_instantiation_error() else: l = helper.unwrap_list(second) head = l[0] if not isinstance(head, term.Atom): error.throw_type_error("atom", head) term.Term(head.name, l[1:]).unify(first, engine.heap)
def add_rule(self, rule, end=True): from pypy.lang.prolog import builtin if DEBUG: debug_print("add_rule", rule) if isinstance(rule, Term): if rule.name == ":-": rule = Rule(rule.args[0], rule.args[1]) else: rule = Rule(rule, None) signature = rule.signature elif isinstance(rule, Atom): rule = Rule(rule, None) signature = rule.signature else: error.throw_type_error("callable", rule) assert 0, "unreachable" # make annotator happy if signature in builtin.builtins: error.throw_permission_error( "modify", "static_procedure", rule.head.get_prolog_signature()) function = self._lookup(signature) function.add_rule(rule, end)
def add_rule(self, rule, end=True): from pypy.lang.prolog import builtin if DEBUG: debug_print("add_rule", rule) if isinstance(rule, Term): if rule.name == ":-": rule = Rule(rule.args[0], rule.args[1]) else: rule = Rule(rule, None) signature = rule.signature elif isinstance(rule, Atom): rule = Rule(rule, None) signature = rule.signature else: error.throw_type_error("callable", rule) assert 0, "unreachable" # make annotator happy if signature in builtin.builtins: error.throw_permission_error("modify", "static_procedure", rule.head.get_prolog_signature()) function = self.signature2function.get(signature, None) if function is not None: self.signature2function[signature].add_rule(rule, end) else: self.signature2function[signature] = Function(rule)
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 impl_and(engine, call1, call2, continuation): if not isinstance(call2, term.Var) and not isinstance(call2, term.Callable): error.throw_type_error('callable', call2) and_continuation = AndContinuation(call2, continuation) return engine.call(call1, and_continuation, choice_point=False)
def eval_arithmetic(self, engine): error.throw_type_error("evaluable", self)
def impl_and(engine, call1, call2, continuation): if not isinstance(call2, term.Var) and not isinstance( call2, term.Callable): error.throw_type_error('callable', call2) and_continuation = AndContinuation(call2, continuation) return engine.call(call1, and_continuation, choice_point=False)
def impl_atom_length(engine, 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, engine.heap)