def simp_ite(i, t, e): if t == e: return t if is_true(i): return t if is_false(i): return e if is_true(t): return simp_or(i, e) if is_false(t): return simp_and(simp_not(i), e) if is_true(e): return simp_or(simp_not(i), t) if is_false(e): return simp_and(i, t) return Ite(i, t, e)
if __name__ == '__main__': S = UninterpretedSort('S') X, Y, Z = (Var(n, S) for n in ['X', 'Y', 'Z']) BinRel = FunctionSort(S, S, Boolean) leq = Const('leq', BinRel) transitive1 = ForAll((X, Y, Z), Implies(And(leq(X, Y), leq(Y, Z)), leq(X, Z))) transitive2 = ForAll((X, Y, Z), Or(Not(leq(X, Y)), Not(leq(Y, Z)), leq(X, Z))) transitive3 = Not( Exists((X, Y, Z), And(leq(X, Y), leq(Y, Z), Not(leq(X, Z))))) antisymmetric = ForAll((X, Y), Implies(And(leq(X, Y), leq(Y, X), true), Eq(Y, X))) print z3_implies(transitive1, transitive2) print z3_implies(transitive2, transitive3) print z3_implies(transitive3, transitive1) print z3_implies(transitive3, antisymmetric) print print z3_implies(true, Iff(transitive1, transitive2)) print x, y = (Const(n, S) for n in ['x', 'y']) b = Const('b', Boolean) print z3_implies(b, Eq(Ite(b, x, y), x)) print z3_implies(Not(b), Eq(Ite(b, x, y), y)) print z3_implies(Not(Eq(x, y)), Iff(Eq(Ite(b, x, y), x), b))
def infer_sorts(t, env=None): """ Infer the sort of term t in environment env. env maps symbol names to sort variables. The result is a pair: (s, tt) where s is a sort or sort variable with the sort of t in env, and tt is a closure that, when called, will concretize t according to inferred sort information at its call time. If env is not None, it must contain all the free variables and constants used in t. """ if env is None: names = free_variables(t, by_name=True).union(x.name for x in used_constants(t)) env = dict((name, SortVar()) for name in names) if type(t) in (Var, Const): if is_polymorphic(t): # each instance can have different sort s = insert_sortvars(t.sort, {}) else: s = env[t.name] unify(s, t.sort) return s, lambda: type(t)(t.name, convert_from_sortvars(s)) elif type(t) is Apply: func_s, func_t = infer_sorts(t.func, env) xys = [infer_sorts(tt, env) for tt in t.terms] terms_s = [x for x, y in xys] terms_t = [y for x, y in xys] sorts = terms_s + [SortVar()] unify(func_s, FunctionSort(*sorts)) return sorts[-1], lambda: Apply(func_t(), *(x() for x in terms_t)) elif type(t) is Eq: s1, t1 = infer_sorts(t.t1, env) s2, t2 = infer_sorts(t.t2, env) unify(s1, s2) return Boolean, lambda: Eq(t1(), t2()) elif type(t) is Ite: s_cond, t_cond = infer_sorts(t.cond, env) s_then, t_then = infer_sorts(t.t_then, env) s_else, t_else = infer_sorts(t.t_else, env) unify(s_cond, Boolean) unify(s_then, s_else) return s_then, lambda: Ite(t_cond(), t_then(), t_else()) elif type(t) in (Not, And, Or, Implies, Iff): xys = [infer_sorts(tt, env) for tt in t] terms_s = [x for x, y in xys] terms_t = [y for x, y in xys] for s in terms_s: unify(s, Boolean) return Boolean, lambda: type(t)(*[x() for x in terms_t]) elif type(t) in (ForAll, Exists): # create a copy of the environment and shadow that quantified # variables env = env.copy() env.update((v.name, SortVar()) for v in t.variables) vars_t = [infer_sorts(v, env)[1] for v in t.variables] body_s, body_t = infer_sorts(t.body, env) unify(body_s, Boolean) return Boolean, lambda: type(t)( [x() for x in vars_t], body_t(), ) elif hasattr(t, 'clone'): xys = [infer_sorts(tt, env) for tt in t.args] terms_t = [y for x, y in xys] return TopSort(), lambda: t.clone([x() for x in terms_t]) else: assert False, type(t)
assert f1 == cf1 print f2 = And(ps(XT), pt(xs)) cf2 = concretize_sorts(f2) print repr(f2) print repr(cf2) print f3 = Exists([TT], And(ps(XT), TT(xs))) cf3 = concretize_sorts(f3) print repr(f3) print repr(cf3) print f4 = Iff(xt, Ite(yt, xt, XT)) cf4 = concretize_sorts(f4) print repr(f4) print repr(cf4) print # TODO: add more tests, specifically a test that checks # unification across different quantified bodies """ c10 = Concept('c10',[X], And(p(X), Not(q(X)))) c01 = Concept('c01',[X], And(Not(p(X)), q(X))) c00 = Concept('c00',[X], And(Not(p(X)), Not(q(X)))) crn = Concept([X, Y], Or(r(X,Y), n(X,Y))) X, Y, _ = (Var(n, T) for n in ['X', 'Y', 'Z'])