Esempio n. 1
0
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)
Esempio n. 2
0
def impl_atom_concat(engine, a1, a2, result, continuation):
    if isinstance(a1, term.Var):
        if isinstance(a2, term.Var):
            # nondeterministic splitting of result
            r = helper.convert_to_str(result)
            for i in range(len(r) + 1):
                oldstate = engine.heap.branch()
                try:
                    a1.unify(term.Atom(r[:i]), engine.heap)
                    a2.unify(term.Atom(r[i:]), engine.heap)
                    return continuation.call(engine, choice_point=True)
                except error.UnificationFailed:
                    engine.heap.revert(oldstate)
            raise error.UnificationFailed()
        else:
            s2 = helper.convert_to_str(a2)
            r = helper.convert_to_str(result)
            if r.endswith(s2):
                stop = len(r) - len(s2)
                assert stop > 0
                a1.unify(term.Atom(r[:stop]), engine.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.Atom(r[len(s1):]), engine.heap)
            else:
                raise error.UnificationFailed()
        else:
            s2 = helper.convert_to_str(a2)
            result.unify(term.Atom(s1 + s2), engine.heap)
    return continuation.call(engine, choice_point=False)
Esempio n. 3
0
def impl_not(engine, call):
    try:
        try:
            engine.call(call)
        except error.CutException, e:
            engine.continue_after_cut(e.continuation)
    except error.UnificationFailed:
        return None
    raise error.UnificationFailed()
Esempio n. 4
0
def impl_does_not_unify(engine, obj1, obj2):
    try:
        branch = engine.heap.branch()
        try:
            obj1.unify(obj2, engine.heap)
        finally:
            engine.heap.revert(branch)
    except error.UnificationFailed:
        return
    raise error.UnificationFailed()
Esempio n. 5
0
def impl_retract(engine, pattern):
    from pypy.lang.prolog.builtin import builtins
    if isinstance(pattern, term.Term) and pattern.name == ":-":
        head = helper.ensure_callable(pattern.args[0])
        body = helper.ensure_callable(pattern.args[1])
    else:
        head = pattern
        body = None
    if head.signature in builtins:
        assert isinstance(head, term.Callable)
        error.throw_permission_error("modify", "static_procedure",
                                     head.get_prolog_signature())
    function = engine.signature2function.get(head.signature, None)
    if function is None:
        raise error.UnificationFailed
    #import pdb; pdb.set_trace()
    rulechain = function.rulechain
    while rulechain:
        rule = rulechain.rule
        oldstate = engine.heap.branch()
        # standardizing apart
        try:
            deleted_body = rule.clone_and_unify_head(engine.heap, head)
            if body is not None:
                body.unify(deleted_body, engine.heap)
        except error.UnificationFailed:
            engine.heap.revert(oldstate)
        else:
            if function.rulechain is rulechain:
                if rulechain.next is None:
                    del engine.signature2function[head.signature]
                else:
                    function.rulechain = rulechain.next
            else:
                function.remove(rulechain)
            break
        rulechain = rulechain.next
    else:
        raise error.UnificationFailed()
Esempio n. 6
0
 def _call(self, engine):
     clone = self.template.getvalue(engine.heap)
     self.found.append(clone)
     raise error.UnificationFailed()
Esempio n. 7
0
def impl_ground(engine, var):
    if isinstance(var, term.Var):
        raise error.UnificationFailed()
    if isinstance(var, term.Term):
        for arg in var.args:
            impl_ground(engine, arg)
Esempio n. 8
0
def impl_nonvar(engine, var):
    if isinstance(var, term.Var):
        raise error.UnificationFailed()
Esempio n. 9
0
def impl_callable(engine, var):
    if not helper.is_callable(var, engine):
        raise error.UnificationFailed()
Esempio n. 10
0
def impl_compound(engine, var):
    if isinstance(var, term.Var) or not isinstance(var, term.Term):
        raise error.UnificationFailed()
Esempio n. 11
0
def impl_sub_atom(engine, s, before, length, after, sub, continuation):
    # XXX can possibly be optimized
    if isinstance(length, term.Var):
        startlength = 0
        stoplength = len(s) + 1
    else:
        startlength = helper.unwrap_int(length)
        stoplength = startlength + 1
        if startlength < 0:
            startlength = 0
            stoplength = len(s) + 1
    if isinstance(before, term.Var):
        startbefore = 0
        stopbefore = len(s) + 1
    else:
        startbefore = helper.unwrap_int(before)
        stopbefore = startbefore + 1
        if startbefore < 0:
            startbefore = 0
            stopbefore = len(s) + 1
    oldstate = engine.heap.branch()
    if not isinstance(sub, term.Var):
        s1 = helper.unwrap_atom(sub)
        if len(s1) >= stoplength or len(s1) < startlength:
            raise error.UnificationFailed()
        start = startbefore
        while True:
            try:
                try:
                    b = s.find(s1, start, stopbefore + len(s1)) # XXX -1?
                    if b < 0:
                        break
                    start = b + 1
                    before.unify(term.Number(b), engine.heap)
                    after.unify(term.Number(len(s) - len(s1) - b), engine.heap)
                    length.unify(term.Number(len(s1)), engine.heap)
                    return continuation.call(engine, choice_point=True)
                except:
                    engine.heap.revert(oldstate)
                    raise
            except error.UnificationFailed:
                pass
        raise error.UnificationFailed()
    if isinstance(after, term.Var):
        for b in range(startbefore, stopbefore):
            for l in range(startlength, stoplength):
                if l + b > len(s):
                    continue
                try:
                    try:
                        before.unify(term.Number(b), engine.heap)
                        after.unify(term.Number(len(s) - l - b), engine.heap)
                        length.unify(term.Number(l), engine.heap)
                        sub.unify(term.Atom(s[b:b + l]), engine.heap)
                        return continuation.call(engine, choice_point=True)
                    except:
                        engine.heap.revert(oldstate)
                        raise
                except error.UnificationFailed:
                    pass
    else:
        a = helper.unwrap_int(after)
        for l in range(startlength, stoplength):
            b = len(s) - l - a
            assert b >= 0
            if l + b > len(s):
                continue
            try:
                try:
                    before.unify(term.Number(b), engine.heap)
                    after.unify(term.Number(a), engine.heap)
                    length.unify(term.Number(l), engine.heap)
                    sub.unify(term.Atom(s[b:b + l]), engine.heap)
                    return continuation.call(engine, choice_point=True)
                    return None
                except:
                    engine.heap.revert(oldstate)
                    raise
            except error.UnificationFailed:
                pass
    raise error.UnificationFailed()
Esempio n. 12
0
def impl_atom(engine, var):
    if isinstance(var, term.Var) or not isinstance(var, term.Atom):
        raise error.UnificationFailed()
Esempio n. 13
0
def impl_number(engine, var):
    if (isinstance(var, term.Var) or (not isinstance(var, term.Number)
                                      and not isinstance(var, term.Float))):
        raise error.UnificationFailed()
Esempio n. 14
0
def impl_float(engine, var):
    if isinstance(var, term.Var) or not isinstance(var, term.Float):
        raise error.UnificationFailed()
Esempio n. 15
0
def impl_integer(engine, var):
    if isinstance(var, term.Var) or not isinstance(var, term.Number):
        raise error.UnificationFailed()
Esempio n. 16
0
def impl_fail(engine):
    raise error.UnificationFailed()
Esempio n. 17
0
def impl_atomic(engine, var):
    if helper.is_atomic(var):
        return
    raise error.UnificationFailed()