l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · 

Proof state:
case hsingle.hsingle
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
⊢ ∀ (a : κ) (b : N),
    ((finsuppTensorFinsupp R M N ι κ) ((fun₀ | i' => m) ⊗ₜ[R] fun₀ | a => b)) (i, k) =
      (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | a => b) k

Next tactic:
intro k' n
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      

Proof state:
case hsingle.hsingle
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
⊢ ((finsuppTensorFinsupp R M N ι κ) ((fun₀ | i' => m) ⊗ₜ[R] fun₀ | k' => n)) (i, k) =
    (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp only [finsuppTensorFinsupp_single]
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      

Proof state:
case hsingle.hsingle
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
by_cases h1 : (i', k') = (i, k)
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · 

Proof state:
case pos
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : (i', k') = (i, k)
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp only [Prod.mk.inj_iff] at h1
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · simp only [Prod.mk.inj_iff] at h1
        

Proof state:
case pos
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : i' = i ∧ k' = k
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp [h1]
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · simp only [Prod.mk.inj_iff] at h1
        simp [h1]
      · 

Proof state:
case neg
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : ¬(i', k') = (i, k)
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp only [Prod.mk.inj_iff, not_and_or] at h1
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · simp only [Prod.mk.inj_iff] at h1
        simp [h1]
      · simp only [Prod.mk.inj_iff, not_and_or] at h1
        

Proof state:
case neg
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : ¬i' = i ∨ ¬k' = k
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
cases' h1 with h1 h1
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · simp only [Prod.mk.inj_iff] at h1
        simp [h1]
      · simp only [Prod.mk.inj_iff, not_and_or] at h1
        cases' h1 with h1 h1 <;> 

Proof state:
case neg.inl
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : ¬i' = i
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp [h1]
@[simp]
theorem finsuppTensorFinsupp_apply (R M N ι κ : Sort _) [CommRing R] [AddCommGroup M] [Module R M]
    [AddCommGroup N] [Module R N] (f : ι →₀ M) (g : κ →₀ N) (i : ι) (k : κ) :
    finsuppTensorFinsupp R M N ι κ (f ⊗ₜ g) (i, k) = f i ⊗ₜ g k := by
  apply Finsupp.induction_linear f
  · simp
  · intro f₁ f₂ hf₁ hf₂
    simp [add_tmul, hf₁, hf₂]
  · intro i' m
    apply Finsupp.induction_linear g
    · simp
    · intro g₁ g₂ hg₁ hg₂
      simp [tmul_add, hg₁, hg₂]
    · intro k' n
      simp only [finsuppTensorFinsupp_single]
      -- split_ifs; finish can close the goal from here
      by_cases h1 : (i', k') = (i, k)
      · simp only [Prod.mk.inj_iff] at h1
        simp [h1]
      · simp only [Prod.mk.inj_iff, not_and_or] at h1
        cases' h1 with h1 h1 <;> 

Proof state:
case neg.inr
R✝ : Type u
M✝ : Type v
N✝ : Type w
inst✝⁹ : Ring R✝
inst✝⁸ : AddCommGroup M✝
inst✝⁷ : Module R✝ M✝
inst✝⁶ : AddCommGroup N✝
inst✝⁵ : Module R✝ N✝
R : Type u_1
M : Type u_2
N : Type u_3
ι : Type u_4
κ : Type u_5
inst✝⁴ : CommRing R
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : AddCommGroup N
inst✝ : Module R N
f : ι →₀ M
g : κ →₀ N
i : ι
k : κ
i' : ι
m : M
k' : κ
n : N
h1 : ¬k' = k
⊢ (fun₀ | (i', k') => m ⊗ₜ[R] n) (i, k) = (fun₀ | i' => m) i ⊗ₜ[R] (fun₀ | k' => n) k

Next tactic:
simp [h1]
@[simp]
theorem finsuppTensorFinsupp'_apply_apply (f : α →₀ S) (g : β →₀ S) (a : α) (b : β) :
    finsuppTensorFinsupp' S α β (f ⊗ₜ[S] g) (a, b) = f a * g b := by 

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁵ : Ring R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
S : Type u_1
inst✝ : CommRing S
α : Type u_2
β : Type u_3
f : α →₀ S
g : β →₀ S
a : α
b : β
⊢ ((finsuppTensorFinsupp' S α β) (f ⊗ₜ[S] g)) (a, b) = f a * g b

Next tactic:
simp [finsuppTensorFinsupp']
@[simp]
theorem finsuppTensorFinsupp'_single_tmul_single (a : α) (b : β) (r₁ r₂ : S) :
    finsuppTensorFinsupp' S α β (Finsupp.single a r₁ ⊗ₜ[S] Finsupp.single b r₂) =
      Finsupp.single (a, b) (r₁ * r₂) := by
  

Proof state:
R : Type u
M : Type v
N : Type w
inst✝⁵ : Ring R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
S : Type u_1
inst✝ : CommRing S
α : Type u_2
β : Type u_3
a : α
b : β
r₁ r₂ : S
⊢ (finsuppTensorFinsupp' S α β) ((fun₀ | a => r₁) ⊗ₜ[S] fun₀ | b => r₂) = fun₀ | (a, b) => r₁ * r₂

Next tactic:
ext ⟨a', b'⟩
@[simp]
theorem finsuppTensorFinsupp'_single_tmul_single (a : α) (b : β) (r₁ r₂ : S) :
    finsuppTensorFinsupp' S α β (Finsupp.single a r₁ ⊗ₜ[S] Finsupp.single b r₂) =
      Finsupp.single (a, b) (r₁ * r₂) := by
  ext ⟨a', b'⟩
  

Proof state:
case h.mk
R : Type u
M : Type v
N : Type w
inst✝⁵ : Ring R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
S : Type u_1
inst✝ : CommRing S
α : Type u_2
β : Type u_3
a : α
b : β
r₁ r₂ : S
a' : α
b' : β
⊢ ((finsuppTensorFinsupp' S α β) ((fun₀ | a => r₁) ⊗ₜ[S] fun₀ | b => r₂)) (a', b') = (fun₀ | (a, b) => r₁ * r₂) (a', b')

Next tactic:
classical
  aesop (add norm [Finsupp.single_apply])
@[simp]
theorem finsuppTensorFinsupp'_single_tmul_single (a : α) (b : β) (r₁ r₂ : S) :
    finsuppTensorFinsupp' S α β (Finsupp.single a r₁ ⊗ₜ[S] Finsupp.single b r₂) =
      Finsupp.single (a, b) (r₁ * r₂) := by
  ext ⟨a', b'⟩
  classical
  

Proof state:
case h.mk
R : Type u
M : Type v
N : Type w
inst✝⁵ : Ring R
inst✝⁴ : AddCommGroup M
inst✝³ : Module R M
inst✝² : AddCommGroup N
inst✝¹ : Module R N
S : Type u_1
inst✝ : CommRing S
α : Type u_2
β : Type u_3
a : α
b : β
r₁ r₂ : S
a' : α
b' : β
⊢ ((finsuppTensorFinsupp' S α β) ((fun₀ | a => r₁) ⊗ₜ[S] fun₀ | b => r₂)) (a', b') = (fun₀ | (a, b) => r₁ * r₂) (a', b')

Next tactic:
aesop (add norm [Finsupp.single_apply])
/-- To construct an isomorphism of algebras, it suffices to give an isomorphism of the As which
commutes with the structure morphisms.
-/
@[simps!]
def isoMk (h : A₀.1 ≅ A₁.1) (w : F.map h.hom ≫ A₁.str = A₀.str ≫ h.hom := by aesop_cat) :
    A₀ ≅ A₁ where
  hom := { f := h.hom }
  inv :=
    { f := h.inv
      h := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : A₀.a ≅ A₁.a
w : autoParam (F.map h.hom ≫ A₁.str = A₀.str ≫ h.hom) _auto✝
⊢ F.map h.inv ≫ A₀.str = A₁.str ≫ h.inv

Next tactic:
rw [h.eq_comp_inv, Category.assoc, ← w, ← Functor.map_comp_assoc]
/-- To construct an isomorphism of algebras, it suffices to give an isomorphism of the As which
commutes with the structure morphisms.
-/
@[simps!]
def isoMk (h : A₀.1 ≅ A₁.1) (w : F.map h.hom ≫ A₁.str = A₀.str ≫ h.hom := by aesop_cat) :
    A₀ ≅ A₁ where
  hom := { f := h.hom }
  inv :=
    { f := h.inv
      h := by
        rw [h.eq_comp_inv, Category.assoc, ← w, ← Functor.map_comp_assoc]
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : A₀.a ≅ A₁.a
w : autoParam (F.map h.hom ≫ A₁.str = A₀.str ≫ h.hom) _auto✝
⊢ F.map (h.inv ≫ h.hom) ≫ A₁.str = A₁.str

Next tactic:
simp
/-- An algebra morphism with an underlying isomorphism hom in `C` is an algebra isomorphism. -/
theorem iso_of_iso (f : A₀ ⟶ A₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f✝ : A₀ ⟶ A₁
g : A₁ ⟶ A₂
f : A₀ ⟶ A₁
inst✝ : IsIso f.f
⊢ F.map (inv f.f) ≫ A₀.str = A₁.str ≫ inv f.f

Next tactic:
rw [IsIso.eq_comp_inv f.1, Category.assoc, ← f.h]
/-- An algebra morphism with an underlying isomorphism hom in `C` is an algebra isomorphism. -/
theorem iso_of_iso (f : A₀ ⟶ A₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_comp_inv f.1, Category.assoc, ← f.h]
        

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f✝ : A₀ ⟶ A₁
g : A₁ ⟶ A₂
f : A₀ ⟶ A₁
inst✝ : IsIso f.f
⊢ F.map (inv f.f) ≫ F.map f.f ≫ A₁.str = A₁.str

Next tactic:
simp
/-- An algebra morphism with an underlying isomorphism hom in `C` is an algebra isomorphism. -/
theorem iso_of_iso (f : A₀ ⟶ A₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_comp_inv f.1, Category.assoc, ← f.h]
        simp }, by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f✝ : A₀ ⟶ A₁
g : A₁ ⟶ A₂
f : A₀ ⟶ A₁
inst✝ : IsIso f.f
⊢ f ≫ Hom.mk (inv f.f) = 𝟙 A₀

Next tactic:
aesop_cat
/-- An algebra morphism with an underlying isomorphism hom in `C` is an algebra isomorphism. -/
theorem iso_of_iso (f : A₀ ⟶ A₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_comp_inv f.1, Category.assoc, ← f.h]
        simp }, by aesop_cat, by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f✝ : A₀ ⟶ A₁
g : A₁ ⟶ A₂
f : A₀ ⟶ A₁
inst✝ : IsIso f.f
⊢ Hom.mk (inv f.f) ≫ f = 𝟙 A₁

Next tactic:
aesop_cat
/-- Naturally isomorphic endofunctors give equivalent categories of algebras.
Furthermore, they are equivalent as categories over `C`, that is,
we have `equiv_of_nat_iso h ⋙ forget = forget`.
-/
@[simps]
def equivOfNatIso {F G : C ⥤ C} (α : F ≅ G) : Algebra F ≌ Algebra G where
  functor := functorOfNatTrans α.inv
  inverse := functorOfNatTrans α.hom
  unitIso := functorOfNatTransId.symm ≪≫ functorOfNatTransEq (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ C
A A₀ A₁ A₂ : Algebra F✝
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
F G : C ⥤ C
α : F ≅ G
⊢ 𝟙 F = α.hom ≫ α.inv

Next tactic:
simp
/-- Naturally isomorphic endofunctors give equivalent categories of algebras.
Furthermore, they are equivalent as categories over `C`, that is,
we have `equiv_of_nat_iso h ⋙ forget = forget`.
-/
@[simps]
def equivOfNatIso {F G : C ⥤ C} (α : F ≅ G) : Algebra F ≌ Algebra G where
  functor := functorOfNatTrans α.inv
  inverse := functorOfNatTrans α.hom
  unitIso := functorOfNatTransId.symm ≪≫ functorOfNatTransEq (by simp) ≪≫ functorOfNatTransComp _ _
  counitIso :=
    (functorOfNatTransComp _ _).symm ≪≫ functorOfNatTransEq (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ C
A A₀ A₁ A₂ : Algebra F✝
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
F G : C ⥤ C
α : F ≅ G
⊢ α.inv ≫ α.hom = 𝟙 G

Next tactic:
simp
theorem left_inv' :
    ⟨strInv h ≫ A.str, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : Limits.IsInitial A
⊢ F.map (strInv h ≫ A.str) ≫ A.str = A.str ≫ strInv h ≫ A.str

Next tactic:
rw [← Category.assoc, F.map_comp, strInv, ← Hom.h]
theorem right_inv : A.str ≫ strInv h = 𝟙 _ := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : Limits.IsInitial A
⊢ A.str ≫ strInv h = 𝟙 (F.obj A.a)

Next tactic:
rw [strInv, ← (h.to ⟨F.obj A.1, F.map A.str⟩).h, ← F.map_id, ← F.map_comp]
theorem right_inv : A.str ≫ strInv h = 𝟙 _ := by
  rw [strInv, ← (h.to ⟨F.obj A.1, F.map A.str⟩).h, ← F.map_id, ← F.map_comp]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : Limits.IsInitial A
⊢ F.map ((Limits.IsInitial.to h { a := F.obj A.a, str := F.map A.str }).f ≫ A.str) = F.map (𝟙 A.a)

Next tactic:
congr
theorem right_inv : A.str ≫ strInv h = 𝟙 _ := by
  rw [strInv, ← (h.to ⟨F.obj A.1, F.map A.str⟩).h, ← F.map_id, ← F.map_comp]
  congr
  

Proof state:
case e_a
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
A A₀ A₁ A₂ : Algebra F
f : A₀ ⟶ A₁
g : A₁ ⟶ A₂
h : Limits.IsInitial A
⊢ (Limits.IsInitial.to h { a := F.obj A.a, str := F.map A.str }).f ≫ A.str = 𝟙 A.a

Next tactic:
exact left_inv h
/-- To construct an isomorphism of coalgebras, it suffices to give an isomorphism of the Vs which
commutes with the structure morphisms.
-/
@[simps]
def isoMk (h : V₀.1 ≅ V₁.1) (w : V₀.str ≫ F.map h.hom = h.hom ≫ V₁.str := by aesop_cat) :
    V₀ ≅ V₁ where
  hom := { f := h.hom }
  inv :=
    { f := h.inv
      h := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f : V₀ ⟶ V₁
g : V₁ ⟶ V₂
h : V₀.V ≅ V₁.V
w : autoParam (V₀.str ≫ F.map h.hom = h.hom ≫ V₁.str) _auto✝
⊢ V₁.str ≫ F.map h.inv = h.inv ≫ V₀.str

Next tactic:
rw [h.eq_inv_comp, ← Category.assoc, ← w, Category.assoc, ← F.map_comp]
/-- To construct an isomorphism of coalgebras, it suffices to give an isomorphism of the Vs which
commutes with the structure morphisms.
-/
@[simps]
def isoMk (h : V₀.1 ≅ V₁.1) (w : V₀.str ≫ F.map h.hom = h.hom ≫ V₁.str := by aesop_cat) :
    V₀ ≅ V₁ where
  hom := { f := h.hom }
  inv :=
    { f := h.inv
      h := by
        rw [h.eq_inv_comp, ← Category.assoc, ← w, Category.assoc, ← F.map_comp]
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f : V₀ ⟶ V₁
g : V₁ ⟶ V₂
h : V₀.V ≅ V₁.V
w : autoParam (V₀.str ≫ F.map h.hom = h.hom ≫ V₁.str) _auto✝
⊢ V₀.str ≫ F.map (h.hom ≫ h.inv) = V₀.str

Next tactic:
simp only [Iso.hom_inv_id, Functor.map_id, Category.comp_id]
/-- A coalgebra morphism with an underlying isomorphism hom in `C` is a coalgebra isomorphism. -/
theorem iso_of_iso (f : V₀ ⟶ V₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f✝ : V₀ ⟶ V₁
g : V₁ ⟶ V₂
f : V₀ ⟶ V₁
inst✝ : IsIso f.f
⊢ V₁.str ≫ F.map (inv f.f) = inv f.f ≫ V₀.str

Next tactic:
rw [IsIso.eq_inv_comp f.1, ← Category.assoc, ← f.h, Category.assoc]
/-- A coalgebra morphism with an underlying isomorphism hom in `C` is a coalgebra isomorphism. -/
theorem iso_of_iso (f : V₀ ⟶ V₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_inv_comp f.1, ← Category.assoc, ← f.h, Category.assoc]
        

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f✝ : V₀ ⟶ V₁
g : V₁ ⟶ V₂
f : V₀ ⟶ V₁
inst✝ : IsIso f.f
⊢ V₀.str ≫ F.map f.f ≫ F.map (inv f.f) = V₀.str

Next tactic:
simp
/-- A coalgebra morphism with an underlying isomorphism hom in `C` is a coalgebra isomorphism. -/
theorem iso_of_iso (f : V₀ ⟶ V₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_inv_comp f.1, ← Category.assoc, ← f.h, Category.assoc]
        simp }, by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f✝ : V₀ ⟶ V₁
g : V₁ ⟶ V₂
f : V₀ ⟶ V₁
inst✝ : IsIso f.f
⊢ f ≫ Hom.mk (inv f.f) = 𝟙 V₀

Next tactic:
aesop_cat
/-- A coalgebra morphism with an underlying isomorphism hom in `C` is a coalgebra isomorphism. -/
theorem iso_of_iso (f : V₀ ⟶ V₁) [IsIso f.1] : IsIso f :=
  ⟨⟨{ f := inv f.1
      h := by
        rw [IsIso.eq_inv_comp f.1, ← Category.assoc, ← f.h, Category.assoc]
        simp }, by aesop_cat, by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
F : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F
f✝ : V₀ ⟶ V₁
g : V₁ ⟶ V₂
f : V₀ ⟶ V₁
inst✝ : IsIso f.f
⊢ Hom.mk (inv f.f) ≫ f = 𝟙 V₁

Next tactic:
aesop_cat
/-- From a natural transformation `α : F → G` we get a functor from
coalgebras of `F` to coalgebras of `G`.
-/
@[simps]
def functorOfNatTrans {F G : C ⥤ C} (α : F ⟶ G) : Coalgebra F ⥤ Coalgebra G where
  obj V :=
    { V := V.1
      str := V.str ≫ α.app V.1 }
  map f :=
    { f := f.1
      h := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F✝
f✝ : V₀ ⟶ V₁
g : V₁ ⟶ V₂
F G : C ⥤ C
α : F ⟶ G
X✝ Y✝ : Coalgebra F
f : X✝ ⟶ Y✝
⊢ ((fun V => { V := V.V, str := V.str ≫ α.app V.V }) X✝).str ≫ G.map f.f =
    f.f ≫ ((fun V => { V := V.V, str := V.str ≫ α.app V.V }) Y✝).str

Next tactic:
rw [Category.assoc, ← α.naturality, ← Category.assoc, f.h, Category.assoc]
/-- Naturally isomorphic endofunctors give equivalent categories of coalgebras.
Furthermore, they are equivalent as categories over `C`, that is,
we have `equiv_of_nat_iso h ⋙ forget = forget`.
-/
@[simps]
def equivOfNatIso {F G : C ⥤ C} (α : F ≅ G) : Coalgebra F ≌ Coalgebra G where
  functor := functorOfNatTrans α.hom
  inverse := functorOfNatTrans α.inv
  unitIso := functorOfNatTransId.symm ≪≫ functorOfNatTransEq (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F✝
f : V₀ ⟶ V₁
g : V₁ ⟶ V₂
F G : C ⥤ C
α : F ≅ G
⊢ 𝟙 F = α.hom ≫ α.inv

Next tactic:
simp
/-- Naturally isomorphic endofunctors give equivalent categories of coalgebras.
Furthermore, they are equivalent as categories over `C`, that is,
we have `equiv_of_nat_iso h ⋙ forget = forget`.
-/
@[simps]
def equivOfNatIso {F G : C ⥤ C} (α : F ≅ G) : Coalgebra F ≌ Coalgebra G where
  functor := functorOfNatTrans α.hom
  inverse := functorOfNatTrans α.inv
  unitIso := functorOfNatTransId.symm ≪≫ functorOfNatTransEq (by simp) ≪≫ functorOfNatTransComp _ _
  counitIso :=
    (functorOfNatTransComp _ _).symm ≪≫ functorOfNatTransEq (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ C
V V₀ V₁ V₂ : Coalgebra F✝
f : V₀ ⟶ V₁
g : V₁ ⟶ V₂
F G : C ⥤ C
α : F ≅ G
⊢ α.inv ≫ α.hom = 𝟙 G

Next tactic:
simp