@[to_additive]
theorem prod_option_index [AddCommMonoid M] [CommMonoid N] (f : Option α →₀ M)
    (b : Option α → M → N) (h_zero : ∀ o, b o 0 = 1)
    (h_add : ∀ o m₁ m₂, b o (m₁ + m₂) = b o m₁ * b o m₂) :
    f.prod b = b none (f none) * f.some.prod fun a => b (Option.some a) := by
  classical
    apply induction_linear f
    · simp [some_zero, h_zero]
    · intro f₁ f₂ h₁ h₂
      rw [Finsupp.prod_add_index, h₁, h₂, some_add, Finsupp.prod_add_index]
      simp only [h_add, Pi.add_apply, Finsupp.coe_add]
      

Proof state:
case hadd
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : CommMonoid N
f : Option α →₀ M
b : Option α → M → N
h_zero : ∀ (o : Option α), b o 0 = 1
h_add : ∀ (o : Option α) (m₁ m₂ : M), b o (m₁ + m₂) = b o m₁ * b o m₂
f₁ f₂ : Option α →₀ M
h₁ : prod f₁ b = b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)
h₂ : prod f₂ b = b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)
⊢ (b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)) *
      (b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)) =
    b none (f₁ none) * b none (f₂ none) *
      ((prod (some f₁) fun a => b (Option.some a)) * prod (some f₂) fun a => b (Option.some a))
case hadd.h_zero
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : CommMonoid N
f : Option α →₀ M
b : Option α → M → N
h_zero : ∀ (o : Option α), b o 0 = 1
h_add : ∀ (o : Option α) (m₁ m₂ : M), b o (m₁ + m₂) = b o m₁ * b o m₂
f₁ f₂ : Option α →₀ M
h₁ : prod f₁ b = b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)
h₂ : prod f₂ b = b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)
⊢ ∀ a ∈ (some f₁).support ∪ (some f₂).support, b (Option.some a) 0 = 1
case hadd.h_add
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : CommMonoid N
f : Option α →₀ M
b : Option α → M → N
h_zero : ∀ (o : Option α), b o 0 = 1
h_add : ∀ (o : Option α) (m₁ m₂ : M), b o (m₁ + m₂) = b o m₁ * b o m₂
f₁ f₂ : Option α →₀ M
h₁ : prod f₁ b = b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)
h₂ : prod f₂ b = b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)
⊢ ∀ a ∈ (some f₁).support ∪ (some f₂).support,
    ∀ (b₁ b₂ : M), b (Option.some a) (b₁ + b₂) = b (Option.some a) b₁ * b (Option.some a) b₂
case hadd.h_zero
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : CommMonoid N
f : Option α →₀ M
b : Option α → M → N
h_zero : ∀ (o : Option α), b o 0 = 1
h_add : ∀ (o : Option α) (m₁ m₂ : M), b o (m₁ + m₂) = b o m₁ * b o m₂
f₁ f₂ : Option α →₀ M
h₁ : prod f₁ b = b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)
h₂ : prod f₂ b = b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)
⊢ ∀ a ∈ f₁.support ∪ f₂.support, b a 0 = 1
case hadd.h_add
α : Type u_1
β : Type u_2
γ : Type u_3
ι : Type u_4
M : Type u_5
M' : Type u_6
N : Type u_7
P : Type u_8
G : Type u_9
H : Type u_10
R : Type u_11
S : Type u_12
inst✝¹ : AddCommMonoid M
inst✝ : CommMonoid N
f : Option α →₀ M
b : Option α → M → N
h_zero : ∀ (o : Option α), b o 0 = 1
h_add : ∀ (o : Option α) (m₁ m₂ : M), b o (m₁ + m₂) = b o m₁ * b o m₂
f₁ f₂ : Option α →₀ M
h₁ : prod f₁ b = b none (f₁ none) * prod (some f₁) fun a => b (Option.some a)
h₂ : prod f₂ b = b none (f₂ none) * prod (some f₂) fun a => b (Option.some a)
⊢ ∀ a ∈ f₁.support ∪ f₂.support, ∀ (b₁ b₂ : M), b a (b₁ + b₂) = b a b₁ * b a b₂

Next tactic:
rw [mul_mul_mul_comm]