Zulip Chat Archive

Stream: new members

Topic: How to use `ZFSet.omega`?


Bbbbbbbbba (Jan 04 2026 at 16:02):

I want to prove something like:

import Mathlib

example (z : ZFSet) : z  ZFSet.omega  z =    y  ZFSet.omega, insert y y = z := sorry

Ruben Van de Velde (Jan 04 2026 at 16:03):

Why?

Bbbbbbbbba (Jan 04 2026 at 16:04):

My original goal was to prove that some alternative definitions of omega are equivalent

Bbbbbbbbba (Jan 04 2026 at 16:05):

But I find it hard to use the hypothesis z ∈ ZFSet.omega

Bbbbbbbbba (Jan 04 2026 at 16:07):

ZFSet.omega_zero and ZFSet.omega_succ only says that omega is an inductive set, but not that it is the minimal one

Miyahara Kō (Jan 04 2026 at 16:28):

I'm proving now...

Mirek Olšák (Jan 04 2026 at 16:38):

example (z : ZFSet) : z  ZFSet.omega  z =    y  ZFSet.omega, insert y y = z := by
  intro zin
  obtain z := z
  apply ZFSet.mk_mem_iff.mp at zin
  obtain ⟨⟨n, hn := zin
  simp [PSet.omega] at hn
  cases n with
  | zero =>
    left
    apply Quot.sound
    convert hn
  | succ n =>
    right
    use .mk <| PSet.omega.Func n
    constructor
    · use n
    · simp [PSet.ofNat] at hn
      symm
      apply Quot.sound
      convert hn

Mirek Olšák (Jan 04 2026 at 16:39):

But my proof was very low-level, not sure if there is more convenient way of handling PSet & ZFSet.

Bbbbbbbbba (Jan 04 2026 at 16:47):

Thanks, I will probably learn quite a few tactic proof techniques from this

Bbbbbbbbba (Jan 04 2026 at 16:51):

I think ideally Mathlib should (re-)define everything ZF-related in a ZF-only language, so that ordinary users do not need to handle PSet directly.

Mirek Olšák (Jan 04 2026 at 16:53):

I think people should not use the ZFC universe much, and in the rare cases we want to embed Lean into it, there should be a meta-code to do that.

Mirek Olšák (Jan 04 2026 at 17:18):

Although that would be a more long-term project...

Miyahara Kō (Jan 04 2026 at 18:17):

Oh no proof was already done, here is my structured proof:

@[induction_eliminator]
protected lemma ZFSet.ind {motive : ZFSet.{u}  Prop} :
    (mk :  s, motive (mk s))   s, motive s :=
  Quotient.ind

@[simp]
lemma ZFSet.insert_mk (s t : PSet.{u}) : insert (mk s) (mk t) = mk (insert s t) :=
  rfl

lemma ZFSet.forall {p : ZFSet.{u}  Prop} : ( s, p s)   s, p (mk s) :=
  Quotient.forall

lemma PSet.mem_omega {s : PSet.{u}} : s  PSet.omega   n, s.Equiv (ofNat.{u} n) := by
  conv_lhs => simp [PSet.omega, PSet.mem_def]

lemma PSet.omega_subset (N : PSet.{u}) (hN0 :   N) (hNs :  n⦄, n  N  insert n n  N) :
    omega  N := by
  simp only [subset_iff, mem_omega, forall_exists_index]
  intro s n hs
  rw [Mem.congr_left hs]
  clear s hs
  induction n <;> unfold ofNat <;> solve_by_elim

lemma ZFSet.omega_subset (N : ZFSet.{u}) (hN0 :   N) (hNs :  n⦄, n  N  insert n n  N) :
    omega  N := by
  induction N with
  | mk N =>
    rw [omega, subset_iff]
    refine PSet.omega_subset N hN0 ?_
    simpa [ZFSet.forall] using hNs

example s : ZFSet.{u}⦄ (hs : s  ZFSet.omega) : s =    t  ZFSet.omega, insert t t = s := by
  classical
  suffices ZFSet.omega  insert  (ZFSet.image (fun t => insert t t) ZFSet.omega) by
    revert s hs
    simpa [ZFSet.subset_def] using this
  apply ZFSet.omega_subset
  case hN0 => simp
  intro n hn
  rw [ZFSet.mem_insert_iff, ZFSet.mem_image] at hn 
  replace hn : n  ZFSet.omega := by
    obtain rfl | n, hn, rfl := hn <;> solve_by_elim [ZFSet.omega_zero, ZFSet.omega_succ]
  grind only

Vlad (Jan 04 2026 at 19:08):

import Mathlib

example :  z, z  ZFSet.omega  z =    y  ZFSet.omega, insert y y = z := by
  rintro ⟨⟩ ⟨_ | n, h <;> have h := Quot.sound h; use .inl h
  right; use .mk $ .ofNat n, ⟨_, by rfl, h.symm

Dexin Zhang (Jan 18 2026 at 16:18):

#34092 provides some better API


Last updated: Feb 28 2026 at 14:05 UTC