l3lab/ntp-mathlib huggingface dataset:
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> 

Proof state:
case inr.inr.inl
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ : E
val✝ : C
f : inr (inr val✝¹) ⟶ inl val✝
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inl val✝)).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
first | cases f | aesop_cat
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> first | 

Proof state:
case inr.inr.inl
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ : E
val✝ : C
f : inr (inr val✝¹) ⟶ inl val✝
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inl val✝)).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
cases f
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> 

Proof state:
case inr.inr.inr.inl
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ : E
val✝ : D
f : inr (inr val✝¹) ⟶ inr (inl val✝)
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inl val✝))).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
first | cases f | aesop_cat
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> first | 

Proof state:
case inr.inr.inr.inl
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ : E
val✝ : D
f : inr (inr val✝¹) ⟶ inr (inl val✝)
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inl val✝))).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
cases f
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> 

Proof state:
case inr.inr.inr.inr
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ val✝ : E
f : inr (inr val✝¹) ⟶ inr (inr val✝)
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝))).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
first | cases f | aesop_cat
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> first | 

Proof state:
case inr.inr.inr.inr
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ val✝ : E
f : inr (inr val✝¹) ⟶ inr (inr val✝)
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝))).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
cases f
/-- The equivalence of categories expressing associativity of sums of categories.
-/
def associativity : Sum (Sum C D) E ≌ Sum C (Sum D E) :=
  Equivalence.mk (associator C D E) (inverseAssociator C D E)
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with ((_|_)|_) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro ((_|_)|_) ((_|_)|_) f <;> first | cases f | aesop_cat))
    (NatIso.ofComponents (fun X => eqToIso
      (by rcases X with (_|(_|_)) <;> rfl)) -- Porting notes: aesop_cat fails
      (by rintro (_|(_|_)) (_|(_|_)) f <;> first | cases f | 

Proof state:
case inr.inr.inr.inr
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
val✝¹ val✝ : E
f : inr (inr val✝¹) ⟶ inr (inr val✝)
⊢ (inverseAssociator C D E ⋙ associator C D E).map f ≫
      ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝))).hom =
    ((fun X => eqToIso (_ : (inverseAssociator C D E ⋙ associator C D E).obj X = (𝟭 (C ⊕ D ⊕ E)).obj X))
          (inr (inr val✝¹))).hom ≫
      (𝟭 (C ⊕ D ⊕ E)).map f

