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
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)
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)
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)
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)
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
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
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)
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
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
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)
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)
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
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)
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)
def pred_print(engine, term, env): term = terms.expand(term, env) print ' '.join(terms.render_term(a) for a in term.args) return True
def pred_unbound(rules, term, env): return not terms.is_bound(terms.expand(term, env))
def func_cat(rules, term, env): term = terms.expand(term, env) result = ' '.join(str(a) for a in term.args) return result
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
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
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