l3lab/ntp-mathlib huggingface dataset:
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => 

Proof state:
case a
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
j✝ : J
| MonoidalCategory.tensorHom (limit.lift (F ⋙ forget C) ((forget C).mapCone s))
      (limit.lift (F ⋙ forget C) ((forget C).mapCone s)) ≫
    MonoidalCategory.tensorHom (limit.π (F ⋙ forget C) j✝) (limit.π (F ⋙ forget C) j✝)
case a
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
j✝ : J
| (F.obj j✝).mul

Next tactic:
rw [← MonoidalCategory.tensor_comp, limit.lift_π]
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by 

Proof state:
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
h : J
⊢ (fun s => Hom.mk (limit.lift (F ⋙ forget C) ((forget C).mapCone s))) s ≫ (limitCone F).π.app h = s.π.app h

Next tactic:
ext
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; 

Proof state:
case w
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
h : J
⊢ ((fun s => Hom.mk (limit.lift (F ⋙ forget C) ((forget C).mapCone s))) s ≫ (limitCone F).π.app h).hom = (s.π.app h).hom

Next tactic:
simp
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; simp
  uniq s m w := by
    

Proof state:
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
m : s.pt ⟶ (limitCone F).pt
w : ∀ (j : J), m ≫ (limitCone F).π.app j = s.π.app j
⊢ m = (fun s => Hom.mk (limit.lift (F ⋙ forget C) ((forget C).mapCone s))) s

Next tactic:
ext1
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; simp
  uniq s m w := by
    ext1
    

Proof state:
case w
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
m : s.pt ⟶ (limitCone F).pt
w : ∀ (j : J), m ≫ (limitCone F).π.app j = s.π.app j
⊢ m.hom = ((fun s => Hom.mk (limit.lift (F ⋙ forget C) ((forget C).mapCone s))) s).hom

Next tactic:
refine' limit.hom_ext (fun j => _)
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; simp
  uniq s m w := by
    ext1
    refine' limit.hom_ext (fun j => _)
    

Proof state:
case w
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
m : s.pt ⟶ (limitCone F).pt
w : ∀ (j : J), m ≫ (limitCone F).π.app j = s.π.app j
j : J
⊢ m.hom ≫ limit.π (MonFunctorCategoryEquivalence.inverse.obj F).X j =
    ((fun s => Hom.mk (limit.lift (F ⋙ forget C) ((forget C).mapCone s))) s).hom ≫
      limit.π (MonFunctorCategoryEquivalence.inverse.obj F).X j

Next tactic:
dsimp
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; simp
  uniq s m w := by
    ext1
    refine' limit.hom_ext (fun j => _)
    dsimp; 

Proof state:
case w
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
m : s.pt ⟶ (limitCone F).pt
w : ∀ (j : J), m ≫ (limitCone F).π.app j = s.π.app j
j : J
⊢ m.hom ≫ limit.π (F ⋙ forget C) j = limit.lift (F ⋙ forget C) ((forget C).mapCone s) ≫ limit.π (F ⋙ forget C) j

Next tactic:
simp only [Mon_.forget_map, limit.lift_π, Functor.mapCone_π_app]
/-- Implementation of `Mon_.hasLimits`:
the proposed cone over a functor `F : J ⥤ Mon_ C` is a limit cone.
-/
@[simps]
def limitConeIsLimit (F : J ⥤ Mon_ C) : IsLimit (limitCone F) where
  lift s :=
    { hom := limit.lift (F ⋙ Mon_.forget C) ((Mon_.forget C).mapCone s)
      mul_hom := by
        dsimp
        ext
        simp only [Functor.comp_obj, forget_obj, Category.assoc, limit.lift_π, Functor.mapCone_pt,
          Functor.mapCone_π_app, forget_map, Hom.mul_hom, limit_mul, Cones.postcompose_obj_pt,
          Cones.postcompose_obj_π, NatTrans.comp_app, Functor.const_obj_obj, tensorObj_obj,
          MonFunctorCategoryEquivalence.Inverse.obj_mul_app]
        slice_rhs 1 2 => rw [← MonoidalCategory.tensor_comp, limit.lift_π] }
  fac s h := by ext; simp
  uniq s m w := by
    ext1
    refine' limit.hom_ext (fun j => _)
    dsimp; simp only [Mon_.forget_map, limit.lift_π, Functor.mapCone_π_app]
    

