Created
January 16, 2026 02:02
-
-
Save philzook58/f60f75dca6ac846655e34c5978862eec to your computer and use it in GitHub Desktop.
llm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import kdrag as kd | |
| import kdrag.smt as smt | |
| import kdrag.theories.logic.zf as zf | |
| Set = zf.ZFSet | |
| A, B, R, x, y, z = smt.Consts("A B R x y z", Set) | |
| a, b, c, p = kd.FreshVars("a b c p", Set) | |
| elem = zf.elem | |
| # Cartesian product | |
| prod = kd.define( | |
| "prod", | |
| [A, B], | |
| zf.sep( | |
| zf.pow(zf.pow(A | B)), | |
| smt.Lambda( | |
| [p], | |
| kd.QExists([x, y], smt.And(elem(x, A), elem(y, B)), p == zf.pair(x, y)), | |
| ), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [A, B, p], | |
| elem(p, prod(A, B)) | |
| == smt.And( | |
| kd.QExists([x, y], smt.And(elem(x, A), elem(y, B)), p == zf.pair(x, y)), | |
| elem(p, zf.pow(zf.pow(A | B))), | |
| ), | |
| ) | |
| ) | |
| def elem_prod(l): | |
| _A, _B, _p = l.fixes() | |
| l.unfold(prod) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| # Relations | |
| is_rel = kd.define( | |
| "is_rel", [R], smt.ForAll([p], smt.Implies(elem(p, R), zf.is_pair(p))) | |
| ) | |
| dom = kd.define( | |
| "dom", | |
| [R], | |
| zf.sep( | |
| zf.bigunion(zf.bigunion(R)), | |
| smt.Lambda([x], kd.QExists([y], elem(zf.pair(x, y), R))), | |
| ), | |
| ) | |
| ran = kd.define( | |
| "ran", | |
| [R], | |
| zf.sep( | |
| zf.bigunion(zf.bigunion(R)), | |
| smt.Lambda([y], kd.QExists([x], elem(zf.pair(x, y), R))), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x], | |
| elem(x, dom(R)) | |
| == smt.And( | |
| kd.QExists([y], elem(zf.pair(x, y), R)), | |
| elem(x, zf.bigunion(zf.bigunion(R))), | |
| ), | |
| ) | |
| ) | |
| def elem_dom(l): | |
| _R, _x = l.fixes() | |
| l.unfold(dom) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, y], | |
| elem(y, ran(R)) | |
| == smt.And( | |
| kd.QExists([x], elem(zf.pair(x, y), R)), | |
| elem(y, zf.bigunion(zf.bigunion(R))), | |
| ), | |
| ) | |
| ) | |
| def elem_ran(l): | |
| _R, _y = l.fixes() | |
| l.unfold(ran) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x], smt.Implies(elem(x, dom(R)), kd.QExists([y], elem(zf.pair(x, y), R))) | |
| ) | |
| ) | |
| def dom_has_pair(l): | |
| _R, _x = l.fixes() | |
| l.intros() | |
| l.rw(elem_dom, at=0) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, y], smt.Implies(elem(y, ran(R)), kd.QExists([x], elem(zf.pair(x, y), R))) | |
| ) | |
| ) | |
| def ran_has_pair(l): | |
| _R, _y = l.fixes() | |
| l.intros() | |
| l.rw(elem_ran, at=0) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([R], dom(R) <= zf.bigunion(zf.bigunion(R)))) | |
| def dom_le_bigunion(l): | |
| _R = l.fix() | |
| l.unfold(zf.le) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(elem_dom, at=0) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([R], ran(R) <= zf.bigunion(zf.bigunion(R)))) | |
| def ran_le_bigunion(l): | |
| _R = l.fix() | |
| l.unfold(zf.le) | |
| _y = l.fix() | |
| l.intros() | |
| l.rw(elem_ran, at=0) | |
| l.auto() | |
| # Images and functions | |
| image = kd.define( | |
| "image", | |
| [R, A], | |
| zf.sep( | |
| ran(R), | |
| smt.Lambda([y], kd.QExists([x], smt.And(elem(x, A), elem(zf.pair(x, y), R)))), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, A, y], | |
| elem(y, image(R, A)) | |
| == smt.And( | |
| kd.QExists([x], smt.And(elem(x, A), elem(zf.pair(x, y), R))), | |
| elem(y, ran(R)), | |
| ), | |
| ) | |
| ) | |
| def elem_image(l): | |
| _R, _A, _y = l.fixes() | |
| l.unfold(image) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| is_fun = kd.define( | |
| "is_fun", | |
| [R], | |
| smt.And( | |
| is_rel(R), | |
| smt.ForAll( | |
| [x, y, z], | |
| smt.Implies( | |
| smt.And(elem(zf.pair(x, y), R), elem(zf.pair(x, z), R)), y == z | |
| ), | |
| ), | |
| ), | |
| ) | |
| @kd.Theorem(smt.ForAll([R], smt.Implies(is_fun(R), is_rel(R)))) | |
| def is_fun_is_rel(l): | |
| _R = l.fix() | |
| l.unfold(is_fun) | |
| l.intros() | |
| l.auto() | |
| # Inverse and composition | |
| inv = kd.define( | |
| "inv", | |
| [R], | |
| zf.sep( | |
| zf.pow(zf.pow(zf.bigunion(zf.bigunion(R)))), | |
| smt.Lambda([p], kd.QExists([x, y], p == zf.pair(y, x), elem(zf.pair(x, y), R))), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, p], | |
| elem(p, inv(R)) | |
| == smt.And( | |
| kd.QExists([x, y], smt.And(p == zf.pair(y, x), elem(zf.pair(x, y), R))), | |
| elem(p, zf.pow(zf.pow(zf.bigunion(zf.bigunion(R))))), | |
| ), | |
| ) | |
| ) | |
| def elem_inv(l): | |
| _R, _p = l.fixes() | |
| l.unfold(inv) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| comp = kd.define( | |
| "comp", | |
| [R, B], | |
| zf.sep( | |
| zf.pow(zf.pow(zf.bigunion(zf.bigunion(B)) | zf.bigunion(zf.bigunion(R)))), | |
| smt.Lambda( | |
| [p], | |
| kd.QExists( | |
| [x, y, z], | |
| smt.And( | |
| elem(zf.pair(x, y), R), elem(zf.pair(y, z), B), p == zf.pair(x, z) | |
| ), | |
| ), | |
| ), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, B, p], | |
| elem(p, comp(R, B)) | |
| == smt.And( | |
| kd.QExists( | |
| [x, y, z], | |
| smt.And( | |
| elem(zf.pair(x, y), R), elem(zf.pair(y, z), B), p == zf.pair(x, z) | |
| ), | |
| ), | |
| elem( | |
| p, | |
| zf.pow( | |
| zf.pow(zf.bigunion(zf.bigunion(B)) | zf.bigunion(zf.bigunion(R))) | |
| ), | |
| ), | |
| ), | |
| ) | |
| ) | |
| def elem_comp(l): | |
| _R, _B, _p = l.fixes() | |
| l.unfold(comp) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x, y], | |
| smt.Implies(elem(zf.pair(y, x), inv(R)), elem(zf.pair(x, y), R)), | |
| ) | |
| ) | |
| def inv_pair_elim(l): | |
| _R, _x, _y = l.fixes() | |
| l.intros() | |
| l.have( | |
| kd.QExists( | |
| [a, b], | |
| smt.And(zf.pair(_y, _x) == zf.pair(b, a), elem(zf.pair(a, b), _R)), | |
| ), | |
| by=[elem_inv], | |
| ) | |
| _a, _b = l.obtain(-1) | |
| l.have(smt.And(_y == _b, _x == _a), by=[zf.pair_inj]) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x, y], | |
| smt.Implies( | |
| smt.And( | |
| elem(zf.pair(x, y), R), | |
| elem(zf.pair(y, x), zf.pow(zf.pow(zf.bigunion(zf.bigunion(R))))), | |
| ), | |
| elem(zf.pair(y, x), inv(R)), | |
| ), | |
| ) | |
| ) | |
| def inv_pair_intro(l): | |
| _R, _x, _y = l.fixes() | |
| l.intros() | |
| l.rw(elem_inv) | |
| l.split() | |
| l.exists(_x, _y) | |
| l.auto() | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([R], is_rel(inv(R)))) | |
| def inv_is_rel(l): | |
| _R = l.fix() | |
| l.unfold(is_rel) | |
| _p = l.fix() | |
| l.intros() | |
| l.have( | |
| kd.QExists( | |
| [a, b], | |
| smt.And(_p == zf.pair(b, a), elem(zf.pair(a, b), _R)), | |
| ), | |
| by=[elem_inv], | |
| ) | |
| _a, _b = l.obtain(-1) | |
| l.have(_p == zf.pair(_b, _a), by=[]) | |
| l.rw(-1) | |
| l.auto(by=[zf.is_pair_pair]) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x], | |
| smt.Implies(elem(x, dom(inv(R))), kd.QExists([y], elem(zf.pair(y, x), R))), | |
| ) | |
| ) | |
| def dom_inv_has_pair(l): | |
| _R, _x = l.fixes() | |
| l.intros() | |
| l.have(kd.QExists([y], elem(zf.pair(_x, y), inv(_R))), by=[dom_has_pair]) | |
| _y = l.obtain(-1) | |
| l.have(elem(zf.pair(_y, _x), _R), by=[inv_pair_elim(_R, _y, _x)]) | |
| l.exists(_y) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, y], | |
| smt.Implies(elem(y, ran(inv(R))), kd.QExists([x], elem(zf.pair(y, x), R))), | |
| ) | |
| ) | |
| def ran_inv_has_pair(l): | |
| _R, _y = l.fixes() | |
| l.intros() | |
| l.have(kd.QExists([x], elem(zf.pair(x, _y), inv(_R))), by=[ran_has_pair]) | |
| _x = l.obtain(-1) | |
| l.have(elem(zf.pair(_y, _x), _R), by=[inv_pair_elim(_R, _y, _x)]) | |
| l.exists(_x) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [R, x, y], | |
| smt.Implies(elem(zf.pair(x, y), inv(inv(R))), elem(zf.pair(x, y), R)), | |
| ) | |
| ) | |
| def inv_inv_elim(l): | |
| _R, _x, _y = l.fixes() | |
| l.intros() | |
| l.have(elem(zf.pair(_y, _x), inv(_R)), by=[inv_pair_elim(inv(_R), _y, _x)]) | |
| l.have(elem(zf.pair(_x, _y), _R), by=[inv_pair_elim(_R, _x, _y)]) | |
| l.auto() | |
| # Identity relation | |
| idrel = kd.define( | |
| "idrel", | |
| [A], | |
| zf.sep( | |
| prod(A, A), | |
| smt.Lambda([p], kd.QExists([x], smt.And(elem(x, A), p == zf.pair(x, x)))), | |
| ), | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [A, p], | |
| elem(p, idrel(A)) | |
| == smt.And( | |
| kd.QExists([x], smt.And(elem(x, A), p == zf.pair(x, x))), | |
| elem(p, prod(A, A)), | |
| ), | |
| ) | |
| ) | |
| def elem_idrel(l): | |
| _A, _p = l.fixes() | |
| l.unfold(idrel) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([A, x, y], smt.Implies(elem(zf.pair(x, y), idrel(A)), x == y))) | |
| def idrel_diag(l): | |
| _A, _x, _y = l.fixes() | |
| l.intros() | |
| l.have( | |
| kd.QExists([a], smt.And(elem(a, _A), zf.pair(_x, _y) == zf.pair(a, a))), | |
| by=[elem_idrel], | |
| ) | |
| _a = l.obtain(-1) | |
| l.have(smt.And(_x == _a, _y == _a), by=[zf.pair_inj]) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([A], is_rel(idrel(A)))) | |
| def idrel_is_rel(l): | |
| _A = l.fix() | |
| l.unfold(is_rel) | |
| _p = l.fix() | |
| l.intros() | |
| l.have( | |
| kd.QExists([x], smt.And(elem(x, _A), _p == zf.pair(x, x))), | |
| by=[elem_idrel], | |
| ) | |
| _x = l.obtain(-1) | |
| l.have(_p == zf.pair(_x, _x), by=[]) | |
| l.rw(-1) | |
| l.auto(by=[zf.is_pair_pair]) | |
| @kd.Theorem(smt.ForAll([A], is_fun(idrel(A)))) | |
| def idrel_is_fun(l): | |
| _A = l.fix() | |
| l.unfold(is_fun) | |
| l.split() | |
| l.auto(by=[idrel_is_rel]) | |
| x, y, z = l.fixes() | |
| l.intros() | |
| l.have(x == y, by=[idrel_diag(_A, x, y)]) | |
| l.have(x == z, by=[idrel_diag(_A, x, z)]) | |
| l.auto() | |
| # von Neumann naturals | |
| succ = kd.define("succ", [a], a | zf.sing(a)) | |
| inductive = kd.define( | |
| "inductive", | |
| [A], | |
| smt.And( | |
| elem(zf.emp, A), smt.ForAll([x], smt.Implies(elem(x, A), elem(succ(x), A))) | |
| ), | |
| ) | |
| inf_ax = kd.axiom(smt.Exists([A], inductive(A))) | |
| (inf_set,), inf_set_inductive = kd.tactics.skolem(inf_ax) | |
| omega = smt.Const("omega", Set) | |
| omega_def = kd.axiom( | |
| omega | |
| == zf.sep( | |
| inf_set, | |
| smt.Lambda([a], smt.ForAll([A], smt.Implies(inductive(A), elem(a, A)))), | |
| ) | |
| ) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [a], | |
| elem(a, omega) | |
| == smt.And( | |
| smt.ForAll([A], smt.Implies(inductive(A), elem(a, A))), elem(a, inf_set) | |
| ), | |
| ) | |
| ) | |
| def elem_omega(l): | |
| _a = l.fix() | |
| l.rw(omega_def) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([A], smt.Implies(inductive(A), elem(zf.emp, A)))) | |
| def inductive_has_emp(l): | |
| _A = l.fix() | |
| l.intros() | |
| l.unfold(inductive, at=0) | |
| l.split(at=0) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [A, x], smt.Implies(inductive(A), smt.Implies(elem(x, A), elem(succ(x), A))) | |
| ) | |
| ) | |
| def inductive_succ(l): | |
| _A, _x = l.fixes() | |
| l.intros() | |
| l.intros() | |
| l.unfold(inductive, at=0) | |
| l.split(at=0) | |
| l.specialize(1, _x) | |
| l.apply(-1) | |
| l.auto() | |
| @kd.Theorem(elem(zf.emp, omega)) | |
| def emp_in_omega(l): | |
| l.rw(elem_omega) | |
| l.split() | |
| with l.sub() as l1: | |
| _A = l1.fix() | |
| l1.intros() | |
| l1.auto(by=[inductive_has_emp(_A)]) | |
| l.auto(by=[inductive_has_emp(inf_set), inf_set_inductive]) | |
| @kd.Theorem(smt.ForAll([a], smt.Implies(elem(a, omega), elem(succ(a), omega)))) | |
| def omega_succ(l): | |
| _a = l.fix() | |
| l.intros() | |
| l.rw(elem_omega) | |
| l.split() | |
| with l.sub() as l1: | |
| _A = l1.fix() | |
| l1.intros() | |
| l1.rw(elem_omega, at=0) | |
| l1.split(at=0) | |
| l1.have(elem(_a, _A)) | |
| l1.specialize(0, _A) | |
| l1.apply(0) | |
| l1.auto() | |
| l1.auto(by=[inductive_succ(_A, _a)]) | |
| l.rw(elem_omega, at=0) | |
| l.split(at=0) | |
| l.auto(by=[inductive_succ(inf_set, _a), inf_set_inductive]) | |
| @kd.Theorem(inductive(omega)) | |
| def omega_inductive(l): | |
| l.unfold(inductive) | |
| l.split() | |
| l.auto(by=[emp_in_omega]) | |
| _x = l.fix() | |
| l.intros() | |
| l.auto(by=[omega_succ(_x)]) | |
| @kd.Theorem(smt.ForAll([A], smt.Implies(inductive(A), omega <= A))) | |
| def omega_le_inductive(l): | |
| _A = l.fix() | |
| l.intros() | |
| l.unfold(zf.le) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(elem_omega, at=1) | |
| l.split(at=1) | |
| l.specialize(1, _A) | |
| l.apply(-1) | |
| l.auto() | |
| zero = zf.emp | |
| one = succ(zero) | |
| two = succ(one) | |
| three = succ(two) | |
| is_nat = kd.define("is_nat", [a], elem(a, omega)) | |
| @kd.Theorem(is_nat(zero)) | |
| def zero_is_nat(l): | |
| l.unfold(is_nat) | |
| l.auto(by=[emp_in_omega]) | |
| @kd.Theorem(smt.ForAll([a], smt.Implies(is_nat(a), is_nat(succ(a))))) | |
| def succ_is_nat(l): | |
| _a = l.fix() | |
| l.intros() | |
| l.unfold(is_nat, at=0) | |
| l.unfold(is_nat) | |
| l.auto(by=[omega_succ(_a)]) | |
| @kd.Theorem(is_nat(one)) | |
| def one_is_nat(l): | |
| l.unfold(is_nat) | |
| l.have(elem(zero, omega), by=[emp_in_omega]) | |
| l.auto(by=[omega_succ(zero)]) | |
| @kd.Theorem(is_nat(two)) | |
| def two_is_nat(l): | |
| l.unfold(is_nat) | |
| l.have(is_nat(one), by=[one_is_nat]) | |
| l.unfold(is_nat, at=-1) | |
| l.auto(by=[omega_succ(one)]) | |
| @kd.Theorem(is_nat(three)) | |
| def three_is_nat(l): | |
| l.unfold(is_nat) | |
| l.have(is_nat(two), by=[two_is_nat]) | |
| l.unfold(is_nat, at=-1) | |
| l.auto(by=[omega_succ(two)]) | |
| @kd.Theorem(smt.ForAll([A], smt.Implies(smt.And(A <= omega, inductive(A)), A == omega))) | |
| def omega_induction(l): | |
| _A = l.fix() | |
| l.intros() | |
| l.split(at=0) | |
| l.rw(zf.ext_ax) | |
| _x = l.fix() | |
| l.split() | |
| with l.sub() as l1: | |
| l1.intros() | |
| l1.unfold(zf.le, at=0) | |
| l1.specialize(0, _x) | |
| l1.apply(-1) | |
| l1.auto() | |
| with l.sub() as l2: | |
| l2.intros() | |
| l2.have(omega <= _A, by=[omega_le_inductive(_A)]) | |
| l2.unfold(zf.le, at=-1) | |
| l2.specialize(-1, _x) | |
| l2.apply(-1) | |
| l2.auto() | |
| @kd.Theorem(smt.ForAll([a, x], elem(x, succ(a)) == smt.Or(elem(x, a), x == a))) | |
| def elem_succ(l): | |
| _a, _x = l.fixes() | |
| l.unfold(succ) | |
| l.rw(zf.elem_union) | |
| l.rw(zf.elem_sing) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([a], elem(a, succ(a)))) | |
| def elem_self_succ(l): | |
| _a = l.fix() | |
| l.rw(elem_succ) | |
| l.auto() | |
| @kd.Theorem(smt.ForAll([a], a <= succ(a))) | |
| def le_succ(l): | |
| _a = l.fix() | |
| l.unfold(zf.le) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(elem_succ) | |
| l.auto() | |
| @kd.Theorem(zf.emp <= omega) | |
| def emp_le_omega(l): | |
| l.unfold(zf.le) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(zf.elem_emp, at=0) | |
| l.auto() | |
| @kd.Theorem( | |
| smt.ForAll([x], smt.Implies(smt.And(x <= omega, elem(x, omega)), succ(x) <= omega)) | |
| ) | |
| def succ_le_omega(l): | |
| _x = l.fix() | |
| l.intros() | |
| l.split(at=0) | |
| l.unfold(zf.le) | |
| _y = l.fix() | |
| l.intros() | |
| l.rw(elem_succ, at=-1) | |
| l.split(at=-1) | |
| with l.sub() as l1: | |
| l1.rw(-1) | |
| l1.auto() | |
| with l.sub() as l2: | |
| l2.unfold(zf.le, at=0) | |
| l2.specialize(0, _y) | |
| l2.apply(-1) | |
| l2.auto() | |
| trans_omega = smt.Const("trans_omega", Set) | |
| trans_omega_def = kd.axiom(trans_omega == zf.sep(omega, smt.Lambda([x], x <= omega))) | |
| @kd.Theorem( | |
| smt.ForAll( | |
| [x], | |
| elem(x, trans_omega) == smt.And(elem(x, omega), x <= omega), | |
| ) | |
| ) | |
| def elem_trans_omega(l): | |
| _x = l.fix() | |
| l.rw(trans_omega_def) | |
| l.rw(zf.elem_sep) | |
| l.auto() | |
| @kd.Theorem(trans_omega <= omega) | |
| def trans_omega_le_omega(l): | |
| l.unfold(zf.le) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(elem_trans_omega, at=0) | |
| l.split(at=0) | |
| l.auto() | |
| @kd.Theorem(inductive(trans_omega)) | |
| def trans_omega_inductive(l): | |
| l.unfold(inductive) | |
| l.split() | |
| l.rw(elem_trans_omega) | |
| l.split() | |
| l.auto(by=[emp_in_omega]) | |
| l.auto(by=[emp_le_omega]) | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(elem_trans_omega) | |
| l.rw(elem_trans_omega, at=0) | |
| l.split(at=0) | |
| l.split() | |
| l.auto(by=[omega_succ(_x)]) | |
| l.auto(by=[succ_le_omega(_x)]) | |
| @kd.Theorem(omega == trans_omega) | |
| def omega_eq_trans_omega(l): | |
| l.have(trans_omega <= omega, by=[trans_omega_le_omega]) | |
| l.have(inductive(trans_omega), by=[trans_omega_inductive]) | |
| l.auto(by=[omega_induction(trans_omega)]) | |
| @kd.Theorem(smt.ForAll([x], smt.Implies(elem(x, omega), x <= omega))) | |
| def omega_transitive(l): | |
| _x = l.fix() | |
| l.intros() | |
| l.rw(omega_eq_trans_omega, at=0) | |
| l.rw(elem_trans_omega, at=0) | |
| l.split(at=0) | |
| l.auto() | |
| @kd.Theorem(elem(zero, one)) | |
| def zero_in_one(l): | |
| l.rw(elem_succ) | |
| l.auto() | |
| @kd.Theorem(elem(zero, two)) | |
| def zero_in_two(l): | |
| l.rw(elem_succ) | |
| l.left() | |
| l.rw(elem_succ) | |
| l.auto() | |
| @kd.Theorem(elem(one, two)) | |
| def one_in_two(l): | |
| l.rw(elem_succ) | |
| l.auto() | |
| print(omega_transitive) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment