l3lab/ntp-mathlib huggingface dataset:
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · 

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this✝ : IsRightAdjoint R'
this : IsRightAdjoint (R' ⋙ Functor.inv (Monad.comparison (Adjunction.ofRightAdjoint U))) := inferInstance
⊢ IsRightAdjoint R

Next tactic:
let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this✝¹ : IsRightAdjoint R'
this✝ : IsRightAdjoint (R' ⋙ Functor.inv (Monad.comparison (Adjunction.ofRightAdjoint U))) := inferInstance
this : R' ⋙ Functor.inv (Monad.comparison (Adjunction.ofRightAdjoint U)) ≅ R :=
  isoWhiskerLeft R (Functor.asEquivalence (Monad.comparison (Adjunction.ofRightAdjoint U))).unitIso.symm ≪≫
    Functor.rightUnitor R
⊢ IsRightAdjoint R

Next tactic:
exact Adjunction.rightAdjointOfNatIso this
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
⊢ IsRightAdjoint R'

Next tactic:
let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
  

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) :=
  Adjunction.rightAdjointOfNatIso (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm)
⊢ IsRightAdjoint R'

Next tactic:
let this : ∀ X, RegularEpi ((Monad.adj (Adjunction.ofRightAdjoint U).toMonad).counit.app X) := by
    intro X
    simp only [Monad.adj_counit]
    exact ⟨_, _, _, _, Monad.beckAlgebraCoequalizer X⟩
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
  let this : ∀ X, RegularEpi ((Monad.adj (Adjunction.ofRightAdjoint U).toMonad).counit.app X) := by
    

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) :=
  Adjunction.rightAdjointOfNatIso (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm)
⊢ (X : Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) →
    RegularEpi ((Monad.adj (Adjunction.toMonad (Adjunction.ofRightAdjoint U))).counit.app X)

Next tactic:
intro X
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
  let this : ∀ X, RegularEpi ((Monad.adj (Adjunction.ofRightAdjoint U).toMonad).counit.app X) := by
    intro X
    

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) :=
  Adjunction.rightAdjointOfNatIso (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm)
X : Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U))
⊢ RegularEpi ((Monad.adj (Adjunction.toMonad (Adjunction.ofRightAdjoint U))).counit.app X)

Next tactic:
simp only [Monad.adj_counit]
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
  let this : ∀ X, RegularEpi ((Monad.adj (Adjunction.ofRightAdjoint U).toMonad).counit.app X) := by
    intro X
    simp only [Monad.adj_counit]
    

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) :=
  Adjunction.rightAdjointOfNatIso (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm)
X : Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U))
⊢ RegularEpi (Monad.Algebra.Hom.mk X.a)

Next tactic:
exact ⟨_, _, _, _, Monad.beckAlgebraCoequalizer X⟩
/-- If `R ⋙ U` has a left adjoint, the domain of `R` has reflexive coequalizers and `U` is a monadic
functor, then `R` has a left adjoint.
This is a special case of `adjointTriangleLift` which is often more useful in practice.
-/
noncomputable def monadicAdjointTriangleLift (U : B ⥤ C) [MonadicRightAdjoint U] {R : A ⥤ B}
    [HasReflexiveCoequalizers A] [IsRightAdjoint (R ⋙ U)] : IsRightAdjoint R := by
  let R' : A ⥤ _ := R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
  rsuffices : IsRightAdjoint R'
  · let this : IsRightAdjoint (R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv) := by
      infer_instance
    · let this : R' ⋙ (Monad.comparison (Adjunction.ofRightAdjoint U)).inv ≅ R :=
        (isoWhiskerLeft R (Monad.comparison _).asEquivalence.unitIso.symm : _) ≪≫ R.rightUnitor
      exact Adjunction.rightAdjointOfNatIso this
  let this : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.ofRightAdjoint U).toMonad) :=
    Adjunction.rightAdjointOfNatIso
      (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm : _)
  let this : ∀ X, RegularEpi ((Monad.adj (Adjunction.ofRightAdjoint U).toMonad).counit.app X) := by
    intro X
    simp only [Monad.adj_counit]
    exact ⟨_, _, _, _, Monad.beckAlgebraCoequalizer X⟩
  

