l3lab/ntp-mathlib huggingface dataset:
/-- All functions are classically definable. -/
noncomputable def allDefinable : ∀ {n} (F : OfArity ZFSet ZFSet n), Definable n F
  | 0, F =>
    let p := @Quotient.exists_rep PSet _ F
    @Definable.EqMk 0 ⟨choose p, Equiv.rfl⟩ _ (choose_spec p)
  | n + 1, (F : OfArity ZFSet ZFSet (n + 1)) => by
    have I := fun x => allDefinable (F x)
    refine' @Definable.EqMk (n + 1) ⟨fun x : PSet => (@Definable.Resp _ _ (I ⟦x⟧)).1, _⟩ _ _
    · dsimp [Arity.Equiv]
      intro x y h
      rw [@Quotient.sound PSet _ _ _ h]
      exact (Definable.Resp (F ⟦y⟧)).2
    refine' funext fun q => Quotient.inductionOn q fun x => _
    

Proof state:
case refine'_2
n : ℕ
F : OfArity ZFSet ZFSet (n + 1)
I : (x : ZFSet) → Definable (Nat.add n 0) (F x)
q : ZFSet
x : PSet
⊢ Resp.eval (n + 1)
      { val := fun x => ↑(Definable.Resp (F ⟦x⟧)),
        property := (_ : Arity.Equiv (fun x => ↑(Definable.Resp (F ⟦x⟧))) fun x => ↑(Definable.Resp (F ⟦x⟧))) }
      ⟦x⟧ =
    F ⟦x⟧

Next tactic:
simp_rw [Resp.eval_val, Resp.f]
/-- All functions are classically definable. -/
noncomputable def allDefinable : ∀ {n} (F : OfArity ZFSet ZFSet n), Definable n F
  | 0, F =>
    let p := @Quotient.exists_rep PSet _ F
    @Definable.EqMk 0 ⟨choose p, Equiv.rfl⟩ _ (choose_spec p)
  | n + 1, (F : OfArity ZFSet ZFSet (n + 1)) => by
    have I := fun x => allDefinable (F x)
    refine' @Definable.EqMk (n + 1) ⟨fun x : PSet => (@Definable.Resp _ _ (I ⟦x⟧)).1, _⟩ _ _
    · dsimp [Arity.Equiv]
      intro x y h
      rw [@Quotient.sound PSet _ _ _ h]
      exact (Definable.Resp (F ⟦y⟧)).2
    refine' funext fun q => Quotient.inductionOn q fun x => _
    simp_rw [Resp.eval_val, Resp.f]
    

Proof state:
case refine'_2
n : ℕ
F : OfArity ZFSet ZFSet (n + 1)
I : (x : ZFSet) → Definable (Nat.add n 0) (F x)
q : ZFSet
x : PSet
⊢ Resp.eval n
      { val := ↑(Definable.Resp (F ⟦x⟧)),
        property :=
          (_ :
            Arity.Equiv
              (↑{ val := fun x => ↑(Definable.Resp (F ⟦x⟧)),
                    property :=
                      (_ : Arity.Equiv (fun x => ↑(Definable.Resp (F ⟦x⟧))) fun x => ↑(Definable.Resp (F ⟦x⟧))) }
                x)
              (↑{ val := fun x => ↑(Definable.Resp (F ⟦x⟧)),
                    property :=
                      (_ : Arity.Equiv (fun x => ↑(Definable.Resp (F ⟦x⟧))) fun x => ↑(Definable.Resp (F ⟦x⟧))) }
                x)) } =
    F ⟦x⟧

Next tactic:
exact @Definable.eq _ (F ⟦x⟧) (I ⟦x⟧)
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    

Proof state:
x : ZFSet
a : PSet
⊢ Small.{u, u + 1} ↑(toSet ⟦a⟧)

Next tactic:
let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    

Proof state:
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
⊢ Small.{u, u + 1} ↑(toSet ⟦a⟧)

Next tactic:
suffices Function.Surjective f by exact small_of_surjective this
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    suffices Function.Surjective f by 

Proof state:
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
this : Function.Surjective f
⊢ Small.{u, u + 1} ↑(toSet ⟦a⟧)

Next tactic:
exact small_of_surjective this
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    suffices Function.Surjective f by exact small_of_surjective this
    

Proof state:
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
⊢ Function.Surjective f

