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 test_term(self): self.assertEquals('andrew', self.term1.pred) self.assertEquals('andrew', self.term2.pred) self.assertEquals('andrew', self.term3.pred) self.assertEquals(False, terms.is_const(self.term1)) self.assertEquals(True, terms.is_bound(self.term1)) self.assertEquals(False, terms.is_variable(self.term1)) self.assertEquals(True, terms.is_term(self.term1)) self.assertEquals(False, terms.is_unbound(self.term1)) self.assertEquals(False, terms.is_list(self.term1)) self.assertEquals(False, terms.is_const(self.term2)) self.assertEquals(False, terms.is_bound(self.term2)) self.assertEquals(False, terms.is_variable(self.term2)) self.assertEquals(True, terms.is_term(self.term2)) self.assertEquals(True, terms.is_unbound(self.term2)) self.assertEquals(False, terms.is_list(self.term2)) self.assertEquals(False, terms.is_const(self.term3)) self.assertEquals(True, terms.is_bound(self.term3)) self.assertEquals(False, terms.is_variable(self.term3)) self.assertEquals(True, terms.is_term(self.term3)) self.assertEquals(False, terms.is_unbound(self.term3)) self.assertEquals(False, terms.is_list(self.term3))
def indices(term): i1 = None i2 = None if term.arity > 0 and terms.is_bound(term.args[0]): i1 = hash(term.args[0]) if term.arity > 1 and terms.is_bound(term.args[1]): i2 = hash(term.args[1]) return (i1, i2)
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 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
def evaluate(self, term, env): if terms.is_bound(term): return term if terms.is_variable(term): if term.pred in env: return env[term.pred] return term if terms.is_split(term): return terms.make_split(self.evaluate(term.head, env), self.evaluate(term.tail, env)) if terms.is_list(term): return tuple(self.evaluate(a, env) for a in term) if term.pred.startswith('$'): builtin = self.functions.get(term.pred[1:]) if not builtin: raise ValueError('unknown function: %s' % term.pred) return builtin(self, term, env) if term.arity == 0: return term args = [self.evaluate(a, env) for a in term.args] return terms.make_term(term.pred, *args)
def test_variable(self): self.assertEquals(False, terms.is_const(self.variable)) self.assertEquals(False, terms.is_bound(self.variable)) self.assertEquals(True, terms.is_variable(self.variable)) self.assertEquals(False, terms.is_term(self.variable)) self.assertEquals(True, terms.is_unbound(self.variable)) self.assertEquals(False, terms.is_list(self.variable))
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_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 test_split(self): self.assertEquals(True, terms.is_split(self.split)) self.assertEquals(False, terms.is_term(self.split)) self.assertEquals(False, terms.is_bound(self.split)) self.assertEquals(self.variable, self.split.head) self.assertEquals(self.variable, self.split.tail)
def check_list3(self,list,e1,e2,e3): self.assertEquals(terms.is_bound(e1) and terms.is_bound(e2) and terms.is_bound(e3), terms.is_bound(list)) self.assertEquals(tuple, list.__class__) self.assertEquals(3, len(list)) self.assertEquals(e1, list[0]) self.check_list2(list[1:],e2,e3)
def check_list1(self,list,e1): self.assertEquals(terms.is_bound(e1), terms.is_bound(list)) self.assertEquals(tuple, list.__class__) self.assertEquals(1, len(list)) self.assertEquals(e1, list[0]) self.check_list0(list[1:])
def check_list0(self,list): self.assertEquals(True, terms.is_list(list)) self.assertEquals(True, terms.is_bound(list)) self.assertEquals(False, terms.is_unbound(list)) self.assertEquals(True, terms.is_list(list)) self.assertEquals(False, terms.is_split(list))
def pred_unbound(rules, term, env): return not terms.is_bound(terms.expand(term, env))