Proof state:
case w
J : Type v
inst✝³ : SmallCategory J
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasLimits C
inst✝ : MonoidalCategory C
F : J ⥤ Mon_ C
s : Cone F
m : s.pt ⟶ (limitCone F).pt
w : ∀ (j : J), m ≫ (limitCone F).π.app j = s.π.app j
j : J
⊢ m.hom ≫ limit.π (F ⋙ forget C) j = (s.π.app j).hom

Next tactic:
exact congr_arg Mon_.Hom.hom (w j)
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ natDegree (det (X • Matrix.map A ⇑C + Matrix.map B ⇑C)) ≤ Fintype.card n

Next tactic:
rw [det_apply]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ natDegree (∑ σ : Equiv.Perm n, sign σ • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (σ i) i) ≤ Fintype.card n

Next tactic:
refine' (natDegree_sum_le _ _).trans _
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ Finset.fold max 0 (natDegree ∘ fun σ => sign σ • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (σ i) i)
      Finset.univ ≤
    Fintype.card n

Next tactic:
refine' Multiset.max_nat_le_of_forall_le _ _ _
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ ∀
    x ∈
      Multiset.map (natDegree ∘ fun σ => sign σ • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (σ i) i)
        Finset.univ.val,
    x ≤ Fintype.card n

Next tactic:
simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ ∀ (a : Equiv.Perm n), natDegree (sign a • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (a i) i) ≤ Fintype.card n

Next tactic:
intro g
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ natDegree (sign g • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) ≤ Fintype.card n

Next tactic:
calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · rw [sg, one_smul]
      · rw [sg, Units.neg_smul, one_smul, natDegree_neg]
    _ ≤ ∑ i : n, natDegree (((X : α[X]) • A.map C + B.map C : Matrix n n α[X]) (g i) i) :=
      (natDegree_prod_le (Finset.univ : Finset n) fun i : n =>
        (X • A.map C + B.map C : Matrix n n α[X]) (g i) i)
    _ ≤ Finset.univ.card • 1 := (Finset.sum_le_card_nsmul _ _ 1 fun (i : n) _ => ?_)
    _ ≤ Fintype.card n := by simp [mul_one, Algebra.id.smul_eq_mul, Finset.card_univ]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ natDegree (sign g • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) ≤
    natDegree (∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i)

Next tactic:
cases' Int.units_eq_one_or (sign g) with sg sg
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · 

Proof state:
case inl
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
sg : sign g = 1
⊢ natDegree (sign g • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) ≤
    natDegree (∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i)

Next tactic:
rw [sg, one_smul]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · rw [sg, one_smul]
      · 

Proof state:
case inr
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
sg : sign g = -1
⊢ natDegree (sign g • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) ≤
    natDegree (∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i)

Next tactic:
rw [sg, Units.neg_smul, one_smul, natDegree_neg]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · rw [sg, one_smul]
      · rw [sg, Units.neg_smul, one_smul, natDegree_neg]
    _ ≤ ∑ i : n, natDegree (((X : α[X]) • A.map C + B.map C : Matrix n n α[X]) (g i) i) :=
      (natDegree_prod_le (Finset.univ : Finset n) fun i : n =>
        (X • A.map C + B.map C : Matrix n n α[X]) (g i) i)
    _ ≤ Finset.univ.card • 1 := (Finset.sum_le_card_nsmul _ _ 1 fun (i : n) _ => ?_)
    _ ≤ Fintype.card n := by 

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ Finset.card Finset.univ • 1 ≤ Fintype.card n