Next tactic:
rintro ⟨y, hb⟩
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    suffices Function.Surjective f by exact small_of_surjective this
    rintro ⟨y, hb⟩
    

Proof state:
case mk
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
y : ZFSet
hb : y ∈ toSet (mk a)
⊢ ∃ a_1, f a_1 = { val := y, property := hb }

Next tactic:
induction y using Quotient.inductionOn
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    suffices Function.Surjective f by exact small_of_surjective this
    rintro ⟨y, hb⟩
    induction y using Quotient.inductionOn
    

Proof state:
case mk.h
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
a✝ : PSet
hb : ⟦a✝⟧ ∈ toSet (mk a)
⊢ ∃ a_1, f a_1 = { val := ⟦a✝⟧, property := hb }

Next tactic:
cases' hb with i h
instance small_toSet (x : ZFSet.{u}) : Small.{u} x.toSet :=
  Quotient.inductionOn x fun a => by
    let f : a.Type → (mk a).toSet := fun i => ⟨mk <| a.Func i, func_mem a i⟩
    suffices Function.Surjective f by exact small_of_surjective this
    rintro ⟨y, hb⟩
    induction y using Quotient.inductionOn
    cases' hb with i h
    

Proof state:
case mk.h.intro
x : ZFSet
a : PSet
f : Type a → ↑(toSet (mk a)) := fun i => { val := mk (Func a i), property := (_ : Func a i ∈ a) }
a✝ : PSet
i : Type a
h : PSet.Equiv a✝ (Func a i)
⊢ ∃ a_1, f a_1 = { val := ⟦a✝⟧, property := (_ : ∃ b, PSet.Equiv a✝ (Func a b)) }

Next tactic:
exact ⟨i, Subtype.coe_injective (Quotient.sound h.symm)⟩
@[simp]
theorem toSet_subset_iff {x y : ZFSet} : x.toSet ⊆ y.toSet ↔ x ⊆ y := by
  

Proof state:
x y : ZFSet
⊢ toSet x ⊆ toSet y ↔ x ⊆ y

Next tactic:
simp [subset_def, Set.subset_def]
theorem ext_iff {x y : ZFSet.{u}} : x = y ↔ ∀ z : ZFSet.{u}, z ∈ x ↔ z ∈ y :=
  ⟨fun h => by 

Proof state:
x y : ZFSet
h : x = y
⊢ ∀ (z : ZFSet), z ∈ x ↔ z ∈ y

Next tactic:
simp [h]
@[simp]
theorem not_nonempty_empty : ¬ZFSet.Nonempty ∅ := by 

Proof state:
⊢ ¬ZFSet.Nonempty ∅

Next tactic:
simp [ZFSet.Nonempty]
@[simp]
theorem nonempty_mk_iff {x : PSet} : (mk x).Nonempty ↔ x.Nonempty := by
  

Proof state:
x : PSet
⊢ ZFSet.Nonempty (mk x) ↔ PSet.Nonempty x

Next tactic:
refine' ⟨_, fun ⟨a, h⟩ => ⟨mk a, h⟩⟩
@[simp]
theorem nonempty_mk_iff {x : PSet} : (mk x).Nonempty ↔ x.Nonempty := by
  refine' ⟨_, fun ⟨a, h⟩ => ⟨mk a, h⟩⟩
  

Proof state:
x : PSet
⊢ ZFSet.Nonempty (mk x) → PSet.Nonempty x

Next tactic:
rintro ⟨a, h⟩
@[simp]
theorem nonempty_mk_iff {x : PSet} : (mk x).Nonempty ↔ x.Nonempty := by
  refine' ⟨_, fun ⟨a, h⟩ => ⟨mk a, h⟩⟩
  rintro ⟨a, h⟩
  

Proof state:
case intro
x : PSet
a : ZFSet
h : a ∈ toSet (mk x)
⊢ PSet.Nonempty x

Next tactic:
induction a using Quotient.inductionOn
@[simp]
theorem nonempty_mk_iff {x : PSet} : (mk x).Nonempty ↔ x.Nonempty := by
  refine' ⟨_, fun ⟨a, h⟩ => ⟨mk a, h⟩⟩
  rintro ⟨a, h⟩
  induction a using Quotient.inductionOn
  

