l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem ppow_zero {f : ArithmeticFunction R} : f.ppow 0 = ζ := by 

Proof state:
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
⊢ ppow f 0 = ↑ζ

Next tactic:
rw [ppow, dif_pos rfl]
@[simp]
theorem ppow_apply {f : ArithmeticFunction R} {k x : ℕ} (kpos : 0 < k) : f.ppow k x = f x ^ k := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k x : ℕ
kpos : 0 < k
⊢ (ppow f k) x = f x ^ k

Next tactic:
rw [ppow, dif_neg (ne_of_gt kpos)]
@[simp]
theorem ppow_apply {f : ArithmeticFunction R} {k x : ℕ} (kpos : 0 < k) : f.ppow k x = f x ^ k := by
  rw [ppow, dif_neg (ne_of_gt kpos)]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k x : ℕ
kpos : 0 < k
⊢ { toFun := fun x => f x ^ k, map_zero' := (_ : (fun x => f x ^ k) 0 = 0) } x = f x ^ k

Next tactic:
rfl
theorem ppow_succ {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k : ℕ
⊢ ppow f (k + 1) = pmul f (ppow f k)

Next tactic:
ext x
theorem ppow_succ {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by
  ext x
  

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k x : ℕ
⊢ (ppow f (k + 1)) x = (pmul f (ppow f k)) x

Next tactic:
rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ]
theorem ppow_succ {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ]
  

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k x : ℕ
⊢ f x * f x ^ k = (pmul f (ppow f k)) x

Next tactic:
induction k
theorem ppow_succ {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ]
  induction k <;> 

Proof state:
case h.zero
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
x : ℕ
⊢ f x * f x ^ Nat.zero = (pmul f (ppow f Nat.zero)) x

Next tactic:
simp
theorem ppow_succ {f : ArithmeticFunction R} {k : ℕ} : f.ppow (k + 1) = f.pmul (f.ppow k) := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ]
  induction k <;> 

Proof state:
case h.succ
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
x n✝ : ℕ
n_ih✝ : f x * f x ^ n✝ = (pmul f (ppow f n✝)) x
⊢ f x * f x ^ succ n✝ = (pmul f (ppow f (succ n✝))) x

Next tactic:
simp
theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} {kpos : 0 < k} :
    f.ppow (k + 1) = (f.ppow k).pmul f := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k : ℕ
kpos : 0 < k
⊢ ppow f (k + 1) = pmul (ppow f k) f

Next tactic:
ext x
theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} {kpos : 0 < k} :
    f.ppow (k + 1) = (f.ppow k).pmul f := by
  ext x
  

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k : ℕ
kpos : 0 < k
x : ℕ
⊢ (ppow f (k + 1)) x = (pmul (ppow f k) f) x

Next tactic:
rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ']
theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} {kpos : 0 < k} :
    f.ppow (k + 1) = (f.ppow k).pmul f := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ']
  

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
k : ℕ
kpos : 0 < k
x : ℕ
⊢ f x ^ k * f x = (pmul (ppow f k) f) x

Next tactic:
induction k
theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} {kpos : 0 < k} :
    f.ppow (k + 1) = (f.ppow k).pmul f := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ']
  induction k <;> 

Proof state:
case h.zero
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
x : ℕ
kpos : 0 < Nat.zero
⊢ f x ^ Nat.zero * f x = (pmul (ppow f Nat.zero) f) x

