Analysis I, Chapter 3 epilogue: Connections with ZFSet

In this epilogue we show that the ZFSet.{u} : Type (u + 1)ZFSet type in Mathlib (derived as a quotient from the PSet.{u} : Type (u + 1)PSet type) can be used to create models of the `SetTheory' class studied in this chapter, so long as we work in a universe of level at least 1. The constructions here are due to Edward van de Meent; see https://leanprover.zulipchat.com/#narrow/channel/113489-new-members/topic/Can.20this.20proof.20related.20to.20Set.20replacement.20be.20shorter.3F/near/527305173

universe u

A preliminary lemma about PSet.{u} : Type (u + 1)PSet: their natural numbers are ordered by membership.

lemma PSet.ofNat_mem_ofNat_of_lt (m n : ) : n < m ofNat n ofNat m := m:n:n < m ofNat n ofNat m m:n:h:n < mofNat n ofNat m induction h with m:n:ofNat n ofNat n.succ m:n:ofNat n insert (ofNat n) (ofNat n); All goals completed! 🐙 m:n:m✝:a✝:n.succ.le m✝ih:ofNat n ofNat m✝ofNat n ofNat m✝.succ m:n:m✝:a✝:n.succ.le m✝ih:ofNat n ofNat m✝ofNat n insert (ofNat m✝) (ofNat m✝); All goals completed! 🐙
lemma PSet.mem_ofNat_iff (n m : ) : ofNat n ofNat m n < m := n:m:ofNat n ofNat m n < m n:m:ofNat n ofNat m n < m n:m:m n ofNat n ofNat m; n:m:m < n m = n ofNat n ofNat m; n:m:h:m < nofNat n ofNat mm:ofNat m ofNat m n:m:h:m < nofNat n ofNat m All goals completed! 🐙 All goals completed! 🐙

Another preliminary lemma: Natural numbers in PSet.{u} : Type (u + 1)PSet can only be equivalent if they are equal.

lemma PSet.eq_of_ofNat_equiv_ofNat (n m : ): (ofNat.{u} n).Equiv (ofNat.{u} m) n = m := n:m:(ofNat n).Equiv (ofNat m) n = m n:m:this: (n m : ), m n (ofNat n).Equiv (ofNat m) n = mhmn:¬m n(ofNat n).Equiv (ofNat m) n = mn:m:hmn:m n(ofNat n).Equiv (ofNat m) n = m n:m:this: (n m : ), m n (ofNat n).Equiv (ofNat m) n = mhmn:¬m n(ofNat n).Equiv (ofNat m) n = m n:m:this: (n m : ), m n (ofNat n).Equiv (ofNat m) n = mhmn:¬m nheq:(ofNat n).Equiv (ofNat m)n = m; n:m:this: (n m : ), m n (ofNat n).Equiv (ofNat m) n = mhmn:¬m nheq:(ofNat n).Equiv (ofNat m)n m; All goals completed! 🐙 n:m:hmn:m nh:(ofNat n).Equiv (ofNat m)n = m; n:m:hmn:m nh: (x : PSet.{u}), x (ofNat n).toSet x (ofNat m).toSetn = m have : n m := n:m:(ofNat n).Equiv (ofNat m) n = m n:m:hmn:m nh:ofNat m (ofNat n).toSet ofNat m (ofNat m).toSetn m; All goals completed! 🐙 All goals completed! 🐙
open PSet in /-- Using the above lemmas, we can create a bijection between `ZFSet.omega` and the natural numbers. -/ noncomputable def ZFSet.nat_equiv : omega.{u} := Equiv.ofBijective (fun n => mk (ofNat.{u} n),mk_mem_iff.mpr (Mem.mk _ (ULift.up n))) (Function.Bijective fun n => mk (ofNat n), Function.Injective fun n => mk (ofNat n), Function.Surjective fun n => mk (ofNat n), Function.Injective fun n => mk (ofNat n), a₁✝:a₂✝:(fun n => mk (ofNat n), ) a₁✝ = (fun n => mk (ofNat n), ) a₂✝ a₁✝ = a₂✝; a₁✝:a₂✝:(ofNat a₁✝).Equiv (ofNat a₂✝) a₁✝ = a₂✝; All goals completed! 🐙 Function.Surjective fun n => mk (ofNat n), x:ZFSet.{u}hx:x omega a, (fun n => mk (ofNat n), ) a = x, hx; x:ZFSet.{u}hx✝:x omegahx:Quotient.out x PSet.omega a, (fun n => mk (ofNat n), ) a = x, hx✝; x:ZFSet.{u}hx:x omegan:PSet.omega.Typehn:(Quotient.out x).Equiv (PSet.omega.Func n) a, (fun n => mk (ofNat n), ) a = x, hx x:ZFSet.{u}hx:x omegan:PSet.omega.Typehn:(Quotient.out x).Equiv (ofNat n.down) a, mk (ofNat a) = x; x:ZFSet.{u}hx:x omegan:PSet.omega.Typehn:(Quotient.out x).Equiv (ofNat n.down)mk (ofNat n.down) = x; x:ZFSet.{u}hx:x omegan:PSet.omega.Typehn:(Quotient.out x).Equiv (ofNat n.down)(ofNat n.down).Equiv (Quotient.out x); All goals completed! 🐙 )open Classical in /-- Show that ZFSet obeys the `Chapter3.SetTheory` axioms. Most of these axioms were essentially already established in Mathlib and are relatively routine to transfer over; the equivalence of `ZF.omega` and `Nat` being the trickiest one in content (and the power set axiom also requiring some technical manipulation). -/ noncomputable instance ZFSet.inst_SetTheory : Chapter3.SetTheory.{u + 1,u + 1} where Set := ZFSet Object := ZFSet set_to_object := { toFun a₁ := a₁, inj' _ _ h := h} mem o s := o s extensionality _ _ := ext emptyset := emptyset_mem := notMem_empty singleton x := {x} singleton_axiom _ _ := mem_singleton union_pair x y := x y union_pair_axiom _ _ _ := mem_union specify A P := ZFSet.sep (fun s (h : s A) P s,h) A specification_axiom := (A : ZFSet.{u}) (P : { x // x A } Prop), (∀ x ZFSet.sep (fun s => (h : s A), P s, h) A, x A) (x : { x // x A }), x ZFSet.sep (fun s => (h : s A), P s, h) A P x All goals completed! 🐙 replace A P hp := @(A.sep (fun s (hs : s A) z, P s,hs z)).image (fun s if h : (hs : s A), z, P s,hs z then h.choose_spec.choose else ) (allZFSetDefinable _) replacement_axiom A P hp s := A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}s image (fun s => if h : (hs : s A), z, P s, hs z then .choose else ) (ZFSet.sep (fun s => (hs : s A), z, P s, hs z) A) x, P x s A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}(∃ z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s) a, (b : a A), P a, b s; A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}(∃ z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s) a, (b : a A), P a, b sA:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}(∃ a, (b : a A), P a, b s) z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}(∃ z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s) a, (b : a A), P a, b s A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz: (hs : z A), z_1, P z, hs z_1hz':(if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s a, (b : a A), P a, b s; A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz: (hs : z A), z_1, P z, hs z_1hz':(if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = sP z, hzA s; A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz: (hs : z A), z_1, P z, hs z_1hz':.choose = sP z, hzA s All goals completed! 🐙 A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}(∃ a, (b : a A), P a, b s) z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz':P z, hzA s z, (z A (hs : z A), z_1, P z, hs z_1) (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) = s; use z, hzA, A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz':P z, hzA s (hs : z A), z_1, P z, hs z_1 All goals completed! 🐙 A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz':P z, hzA sP z, hzA (if h : (hs : z A), z_1, P z, hs z_1 then .choose else ) P z, hzA s; A:ZFSet.{u}P:{ x // x A } ZFSet.{u} Prophp: (x : { x // x A }) (y y' : ZFSet.{u}), P x y P x y' y = y's:ZFSet.{u}z:ZFSet.{u}hzA:z Ahz':P z, hzA sP z, hzA .choose P z, hzA s; All goals completed! 🐙 nat := omega nat_equiv := nat_equiv regularity_axiom A := A:ZFSet.{u}(∃ x, x A) x A, (S : ZFSet.{u}), x = { toFun := fun a₁ => a₁, inj' := } S ¬ y A, y S A:ZFSet.{u} x A, x A, x_1 A, x_1 x; A:ZFSet.{u}x:ZFSet.{u}hx:x A x A, x_1 A, x_1 x; have y,hy,_ := regularity A (A:ZFSet.{u}x:ZFSet.{u}hx:x AA All goals completed! 🐙) A:ZFSet.{u}x:ZFSet.{u}hx:x Ay:ZFSet.{u}hy:y Aright✝:A y = x A, x y; A:ZFSet.{u}x:ZFSet.{u}hx:x Ay:ZFSet.{u}hy:y Aright✝:A y = z:ZFSet.{u}a✝¹:z Aa✝:z yFalse; have : z A y := A:ZFSet.{u}(∃ x, x A) x A, (S : ZFSet.{u}), x = { toFun := fun a₁ => a₁, inj' := } S ¬ y A, y S A:ZFSet.{u}x:ZFSet.{u}hx:x Ay:ZFSet.{u}hy:y Aright✝:A y = z:ZFSet.{u}a✝¹:z Aa✝:z yz A z y; All goals completed! 🐙 All goals completed! 🐙 pow X Y := funs Y X function_to_object X Y := { toFun f := @map (fun s if h : s X then f s,h else ) (allZFSetDefinable _) X inj' x _ h := X:ZFSet.{u}Y:ZFSet.{u}x:{ x // x X } { x // x Y }x✝:{ x // x X } { x // x Y }h:(fun f => map (fun s => if h : s X then (f s, h) else ) X) x = (fun f => map (fun s => if h : s X then (f s, h) else ) X) x✝x = x✝ X:ZFSet.{u}Y:ZFSet.{u}x:{ x // x X } { x // x Y }x✝:{ x // x X } { x // x Y }h:(fun f => map (fun s => if h : s X then (f s, h) else ) X) x = (fun f => map (fun s => if h : s X then (f s, h) else ) X) x✝s:ZFSet.{u}hs:s Xz✝:ZFSet.{u}z✝ (x s, hs) z✝ (x✝ s, hs); X:ZFSet.{u}Y:ZFSet.{u}x:{ x // x X } { x // x Y }x✝:{ x // x X } { x // x Y }s:ZFSet.{u}hs:s Xz✝:ZFSet.{u}h: (z : ZFSet.{u}), (∃ z_1 X, z_1.pair (if h : z_1 X then (x z_1, h) else ) = z) z_1 X, z_1.pair (if h : z_1 X then (x✝ z_1, h) else ) = zz✝ (x s, hs) z✝ (x✝ s, hs) X:ZFSet.{u}Y:ZFSet.{u}x:{ x // x X } { x // x Y }x✝:{ x // x X } { x // x Y }s:ZFSet.{u}hs:s Xz✝:ZFSet.{u}h:(∃ z X, z.pair (if h : z X then (x z, h) else ) = s.pair (x s, hs)) z X, z.pair (if h : z X then (x✝ z, h) else ) = s.pair (x s, hs)z✝ (x s, hs) z✝ (x✝ s, hs); All goals completed! 🐙} powerset_axiom X Y F := X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}F Y.funs X f, { toFun := fun f => map (fun s => if h : s Y then (f s, h) else ) Y, inj' := } f = F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}(F Y.prod X z Y, ∃! w, z.pair w F) f, map (fun s => if h : s Y then (f s, h) else ) Y = F; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}(F Y.prod X z Y, ∃! w, z.pair w F) f, map (fun s => if h : s Y then (f s, h) else ) Y = FX:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}(∃ f, map (fun s => if h : s Y then (f s, h) else ) Y = F) F Y.prod X z Y, ∃! w, z.pair w F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}(F Y.prod X z Y, ∃! w, z.pair w F) f, map (fun s => if h : s Y then (f s, h) else ) Y = F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w F f, map (fun s => if h : s Y then (f s, h) else ) Y = F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fmap (fun s => if h : s Y then ((fun x => .choose, ) s, h) else ) Y = F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}z✝ map (fun s => if h : s Y then .choose, else ) Y z✝ F; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}(∃ z Y, z.pair (if h : z Y then .choose else ) = z✝) z✝ F; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}(∃ z Y, z.pair (if h : z Y then .choose else ) = z✝) z✝ FX:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}z✝ F z Y, z.pair (if h : z Y then .choose else ) = z✝ X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}(∃ z Y, z.pair (if h : z Y then .choose else ) = z✝) z✝ F X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fy:ZFSet.{u}hy:y Yy.pair (if h : y Y then .choose else ) F; All goals completed! 🐙 X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}z✝ F z Y, z.pair (if h : z Y then .choose else ) = z✝ X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}hsub:F Y.prod Xhuniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}hf:z✝ F z Y, z.pair (if h : z Y then .choose else ) = z✝; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}huniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}hf:z✝ Fhsub:z✝ Y.prod X z Y, z.pair (if h : z Y then .choose else ) = z✝; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}huniq: z Y, ∃! w, z.pair w Fz✝:ZFSet.{u}hf:z✝ Fhsub: a Y, b X, z✝ = a.pair b z Y, z.pair (if h : z Y then .choose else ) = z✝; X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}huniq: z Y, ∃! w, z.pair w Fy:ZFSet.{u}hy:y Yx:ZFSet.{u}left✝:x Xhf:y.pair x F z Y, z.pair (if h : z Y then .choose else ) = y.pair x X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}huniq: z Y, ∃! w, z.pair w Fy:ZFSet.{u}hy:y Yx:ZFSet.{u}left✝:x Xhf:y.pair x Fy.pair (if h : y Y then .choose else ) = y.pair x; All goals completed! 🐙 X:ZFSet.{u}Y:ZFSet.{u}F:ZFSet.{u}(∃ f, map (fun s => if h : s Y then (f s, h) else ) Y = F) F Y.prod X z Y, ∃! w, z.pair w F X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }map (fun s => if h : s Y then (f s, h) else ) Y Y.prod X z Y, ∃! w, z.pair w map (fun s => if h : s Y then (f s, h) else ) Y; X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }map (fun s => if h : s Y then (f s, h) else ) Y Y.prod X z Y, ∃! w, z Y (if h : z Y then (f z, h) else ) = w; X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }map (fun s => if h : s Y then (f s, h) else ) Y Y.prod XX:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X } z Y, ∃! w, z Y (if h : z Y then (f z, h) else ) = w X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }map (fun s => if h : s Y then (f s, h) else ) Y Y.prod XX:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X } z Y, ∃! w, z Y (if h : z Y then (f z, h) else ) = w X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }z✝:ZFSet.{u}a✝:z✝ Y∃! w, z✝ Y (if h : z✝ Y then (f z✝, h) else ) = w X:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }z✝:ZFSet.{u}a✝:z✝ map (fun s => if h : s Y then (f s, h) else ) Yz✝ Y.prod XX:ZFSet.{u}Y:ZFSet.{u}f:{ x // x Y } { x // x X }z✝:ZFSet.{u}a✝:z✝ Y∃! w, z✝ Y (if h : z✝ Y then (f z✝, h) else ) = w All goals completed! 🐙 union := sUnion union_axiom _ _ := x✝¹:ZFSet.{u}x✝:ZFSet.{u}x✝ ⋃₀ x✝¹ S, x✝ S { toFun := fun a₁ => a₁, inj' := } S x✝¹ All goals completed! 🐙