Proof state:
A : Type u₁
B : Type u₂
C : Type u₃
inst✝⁵ : Category.{v₁, u₁} A
inst✝⁴ : Category.{v₂, u₂} B
inst✝³ : Category.{v₃, u₃} C
U : B ⥤ C
inst✝² : MonadicRightAdjoint U
R : A ⥤ B
inst✝¹ : HasReflexiveCoequalizers A
inst✝ : IsRightAdjoint (R ⋙ U)
R' : A ⥤ Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U)) :=
  R ⋙ Monad.comparison (Adjunction.ofRightAdjoint U)
this✝ : IsRightAdjoint (R' ⋙ Monad.forget (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) :=
  Adjunction.rightAdjointOfNatIso (isoWhiskerLeft R (Monad.comparisonForget (Adjunction.ofRightAdjoint U)).symm)
this : (X : Monad.Algebra (Adjunction.toMonad (Adjunction.ofRightAdjoint U))) →
  RegularEpi ((Monad.adj (Adjunction.toMonad (Adjunction.ofRightAdjoint U))).counit.app X) :=
  fun X =>
    Eq.mpr
      (_ :
        RegularEpi ((Monad.adj (Adjunction.toMonad (Adjunction.ofRightAdjoint U))).counit.app X) =
          RegularEpi (Monad.Algebra.Hom.mk X.a))
      (RegularEpi.mk
        ((Monad.free (Adjunction.toMonad (Adjunction.ofRightAdjoint U))).obj
          ((Adjunction.toMonad (Adjunction.ofRightAdjoint U)).toFunctor.obj X.A))
        (Monad.FreeCoequalizer.topMap X) (Monad.FreeCoequalizer.bottomMap X) (Monad.beckAlgebraCoequalizer X))
⊢ IsRightAdjoint R'

Next tactic:
exact adjointTriangleLift R' (Monad.adj _)
lemma CharP.cast_int_eq_mod (R : Type _) [Ring R] (p : ℕ) [CharP R p] (k : ℤ) :
    (k : R) = (k % p : ℤ) := by
  

Proof state:
R : Type u_1
inst✝¹ : Ring R
p : ℕ
inst✝ : CharP R p
k : ℤ
⊢ ↑k = ↑(k % ↑p)

Next tactic:
calc
    (k : R) = ↑(k % p + p * (k / p)) := by rw [Int.emod_add_ediv]
    _ = ↑(k % p) := by simp [CharP.cast_eq_zero R]
lemma CharP.cast_int_eq_mod (R : Type _) [Ring R] (p : ℕ) [CharP R p] (k : ℤ) :
    (k : R) = (k % p : ℤ) := by
  calc
    (k : R) = ↑(k % p + p * (k / p)) := by 

Proof state:
R : Type u_1
inst✝¹ : Ring R
p : ℕ
inst✝ : CharP R p
k : ℤ
⊢ ↑k = ↑(k % ↑p + ↑p * (k / ↑p))

Next tactic:
rw [Int.emod_add_ediv]
lemma CharP.cast_int_eq_mod (R : Type _) [Ring R] (p : ℕ) [CharP R p] (k : ℤ) :
    (k : R) = (k % p : ℤ) := by
  calc
    (k : R) = ↑(k % p + p * (k / p)) := by rw [Int.emod_add_ediv]
    _ = ↑(k % p) := by 

Proof state:
R : Type u_1
inst✝¹ : Ring R
p : ℕ
inst✝ : CharP R p
k : ℤ
⊢ ↑(k % ↑p + ↑p * (k / ↑p)) = ↑(k % ↑p)

Next tactic:
simp [CharP.cast_eq_zero R]
lemma CharP.isInt_of_mod {α : Type _} [Ring α] {n n' : ℕ} (inst : CharP α n) {e : α}
    (he : IsInt e e') (hn : IsNat n n') (h₂ : IsInt (e' % n') r) : IsInt e r :=
  ⟨by 

Proof state:
e' r : ℤ
α : Type u_1
inst✝ : Ring α
n n' : ℕ
inst : CharP α n
e : α
he : IsInt e e'
hn : IsNat n n'
h₂ : IsInt (e' % ↑n') r
⊢ e = ↑r

Next tactic:
rw [he.out, CharP.cast_int_eq_mod α n, show n = n' from hn.out, h₂.out, Int.cast_id]
lemma CharP.neg_eq_sub_one_mul {α : Type _} [Ring α] (n : ℕ) (inst : CharP α n) (b : α)
    (a : ℕ) (a' : α) (p : IsNat (n - 1 : α) a) (pa : a = a') :
    -b = a' * b := by
  

Proof state:
α : Type u_1
inst✝ : Ring α
n : ℕ
inst : CharP α n
b : α
a : ℕ
a' : α
p : IsNat (↑n - 1) a
pa : ↑a = a'
⊢ -b = a' * b

Next tactic:
rw [← pa, ← p.out, ← neg_one_mul]
lemma CharP.neg_eq_sub_one_mul {α : Type _} [Ring α] (n : ℕ) (inst : CharP α n) (b : α)
    (a : ℕ) (a' : α) (p : IsNat (n - 1 : α) a) (pa : a = a') :
    -b = a' * b := by
  rw [← pa, ← p.out, ← neg_one_mul]
  

Proof state:
α : Type u_1
inst✝ : Ring α
n : ℕ
inst : CharP α n
b : α
a : ℕ
a' : α
p : IsNat (↑n - 1) a
pa : ↑a = a'
⊢ -1 * b = (↑n - 1) * b

Next tactic:
simp
lemma CharP.neg_mul_eq_sub_one_mul {α : Type _} [Ring α] (n : ℕ) (inst : CharP α n) (a b : α)
    (na : ℕ) (na' : α) (p : IsNat ((n - 1) * a : α) na) (pa : na = na') :
    -(a * b) = na' * b := by
  

Proof state:
α : Type u_1
inst✝ : Ring α
n : ℕ
inst : CharP α n
a b : α
na : ℕ
na' : α
p : IsNat ((↑n - 1) * a) na
pa : ↑na = na'
⊢ -(a * b) = na' * b

Next tactic:
rw [← pa, ← p.out, ← neg_one_mul]
lemma CharP.neg_mul_eq_sub_one_mul {α : Type _} [Ring α] (n : ℕ) (inst : CharP α n) (a b : α)
    (na : ℕ) (na' : α) (p : IsNat ((n - 1) * a : α) na) (pa : na = na') :
    -(a * b) = na' * b := by
  rw [← pa, ← p.out, ← neg_one_mul]
  

Proof state:
α : Type u_1
inst✝ : Ring α
n : ℕ
inst : CharP α n
a b : α
na : ℕ
na' : α
p : IsNat ((↑n - 1) * a) na
pa : ↑na = na'
⊢ -1 * (a * b) = (↑n - 1) * a * b

Next tactic:
simp
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion_of_isCompact [hι : Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s✝ t : Set X
hι : Countable ι
s : ι → Set X
hcomp : ∀ (i : ι), IsCompact (s i)
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
rcases isEmpty_or_nonempty ι
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion_of_isCompact [hι : Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  rcases isEmpty_or_nonempty ι
  · 

Proof state:
case inl
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s✝ t : Set X
hι : Countable ι
s : ι → Set X
hcomp : ∀ (i : ι), IsCompact (s i)
h✝ : IsEmpty ι
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
simp only [iUnion_of_empty, isSigmaCompact_empty]
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion_of_isCompact [hι : Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  rcases isEmpty_or_nonempty ι
  · simp only [iUnion_of_empty, isSigmaCompact_empty]
  · -- If ι is non-empty, choose a surjection f : ℕ → ι, this yields a map ℕ → Set X.
    

Proof state:
case inr
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s✝ t : Set X
hι : Countable ι
s : ι → Set X
hcomp : ∀ (i : ι), IsCompact (s i)
h✝ : Nonempty ι
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
obtain ⟨f, hf⟩ := countable_iff_exists_surjective.mp hι
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion_of_isCompact [hι : Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  rcases isEmpty_or_nonempty ι
  · simp only [iUnion_of_empty, isSigmaCompact_empty]
  · -- If ι is non-empty, choose a surjection f : ℕ → ι, this yields a map ℕ → Set X.
    obtain ⟨f, hf⟩ := countable_iff_exists_surjective.mp hι
    

Proof state:
case inr.intro
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s✝ t : Set X
hι : Countable ι
s : ι → Set X
hcomp : ∀ (i : ι), IsCompact (s i)
h✝ : Nonempty ι
f : ℕ → ι
hf : Function.Surjective f
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
exact ⟨s ∘ f, fun n ↦ hcomp (f n), Function.Surjective.iUnion_comp hf _⟩
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_sUnion_of_isCompact {S : Set (Set X)} (hc : Set.Countable S)
    (hcomp : ∀ (s : Set X), s ∈ S → IsCompact s) : IsSigmaCompact (⋃₀ S) := by
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s t : Set X
S : Set (Set X)
hc : Set.Countable S
hcomp : ∀ s ∈ S, IsCompact s
⊢ IsSigmaCompact (⋃₀ S)

Next tactic:
have : Countable S := countable_coe_iff.mpr hc
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_sUnion_of_isCompact {S : Set (Set X)} (hc : Set.Countable S)
    (hcomp : ∀ (s : Set X), s ∈ S → IsCompact s) : IsSigmaCompact (⋃₀ S) := by
  have : Countable S := countable_coe_iff.mpr hc
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s t : Set X
S : Set (Set X)
hc : Set.Countable S
hcomp : ∀ s ∈ S, IsCompact s
this : Countable ↑S
⊢ IsSigmaCompact (⋃₀ S)

Next tactic:
rw [sUnion_eq_iUnion]
/-- Countable unions of compact sets are σ-compact. -/
lemma isSigmaCompact_sUnion_of_isCompact {S : Set (Set X)} (hc : Set.Countable S)
    (hcomp : ∀ (s : Set X), s ∈ S → IsCompact s) : IsSigmaCompact (⋃₀ S) := by
  have : Countable S := countable_coe_iff.mpr hc
  rw [sUnion_eq_iUnion]
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
s t : Set X
S : Set (Set X)
hc : Set.Countable S
hcomp : ∀ s ∈ S, IsCompact s
this : Countable ↑S
⊢ IsSigmaCompact (⋃ i, ↑i)

Next tactic:
apply isSigmaCompact_iUnion_of_isCompact _ (fun ⟨s, hs⟩ ↦ hcomp s hs)
/-- Countable unions of σ-compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion [Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsSigmaCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  -- Choose a decomposition s_i = ⋃ K_i,j for each i.
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X
inst✝¹ : TopologicalSpace Y
s✝ t : Set X
inst✝ : Countable ι
s : ι → Set X
hcomp : ∀ (i : ι), IsSigmaCompact (s i)
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
choose K hcomp hcov using fun i ↦ hcomp i
/-- Countable unions of σ-compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion [Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsSigmaCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  -- Choose a decomposition s_i = ⋃ K_i,j for each i.
  choose K hcomp hcov using fun i ↦ hcomp i
  -- Then, we have a countable union of countable unions of compact sets, i.e. countably many.
  

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X
inst✝¹ : TopologicalSpace Y
s✝ t : Set X
inst✝ : Countable ι
s : ι → Set X
hcomp✝ : ∀ (i : ι), IsSigmaCompact (s i)
K : ι → ℕ → Set X
hcomp : ∀ (i : ι) (n : ℕ), IsCompact (K i n)
hcov : ∀ (i : ι), ⋃ n, K i n = s i
⊢ IsSigmaCompact (⋃ i, s i)

Next tactic:
have := calc
    ⋃ i, s i
    _ = ⋃ i, ⋃ n, (K i n) := by simp_rw [hcov]
    _ = ⋃ (i) (n : ℕ), (K.uncurry ⟨i, n⟩) := by rw [Function.uncurry_def]
    _ = ⋃ x, K.uncurry x := by rw [← iUnion_prod']
/-- Countable unions of σ-compact sets are σ-compact. -/
lemma isSigmaCompact_iUnion [Countable ι] (s : ι → Set X)
    (hcomp : ∀ i, IsSigmaCompact (s i)) : IsSigmaCompact (⋃ i, s i) := by
  -- Choose a decomposition s_i = ⋃ K_i,j for each i.
  choose K hcomp hcov using fun i ↦ hcomp i
  -- Then, we have a countable union of countable unions of compact sets, i.e. countably many.
  have := calc
    ⋃ i, s i
    _ = ⋃ i, ⋃ n, (K i n) := by 

Proof state:
X : Type u_1
Y : Type u_2
ι : Type u_3
inst✝² : TopologicalSpace X
inst✝¹ : TopologicalSpace Y
s✝ t : Set X
inst✝ : Countable ι
s : ι → Set X
hcomp✝ : ∀ (i : ι), IsSigmaCompact (s i)
K : ι → ℕ → Set X
hcomp : ∀ (i : ι) (n : ℕ), IsCompact (K i n)
hcov : ∀ (i : ι), ⋃ n, K i n = s i
⊢ ⋃ i, s i = ⋃ i, ⋃ n, K i n

Next tactic:
simp_rw [hcov]