예제 #1
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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
예제 #2
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_allset(rules, term, env):
    if term.arity < 2: return term
    key = term.args[0]
    goals = [terms.expand(g, env) for g in term.args[1:]]
    results = [terms.expand(key, r) for r in rules.search(*goals)]

    return frozenset(results)
예제 #3
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_allelse(rules, term, env):
    if term.arity < 3: return term
    key = term.args[0]
    alt = term.args[-1]
    goals = [terms.expand(g, env) for g in term.args[1:-1]]
    results = [terms.expand(key, r) for r in rules.search(*goals)]
    if len(results) > 0:
        return tuple(results)
    return rules.evaluate(alt, env)
예제 #4
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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)
예제 #5
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_alluniq(rules, term, env):
    if term.arity < 2: return term
    key = term.args[0]
    goals = [terms.expand(g, env) for g in term.args[1:]]
    results = [terms.expand(key, r) for r in rules.search(*goals)]

    results.sort()
    if len(results) >= 2:
        i = 0
        while i < len(results) - 1:
            if results[i] == results[i + 1]: del results[i]
            else: i = i + 1

    return tuple(results)
예제 #6
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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
예제 #7
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_any(rules, term, env):
    if term.arity < 2: return term
    key = term.args[0]
    goals = [terms.expand(g, env) for g in term.args[1:]]
    for result in rules.search(*goals):
        return rules.evaluate(key, result)
    return term
예제 #8
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_anyelse(rules, term, env):
    if term.arity < 3: return term
    key = term.args[0]
    alt = term.args[-1]
    goals = [terms.expand(g, env) for g in term.args[1:-1]]
    for result in rules.search(*goals):
        return rules.evaluate(key, result)
    return rules.evaluate(alt, env)
예제 #9
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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
예제 #10
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def pred_numeric(rules, term, env):
    term = terms.expand(term, env)
    for a in term.args:
        try:
            if not terms.is_const(a): return False
            f = float(a)
        except ValueError:
            return False
    return True
예제 #11
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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)
예제 #12
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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)
예제 #13
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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
예제 #14
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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)
예제 #15
0
파일: builtin.py 프로젝트: tylerwood/EigenD
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)
예제 #16
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def pred_print(engine, term, env):
    term = terms.expand(term, env)
    print ' '.join(terms.render_term(a) for a in term.args)
    return True
예제 #17
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def pred_unbound(rules, term, env):
    return not terms.is_bound(terms.expand(term, env))
예제 #18
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def func_cat(rules, term, env):
    term = terms.expand(term, env)
    result = ' '.join(str(a) for a in term.args)
    return result
예제 #19
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def pred_nonempty(engine, term, env):
    if term.arity != 1: return False
    t = terms.expand(term.args[0], env)
    if not terms.is_list(t): return False
    if not t: return False
    return True
예제 #20
0
파일: engine.py 프로젝트: tylerwood/EigenD
 def find_rules(self, term, env):
     ruleset = self.ruledict.get(term.signature())
     if ruleset != None:
         for rule in ruleset.find(terms.expand(term, env)):
             yield rule
예제 #21
0
파일: builtin.py 프로젝트: tylerwood/EigenD
def pred_not(rules, term, env):
    if term.arity < 1: return False
    goals = [terms.expand(g, env) for g in term.args]
    for result in rules.search(*goals):
        return False
    return True