Next tactic:
aesop_cat
instance associatorIsEquivalence : IsEquivalence (associator C D E) :=
  (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
⊢ IsEquivalence (associativity C D E).functor

Next tactic:
infer_instance
instance inverseAssociatorIsEquivalence : IsEquivalence (inverseAssociator C D E) :=
  (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u
inst✝¹ : Category.{v, u} D
E : Type u
inst✝ : Category.{v, u} E
⊢ IsEquivalence (associativity C D E).inverse

Next tactic:
infer_instance
theorem Monic.isPrimitive {p : R[X]} (hp : p.Monic) : p.IsPrimitive := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
⊢ IsPrimitive p

Next tactic:
rintro r ⟨q, h⟩
theorem Monic.isPrimitive {p : R[X]} (hp : p.Monic) : p.IsPrimitive := by
  rintro r ⟨q, h⟩
  

Proof state:
case intro
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
r : R
q : R[X]
h : p = C r * q
⊢ IsUnit r

Next tactic:
exact isUnit_of_mul_eq_one r (q.coeff p.natDegree) (by rwa [← coeff_C_mul, ← h])
theorem Monic.isPrimitive {p : R[X]} (hp : p.Monic) : p.IsPrimitive := by
  rintro r ⟨q, h⟩
  exact isUnit_of_mul_eq_one r (q.coeff p.natDegree) (by 

Proof state:
R : Type u_1
inst✝ : CommSemiring R
p : R[X]
hp : Monic p
r : R
q : R[X]
h : p = C r * q
⊢ r * coeff q (natDegree p) = 1

Next tactic:
rwa [← coeff_C_mul, ← h]
theorem IsPrimitive.ne_zero [Nontrivial R] {p : R[X]} (hp : p.IsPrimitive) : p ≠ 0 := by
  

Proof state:
R : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
p : R[X]
hp : IsPrimitive p
⊢ p ≠ 0

Next tactic:
rintro rfl
theorem IsPrimitive.ne_zero [Nontrivial R] {p : R[X]} (hp : p.IsPrimitive) : p ≠ 0 := by
  rintro rfl
  

Proof state:
R : Type u_1
inst✝¹ : CommSemiring R
inst✝ : Nontrivial R
hp : IsPrimitive 0
⊢ False

Next tactic:
exact (hp 0 (dvd_zero (C 0))).ne_zero rfl
theorem content_dvd_coeff {p : R[X]} (n : ℕ) : p.content ∣ p.coeff n := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
⊢ content p ∣ coeff p n

Next tactic:
by_cases h : n ∈ p.support
theorem content_dvd_coeff {p : R[X]} (n : ℕ) : p.content ∣ p.coeff n := by
  by_cases h : n ∈ p.support
  · 

Proof state:
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : n ∈ support p
⊢ content p ∣ coeff p n

Next tactic:
apply Finset.gcd_dvd h
theorem content_dvd_coeff {p : R[X]} (n : ℕ) : p.content ∣ p.coeff n := by
  by_cases h : n ∈ p.support
  · apply Finset.gcd_dvd h
  

Proof state:
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : n ∉ support p
⊢ content p ∣ coeff p n

Next tactic:
rw [mem_support_iff, Classical.not_not] at h
theorem content_dvd_coeff {p : R[X]} (n : ℕ) : p.content ∣ p.coeff n := by
  by_cases h : n ∈ p.support
  · apply Finset.gcd_dvd h
  rw [mem_support_iff, Classical.not_not] at h
  

Proof state:
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : coeff p n = 0
⊢ content p ∣ coeff p n

Next tactic:
rw [h]
theorem content_dvd_coeff {p : R[X]} (n : ℕ) : p.content ∣ p.coeff n := by
  by_cases h : n ∈ p.support
  · apply Finset.gcd_dvd h
  rw [mem_support_iff, Classical.not_not] at h
  rw [h]
  

Proof state:
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
n : ℕ
h : coeff p n = 0
⊢ content p ∣ 0

Next tactic:
apply dvd_zero
@[simp]
theorem content_C {r : R} : (C r).content = normalize r := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
⊢ content (C r) = normalize r

Next tactic:
rw [content]
@[simp]
theorem content_C {r : R} : (C r).content = normalize r := by
  rw [content]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
⊢ Finset.gcd (support (C r)) (coeff (C r)) = normalize r

Next tactic:
by_cases h0 : r = 0
@[simp]
theorem content_C {r : R} : (C r).content = normalize r := by
  rw [content]
  by_cases h0 : r = 0
  · 

Proof state:
case pos
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : r = 0
⊢ Finset.gcd (support (C r)) (coeff (C r)) = normalize r

Next tactic:
simp [h0]
@[simp]
theorem content_C {r : R} : (C r).content = normalize r := by
  rw [content]
  by_cases h0 : r = 0
  · simp [h0]
  

Proof state:
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
⊢ Finset.gcd (support (C r)) (coeff (C r)) = normalize r

Next tactic:
have h : (C r).support = {0} := support_monomial _ h0
@[simp]
theorem content_C {r : R} : (C r).content = normalize r := by
  rw [content]
  by_cases h0 : r = 0
  · simp [h0]
  have h : (C r).support = {0} := support_monomial _ h0
  

Proof state:
case neg
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
r : R
h0 : ¬r = 0
h : support (C r) = {0}
⊢ Finset.gcd (support (C r)) (coeff (C r)) = normalize r

Next tactic:
simp [h]
@[simp]
theorem content_zero : content (0 : R[X]) = 0 := by 

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content 0 = 0

Next tactic:
rw [← C_0, content_C, normalize_zero]
@[simp]
theorem content_one : content (1 : R[X]) = 1 := by 

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
⊢ content 1 = 1

Next tactic:
rw [← C_1, content_C, normalize_one]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ content (X * p) = content p

Next tactic:
rw [content, content, Finset.gcd_def, Finset.gcd_def]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ Multiset.gcd (Multiset.map (coeff (X * p)) (support (X * p)).val) =
    Multiset.gcd (Multiset.map (coeff p) (support p).val)

Next tactic:
refine' congr rfl _
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ Multiset.map (coeff (X * p)) (support (X * p)).val = Multiset.map (coeff p) (support p).val

Next tactic:
have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · rintro ⟨b, ⟨h1, h2⟩⟩
      rw [← Nat.succ_injective h2]
      apply h1
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)

Next tactic:
ext a
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    

Proof state:
case a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ a ∈ support (X * p) ↔ a ∈ Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)

Next tactic:
simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    

Proof state:
case a
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff (X * p) a = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = a

Next tactic:
cases' a with a
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · 

Proof state:
case a.zero
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
⊢ ¬coeff (X * p) Nat.zero = 0 ↔ ∃ a, ¬coeff p a = 0 ∧ Nat.succ a = Nat.zero

Next tactic:
simp [coeff_X_mul_zero, Nat.succ_ne_zero]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    

Proof state:
case a.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff (X * p) (Nat.succ a) = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a

Next tactic:
rw [mul_comm, coeff_mul_X]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    

Proof state:
case a.succ
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff p a = 0 ↔ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a

Next tactic:
constructor
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · 

Proof state:
case a.succ.mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ ¬coeff p a = 0 → ∃ a_2, ¬coeff p a_2 = 0 ∧ Nat.succ a_2 = Nat.succ a

Next tactic:
intro h
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      

Proof state:
case a.succ.mp
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
h : ¬coeff p a = 0
⊢ ∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a

Next tactic:
use a
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · 

Proof state:
case a.succ.mpr
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a : ℕ
⊢ (∃ a_1, ¬coeff p a_1 = 0 ∧ Nat.succ a_1 = Nat.succ a) → ¬coeff p a = 0

Next tactic:
rintro ⟨b, ⟨h1, h2⟩⟩
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · rintro ⟨b, ⟨h1, h2⟩⟩
      

Proof state:
case a.succ.mpr.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a b : ℕ
h1 : ¬coeff p b = 0
h2 : Nat.succ b = Nat.succ a
⊢ ¬coeff p a = 0

Next tactic:
rw [← Nat.succ_injective h2]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · rintro ⟨b, ⟨h1, h2⟩⟩
      rw [← Nat.succ_injective h2]
      

Proof state:
case a.succ.mpr.intro.intro
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
a b : ℕ
h1 : ¬coeff p b = 0
h2 : Nat.succ b = Nat.succ a
⊢ ¬coeff p b = 0

Next tactic:
apply h1
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · rintro ⟨b, ⟨h1, h2⟩⟩
      rw [← Nat.succ_injective h2]
      apply h1
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ Multiset.map (coeff (X * p)) (support (X * p)).val = Multiset.map (coeff p) (support p).val

Next tactic:
rw [h]
theorem content_X_mul {p : R[X]} : content (X * p) = content p := by
  rw [content, content, Finset.gcd_def, Finset.gcd_def]
  refine' congr rfl _
  have h : (X * p).support = p.support.map ⟨Nat.succ, Nat.succ_injective⟩ := by
    ext a
    simp only [exists_prop, Finset.mem_map, Function.Embedding.coeFn_mk, Ne.def, mem_support_iff]
    cases' a with a
    · simp [coeff_X_mul_zero, Nat.succ_ne_zero]
    rw [mul_comm, coeff_mul_X]
    constructor
    · intro h
      use a
    · rintro ⟨b, ⟨h1, h2⟩⟩
      rw [← Nat.succ_injective h2]
      apply h1
  rw [h]
  

Proof state:
R : Type u_1
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : NormalizedGCDMonoid R
p : R[X]
h : support (X * p) = Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)
⊢ Multiset.map (coeff (X * p)) (Finset.map { toFun := Nat.succ, inj' := Nat.succ_injective } (support p)).val =
    Multiset.map (coeff p) (support p).val

Next tactic:
simp only [Finset.map_val, Function.comp_apply, Function.Embedding.coeFn_mk, Multiset.map_map]