l3lab/ntp-mathlib huggingface dataset:
lemma Functor.toSheafify_pullbackSheafificationCompatibility (F : Dᵒᵖ ⥤ A) :
    J.toSheafify (G.op ⋙ F) ≫
    ((G.pushforwardContinuousSheafificationCompatibility A J K).hom.app F).val =
    whiskerLeft _ (K.toSheafify _) := by
  dsimp [pushforwardContinuousSheafificationCompatibility, Adjunction.leftAdjointUniq]
  apply Quiver.Hom.op_inj
  apply coyoneda.map_injective
  ext E : 2
  dsimp [Functor.preimage, Full.preimage, coyoneda, Adjunction.leftAdjointsCoyonedaEquiv]
  erw [Adjunction.homEquiv_unit, Adjunction.homEquiv_counit]
  dsimp [Adjunction.comp]
  simp only [sheafificationAdjunction_unit_app, Category.comp_id, Functor.map_id,
    whiskerLeft_id', GrothendieckTopology.sheafifyMap_comp,
    GrothendieckTopology.sheafifyMap_sheafifyLift, Category.id_comp,
    Category.assoc, GrothendieckTopology.toSheafify_sheafifyLift]
  ext t s : 3
  dsimp [sheafPushforwardContinuous]
  congr 1
  simp only [← Category.assoc]
  convert Category.id_comp (obj := A) _
  

Proof state:
case h.e'_2.h.h.e'_6
C D : Type u
inst✝¹³ : Category.{v, u} C
inst✝¹² : Category.{v, u} D
G : C ⥤ D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : HasLimits A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝⁹ : IsCocontinuous G J K
inst✝⁸ : ConcreteCategory A
inst✝⁷ : PreservesLimits (forget A)
inst✝⁶ : ReflectsIsomorphisms (forget A)
inst✝⁵ : (X : C) → PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝⁴ : ∀ (X : C), HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝³ : (X : D) → PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝² : ∀ (X : D), HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
inst✝¹ : IsCocontinuous G J K
inst✝ : IsContinuous G J K
F : Dᵒᵖ ⥤ A
E : Cᵒᵖ ⥤ A
t : ((sheafPushforwardContinuous G A J K).obj ((presheafToSheaf K A).obj F)).val ⟶ E
s : Cᵒᵖ
⊢ ((Ran.adjunction A G.op).unit.app (GrothendieckTopology.sheafify K F)).app (op (G.obj s.unop)) ≫
      ((Ran.adjunction A G.op).counit.app (G.op ⋙ GrothendieckTopology.sheafify K F)).app s =
    𝟙 ((GrothendieckTopology.sheafify K F).obj (op (G.obj s.unop)))

Next tactic:
have := (Ran.adjunction A G.op).left_triangle
lemma Functor.toSheafify_pullbackSheafificationCompatibility (F : Dᵒᵖ ⥤ A) :
    J.toSheafify (G.op ⋙ F) ≫
    ((G.pushforwardContinuousSheafificationCompatibility A J K).hom.app F).val =
    whiskerLeft _ (K.toSheafify _) := by
  dsimp [pushforwardContinuousSheafificationCompatibility, Adjunction.leftAdjointUniq]
  apply Quiver.Hom.op_inj
  apply coyoneda.map_injective
  ext E : 2
  dsimp [Functor.preimage, Full.preimage, coyoneda, Adjunction.leftAdjointsCoyonedaEquiv]
  erw [Adjunction.homEquiv_unit, Adjunction.homEquiv_counit]
  dsimp [Adjunction.comp]
  simp only [sheafificationAdjunction_unit_app, Category.comp_id, Functor.map_id,
    whiskerLeft_id', GrothendieckTopology.sheafifyMap_comp,
    GrothendieckTopology.sheafifyMap_sheafifyLift, Category.id_comp,
    Category.assoc, GrothendieckTopology.toSheafify_sheafifyLift]
  ext t s : 3
  dsimp [sheafPushforwardContinuous]
  congr 1
  simp only [← Category.assoc]
  convert Category.id_comp (obj := A) _
  have := (Ran.adjunction A G.op).left_triangle
  

