def impl_atom_concat(engine, heap, a1, a2, result, scont, fcont): if isinstance(a1, term.Var): r = helper.convert_to_str(result) if isinstance(a2, term.Var): return continue_atom_concat(engine, scont, fcont, heap, a1, a2, r, 0) else: s2 = helper.convert_to_str(a2) if r.endswith(s2): stop = len(r) - len(s2) assert stop > 0 a1.unify(term.Callable.build(r[:stop], cache=False), heap) else: raise error.UnificationFailed() else: s1 = helper.convert_to_str(a1) if isinstance(a2, term.Var): r = helper.convert_to_str(result) if r.startswith(s1): a2.unify(term.Callable.build(r[len(s1):], cache=False), heap) else: raise error.UnificationFailed() else: s2 = helper.convert_to_str(a2) result.unify(term.Callable.build(s1 + s2, cache=False), heap) return scont, fcont, heap
def impl_current_module(engine, heap, module, scont, fcont): if isinstance(module, Atom): try: engine.modulewrapper.modules[module.name()] except KeyError: raise error.UnificationFailed() elif isinstance(module, Var): mods = [val.nameatom for val in engine.modulewrapper.modules.values()] return continue_current_module(engine, scont, fcont, heap, mods, 0, module) else: raise error.UnificationFailed() return scont, fcont, heap
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_ground(engine, heap, var): var = var.dereference(heap) if isinstance(var, term.Var): raise error.UnificationFailed() if isinstance(var, term.Callable): for arg in var.arguments(): impl_ground(engine, heap, arg)
def __init__(self, engine, scont, fcont, heap, atom, before, length, after, sub): SubAtomContinuation.__init__(self, engine, scont, fcont, heap, atom, before, length, after, sub) self.s1 = helper.unwrap_atom(sub) if len(self.s1) >= self.stoplength or len(self.s1) < self.startlength: raise error.UnificationFailed() self.start = self.startbefore
def impl_does_not_unify(engine, heap, obj1, obj2): new_heap = heap.branch() try: obj1.unify(obj2, new_heap) except error.UnificationFailed: new_heap.revert_upto(heap) return new_heap.revert_upto(heap) raise error.UnificationFailed()
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
def impl_library_directory(engine, heap, directory, scont, fcont): if isinstance(directory, Var): if not engine.modulewrapper.libs: raise error.UnificationFailed return continue_librarydir(engine, scont, fcont, heap, directory, 0) elif isinstance(directory, Atom): for lib in engine.modulewrapper.libs: if lib == directory.name(): return scont, fcont, heap raise error.UnificationFailed()
def impl_strictly_identical_or_not_unifiable(engine, heap, obj1, obj2): try: impl_standard_comparison_eq(engine, heap, obj1, obj2) return except error.UnificationFailed: memo = CopyMemo() copy1 = obj1.copy(heap, memo) copy2 = obj2.copy(heap, memo) try: copy1.unify(copy2, heap) except error.UnificationFailed: return raise error.UnificationFailed()
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 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 impl_retract(engine, heap, module, pattern): modname = None if pattern.signature().eq(prefixsig): modname, pattern = unpack_modname_and_predicate(pattern) assert isinstance(pattern, term.Callable) if helper.is_term(pattern) and pattern.signature().eq(implsig): head = helper.ensure_callable(pattern.argument_at(0)) body = helper.ensure_callable(pattern.argument_at(1)) else: head = pattern body = None assert isinstance(head, term.Callable) if head.signature().get_extra("builtin"): error.throw_permission_error("modify", "static_procedure", head.get_prolog_signature()) if modname is None: function = module.lookup(head.signature()) else: function = engine.modulewrapper.get_module(modname, pattern).lookup( head.signature()) if function.rulechain is None: raise error.UnificationFailed rulechain = function.rulechain oldstate = heap.branch() while rulechain: rule = rulechain # standardizing apart try: deleted_body = rule.clone_and_unify_head(heap, head) if body is not None: body.unify(deleted_body, heap) except error.UnificationFailed: oldstate.revert_upto(heap) else: if function.rulechain is rulechain: function.rulechain = rulechain.next else: function.remove(rulechain) break rulechain = rulechain.next else: raise error.UnificationFailed()
def impl_nonvar(engine, heap, var): if isinstance(var, term.Var): raise error.UnificationFailed()
def impl_fail(engine, heap): raise error.UnificationFailed()
def impl_callable(engine, heap, var): if not helper.is_callable(var, engine): raise error.UnificationFailed()
def impl_compound(engine, heap, var): if isinstance(var, term.Var): raise error.UnificationFailed() if helper.is_term(var): return raise error.UnificationFailed()
def impl_atomic(engine, heap, var): if helper.is_atomic(var): return raise error.UnificationFailed()
def impl_atom(engine, heap, var): if isinstance(var, term.Var) or not isinstance(var, term.Atom): raise error.UnificationFailed()
def impl_number(engine, heap, var): if (isinstance(var, term.Var) or (not (isinstance(var, term.Number) or isinstance(var, term.BigInt)) and not isinstance(var, term.Float))): raise error.UnificationFailed()
def impl_float(engine, heap, var): if isinstance(var, term.Var) or not isinstance(var, term.Float): raise error.UnificationFailed()
def impl_integer(engine, heap, var): if (isinstance(var, term.Var) or not (isinstance(var, term.Number) or isinstance(var, term.BigInt))): raise error.UnificationFailed()
def activate(self, fcont, _): m = memo.CopyMemo() clone = self.template.copy(self.heap, m) self.result.append(clone) raise error.UnificationFailed()
def impl_at_end_of_stream(engine, heap, stream): byte = peek_byte(stream) if byte > -1: raise error.UnificationFailed()