Next tactic:
simp
theorem ppow_succ' {f : ArithmeticFunction R} {k : ℕ} {kpos : 0 < k} :
    f.ppow (k + 1) = (f.ppow k).pmul f := by
  ext x
  rw [ppow_apply (Nat.succ_pos k), _root_.pow_succ']
  induction k <;> 

Proof state:
case h.succ
R : Type u_1
inst✝ : Semiring R
f : ArithmeticFunction R
x n✝ : ℕ
n_ih✝ : ∀ {kpos : 0 < n✝}, f x ^ n✝ * f x = (pmul (ppow f n✝) f) x
kpos : 0 < succ n✝
⊢ f x ^ succ n✝ * f x = (pmul (ppow f (succ n✝)) f) x

Next tactic:
simp
/-- This is the pointwise division of `ArithmeticFunction`s. -/
def pdiv [GroupWithZero R] (f g : ArithmeticFunction R) : ArithmeticFunction R :=
  ⟨fun n => f n / g n, by 

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

Next tactic:
simp only [map_zero, ne_eq, not_true, div_zero]
/-- This result only holds for `DivisionSemiring`s instead of `GroupWithZero`s because zeta takes
values in ℕ, and hence the coersion requires an `AddMonoidWithOne`. TODO: Generalise zeta -/
@[simp]
theorem pdiv_zeta [DivisionSemiring R] (f : ArithmeticFunction R) :
    pdiv f zeta = f := by
  

Proof state:
R : Type u_1
inst✝ : DivisionSemiring R
f : ArithmeticFunction R
⊢ pdiv f ↑ζ = f

Next tactic:
ext n
/-- This result only holds for `DivisionSemiring`s instead of `GroupWithZero`s because zeta takes
values in ℕ, and hence the coersion requires an `AddMonoidWithOne`. TODO: Generalise zeta -/
@[simp]
theorem pdiv_zeta [DivisionSemiring R] (f : ArithmeticFunction R) :
    pdiv f zeta = f := by
  ext n
  

Proof state:
case h
R : Type u_1
inst✝ : DivisionSemiring R
f : ArithmeticFunction R
n : ℕ
⊢ (pdiv f ↑ζ) n = f n

Next tactic:
cases n
/-- This result only holds for `DivisionSemiring`s instead of `GroupWithZero`s because zeta takes
values in ℕ, and hence the coersion requires an `AddMonoidWithOne`. TODO: Generalise zeta -/
@[simp]
theorem pdiv_zeta [DivisionSemiring R] (f : ArithmeticFunction R) :
    pdiv f zeta = f := by
  ext n
  cases n <;> 

Proof state:
case h.zero
R : Type u_1
inst✝ : DivisionSemiring R
f : ArithmeticFunction R
⊢ (pdiv f ↑ζ) Nat.zero = f Nat.zero

Next tactic:
simp [succ_ne_zero]
/-- This result only holds for `DivisionSemiring`s instead of `GroupWithZero`s because zeta takes
values in ℕ, and hence the coersion requires an `AddMonoidWithOne`. TODO: Generalise zeta -/
@[simp]
theorem pdiv_zeta [DivisionSemiring R] (f : ArithmeticFunction R) :
    pdiv f zeta = f := by
  ext n
  cases n <;> 

Proof state:
case h.succ
R : Type u_1
inst✝ : DivisionSemiring R
f : ArithmeticFunction R
n✝ : ℕ
⊢ (pdiv f ↑ζ) (succ n✝) = f (succ n✝)

Next tactic:
simp [succ_ne_zero]
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  

Proof state:
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
s : Finset ι
hs : Set.Pairwise (↑s) (Coprime on g)
⊢ f (∏ i in s, g i) = ∏ i in s, f (g i)

Next tactic:
classical
    induction' s using Finset.induction_on with a s has ih hs
    · simp [hf]
    rw [coe_insert, Set.pairwise_insert_of_symmetric (Coprime.symmetric.comap g)] at hs
    rw [prod_insert has, prod_insert has, hf.map_mul_of_coprime, ih hs.1]
    exact .prod_right fun i hi => hs.2 _ hi (hi.ne_of_not_mem has).symm
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  classical
    

Proof state:
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
s : Finset ι
hs : Set.Pairwise (↑s) (Coprime on g)
⊢ f (∏ i in s, g i) = ∏ i in s, f (g i)

Next tactic:
induction' s using Finset.induction_on with a s has ih hs
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  classical
    induction' s using Finset.induction_on with a s has ih hs
    · 

Proof state:
case empty
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
hs : Set.Pairwise (↑∅) (Coprime on g)
⊢ f (∏ i in ∅, g i) = ∏ i in ∅, f (g i)

Next tactic:
simp [hf]
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  classical
    induction' s using Finset.induction_on with a s has ih hs
    · simp [hf]
    

Proof state:
case insert
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
a : ι
s : Finset ι
has : a ∉ s
ih : Set.Pairwise (↑s) (Coprime on g) → f (∏ i in s, g i) = ∏ i in s, f (g i)
hs : Set.Pairwise (↑(insert a s)) (Coprime on g)
⊢ f (∏ i in insert a s, g i) = ∏ i in insert a s, f (g i)

Next tactic:
rw [coe_insert, Set.pairwise_insert_of_symmetric (Coprime.symmetric.comap g)] at hs
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  classical
    induction' s using Finset.induction_on with a s has ih hs
    · simp [hf]
    rw [coe_insert, Set.pairwise_insert_of_symmetric (Coprime.symmetric.comap g)] at hs
    

Proof state:
case insert
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
a : ι
s : Finset ι
has : a ∉ s
ih : Set.Pairwise (↑s) (Coprime on g) → f (∏ i in s, g i) = ∏ i in s, f (g i)
hs : Set.Pairwise (↑s) (Coprime on g) ∧ ∀ b ∈ ↑s, a ≠ b → (Coprime on g) a b
⊢ f (∏ i in insert a s, g i) = ∏ i in insert a s, f (g i)

Next tactic:
rw [prod_insert has, prod_insert has, hf.map_mul_of_coprime, ih hs.1]
theorem map_prod {ι : Type*} [CommMonoidWithZero R] (g : ι → ℕ) {f : Nat.ArithmeticFunction R}
    (hf : f.IsMultiplicative) (s : Finset ι) (hs : (s : Set ι).Pairwise (Coprime on g)) :
    f (∏ i in s, g i) = ∏ i in s, f (g i) := by
  classical
    induction' s using Finset.induction_on with a s has ih hs
    · simp [hf]
    rw [coe_insert, Set.pairwise_insert_of_symmetric (Coprime.symmetric.comap g)] at hs
    rw [prod_insert has, prod_insert has, hf.map_mul_of_coprime, ih hs.1]
    

Proof state:
case insert
R : Type u_1
ι : Type u_2
inst✝ : CommMonoidWithZero R
g : ι → ℕ
f : ArithmeticFunction R
hf : IsMultiplicative f
a : ι
s : Finset ι
has : a ∉ s
ih : Set.Pairwise (↑s) (Coprime on g) → f (∏ i in s, g i) = ∏ i in s, f (g i)
hs : Set.Pairwise (↑s) (Coprime on g) ∧ ∀ b ∈ ↑s, a ≠ b → (Coprime on g) a b
⊢ Coprime (g a) (∏ x in s, g x)

Next tactic:
exact .prod_right fun i hi => hs.2 _ hi (hi.ne_of_not_mem has).symm
theorem nat_cast {f : ArithmeticFunction ℕ} [Semiring R] (h : f.IsMultiplicative) :
    IsMultiplicative (f : ArithmeticFunction R) :=
                                 -- porting note: was `by simp [cop, h]`
  ⟨by 

Proof state:
R : Type u_1
f : ArithmeticFunction ℕ
inst✝ : Semiring R
h : IsMultiplicative f
⊢ ↑f 1 = 1

Next tactic:
simp [h]
theorem nat_cast {f : ArithmeticFunction ℕ} [Semiring R] (h : f.IsMultiplicative) :
    IsMultiplicative (f : ArithmeticFunction R) :=
                                 -- porting note: was `by simp [cop, h]`
  ⟨by simp [h], fun {m n} cop => by 

Proof state:
R : Type u_1
f : ArithmeticFunction ℕ
inst✝ : Semiring R
h : IsMultiplicative f
m n : ℕ
cop : Coprime m n
⊢ ↑f (m * n) = ↑f m * ↑f n

Next tactic:
simp [h.2 cop]
theorem int_cast {f : ArithmeticFunction ℤ} [Ring R] (h : f.IsMultiplicative) :
    IsMultiplicative (f : ArithmeticFunction R) :=
                                 -- porting note: was `by simp [cop, h]`
  ⟨by 

Proof state:
R : Type u_1
f : ArithmeticFunction ℤ
inst✝ : Ring R
h : IsMultiplicative f
⊢ ↑f 1 = 1

Next tactic:
simp [h]
theorem int_cast {f : ArithmeticFunction ℤ} [Ring R] (h : f.IsMultiplicative) :
    IsMultiplicative (f : ArithmeticFunction R) :=
                                 -- porting note: was `by simp [cop, h]`
  ⟨by simp [h], fun {m n} cop => by 

Proof state:
R : Type u_1
f : ArithmeticFunction ℤ
inst✝ : Ring R
h : IsMultiplicative f
m n : ℕ
cop : Coprime m n
⊢ ↑f (m * n) = ↑f m * ↑f n

Next tactic:
simp [h.2 cop]
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
⊢ (f * g) 1 = 1

Next tactic:
simp [hf.1, hg.1]
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
⊢ ∀ {m n : ℕ}, Coprime m n → (f * g) (m * n) = (f * g) m * (f * g) n

Next tactic:
simp only [mul_apply]
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
⊢ ∀ {m n : ℕ},
    Coprime m n →
      ∑ x in divisorsAntidiagonal (m * n), f x.1 * g x.2 =
        (∑ x in divisorsAntidiagonal m, f x.1 * g x.2) * ∑ x in divisorsAntidiagonal n, f x.1 * g x.2

Next tactic:
intro m n cop
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
⊢ ∑ x in divisorsAntidiagonal (m * n), f x.1 * g x.2 =
    (∑ x in divisorsAntidiagonal m, f x.1 * g x.2) * ∑ x in divisorsAntidiagonal n, f x.1 * g x.2

Next tactic:
rw [sum_mul_sum]
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
⊢ ∑ x in divisorsAntidiagonal (m * n), f x.1 * g x.2 =
    ∑ p in divisorsAntidiagonal m ×ˢ divisorsAntidiagonal n, f p.1.1 * g p.1.2 * (f p.2.1 * g p.2.2)

Next tactic:
symm
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
⊢ ∑ p in divisorsAntidiagonal m ×ˢ divisorsAntidiagonal n, f p.1.1 * g p.1.2 * (f p.2.1 * g p.2.2) =
    ∑ x in divisorsAntidiagonal (m * n), f x.1 * g x.2

Next tactic:
apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · 

Proof state:
case hi
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
⊢ ∀ a ∈ divisorsAntidiagonal m ×ˢ divisorsAntidiagonal n, (a.1.1 * a.2.1, a.1.2 * a.2.2) ∈ divisorsAntidiagonal (m * n)

Next tactic:
rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      

Proof state:
case hi.mk.mk.mk
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
a1 a2 b1 b2 : ℕ
h : ((a1, a2), b1, b2) ∈ divisorsAntidiagonal m ×ˢ divisorsAntidiagonal n
⊢ (((a1, a2), b1, b2).1.1 * ((a1, a2), b1, b2).2.1, ((a1, a2), b1, b2).1.2 * ((a1, a2), b1, b2).2.2) ∈
    divisorsAntidiagonal (m * n)

Next tactic:
simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      

Proof state:
case hi.mk.mk.mk
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
a1 a2 b1 b2 : ℕ
h : (a1 * a2 = m ∧ ¬m = 0) ∧ b1 * b2 = n ∧ ¬n = 0
⊢ (((a1, a2), b1, b2).1.1 * ((a1, a2), b1, b2).2.1, ((a1, a2), b1, b2).1.2 * ((a1, a2), b1, b2).2.2) ∈
    divisorsAntidiagonal (m * n)

Next tactic:
rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      

Proof state:
case hi.mk.mk.mk.intro.intro.intro
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
a1 a2 b1 b2 : ℕ
ha : ¬a1 * a2 = 0
cop : Coprime (a1 * a2) (b1 * b2)
hb : ¬b1 * b2 = 0
⊢ (((a1, a2), b1, b2).1.1 * ((a1, a2), b1, b2).2.1, ((a1, a2), b1, b2).1.2 * ((a1, a2), b1, b2).2.2) ∈
    divisorsAntidiagonal (a1 * a2 * (b1 * b2))

Next tactic:
simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      

Proof state:
case hi.mk.mk.mk.intro.intro.intro
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
a1 a2 b1 b2 : ℕ
ha : ¬a1 * a2 = 0
cop : Coprime (a1 * a2) (b1 * b2)
hb : ¬b1 * b2 = 0
⊢ a1 * b1 * (a2 * b2) = a1 * a2 * (b1 * b2) ∧ ¬((a1 = 0 ∨ a2 = 0) ∨ b1 = 0 ∨ b2 = 0)

Next tactic:
constructor
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      constructor
      · 

Proof state:
case hi.mk.mk.mk.intro.intro.intro.left
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
a1 a2 b1 b2 : ℕ
ha : ¬a1 * a2 = 0
cop : Coprime (a1 * a2) (b1 * b2)
hb : ¬b1 * b2 = 0
⊢ a1 * b1 * (a2 * b2) = a1 * a2 * (b1 * b2)

Next tactic:
ring
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      constructor
      · ring
      

Proof state:
case hi.mk.mk.mk.intro.intro.intro.right
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
a1 a2 b1 b2 : ℕ
ha : ¬a1 * a2 = 0
cop : Coprime (a1 * a2) (b1 * b2)
hb : ¬b1 * b2 = 0
⊢ ¬((a1 = 0 ∨ a2 = 0) ∨ b1 = 0 ∨ b2 = 0)

Next tactic:
rw [Nat.mul_eq_zero] at *
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      constructor
      · ring
      rw [Nat.mul_eq_zero] at *
      

Proof state:
case hi.mk.mk.mk.intro.intro.intro.right
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
a1 a2 b1 b2 : ℕ
ha : ¬(a1 = 0 ∨ a2 = 0)
cop : Coprime (a1 * a2) (b1 * b2)
hb : ¬(b1 = 0 ∨ b2 = 0)
⊢ ¬((a1 = 0 ∨ a2 = 0) ∨ b1 = 0 ∨ b2 = 0)

Next tactic:
apply not_or_of_not ha hb
theorem mul [CommSemiring R] {f g : ArithmeticFunction R} (hf : f.IsMultiplicative)
    (hg : g.IsMultiplicative) : IsMultiplicative (f * g) :=
  ⟨by
    -- porting note was `simp [hf, hg]`.
    simp [hf.1, hg.1],
  by
    simp only [mul_apply]
    intro m n cop
    rw [sum_mul_sum]
    symm
    apply sum_bij fun (x : (ℕ × ℕ) × ℕ × ℕ) _h => (x.1.1 * x.2.1, x.1.2 * x.2.2)
    · rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h
      simp only [mem_divisorsAntidiagonal, Ne.def, mem_product] at h
      rcases h with ⟨⟨rfl, ha⟩, ⟨rfl, hb⟩⟩
      simp only [mem_divisorsAntidiagonal, Nat.mul_eq_zero, Ne.def]
      constructor
      · ring
      rw [Nat.mul_eq_zero] at *
      apply not_or_of_not ha hb
    · 

Proof state:
case h
R : Type u_1
inst✝ : CommSemiring R
f g : ArithmeticFunction R
hf : IsMultiplicative f
hg : IsMultiplicative g
m n : ℕ
cop : Coprime m n
⊢ ∀ a ∈ divisorsAntidiagonal m ×ˢ divisorsAntidiagonal n,
    f a.1.1 * g a.1.2 * (f a.2.1 * g a.2.2) = f (a.1.1 * a.2.1, a.1.2 * a.2.2).1 * g (a.1.1 * a.2.1, a.1.2 * a.2.2).2

Next tactic:
rintro ⟨⟨a1, a2⟩, ⟨b1, b2⟩⟩ h