Proof state:
case h.e'_2.h.h.e'_6
C D : Type u
inst✝¹³ : Category.{v, u} C
inst✝¹² : Category.{v, u} D
G : C ⥤ D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : HasLimits A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝⁹ : IsCocontinuous G J K
inst✝⁸ : ConcreteCategory A
inst✝⁷ : PreservesLimits (forget A)
inst✝⁶ : ReflectsIsomorphisms (forget A)
inst✝⁵ : (X : C) → PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝⁴ : ∀ (X : C), HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝³ : (X : D) → PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝² : ∀ (X : D), HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
inst✝¹ : IsCocontinuous G J K
inst✝ : IsContinuous G J K
F : Dᵒᵖ ⥤ A
E : Cᵒᵖ ⥤ A
t : ((sheafPushforwardContinuous G A J K).obj ((presheafToSheaf K A).obj F)).val ⟶ E
s : Cᵒᵖ
this :
  whiskerRight (Ran.adjunction A G.op).unit ((whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op) ≫
      whiskerLeft ((whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op) (Ran.adjunction A G.op).counit =
    𝟙 (𝟭 (Dᵒᵖ ⥤ A) ⋙ (whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op)
⊢ ((Ran.adjunction A G.op).unit.app (GrothendieckTopology.sheafify K F)).app (op (G.obj s.unop)) ≫
      ((Ran.adjunction A G.op).counit.app (G.op ⋙ GrothendieckTopology.sheafify K F)).app s =
    𝟙 ((GrothendieckTopology.sheafify K F).obj (op (G.obj s.unop)))

Next tactic:
apply_fun (fun e => (e.app (K.sheafify F)).app s) at this
lemma Functor.toSheafify_pullbackSheafificationCompatibility (F : Dᵒᵖ ⥤ A) :
    J.toSheafify (G.op ⋙ F) ≫
    ((G.pushforwardContinuousSheafificationCompatibility A J K).hom.app F).val =
    whiskerLeft _ (K.toSheafify _) := by
  dsimp [pushforwardContinuousSheafificationCompatibility, Adjunction.leftAdjointUniq]
  apply Quiver.Hom.op_inj
  apply coyoneda.map_injective
  ext E : 2
  dsimp [Functor.preimage, Full.preimage, coyoneda, Adjunction.leftAdjointsCoyonedaEquiv]
  erw [Adjunction.homEquiv_unit, Adjunction.homEquiv_counit]
  dsimp [Adjunction.comp]
  simp only [sheafificationAdjunction_unit_app, Category.comp_id, Functor.map_id,
    whiskerLeft_id', GrothendieckTopology.sheafifyMap_comp,
    GrothendieckTopology.sheafifyMap_sheafifyLift, Category.id_comp,
    Category.assoc, GrothendieckTopology.toSheafify_sheafifyLift]
  ext t s : 3
  dsimp [sheafPushforwardContinuous]
  congr 1
  simp only [← Category.assoc]
  convert Category.id_comp (obj := A) _
  have := (Ran.adjunction A G.op).left_triangle
  apply_fun (fun e => (e.app (K.sheafify F)).app s) at this
  

Proof state:
case h.e'_2.h.h.e'_6
C D : Type u
inst✝¹³ : Category.{v, u} C
inst✝¹² : Category.{v, u} D
G : C ⥤ D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : HasLimits A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝⁹ : IsCocontinuous G J K
inst✝⁸ : ConcreteCategory A
inst✝⁷ : PreservesLimits (forget A)
inst✝⁶ : ReflectsIsomorphisms (forget A)
inst✝⁵ : (X : C) → PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝⁴ : ∀ (X : C), HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝³ : (X : D) → PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝² : ∀ (X : D), HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
inst✝¹ : IsCocontinuous G J K
inst✝ : IsContinuous G J K
F : Dᵒᵖ ⥤ A
E : Cᵒᵖ ⥤ A
t : ((sheafPushforwardContinuous G A J K).obj ((presheafToSheaf K A).obj F)).val ⟶ E
s : Cᵒᵖ
this :
  ((whiskerRight (Ran.adjunction A G.op).unit ((whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op) ≫
              whiskerLeft ((whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op) (Ran.adjunction A G.op).counit).app
          (GrothendieckTopology.sheafify K F)).app
      s =
    ((𝟙 (𝟭 (Dᵒᵖ ⥤ A) ⋙ (whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op)).app (GrothendieckTopology.sheafify K F)).app s
⊢ ((Ran.adjunction A G.op).unit.app (GrothendieckTopology.sheafify K F)).app (op (G.obj s.unop)) ≫
      ((Ran.adjunction A G.op).counit.app (G.op ⋙ GrothendieckTopology.sheafify K F)).app s =
    𝟙 ((GrothendieckTopology.sheafify K F).obj (op (G.obj s.unop)))

Next tactic:
exact this
@[simp]
lemma Functor.pushforwardContinuousSheafificationCompatibility_hom_app_val (F : Dᵒᵖ ⥤ A) :
    ((G.pushforwardContinuousSheafificationCompatibility A J K).hom.app F).val =
    J.sheafifyLift (whiskerLeft G.op <| K.toSheafify F)
      ((presheafToSheaf K A ⋙ G.sheafPushforwardContinuous A J K).obj F).cond := by
  

Proof state:
C D : Type u
inst✝¹³ : Category.{v, u} C
inst✝¹² : Category.{v, u} D
G : C ⥤ D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : HasLimits A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝⁹ : IsCocontinuous G J K
inst✝⁸ : ConcreteCategory A
inst✝⁷ : PreservesLimits (forget A)
inst✝⁶ : ReflectsIsomorphisms (forget A)
inst✝⁵ : (X : C) → PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝⁴ : ∀ (X : C), HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝³ : (X : D) → PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝² : ∀ (X : D), HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
inst✝¹ : IsCocontinuous G J K
inst✝ : IsContinuous G J K
F : Dᵒᵖ ⥤ A
⊢ ((pushforwardContinuousSheafificationCompatibility G A J K).hom.app F).val =
    GrothendieckTopology.sheafifyLift J (whiskerLeft G.op (GrothendieckTopology.toSheafify K F))
      (_ : Presheaf.IsSheaf J ((presheafToSheaf K A ⋙ sheafPushforwardContinuous G A J K).obj F).val)

Next tactic:
apply J.sheafifyLift_unique
@[simp]
lemma Functor.pushforwardContinuousSheafificationCompatibility_hom_app_val (F : Dᵒᵖ ⥤ A) :
    ((G.pushforwardContinuousSheafificationCompatibility A J K).hom.app F).val =
    J.sheafifyLift (whiskerLeft G.op <| K.toSheafify F)
      ((presheafToSheaf K A ⋙ G.sheafPushforwardContinuous A J K).obj F).cond := by
  apply J.sheafifyLift_unique
  

Proof state:
case a
C D : Type u
inst✝¹³ : Category.{v, u} C
inst✝¹² : Category.{v, u} D
G : C ⥤ D
A : Type w
inst✝¹¹ : Category.{max u v, w} A
inst✝¹⁰ : HasLimits A
J : GrothendieckTopology C
K : GrothendieckTopology D
inst✝⁹ : IsCocontinuous G J K
inst✝⁸ : ConcreteCategory A
inst✝⁷ : PreservesLimits (forget A)
inst✝⁶ : ReflectsIsomorphisms (forget A)
inst✝⁵ : (X : C) → PreservesColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ (forget A)
inst✝⁴ : ∀ (X : C), HasColimitsOfShape (GrothendieckTopology.Cover J X)ᵒᵖ A
inst✝³ : (X : D) → PreservesColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ (forget A)
inst✝² : ∀ (X : D), HasColimitsOfShape (GrothendieckTopology.Cover K X)ᵒᵖ A
inst✝¹ : IsCocontinuous G J K
inst✝ : IsContinuous G J K
F : Dᵒᵖ ⥤ A
⊢ GrothendieckTopology.toSheafify J (((whiskeringLeft Cᵒᵖ Dᵒᵖ A).obj G.op).obj F) ≫
      ((pushforwardContinuousSheafificationCompatibility G A J K).hom.app F).val =
    whiskerLeft G.op (GrothendieckTopology.toSheafify K F)

Next tactic:
apply toSheafify_pullbackSheafificationCompatibility
theorem elim_injective (γ : Type*) (fγ : (Σa : α, β a → γ) → γ)
    (fγ_injective : Function.Injective fγ) : Function.Injective (elim γ fγ)
  | ⟨a₁, f₁⟩, ⟨a₂, f₂⟩, h => by
    

Proof state:
α : Type u_1
β : α → Type u_2
γ : Type u_3
fγ : (a : α) × (β a → γ) → γ
fγ_injective : Function.Injective fγ
a₁ : α
f₁ : β a₁ → WType fun a => β a
a₂ : α
f₂ : β a₂ → WType fun a => β a
h : elim γ fγ (mk a₁ f₁) = elim γ fγ (mk a₂ f₂)
⊢ mk a₁ f₁ = mk a₂ f₂

Next tactic:
obtain ⟨rfl, h⟩ := Sigma.mk.inj_iff.mp (fγ_injective h)
theorem elim_injective (γ : Type*) (fγ : (Σa : α, β a → γ) → γ)
    (fγ_injective : Function.Injective fγ) : Function.Injective (elim γ fγ)
  | ⟨a₁, f₁⟩, ⟨a₂, f₂⟩, h => by
    obtain ⟨rfl, h⟩ := Sigma.mk.inj_iff.mp (fγ_injective h)
    

Proof state:
case intro
α : Type u_1
β : α → Type u_2
γ : Type u_3
fγ : (a : α) × (β a → γ) → γ
fγ_injective : Function.Injective fγ
a₁ : α
f₁ f₂ : β a₁ → WType fun a => β a
h✝ : elim γ fγ (mk a₁ f₁) = elim γ fγ (mk a₁ f₂)
h : HEq (fun b => elim γ fγ (f₁ b)) fun b => elim γ fγ (f₂ b)
⊢ mk a₁ f₁ = mk a₁ f₂

Next tactic:
congr with x
theorem elim_injective (γ : Type*) (fγ : (Σa : α, β a → γ) → γ)
    (fγ_injective : Function.Injective fγ) : Function.Injective (elim γ fγ)
  | ⟨a₁, f₁⟩, ⟨a₂, f₂⟩, h => by
    obtain ⟨rfl, h⟩ := Sigma.mk.inj_iff.mp (fγ_injective h)
    congr with x
    

Proof state:
case intro.e_f.h
α : Type u_1
β : α → Type u_2
γ : Type u_3
fγ : (a : α) × (β a → γ) → γ
fγ_injective : Function.Injective fγ
a₁ : α
f₁ f₂ : β a₁ → WType fun a => β a
h✝ : elim γ fγ (mk a₁ f₁) = elim γ fγ (mk a₁ f₂)
h : HEq (fun b => elim γ fγ (f₁ b)) fun b => elim γ fγ (f₂ b)
x : β a₁
⊢ f₁ x = f₂ x

Next tactic:
exact elim_injective γ fγ fγ_injective (congr_fun (eq_of_heq h) x : _)
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    

Proof state:
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
⊢ ¬Finite (WType β)

Next tactic:
intro hf
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    

Proof state:
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
⊢ False

Next tactic:
have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    

Proof state:
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
⊢ False

Next tactic:
refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    

Proof state:
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
⊢ Function.Injective fun n =>
    let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
    this

Next tactic:
intro n m h
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    

Proof state:
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
n m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      n =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      m
⊢ n = m

Next tactic:
induction' n with n ih generalizing m
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · 

Proof state:
case zero
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      Nat.zero =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      m
⊢ Nat.zero = m

Next tactic:
cases' m with m
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> 

Proof state:
case zero.zero
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      Nat.zero =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      Nat.zero
⊢ Nat.zero = Nat.zero

Next tactic:
simp_all
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> 

Proof state:
case zero.succ
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      Nat.zero =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ m)
⊢ Nat.zero = Nat.succ m

Next tactic:
simp_all
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> simp_all
    · 

Proof state:
case succ
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
n : ℕ
ih :
  ∀ ⦃m : ℕ⦄,
    (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          n =
        (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          m →
      n = m
m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ n) =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      m
⊢ Nat.succ n = m

Next tactic:
cases' m with m
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> simp_all
    · cases' m with m
      · 

Proof state:
case succ.zero
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
n : ℕ
ih :
  ∀ ⦃m : ℕ⦄,
    (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          n =
        (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          m →
      n = m
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ n) =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      Nat.zero
⊢ Nat.succ n = Nat.zero

Next tactic:
simp_all
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> simp_all
    · cases' m with m
      · simp_all
      · 

Proof state:
case succ.succ
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
n : ℕ
ih :
  ∀ ⦃m : ℕ⦄,
    (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          n =
        (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          m →
      n = m
m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ n) =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ m)
⊢ Nat.succ n = Nat.succ m

Next tactic:
refine' congr_arg Nat.succ (ih _)
theorem infinite_of_nonempty_of_isEmpty (a b : α) [ha : Nonempty (β a)] [he : IsEmpty (β b)] :
    Infinite (WType β) :=
  ⟨by
    intro hf
    have hba : b ≠ a := fun h => ha.elim (IsEmpty.elim' (show IsEmpty (β a) from h ▸ he))
    refine'
      not_injective_infinite_finite
        (fun n : ℕ =>
          show WType β from Nat.recOn n ⟨b, IsEmpty.elim' he⟩ fun _ ih => ⟨a, fun _ => ih⟩)
        _
    intro n m h
    induction' n with n ih generalizing m
    · cases' m with m <;> simp_all
    · cases' m with m
      · simp_all
      · refine' congr_arg Nat.succ (ih _)
        

Proof state:
case succ.succ
α : Type u_1
β : α → Type u_2
a b : α
ha : Nonempty (β a)
he : IsEmpty (β b)
hf : Finite (WType β)
hba : b ≠ a
n : ℕ
ih :
  ∀ ⦃m : ℕ⦄,
    (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          n =
        (fun n =>
            let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
            this)
          m →
      n = m
m : ℕ
h :
  (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ n) =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      (Nat.succ m)
⊢ (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      n =
    (fun n =>
        let_fun this := Nat.recOn n (mk b (IsEmpty.elim' he)) fun x ih => mk a fun x => ih;
        this)
      m

Next tactic:
simp_all [Function.funext_iff]
theorem depth_pos (t : WType β) : 0 < t.depth := by
  

Proof state:
α : Type u_1
β : α → Type u_2
inst✝ : (a : α) → Fintype (β a)
t : WType β
⊢ 0 < depth t

Next tactic:
cases t
theorem depth_pos (t : WType β) : 0 < t.depth := by
  cases t
  

Proof state:
case mk
α : Type u_1
β : α → Type u_2
inst✝ : (a : α) → Fintype (β a)
a✝ : α
f✝ : β a✝ → WType β
⊢ 0 < depth (mk a✝ f✝)

Next tactic:
apply Nat.succ_pos
private def encodable_zero : Encodable (WType' β 0) :=
  let f : WType' β 0 → Empty := fun ⟨x, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _)
  let finv : Empty → WType' β 0 := by
    

Proof state:
α : Type u_1
β : α → Type u_2
inst✝¹ : (a : α) → Fintype (β a)
inst✝ : (a : α) → Encodable (β a)
f : WType.WType' β 0 → Empty :=
  fun x =>
    match x with
    | { val := x, property := h } => (_ : False).elim
⊢ Empty → WType.WType' β 0

Next tactic:
intro x
private def encodable_zero : Encodable (WType' β 0) :=
  let f : WType' β 0 → Empty := fun ⟨x, h⟩ => False.elim <| not_lt_of_ge h (WType.depth_pos _)
  let finv : Empty → WType' β 0 := by
    intro x
    

Proof state:
α : Type u_1
β : α → Type u_2
inst✝¹ : (a : α) → Fintype (β a)
inst✝ : (a : α) → Encodable (β a)
f : WType.WType' β 0 → Empty :=
  fun x =>
    match x with
    | { val := x, property := h } => (_ : False).elim
x : Empty
⊢ WType.WType' β 0

Next tactic:
cases x