Proof state:
case intro.h
x a✝ : PSet
h : ⟦a✝⟧ ∈ toSet (mk x)
⊢ PSet.Nonempty x

Next tactic:
exact ⟨_, h⟩
theorem eq_empty (x : ZFSet.{u}) : x = ∅ ↔ ∀ y : ZFSet.{u}, y ∉ x := by
  

Proof state:
x : ZFSet
⊢ x = ∅ ↔ ∀ (y : ZFSet), y ∉ x

Next tactic:
rw [ext_iff]
theorem eq_empty (x : ZFSet.{u}) : x = ∅ ↔ ∀ y : ZFSet.{u}, y ∉ x := by
  rw [ext_iff]
  

Proof state:
x : ZFSet
⊢ (∀ (z : ZFSet), z ∈ x ↔ z ∈ ∅) ↔ ∀ (y : ZFSet), y ∉ x

Next tactic:
simp
theorem eq_empty_or_nonempty (u : ZFSet) : u = ∅ ∨ u.Nonempty := by
  

Proof state:
u : ZFSet
⊢ u = ∅ ∨ ZFSet.Nonempty u

Next tactic:
rw [eq_empty, ← not_exists]
theorem eq_empty_or_nonempty (u : ZFSet) : u = ∅ ∨ u.Nonempty := by
  rw [eq_empty, ← not_exists]
  

Proof state:
u : ZFSet
⊢ (¬∃ x, x ∈ u) ∨ ZFSet.Nonempty u

Next tactic:
apply em'
@[simp]
theorem toSet_insert (x y : ZFSet) : (insert x y).toSet = insert x y.toSet := by
  

Proof state:
x y : ZFSet
⊢ toSet (insert x y) = insert x (toSet y)

Next tactic:
ext
@[simp]
theorem toSet_insert (x y : ZFSet) : (insert x y).toSet = insert x y.toSet := by
  ext
  

Proof state:
case h
x y x✝ : ZFSet
⊢ x✝ ∈ toSet (insert x y) ↔ x✝ ∈ insert x (toSet y)

Next tactic:
simp
@[simp]
theorem toSet_singleton (x : ZFSet) : ({x} : ZFSet).toSet = {x} := by
  

Proof state:
x : ZFSet
⊢ toSet {x} = {x}

Next tactic:
ext
@[simp]
theorem toSet_singleton (x : ZFSet) : ({x} : ZFSet).toSet = {x} := by
  ext
  

Proof state:
case h
x x✝ : ZFSet
⊢ x✝ ∈ toSet {x} ↔ x✝ ∈ {x}

Next tactic:
simp
theorem mem_pair {x y z : ZFSet.{u}} : x ∈ ({y, z} : ZFSet) ↔ x = y ∨ x = z := by
  

Proof state:
x y z : ZFSet
⊢ x ∈ {y, z} ↔ x = y ∨ x = z

Next tactic:
simp
@[simp]
theorem omega_succ {n} : n ∈ omega.{u} → insert n n ∈ omega.{u} :=
  Quotient.inductionOn n fun x ⟨⟨n⟩, h⟩ =>
    ⟨⟨n + 1⟩,
      ZFSet.exact <|
        show insert (mk x) (mk x) = insert (mk <| ofNat n) (mk <| ofNat n) by
          

Proof state:
n✝ : ZFSet
x : PSet
x✝ : ⟦x⟧ ∈ omega
n : ℕ
h : PSet.Equiv x (Func PSet.omega { down := n })
⊢ insert (mk x) (mk x) = insert (mk (ofNat n)) (mk (ofNat n))

Next tactic:
rw [ZFSet.sound h]
@[simp]
theorem omega_succ {n} : n ∈ omega.{u} → insert n n ∈ omega.{u} :=
  Quotient.inductionOn n fun x ⟨⟨n⟩, h⟩ =>
    ⟨⟨n + 1⟩,
      ZFSet.exact <|
        show insert (mk x) (mk x) = insert (mk <| ofNat n) (mk <| ofNat n) by
          rw [ZFSet.sound h]
          

Proof state:
n✝ : ZFSet
x : PSet
x✝ : ⟦x⟧ ∈ omega
n : ℕ
h : PSet.Equiv x (Func PSet.omega { down := n })
⊢ insert (mk (Func PSet.omega { down := n })) (mk (Func PSet.omega { down := n })) =
    insert (mk (ofNat n)) (mk (ofNat n))

