def activate(self, fcont, heap): if self.b < self.stopbefore: if self.l < self.stoplength: if self.l + self.b > len(self.atom): self.b += 1 self.l = self.startlength return self.activate(fcont, heap) fcont, heap = self.prepare_more_solutions(fcont, heap) self.before.unify(term.Number(self.b), heap) self.after.unify(term.Number(len(self.atom) - self.l - self.b), heap) self.length.unify(term.Number(self.l), heap) b = self.b l = self.l assert b >= 0 assert l >= 0 self.sub.unify( term.Callable.build(self.atom[b:b + l], cache=False), heap) self.l += 1 return self.nextcont, fcont, heap else: self.b += 1 self.l = self.startlength return self.activate(fcont, heap) raise error.UnificationFailed()
def impl_functor(engine, heap, t, functor, arity): if helper.is_atomic(t): functor.unify(t, heap) arity.unify(term.Number(0), heap) elif helper.is_term(t): assert isinstance(t, term.Callable) sig = t.signature() atom = term.Callable.build(t.name(), signature=sig.atom_signature) functor.unify(atom, heap) arity.unify(term.Number(t.argument_count()), heap) elif isinstance(t, term.Var): if isinstance(functor, term.Var): error.throw_instantiation_error() a = helper.unwrap_int(arity) jit.promote(a) if a < 0: error.throw_domain_error("not_less_than_zero", arity) else: functor = helper.ensure_atomic(functor) if a == 0: t.unify(functor, heap) else: jit.promote(functor) name = helper.unwrap_atom(functor) t.unify( term.Callable.build(name, [heap.newvar() for i in range(a)]), heap)
def impl_seek(engine, heap, stream, offset, mode, obj): try: mode = seek_mode[mode] except KeyError: error.throw_domain_error("seek_method", term.Callable.build(mode)) try: stream.seek(offset, mode) except OSError: error.throw_domain_error("position", term.Number(offset)) pos = int(stream.tell()) obj.unify(term.Number(pos), heap)
def arith_shr_number(self, other_num): try: num = self.value.toint() except OverflowError: # XXX raise a Prolog-level error! raise ValueError('Right operand too big') return term.Number(other_num >> num)
def arith_floordiv_number(self, other_num): if self.num == 0: error.throw_evaluation_error("zero_divisor") try: res = rarithmetic.ovfcheck(other_num // self.num) except OverflowError: return self.arith_floordiv_bigint(rbigint.fromint(other_num)) return term.Number(res)
def continue_arg(Choice, engine, scont, fcont, heap, varnum, num, temarg, vararg, rule): if num < temarg.argument_count() - 1: fcont = Choice(engine, scont, fcont, heap, varnum, num + 1, temarg, vararg, rule) heap = heap.branch() scont = continuation.BodyContinuation( engine, rule, scont, term.Callable.build("=", [vararg, temarg.argument_at(num)])) varnum.unify(term.Number(num + 1), heap) return scont, fcont, heap
def impl_get_byte(engine, heap, stream, obj): assert isinstance(stream, PrologInputStream) byte = stream.read(1) if byte != '': code = ord(byte[0]) else: code = -1 obj.unify(term.Number(code), heap)
def impl_statistics(engine, heap, stat_name, value): t = [] if stat_name == 'runtime': t = engine.clocks.get_cputime() if stat_name == 'walltime': t = engine.clocks.get_walltime() l = [term.Number(x) for x in t] helper.wrap_list(l).unify(value, heap)
def make_int(w_value): if isinstance(w_value, term.BigInt): try: num = w_value.value.toint() except OverflowError: pass else: return term.Number(num) return w_value
def activate(self, fcont, heap): start = self.start assert start >= 0 end = self.stopbefore + len(self.s1) assert end >= 0 b = self.atom.find(self.s1, start, end) # XXX -1? if b < 0: raise error.UnificationFailed() fcont, heap = self.prepare_more_solutions(fcont, heap) self.start = b + 1 try: self.before.unify(term.Number(b), heap) self.after.unify(term.Number(len(self.atom) - len(self.s1) - b), heap) self.length.unify(term.Number(len(self.s1)), heap) except error.UnificationFailed: pass return self.nextcont, fcont, heap
def arith_round(self): fval = self.floatval if fval >= 0: factor = 1 else: factor = -1 fval = fval * factor try: val = ovfcheck_float_to_int(math.floor(fval + 0.5) * factor) except OverflowError: return term.BigInt(rbigint.fromfloat(math.floor(self.floatval + 0.5) * factor)) return term.Number(val)
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 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 arith_mul_number(self, other_num): try: res = rarithmetic.ovfcheck(other_num * self.num) except OverflowError: return self.arith_mul_bigint(rbigint.fromint(other_num)) return term.Number(res)
def arith_unarysub(self): try: res = rarithmetic.ovfcheck(-self.num) except OverflowError: return term.BigInt(rbigint.fromint(self.num).neg()) return term.Number(res)
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 arith_pow_number(self, other_num): try: res = ovfcheck_float_to_int(math.pow(other_num, self.num)) except OverflowError: return self.arith_pow_bigint(rbigint.fromint(other_num)) return term.Number(res)
def arith_shl_number(self, other_num): return term.Number(intmask(other_num << self.num))
def arith_shr_number(self, other_num): return term.Number(other_num >> self.num)
def arith_arith_fractional_part(self): return term.Number(0)
def arith_max_number(self, other_num): return term.Number(max(other_num, self.num))
def arith_float_integer_part(self): try: val = ovfcheck_float_to_int(self.floatval) except OverflowError: return term.BigInt(rbigint.fromfloat(self.floatval)) return term.Number(val)
def arith_xor_number(self, other_num): return term.Number(other_num ^ self.num)
def arith_ceiling(self): try: val = ovfcheck_float_to_int(math.ceil(self.floatval)) except OverflowError: return term.BigInt(rbigint.fromfloat(math.ceil(self.floatval))) return term.Number(val)
def arith_mod_number(self, other_num): if self.num == 0: error.throw_evaluation_error("zero_divisor") return term.Number(other_num % self.num)
def arith_not(self): return term.Number(~self.num)
def continue_between(Choice, engine, scont, fcont, heap, lower, upper, var): if lower < upper: fcont = Choice(engine, scont, fcont, heap, lower + 1, upper, var) heap = heap.branch() var.unify(term.Number(lower), heap) return scont, fcont, heap
def arith_and_number(self, other_num): return term.Number(other_num & self.num)
def arith_min_number(self, other_num): return term.Number(min(other_num, self.num))
def arith_abs(self): if self.num >= 0: return self return term.Number(0).arith_sub(self)