Example #1
0
def pred_reverse(rules, term, env):
    if term.arity != 2: return False

    left_term = terms.expand(term.args[0], env)
    right_term = terms.expand(term.args[1], env)

    if terms.is_bound(left_term) and terms.is_bound(right_term):
        if not terms.is_list(left_term): return False
        left_list = list(left_term)
        left_list.reverse()
        left_term = tuple(left_list)
        return left_term == right_term

    if terms.is_bound(left_term):
        if not terms.is_list(left_term): return False
        left_list = list(left_term)
        left_list.reverse()
        left_term = tuple(left_list)
        return terms.unify(left_term, {}, right_term, env)

    if terms.is_bound(right_term):
        if not terms.is_list(right_term): return False
        right_list = list(right_term)
        right_list.reverse()
        right_term = tuple(right_list)
        return terms.unify(right_term, {}, left_term, env)

    return False
Example #2
0
def pred_extract(rules, term, env):
    if term.arity != 3: return False

    left = terms.expand(term.args[0], env)
    middle = terms.expand(term.args[1], env)
    right = terms.expand(term.args[2], env)

    if terms.is_unbound(middle):
        return False

    if not terms.is_list(middle): return False

    if terms.is_bound(right):
        # l,m,r const
        if not terms.is_list(right): return False
        if terms.is_bound(left):
            for (i, e) in enumerate(middle):
                if e == left:
                    rl = middle[0:i] + middle[i + 1:]
                    return rl == right
            return False
        # r,m const l variable
        r = []
        for (i, e) in enumerate(middle):
            env_copy = env.copy()
            if terms.unify(e, env, left, env_copy):
                rl = middle[0:i] + middle[i + 1:]
                if rl == right:
                    r.append(env_copy)
        return r

    # right variable
    if terms.is_unbound(left):
        # r,l var m const
        r = []
        for (i, e) in enumerate(middle):
            env_copy = env.copy()
            if terms.unify(e, env, left, env_copy):
                rl = middle[0:i] + middle[i + 1:]
                if terms.unify(rl, env, right, env_copy):
                    r.append(env_copy)
        return tuple(r)

    # l,m const r var
    r = []
    for (i, e) in enumerate(middle):
        if e == left:
            rl = middle[0:i] + middle[i + 1:]
            env_copy = env.copy()
            if terms.unify(rl, env, right, env_copy):
                r.append(env_copy)

    return tuple(r)
Example #3
0
def pred_is(rules, term, env):
    if term.arity != 2: return False

    leftv = rules.evaluate(term.args[0], env)
    rightv = rules.evaluate(term.args[1], env)

    if terms.is_bound(leftv):
        if terms.is_bound(rightv):
            return leftv == rightv
        return terms.unify(leftv, {}, rightv, env)

    if terms.is_bound(rightv):
        return terms.unify(rightv, {}, leftv, env)

    return False
Example #4
0
    def search_env(self, goal_env, *goals):
        queue = [
            Goal(terms.make_rule(terms.make_term('head'), *goals), None,
                 goal_env, 0)
        ]

        while queue:
            goal = queue.pop()
            if goal.current >= len(goal.rule.goals):
                if goal.parent == None:
                    yield goal.env
                else:
                    parent = goal.parent
                    terms.unify(goal.rule.head, goal.env,
                                parent.rule.goals[parent.current], parent.env)
                    parent.current = parent.current + 1
                    queue.insert(0, parent)
                continue

            term = goal.rule.goals[goal.current]

            if isinstance(term.pred, str) and term.pred.startswith('@'):
                builtin = self.predicates.get(term.pred[1:])
                if not builtin: continue

                results = builtin(self, term, goal.env)
                if results == False: continue

                goal.current = goal.current + 1
                if results == True:
                    queue.insert(0, goal)
                    continue

                for result in results:
                    queue.insert(
                        0, Goal(goal.rule, goal.parent, result, goal.current))

                continue

            for rule in self.find_rules(term, goal.env):
                rule_env = {}
                if self.unify(term, goal.env, rule.head, rule_env):
                    queue.insert(0, Goal(rule, goal, rule_env, 0))
