l3lab/ntp-mathlib huggingface dataset:
/-- The 0th cohomology of a cochain complex is isomorphic to the kernel of `d : C₀ → C₁`. -/
def CochainComplex.homology'ZeroIso [HasZeroObject V] [HasKernels V] [HasImages V] [HasCokernels V]
    (C : CochainComplex V ℕ) : C.homology' 0 ≅ kernel (C.d 0 1) :=
  (homology'.mapIso _ _
      (Arrow.isoMk (C.xPrevIsoSelf (by rw [CochainComplex.prev_nat_zero]; exact one_ne_zero))
          (Iso.refl _) (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
c : ComplexShape ι
C✝ : HomologicalComplex V c
inst✝³ : HasZeroObject V
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
C : CochainComplex V ℕ
⊢ (HomologicalComplex.xPrevIsoSelf C
          (_ : ¬ComplexShape.Rel (ComplexShape.up ℕ) (ComplexShape.prev (ComplexShape.up ℕ) 0) 0)).hom ≫
      (Arrow.mk 0).hom =
    (Arrow.mk (HomologicalComplex.dTo C 0)).hom ≫ (Iso.refl (Arrow.mk (HomologicalComplex.dTo C 0)).right).hom

Next tactic:
simp
/-- The 0th cohomology of a cochain complex is isomorphic to the kernel of `d : C₀ → C₁`. -/
def CochainComplex.homology'ZeroIso [HasZeroObject V] [HasKernels V] [HasImages V] [HasCokernels V]
    (C : CochainComplex V ℕ) : C.homology' 0 ≅ kernel (C.d 0 1) :=
  (homology'.mapIso _ _
      (Arrow.isoMk (C.xPrevIsoSelf (by rw [CochainComplex.prev_nat_zero]; exact one_ne_zero))
          (Iso.refl _) (by simp) : Arrow.mk (C.dTo 0) ≅ Arrow.mk 0)
      (Arrow.isoMk (Iso.refl _) (C.xNextIso rfl) (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
c : ComplexShape ι
C✝ : HomologicalComplex V c
inst✝³ : HasZeroObject V
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
C : CochainComplex V ℕ
⊢ (Iso.refl (Arrow.mk (HomologicalComplex.dFrom C 0)).left).hom ≫ (Arrow.mk (HomologicalComplex.d C 0 1)).hom =
    (Arrow.mk (HomologicalComplex.dFrom C 0)).hom ≫ (HomologicalComplex.xNextIso C (_ : 0 + 1 = 0 + 1)).hom

Next tactic:
simp
/-- The 0th cohomology of a cochain complex is isomorphic to the kernel of `d : C₀ → C₁`. -/
def CochainComplex.homology'ZeroIso [HasZeroObject V] [HasKernels V] [HasImages V] [HasCokernels V]
    (C : CochainComplex V ℕ) : C.homology' 0 ≅ kernel (C.d 0 1) :=
  (homology'.mapIso _ _
      (Arrow.isoMk (C.xPrevIsoSelf (by rw [CochainComplex.prev_nat_zero]; exact one_ne_zero))
          (Iso.refl _) (by simp) : Arrow.mk (C.dTo 0) ≅ Arrow.mk 0)
      (Arrow.isoMk (Iso.refl _) (C.xNextIso rfl) (by simp) :
        Arrow.mk (C.dFrom 0) ≅ Arrow.mk (C.d 0 1)) <|
      by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
c : ComplexShape ι
C✝ : HomologicalComplex V c
inst✝³ : HasZeroObject V
inst✝² : HasKernels V
inst✝¹ : HasImages V
inst✝ : HasCokernels V
C : CochainComplex V ℕ
⊢ (Arrow.isoMk
          (HomologicalComplex.xPrevIsoSelf C
            (_ : ¬ComplexShape.Rel (ComplexShape.up ℕ) (ComplexShape.prev (ComplexShape.up ℕ) 0) 0))
          (Iso.refl (Arrow.mk (HomologicalComplex.dTo C 0)).right)).hom.right =
    (Arrow.isoMk (Iso.refl (Arrow.mk (HomologicalComplex.dFrom C 0)).left)
          (HomologicalComplex.xNextIso C (_ : 0 + 1 = 0 + 1))).hom.left

Next tactic:
simp
/-- The morphism between cycles induced by a chain map. -/
abbrev cycles'Map (f : C₁ ⟶ C₂) (i : ι) : (C₁.cycles' i : V) ⟶ (C₂.cycles' i : V) :=
  Subobject.factorThru _ ((C₁.cycles' i).arrow ≫ f.f i) (kernelSubobject_factors _ _ (by 

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f✝ f : C₁ ⟶ C₂
i : ι
⊢ (Subobject.arrow (cycles' C₁ i) ≫ Hom.f f i) ≫ dFrom C₂ i = 0

Next tactic:
simp
@[reassoc, elementwise] -- @[simp] -- Porting note: simp can prove this
theorem cycles'Map_arrow (f : C₁ ⟶ C₂) (i : ι) :
    cycles'Map f i ≫ (C₂.cycles' i).arrow = (C₁.cycles' i).arrow ≫ f.f i := by 

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f✝ f : C₁ ⟶ C₂
i : ι
⊢ cycles'Map f i ≫ Subobject.arrow (cycles' C₂ i) = Subobject.arrow (cycles' C₁ i) ≫ Hom.f f i

Next tactic:
simp
@[simp]
theorem cycles'Map_id (i : ι) : cycles'Map (𝟙 C₁) i = 𝟙 _ := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f : C₁ ⟶ C₂
i : ι
⊢ cycles'Map (𝟙 C₁) i = 𝟙 (Subobject.underlying.obj (cycles' C₁ i))

Next tactic:
dsimp only [cycles'Map]
@[simp]
theorem cycles'Map_id (i : ι) : cycles'Map (𝟙 C₁) i = 𝟙 _ := by
  dsimp only [cycles'Map]
  

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f : C₁ ⟶ C₂
i : ι
⊢ Subobject.factorThru (cycles' C₁ i) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f (𝟙 C₁) i)
      (_ : Subobject.Factors (kernelSubobject (dFrom C₁ i)) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f (𝟙 C₁) i)) =
    𝟙 (Subobject.underlying.obj (cycles' C₁ i))

Next tactic:
simp
@[simp]
theorem cycles'Map_comp (f : C₁ ⟶ C₂) (g : C₂ ⟶ C₃) (i : ι) :
    cycles'Map (f ≫ g) i = cycles'Map f i ≫ cycles'Map g i := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f✝ f : C₁ ⟶ C₂
g : C₂ ⟶ C₃
i : ι
⊢ cycles'Map (f ≫ g) i = cycles'Map f i ≫ cycles'Map g i

Next tactic:
dsimp only [cycles'Map]
@[simp]
theorem cycles'Map_comp (f : C₁ ⟶ C₂) (g : C₂ ⟶ C₃) (i : ι) :
    cycles'Map (f ≫ g) i = cycles'Map f i ≫ cycles'Map g i := by
  dsimp only [cycles'Map]
  

Proof state:
ι : Type u_1
V : Type u
inst✝² : Category.{v, u} V
inst✝¹ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝ : HasKernels V
C₁ C₂ C₃ : HomologicalComplex V c
f✝ f : C₁ ⟶ C₂
g : C₂ ⟶ C₃
i : ι
⊢ Subobject.factorThru (cycles' C₃ i) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f (f ≫ g) i)
      (_ : Subobject.Factors (kernelSubobject (dFrom C₃ i)) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f (f ≫ g) i)) =
    Subobject.factorThru (cycles' C₂ i) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f f i)
        (_ : Subobject.Factors (kernelSubobject (dFrom C₂ i)) (Subobject.arrow (cycles' C₁ i) ≫ Hom.f f i)) ≫
      Subobject.factorThru (cycles' C₃ i) (Subobject.arrow (cycles' C₂ i) ≫ Hom.f g i)
        (_ : Subobject.Factors (kernelSubobject (dFrom C₃ i)) (Subobject.arrow (cycles' C₂ i) ≫ Hom.f g i))

Next tactic:
simp [Subobject.factorThru_right]
@[reassoc (attr := simp)]
theorem boundariesToCycles'_naturality (i : ι) :
    boundariesMap f i ≫ C₂.boundariesToCycles' i =
      C₁.boundariesToCycles' i ≫ cycles'Map f i := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝² : HasEqualizers V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
C₁ C₂ : HomologicalComplex V c
f : C₁ ⟶ C₂
i : ι
⊢ boundariesMap f i ≫ boundariesToCycles' C₂ i = boundariesToCycles' C₁ i ≫ cycles'Map f i

Next tactic:
ext
@[reassoc (attr := simp)]
theorem boundariesToCycles'_naturality (i : ι) :
    boundariesMap f i ≫ C₂.boundariesToCycles' i =
      C₁.boundariesToCycles' i ≫ cycles'Map f i := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
c : ComplexShape ι
C : HomologicalComplex V c
inst✝² : HasEqualizers V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
C₁ C₂ : HomologicalComplex V c
f : C₁ ⟶ C₂
i : ι
⊢ (boundariesMap f i ≫ boundariesToCycles' C₂ i) ≫ Subobject.arrow (cycles' C₂ i) =
    (boundariesToCycles' C₁ i ≫ cycles'Map f i) ≫ Subobject.arrow (cycles' C₂ i)

Next tactic:
simp
/-- Coerce an arithmetic function with values in `ℕ` to one with values in `R`. We cannot inline
this in `natCoe` because it gets unfolded too much. -/
@[coe]  -- porting note: added `coe` tag.
def natToArithmeticFunction [AddMonoidWithOne R] :
    (ArithmeticFunction ℕ) → (ArithmeticFunction R) :=
  fun f => ⟨fun n => ↑(f n), by 

Proof state:
R : Type u_1
inst✝ : AddMonoidWithOne R
f : ArithmeticFunction ℕ
⊢ (fun n => ↑(f n)) 0 = 0

Next tactic:
simp
/-- Coerce an arithmetic function with values in `ℤ` to one with values in `R`. We cannot inline
this in `intCoe` because it gets unfolded too much. -/
@[coe]
def ofInt [AddGroupWithOne R] :
    (ArithmeticFunction ℤ) → (ArithmeticFunction R) :=
  fun f => ⟨fun n => ↑(f n), by 

Proof state:
R : Type u_1
inst✝ : AddGroupWithOne R
f : ArithmeticFunction ℤ
⊢ (fun n => ↑(f n)) 0 = 0

Next tactic:
simp
@[simp]
theorem coe_coe [AddGroupWithOne R] {f : ArithmeticFunction ℕ} :
    ((f : ArithmeticFunction ℤ) : ArithmeticFunction R) = (f : ArithmeticFunction R) := by
  

Proof state:
R : Type u_1
inst✝ : AddGroupWithOne R
f : ArithmeticFunction ℕ
⊢ ↑↑f = ↑f

Next tactic:
ext
@[simp]
theorem coe_coe [AddGroupWithOne R] {f : ArithmeticFunction ℕ} :
    ((f : ArithmeticFunction ℤ) : ArithmeticFunction R) = (f : ArithmeticFunction R) := by
  ext
  

Proof state:
case h
R : Type u_1
inst✝ : AddGroupWithOne R
f : ArithmeticFunction ℕ
x✝ : ℕ
⊢ ↑↑f x✝ = ↑f x✝

Next tactic:
simp
@[simp]
theorem natCoe_one [AddMonoidWithOne R] :
    ((1 : ArithmeticFunction ℕ) : ArithmeticFunction R) = 1 := by
  

Proof state:
R : Type u_1
inst✝ : AddMonoidWithOne R
⊢ ↑1 = 1

Next tactic:
ext n
@[simp]
theorem natCoe_one [AddMonoidWithOne R] :
    ((1 : ArithmeticFunction ℕ) : ArithmeticFunction R) = 1 := by
  ext n
  

Proof state:
case h
R : Type u_1
inst✝ : AddMonoidWithOne R
n : ℕ
⊢ ↑1 n = 1 n

Next tactic:
simp [one_apply]
@[simp]
theorem intCoe_one [AddGroupWithOne R] : ((1 : ArithmeticFunction ℤ) :
    ArithmeticFunction R) = 1 := by
  

Proof state:
R : Type u_1
inst✝ : AddGroupWithOne R
⊢ ↑1 = 1

Next tactic:
ext n
@[simp]
theorem intCoe_one [AddGroupWithOne R] : ((1 : ArithmeticFunction ℤ) :
    ArithmeticFunction R) = 1 := by
  ext n
  

Proof state:
case h
R : Type u_1
inst✝ : AddGroupWithOne R
n : ℕ
⊢ ↑1 n = 1 n

Next tactic:
simp [one_apply]
instance add : Add (ArithmeticFunction R) :=
  ⟨fun f g => ⟨fun n => f n + g n, by 

Proof state:
R : Type u_1
inst✝ : AddMonoid R
f g : ArithmeticFunction R
⊢ (fun n => f n + g n) 0 = 0

Next tactic:
simp
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by 

Proof state:
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
n : ℕ
⊢ (fun x => if x = 1 then ↑n else 0) 0 = 0

Next tactic:
simp
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by 

Proof state:
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
⊢ NatCast.natCast 0 = 0

Next tactic:
ext
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by ext; 

Proof state:
case h
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
x✝ : ℕ
⊢ (NatCast.natCast 0) x✝ = 0 x✝

Next tactic:
simp
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by ext; simp
    natCast_succ := fun n => by 

Proof state:
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
n : ℕ
⊢ NatCast.natCast (n + 1) = NatCast.natCast n + 1

Next tactic:
ext x
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by ext; simp
    natCast_succ := fun n => by ext x; 

Proof state:
case h
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
n x : ℕ
⊢ (NatCast.natCast (n + 1)) x = (NatCast.natCast n + 1) x

Next tactic:
by_cases h : x = 1
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by ext; simp
    natCast_succ := fun n => by ext x; by_cases h : x = 1 <;> 

Proof state:
case pos
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
n x : ℕ
h : x = 1
⊢ (NatCast.natCast (n + 1)) x = (NatCast.natCast n + 1) x

Next tactic:
simp [h]
instance instAddMonoidWithOne [AddMonoidWithOne R] : AddMonoidWithOne (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid,
    ArithmeticFunction.one with
    natCast := fun n => ⟨fun x => if x = 1 then (n : R) else 0, by simp⟩
    natCast_zero := by ext; simp
    natCast_succ := fun n => by ext x; by_cases h : x = 1 <;> 

Proof state:
case neg
R : Type u_1
inst✝ : AddMonoidWithOne R
src✝¹ : AddMonoid (ArithmeticFunction R) := instAddMonoid
src✝ : One (ArithmeticFunction R) := one
n x : ℕ
h : ¬x = 1
⊢ (NatCast.natCast (n + 1)) x = (NatCast.natCast n + 1) x

Next tactic:
simp [h]
instance [AddGroup R] : AddGroup (ArithmeticFunction R) :=
  { ArithmeticFunction.instAddMonoid with
    neg := fun f => ⟨fun n => -f n, by 

Proof state:
R : Type u_1
inst✝ : AddGroup R
src✝ : AddMonoid (ArithmeticFunction R) := instAddMonoid
f : ArithmeticFunction R
⊢ (fun n => -f n) 0 = 0

Next tactic:
simp
instance [AddCommGroup R] : AddCommGroup (ArithmeticFunction R) :=
  { show AddGroup (ArithmeticFunction R) by 

Proof state:
R : Type u_1
inst✝ : AddCommGroup R
⊢ AddGroup (ArithmeticFunction R)

Next tactic:
infer_instance
/-- The Dirichlet convolution of two arithmetic functions `f` and `g` is another arithmetic function
  such that `(f * g) n` is the sum of `f x * g y` over all `(x,y)` such that `x * y = n`. -/
instance : SMul (ArithmeticFunction R) (ArithmeticFunction M) :=
  ⟨fun f g => ⟨fun n => ∑ x in divisorsAntidiagonal n, f x.fst • g x.snd, by 

Proof state:
R : Type u_1
M : Type u_2
inst✝² : Zero R
inst✝¹ : AddCommMonoid M
inst✝ : SMul R M
f : ArithmeticFunction R
g : ArithmeticFunction M
⊢ (fun n => ∑ x in divisorsAntidiagonal n, f x.1 • g x.2) 0 = 0

Next tactic:
simp
theorem mul_apply_one [Semiring R] {f g : ArithmeticFunction R} : (f * g) 1 = f 1 * g 1 := by 

Proof state:
R : Type u_1
inst✝ : Semiring R
f g : ArithmeticFunction R
⊢ (f * g) 1 = f 1 * g 1

Next tactic:
simp
@[simp, norm_cast]
theorem natCoe_mul [Semiring R] {f g : ArithmeticFunction ℕ} :
    (↑(f * g) : ArithmeticFunction R) = f * g := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f g : ArithmeticFunction ℕ
⊢ ↑(f * g) = ↑f * ↑g

Next tactic:
ext n
@[simp, norm_cast]
theorem natCoe_mul [Semiring R] {f g : ArithmeticFunction ℕ} :
    (↑(f * g) : ArithmeticFunction R) = f * g := by
  ext n
  

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
f g : ArithmeticFunction ℕ
n : ℕ
⊢ ↑(f * g) n = (↑f * ↑g) n

Next tactic:
simp
@[simp, norm_cast]
theorem intCoe_mul [Ring R] {f g : ArithmeticFunction ℤ} :
    (↑(f * g) : ArithmeticFunction R) = ↑f * g := by
  

Proof state:
R : Type u_1
inst✝ : Ring R
f g : ArithmeticFunction ℤ
⊢ ↑(f * g) = ↑f * ↑g

Next tactic:
ext n
@[simp, norm_cast]
theorem intCoe_mul [Ring R] {f g : ArithmeticFunction ℤ} :
    (↑(f * g) : ArithmeticFunction R) = ↑f * g := by
  ext n
  

Proof state:
case h
R : Type u_1
inst✝ : Ring R
f g : ArithmeticFunction ℤ
n : ℕ
⊢ ↑(f * g) n = (↑f * ↑g) n

Next tactic:
simp
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  

Proof state:
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
⊢ (f * g) • h = f • g • h

Next tactic:
ext n
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  

Proof state:
case h
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ((f * g) • h) n = (f • g • h) n

Next tactic:
simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  

Proof state:
case h
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∑ x in Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1, f x.snd.1 • g x.snd.2 • h x.fst.2 =
    ∑ x in Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.2, f x.fst.1 • g x.snd.1 • h x.snd.2

Next tactic:
apply Finset.sum_bij
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  apply Finset.sum_bij
  

Proof state:
case h.hi
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∀ (a : (_ : ℕ × ℕ) × ℕ × ℕ) (ha : a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1),
    ?h.i a ha ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.2
case h.h
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∀ (a : (_ : ℕ × ℕ) × ℕ × ℕ) (ha : a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1),
    f a.snd.1 • g a.snd.2 • h a.fst.2 = f (?h.i a ha).fst.1 • g (?h.i a ha).snd.1 • h (?h.i a ha).snd.2
case h.i_inj
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∀ (a₁ a₂ : (_ : ℕ × ℕ) × ℕ × ℕ) (ha₁ : a₁ ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1)
    (ha₂ : a₂ ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1),
    ?h.i a₁ ha₁ = ?h.i a₂ ha₂ → a₁ = a₂
case h.i_surj
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∀ b ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.2,
    ∃ a, ∃ (ha : a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1), b = ?h.i a ha
case h.i
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ (a : (_ : ℕ × ℕ) × ℕ × ℕ) →
    (a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) → (_ : ℕ × ℕ) × ℕ × ℕ

Next tactic:
pick_goal 5
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  apply Finset.sum_bij
  pick_goal 5
  · 

Proof state:
case h.i
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ (a : (_ : ℕ × ℕ) × ℕ × ℕ) →
    (a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) → (_ : ℕ × ℕ) × ℕ × ℕ

Next tactic:
rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ _H
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  apply Finset.sum_bij
  pick_goal 5
  · rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ _H
    

Proof state:
case h.i.mk.mk.mk
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n i j k l : ℕ
_H : { fst := (i, j), snd := (k, l) } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1
⊢ (_ : ℕ × ℕ) × ℕ × ℕ

Next tactic:
exact ⟨(k, l * j), (l, j)⟩
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  apply Finset.sum_bij
  pick_goal 5
  · rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ _H
    exact ⟨(k, l * j), (l, j)⟩
  · 

Proof state:
case h.hi
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n : ℕ
⊢ ∀ (a : (_ : ℕ × ℕ) × ℕ × ℕ) (ha : a ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1),
    Sigma.casesOn (motive := fun x =>
        (x ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) → (_ : ℕ × ℕ) × ℕ × ℕ) a
        (fun fst snd =>
          Prod.casesOn (motive := fun x =>
            ({ fst := x, snd := snd } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) →
              (_ : ℕ × ℕ) × ℕ × ℕ)
            fst fun i j =>
            Prod.casesOn (motive := fun x =>
              ({ fst := (i, j), snd := x } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) →
                (_ : ℕ × ℕ) × ℕ × ℕ)
              snd fun k l _H => { fst := (k, l * j), snd := (l, j) })
        ha ∈
      Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.2

Next tactic:
rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ H
theorem mul_smul' (f g : ArithmeticFunction R) (h : ArithmeticFunction M) :
    (f * g) • h = f • g • h := by
  ext n
  simp only [mul_apply, smul_apply, sum_smul, mul_smul, smul_sum, Finset.sum_sigma']
  apply Finset.sum_bij
  pick_goal 5
  · rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ _H
    exact ⟨(k, l * j), (l, j)⟩
  · rintro ⟨⟨i, j⟩, ⟨k, l⟩⟩ H
    

Proof state:
case h.hi.mk.mk.mk
R : Type u_1
M : Type u_2
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
f g : ArithmeticFunction R
h : ArithmeticFunction M
n i j k l : ℕ
H : { fst := (i, j), snd := (k, l) } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1
⊢ Sigma.casesOn (motive := fun x =>
      (x ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) → (_ : ℕ × ℕ) × ℕ × ℕ)
      { fst := (i, j), snd := (k, l) }
      (fun fst snd =>
        Prod.casesOn (motive := fun x =>
          ({ fst := x, snd := snd } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) →
            (_ : ℕ × ℕ) × ℕ × ℕ)
          fst fun i j =>
          Prod.casesOn (motive := fun x =>
            ({ fst := (i, j), snd := x } ∈ Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.1) →
              (_ : ℕ × ℕ) × ℕ × ℕ)
            snd fun k l _H => { fst := (k, l * j), snd := (l, j) })
      H ∈
    Finset.sigma (divisorsAntidiagonal n) fun a => divisorsAntidiagonal a.2

Next tactic:
simp only [Finset.mem_sigma, mem_divisorsAntidiagonal] at H ⊢