l3lab/ntp-mathlib huggingface dataset:
lemma exists_ideal_comap_le_prime (P : Ideal R) [P.IsPrime]
    (I : Ideal S) (hI : I.comap (algebraMap R S) ≤ P) :
    ∃ Q ≥ I, Q.IsPrime ∧ Q.comap (algebraMap R S) ≤ P := by
  let Sₚ := Localization (Algebra.algebraMapSubmonoid S P.primeCompl)
  let Iₚ := I.map (algebraMap S Sₚ)
  have hI' : Disjoint (Algebra.algebraMapSubmonoid S P.primeCompl : Set S) I
  · rw [Set.disjoint_iff]
    rintro _ ⟨⟨x, hx : x ∉ P, rfl⟩, hx'⟩
    exact (hx (hI hx')).elim
  have : Iₚ ≠ ⊤
  · rw [Ne.def, Ideal.eq_top_iff_one, IsLocalization.mem_map_algebraMap_iff
      (Algebra.algebraMapSubmonoid S P.primeCompl) Sₚ, not_exists]
    simp only [one_mul, IsLocalization.eq_iff_exists (Algebra.algebraMapSubmonoid S P.primeCompl),
      not_exists]
    exact fun x c ↦ hI'.ne_of_mem (mul_mem c.2 x.2.2) (I.mul_mem_left c x.1.2)
  obtain ⟨M, hM, hM'⟩ := Ideal.exists_le_maximal _ this
  refine ⟨_, Ideal.map_le_iff_le_comap.mp hM', hM.isPrime.comap _, ?_⟩
  intro x hx
  

Proof state:
case intro.intro
R : Type u_1
inst✝³ : CommRing R
S : Type u_2
inst✝² : CommRing S
f : R →+* S
I✝ J : Ideal S
inst✝¹ : Algebra R S
P : Ideal R
inst✝ : IsPrime P
I : Ideal S
hI : comap (algebraMap R S) I ≤ P
Sₚ : Type u_2 := Localization (Algebra.algebraMapSubmonoid S (primeCompl P))
Iₚ : Ideal Sₚ := map (algebraMap S Sₚ) I
hI' : Disjoint ↑(Algebra.algebraMapSubmonoid S (primeCompl P)) ↑I
this : Iₚ ≠ ⊤
M : Ideal Sₚ
hM : IsMaximal M
hM' : Iₚ ≤ M
x : R
hx : x ∈ comap (algebraMap R S) (comap (algebraMap S Sₚ) M)
⊢ x ∈ P

Next tactic:
by_contra hx'
lemma exists_ideal_comap_le_prime (P : Ideal R) [P.IsPrime]
    (I : Ideal S) (hI : I.comap (algebraMap R S) ≤ P) :
    ∃ Q ≥ I, Q.IsPrime ∧ Q.comap (algebraMap R S) ≤ P := by
  let Sₚ := Localization (Algebra.algebraMapSubmonoid S P.primeCompl)
  let Iₚ := I.map (algebraMap S Sₚ)
  have hI' : Disjoint (Algebra.algebraMapSubmonoid S P.primeCompl : Set S) I
  · rw [Set.disjoint_iff]
    rintro _ ⟨⟨x, hx : x ∉ P, rfl⟩, hx'⟩
    exact (hx (hI hx')).elim
  have : Iₚ ≠ ⊤
  · rw [Ne.def, Ideal.eq_top_iff_one, IsLocalization.mem_map_algebraMap_iff
      (Algebra.algebraMapSubmonoid S P.primeCompl) Sₚ, not_exists]
    simp only [one_mul, IsLocalization.eq_iff_exists (Algebra.algebraMapSubmonoid S P.primeCompl),
      not_exists]
    exact fun x c ↦ hI'.ne_of_mem (mul_mem c.2 x.2.2) (I.mul_mem_left c x.1.2)
  obtain ⟨M, hM, hM'⟩ := Ideal.exists_le_maximal _ this
  refine ⟨_, Ideal.map_le_iff_le_comap.mp hM', hM.isPrime.comap _, ?_⟩
  intro x hx
  by_contra hx'
  

Proof state:
case intro.intro
R : Type u_1
inst✝³ : CommRing R
S : Type u_2
inst✝² : CommRing S
f : R →+* S
I✝ J : Ideal S
inst✝¹ : Algebra R S
P : Ideal R
inst✝ : IsPrime P
I : Ideal S
hI : comap (algebraMap R S) I ≤ P
Sₚ : Type u_2 := Localization (Algebra.algebraMapSubmonoid S (primeCompl P))
Iₚ : Ideal Sₚ := map (algebraMap S Sₚ) I
hI' : Disjoint ↑(Algebra.algebraMapSubmonoid S (primeCompl P)) ↑I
this : Iₚ ≠ ⊤
M : Ideal Sₚ
hM : IsMaximal M
hM' : Iₚ ≤ M
x : R
hx : x ∈ comap (algebraMap R S) (comap (algebraMap S Sₚ) M)
hx' : x ∉ P
⊢ False

Next tactic:
exact Set.disjoint_left.mp ((IsLocalization.isPrime_iff_isPrime_disjoint
    (Algebra.algebraMapSubmonoid S P.primeCompl) Sₚ M).mp hM.isPrime).2 ⟨_, hx', rfl⟩ hx
theorem exists_ideal_over_prime_of_isIntegral (H : Algebra.IsIntegral R S) (P : Ideal R) [IsPrime P]
    (I : Ideal S) (hIP : I.comap (algebraMap R S) ≤ P) :
    ∃ Q ≥ I, IsPrime Q ∧ Q.comap (algebraMap R S) = P := by
  

Proof state:
R : Type u_1
inst✝³ : CommRing R
S : Type u_2
inst✝² : CommRing S
f : R →+* S
I✝ J : Ideal S
inst✝¹ : Algebra R S
H : Algebra.IsIntegral R S
P : Ideal R
inst✝ : IsPrime P
I : Ideal S
hIP : comap (algebraMap R S) I ≤ P
⊢ ∃ Q ≥ I, IsPrime Q ∧ comap (algebraMap R S) Q = P

Next tactic:
have ⟨P', hP, hP', hP''⟩ := exists_ideal_comap_le_prime P I hIP
theorem exists_ideal_over_prime_of_isIntegral (H : Algebra.IsIntegral R S) (P : Ideal R) [IsPrime P]
    (I : Ideal S) (hIP : I.comap (algebraMap R S) ≤ P) :
    ∃ Q ≥ I, IsPrime Q ∧ Q.comap (algebraMap R S) = P := by
  have ⟨P', hP, hP', hP''⟩ := exists_ideal_comap_le_prime P I hIP
  

Proof state:
R : Type u_1
inst✝³ : CommRing R
S : Type u_2
inst✝² : CommRing S
f : R →+* S
I✝ J : Ideal S
inst✝¹ : Algebra R S
H : Algebra.IsIntegral R S
P : Ideal R
inst✝ : IsPrime P
I : Ideal S
hIP : comap (algebraMap R S) I ≤ P
P' : Ideal S
hP : P' ≥ I
hP' : IsPrime P'
hP'' : comap (algebraMap R S) P' ≤ P
⊢ ∃ Q ≥ I, IsPrime Q ∧ comap (algebraMap R S) Q = P

Next tactic:
obtain ⟨Q, hQ, hQ', hQ''⟩ := exists_ideal_over_prime_of_isIntegral_of_isPrime H P P' hP''
theorem exists_ideal_over_prime_of_isIntegral (H : Algebra.IsIntegral R S) (P : Ideal R) [IsPrime P]
    (I : Ideal S) (hIP : I.comap (algebraMap R S) ≤ P) :
    ∃ Q ≥ I, IsPrime Q ∧ Q.comap (algebraMap R S) = P := by
  have ⟨P', hP, hP', hP''⟩ := exists_ideal_comap_le_prime P I hIP
  obtain ⟨Q, hQ, hQ', hQ''⟩ := exists_ideal_over_prime_of_isIntegral_of_isPrime H P P' hP''
  

Proof state:
case intro.intro.intro
R : Type u_1
inst✝³ : CommRing R
S : Type u_2
inst✝² : CommRing S
f : R →+* S
I✝ J : Ideal S
inst✝¹ : Algebra R S
H : Algebra.IsIntegral R S
P : Ideal R
inst✝ : IsPrime P
I : Ideal S
hIP : comap (algebraMap R S) I ≤ P
P' : Ideal S
hP : P' ≥ I
hP' : IsPrime P'
hP'' : comap (algebraMap R S) P' ≤ P
Q : Ideal S
hQ : Q ≥ P'
hQ' : IsPrime Q
hQ'' : comap (algebraMap R S) Q = P
⊢ ∃ Q ≥ I, IsPrime Q ∧ comap (algebraMap R S) Q = P

Next tactic:
exact ⟨Q, hP.trans hQ, hQ', hQ''⟩
/-- `comap (algebraMap R S)` is a surjection from the max spec of `S` to max spec of `R`.
`hP : (algebraMap R S).ker ≤ P` is a slight generalization of the extension being injective -/
theorem exists_ideal_over_maximal_of_isIntegral (H : Algebra.IsIntegral R S)
    (P : Ideal R) [P_max : IsMaximal P] (hP : RingHom.ker (algebraMap R S) ≤ P) :
    ∃ Q : Ideal S, IsMaximal Q ∧ Q.comap (algebraMap R S) = P := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f : R →+* S
I J : Ideal S
inst✝ : Algebra R S
H : Algebra.IsIntegral R S
P : Ideal R
P_max : IsMaximal P
hP : RingHom.ker (algebraMap R S) ≤ P
⊢ ∃ Q, IsMaximal Q ∧ comap (algebraMap R S) Q = P

Next tactic:
obtain ⟨Q, -, Q_prime, hQ⟩ := exists_ideal_over_prime_of_isIntegral H P ⊥ hP
/-- `comap (algebraMap R S)` is a surjection from the max spec of `S` to max spec of `R`.
`hP : (algebraMap R S).ker ≤ P` is a slight generalization of the extension being injective -/
theorem exists_ideal_over_maximal_of_isIntegral (H : Algebra.IsIntegral R S)
    (P : Ideal R) [P_max : IsMaximal P] (hP : RingHom.ker (algebraMap R S) ≤ P) :
    ∃ Q : Ideal S, IsMaximal Q ∧ Q.comap (algebraMap R S) = P := by
  obtain ⟨Q, -, Q_prime, hQ⟩ := exists_ideal_over_prime_of_isIntegral H P ⊥ hP
  

Proof state:
case intro.intro.intro
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f : R →+* S
I J : Ideal S
inst✝ : Algebra R S
H : Algebra.IsIntegral R S
P : Ideal R
P_max : IsMaximal P
hP : RingHom.ker (algebraMap R S) ≤ P
Q : Ideal S
Q_prime : IsPrime Q
hQ : comap (algebraMap R S) Q = P
⊢ ∃ Q, IsMaximal Q ∧ comap (algebraMap R S) Q = P

Next tactic:
exact ⟨Q, isMaximal_of_isIntegral_of_isMaximal_comap H _ (hQ.symm ▸ P_max), hQ⟩
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ map f I = ⊤ ↔ I = ⊤

Next tactic:
constructor
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; 

Proof state:
case mp
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ map f I = ⊤ → I = ⊤
case mpr
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ I = ⊤ → map f I = ⊤

Next tactic:
swap
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · 

Proof state:
case mpr
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ I = ⊤ → map f I = ⊤

Next tactic:
rintro rfl
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; 

Proof state:
case mpr
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I J : Ideal S
inst✝ : Algebra R S
f : R →+* S
hf₂ : RingHom.IsIntegral f
hf₁ : RingHom.ker f ≤ ⊤
⊢ map f ⊤ = ⊤

Next tactic:
exact Ideal.map_top _
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  

Proof state:
case mp
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ map f I = ⊤ → I = ⊤

Next tactic:
contrapose
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  

Proof state:
case mp
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
⊢ ¬I = ⊤ → ¬map f I = ⊤

Next tactic:
intro h
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  intro h
  

Proof state:
case mp
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
h : ¬I = ⊤
⊢ ¬map f I = ⊤

Next tactic:
obtain ⟨m, _, hm⟩ := Ideal.exists_le_maximal I h
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  intro h
  obtain ⟨m, _, hm⟩ := Ideal.exists_le_maximal I h
  

Proof state:
case mp.intro.intro
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
h : ¬I = ⊤
m : Ideal R
left✝ : IsMaximal m
hm : I ≤ m
⊢ ¬map f I = ⊤

Next tactic:
letI := f.toAlgebra
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  intro h
  obtain ⟨m, _, hm⟩ := Ideal.exists_le_maximal I h
  letI := f.toAlgebra
  

Proof state:
case mp.intro.intro
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
h : ¬I = ⊤
m : Ideal R
left✝ : IsMaximal m
hm : I ≤ m
this : Algebra R S := RingHom.toAlgebra f
⊢ ¬map f I = ⊤

Next tactic:
obtain ⟨m', _, rfl⟩ := exists_ideal_over_maximal_of_isIntegral hf₂ m (hf₁.trans hm)
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  intro h
  obtain ⟨m, _, hm⟩ := Ideal.exists_le_maximal I h
  letI := f.toAlgebra
  obtain ⟨m', _, rfl⟩ := exists_ideal_over_maximal_of_isIntegral hf₂ m (hf₁.trans hm)
  

Proof state:
case mp.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
h : ¬I = ⊤
this : Algebra R S := RingHom.toAlgebra f
m' : Ideal S
left✝¹ : IsMaximal m'
left✝ : IsMaximal (comap (algebraMap R S) m')
hm : I ≤ comap (algebraMap R S) m'
⊢ ¬map f I = ⊤

Next tactic:
rw [← map_le_iff_le_comap] at hm
lemma map_eq_top_iff_of_ker_le
    (f : R →+* S) {I : Ideal R} (hf₁ : RingHom.ker f ≤ I) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ := by
  constructor; swap
  · rintro rfl; exact Ideal.map_top _
  contrapose
  intro h
  obtain ⟨m, _, hm⟩ := Ideal.exists_le_maximal I h
  letI := f.toAlgebra
  obtain ⟨m', _, rfl⟩ := exists_ideal_over_maximal_of_isIntegral hf₂ m (hf₁.trans hm)
  rw [← map_le_iff_le_comap] at hm
  

Proof state:
case mp.intro.intro.intro.intro
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : RingHom.ker f ≤ I
hf₂ : RingHom.IsIntegral f
h : ¬I = ⊤
this : Algebra R S := RingHom.toAlgebra f
m' : Ideal S
left✝¹ : IsMaximal m'
left✝ : IsMaximal (comap (algebraMap R S) m')
hm : map (algebraMap R S) I ≤ m'
⊢ ¬map f I = ⊤

Next tactic:
exact (hm.trans_lt (lt_top_iff_ne_top.mpr (IsMaximal.ne_top ‹_›))).ne
lemma map_eq_top_iff
    (f : R →+* S) {I : Ideal R} (hf₁ : Function.Injective f) (hf₂ : f.IsIntegral) :
    I.map f = ⊤ ↔ I = ⊤ :=
  map_eq_top_iff_of_ker_le f (by 

Proof state:
R : Type u_1
inst✝² : CommRing R
S : Type u_2
inst✝¹ : CommRing S
f✝ : R →+* S
I✝ J : Ideal S
inst✝ : Algebra R S
f : R →+* S
I : Ideal R
hf₁ : Function.Injective ⇑f
hf₂ : RingHom.IsIntegral f
⊢ RingHom.ker f ≤ I

Next tactic:
simp [f.injective_iff_ker_eq_bot.mp hf₁]
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by 

Proof state:
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
f : Except ε α✝
⊢ Except.map (⇑e.symm) (Except.map (⇑e) f) = f

Next tactic:
cases f
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by cases f <;> 

Proof state:
case error
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
a✝ : ε
⊢ Except.map (⇑e.symm) (Except.map (⇑e) (error a✝)) = error a✝

Next tactic:
simp [Except.map]
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by cases f <;> 

Proof state:
case ok
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
a✝ : α✝
⊢ Except.map (⇑e.symm) (Except.map (⇑e) (ok a✝)) = ok a✝

Next tactic:
simp [Except.map]
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by cases f <;> simp [Except.map]
      right_inv := fun f => by 

Proof state:
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
f : Except ε β✝
⊢ Except.map (⇑e) (Except.map (⇑e.symm) f) = f

Next tactic:
cases f
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by cases f <;> simp [Except.map]
      right_inv := fun f => by cases f <;> 

Proof state:
case error
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
a✝ : ε
⊢ Except.map (⇑e) (Except.map (⇑e.symm) (error a✝)) = error a✝

Next tactic:
simp [Except.map]
instance Except.instULiftable {ε : Type u₀} : ULiftable (Except.{u₀,v₁} ε) (Except.{u₀,v₂} ε) where
  congr e :=
    { toFun := Except.map e
      invFun := Except.map e.symm
      left_inv := fun f => by cases f <;> simp [Except.map]
      right_inv := fun f => by cases f <;> 

Proof state:
case ok
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
ε : Type u₀
α✝ : Type v₁
β✝ : Type v₂
e : α✝ ≃ β✝
a✝ : β✝
⊢ Except.map (⇑e) (Except.map (⇑e.symm) (ok a✝)) = ok a✝

Next tactic:
simp [Except.map]
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by 

Proof state:
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
f : Option α✝
⊢ Option.map (⇑e.symm) (Option.map (⇑e) f) = f

Next tactic:
cases f
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by cases f <;> 

Proof state:
case none
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
⊢ Option.map (⇑e.symm) (Option.map (⇑e) none) = none

Next tactic:
simp
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by cases f <;> 

Proof state:
case some
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
val✝ : α✝
⊢ Option.map (⇑e.symm) (Option.map (⇑e) (some val✝)) = some val✝

Next tactic:
simp
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by cases f <;> simp
      right_inv := fun f => by 

Proof state:
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
f : Option β✝
⊢ Option.map (⇑e) (Option.map (⇑e.symm) f) = f

Next tactic:
cases f
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by cases f <;> simp
      right_inv := fun f => by cases f <;> 

Proof state:
case none
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
⊢ Option.map (⇑e) (Option.map (⇑e.symm) none) = none

Next tactic:
simp
instance Option.instULiftable : ULiftable Option.{u₀} Option.{u₁} where
  congr e :=
    { toFun := Option.map e
      invFun := Option.map e.symm
      left_inv := fun f => by cases f <;> simp
      right_inv := fun f => by cases f <;> 

Proof state:
case some
s : Type u₀
s' : Type u₁
r : Type u_1
r' : Type u_2
w : Type u_3
w' : Type u_4
α✝ : Type u₀
β✝ : Type u₁
e : α✝ ≃ β✝
val✝ : β✝
⊢ Option.map (⇑e) (Option.map (⇑e.symm) (some val✝)) = some val✝

Next tactic:
simp
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A : IndexSet Δ
⊢ X.obj Δ ⟶ N s (SimplexCategory.len A.fst.unop)

Next tactic:
refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A B : IndexSet Δ
⊢ summand s.N Δ B ⟶ N s (SimplexCategory.len A.fst.unop)

Next tactic:
by_cases h : B = A
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
  by_cases h : B = A
  · 

Proof state:
case pos
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A B : IndexSet Δ
h : B = A
⊢ summand s.N Δ B ⟶ N s (SimplexCategory.len A.fst.unop)

Next tactic:
exact eqToHom (by subst h; rfl)
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
  by_cases h : B = A
  · exact eqToHom (by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A B : IndexSet Δ
h : B = A
⊢ summand s.N Δ B = N s (SimplexCategory.len A.fst.unop)

Next tactic:
subst h
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
  by_cases h : B = A
  · exact eqToHom (by subst h; 

Proof state:
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
B : IndexSet Δ
⊢ summand s.N Δ B = N s (SimplexCategory.len B.fst.unop)

Next tactic:
rfl
/-- The projection on a summand of the coproduct decomposition given
by a splitting of a simplicial object. -/
noncomputable def πSummand [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    X.obj Δ ⟶ s.N A.1.unop.len := by
  refine' (s.iso Δ).inv ≫ Sigma.desc fun B => _
  by_cases h : B = A
  · exact eqToHom (by subst h; rfl)
  · 

Proof state:
case neg
C : Type u_1
inst✝² : Category.{?u.257, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A B : IndexSet Δ
h : ¬B = A
⊢ summand s.N Δ B ⟶ N s (SimplexCategory.len A.fst.unop)

Next tactic:
exact 0
@[reassoc (attr := simp)]
theorem ι_πSummand_eq_id [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    s.ιSummand A ≫ s.πSummand A = 𝟙 _ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A : IndexSet Δ
⊢ ιSummand s A ≫ πSummand s A = 𝟙 (N s (SimplexCategory.len A.fst.unop))

Next tactic:
dsimp only [ιSummand, iso_hom, πSummand, iso_inv, summand]
@[reassoc (attr := simp)]
theorem ι_πSummand_eq_id [HasZeroMorphisms C] {Δ : SimplexCategoryᵒᵖ} (A : IndexSet Δ) :
    s.ιSummand A ≫ s.πSummand A = 𝟙 _ := by
  dsimp only [ιSummand, iso_hom, πSummand, iso_inv, summand]
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasFiniteCoproducts C
X : SimplicialObject C
s : Splitting X
inst✝ : HasZeroMorphisms C
Δ : SimplexCategoryᵒᵖ
A : IndexSet Δ
⊢ ((ιCoprod s.N A ≫ map X s.ι Δ) ≫
      inv (map X s.ι Δ) ≫
        Sigma.desc fun B =>
          if h : B = A then eqToHom (_ : summand s.N Δ B = N s (SimplexCategory.len A.fst.unop)) else 0) =
    𝟙 (N s (SimplexCategory.len A.fst.unop))

Next tactic:
simp only [summand, assoc, IsIso.hom_inv_id_assoc]