Next tactic:
simp [mul_one, Algebra.id.smul_eq_mul, Finset.card_univ]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · rw [sg, one_smul]
      · rw [sg, Units.neg_smul, one_smul, natDegree_neg]
    _ ≤ ∑ i : n, natDegree (((X : α[X]) • A.map C + B.map C : Matrix n n α[X]) (g i) i) :=
      (natDegree_prod_le (Finset.univ : Finset n) fun i : n =>
        (X • A.map C + B.map C : Matrix n n α[X]) (g i) i)
    _ ≤ Finset.univ.card • 1 := (Finset.sum_le_card_nsmul _ _ 1 fun (i : n) _ => ?_)
    _ ≤ Fintype.card n := by simp [mul_one, Algebra.id.smul_eq_mul, Finset.card_univ]
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
i : n
x✝ : i ∈ Finset.univ
⊢ natDegree ((X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) ≤ 1

Next tactic:
dsimp only [add_apply, smul_apply, map_apply, smul_eq_mul]
theorem natDegree_det_X_add_C_le (A B : Matrix n n α) :
    natDegree (det ((X : α[X]) • A.map C + B.map C : Matrix n n α[X])) ≤ Fintype.card n := by
  rw [det_apply]
  refine' (natDegree_sum_le _ _).trans _
  refine' Multiset.max_nat_le_of_forall_le _ _ _
  simp only [forall_apply_eq_imp_iff, true_and_iff, Function.comp_apply, Multiset.map_map,
    Multiset.mem_map, exists_imp, Finset.mem_univ_val]
  intro g
  calc
    natDegree (sign g • ∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) ≤
        natDegree (∏ i : n, (X • A.map C + B.map C : Matrix n n α[X]) (g i) i) := by
      cases' Int.units_eq_one_or (sign g) with sg sg
      · rw [sg, one_smul]
      · rw [sg, Units.neg_smul, one_smul, natDegree_neg]
    _ ≤ ∑ i : n, natDegree (((X : α[X]) • A.map C + B.map C : Matrix n n α[X]) (g i) i) :=
      (natDegree_prod_le (Finset.univ : Finset n) fun i : n =>
        (X • A.map C + B.map C : Matrix n n α[X]) (g i) i)
    _ ≤ Finset.univ.card • 1 := (Finset.sum_le_card_nsmul _ _ 1 fun (i : n) _ => ?_)
    _ ≤ Fintype.card n := by simp [mul_one, Algebra.id.smul_eq_mul, Finset.card_univ]
  dsimp only [add_apply, smul_apply, map_apply, smul_eq_mul]
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
i : n
x✝ : i ∈ Finset.univ
⊢ natDegree (X * C (A (g i) i) + C (B (g i) i)) ≤ 1

Next tactic:
compute_degree
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ coeff (det (X • Matrix.map A ⇑C + Matrix.map B ⇑C)) 0 = det B

Next tactic:
rw [det_apply, finset_sum_coeff, det_apply]
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ ∑ b : Equiv.Perm n, coeff (sign b • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (b i) i) 0 =
    ∑ σ : Equiv.Perm n, sign σ • ∏ i : n, B (σ i) i

Next tactic:
refine' Finset.sum_congr rfl _
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  refine' Finset.sum_congr rfl _
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
⊢ ∀ x ∈ Finset.univ,
    coeff (sign x • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (x i) i) 0 = sign x • ∏ i : n, B (x i) i

Next tactic:
rintro g -
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  refine' Finset.sum_congr rfl _
  rintro g -
  

Proof state:
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ coeff (sign g • ∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) 0 = sign g • ∏ i : n, B (g i) i

Next tactic:
convert coeff_smul (R := α) (sign g) _ 0
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  refine' Finset.sum_congr rfl _
  rintro g -
  convert coeff_smul (R := α) (sign g) _ 0
  

Proof state:
case h.e'_3.h.e'_6
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ ∏ i : n, B (g i) i = coeff (∏ i : n, (X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) 0

Next tactic:
rw [coeff_zero_prod]
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  refine' Finset.sum_congr rfl _
  rintro g -
  convert coeff_smul (R := α) (sign g) _ 0
  rw [coeff_zero_prod]
  

Proof state:
case h.e'_3.h.e'_6
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ ∏ i : n, B (g i) i = ∏ i : n, coeff ((X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g i) i) 0

Next tactic:
refine' Finset.prod_congr rfl _
theorem coeff_det_X_add_C_zero (A B : Matrix n n α) :
    coeff (det ((X : α[X]) • A.map C + B.map C)) 0 = det B := by
  rw [det_apply, finset_sum_coeff, det_apply]
  refine' Finset.sum_congr rfl _
  rintro g -
  convert coeff_smul (R := α) (sign g) _ 0
  rw [coeff_zero_prod]
  refine' Finset.prod_congr rfl _
  

Proof state:
case h.e'_3.h.e'_6
n : Type u_1
α : Type u_2
inst✝² : DecidableEq n
inst✝¹ : Fintype n
inst✝ : CommRing α
A B : Matrix n n α
g : Equiv.Perm n
⊢ ∀ x ∈ Finset.univ, B (g x) x = coeff ((X • Matrix.map A ⇑C + Matrix.map B ⇑C) (g x) x) 0

Next tactic:
simp