Next tactic:
rfl
/-- `{x ∈ a | p x}` is the set of elements in `a` satisfying `p` -/
protected def sep (p : ZFSet → Prop) : ZFSet → ZFSet :=
  Resp.eval 1
    ⟨PSet.sep fun y => p (mk y), fun ⟨α, A⟩ ⟨β, B⟩ ⟨αβ, βα⟩ =>
      ⟨fun ⟨a, pa⟩ =>
        let ⟨b, hb⟩ := αβ a
        ⟨⟨b, by 

Proof state:
p : ZFSet → Prop
x✝³ x✝² : PSet
α : Type ?u.52921
A : α → PSet
β : Type ?u.52921
B : β → PSet
x✝¹ : PSet.Equiv (PSet.mk α A) (PSet.mk β B)
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
βα : ∀ (b : β), ∃ a, PSet.Equiv (A a) (B b)
x✝ : { a // (fun y => p (mk y)) (Func (PSet.mk α A) a) }
a : Type (PSet.mk α A)
pa : (fun y => p (mk y)) (Func (PSet.mk α A) a)
b : β
hb : PSet.Equiv (A a) (B b)
⊢ (fun y => p (mk y)) (Func (PSet.mk β B) b)

Next tactic:
simpa only [mk_func, ← ZFSet.sound hb]
/-- `{x ∈ a | p x}` is the set of elements in `a` satisfying `p` -/
protected def sep (p : ZFSet → Prop) : ZFSet → ZFSet :=
  Resp.eval 1
    ⟨PSet.sep fun y => p (mk y), fun ⟨α, A⟩ ⟨β, B⟩ ⟨αβ, βα⟩ =>
      ⟨fun ⟨a, pa⟩ =>
        let ⟨b, hb⟩ := αβ a
        ⟨⟨b, by simpa only [mk_func, ← ZFSet.sound hb]⟩, hb⟩,
        fun ⟨b, pb⟩ =>
        let ⟨a, ha⟩ := βα b
        ⟨⟨a, by 

Proof state:
p : ZFSet → Prop
x✝³ x✝² : PSet
α : Type ?u.52921
A : α → PSet
β : Type ?u.52921
B : β → PSet
x✝¹ : PSet.Equiv (PSet.mk α A) (PSet.mk β B)
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
βα : ∀ (b : β), ∃ a, PSet.Equiv (A a) (B b)
x✝ : { a // (fun y => p (mk y)) (Func (PSet.mk β B) a) }
b : Type (PSet.mk β B)
pb : (fun y => p (mk y)) (Func (PSet.mk β B) b)
a : α
ha : PSet.Equiv (A a) (B b)
⊢ (fun y => p (mk y)) (Func (PSet.mk α A) a)

Next tactic:
simpa only [mk_func, ZFSet.sound ha]
@[simp]
theorem mem_sep {p : ZFSet.{u} → Prop} {x y : ZFSet.{u}} :
    y ∈ ZFSet.sep p x ↔ y ∈ x ∧ p y :=
  Quotient.inductionOn₂ x y fun ⟨α, A⟩ y =>
    ⟨fun ⟨⟨a, pa⟩, h⟩ => ⟨⟨a, h⟩, by 

Proof state:
p : ZFSet → Prop
x y✝ : ZFSet
x✝¹ y : PSet
α : Type u
A : α → PSet
x✝ : ⟦y⟧ ∈ ZFSet.sep p ⟦PSet.mk α A⟧
a : Type (PSet.mk α A)
pa : (fun y => p (mk y)) (Func (PSet.mk α A) a)
h :
  PSet.Equiv y
    (Func
      ↑(Resp.f
          { val := PSet.sep fun y => p (mk y),
            property :=
              (_ :
                ∀ (x x_1 : PSet),
                  PSet.Equiv x x_1 → Arity.Equiv (PSet.sep (fun y => p (mk y)) x) (PSet.sep (fun y => p (mk y)) x_1)) }
          (PSet.mk α A))
      { val := a, property := pa })
⊢ p ⟦y⟧

Next tactic:
rwa [@Quotient.sound PSet _ _ _ h]
@[simp]
theorem mem_sep {p : ZFSet.{u} → Prop} {x y : ZFSet.{u}} :
    y ∈ ZFSet.sep p x ↔ y ∈ x ∧ p y :=
  Quotient.inductionOn₂ x y fun ⟨α, A⟩ y =>
    ⟨fun ⟨⟨a, pa⟩, h⟩ => ⟨⟨a, h⟩, by rwa [@Quotient.sound PSet _ _ _ h]⟩, fun ⟨⟨a, h⟩, pa⟩ =>
      ⟨⟨a, by
          

Proof state:
p : ZFSet → Prop
x y✝ : ZFSet
x✝¹ y : PSet
α : Type u
A : α → PSet
x✝ : ⟦y⟧ ∈ ⟦PSet.mk α A⟧ ∧ p ⟦y⟧
a : Type (PSet.mk α A)
h : PSet.Equiv y (Func (PSet.mk α A) a)
pa : p ⟦y⟧
⊢ (fun y => p (mk y)) (Func (PSet.mk α A) a)

Next tactic:
rw [mk_func] at h
@[simp]
theorem mem_sep {p : ZFSet.{u} → Prop} {x y : ZFSet.{u}} :
    y ∈ ZFSet.sep p x ↔ y ∈ x ∧ p y :=
  Quotient.inductionOn₂ x y fun ⟨α, A⟩ y =>
    ⟨fun ⟨⟨a, pa⟩, h⟩ => ⟨⟨a, h⟩, by rwa [@Quotient.sound PSet _ _ _ h]⟩, fun ⟨⟨a, h⟩, pa⟩ =>
      ⟨⟨a, by
          rw [mk_func] at h
          

Proof state:
p : ZFSet → Prop
x y✝ : ZFSet
x✝¹ y : PSet
α : Type u
A : α → PSet
x✝ : ⟦y⟧ ∈ ⟦PSet.mk α A⟧ ∧ p ⟦y⟧
a : Type (PSet.mk α A)
h : PSet.Equiv y (A a)
pa : p ⟦y⟧
⊢ p (mk (Func (PSet.mk α A) a))

Next tactic:
rwa [mk_func, ← ZFSet.sound h]
@[simp]
theorem toSet_sep (a : ZFSet) (p : ZFSet → Prop) :
    (ZFSet.sep p a).toSet = { x ∈ a.toSet | p x } := by
  

Proof state:
a : ZFSet
p : ZFSet → Prop
⊢ toSet (ZFSet.sep p a) = {x | x ∈ toSet a ∧ p x}

Next tactic:
ext
@[simp]
theorem toSet_sep (a : ZFSet) (p : ZFSet → Prop) :
    (ZFSet.sep p a).toSet = { x ∈ a.toSet | p x } := by
  ext
  

Proof state:
case h
a : ZFSet
p : ZFSet → Prop
x✝ : ZFSet
⊢ x✝ ∈ toSet (ZFSet.sep p a) ↔ x✝ ∈ {x | x ∈ toSet a ∧ p x}

Next tactic:
simp
@[simp]
theorem mem_powerset {x y : ZFSet.{u}} : y ∈ powerset x ↔ y ⊆ x :=
  Quotient.inductionOn₂ x y fun ⟨α, A⟩ ⟨β, B⟩ =>
    show (⟨β, B⟩ : PSet.{u}) ∈ PSet.powerset.{u} ⟨α, A⟩ ↔ _ by 

Proof state:
x y : ZFSet
x✝¹ x✝ : PSet
α : Type u
A : α → PSet
β : Type u
B : β → PSet
⊢ PSet.mk β B ∈ PSet.powerset (PSet.mk α A) ↔ ⟦PSet.mk β B⟧ ⊆ ⟦PSet.mk α A⟧

Next tactic:
simp [mem_powerset, subset_iff]
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    

Proof state:
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
let ⟨b, hb⟩ := αβ a
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    

Proof state:
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
b : β
hb : PSet.Equiv (A a) (B b)
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
induction' ea : A a with γ Γ
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    

Proof state:
case mk
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
b : β
hb : PSet.Equiv (A a) (B b)
γ : Type u
Γ : γ → PSet
A_ih✝ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
induction' eb : B b with δ Δ
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    

Proof state:
case mk.mk
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
b : β
hb : PSet.Equiv (A a) (B b)
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
rw [ea, eb] at hb
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    

Proof state:
case mk.mk
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
hb : PSet.Equiv (PSet.mk γ Γ) (PSet.mk δ Δ)
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
cases' hb with γδ δγ
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    cases' hb with γδ δγ
    

Proof state:
case mk.mk.intro
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
γδ : ∀ (a : γ), ∃ b, PSet.Equiv (Γ a) (Δ b)
δγ : ∀ (b : δ), ∃ a, PSet.Equiv (Γ a) (Δ b)
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
let c : (A a).Type := c
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    cases' hb with γδ δγ
    let c : (A a).Type := c
    

Proof state:
case mk.mk.intro
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c✝ : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
γδ : ∀ (a : γ), ∃ b, PSet.Equiv (Γ a) (Δ b)
δγ : ∀ (b : δ), ∃ a, PSet.Equiv (Γ a) (Δ b)
c : Type (A a) := c✝
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
let ⟨d, hd⟩ := γδ (by rwa [ea] at c)
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    cases' hb with γδ δγ
    let c : (A a).Type := c
    let ⟨d, hd⟩ := γδ (by 

Proof state:
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c✝ : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
γδ : ∀ (a : γ), ∃ b, PSet.Equiv (Γ a) (Δ b)
δγ : ∀ (b : δ), ∃ a, PSet.Equiv (Γ a) (Δ b)
c : Type (A a) := c✝
⊢ γ

Next tactic:
rwa [ea] at c
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    cases' hb with γδ δγ
    let c : (A a).Type := c
    let ⟨d, hd⟩ := γδ (by rwa [ea] at c)
    

Proof state:
case mk.mk.intro
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c✝ : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
γδ : ∀ (a : γ), ∃ b, PSet.Equiv (Γ a) (Δ b)
δγ : ∀ (b : δ), ∃ a, PSet.Equiv (Γ a) (Δ b)
c : Type (A a) := c✝
d : δ
hd : PSet.Equiv (Γ (Eq.mp (_ : Type (A a) = Type (PSet.mk γ Γ)) c)) (Δ d)
⊢ ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)

Next tactic:
use ⟨b, Eq.ndrec d (Eq.symm eb)⟩
theorem sUnion_lem {α β : Type u} (A : α → PSet) (B : β → PSet) (αβ : ∀ a, ∃ b, Equiv (A a) (B b)) :
    ∀ a, ∃ b, Equiv ((sUnion ⟨α, A⟩).Func a) ((sUnion ⟨β, B⟩).Func b)
  | ⟨a, c⟩ => by
    let ⟨b, hb⟩ := αβ a
    induction' ea : A a with γ Γ
    induction' eb : B b with δ Δ
    rw [ea, eb] at hb
    cases' hb with γδ δγ
    let c : (A a).Type := c
    let ⟨d, hd⟩ := γδ (by rwa [ea] at c)
    use ⟨b, Eq.ndrec d (Eq.symm eb)⟩
    

Proof state:
case h
α β : Type u
A : α → PSet
B : β → PSet
αβ : ∀ (a : α), ∃ b, PSet.Equiv (A a) (B b)
a : Type (PSet.mk α A)
c✝ : Type (Func (PSet.mk α A) a)
b : β
γ : Type u
Γ : γ → PSet
A_ih✝¹ :
  ∀ (a_1 : γ), A a = Γ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
ea : A a = PSet.mk γ Γ
δ : Type u
Δ : δ → PSet
A_ih✝ :
  ∀ (a_1 : δ), B b = Δ a_1 → ∃ b, PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ }) (Func (⋃₀ PSet.mk β B) b)
eb : B b = PSet.mk δ Δ
γδ : ∀ (a : γ), ∃ b, PSet.Equiv (Γ a) (Δ b)
δγ : ∀ (b : δ), ∃ a, PSet.Equiv (Γ a) (Δ b)
c : Type (A a) := c✝
d : δ
hd : PSet.Equiv (Γ (Eq.mp (_ : Type (A a) = Type (PSet.mk γ Γ)) c)) (Δ d)
⊢ PSet.Equiv (Func (⋃₀ PSet.mk α A) { fst := a, snd := c✝ })
    (Func (⋃₀ PSet.mk β B) { fst := b, snd := (_ : PSet.mk δ Δ = Func (PSet.mk β B) b) ▸ d })

Next tactic:
change PSet.Equiv ((A a).Func c) ((B b).Func (Eq.ndrec d eb.symm))