l3lab/ntp-mathlib huggingface dataset:
theorem perm_of_prod_eq_prod :
    ∀ {l₁ l₂ : List M}, l₁.prod = l₂.prod → (∀ p ∈ l₁, Prime p) → (∀ p ∈ l₂, Prime p) → Perm l₁ l₂
  | [], [], _, _, _ => Perm.nil
  | [], a :: l, h₁, _, h₃ =>
    have ha : a ∣ 1 := @prod_nil M _ ▸ h₁.symm ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _
    absurd ha (Prime.not_dvd_one (h₃ a (mem_cons_self _ _)))
  | a :: l, [], h₁, h₂, _ =>
    have ha : a ∣ 1 := @prod_nil M _ ▸ h₁ ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _
    absurd ha (Prime.not_dvd_one (h₂ a (mem_cons_self _ _)))
  | a :: l₁, b :: l₂, h, hl₁, hl₂ => by
    classical
      have hl₁' : ∀ p ∈ l₁, Prime p := fun p hp => hl₁ p (mem_cons_of_mem _ hp)
      have hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p := fun p hp => hl₂ p (mem_of_mem_erase hp)
      have ha : a ∈ b :: l₂ :=
        mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
          (h ▸ by rw [prod_cons]; exact dvd_mul_right _ _)
      have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha
      have hl : prod l₁ = prod ((b :: l₂).erase a) :=
        (mul_right_inj' (hl₁ a (mem_cons_self _ _)).ne_zero).1 <| by
          

Proof state:
M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : prod (a :: l₁) = prod (b :: l₂)
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ List.erase (b :: l₂) a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: List.erase (b :: l₂) a
⊢ a * prod l₁ = a * prod (List.erase (b :: l₂) a)

Next tactic:
rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]
theorem perm_of_prod_eq_prod :
    ∀ {l₁ l₂ : List M}, l₁.prod = l₂.prod → (∀ p ∈ l₁, Prime p) → (∀ p ∈ l₂, Prime p) → Perm l₁ l₂
  | [], [], _, _, _ => Perm.nil
  | [], a :: l, h₁, _, h₃ =>
    have ha : a ∣ 1 := @prod_nil M _ ▸ h₁.symm ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _
    absurd ha (Prime.not_dvd_one (h₃ a (mem_cons_self _ _)))
  | a :: l, [], h₁, h₂, _ =>
    have ha : a ∣ 1 := @prod_nil M _ ▸ h₁ ▸ (@prod_cons _ _ l a).symm ▸ dvd_mul_right _ _
    absurd ha (Prime.not_dvd_one (h₂ a (mem_cons_self _ _)))
  | a :: l₁, b :: l₂, h, hl₁, hl₂ => by
    classical
      have hl₁' : ∀ p ∈ l₁, Prime p := fun p hp => hl₁ p (mem_cons_of_mem _ hp)
      have hl₂' : ∀ p ∈ (b :: l₂).erase a, Prime p := fun p hp => hl₂ p (mem_of_mem_erase hp)
      have ha : a ∈ b :: l₂ :=
        mem_list_primes_of_dvd_prod (hl₁ a (mem_cons_self _ _)) hl₂
          (h ▸ by rw [prod_cons]; exact dvd_mul_right _ _)
      have hb : b :: l₂ ~ a :: (b :: l₂).erase a := perm_cons_erase ha
      have hl : prod l₁ = prod ((b :: l₂).erase a) :=
        (mul_right_inj' (hl₁ a (mem_cons_self _ _)).ne_zero).1 <| by
          rwa [← prod_cons, ← prod_cons, ← hb.prod_eq]
      

Proof state:
M : Type u_1
inst✝¹ : CancelCommMonoidWithZero M
inst✝ : Unique Mˣ
a : M
l₁ : List M
b : M
l₂ : List M
h : prod (a :: l₁) = prod (b :: l₂)
hl₁ : ∀ p ∈ a :: l₁, Prime p
hl₂ : ∀ p ∈ b :: l₂, Prime p
hl₁' : ∀ p ∈ l₁, Prime p
hl₂' : ∀ p ∈ List.erase (b :: l₂) a, Prime p
ha : a ∈ b :: l₂
hb : b :: l₂ ~ a :: List.erase (b :: l₂) a
hl : prod l₁ = prod (List.erase (b :: l₂) a)
⊢ a :: l₁ ~ b :: l₂

Next tactic:
exact Perm.trans ((perm_of_prod_eq_prod hl hl₁' hl₂').cons _) hb.symm
/-- In a nontrivial ring, `Matrix.mvPolynomialX m m R` has non-zero determinant. -/
theorem det_mvPolynomialX_ne_zero [DecidableEq m] [Fintype m] [CommRing R] [Nontrivial R] :
    det (mvPolynomialX m m R) ≠ 0 := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
S : Type u_4
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing R
inst✝ : Nontrivial R
⊢ det (mvPolynomialX m m R) ≠ 0

Next tactic:
intro h_det
/-- In a nontrivial ring, `Matrix.mvPolynomialX m m R` has non-zero determinant. -/
theorem det_mvPolynomialX_ne_zero [DecidableEq m] [Fintype m] [CommRing R] [Nontrivial R] :
    det (mvPolynomialX m m R) ≠ 0 := by
  intro h_det
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
S : Type u_4
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing R
inst✝ : Nontrivial R
h_det : det (mvPolynomialX m m R) = 0
⊢ False

Next tactic:
have := congr_arg Matrix.det (mvPolynomialX_mapMatrix_eval (1 : Matrix m m R))
/-- In a nontrivial ring, `Matrix.mvPolynomialX m m R` has non-zero determinant. -/
theorem det_mvPolynomialX_ne_zero [DecidableEq m] [Fintype m] [CommRing R] [Nontrivial R] :
    det (mvPolynomialX m m R) ≠ 0 := by
  intro h_det
  have := congr_arg Matrix.det (mvPolynomialX_mapMatrix_eval (1 : Matrix m m R))
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
S : Type u_4
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing R
inst✝ : Nontrivial R
h_det : det (mvPolynomialX m m R) = 0
this : det ((RingHom.mapMatrix (MvPolynomial.eval fun p => OfNat.ofNat 1 p.1 p.2)) (mvPolynomialX m m R)) = det 1
⊢ False

Next tactic:
rw [det_one, ← RingHom.map_det, h_det, RingHom.map_zero] at this
/-- In a nontrivial ring, `Matrix.mvPolynomialX m m R` has non-zero determinant. -/
theorem det_mvPolynomialX_ne_zero [DecidableEq m] [Fintype m] [CommRing R] [Nontrivial R] :
    det (mvPolynomialX m m R) ≠ 0 := by
  intro h_det
  have := congr_arg Matrix.det (mvPolynomialX_mapMatrix_eval (1 : Matrix m m R))
  rw [det_one, ← RingHom.map_det, h_det, RingHom.map_zero] at this
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
S : Type u_4
inst✝³ : DecidableEq m
inst✝² : Fintype m
inst✝¹ : CommRing R
inst✝ : Nontrivial R
h_det : det (mvPolynomialX m m R) = 0
this : 0 = 1
⊢ False

Next tactic:
exact zero_ne_one this
@[simp]
theorem L_mul {G : Type*} [Semigroup G] [TopologicalSpace G] [ChartedSpace H G] [SmoothMul I G]
    (g h : G) : 𝑳 I (g * h) = (𝑳 I g).comp (𝑳 I h) := by
  

Proof state:
𝕜 : Type u_1
inst✝¹⁶ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹⁵ : TopologicalSpace H
E : Type u_3
inst✝¹⁴ : NormedAddCommGroup E
inst✝¹³ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G✝ : Type u_4
inst✝¹² : Mul G✝
inst✝¹¹ : TopologicalSpace G✝
inst✝¹⁰ : ChartedSpace H G✝
inst✝⁹ : SmoothMul I G✝
E' : Type u_5
inst✝⁸ : NormedAddCommGroup E'
inst✝⁷ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝⁶ : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_7
inst✝⁵ : TopologicalSpace M
inst✝⁴ : ChartedSpace H' M
g✝ h✝ : G✝
G : Type u_8
inst✝³ : Semigroup G
inst✝² : TopologicalSpace G
inst✝¹ : ChartedSpace H G
inst✝ : SmoothMul I G
g h : G
⊢ 𝑳 I (g * h) = ContMDiffMap.comp (𝑳 I g) (𝑳 I h)

Next tactic:
ext
@[simp]
theorem L_mul {G : Type*} [Semigroup G] [TopologicalSpace G] [ChartedSpace H G] [SmoothMul I G]
    (g h : G) : 𝑳 I (g * h) = (𝑳 I g).comp (𝑳 I h) := by
  ext
  

Proof state:
case h
𝕜 : Type u_1
inst✝¹⁶ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹⁵ : TopologicalSpace H
E : Type u_3
inst✝¹⁴ : NormedAddCommGroup E
inst✝¹³ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G✝ : Type u_4
inst✝¹² : Mul G✝
inst✝¹¹ : TopologicalSpace G✝
inst✝¹⁰ : ChartedSpace H G✝
inst✝⁹ : SmoothMul I G✝
E' : Type u_5
inst✝⁸ : NormedAddCommGroup E'
inst✝⁷ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝⁶ : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_7
inst✝⁵ : TopologicalSpace M
inst✝⁴ : ChartedSpace H' M
g✝ h✝ : G✝
G : Type u_8
inst✝³ : Semigroup G
inst✝² : TopologicalSpace G
inst✝¹ : ChartedSpace H G
inst✝ : SmoothMul I G
g h x✝ : G
⊢ (𝑳 I (g * h)) x✝ = (ContMDiffMap.comp (𝑳 I g) (𝑳 I h)) x✝

Next tactic:
simp only [ContMDiffMap.comp_apply, L_apply, mul_assoc]
@[simp]
theorem R_mul {G : Type*} [Semigroup G] [TopologicalSpace G] [ChartedSpace H G] [SmoothMul I G]
    (g h : G) : 𝑹 I (g * h) = (𝑹 I h).comp (𝑹 I g) := by
  

Proof state:
𝕜 : Type u_1
inst✝¹⁶ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹⁵ : TopologicalSpace H
E : Type u_3
inst✝¹⁴ : NormedAddCommGroup E
inst✝¹³ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G✝ : Type u_4
inst✝¹² : Mul G✝
inst✝¹¹ : TopologicalSpace G✝
inst✝¹⁰ : ChartedSpace H G✝
inst✝⁹ : SmoothMul I G✝
E' : Type u_5
inst✝⁸ : NormedAddCommGroup E'
inst✝⁷ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝⁶ : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_7
inst✝⁵ : TopologicalSpace M
inst✝⁴ : ChartedSpace H' M
g✝ h✝ : G✝
G : Type u_8
inst✝³ : Semigroup G
inst✝² : TopologicalSpace G
inst✝¹ : ChartedSpace H G
inst✝ : SmoothMul I G
g h : G
⊢ 𝑹 I (g * h) = ContMDiffMap.comp (𝑹 I h) (𝑹 I g)

Next tactic:
ext
@[simp]
theorem R_mul {G : Type*} [Semigroup G] [TopologicalSpace G] [ChartedSpace H G] [SmoothMul I G]
    (g h : G) : 𝑹 I (g * h) = (𝑹 I h).comp (𝑹 I g) := by
  ext
  

Proof state:
case h
𝕜 : Type u_1
inst✝¹⁶ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹⁵ : TopologicalSpace H
E : Type u_3
inst✝¹⁴ : NormedAddCommGroup E
inst✝¹³ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G✝ : Type u_4
inst✝¹² : Mul G✝
inst✝¹¹ : TopologicalSpace G✝
inst✝¹⁰ : ChartedSpace H G✝
inst✝⁹ : SmoothMul I G✝
E' : Type u_5
inst✝⁸ : NormedAddCommGroup E'
inst✝⁷ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝⁶ : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_7
inst✝⁵ : TopologicalSpace M
inst✝⁴ : ChartedSpace H' M
g✝ h✝ : G✝
G : Type u_8
inst✝³ : Semigroup G
inst✝² : TopologicalSpace G
inst✝¹ : ChartedSpace H G
inst✝ : SmoothMul I G
g h x✝ : G
⊢ (𝑹 I (g * h)) x✝ = (ContMDiffMap.comp (𝑹 I h) (𝑹 I g)) x✝

Next tactic:
simp only [ContMDiffMap.comp_apply, R_apply, mul_assoc]
@[to_additive]
theorem smooth_pow : ∀ n : ℕ, Smooth I I fun a : G => a ^ n
  | 0 => by 

Proof state:
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
⊢ Smooth I I fun a => a ^ 0

Next tactic:
simp only [pow_zero]
@[to_additive]
theorem smooth_pow : ∀ n : ℕ, Smooth I I fun a : G => a ^ n
  | 0 => by simp only [pow_zero]; 

Proof state:
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
⊢ Smooth I I fun a => 1

Next tactic:
exact smooth_const
@[to_additive]
theorem smooth_pow : ∀ n : ℕ, Smooth I I fun a : G => a ^ n
  | 0 => by simp only [pow_zero]; exact smooth_const
  | k + 1 => by 

Proof state:
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
k : ℕ
⊢ Smooth I I fun a => a ^ (k + 1)

Next tactic:
simpa [pow_succ] using smooth_id.mul (smooth_pow _)
@[to_additive]
instance : MonoidHomClass (SmoothMonoidMorphism I I' G G') G G' where
  coe a := a.toFun
  coe_injective' f g h := by 

Proof state:
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
f g : SmoothMonoidMorphism I I' G G'
h : (fun a => a.toFun) f = (fun a => a.toFun) g
⊢ f = g

Next tactic:
cases f
@[to_additive]
instance : MonoidHomClass (SmoothMonoidMorphism I I' G G') G G' where
  coe a := a.toFun
  coe_injective' f g h := by cases f; 

Proof state:
case mk
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
g : SmoothMonoidMorphism I I' G G'
toMonoidHom✝ : G →* G'
smooth_toFun✝ : Smooth I I' toMonoidHom✝.toFun
h : (fun a => a.toFun) { toMonoidHom := toMonoidHom✝, smooth_toFun := smooth_toFun✝ } = (fun a => a.toFun) g
⊢ { toMonoidHom := toMonoidHom✝, smooth_toFun := smooth_toFun✝ } = g

Next tactic:
cases g
@[to_additive]
instance : MonoidHomClass (SmoothMonoidMorphism I I' G G') G G' where
  coe a := a.toFun
  coe_injective' f g h := by cases f; cases g; 

Proof state:
case mk.mk
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
toMonoidHom✝¹ : G →* G'
smooth_toFun✝¹ : Smooth I I' toMonoidHom✝¹.toFun
toMonoidHom✝ : G →* G'
smooth_toFun✝ : Smooth I I' toMonoidHom✝.toFun
h :
  (fun a => a.toFun) { toMonoidHom := toMonoidHom✝¹, smooth_toFun := smooth_toFun✝¹ } =
    (fun a => a.toFun) { toMonoidHom := toMonoidHom✝, smooth_toFun := smooth_toFun✝ }
⊢ { toMonoidHom := toMonoidHom✝¹, smooth_toFun := smooth_toFun✝¹ } =
    { toMonoidHom := toMonoidHom✝, smooth_toFun := smooth_toFun✝ }

Next tactic:
congr
@[to_additive]
instance : MonoidHomClass (SmoothMonoidMorphism I I' G G') G G' where
  coe a := a.toFun
  coe_injective' f g h := by cases f; cases g; congr; 

Proof state:
case mk.mk.e_toMonoidHom
𝕜 : Type u_1
inst✝¹⁴ : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹³ : TopologicalSpace H
E : Type u_3
inst✝¹² : NormedAddCommGroup E
inst✝¹¹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝¹⁰ : Monoid G
inst✝⁹ : TopologicalSpace G
inst✝⁸ : ChartedSpace H G
inst✝⁷ : SmoothMul I G
H' : Type u_5
inst✝⁶ : TopologicalSpace H'
E' : Type u_6
inst✝⁵ : NormedAddCommGroup E'
inst✝⁴ : NormedSpace 𝕜 E'
I' : ModelWithCorners 𝕜 E' H'
G' : Type u_7
inst✝³ : Monoid G'
inst✝² : TopologicalSpace G'
inst✝¹ : ChartedSpace H' G'
inst✝ : SmoothMul I' G'
toMonoidHom✝¹ : G →* G'
smooth_toFun✝¹ : Smooth I I' toMonoidHom✝¹.toFun
toMonoidHom✝ : G →* G'
smooth_toFun✝ : Smooth I I' toMonoidHom✝.toFun
h :
  (fun a => a.toFun) { toMonoidHom := toMonoidHom✝¹, smooth_toFun := smooth_toFun✝¹ } =
    (fun a => a.toFun) { toMonoidHom := toMonoidHom✝, smooth_toFun := smooth_toFun✝ }
⊢ toMonoidHom✝¹ = toMonoidHom✝

Next tactic:
exact FunLike.ext' h
@[to_additive]
theorem contMDiffWithinAt_finset_prod (h : ∀ i ∈ t, ContMDiffWithinAt I' I n (f i) s x) :
    ContMDiffWithinAt I' I n (fun x => ∏ i in t, f i x) s x := by
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
h : ∀ i ∈ t, ContMDiffWithinAt I' I n (f i) s x
⊢ ContMDiffWithinAt I' I n (fun x => ∏ i in t, f i x) s x

Next tactic:
simp only [← Finset.prod_apply]
@[to_additive]
theorem contMDiffWithinAt_finset_prod (h : ∀ i ∈ t, ContMDiffWithinAt I' I n (f i) s x) :
    ContMDiffWithinAt I' I n (fun x => ∏ i in t, f i x) s x := by
  simp only [← Finset.prod_apply]
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
h : ∀ i ∈ t, ContMDiffWithinAt I' I n (f i) s x
⊢ ContMDiffWithinAt I' I n (fun x => Finset.prod t (fun c => f c) x) s x

Next tactic:
exact contMDiffWithinAt_finset_prod' h
@[to_additive]
theorem contMDiff_finprod (h : ∀ i, ContMDiff I' I n (f i))
    (hfin : LocallyFinite fun i => mulSupport (f i)) : ContMDiff I' I n fun x => ∏ᶠ i, f i x := by
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
h : ∀ (i : ι), ContMDiff I' I n (f i)
hfin : LocallyFinite fun i => mulSupport (f i)
⊢ ContMDiff I' I n fun x => ∏ᶠ (i : ι), f i x

Next tactic:
intro x
@[to_additive]
theorem contMDiff_finprod (h : ∀ i, ContMDiff I' I n (f i))
    (hfin : LocallyFinite fun i => mulSupport (f i)) : ContMDiff I' I n fun x => ∏ᶠ i, f i x := by
  intro x
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x✝ : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
h : ∀ (i : ι), ContMDiff I' I n (f i)
hfin : LocallyFinite fun i => mulSupport (f i)
x : M
⊢ ContMDiffAt I' I n (fun x => ∏ᶠ (i : ι), f i x) x

Next tactic:
rcases finprod_eventually_eq_prod hfin x with ⟨s, hs⟩
@[to_additive]
theorem contMDiff_finprod (h : ∀ i, ContMDiff I' I n (f i))
    (hfin : LocallyFinite fun i => mulSupport (f i)) : ContMDiff I' I n fun x => ∏ᶠ i, f i x := by
  intro x
  rcases finprod_eventually_eq_prod hfin x with ⟨s, hs⟩
  

Proof state:
case intro
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s✝ : Set M
x✝ : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
h : ∀ (i : ι), ContMDiff I' I n (f i)
hfin : LocallyFinite fun i => mulSupport (f i)
x : M
s : Finset ι
hs : ∀ᶠ (y : M) in nhds x, ∏ᶠ (i : ι), f i y = ∏ i in s, f i y
⊢ ContMDiffAt I' I n (fun x => ∏ᶠ (i : ι), f i x) x

Next tactic:
exact (contMDiff_finset_prod (fun i _ => h i) x).congr_of_eventuallyEq hs
@[to_additive]
theorem contMDiff_finprod_cond (hc : ∀ i, p i → ContMDiff I' I n (f i))
    (hf : LocallyFinite fun i => mulSupport (f i)) :
    ContMDiff I' I n fun x => ∏ᶠ (i) (_ : p i), f i x := by
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
hc : ∀ (i : ι), p i → ContMDiff I' I n (f i)
hf : LocallyFinite fun i => mulSupport (f i)
⊢ ContMDiff I' I n fun x => ∏ᶠ (i : ι) (_ : p i), f i x

Next tactic:
simp only [← finprod_subtype_eq_finprod_cond]
@[to_additive]
theorem contMDiff_finprod_cond (hc : ∀ i, p i → ContMDiff I' I n (f i))
    (hf : LocallyFinite fun i => mulSupport (f i)) :
    ContMDiff I' I n fun x => ∏ᶠ (i) (_ : p i), f i x := by
  simp only [← finprod_subtype_eq_finprod_cond]
  

Proof state:
ι : Type u_1
𝕜 : Type u_2
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_3
inst✝¹¹ : TopologicalSpace H
E : Type u_4
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_5
inst✝⁸ : CommMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_6
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_7
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_8
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
s : Set M
x : M
t : Finset ι
f : ι → M → G
n : ℕ∞
p : ι → Prop
hc : ∀ (i : ι), p i → ContMDiff I' I n (f i)
hf : LocallyFinite fun i => mulSupport (f i)
⊢ ContMDiff I' I n fun x => ∏ᶠ (j : { i // p i }), f (↑j) x

Next tactic:
exact contMDiff_finprod (fun i => hc i i.2) (hf.comp_injective Subtype.coe_injective)
instance hasSmoothAddSelf : SmoothAdd 𝓘(𝕜, E) E :=
  ⟨by 

Proof state:
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
⊢ Smooth (ModelWithCorners.prod 𝓘(𝕜, E) 𝓘(𝕜, E)) 𝓘(𝕜, E) fun p => p.1 + p.2

Next tactic:
rw [← modelWithCornersSelf_prod]
instance hasSmoothAddSelf : SmoothAdd 𝓘(𝕜, E) E :=
  ⟨by rw [← modelWithCornersSelf_prod]; 

Proof state:
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
⊢ Smooth 𝓘(𝕜, E × E) 𝓘(𝕜, E) fun p => p.1 + p.2

Next tactic:
exact contDiff_add.contMDiff
@[to_additive]
theorem ContMDiffWithinAt.div_const (hf : ContMDiffWithinAt I' I n f s x) :
    ContMDiffWithinAt I' I n (fun x ↦ f x / c) s x := by
  

Proof state:
𝕜 : Type u_1
inst✝¹² : NontriviallyNormedField 𝕜
H : Type u_2
inst✝¹¹ : TopologicalSpace H
E : Type u_3
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedSpace 𝕜 E
I : ModelWithCorners 𝕜 E H
G : Type u_4
inst✝⁸ : DivInvMonoid G
inst✝⁷ : TopologicalSpace G
inst✝⁶ : ChartedSpace H G
inst✝⁵ : SmoothMul I G
E' : Type u_5
inst✝⁴ : NormedAddCommGroup E'
inst✝³ : NormedSpace 𝕜 E'
H' : Type u_6
inst✝² : TopologicalSpace H'
I' : ModelWithCorners 𝕜 E' H'
M : Type u_7
inst✝¹ : TopologicalSpace M
inst✝ : ChartedSpace H' M
f : M → G
s : Set M
x : M
n : ℕ∞
c : G
hf : ContMDiffWithinAt I' I n f s x
⊢ ContMDiffWithinAt I' I n (fun x => f x / c) s x

Next tactic:
simpa only [div_eq_mul_inv] using hf.mul contMDiffWithinAt_const