Example #5
0
def pred_meta(engine, term, env):
    if term.arity != 3: return False

    t = terms.expand(term.args[0], env)
    p = terms.expand(term.args[1], env)
    a = terms.expand(term.args[2], env)

    if terms.is_unbound(t):
        if terms.is_unbound(p) or terms.is_unbound(a):
            return False
        if not isinstance(p, str) or not terms.is_list(a):
            return False
        x = terms.make_term(p, *a)
        return terms.unify(x, {}, t, env)

    e = env.copy()
    if terms.unify(t.pred, {}, p, e) and terms.unify(t.args, {}, a, e):
        env.update(e)
        return True

    return False
Example #6
0
def pred_map(rules, term, env):
    if term.arity < 4: return False

    var = terms.expand(term.args[0], env)
    list = terms.expand(term.args[1], env)
    var2 = terms.expand(term.args[2], env)
    list2 = terms.expand(term.args[3], env)
    clauses = [terms.expand(t, env) for t in term.args[4:]]

    if terms.is_unbound(list) or not terms.is_list(list): return False

    r = []

    for e in list:
        e2 = {}
        if not terms.unify(e, {}, var, e2): return False
        r2 = rules.search_any_env(e2, *clauses)
        if r2 is None: return False
        r.append(terms.expand(var2, r2))

    return terms.unify(tuple(r), env, list2, env)
Example #7
0
def pred_last(rules, term, env):
    if term.arity != 3: return False

    left = terms.expand(term.args[0], env)
    middle = terms.expand(term.args[1], env)
    right = terms.expand(term.args[2], env)

    if terms.is_bound(left):
        if not terms.is_list(left) or not left:
            return False
        env_copy = env.copy()
        if not terms.unify(left[-1], env, middle, env_copy):
            return False
        if not terms.unify(left[:-1], env, right, env_copy):
            return False
        return [env_copy]

    if terms.is_unbound(middle) or terms.is_unbound(
            right) or not terms.is_list(right):
        return False

    l2 = right + (middle, )
    return terms.unify(l2, env, left, env)
Example #8
0
def pred_applies(rules, term, env):
    if term.arity < 2: return False

    var = terms.expand(term.args[0], env)
    list = terms.expand(term.args[1], env)
    clauses = [terms.expand(t, env) for t in term.args[2:]]

    if terms.is_unbound(list) or not terms.is_list(list): return False

    for e in list:
        e2 = {}
        if not terms.unify(e, {}, var, e2): return False
        if rules.search_any_env(e2, *clauses) is None: return False

    return True
Example #9
0
def pred_in(rules, term, env):
    if term.arity != 2: return False

    right = terms.expand(term.args[1], env)
    if terms.is_unbound(right) or not terms.is_list(right): return False

    left = terms.expand(term.args[0], env)

    if terms.is_bound(left):
        return left in right

    r = []
    for e in right:
        env_copy = env.copy()
        if terms.unify(e, env, term.args[0], env_copy):
            r.append(env_copy)

    return r
Example #10
0
def func_filter(rules, term, env):
    if term.arity < 2: return ()

    var = terms.expand(term.args[0], env)
    list = terms.expand(term.args[1], env)
    clauses = [terms.expand(t, env) for t in term.args[2:]]

    if terms.is_unbound(list) or not terms.is_list(list): return ()

    r = []

    for e in list:
        e2 = {}
        if not terms.unify(e, {}, var, e2): continue
        if rules.search_any_env(e2, *clauses) is None: continue
        r.append(terms.expand(var, e2))

    return tuple(r)
Example #11
0
def func_extend(rules, term, env):
    if term.arity < 3: return ()

    var1 = terms.expand(term.args[0], env)
    list = terms.expand(term.args[1], env)
    var2 = terms.expand(term.args[2], env)
    clauses = [terms.expand(t, env) for t in term.args[3:]]

    if terms.is_unbound(list) or not terms.is_list(list): return ()

    r = []

    for e in list:
        e2 = {}
        if not terms.unify(e, {}, var1, e2): continue
        for r2 in rules.search_env(e2, *clauses):
            r.append(terms.expand(var2, r2))

    return tuple(r)
Example #12
0
 def unify(self, src, src_env, dest, dest_env):
     return terms.unify(src, src_env, dest, dest_env)