[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
inst✝ : CommMonoid α
s : Finset α
⊢ Multiset.prod s.val = Finset.prod s id
[PROOFSTEP]
rw [Finset.prod, Multiset.map_id]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
s : Finset α
⊢ ∑ x in s, {x} = s.val
[PROOFSTEP]
simp only [sum_eq_multiset_sum, Multiset.sum_map_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
inst✝² : CommMonoid β
inst✝¹ : CommMonoid γ
G : Type u_2
inst✝ : MonoidHomClass G β γ
g : G
f : α → β
s : Finset α
⊢ ↑g (∏ x in s, f x) = ∏ x in s, ↑g (f x)
[PROOFSTEP]
simp only [Finset.prod_eq_multiset_prod, map_multiset_prod, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
inst✝² : CommMonoid β
inst✝¹ : CommMonoid γ
G : Type u_2
inst✝ : MonoidHomClass G β γ
g : G
f : α → β
s : Finset α
⊢ Multiset.prod (Multiset.map ((fun x => ↑g x) ∘ fun x => f x) s.val) =
    Multiset.prod (Multiset.map (fun x => ↑g (f x)) s.val)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : IsEmpty α
s : Finset α
⊢ ∏ i in s, f i = 1
[PROOFSTEP]
rw [eq_empty_of_isEmpty s, prod_empty]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : ¬a ∈ s → f a = 1
⊢ ∏ x in insert a s, f x = ∏ x in s, f x
[PROOFSTEP]
by_cases hm : a ∈ s
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : ¬a ∈ s → f a = 1
hm : a ∈ s
⊢ ∏ x in insert a s, f x = ∏ x in s, f x
[PROOFSTEP]
simp_rw [insert_eq_of_mem hm]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : ¬a ∈ s → f a = 1
hm : ¬a ∈ s
⊢ ∏ x in insert a s, f x = ∏ x in s, f x
[PROOFSTEP]
rw [prod_insert hm, h hm, one_mul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
a b : α
h : a ≠ b
⊢ ∏ x in {a, b}, f x = f a * f b
[PROOFSTEP]
rw [prod_insert (not_mem_singleton.2 h), prod_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
⊢ ∏ _x in s, 1 = 1
[PROOFSTEP]
simp only [Finset.prod, Multiset.map_const', Multiset.prod_replicate, one_pow]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
e : α ↪ γ
f : γ → β
⊢ ∏ x in map e s, f x = ∏ x in s, f (↑e x)
[PROOFSTEP]
rw [Finset.prod, Finset.map_val, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
e : α ↪ γ
f : γ → β
⊢ Multiset.prod (Multiset.map ((fun x => f x) ∘ ↑e) s.val) = ∏ x in s, f (↑e x)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : s₁ = s₂
⊢ (∀ (x : α), x ∈ s₂ → f x = g x) → Finset.prod s₁ f = Finset.prod s₂ g
[PROOFSTEP]
rw [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : s₁ = s₂
⊢ (∀ (x : α), x ∈ s₂ → f x = g x) → Finset.prod s₂ f = Finset.prod s₂ g
[PROOFSTEP]
exact fold_congr
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : Disjoint s₁ s₂
⊢ ∏ x in disjUnion s₁ s₂ h, f x = (∏ x in s₁, f x) * ∏ x in s₂, f x
[PROOFSTEP]
refine' Eq.trans _ (fold_disjUnion h)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : Disjoint s₁ s₂
⊢ ∏ x in disjUnion s₁ s₂ h, f x = fold (fun x x_1 => x * x_1) (1 * 1) (fun x => f x) (disjUnion s₁ s₂ h)
[PROOFSTEP]
rw [one_mul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : Disjoint s₁ s₂
⊢ ∏ x in disjUnion s₁ s₂ h, f x = fold (fun x x_1 => x * x_1) 1 (fun x => f x) (disjUnion s₁ s₂ h)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
s : Finset ι
t : ι → Finset α
h : Set.PairwiseDisjoint (↑s) t
⊢ ∏ x in disjiUnion s t h, f x = ∏ i in s, ∏ x in t i, f x
[PROOFSTEP]
refine' Eq.trans _ (fold_disjiUnion h)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
s : Finset ι
t : ι → Finset α
h : Set.PairwiseDisjoint (↑s) t
⊢ ∏ x in disjiUnion s t h, f x =
    fold (fun x x_1 => x * x_1) (fold (fun x x_1 => x * x_1) 1 (fun i => 1) s) (fun x => f x) (disjiUnion s t h)
[PROOFSTEP]
dsimp [Finset.prod, Multiset.prod, Multiset.fold, Finset.disjUnion, Finset.fold]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
s : Finset ι
t : ι → Finset α
h : Set.PairwiseDisjoint (↑s) t
⊢ Multiset.foldr (fun x x_1 => x * x_1) (_ : ∀ (x y z : β), x * (y * z) = y * (x * z)) 1
      (Multiset.map (fun x => f x) (Multiset.bind s.val fun a => (t a).val)) =
    Multiset.foldr (fun x x_1 => x * x_1) (_ : LeftCommutative fun x x_1 => x * x_1)
      (Multiset.foldr (fun x x_1 => x * x_1) (_ : LeftCommutative fun x x_1 => x * x_1) 1
        (Multiset.map (fun i => 1) s.val))
      (Multiset.map (fun x => f x) (Multiset.bind s.val fun a => (t a).val))
[PROOFSTEP]
congr
[GOAL]
case e_b
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
s : Finset ι
t : ι → Finset α
h : Set.PairwiseDisjoint (↑s) t
⊢ 1 =
    Multiset.foldr (fun x x_1 => x * x_1) (_ : LeftCommutative fun x x_1 => x * x_1) 1 (Multiset.map (fun i => 1) s.val)
[PROOFSTEP]
exact prod_const_one.symm
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : Disjoint s₁ s₂
⊢ ∏ x in s₁ ∪ s₂, f x = (∏ x in s₁, f x) * ∏ x in s₂, f x
[PROOFSTEP]
rw [← prod_union_inter, disjoint_iff_inter_eq_empty.mp h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : Disjoint s₁ s₂
⊢ ∏ x in s₁ ∪ s₂, f x = (∏ x in s₁ ∪ s₂, f x) * ∏ x in ∅, f x
[PROOFSTEP]
exact (mul_one _).symm
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
s : Finset α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : (x : α) → Decidable ¬p x
f : α → β
⊢ (∏ x in filter p s, f x) * ∏ x in filter (fun x => ¬p x) s, f x = ∏ x in s, f x
[PROOFSTEP]
have := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
s : Finset α
p : α → Prop
inst✝¹ : DecidablePred p
inst✝ : (x : α) → Decidable ¬p x
f : α → β
this : DecidableEq α
⊢ (∏ x in filter p s, f x) * ∏ x in filter (fun x => ¬p x) s, f x = ∏ x in s, f x
[PROOFSTEP]
rw [← prod_union (disjoint_filter_filter_neg s s p), filter_union_filter_neg_eq]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
⊢ List.prod (List.map f (toList s)) = Finset.prod s f
[PROOFSTEP]
rw [Finset.prod, ← Multiset.coe_prod, ← Multiset.coe_map, Finset.coe_toList]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
σ : Equiv.Perm α
s : Finset α
f : α → β
hs : {a | ↑σ a ≠ a} ⊆ ↑s
⊢ ∏ x in s, f (↑σ x) = ∏ x in s, f x
[PROOFSTEP]
convert (prod_map s σ.toEmbedding f).symm
[GOAL]
case h.e'_3.h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
σ : Equiv.Perm α
s : Finset α
f : α → β
hs : {a | ↑σ a ≠ a} ⊆ ↑s
⊢ s = map (Equiv.toEmbedding σ) s
[PROOFSTEP]
exact (map_perm hs).symm
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
σ : Equiv.Perm α
s : Finset α
f : α → α → β
hs : {a | ↑σ a ≠ a} ⊆ ↑s
⊢ ∏ x in s, f (↑σ x) x = ∏ x in s, f x (↑σ.symm x)
[PROOFSTEP]
convert σ.prod_comp s (fun x => f x (σ.symm x)) hs
[GOAL]
case h.e'_2.a.h.e'_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
σ : Equiv.Perm α
s : Finset α
f : α → α → β
hs : {a | ↑σ a ≠ a} ⊆ ↑s
x✝ : α
a✝ : x✝ ∈ s
⊢ x✝ = ↑σ.symm (↑σ x✝)
[PROOFSTEP]
rw [Equiv.symm_apply_apply]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : Fintype α
inst✝ : CommMonoid β
s t : Finset α
h : IsCompl s t
f : α → β
⊢ ∏ x in disjUnion s t (_ : Disjoint s t), f x = ∏ i : α, f i
[PROOFSTEP]
classical rw [Finset.disjUnion_eq_union, ← Finset.sup_eq_union, h.sup_eq_top]; rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : Fintype α
inst✝ : CommMonoid β
s t : Finset α
h : IsCompl s t
f : α → β
⊢ ∏ x in disjUnion s t (_ : Disjoint s t), f x = ∏ i : α, f i
[PROOFSTEP]
rw [Finset.disjUnion_eq_union, ← Finset.sup_eq_union, h.sup_eq_top]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : Fintype α
inst✝ : CommMonoid β
s t : Finset α
h : IsCompl s t
f : α → β
⊢ ∏ x in ⊤, f x = ∏ i : α, f i
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : s₁ ⊆ s₂
⊢ (∏ x in s₂ \ s₁, f x) * ∏ x in s₁, f x = ∏ x in s₂, f x
[PROOFSTEP]
rw [← prod_union sdiff_disjoint, sdiff_union_of_subset h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α ⊕ γ → β
⊢ ∏ x in disjSum s t, f x = (∏ x in s, f (Sum.inl x)) * ∏ x in t, f (Sum.inr x)
[PROOFSTEP]
rw [← map_inl_disjUnion_map_inr, prod_disjUnion, prod_map, prod_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α ⊕ γ → β
⊢ (∏ x in s, f (↑Function.Embedding.inl x)) * ∏ x in t, f (↑Function.Embedding.inr x) =
    (∏ x in s, f (Sum.inl x)) * ∏ x in t, f (Sum.inr x)
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
⊢ ∏ x in disjSum s t, Sum.elim f g x = (∏ x in s, f x) * ∏ x in t, g x
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset γ
t : γ → Finset α
hs : Set.PairwiseDisjoint (↑s) t
⊢ ∏ x in Finset.biUnion s t, f x = ∏ x in s, ∏ i in t x, f i
[PROOFSTEP]
rw [← disjiUnion_eq_biUnion _ _ hs, prod_disjiUnion]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
σ : α → Type u_2
s : Finset α
t : (a : α) → Finset (σ a)
f : Sigma σ → β
⊢ ∏ x in Finset.sigma s t, f x = ∏ a in s, ∏ s in t a, f { fst := a, snd := s }
[PROOFSTEP]
simp_rw [← disjiUnion_map_sigma_mk, prod_disjiUnion, prod_map, Function.Embedding.sigmaMk_apply]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
⊢ ∏ x in s, f x = ∏ x in t, g x
[PROOFSTEP]
refine' prod_bij i hi h _ _
[GOAL]
case refine'_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
⊢ ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s), i a₁ ha₁ = i a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
intro a1 a2 h1 h2 eq
[GOAL]
case refine'_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
a1 a2 : α
h1 : a1 ∈ s
h2 : a2 ∈ s
eq : i a1 h1 = i a2 h2
⊢ a1 = a2
[PROOFSTEP]
rw [← left_inv a1 h1, ← left_inv a2 h2]
[GOAL]
case refine'_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
a1 a2 : α
h1 : a1 ∈ s
h2 : a2 ∈ s
eq : i a1 h1 = i a2 h2
⊢ j (i a1 h1) (_ : i a1 h1 ∈ t) = j (i a2 h2) (_ : i a2 h2 ∈ t)
[PROOFSTEP]
simp only [eq]
[GOAL]
case refine'_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
⊢ ∀ (b : γ), b ∈ t → ∃ a ha, b = i a ha
[PROOFSTEP]
intro b hb
[GOAL]
case refine'_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
b : γ
hb : b ∈ t
⊢ ∃ a ha, b = i a ha
[PROOFSTEP]
use j b hb
[GOAL]
case h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
b : γ
hb : b ∈ t
⊢ ∃ ha, b = i (j b hb) ha
[PROOFSTEP]
use hj b hb
[GOAL]
case h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → γ
hi : ∀ (a : α) (ha : a ∈ s), i a ha ∈ t
h : ∀ (a : α) (ha : a ∈ s), f a = g (i a ha)
j : (a : γ) → a ∈ t → α
hj : ∀ (a : γ) (ha : a ∈ t), j a ha ∈ s
left_inv : ∀ (a : α) (ha : a ∈ s), j (i a ha) (_ : i a ha ∈ t) = a
right_inv : ∀ (a : γ) (ha : a ∈ t), i (j a ha) (_ : j a ha ∈ s) = a
b : γ
hb : b ∈ t
⊢ b = i (j b hb) (_ : j b hb ∈ s)
[PROOFSTEP]
exact (right_inv b hb).symm
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
⊢ ∏ i' in s', f i' = ∏ i in s, f (↑e i)
[PROOFSTEP]
rw [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
⊢ ∏ i' in s', f i' = ∏ i in image (↑e.symm) s', f (↑e i)
[PROOFSTEP]
refine'
  Finset.prod_bij' (fun i' _hi' => e.symm i') (fun a ha => Finset.mem_image_of_mem _ ha)
    (fun a _ha => by simp_rw [e.apply_symm_apply]) (fun i _hi => e i) (fun a ha => _)
    (fun a _ha => e.apply_symm_apply a) fun a _ha => e.symm_apply_apply a
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
a : ι'
_ha : a ∈ s'
⊢ f a = f (↑e ((fun i' _hi' => ↑e.symm i') a _ha))
[PROOFSTEP]
simp_rw [e.apply_symm_apply]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
a : ι
ha : a ∈ image (↑e.symm) s'
⊢ (fun i _hi => ↑e i) a ha ∈ s'
[PROOFSTEP]
rcases Finset.mem_image.mp ha with ⟨i', hi', rfl⟩
[GOAL]
case intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
i' : ι'
hi' : i' ∈ s'
ha : ↑e.symm i' ∈ image (↑e.symm) s'
⊢ (fun i _hi => ↑e i) (↑e.symm i') ha ∈ s'
[PROOFSTEP]
dsimp only
[GOAL]
case intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι' : Type u_2
inst✝ : DecidableEq ι
e : ι ≃ ι'
f : ι' → β
s' : Finset ι'
s : Finset ι
h : s = image (↑e.symm) s'
i' : ι'
hi' : i' ∈ s'
ha : ↑e.symm i' ∈ image (↑e.symm) s'
⊢ ↑e (↑e.symm i') ∈ s'
[PROOFSTEP]
rwa [e.apply_symm_apply]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
r : Finset (γ × α)
s : Finset γ
t : γ → Finset α
h : ∀ (p : γ × α), p ∈ r ↔ p.fst ∈ s ∧ p.snd ∈ t p.fst
f : γ × α → β
⊢ ∏ p in r, f p = ∏ c in s, ∏ a in t c, f (c, a)
[PROOFSTEP]
refine' Eq.trans _ (prod_sigma s t fun p => f (p.1, p.2))
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
r : Finset (γ × α)
s : Finset γ
t : γ → Finset α
h : ∀ (p : γ × α), p ∈ r ↔ p.fst ∈ s ∧ p.snd ∈ t p.fst
f : γ × α → β
⊢ ∏ p in r, f p = ∏ x in Finset.sigma s t, f (x.fst, x.snd)
[PROOFSTEP]
exact
  prod_bij' (fun p _hp => ⟨p.1, p.2⟩) (fun p => mem_sigma.mpr ∘ (h p).mp) (fun p hp => congr_arg f Prod.mk.eta.symm)
    (fun p _hp => (p.1, p.2)) (fun p => (h (p.1, p.2)).mpr ∘ mem_sigma.mp) (fun p _hp => Prod.mk.eta) fun p _hp => p.eta
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
r : Finset (α × γ)
s : Finset γ
t : γ → Finset α
h : ∀ (p : α × γ), p ∈ r ↔ p.snd ∈ s ∧ p.fst ∈ t p.snd
f : α × γ → β
⊢ ∏ p in r, f p = ∏ c in s, ∏ a in t c, f (a, c)
[PROOFSTEP]
refine' Eq.trans _ (prod_sigma s t fun p => f (p.2, p.1))
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
r : Finset (α × γ)
s : Finset γ
t : γ → Finset α
h : ∀ (p : α × γ), p ∈ r ↔ p.snd ∈ s ∧ p.fst ∈ t p.snd
f : α × γ → β
⊢ ∏ p in r, f p = ∏ x in Finset.sigma s t, f (x.snd, x.fst)
[PROOFSTEP]
exact
  prod_bij' (fun p _hp => ⟨p.2, p.1⟩) (fun p => mem_sigma.mpr ∘ (h p).mp) (fun p hp => congr_arg f Prod.mk.eta.symm)
    (fun p _hp => (p.2, p.1)) (fun p => (h (p.2, p.1)).mpr ∘ mem_sigma.mp) (fun p _hp => Prod.mk.eta) fun p _hp => p.eta
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
s : Finset α
t : Finset γ
g : α → γ
h : ∀ (x : α), x ∈ s → g x ∈ t
f : α → β
⊢ ∏ y in t, ∏ x in filter (fun x => g x = y) s, f x = ∏ x in s, f x
[PROOFSTEP]
rw [← prod_disjiUnion, disjiUnion_filter_eq_of_maps_to h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
⊢ ∏ x in s, f x * g x = fold (fun x x_1 => x * x_1) (1 * 1) (fun x => f x * g x) s
[PROOFSTEP]
rw [one_mul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
⊢ ∏ x in s, f x * g x = fold (fun x x_1 => x * x_1) 1 (fun x => f x * g x) s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset γ
t : γ → Finset α
t' : Finset α
s' : α → Finset γ
h : ∀ (x : γ) (y : α), x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t'
f : γ → α → β
⊢ ∏ x in s, ∏ y in t x, f x y = ∏ y in t', ∏ x in s' y, f x y
[PROOFSTEP]
classical
have : ∀ z : γ × α, (z ∈ s.biUnion fun x => (t x).map <| Function.Embedding.sectr x _) ↔ z.1 ∈ s ∧ z.2 ∈ t z.1 :=
  by
  rintro ⟨x, y⟩
  simp only [mem_biUnion, mem_map, Function.Embedding.sectr_apply, Prod.mk.injEq, exists_eq_right, ← and_assoc]
exact
  (prod_finset_product' _ _ _ this).symm.trans
    ((prod_finset_product_right' _ _ _) fun ⟨x, y⟩ => (this _).trans ((h x y).trans and_comm))
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset γ
t : γ → Finset α
t' : Finset α
s' : α → Finset γ
h : ∀ (x : γ) (y : α), x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t'
f : γ → α → β
⊢ ∏ x in s, ∏ y in t x, f x y = ∏ y in t', ∏ x in s' y, f x y
[PROOFSTEP]
have : ∀ z : γ × α, (z ∈ s.biUnion fun x => (t x).map <| Function.Embedding.sectr x _) ↔ z.1 ∈ s ∧ z.2 ∈ t z.1 :=
  by
  rintro ⟨x, y⟩
  simp only [mem_biUnion, mem_map, Function.Embedding.sectr_apply, Prod.mk.injEq, exists_eq_right, ← and_assoc]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset γ
t : γ → Finset α
t' : Finset α
s' : α → Finset γ
h : ∀ (x : γ) (y : α), x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t'
f : γ → α → β
⊢ ∀ (z : γ × α), (z ∈ Finset.biUnion s fun x => map (Function.Embedding.sectr x α) (t x)) ↔ z.fst ∈ s ∧ z.snd ∈ t z.fst
[PROOFSTEP]
rintro ⟨x, y⟩
[GOAL]
case mk
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset γ
t : γ → Finset α
t' : Finset α
s' : α → Finset γ
h : ∀ (x : γ) (y : α), x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t'
f : γ → α → β
x : γ
y : α
⊢ ((x, y) ∈ Finset.biUnion s fun x => map (Function.Embedding.sectr x α) (t x)) ↔
    (x, y).fst ∈ s ∧ (x, y).snd ∈ t (x, y).fst
[PROOFSTEP]
simp only [mem_biUnion, mem_map, Function.Embedding.sectr_apply, Prod.mk.injEq, exists_eq_right, ← and_assoc]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset γ
t : γ → Finset α
t' : Finset α
s' : α → Finset γ
h : ∀ (x : γ) (y : α), x ∈ s ∧ y ∈ t x ↔ x ∈ s' y ∧ y ∈ t'
f : γ → α → β
this :
  ∀ (z : γ × α), (z ∈ Finset.biUnion s fun x => map (Function.Embedding.sectr x α) (t x)) ↔ z.fst ∈ s ∧ z.snd ∈ t z.fst
⊢ ∏ x in s, ∏ y in t x, f x y = ∏ y in t', ∏ x in s' y, f x y
[PROOFSTEP]
exact
  (prod_finset_product' _ _ _ this).symm.trans
    ((prod_finset_product_right' _ _ _) fun ⟨x, y⟩ => (this _).trans ((h x y).trans and_comm))
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : CommMonoid γ
r : β → γ → Prop
f : α → β
g : α → γ
s : Finset α
h₁ : r 1 1
h₂ : ∀ (a : α) (b : β) (c : γ), r b c → r (f a * b) (g a * c)
⊢ r (∏ x in s, f x) (∏ x in s, g x)
[PROOFSTEP]
delta Finset.prod
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : CommMonoid γ
r : β → γ → Prop
f : α → β
g : α → γ
s : Finset α
h₁ : r 1 1
h₂ : ∀ (a : α) (b : β) (c : γ), r b c → r (f a * b) (g a * c)
⊢ r (Multiset.prod (Multiset.map (fun x => f x) s.val)) (Multiset.prod (Multiset.map (fun x => g x) s.val))
[PROOFSTEP]
apply Multiset.prod_hom_rel
[GOAL]
case h₁
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : CommMonoid γ
r : β → γ → Prop
f : α → β
g : α → γ
s : Finset α
h₁ : r 1 1
h₂ : ∀ (a : α) (b : β) (c : γ), r b c → r (f a * b) (g a * c)
⊢ r 1 1
[PROOFSTEP]
assumption
[GOAL]
case h₂
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : CommMonoid γ
r : β → γ → Prop
f : α → β
g : α → γ
s : Finset α
h₁ : r 1 1
h₂ : ∀ (a : α) (b : β) (c : γ), r b c → r (f a * b) (g a * c)
⊢ ∀ ⦃a : α⦄ ⦃b : β⦄ ⦃c : γ⦄, r b c → r (f a * b) (g a * c)
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : s₁ ⊆ s₂
hg : ∀ (x : α), x ∈ s₂ \ s₁ → g x = 1
hfg : ∀ (x : α), x ∈ s₁ → f x = g x
⊢ ∏ i in s₁, f i = ∏ i in s₂, g i
[PROOFSTEP]
rw [← prod_sdiff h, prod_eq_one hg, one_mul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
h : s₁ ⊆ s₂
hg : ∀ (x : α), x ∈ s₂ \ s₁ → g x = 1
hfg : ∀ (x : α), x ∈ s₁ → f x = g x
⊢ ∏ i in s₁, f i = ∏ x in s₁, g x
[PROOFSTEP]
exact prod_congr rfl hfg
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : s₁ ⊆ s₂
hf : ∀ (x : α), x ∈ s₂ → ¬x ∈ s₁ → f x = 1
this : DecidableEq α
⊢ ∀ (x : α), x ∈ s₂ \ s₁ → f x = 1
[PROOFSTEP]
simpa
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
hp : ∀ (x : α), x ∈ s → f x ≠ 1 → p x
x : α
⊢ x ∈ s → ¬x ∈ filter p s → f x = 1
[PROOFSTEP]
classical
rw [not_imp_comm, mem_filter]
exact fun h₁ h₂ => ⟨h₁, by simpa using hp _ h₁ h₂⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
hp : ∀ (x : α), x ∈ s → f x ≠ 1 → p x
x : α
⊢ x ∈ s → ¬x ∈ filter p s → f x = 1
[PROOFSTEP]
rw [not_imp_comm, mem_filter]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
hp : ∀ (x : α), x ∈ s → f x ≠ 1 → p x
x : α
⊢ x ∈ s → ¬f x = 1 → x ∈ s ∧ p x
[PROOFSTEP]
exact fun h₁ h₂ => ⟨h₁, by simpa using hp _ h₁ h₂⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
hp : ∀ (x : α), x ∈ s → f x ≠ 1 → p x
x : α
h₁ : x ∈ s
h₂ : ¬f x = 1
⊢ p x
[PROOFSTEP]
simpa using hp _ h₁ h₂
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
a : α
h : a ∈ filter p s
⊢ f a = if p a then f a else 1
[PROOFSTEP]
rw [if_pos]
[GOAL]
case hc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
a : α
h : a ∈ filter p s
⊢ p a
[PROOFSTEP]
simpa using (mem_filter.1 h).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
⊢ (∏ a in filter p s, if p a then f a else 1) = ∏ a in s, if p a then f a else 1
[PROOFSTEP]
{ refine' prod_subset (filter_subset _ s) fun x hs h => _
  rw [mem_filter, not_and] at h 
  exact if_neg (by simpa using h hs)
}
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
⊢ (∏ a in filter p s, if p a then f a else 1) = ∏ a in s, if p a then f a else 1
[PROOFSTEP]
refine' prod_subset (filter_subset _ s) fun x hs h => _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
x : α
hs : x ∈ s
h : ¬x ∈ filter p s
⊢ (if p x then f x else 1) = 1
[PROOFSTEP]
rw [mem_filter, not_and] at h 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
x : α
hs : x ∈ s
h : x ∈ s → ¬p x
⊢ (if p x then f x else 1) = 1
[PROOFSTEP]
exact if_neg (by simpa using h hs)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
p : α → Prop
inst✝ : DecidablePred p
f : α → β
x : α
hs : x ∈ s
h : x ∈ s → ¬p x
⊢ ¬p x
[PROOFSTEP]
simpa using h hs
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
⊢ ∏ x in s, f x = f a
[PROOFSTEP]
haveI := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
⊢ ∏ x in s, f x = f a
[PROOFSTEP]
calc
  ∏ x in s, f x = ∏ x in { a }, f x := by {
    refine' (prod_subset _ _).symm
    · intro _ H
      rwa [mem_singleton.1 H]
    · simpa only [mem_singleton]
  }
  _ = f a := prod_singleton
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
⊢ ∏ x in s, f x = ∏ x in {a}, f x
[PROOFSTEP]
{ refine' (prod_subset _ _).symm
  · intro _ H
    rwa [mem_singleton.1 H]
  · simpa only [mem_singleton]
}
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
⊢ ∏ x in s, f x = ∏ x in {a}, f x
[PROOFSTEP]
refine' (prod_subset _ _).symm
[GOAL]
case refine'_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
⊢ {a} ⊆ s
[PROOFSTEP]
intro _ H
[GOAL]
case refine'_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
a✝ : α
H : a✝ ∈ {a}
⊢ a✝ ∈ s
[PROOFSTEP]
rwa [mem_singleton.1 H]
[GOAL]
case refine'_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h : a ∈ s
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
this : DecidableEq α
⊢ ∀ (x : α), x ∈ s → ¬x ∈ {a} → f x = 1
[PROOFSTEP]
simpa only [mem_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
h₀ : ∀ (b : α), b ∈ s → b ≠ a → f b = 1
h₁ : ¬a ∈ s → f a = 1
this✝ : DecidableEq α
this : ¬a ∈ s
b : α
hb : b ∈ s
⊢ b ≠ a
[PROOFSTEP]
rintro rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
this✝ : DecidableEq α
b : α
hb : b ∈ s
h₀ : ∀ (b_1 : α), b_1 ∈ s → b_1 ≠ b → f b_1 = 1
h₁ : ¬b ∈ s → f b = 1
this : ¬b ∈ s
⊢ False
[PROOFSTEP]
exact this hb
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
haveI := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
let s' := ({ a, b } : Finset α)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
have hu : s' ⊆ s := by
  refine' insert_subset_iff.mpr _
  apply And.intro ha
  apply singleton_subset_iff.mpr hb
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
⊢ s' ⊆ s
[PROOFSTEP]
refine' insert_subset_iff.mpr _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
⊢ a ∈ s ∧ {b} ⊆ s
[PROOFSTEP]
apply And.intro ha
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
⊢ {b} ⊆ s
[PROOFSTEP]
apply singleton_subset_iff.mpr hb
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
have hf : ∀ c ∈ s, c ∉ s' → f c = 1 := by
  intro c hc hcs
  apply h₀ c hc
  apply not_or.mp
  intro hab
  apply hcs
  apply mem_insert.mpr
  rw [mem_singleton]
  exact hab
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
⊢ ∀ (c : α), c ∈ s → ¬c ∈ s' → f c = 1
[PROOFSTEP]
intro c hc hcs
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
⊢ f c = 1
[PROOFSTEP]
apply h₀ c hc
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
⊢ c ≠ a ∧ c ≠ b
[PROOFSTEP]
apply not_or.mp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
⊢ ¬(c = a ∨ c = b)
[PROOFSTEP]
intro hab
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
hab : c = a ∨ c = b
⊢ False
[PROOFSTEP]
apply hcs
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
hab : c = a ∨ c = b
⊢ c ∈ s'
[PROOFSTEP]
apply mem_insert.mpr
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
hab : c = a ∨ c = b
⊢ c = a ∨ c ∈ {b}
[PROOFSTEP]
rw [mem_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
c : α
hc : c ∈ s
hcs : ¬c ∈ s'
hab : c = a ∨ c = b
⊢ c = a ∨ c = b
[PROOFSTEP]
exact hab
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
hf : ∀ (c : α), c ∈ s → ¬c ∈ s' → f c = 1
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
rw [← prod_subset hu hf]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
ha : a ∈ s
hb : b ∈ s
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
this : DecidableEq α
s' : Finset α := {a, b}
hu : s' ⊆ s
hf : ∀ (c : α), c ∈ s → ¬c ∈ s' → f c = 1
⊢ ∏ x in s', f x = f a * f b
[PROOFSTEP]
exact Finset.prod_pair hn
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
haveI := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
by_cases h₁ : a ∈ s
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : a ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
by_cases h₂ : b ∈ s
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
by_cases h₂ : b ∈ s
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : a ∈ s
h₂ : b ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
exact prod_eq_mul_of_mem a b h₁ h₂ hn h₀
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : a ∈ s
h₂ : ¬b ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
rw [hb h₂, mul_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : a ∈ s
h₂ : ¬b ∈ s
⊢ ∏ x in s, f x = f a
[PROOFSTEP]
apply prod_eq_single_of_mem a h₁
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : a ∈ s
h₂ : ¬b ∈ s
⊢ ∀ (b : α), b ∈ s → b ≠ a → f b = 1
[PROOFSTEP]
exact fun c hc hca => h₀ c hc ⟨hca, ne_of_mem_of_not_mem hc h₂⟩
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
h₂ : b ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
rw [ha h₁, one_mul]
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
h₂ : b ∈ s
⊢ ∏ x in s, f x = f b
[PROOFSTEP]
apply prod_eq_single_of_mem b h₂
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
h₂ : b ∈ s
⊢ ∀ (b_1 : α), b_1 ∈ s → b_1 ≠ b → f b_1 = 1
[PROOFSTEP]
exact fun c hc hcb => h₀ c hc ⟨ne_of_mem_of_not_mem hc h₁, hcb⟩
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
h₂ : ¬b ∈ s
⊢ ∏ x in s, f x = f a * f b
[PROOFSTEP]
rw [ha h₁, hb h₂, mul_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a b : α
hn : a ≠ b
h₀ : ∀ (c : α), c ∈ s → c ≠ a ∧ c ≠ b → f c = 1
ha : ¬a ∈ s → f a = 1
hb : ¬b ∈ s → f b = 1
this : DecidableEq α
h₁ : ¬a ∈ s
h₂ : ¬b ∈ s
⊢ ∏ x in s, f x = 1
[PROOFSTEP]
exact
  _root_.trans (prod_congr rfl fun c hc => h₀ c hc ⟨ne_of_mem_of_not_mem hc h₁, ne_of_mem_of_not_mem hc h₂⟩)
    prod_const_one
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
this : DecidableEq α
⊢ ∏ x in attach s, f ↑x = ∏ x in image Subtype.val (attach s), f x
[PROOFSTEP]
{rw [prod_image]; exact fun x _ y _ => Subtype.eq
}
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
this : DecidableEq α
⊢ ∏ x in attach s, f ↑x = ∏ x in image Subtype.val (attach s), f x
[PROOFSTEP]
rw [prod_image]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
this : DecidableEq α
⊢ ∀ (x : { x // x ∈ s }), x ∈ attach s → ∀ (y : { x // x ∈ s }), y ∈ attach s → ↑x = ↑y → x = y
[PROOFSTEP]
exact fun x _ y _ => Subtype.eq
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
this : DecidableEq α
⊢ ∏ x in image Subtype.val (attach s), f x = ∏ x in s, f x
[PROOFSTEP]
rw [attach_image_val]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
⊢ ∏ x in Finset.subtype p s, f ↑x = ∏ x in filter p s, f x
[PROOFSTEP]
conv_lhs => erw [← prod_map (s.subtype p) (Function.Embedding.subtype _) f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
| ∏ x in Finset.subtype p s, f ↑x
[PROOFSTEP]
erw [← prod_map (s.subtype p) (Function.Embedding.subtype _) f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
| ∏ x in Finset.subtype p s, f ↑x
[PROOFSTEP]
erw [← prod_map (s.subtype p) (Function.Embedding.subtype _) f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
| ∏ x in Finset.subtype p s, f ↑x
[PROOFSTEP]
erw [← prod_map (s.subtype p) (Function.Embedding.subtype _) f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
⊢ ∏ x in map (Function.Embedding.subtype p) (Finset.subtype p s), f x = ∏ x in filter p s, f x
[PROOFSTEP]
exact prod_congr (subtype_map _) fun x _hx => rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
⊢ ∏ x in Finset.subtype p s, f ↑x = ∏ x in s, f x
[PROOFSTEP]
rw [prod_subtype_eq_prod_filter, filter_true_of_mem]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → β
p : α → Prop
inst✝ : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
⊢ ∀ (x : α), x ∈ s → p x
[PROOFSTEP]
simpa using h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
s : Finset { x // p x }
f : { x // p x } → β
g : α → β
h : ∀ (x : { x // p x }), x ∈ s → g ↑x = f x
⊢ ∏ x in map (Function.Embedding.subtype fun x => p x) s, g x = ∏ x in s, f x
[PROOFSTEP]
rw [Finset.prod_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
s : Finset { x // p x }
f : { x // p x } → β
g : α → β
h : ∀ (x : { x // p x }), x ∈ s → g ↑x = f x
⊢ ∏ x in s, g (↑(Function.Embedding.subtype fun x => p x) x) = ∏ x in s, f x
[PROOFSTEP]
exact Finset.prod_congr rfl h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
p : α → Prop
F : Fintype (Subtype p)
s : Finset α
h : ∀ (x : α), x ∈ s ↔ p x
f : α → β
⊢ ∏ a in s, f a = ∏ a : Subtype p, f ↑a
[PROOFSTEP]
have : (· ∈ s) = p := Set.ext h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
p : α → Prop
F : Fintype (Subtype p)
s : Finset α
h : ∀ (x : α), x ∈ s ↔ p x
f : α → β
this : (fun x => x ∈ s) = p
⊢ ∏ a in s, f a = ∏ a : Subtype p, f ↑a
[PROOFSTEP]
subst p
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
F : Fintype { x // x ∈ s }
h : ∀ (x : α), x ∈ s ↔ (fun x => x ∈ s) x
⊢ ∏ a in s, f a = ∏ a : { x // x ∈ s }, f ↑a
[PROOFSTEP]
rw [← prod_coe_sort]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
F : Fintype { x // x ∈ s }
h : ∀ (x : α), x ∈ s ↔ (fun x => x ∈ s) x
⊢ ∏ i : { x // x ∈ s }, f ↑i = ∏ a : { x // x ∈ s }, f ↑a
[PROOFSTEP]
congr!
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ Finset.prod univ f = Finset.prod univ g
[PROOFSTEP]
rw [← @Finset.prod_subset _ _ s.toFinset Finset.univ f _ (by simp)]
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ Set.toFinset s ⊆ univ
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ ∏ x in Set.toFinset s, f x = Finset.prod univ g
[PROOFSTEP]
rw [Finset.prod_subtype]
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ ∏ a : Subtype ?m.393471, f ↑a = Finset.prod univ g
[PROOFSTEP]
apply Finset.prod_congr rfl
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ ∀ (x : { x // x ∈ s }), x ∈ univ → f ↑x = g x
[PROOFSTEP]
exact fun ⟨x, h⟩ _ => w x h
[GOAL]
case h
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ ∀ (x : β), x ∈ Set.toFinset s ↔ x ∈ s
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
⊢ ∀ (x : β), x ∈ univ → ¬x ∈ Set.toFinset s → f x = 1
[PROOFSTEP]
rintro x _ h
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
x : β
a✝ : x ∈ univ
h : ¬x ∈ Set.toFinset s
⊢ f x = 1
[PROOFSTEP]
exact w' x (by simpa using h)
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g✝ : α✝ → β✝
inst✝³ : CommMonoid β✝
α : Type u_2
inst✝² : CommMonoid α
β : Type u_3
inst✝¹ : Fintype β
s : Set β
inst✝ : DecidablePred fun x => x ∈ s
f : β → α
g : ↑s → α
w : ∀ (x : β) (h : x ∈ s), f x = g { val := x, property := h }
w' : ∀ (x : β), ¬x ∈ s → f x = 1
x : β
a✝ : x ∈ univ
h : ¬x ∈ Set.toFinset s
⊢ ¬x ∈ s
[PROOFSTEP]
simpa using h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter p s }
⊢ p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter (fun x => ¬p x) s }
⊢ ¬p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter p s }
⊢ p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter (fun x => ¬p x) s }
⊢ ¬p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter p s }
_hx : x ∈ attach (filter p s)
⊢ p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
inst✝ : DecidablePred fun x => ¬p x
f : (x : α) → p x → γ
g : (x : α) → ¬p x → γ
h : γ → β
x : { x // x ∈ filter (fun x => ¬p x) s }
_hx : x ∈ attach (filter (fun x => ¬p x) s)
⊢ ¬p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
x : { x // x ∈ filter p s }
⊢ p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
x : { x // x ∈ filter (fun x => ¬p x) s }
⊢ ¬p ↑x
[PROOFSTEP]
simpa using (mem_filter.mp x.2).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
⊢ (∏ x in s, if hx : p x then f x hx else g x hx) =
    (∏ x in attach (filter p s), f ↑x (_ : p ↑x)) * ∏ x in attach (filter (fun x => ¬p x) s), g ↑x (_ : ¬p ↑x)
[PROOFSTEP]
simp [prod_apply_dite _ _ fun x => x]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
p : α → Prop
hp : DecidablePred p
f g : α → β
⊢ (∏ x in s, if p x then f x else g x) = (∏ x in filter p s, f x) * ∏ x in filter (fun x => ¬p x) s, g x
[PROOFSTEP]
simp [prod_apply_ite _ _ fun x => x]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ (∏ x in s, if p x then f x else g x) = ∏ x in s, g x
[PROOFSTEP]
rw [prod_ite, filter_false_of_mem, filter_true_of_mem]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ (∏ x in ∅, f x) * ∏ x in s, g x = ∏ x in s, g x
[PROOFSTEP]
simp only [prod_empty, one_mul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ ∀ (x : α), x ∈ s → ¬p x
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ ∀ (x : α), x ∈ s → ¬p x
[PROOFSTEP]
all_goals intros; apply h; assumption
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ ∀ (x : α), x ∈ s → ¬p x
[PROOFSTEP]
intros
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
x✝ : α
a✝ : x✝ ∈ s
⊢ ¬p x✝
[PROOFSTEP]
apply h
[GOAL]
case a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
x✝ : α
a✝ : x✝ ∈ s
⊢ x✝ ∈ s
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ ∀ (x : α), x ∈ s → ¬p x
[PROOFSTEP]
intros
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
x✝ : α
a✝ : x✝ ∈ s
⊢ ¬p x✝
[PROOFSTEP]
apply h
[GOAL]
case a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → ¬p x
x✝ : α
a✝ : x✝ ∈ s
⊢ x✝ ∈ s
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → p x
⊢ (∏ x in s, if p x then f x else g x) = ∏ x in s, f x
[PROOFSTEP]
simp_rw [← ite_not (p _)]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → p x
⊢ (∏ x in s, if ¬p x then g x else f x) = ∏ x in s, f x
[PROOFSTEP]
apply prod_ite_of_false
[GOAL]
case h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → β
h : ∀ (x : α), x ∈ s → p x
⊢ ∀ (x : α), x ∈ s → ¬¬p x
[PROOFSTEP]
simpa
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → γ
k : γ → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ ∏ x in s, k (if p x then f x else g x) = ∏ x in s, k (g x)
[PROOFSTEP]
simp_rw [apply_ite k]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → γ
k : γ → β
h : ∀ (x : α), x ∈ s → ¬p x
⊢ (∏ x in s, if p x then k (f x) else k (g x)) = ∏ x in s, k (g x)
[PROOFSTEP]
exact prod_ite_of_false _ _ h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → γ
k : γ → β
h : ∀ (x : α), x ∈ s → p x
⊢ ∏ x in s, k (if p x then f x else g x) = ∏ x in s, k (f x)
[PROOFSTEP]
simp_rw [apply_ite k]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
f g : α → γ
k : γ → β
h : ∀ (x : α), x ∈ s → p x
⊢ (∏ x in s, if p x then k (f x) else k (g x)) = ∏ x in s, k (f x)
[PROOFSTEP]
exact prod_ite_of_true _ _ h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s t : Finset α
f : α → β
⊢ (∏ i in s, if i ∈ t then f i else 1) = ∏ i in s ∩ t, f i
[PROOFSTEP]
rw [← Finset.prod_filter, Finset.filter_mem_eq_inter]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
⊢ (∏ x in s, if h : a = x then b x h else 1) = if a ∈ s then b a (_ : a = a) else 1
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : a ∈ s
⊢ (∏ x in s, if h : a = x then b x h else 1) = b a (_ : a = a)
[PROOFSTEP]
rw [Finset.prod_eq_single a, dif_pos rfl]
[GOAL]
case pos.h₀
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : a ∈ s
⊢ ∀ (b_1 : α), b_1 ∈ s → b_1 ≠ a → (if h : a = b_1 then b b_1 h else 1) = 1
[PROOFSTEP]
intros _ _ h
[GOAL]
case pos.h₀
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h✝ : a ∈ s
b✝ : α
a✝ : b✝ ∈ s
h : b✝ ≠ a
⊢ (if h : a = b✝ then b b✝ h else 1) = 1
[PROOFSTEP]
rw [dif_neg]
[GOAL]
case pos.h₀.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h✝ : a ∈ s
b✝ : α
a✝ : b✝ ∈ s
h : b✝ ≠ a
⊢ ¬a = b✝
[PROOFSTEP]
exact h.symm
[GOAL]
case pos.h₁
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : a ∈ s
⊢ ¬a ∈ s → (if h : a = a then b a h else 1) = 1
[PROOFSTEP]
simp [h]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : ¬a ∈ s
⊢ (∏ x in s, if h : a = x then b x h else 1) = 1
[PROOFSTEP]
rw [Finset.prod_eq_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : ¬a ∈ s
⊢ ∀ (x : α), x ∈ s → (if h : a = x then b x h else 1) = 1
[PROOFSTEP]
intros
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : ¬a ∈ s
x✝ : α
a✝ : x✝ ∈ s
⊢ (if h : a = x✝ then b x✝ h else 1) = 1
[PROOFSTEP]
rw [dif_neg]
[GOAL]
case neg.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : ¬a ∈ s
x✝ : α
a✝ : x✝ ∈ s
⊢ ¬a = x✝
[PROOFSTEP]
rintro rfl
[GOAL]
case neg.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → a = x → β
h : ¬a ∈ s
a✝ : a ∈ s
⊢ False
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
⊢ (∏ x in s, if h : x = a then b x h else 1) = if a ∈ s then b a (_ : a = a) else 1
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : a ∈ s
⊢ (∏ x in s, if h : x = a then b x h else 1) = b a (_ : a = a)
[PROOFSTEP]
rw [Finset.prod_eq_single a, dif_pos rfl]
[GOAL]
case pos.h₀
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : a ∈ s
⊢ ∀ (b_1 : α), b_1 ∈ s → b_1 ≠ a → (if h : b_1 = a then b b_1 h else 1) = 1
[PROOFSTEP]
intros _ _ h
[GOAL]
case pos.h₀
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h✝ : a ∈ s
b✝ : α
a✝ : b✝ ∈ s
h : b✝ ≠ a
⊢ (if h : b✝ = a then b b✝ h else 1) = 1
[PROOFSTEP]
rw [dif_neg]
[GOAL]
case pos.h₀.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h✝ : a ∈ s
b✝ : α
a✝ : b✝ ∈ s
h : b✝ ≠ a
⊢ ¬b✝ = a
[PROOFSTEP]
exact h
[GOAL]
case pos.h₁
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : a ∈ s
⊢ ¬a ∈ s → (if h : a = a then b a h else 1) = 1
[PROOFSTEP]
simp [h]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : ¬a ∈ s
⊢ (∏ x in s, if h : x = a then b x h else 1) = 1
[PROOFSTEP]
rw [Finset.prod_eq_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : ¬a ∈ s
⊢ ∀ (x : α), x ∈ s → (if h : x = a then b x h else 1) = 1
[PROOFSTEP]
intros
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : ¬a ∈ s
x✝ : α
a✝ : x✝ ∈ s
⊢ (if h : x✝ = a then b x✝ h else 1) = 1
[PROOFSTEP]
rw [dif_neg]
[GOAL]
case neg.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝¹ : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
a : α
b : (x : α) → x = a → β
h : ¬a ∈ s
x✝ : α
a✝ : x✝ ∈ s
⊢ ¬x✝ = a
[PROOFSTEP]
rintro rfl
[GOAL]
case neg.hnc
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
x✝ : α
a✝ : x✝ ∈ s
b : (x : α) → x = x✝ → β
h : ¬x✝ ∈ s
⊢ False
[PROOFSTEP]
contradiction
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f g : α → β
⊢ (∏ x in s, if p then f x else g x) = if p then ∏ x in s, f x else ∏ x in s, g x
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f g : α → β
h : p
⊢ ∏ x in s, f x = ∏ x in s, f x
[PROOFSTEP]
rfl
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f g : α → β
h : ¬p
⊢ ∏ x in s, g x = ∏ x in s, g x
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f : p → α → β
g : ¬p → α → β
⊢ (∏ x in s, if h : p then f h x else g h x) = if h : p then ∏ x in s, f h x else ∏ x in s, g h x
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f : p → α → β
g : ¬p → α → β
h : p
⊢ ∏ x in s, f h x = ∏ x in s, f h x
[PROOFSTEP]
rfl
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
p : Prop
inst✝ : Decidable p
s : Finset α
f : p → α → β
g : ¬p → α → β
h : ¬p
⊢ ∏ x in s, g h x = ∏ x in s, g h x
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∏ x in s, f x = ∏ x in t, g x
[PROOFSTEP]
classical
calc
  ∏ x in s, f x = ∏ x in s.filter fun x => f x ≠ 1, f x := prod_filter_ne_one.symm
  _ = ∏ x in t.filter fun x => g x ≠ 1, g x :=
    (prod_bij (fun a ha => i a (mem_filter.mp ha).1 $ by simpa using (mem_filter.mp ha).2) ?_ ?_ ?_ ?_)
  _ = ∏ x in t, g x := prod_filter_ne_one
· intros a ha
  refine' (mem_filter.mp ha).elim _
  intros h₁ h₂
  refine (mem_filter.mpr ⟨hi a h₁ _, ?_⟩)
  specialize h a h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
  rwa [← h]
· refine' (fun a ha => (mem_filter.mp ha).elim fun h₁ h₂ ↦ _)
  exact h a h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
· intros a₁ a₂ ha₁ ha₂
  refine' (mem_filter.mp ha₁).elim fun _ha₁₁ _ha₁₂ ↦ _
  refine' (mem_filter.mp ha₂).elim fun _ha₂₁ _ha₂₂ ↦ _
  apply i_inj
· intros b hb
  refine' (mem_filter.mp hb).elim fun h₁ h₂ ↦ _
  obtain ⟨a, ha₁, ha₂, eq⟩ := i_surj b h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
  exact ⟨a, mem_filter.mpr ⟨ha₁, ha₂⟩, eq⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∏ x in s, f x = ∏ x in t, g x
[PROOFSTEP]
calc
  ∏ x in s, f x = ∏ x in s.filter fun x => f x ≠ 1, f x := prod_filter_ne_one.symm
  _ = ∏ x in t.filter fun x => g x ≠ 1, g x :=
    (prod_bij (fun a ha => i a (mem_filter.mp ha).1 $ by simpa using (mem_filter.mp ha).2) ?_ ?_ ?_ ?_)
  _ = ∏ x in t, g x := prod_filter_ne_one
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
⊢ f a ≠ 1
[PROOFSTEP]
simpa using (mem_filter.mp ha).2
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∀ (a : α) (ha : a ∈ filter (fun x => f x ≠ 1) s),
    (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha ∈ filter (fun x => g x ≠ 1) t
[PROOFSTEP]
intros a ha
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
⊢ (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha ∈ filter (fun x => g x ≠ 1) t
[PROOFSTEP]
refine' (mem_filter.mp ha).elim _
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
⊢ a ∈ s → f a ≠ 1 → (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha ∈ filter (fun x => g x ≠ 1) t
[PROOFSTEP]
intros h₁ h₂
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
⊢ (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha ∈ filter (fun x => g x ≠ 1) t
[PROOFSTEP]
refine (mem_filter.mpr ⟨hi a h₁ _, ?_⟩)
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
⊢ g ((fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha) ≠ 1
[PROOFSTEP]
specialize h a h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
H : f a = 1
⊢ False
[PROOFSTEP]
rw [H] at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : 1 ≠ 1
H : f a = 1
⊢ False
[PROOFSTEP]
simp at h₂ 
[GOAL]
case calc_1
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
h : f a = g (i a h₁ (_ : f a = 1 → False))
⊢ g ((fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha) ≠ 1
[PROOFSTEP]
rwa [← h]
[GOAL]
case calc_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∀ (a : α) (ha : a ∈ filter (fun x => f x ≠ 1) s), f a = g ((fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha)
[PROOFSTEP]
refine' (fun a ha => (mem_filter.mp ha).elim fun h₁ h₂ ↦ _)
[GOAL]
case calc_2
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
⊢ f a = g ((fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha)
[PROOFSTEP]
exact h a h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : f a ≠ 1
H : f a = 1
⊢ False
[PROOFSTEP]
rw [H] at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a : α
ha : a ∈ filter (fun x => f x ≠ 1) s
h₁ : a ∈ s
h₂ : 1 ≠ 1
H : f a = 1
⊢ False
[PROOFSTEP]
simp at h₂ 
[GOAL]
case calc_3
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ filter (fun x => f x ≠ 1) s) (ha₂ : a₂ ∈ filter (fun x => f x ≠ 1) s),
    (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₁ ha₁ = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
intros a₁ a₂ ha₁ ha₂
[GOAL]
case calc_3
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a₁ a₂ : α
ha₁ : a₁ ∈ filter (fun x => f x ≠ 1) s
ha₂ : a₂ ∈ filter (fun x => f x ≠ 1) s
⊢ (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₁ ha₁ = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
refine' (mem_filter.mp ha₁).elim fun _ha₁₁ _ha₁₂ ↦ _
[GOAL]
case calc_3
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a₁ a₂ : α
ha₁ : a₁ ∈ filter (fun x => f x ≠ 1) s
ha₂ : a₂ ∈ filter (fun x => f x ≠ 1) s
_ha₁₁ : a₁ ∈ s
_ha₁₂ : f a₁ ≠ 1
⊢ (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₁ ha₁ = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
refine' (mem_filter.mp ha₂).elim fun _ha₂₁ _ha₂₂ ↦ _
[GOAL]
case calc_3
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
a₁ a₂ : α
ha₁ : a₁ ∈ filter (fun x => f x ≠ 1) s
ha₂ : a₂ ∈ filter (fun x => f x ≠ 1) s
_ha₁₁ : a₁ ∈ s
_ha₁₂ : f a₁ ≠ 1
_ha₂₁ : a₂ ∈ s
_ha₂₂ : f a₂ ≠ 1
⊢ (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₁ ha₁ = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
apply i_inj
[GOAL]
case calc_4
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
⊢ ∀ (b : γ), b ∈ filter (fun x => g x ≠ 1) t → ∃ a ha, b = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha
[PROOFSTEP]
intros b hb
[GOAL]
case calc_4
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
b : γ
hb : b ∈ filter (fun x => g x ≠ 1) t
⊢ ∃ a ha, b = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha
[PROOFSTEP]
refine' (mem_filter.mp hb).elim fun h₁ h₂ ↦ _
[GOAL]
case calc_4
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
b : γ
hb : b ∈ filter (fun x => g x ≠ 1) t
h₁ : b ∈ t
h₂ : g b ≠ 1
⊢ ∃ a ha, b = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha
[PROOFSTEP]
obtain ⟨a, ha₁, ha₂, eq⟩ := i_surj b h₁ fun H ↦ by rw [H] at h₂ ; simp at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
b : γ
hb : b ∈ filter (fun x => g x ≠ 1) t
h₁ : b ∈ t
h₂ : g b ≠ 1
H : g b = 1
⊢ False
[PROOFSTEP]
rw [H] at h₂ 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
b : γ
hb : b ∈ filter (fun x => g x ≠ 1) t
h₁ : b ∈ t
h₂ : 1 ≠ 1
H : g b = 1
⊢ False
[PROOFSTEP]
simp at h₂ 
[GOAL]
case calc_4.intro.intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s : Finset α
t : Finset γ
f : α → β
g : γ → β
i : (a : α) → a ∈ s → f a ≠ 1 → γ
hi : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), i a h₁ h₂ ∈ t
i_inj :
  ∀ (a₁ a₂ : α) (h₁₁ : a₁ ∈ s) (h₁₂ : f a₁ ≠ 1) (h₂₁ : a₂ ∈ s) (h₂₂ : f a₂ ≠ 1), i a₁ h₁₁ h₁₂ = i a₂ h₂₁ h₂₂ → a₁ = a₂
i_surj : ∀ (b : γ), b ∈ t → g b ≠ 1 → ∃ a h₁ h₂, b = i a h₁ h₂
h : ∀ (a : α) (h₁ : a ∈ s) (h₂ : f a ≠ 1), f a = g (i a h₁ h₂)
b : γ
hb : b ∈ filter (fun x => g x ≠ 1) t
h₁ : b ∈ t
h₂ : g b ≠ 1
a : α
ha₁ : a ∈ s
ha₂ : f a ≠ 1
eq : b = i a ha₁ ha₂
⊢ ∃ a ha, b = (fun a ha => i a (_ : a ∈ s) (_ : f a ≠ 1)) a ha
[PROOFSTEP]
exact ⟨a, mem_filter.mpr ⟨ha₁, ha₂⟩, eq⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → ¬p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
x : α
hx : x ∈ s
⊢ (fun x hx => { val := x, property := hx }) x hx ∈ univ
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → ¬p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
a : α
ha : a ∈ s
⊢ (if hx : p a then f a hx else g a hx) =
    g ↑((fun x hx => { val := x, property := hx }) a ha) (_ : ¬p ↑((fun x hx => { val := x, property := hx }) a ha))
[PROOFSTEP]
dsimp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → ¬p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
a : α
ha : a ∈ s
⊢ (if hx : p a then f a hx else g a hx) = g a (_ : ¬p a)
[PROOFSTEP]
rw [dif_neg]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → ¬p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
b : { x // x ∈ s }
_hb : b ∈ univ
⊢ b = (fun x hx => { val := x, property := hx }) ↑b (_ : ↑b ∈ s)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
x : α
hx : x ∈ s
⊢ (fun x hx => { val := x, property := hx }) x hx ∈ univ
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
a : α
ha : a ∈ s
⊢ (if hx : p a then f a hx else g a hx) =
    f ↑((fun x hx => { val := x, property := hx }) a ha) (_ : p ↑((fun x hx => { val := x, property := hx }) a ha))
[PROOFSTEP]
dsimp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
a : α
ha : a ∈ s
⊢ (if hx : p a then f a hx else g a hx) = f a (_ : p a)
[PROOFSTEP]
rw [dif_pos]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
p : α → Prop
hp : DecidablePred p
h : ∀ (x : α), x ∈ s → p x
f : (x : α) → p x → β
g : (x : α) → ¬p x → β
b : { x // x ∈ s }
_hb : b ∈ univ
⊢ b = (fun x hx => { val := x, property := hx }) ↑b (_ : ↑b ∈ s)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : ∏ x in s, f x ≠ 1
⊢ ∃ a, a ∈ s ∧ f a ≠ 1
[PROOFSTEP]
classical
rw [← prod_filter_ne_one] at h 
rcases nonempty_of_prod_ne_one h with ⟨x, hx⟩
exact ⟨x, (mem_filter.1 hx).1, by simpa using (mem_filter.1 hx).2⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h : ∏ x in s, f x ≠ 1
⊢ ∃ a, a ∈ s ∧ f a ≠ 1
[PROOFSTEP]
rw [← prod_filter_ne_one] at h 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h✝ : ∏ x in s, f x ≠ 1
h : ∏ x in filter (fun x => f x ≠ 1) s, f x ≠ 1
⊢ ∃ a, a ∈ s ∧ f a ≠ 1
[PROOFSTEP]
rcases nonempty_of_prod_ne_one h with ⟨x, hx⟩
[GOAL]
case intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h✝ : ∏ x in s, f x ≠ 1
h : ∏ x in filter (fun x => f x ≠ 1) s, f x ≠ 1
x : α
hx : x ∈ filter (fun x => f x ≠ 1) s
⊢ ∃ a, a ∈ s ∧ f a ≠ 1
[PROOFSTEP]
exact ⟨x, (mem_filter.1 hx).1, by simpa using (mem_filter.1 hx).2⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
h✝ : ∏ x in s, f x ≠ 1
h : ∏ x in filter (fun x => f x ≠ 1) s, f x ≠ 1
x : α
hx : x ∈ filter (fun x => f x ≠ 1) s
⊢ f x ≠ 1
[PROOFSTEP]
simpa using (mem_filter.1 hx).2
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
⊢ ∏ x in range (n + 1), f x = f n * ∏ x in range n, f x
[PROOFSTEP]
rw [range_succ, prod_insert not_mem_range_self]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
⊢ ∏ x in range (n + 1), f x = (∏ x in range n, f x) * f n
[PROOFSTEP]
simp only [mul_comm, prod_range_succ_comm]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
⊢ ∏ k in range (n + 1 + 1), f k = (∏ k in range (n + 1), f (k + 1)) * f 0
[PROOFSTEP]
rw [prod_range_succ _ n, mul_right_comm, ← prod_range_succ' _ n, prod_range_succ]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
n : ℕ
hn : N ≤ n
⊢ ∏ k in range (n + 1), u k = ∏ k in range (N + 1), u k
[PROOFSTEP]
obtain ⟨m, rfl : n = N + m⟩ := le_iff_exists_add.mp hn
[GOAL]
case intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
m : ℕ
hn : N ≤ N + m
⊢ ∏ k in range (N + m + 1), u k = ∏ k in range (N + 1), u k
[PROOFSTEP]
clear hn
[GOAL]
case intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
m : ℕ
⊢ ∏ k in range (N + m + 1), u k = ∏ k in range (N + 1), u k
[PROOFSTEP]
induction' m with m hm
[GOAL]
case intro.zero
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
⊢ ∏ k in range (N + Nat.zero + 1), u k = ∏ k in range (N + 1), u k
[PROOFSTEP]
simp
[GOAL]
case intro.succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
m : ℕ
hm : ∏ k in range (N + m + 1), u k = ∏ k in range (N + 1), u k
⊢ ∏ k in range (N + Nat.succ m + 1), u k = ∏ k in range (N + 1), u k
[PROOFSTEP]
erw [prod_range_succ, hm]
[GOAL]
case intro.succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
u : ℕ → β
N : ℕ
hu : ∀ (n : ℕ), n ≥ N → u n = 1
m : ℕ
hm : ∏ k in range (N + m + 1), u k = ∏ k in range (N + 1), u k
⊢ (∏ k in range (N + 1), u k) * u (N + Nat.succ m) = ∏ k in range (N + 1), u k
[PROOFSTEP]
simp [hu, @zero_le' ℕ]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n m : ℕ
⊢ ∏ x in range (n + m), f x = (∏ x in range n, f x) * ∏ x in range m, f (n + x)
[PROOFSTEP]
induction' m with m hm
[GOAL]
case zero
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
⊢ ∏ x in range (n + Nat.zero), f x = (∏ x in range n, f x) * ∏ x in range Nat.zero, f (n + x)
[PROOFSTEP]
simp
[GOAL]
case succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n m : ℕ
hm : ∏ x in range (n + m), f x = (∏ x in range n, f x) * ∏ x in range m, f (n + x)
⊢ ∏ x in range (n + Nat.succ m), f x = (∏ x in range n, f x) * ∏ x in range (Nat.succ m), f (n + x)
[PROOFSTEP]
erw [Nat.add_succ, prod_range_succ, prod_range_succ, hm, mul_assoc]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
⊢ ∏ k in range 0, f k = 1
[PROOFSTEP]
rw [range_zero, prod_empty]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
⊢ ∏ k in range 1, f k = f 0
[PROOFSTEP]
rw [range_one]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
⊢ ∏ k in {0}, f k = f 0
[PROOFSTEP]
apply @prod_singleton β ℕ 0 f
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
l : List α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
⊢ prod (List.map f l) = ∏ m in toFinset l, f m ^ count m l
[PROOFSTEP]
induction' l with a s IH
[GOAL]
case nil
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
⊢ prod (List.map f []) = ∏ m in toFinset [], f m ^ count m []
[PROOFSTEP]
simp only [map_nil, prod_nil, count_nil, pow_zero, prod_const_one]
[GOAL]
case cons
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
⊢ prod (List.map f (a :: s)) = ∏ m in toFinset (a :: s), f m ^ count m (a :: s)
[PROOFSTEP]
simp only [List.map, List.prod_cons, toFinset_cons, IH]
[GOAL]
case cons
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
⊢ f a * ∏ m in toFinset s, f m ^ count m s = ∏ x in insert a (toFinset s), f x ^ count x (a :: s)
[PROOFSTEP]
by_cases has : a ∈ s.toFinset
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : a ∈ toFinset s
⊢ f a * ∏ m in toFinset s, f m ^ count m s = ∏ x in insert a (toFinset s), f x ^ count x (a :: s)
[PROOFSTEP]
rw [insert_eq_of_mem has, ← insert_erase has, prod_insert (not_mem_erase _ _), prod_insert (not_mem_erase _ _), ←
  mul_assoc, count_cons_self, pow_succ]
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : a ∈ toFinset s
⊢ f a * f a ^ count a s * ∏ x in erase (toFinset s) a, f x ^ count x s =
    f a * f a ^ count a s * ∏ x in erase (toFinset s) a, f x ^ count x (a :: s)
[PROOFSTEP]
congr 1
[GOAL]
case pos.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : a ∈ toFinset s
⊢ ∏ x in erase (toFinset s) a, f x ^ count x s = ∏ x in erase (toFinset s) a, f x ^ count x (a :: s)
[PROOFSTEP]
refine' prod_congr rfl fun x hx => _
[GOAL]
case pos.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : a ∈ toFinset s
x : α
hx : x ∈ erase (toFinset s) a
⊢ f x ^ count x s = f x ^ count x (a :: s)
[PROOFSTEP]
rw [count_cons_of_ne (ne_of_mem_erase hx)]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : ¬a ∈ toFinset s
⊢ f a * ∏ m in toFinset s, f m ^ count m s = ∏ x in insert a (toFinset s), f x ^ count x (a :: s)
[PROOFSTEP]
rw [prod_insert has, count_cons_self, count_eq_zero_of_not_mem (mt mem_toFinset.2 has), pow_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : ¬a ∈ toFinset s
⊢ f a * ∏ m in toFinset s, f m ^ count m s = f a * ∏ x in toFinset s, f x ^ count x (a :: s)
[PROOFSTEP]
congr 1
[GOAL]
case neg.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : ¬a ∈ toFinset s
⊢ ∏ m in toFinset s, f m ^ count m s = ∏ x in toFinset s, f x ^ count x (a :: s)
[PROOFSTEP]
refine' prod_congr rfl fun x hx => _
[GOAL]
case neg.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : ¬a ∈ toFinset s
x : α
hx : x ∈ toFinset s
⊢ f x ^ count x s = f x ^ count x (a :: s)
[PROOFSTEP]
rw [count_cons_of_ne]
[GOAL]
case neg.e_a.h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
a : α
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
has : ¬a ∈ toFinset s
x : α
hx : x ∈ toFinset s
⊢ x ≠ a
[PROOFSTEP]
rintro rfl
[GOAL]
case neg.e_a.h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
s : List α
IH : prod (List.map f s) = ∏ m in toFinset s, f m ^ count m s
x : α
hx : x ∈ toFinset s
has : ¬x ∈ toFinset s
⊢ False
[PROOFSTEP]
exact has hx
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
s : List α
⊢ prod s = ∏ m in toFinset s, m ^ count m s
[PROOFSTEP]
simpa using prod_list_map_count s id
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : List α
s : Finset α
hs : toFinset m ⊆ s
⊢ prod m = ∏ i in s, i ^ count i m
[PROOFSTEP]
rw [prod_list_count]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : List α
s : Finset α
hs : toFinset m ⊆ s
⊢ ∏ m_1 in toFinset m, m_1 ^ count m_1 m = ∏ i in s, i ^ count i m
[PROOFSTEP]
refine' prod_subset hs fun x _ hx => _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : List α
s : Finset α
hs : toFinset m ⊆ s
x : α
x✝ : x ∈ s
hx : ¬x ∈ toFinset m
⊢ x ^ count x m = 1
[PROOFSTEP]
rw [mem_toFinset] at hx 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : List α
s : Finset α
hs : toFinset m ⊆ s
x : α
x✝ : x ∈ s
hx : ¬x ∈ m
⊢ x ^ count x m = 1
[PROOFSTEP]
rw [count_eq_zero_of_not_mem hx, pow_zero]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
p : α → Prop
inst✝ : DecidablePred p
l : List α
⊢ ∑ x in filter p (toFinset l), count x l = countp (fun b => decide (p b)) l
[PROOFSTEP]
simp [Finset.sum, sum_map_count_dedup_filter_eq_countp p l]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
s : Multiset α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
⊢ Multiset.prod (Multiset.map f s) = ∏ m in Multiset.toFinset s, f m ^ Multiset.count m s
[PROOFSTEP]
refine' Quot.induction_on s fun l => _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
s : Multiset α
M : Type u_2
inst✝ : CommMonoid M
f : α → M
l : List α
⊢ Multiset.prod (Multiset.map f (Quot.mk Setoid.r l)) =
    ∏ m in Multiset.toFinset (Quot.mk Setoid.r l), f m ^ Multiset.count m (Quot.mk Setoid.r l)
[PROOFSTEP]
simp [prod_list_map_count l f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
s : Multiset α
⊢ Multiset.prod s = ∏ m in Multiset.toFinset s, m ^ Multiset.count m s
[PROOFSTEP]
convert prod_multiset_map_count s id
[GOAL]
case h.e'_2.h.e'_3
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
s : Multiset α
⊢ s = Multiset.map id s
[PROOFSTEP]
rw [Multiset.map_id]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : Multiset α
s : Finset α
hs : Multiset.toFinset m ⊆ s
⊢ Multiset.prod m = ∏ i in s, i ^ Multiset.count i m
[PROOFSTEP]
revert hs
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : Multiset α
s : Finset α
⊢ Multiset.toFinset m ⊆ s → Multiset.prod m = ∏ i in s, i ^ Multiset.count i m
[PROOFSTEP]
refine' Quot.induction_on m fun l => _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : Multiset α
s : Finset α
l : List α
⊢ Multiset.toFinset (Quot.mk Setoid.r l) ⊆ s →
    Multiset.prod (Quot.mk Setoid.r l) = ∏ i in s, i ^ Multiset.count i (Quot.mk Setoid.r l)
[PROOFSTEP]
simp only [quot_mk_to_coe'', coe_prod, coe_count]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoid β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
m : Multiset α
s : Finset α
l : List α
⊢ Multiset.toFinset ↑l ⊆ s → List.prod l = ∏ x in s, x ^ List.count x l
[PROOFSTEP]
apply prod_list_count_of_subset l s
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
m : Multiset α
f : { x // x ∈ m } → β
g : α → β
hfg : ∀ (x : { x // x ∈ m }), f x = g ↑x
x✝³ x✝² : { x // x ∈ m }
x✝¹ : x✝³ ∈ univ
x✝ : x✝² ∈ univ
h : (fun x x_1 => ↑x) x✝³ x✝¹ = (fun x x_1 => ↑x) x✝² x✝
⊢ x✝³ = x✝²
[PROOFSTEP]
ext
[GOAL]
case a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
m : Multiset α
f : { x // x ∈ m } → β
g : α → β
hfg : ∀ (x : { x // x ∈ m }), f x = g ↑x
x✝³ x✝² : { x // x ∈ m }
x✝¹ : x✝³ ∈ univ
x✝ : x✝² ∈ univ
h : (fun x x_1 => ↑x) x✝³ x✝¹ = (fun x x_1 => ↑x) x✝² x✝
⊢ ↑x✝³ = ↑x✝²
[PROOFSTEP]
assumption
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommMonoid M
f : α → M
p : M → Prop
hom : ∀ (a b : M), p a → p b → p (a * b)
nonempty : Finset.Nonempty s
base : ∀ (x : α), x ∈ s → p (f x)
⊢ Multiset.map (fun x => f x) s.val ≠ ∅
[PROOFSTEP]
simp [nonempty_iff_ne_empty.mp nonempty]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f s : ℕ → β
base : s 0 = 1
step : ∀ (n : ℕ), s (n + 1) = s n * f n
n : ℕ
⊢ ∏ k in range n, f k = s n
[PROOFSTEP]
induction' n with k hk
[GOAL]
case zero
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f s : ℕ → β
base : s 0 = 1
step : ∀ (n : ℕ), s (n + 1) = s n * f n
⊢ ∏ k in range Nat.zero, f k = s Nat.zero
[PROOFSTEP]
rw [Finset.prod_range_zero, base]
[GOAL]
case succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f s : ℕ → β
base : s 0 = 1
step : ∀ (n : ℕ), s (n + 1) = s n * f n
k : ℕ
hk : ∏ k in range k, f k = s k
⊢ ∏ k in range (Nat.succ k), f k = s (Nat.succ k)
[PROOFSTEP]
simp only [hk, Finset.prod_range_succ, step, mul_comm]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ ∏ i in range n, f (i + 1) / f i = f n / f 0
[PROOFSTEP]
apply prod_range_induction
[GOAL]
case base
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ f 0 / f 0 = 1
[PROOFSTEP]
simp
[GOAL]
case step
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ ∀ (n : ℕ), f (n + 1) / f 0 = f n / f 0 * (f (n + 1) / f n)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ ∏ i in range n, f i / f (i + 1) = f 0 / f n
[PROOFSTEP]
apply prod_range_induction
[GOAL]
case base
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ f 0 / f 0 = 1
[PROOFSTEP]
simp
[GOAL]
case step
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ ∀ (n : ℕ), f 0 / f (n + 1) = f 0 / f n * (f n / f (n + 1))
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ f n = f 0 * ∏ i in range n, f (i + 1) / f i
[PROOFSTEP]
rw [prod_range_div, mul_div_cancel'_right]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ f n = ∏ i in range (n + 1), if i = 0 then f 0 else f i / f (i - 1)
[PROOFSTEP]
conv_lhs => rw [Finset.eq_prod_range_div f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
| f n
[PROOFSTEP]
rw [Finset.eq_prod_range_div f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
| f n
[PROOFSTEP]
rw [Finset.eq_prod_range_div f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
| f n
[PROOFSTEP]
rw [Finset.eq_prod_range_div f]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
M : Type u_2
inst✝ : CommGroup M
f : ℕ → M
n : ℕ
⊢ f 0 * ∏ i in range n, f (i + 1) / f i = ∏ i in range (n + 1), if i = 0 then f 0 else f i / f (i - 1)
[PROOFSTEP]
simp [Finset.prod_range_succ', mul_comm]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ ∑ i in range n, (f (i + 1) - f i) = f n - f 0
[PROOFSTEP]
apply sum_range_induction
[GOAL]
case base
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ f 0 - f 0 = 0
case step
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ ∀ (n : ℕ), f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
case base => apply tsub_self
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ f 0 - f 0 = 0
[PROOFSTEP]
case base => apply tsub_self
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ f 0 - f 0 = 0
[PROOFSTEP]
apply tsub_self
[GOAL]
case step
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ ∀ (n : ℕ), f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
case step =>
  intro n
  have h₁ : f n ≤ f (n + 1) := h (Nat.le_succ _)
  have h₂ : f 0 ≤ f n := h (Nat.zero_le _)
  rw [tsub_add_eq_add_tsub h₂, add_tsub_cancel_of_le h₁]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ ∀ (n : ℕ), f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
case step =>
  intro n
  have h₁ : f n ≤ f (n + 1) := h (Nat.le_succ _)
  have h₂ : f 0 ≤ f n := h (Nat.zero_le _)
  rw [tsub_add_eq_add_tsub h₂, add_tsub_cancel_of_le h₁]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n : ℕ
⊢ ∀ (n : ℕ), f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
intro n
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n✝ n : ℕ
⊢ f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
have h₁ : f n ≤ f (n + 1) := h (Nat.le_succ _)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n✝ n : ℕ
h₁ : f n ≤ f (n + 1)
⊢ f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
have h₂ : f 0 ≤ f n := h (Nat.zero_le _)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝⁴ : CommMonoid β
inst✝³ : CanonicallyOrderedAddMonoid α
inst✝² : Sub α
inst✝¹ : OrderedSub α
inst✝ : ContravariantClass α α (fun x x_1 => x + x_1) fun x x_1 => x ≤ x_1
f : ℕ → α
h : Monotone f
n✝ n : ℕ
h₁ : f n ≤ f (n + 1)
h₂ : f 0 ≤ f n
⊢ f (n + 1) - f 0 = f n - f 0 + (f (n + 1) - f n)
[PROOFSTEP]
rw [tsub_add_eq_add_tsub h₂, add_tsub_cancel_of_le h₁]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
b : β
⊢ ∀ (n : ℕ), b ^ n = ∏ _k in range n, b
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
n : ℕ
f : ℕ → β
⊢ ∏ r in range (n + 1), f (n - r) = ∏ k in range (n + 1), f k
[PROOFSTEP]
induction' n with n ih
[GOAL]
case zero
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
⊢ ∏ r in range (Nat.zero + 1), f (Nat.zero - r) = ∏ k in range (Nat.zero + 1), f k
[PROOFSTEP]
rw [prod_range_one, prod_range_one]
[GOAL]
case succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
ih : ∏ r in range (n + 1), f (n - r) = ∏ k in range (n + 1), f k
⊢ ∏ r in range (Nat.succ n + 1), f (Nat.succ n - r) = ∏ k in range (Nat.succ n + 1), f k
[PROOFSTEP]
rw [prod_range_succ', prod_range_succ _ (Nat.succ n)]
[GOAL]
case succ
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
f : ℕ → β
n : ℕ
ih : ∏ r in range (n + 1), f (n - r) = ∏ k in range (n + 1), f k
⊢ (∏ k in range (n + 1), f (Nat.succ n - (k + 1))) * f (Nat.succ n - 0) =
    (∏ x in range (Nat.succ n), f x) * f (Nat.succ n)
[PROOFSTEP]
simp [← ih]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1
[PROOFSTEP]
haveI := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
this : DecidableEq α
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1
[PROOFSTEP]
haveI := Classical.decEq β
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
⊢ ∀ (g : (a : α) → a ∈ s → α),
    (∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1) →
      (∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a) →
        ∀ (g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s),
          (∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a) → ∏ x in s, f x = 1
[PROOFSTEP]
exact
  Finset.strongInductionOn s fun s ih g h g_ne g_mem g_inv =>
    s.eq_empty_or_nonempty.elim (fun hs => hs.symm ▸ rfl) fun ⟨x, hx⟩ =>
      have hmem : ∀ y ∈ (s.erase x).erase (g x hx), y ∈ s := fun y hy => mem_of_mem_erase (mem_of_mem_erase hy)
      have g_inj : ∀ {x hx y hy}, g x hx = g y hy → x = y := fun {x hx y hy} h => by rw [← g_inv x hx, ← g_inv y hy];
        simp [h]
      have ih' : (∏ y in erase (erase s x) (g x hx), f y) = (1 : β) :=
        ih ((s.erase x).erase (g x hx))
          ⟨Subset.trans (erase_subset _ _) (erase_subset _ _), fun h =>
            not_mem_erase (g x hx) (s.erase x) (h (g_mem x hx))⟩
          (fun y hy => g y (hmem y hy)) (fun y hy => h y (hmem y hy)) (fun y hy => g_ne y (hmem y hy))
          (fun y hy =>
            mem_erase.2
              ⟨fun h : g y _ = g x hx => by simp [g_inj h] at hy ,
                mem_erase.2
                  ⟨fun h : g y _ = x => by
                    have : y = g x hx := g_inv y (hmem y hy) ▸ by simp [h]
                    simp [this] at hy , g_mem y (hmem y hy)⟩⟩)
          fun y hy => g_inv y (hmem y hy)
      if hx1 : f x = 1 then
        ih' ▸
          Eq.symm
            (prod_subset hmem fun y hy hy₁ =>
              have : y = x ∨ y = g x hx := by simpa [hy, -not_and, mem_erase, not_and_or, or_comm] using hy₁
              this.elim (fun hy => hy.symm ▸ hx1) fun hy => h x hx ▸ hy ▸ hx1.symm ▸ (one_mul _).symm)
      else by
        rw [← insert_erase hx, prod_insert (not_mem_erase _ _), ←
          insert_erase (mem_erase.2 ⟨g_ne x hx hx1, g_mem x hx⟩), prod_insert (not_mem_erase _ _), ih', mul_one, h x hx]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝¹ : Finset.Nonempty s
x✝ : α
hx✝ : x✝ ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x✝) (g x✝ hx✝) → y ∈ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
h : g x hx = g y hy
⊢ x = y
[PROOFSTEP]
rw [← g_inv x hx, ← g_inv y hy]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝¹ : Finset.Nonempty s
x✝ : α
hx✝ : x✝ ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x✝) (g x✝ hx✝) → y ∈ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
h : g x hx = g y hy
⊢ g (g x hx) (_ : g x hx ∈ s) = g (g y hy) (_ : g y hy ∈ s)
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = g x hx
⊢ False
[PROOFSTEP]
simp [g_inj h] at hy 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
⊢ False
[PROOFSTEP]
have : y = g x hx := g_inv y (hmem y hy) ▸ by simp [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
⊢ g (g y (_ : y ∈ s)) (_ : g y (_ : y ∈ s) ∈ s) = g x hx
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝¹ : DecidableEq α
this✝ : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h✝ : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
y : α
hy : y ∈ erase (erase s x) (g x hx)
h : g y (_ : y ∈ s) = x
this : y = g x hx
⊢ False
[PROOFSTEP]
simp [this] at hy 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
ih' : ∏ y in erase (erase s x) (g x hx), f y = 1
hx1 : f x = 1
y : α
hy : y ∈ s
hy₁ : ¬y ∈ erase (erase s x) (g x hx)
⊢ y = x ∨ y = g x hx
[PROOFSTEP]
simpa [hy, -not_and, mem_erase, not_and_or, or_comm] using hy₁
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommMonoid β
s✝ : Finset α
f : α → β
this✝ : DecidableEq α
this : DecidableEq β
s : Finset α
ih :
  ∀ (t : Finset α),
    t ⊂ s →
      ∀ (g : (a : α) → a ∈ t → α),
        (∀ (a : α) (ha : a ∈ t), f a * f (g a ha) = 1) →
          (∀ (a : α) (ha : a ∈ t), f a ≠ 1 → g a ha ≠ a) →
            ∀ (g_mem : ∀ (a : α) (ha : a ∈ t), g a ha ∈ t),
              (∀ (a : α) (ha : a ∈ t), g (g a ha) (_ : g a ha ∈ t) = a) → ∏ x in t, f x = 1
g : (a : α) → a ∈ s → α
h : ∀ (a : α) (ha : a ∈ s), f a * f (g a ha) = 1
g_ne : ∀ (a : α) (ha : a ∈ s), f a ≠ 1 → g a ha ≠ a
g_mem : ∀ (a : α) (ha : a ∈ s), g a ha ∈ s
g_inv : ∀ (a : α) (ha : a ∈ s), g (g a ha) (_ : g a ha ∈ s) = a
x✝ : Finset.Nonempty s
x : α
hx : x ∈ s
hmem : ∀ (y : α), y ∈ erase (erase s x) (g x hx) → y ∈ s
g_inj : ∀ {x : α} {hx : x ∈ s} {y : α} {hy : y ∈ s}, g x hx = g y hy → x = y
ih' : ∏ y in erase (erase s x) (g x hx), f y = 1
hx1 : ¬f x = 1
⊢ ∏ x in s, f x = 1
[PROOFSTEP]
rw [← insert_erase hx, prod_insert (not_mem_erase _ _), ← insert_erase (mem_erase.2 ⟨g_ne x hx hx1, g_mem x hx⟩),
  prod_insert (not_mem_erase _ _), ih', mul_one, h x hx]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
⊢ ∀ (a : α) (ha : a ∈ s),
    (fun a _ha => { fst := g a, snd := a }) a ha ∈ Finset.sigma (image g s) fun b => filter (fun a => g a = b) s
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
⊢ ∀ (a : α), a ∈ s → (∃ a_1, a_1 ∈ s ∧ g a_1 = g a) ∧ a ∈ s
[PROOFSTEP]
tauto
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
⊢ ∀ (a₁ a₂ : α) (ha₁ : a₁ ∈ s) (ha₂ : a₂ ∈ s),
    (fun a _ha => { fst := g a, snd := a }) a₁ ha₁ = (fun a _ha => { fst := g a, snd := a }) a₂ ha₂ → a₁ = a₂
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
⊢ ∀ (b : (_ : γ) × α),
    (b ∈ Finset.sigma (image g s) fun b => filter (fun a => g a = b) s) →
      ∃ a ha, b = (fun a _ha => { fst := g a, snd := a }) a ha
[PROOFSTEP]
rintro ⟨b_fst, b_snd⟩ H
[GOAL]
case mk
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
b_fst : γ
b_snd : α
H : { fst := b_fst, snd := b_snd } ∈ Finset.sigma (image g s) fun b => filter (fun a => g a = b) s
⊢ ∃ a ha, { fst := b_fst, snd := b_snd } = (fun a _ha => { fst := g a, snd := a }) a ha
[PROOFSTEP]
simp only [mem_image, exists_prop, mem_filter, mem_sigma, decide_eq_true_eq] at H 
[GOAL]
case mk
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
b_fst : γ
b_snd : α
H : (∃ a, a ∈ s ∧ g a = b_fst) ∧ b_snd ∈ s ∧ g b_snd = b_fst
⊢ ∃ a ha, { fst := b_fst, snd := b_snd } = (fun a _ha => { fst := g a, snd := a }) a ha
[PROOFSTEP]
tauto
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq γ
f : γ → β
g : α → γ
b : γ
_hb : b ∈ image g s
⊢ ∀ (x : α), x ∈ filter (fun a => g a = b) s → f (g x) = f b
[PROOFSTEP]
simp (config := { contextual := true })
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s t : Finset α
f g : α → β
⊢ ∏ x in s, piecewise t f g x = (∏ x in s ∩ t, f x) * ∏ x in s \ t, g x
[PROOFSTEP]
erw [prod_ite, filter_mem_eq_inter, ← sdiff_eq_filter]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s t : Finset α
f : α → β
⊢ (∏ x in s ∩ t, f x) * ∏ x in s \ t, f x = ∏ x in s, f x
[PROOFSTEP]
convert (s.prod_piecewise t f f).symm
[GOAL]
case h.e'_3.a.h.e
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s t : Finset α
f : α → β
x✝ : α
a✝ : x✝ ∈ s
⊢ f = piecewise t f f
[PROOFSTEP]
simp [Finset.piecewise]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : i ∈ s
f : α → β
⊢ ∏ x in s, f x = f i * ∏ x in s \ {i}, f x
[PROOFSTEP]
convert (s.prod_inter_mul_prod_diff { i } f).symm
[GOAL]
case h.e'_3.h.e'_5
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : i ∈ s
f : α → β
⊢ f i = ∏ x in s ∩ {i}, f x
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : i ∈ s
f : α → β
⊢ ∏ x in s, f x = (∏ x in s \ {i}, f x) * f i
[PROOFSTEP]
rw [prod_eq_mul_prod_diff_singleton h, mul_comm]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
a : α
s : Finset α
ha : a ∈ s
⊢ f a ∣ ∏ i in s, f i
[PROOFSTEP]
classical
rw [Finset.prod_eq_mul_prod_diff_singleton ha]
exact dvd_mul_right _ _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
a : α
s : Finset α
ha : a ∈ s
⊢ f a ∣ ∏ i in s, f i
[PROOFSTEP]
rw [Finset.prod_eq_mul_prod_diff_singleton ha]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
f : α → β
a : α
s : Finset α
ha : a ∈ s
⊢ f a ∣ f a * ∏ x in s \ {a}, f x
[PROOFSTEP]
exact dvd_mul_right _ _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
⊢ ∏ x in s, f x = ∏ xbar in image Quotient.mk'' s, ∏ y in filter (fun x => Quotient.mk R x = xbar) s, f y
[PROOFSTEP]
refine' (Finset.prod_image' f fun x _hx => _).symm
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
x : α
_hx : x ∈ s
⊢ ∏ y in filter (fun x_1 => Quotient.mk R x_1 = Quotient.mk'' x) s, f y =
    ∏ x in filter (fun c' => Quotient.mk'' c' = Quotient.mk'' x) s, f x
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
h : ∀ (x : α), x ∈ s → ∏ a in filter (fun y => y ≈ x) s, f a = 1
⊢ ∏ x in s, f x = 1
[PROOFSTEP]
rw [prod_partition R, ← Finset.prod_eq_one]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
h : ∀ (x : α), x ∈ s → ∏ a in filter (fun y => y ≈ x) s, f a = 1
⊢ ∀ (x : Quotient R), x ∈ image Quotient.mk'' s → ∏ y in filter (fun x_1 => Quotient.mk R x_1 = x) s, f y = 1
[PROOFSTEP]
intro xbar xbar_in_s
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
h : ∀ (x : α), x ∈ s → ∏ a in filter (fun y => y ≈ x) s, f a = 1
xbar : Quotient R
xbar_in_s : xbar ∈ image Quotient.mk'' s
⊢ ∏ y in filter (fun x => Quotient.mk R x = xbar) s, f y = 1
[PROOFSTEP]
obtain ⟨x, x_in_s, rfl⟩ := mem_image.mp xbar_in_s
[GOAL]
case intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
h : ∀ (x : α), x ∈ s → ∏ a in filter (fun y => y ≈ x) s, f a = 1
x : α
x_in_s : x ∈ s
xbar_in_s : Quotient.mk'' x ∈ image Quotient.mk'' s
⊢ ∏ y in filter (fun x_1 => Quotient.mk R x_1 = Quotient.mk'' x) s, f y = 1
[PROOFSTEP]
simp only [← Quotient.eq] at h 
[GOAL]
case intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoid β
R : Setoid α
inst✝ : DecidableRel Setoid.r
x : α
x_in_s : x ∈ s
xbar_in_s : Quotient.mk'' x ∈ image Quotient.mk'' s
h : ∀ (x : α), x ∈ s → ∏ x in filter (fun y => Quotient.mk R y = Quotient.mk R x) s, f x = 1
⊢ ∏ y in filter (fun x_1 => Quotient.mk R x_1 = Quotient.mk'' x) s, f y = 1
[PROOFSTEP]
exact h x x_in_s
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : ¬i ∈ s
f : α → β
b : β
⊢ ∏ x in s, Function.update f i b x = ∏ x in s, f x
[PROOFSTEP]
apply prod_congr rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : ¬i ∈ s
f : α → β
b : β
⊢ ∀ (x : α), x ∈ s → Function.update f i b x = f x
[PROOFSTEP]
intros j hj
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : ¬i ∈ s
f : α → β
b : β
j : α
hj : j ∈ s
⊢ Function.update f i b j = f j
[PROOFSTEP]
have : j ≠ i := by
  rintro rfl
  exact h hj
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : ¬i ∈ s
f : α → β
b : β
j : α
hj : j ∈ s
⊢ j ≠ i
[PROOFSTEP]
rintro rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
b : β
j : α
hj : j ∈ s
h : ¬j ∈ s
⊢ False
[PROOFSTEP]
exact h hj
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : ¬i ∈ s
f : α → β
b : β
j : α
hj : j ∈ s
this : j ≠ i
⊢ Function.update f i b j = f j
[PROOFSTEP]
simp [this]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : i ∈ s
f : α → β
b : β
⊢ ∏ x in s, Function.update f i b x = b * ∏ x in s \ {i}, f x
[PROOFSTEP]
rw [update_eq_piecewise, prod_piecewise]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
i : α
h : i ∈ s
f : α → β
b : β
⊢ (∏ x in s ∩ {i}, b) * ∏ x in s \ {i}, f x = b * ∏ x in s \ {i}, f x
[PROOFSTEP]
simp [h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
⊢ ∀ (x : α), x ∈ s → f x = b
[PROOFSTEP]
intro x hx
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
⊢ f x = b
[PROOFSTEP]
by_cases hc0 : s.card = 0
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
hc0 : card s = 0
⊢ f x = b
[PROOFSTEP]
exact False.elim (card_ne_zero_of_mem hx hc0)
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
hc0 : ¬card s = 0
⊢ f x = b
[PROOFSTEP]
have h1 : s.card = 1 := le_antisymm hc (Nat.one_le_of_lt (Nat.pos_of_ne_zero hc0))
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
hc0 : ¬card s = 0
h1 : card s = 1
⊢ f x = b
[PROOFSTEP]
rw [card_eq_one] at h1 
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
hc0 : ¬card s = 0
h1 : ∃ a, s = {a}
⊢ f x = b
[PROOFSTEP]
cases' h1 with x2 hx2
[GOAL]
case neg.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hx : x ∈ s
hc0 : ¬card s = 0
x2 : α
hx2 : s = {x2}
⊢ f x = b
[PROOFSTEP]
rw [hx2, mem_singleton] at hx 
[GOAL]
case neg.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
h : ∏ x in s, f x = b
x : α
hc0 : ¬card s = 0
x2 : α
hx : x = x2
hx2 : s = {x2}
⊢ f x = b
[PROOFSTEP]
simp_rw [hx2] at h 
[GOAL]
case neg.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
x : α
hc0 : ¬card s = 0
x2 : α
hx : x = x2
hx2 : s = {x2}
h : ∏ x in {x2}, f x = b
⊢ f x = b
[PROOFSTEP]
rw [hx]
[GOAL]
case neg.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
x : α
hc0 : ¬card s = 0
x2 : α
hx : x = x2
hx2 : s = {x2}
h : ∏ x in {x2}, f x = b
⊢ f x2 = b
[PROOFSTEP]
rw [prod_singleton] at h 
[GOAL]
case neg.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
hc : card s ≤ 1
f : α → β
b : β
x : α
hc0 : ¬card s = 0
x2 : α
hx : x = x2
hx2 : s = {x2}
h : f x2 = b
⊢ f x2 = b
[PROOFSTEP]
exact h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : a ∈ s
⊢ f a * ∏ x in erase s a, f x = ∏ x in s, f x
[PROOFSTEP]
rw [← prod_insert (not_mem_erase a s), insert_erase h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : a ∈ s
⊢ (∏ x in erase s a, f x) * f a = ∏ x in s, f x
[PROOFSTEP]
rw [mul_comm, mul_prod_erase s f h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : f a = 1
⊢ ∏ x in erase s a, f x = ∏ x in s, f x
[PROOFSTEP]
rw [← sdiff_singleton_eq_erase]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : f a = 1
⊢ ∏ x in s \ {a}, f x = ∏ x in s, f x
[PROOFSTEP]
refine' prod_subset (sdiff_subset _ _) fun x hx hnx => _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : f a = 1
x : α
hx : x ∈ s
hnx : ¬x ∈ s \ {a}
⊢ f x = 1
[PROOFSTEP]
rw [sdiff_singleton_eq_erase] at hnx 
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
h : f a = 1
x : α
hx : x ∈ s
hnx : ¬x ∈ erase s a
⊢ f x = 1
[PROOFSTEP]
rwa [eq_of_mem_of_not_mem_erase hx hnx]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
⊢ (∏ i in s, if f i then a else 1) = if ∃ i, i ∈ s ∧ f i then a else 1
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
h : ∃ i, i ∈ s ∧ f i
⊢ (∏ i in s, if f i then a else 1) = a
[PROOFSTEP]
obtain ⟨i, hi, hfi⟩ := h
[GOAL]
case pos.intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
i : α
hi : i ∈ s
hfi : f i
⊢ (∏ i in s, if f i then a else 1) = a
[PROOFSTEP]
rw [prod_eq_single_of_mem _ hi, if_pos hfi]
[GOAL]
case pos.intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
i : α
hi : i ∈ s
hfi : f i
⊢ ∀ (b : α), b ∈ s → b ≠ i → (if f b then a else 1) = 1
[PROOFSTEP]
exact fun j hj h => if_neg fun hfj => (hf hj hi h).le_bot ⟨hfj, hfi⟩
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
h : ¬∃ i, i ∈ s ∧ f i
⊢ (∏ i in s, if f i then a else 1) = 1
[PROOFSTEP]
push_neg at h 
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
h : ∀ (i : α), i ∈ s → ¬f i
⊢ (∏ i in s, if f i then a else 1) = 1
[PROOFSTEP]
rw [prod_eq_one]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
f : α → Prop
inst✝ : DecidablePred f
hf : Set.PairwiseDisjoint (↑s) f
a : β
h : ∀ (i : α), i ∈ s → ¬f i
⊢ ∀ (x : α), x ∈ s → (if f x then a else 1) = 1
[PROOFSTEP]
exact fun i hi => if_neg (h i hi)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
⊢ ∏ m in erase s d, f m < ∏ m in s, f m
[PROOFSTEP]
conv in ∏ m in s, f m => rw [← Finset.insert_erase hd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
| ∏ m in s, f m
[PROOFSTEP]
rw [← Finset.insert_erase hd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
| ∏ m in s, f m
[PROOFSTEP]
rw [← Finset.insert_erase hd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
| ∏ m in s, f m
[PROOFSTEP]
rw [← Finset.insert_erase hd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
⊢ ∏ m in erase s d, f m < ∏ m in insert d (erase s d), f m
[PROOFSTEP]
rw [Finset.prod_insert (Finset.not_mem_erase d s)]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ✝ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝³ : CommMonoid β
γ : Type u_2
inst✝² : DecidableEq α
inst✝¹ : OrderedCommMonoid γ
inst✝ : CovariantClass γ γ (fun x x_1 => x * x_1) fun x x_1 => x < x_1
s : Finset α
d : α
hd : d ∈ s
f : α → γ
hdf : 1 < f d
⊢ ∏ m in erase s d, f m < f d * ∏ x in erase s d, f x
[PROOFSTEP]
exact lt_mul_of_one_lt_left' _ hdf
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
⊢ ∀ (x : α), x ∈ s → f x = 1
[PROOFSTEP]
intro x hx
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : x ∈ s
⊢ f x = 1
[PROOFSTEP]
classical
by_cases h : x = a
· rw [h]
  rw [h] at hx 
  rw [← prod_subset (singleton_subset_iff.2 hx) fun t ht ha => h1 t ht (not_mem_singleton.1 ha), prod_singleton] at hp 
  exact hp
· exact h1 x hx h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : x ∈ s
⊢ f x = 1
[PROOFSTEP]
by_cases h : x = a
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : x ∈ s
h : x = a
⊢ f x = 1
[PROOFSTEP]
rw [h]
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : x ∈ s
h : x = a
⊢ f a = 1
[PROOFSTEP]
rw [h] at hx 
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : a ∈ s
h : x = a
⊢ f a = 1
[PROOFSTEP]
rw [← prod_subset (singleton_subset_iff.2 hx) fun t ht ha => h1 t ht (not_mem_singleton.1 ha), prod_singleton] at hp 
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : f a = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : a ∈ s
h : x = a
⊢ f a = 1
[PROOFSTEP]
exact hp
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : CommMonoid β
s : Finset α
f : α → β
a : α
hp : ∏ x in s, f x = 1
h1 : ∀ (x : α), x ∈ s → x ≠ a → f x = 1
x : α
hx : x ∈ s
h : ¬x = a
⊢ f x = 1
[PROOFSTEP]
exact h1 x hx h
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝¹ : CommMonoid β
inst✝ : DecidableEq α
s : Finset α
f : α → β
a : α
⊢ (∏ x in s, f x ^ if a = x then 1 else 0) = if a ∈ s then f a else 1
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
S : Finset α
g1 g2 : α → β
h : ∀ (a : α), a ∈ S → g1 a ∣ g2 a
⊢ Finset.prod S g1 ∣ Finset.prod S g2
[PROOFSTEP]
classical
induction' S using Finset.induction_on' with a T _haS _hTS haT IH
· simp
rw [Finset.prod_insert haT, Finset.prod_insert haT]
exact mul_dvd_mul (h a $ T.mem_insert_self a) (IH fun b hb ↦ h b $ Finset.mem_insert_of_mem hb)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
S : Finset α
g1 g2 : α → β
h : ∀ (a : α), a ∈ S → g1 a ∣ g2 a
⊢ Finset.prod S g1 ∣ Finset.prod S g2
[PROOFSTEP]
induction' S using Finset.induction_on' with a T _haS _hTS haT IH
[GOAL]
case h₁
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid β
S : Finset α
g1 g2 : α → β
h✝ : ∀ (a : α), a ∈ S → g1 a ∣ g2 a
h : ∀ (a : α), a ∈ ∅ → g1 a ∣ g2 a
⊢ Finset.prod ∅ g1 ∣ Finset.prod ∅ g2
[PROOFSTEP]
simp
[GOAL]
case h₂
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : CommMonoid β
S : Finset α
g1 g2 : α → β
h✝ : ∀ (a : α), a ∈ S → g1 a ∣ g2 a
a : α
T : Finset α
_haS : a ∈ S
_hTS : T ⊆ S
haT : ¬a ∈ T
IH : (∀ (a : α), a ∈ T → g1 a ∣ g2 a) → Finset.prod T g1 ∣ Finset.prod T g2
h : ∀ (a_1 : α), a_1 ∈ insert a T → g1 a_1 ∣ g2 a_1
⊢ Finset.prod (insert a T) g1 ∣ Finset.prod (insert a T) g2
[PROOFSTEP]
rw [Finset.prod_insert haT, Finset.prod_insert haT]
[GOAL]
case h₂
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : CommMonoid β
S : Finset α
g1 g2 : α → β
h✝ : ∀ (a : α), a ∈ S → g1 a ∣ g2 a
a : α
T : Finset α
_haS : a ∈ S
_hTS : T ⊆ S
haT : ¬a ∈ T
IH : (∀ (a : α), a ∈ T → g1 a ∣ g2 a) → Finset.prod T g1 ∣ Finset.prod T g2
h : ∀ (a_1 : α), a_1 ∈ insert a T → g1 a_1 ∣ g2 a_1
⊢ g1 a * ∏ x in T, g1 x ∣ g2 a * ∏ x in T, g2 x
[PROOFSTEP]
exact mul_dvd_mul (h a $ T.mem_insert_self a) (IH fun b hb ↦ h b $ Finset.mem_insert_of_mem hb)
[GOAL]
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝¹ : CommMonoid β
ι : Type u_2
M : Type u_3
inst✝ : CommMonoid M
s t : Finset ι
f : ι → M
h : s ⊆ t
⊢ s.val ≤ t.val
[PROOFSTEP]
simpa
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∏ i in s, g i + ∏ i in s, h i = ∏ i in s, f i
[PROOFSTEP]
classical
simp_rw [prod_eq_mul_prod_diff_singleton hi, ← h1, right_distrib]
congr 2 <;> apply prod_congr rfl <;> simpa
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∏ i in s, g i + ∏ i in s, h i = ∏ i in s, f i
[PROOFSTEP]
simp_rw [prod_eq_mul_prod_diff_singleton hi, ← h1, right_distrib]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ g i * ∏ i in s \ {i}, g i + h i * ∏ i in s \ {i}, h i = g i * ∏ i in s \ {i}, f i + h i * ∏ i in s \ {i}, f i
[PROOFSTEP]
congr 2
[GOAL]
case e_a.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∏ i in s \ {i}, g i = ∏ i in s \ {i}, f i
[PROOFSTEP]
apply prod_congr rfl
[GOAL]
case e_a.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∏ i in s \ {i}, h i = ∏ i in s \ {i}, f i
[PROOFSTEP]
apply prod_congr rfl
[GOAL]
case e_a.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∀ (x : α), x ∈ s \ {i} → g x = f x
[PROOFSTEP]
simpa
[GOAL]
case e_a.e_a
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g✝ : α → β
inst✝ : CommSemiring β
s : Finset α
i : α
f g h : α → β
hi : i ∈ s
h1 : g i + h i = f i
h2 : ∀ (j : α), j ∈ s → j ≠ i → g j = f j
h3 : ∀ (j : α), j ∈ s → j ≠ i → h j = f j
⊢ ∀ (x : α), x ∈ s \ {i} → h x = f x
[PROOFSTEP]
simpa
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
s : Finset α
⊢ card s = ∑ x in s, 1
[PROOFSTEP]
rw [sum_const, smul_eq_mul, mul_one]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
m : ℕ
f : α → ℕ
h₁ : ∀ (x : α), x ∈ s → f x = m
⊢ ∑ x in s, f x = card s * m
[PROOFSTEP]
rw [← Nat.nsmul_eq_mul, ← sum_const]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
m : ℕ
f : α → ℕ
h₁ : ∀ (x : α), x ∈ s → f x = m
⊢ ∑ x in s, f x = ∑ _x in s, m
[PROOFSTEP]
apply sum_congr rfl h₁
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
s : Finset α
p : α → Prop
inst✝ : NonAssocSemiring β
hp : DecidablePred p
⊢ (∑ x in s, if p x then 1 else 0) = ↑(card (filter p s))
[PROOFSTEP]
simp only [add_zero, mul_one, Finset.sum_const, nsmul_eq_mul, eq_self_iff_true, Finset.sum_const_zero, Finset.sum_ite,
  mul_zero]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : NonUnitalNonAssocSemiring β
s : Finset α
f : α → β
b✝ : β
h : ∀ (i : α), i ∈ s → Commute b✝ (f i)
b : β
hb : b ∈ Multiset.map (fun i => f i) s.val
⊢ Commute b✝ b
[PROOFSTEP]
obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hb
[GOAL]
case intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : NonUnitalNonAssocSemiring β
s : Finset α
f : α → β
b : β
h : ∀ (i : α), i ∈ s → Commute b (f i)
i : α
hi : i ∈ s.val
hb : f i ∈ Multiset.map (fun i => f i) s.val
⊢ Commute b (f i)
[PROOFSTEP]
exact h _ hi
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommGroup β
inst✝ : DecidableEq α
h : s₁ ⊆ s₂
⊢ ∏ x in s₂ \ s₁, f x = (∏ x in s₂, f x) / ∏ x in s₁, f x
[PROOFSTEP]
rw [eq_div_iff_mul_eq', prod_sdiff h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommGroup β
inst✝ : DecidableEq α
⊢ (∏ x in s₂ \ s₁, f x) / ∏ x in s₁ \ s₂, f x = (∏ x in s₂, f x) / ∏ x in s₁, f x
[PROOFSTEP]
simp [← Finset.prod_sdiff (@inf_le_left _ _ s₁ s₂), ← Finset.prod_sdiff (@inf_le_right _ _ s₁ s₂)]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝¹ : CommGroup β
inst✝ : DecidableEq α
a : α
h : a ∈ s
⊢ ∏ x in erase s a, f x = (∏ x in s, f x) / f a
[PROOFSTEP]
rw [eq_div_iff_mul_eq', prod_erase_mul _ _ h]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq β
s : Finset α
t : α → Finset β
h : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x ≠ y → Disjoint (t x) (t y)
⊢ ∑ a in s, ∑ _i in t a, 1 = ∑ u in s, card (t u)
[PROOFSTEP]
simp_rw [card_eq_sum_ones]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq β
s : Finset α
t : α → Finset β
this : DecidableEq α
⊢ card (Finset.biUnion ∅ t) ≤ ∑ a in ∅, card (t a)
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : DecidableEq β
s✝ : Finset α
t : α → Finset β
this : DecidableEq α
a : α
s : Finset α
has : ¬a ∈ s
ih : card (Finset.biUnion s t) ≤ ∑ a in s, card (t a)
⊢ card (Finset.biUnion (insert a s) t) ≤ card (t a) + card (Finset.biUnion s t)
[PROOFSTEP]
{rw [biUnion_insert]; exact Finset.card_union_le _ _
}
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : DecidableEq β
s✝ : Finset α
t : α → Finset β
this : DecidableEq α
a : α
s : Finset α
has : ¬a ∈ s
ih : card (Finset.biUnion s t) ≤ ∑ a in s, card (t a)
⊢ card (Finset.biUnion (insert a s) t) ≤ card (t a) + card (Finset.biUnion s t)
[PROOFSTEP]
rw [biUnion_insert]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : DecidableEq β
s✝ : Finset α
t : α → Finset β
this : DecidableEq α
a : α
s : Finset α
has : ¬a ∈ s
ih : card (Finset.biUnion s t) ≤ ∑ a in s, card (t a)
⊢ card (t a ∪ Finset.biUnion s t) ≤ card (t a) + card (Finset.biUnion s t)
[PROOFSTEP]
exact Finset.card_union_le _ _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : DecidableEq β
s✝ : Finset α
t : α → Finset β
this : DecidableEq α
a : α
s : Finset α
has : ¬a ∈ s
ih : card (Finset.biUnion s t) ≤ ∑ a in s, card (t a)
⊢ card (t a) + card (Finset.biUnion s t) ≤ ∑ a in insert a s, card (t a)
[PROOFSTEP]
rw [sum_insert has]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝¹ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝ : DecidableEq β
s✝ : Finset α
t : α → Finset β
this : DecidableEq α
a : α
s : Finset α
has : ¬a ∈ s
ih : card (Finset.biUnion s t) ≤ ∑ a in s, card (t a)
⊢ card (t a) + card (Finset.biUnion s t) ≤ card (t a) + ∑ x in s, card (t x)
[PROOFSTEP]
exact add_le_add_left ih _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : DecidableEq β
f : α → β
s : Finset α
t : Finset β
H : ∀ (x : α), x ∈ s → f x ∈ t
⊢ card s = ∑ a in t, card (filter (fun x => f x = a) s)
[PROOFSTEP]
simp only [card_eq_sum_ones, sum_fiberwise_of_maps_to H]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
f : α → Multiset β
s : Finset α
b : β
⊢ b ∈ ∑ x in s, f x ↔ ∃ a, a ∈ s ∧ b ∈ f a
[PROOFSTEP]
classical
refine' s.induction_on (by simp) _
· intro a t hi ih
  simp [sum_insert hi, ih, or_and_right, exists_or]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
f : α → Multiset β
s : Finset α
b : β
⊢ b ∈ ∑ x in s, f x ↔ ∃ a, a ∈ s ∧ b ∈ f a
[PROOFSTEP]
refine' s.induction_on (by simp) _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
f : α → Multiset β
s : Finset α
b : β
⊢ b ∈ ∑ x in ∅, f x ↔ ∃ a, a ∈ ∅ ∧ b ∈ f a
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
f : α → Multiset β
s : Finset α
b : β
⊢ ∀ ⦃a : α⦄ {s : Finset α},
    ¬a ∈ s →
      (b ∈ ∑ x in s, f x ↔ ∃ a, a ∈ s ∧ b ∈ f a) → (b ∈ ∑ x in insert a s, f x ↔ ∃ a_3, a_3 ∈ insert a s ∧ b ∈ f a_3)
[PROOFSTEP]
intro a t hi ih
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
f : α → Multiset β
s : Finset α
b : β
a : α
t : Finset α
hi : ¬a ∈ t
ih : b ∈ ∑ x in t, f x ↔ ∃ a, a ∈ t ∧ b ∈ f a
⊢ b ∈ ∑ x in insert a t, f x ↔ ∃ a_1, a_1 ∈ insert a t ∧ b ∈ f a_1
[PROOFSTEP]
simp [sum_insert hi, ih, or_and_right, exists_or]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoidWithZero β
ha : a ∈ s
h : f a = 0
⊢ ∏ x in s, f x = 0
[PROOFSTEP]
haveI := Classical.decEq α
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoidWithZero β
ha : a ∈ s
h : f a = 0
this : DecidableEq α
⊢ ∏ x in s, f x = 0
[PROOFSTEP]
rw [← prod_erase_mul _ _ ha, h, mul_zero]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
⊢ (∏ i in s, if p i then 1 else 0) = if ∀ (i : α), i ∈ s → p i then 1 else 0
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
h : ∀ (i : α), i ∈ s → p i
⊢ (∏ i in s, if p i then 1 else 0) = 1
[PROOFSTEP]
apply prod_eq_one
[GOAL]
case pos.h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
h : ∀ (i : α), i ∈ s → p i
⊢ ∀ (x : α), x ∈ s → (if p x then 1 else 0) = 1
[PROOFSTEP]
intro i hi
[GOAL]
case pos.h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
h : ∀ (i : α), i ∈ s → p i
i : α
hi : i ∈ s
⊢ (if p i then 1 else 0) = 1
[PROOFSTEP]
rw [if_pos (h i hi)]
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
h : ¬∀ (i : α), i ∈ s → p i
⊢ (∏ i in s, if p i then 1 else 0) = 0
[PROOFSTEP]
push_neg at h 
[GOAL]
case neg
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
h : ∃ i, i ∈ s ∧ ¬p i
⊢ (∏ i in s, if p i then 1 else 0) = 0
[PROOFSTEP]
rcases h with ⟨i, hi, hq⟩
[GOAL]
case neg.intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
i : α
hi : i ∈ s
hq : ¬p i
⊢ (∏ i in s, if p i then 1 else 0) = 0
[PROOFSTEP]
apply prod_eq_zero hi
[GOAL]
case neg.intro.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : CommMonoidWithZero β
s : Finset α
p : α → Prop
inst✝ : DecidablePred p
i : α
hi : i ∈ s
hq : ¬p i
⊢ (if p i then 1 else 0) = 0
[PROOFSTEP]
rw [if_neg hq]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ ∏ x in s, f x = 0 ↔ ∃ a, a ∈ s ∧ f a = 0
[PROOFSTEP]
classical
induction' s using Finset.induction_on with a s ha ih
· exact ⟨Not.elim one_ne_zero, fun ⟨_, H, _⟩ => by simp at H ⟩
· rw [prod_insert ha, mul_eq_zero, exists_mem_insert, ih, ← bex_def]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ ∏ x in s, f x = 0 ↔ ∃ a, a ∈ s ∧ f a = 0
[PROOFSTEP]
induction' s using Finset.induction_on with a s ha ih
[GOAL]
case empty
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ ∏ x in ∅, f x = 0 ↔ ∃ a, a ∈ ∅ ∧ f a = 0
[PROOFSTEP]
exact ⟨Not.elim one_ne_zero, fun ⟨_, H, _⟩ => by simp at H ⟩
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
x✝ : ∃ a, a ∈ ∅ ∧ f a = 0
w✝ : α
H : w✝ ∈ ∅
right✝ : f w✝ = 0
⊢ ∏ x in ∅, f x = 0
[PROOFSTEP]
simp at H 
[GOAL]
case insert
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
a : α
s : Finset α
ha : ¬a ∈ s
ih : ∏ x in s, f x = 0 ↔ ∃ a, a ∈ s ∧ f a = 0
⊢ ∏ x in insert a s, f x = 0 ↔ ∃ a_1, a_1 ∈ insert a s ∧ f a_1 = 0
[PROOFSTEP]
rw [prod_insert ha, mul_eq_zero, exists_mem_insert, ih, ← bex_def]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ ∏ x in s, f x ≠ 0 ↔ ∀ (a : α), a ∈ s → f a ≠ 0
[PROOFSTEP]
rw [Ne, prod_eq_zero_iff]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ (¬∃ a, a ∈ s ∧ f a = 0) ↔ ∀ (a : α), a ∈ s → f a ≠ 0
[PROOFSTEP]
push_neg
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝² : CommMonoidWithZero β
inst✝¹ : Nontrivial β
inst✝ : NoZeroDivisors β
⊢ (∀ (a : α), a ∈ s → f a ≠ 0) ↔ ∀ (a : α), a ∈ s → f a ≠ 0
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝¹ : CommMonoid β
inst✝ : Unique α
s : Finset α
f : α → β
h : Finset.Nonempty s
⊢ ∏ x in s, f x = f default
[PROOFSTEP]
rw [h.eq_singleton_default, Finset.prod_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℕ
f : α → ℕ
⊢ Multiset.sum (Multiset.map (fun x => x % n) (Multiset.map (fun i => f i) s.val)) % n = (∑ i in s, f i % n) % n
[PROOFSTEP]
rw [Finset.sum, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℕ
f : α → ℕ
⊢ Multiset.sum (Multiset.map ((fun x => x % n) ∘ fun i => f i) s.val) % n =
    Multiset.sum (Multiset.map (fun i => f i % n) s.val) % n
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℕ
f : α → ℕ
⊢ Multiset.prod (Multiset.map (fun x => x % n) (Multiset.map (fun i => f i) s.val)) % n = (∏ i in s, f i % n) % n
[PROOFSTEP]
rw [Finset.prod, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℕ
f : α → ℕ
⊢ Multiset.prod (Multiset.map ((fun x => x % n) ∘ fun i => f i) s.val) % n =
    Multiset.prod (Multiset.map (fun i => f i % n) s.val) % n
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℤ
f : α → ℤ
⊢ Multiset.sum (Multiset.map (fun x => x % n) (Multiset.map (fun i => f i) s.val)) % n = (∑ i in s, f i % n) % n
[PROOFSTEP]
rw [Finset.sum, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℤ
f : α → ℤ
⊢ Multiset.sum (Multiset.map ((fun x => x % n) ∘ fun i => f i) s.val) % n =
    Multiset.sum (Multiset.map (fun i => f i % n) s.val) % n
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℤ
f : α → ℤ
⊢ Multiset.prod (Multiset.map (fun x => x % n) (Multiset.map (fun i => f i) s.val)) % n = (∏ i in s, f i % n) % n
[PROOFSTEP]
rw [Finset.prod, Multiset.map_map]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
s : Finset α
n : ℤ
f : α → ℤ
⊢ Multiset.prod (Multiset.map ((fun x => x % n) ∘ fun i => f i) s.val) % n =
    Multiset.prod (Multiset.map (fun i => f i % n) s.val) % n
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : CommMonoid β
inst✝¹ : Unique α
inst✝ : Fintype α
f : α → β
⊢ ∏ x : α, f x = f default
[PROOFSTEP]
rw [univ_unique, prod_singleton]
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a✝ : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : CommMonoid β
inst✝¹ : Subsingleton α
inst✝ : Fintype α
f : α → β
a : α
⊢ ∏ x : α, f x = f a
[PROOFSTEP]
haveI : Unique α := uniqueOfSubsingleton a
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a✝ : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : CommMonoid β
inst✝¹ : Subsingleton α
inst✝ : Fintype α
f : α → β
a : α
this : Unique α
⊢ ∏ x : α, f x = f a
[PROOFSTEP]
rw [prod_unique f, Subsingleton.elim default a]
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
⊢ (∏ i : { x // p x }, f ↑i) * ∏ i : { x // ¬p x }, f ↑i = ∏ i : α, f i
[PROOFSTEP]
classical
let s := {x | p x}.toFinset
rw [← Finset.prod_subtype s, ← Finset.prod_subtype sᶜ]
· exact Finset.prod_mul_prod_compl _ _
· simp
· simp
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
⊢ (∏ i : { x // p x }, f ↑i) * ∏ i : { x // ¬p x }, f ↑i = ∏ i : α, f i
[PROOFSTEP]
let s := {x | p x}.toFinset
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
s : Finset α := Set.toFinset {x | p x}
⊢ (∏ i : { x // p x }, f ↑i) * ∏ i : { x // ¬p x }, f ↑i = ∏ i : α, f i
[PROOFSTEP]
rw [← Finset.prod_subtype s, ← Finset.prod_subtype sᶜ]
[GOAL]
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
s : Finset α := Set.toFinset {x | p x}
⊢ (∏ a in s, f a) * ∏ a in sᶜ, f a = ∏ i : α, f i
[PROOFSTEP]
exact Finset.prod_mul_prod_compl _ _
[GOAL]
case h
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
s : Finset α := Set.toFinset {x | p x}
⊢ ∀ (x : α), x ∈ sᶜ ↔ ¬p x
[PROOFSTEP]
simp
[GOAL]
case h
ι : Type u_1
β✝ : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β✝
α : Type u_2
β : Type u_3
inst✝² : Fintype α
inst✝¹ : CommMonoid β
p : α → Prop
f : α → β
inst✝ : DecidablePred p
s : Finset α := Set.toFinset {x | p x}
⊢ ∀ (x : α), x ∈ s ↔ p x
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
M : Type u_2
inst✝¹ : DecidableEq α
inst✝ : CommMonoid M
f : α → M
x✝ : Nodup []
⊢ Finset.prod (toFinset []) f = prod (map f [])
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
M : Type u_2
inst✝¹ : DecidableEq α
inst✝ : CommMonoid M
f : α → M
a : α
l : List α
hl : Nodup (a :: l)
⊢ Finset.prod (toFinset (a :: l)) f = prod (map f (a :: l))
[PROOFSTEP]
let ⟨not_mem, hl⟩ := List.nodup_cons.mp hl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
M : Type u_2
inst✝¹ : DecidableEq α
inst✝ : CommMonoid M
f : α → M
a : α
l : List α
hl✝ : Nodup (a :: l)
not_mem : ¬a ∈ l
hl : Nodup l
⊢ Finset.prod (toFinset (a :: l)) f = prod (map f (a :: l))
[PROOFSTEP]
simp [Finset.prod_insert (mt List.mem_toFinset.mp not_mem), prod_toFinset _ hl]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
l : List (Multiset α)
⊢ Disjoint (List.sum l) a ↔ ∀ (b : Multiset α), b ∈ l → Disjoint b a
[PROOFSTEP]
induction' l with b bs ih
[GOAL]
case nil
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
⊢ Disjoint (List.sum []) a ↔ ∀ (b : Multiset α), b ∈ [] → Disjoint b a
[PROOFSTEP]
simp only [zero_disjoint, List.not_mem_nil, IsEmpty.forall_iff, forall_const, List.sum_nil]
[GOAL]
case cons
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a b : Multiset α
bs : List (Multiset α)
ih : Disjoint (List.sum bs) a ↔ ∀ (b : Multiset α), b ∈ bs → Disjoint b a
⊢ Disjoint (List.sum (b :: bs)) a ↔ ∀ (b_1 : Multiset α), b_1 ∈ b :: bs → Disjoint b_1 a
[PROOFSTEP]
simp_rw [List.sum_cons, disjoint_add_left, List.mem_cons, forall_eq_or_imp]
[GOAL]
case cons
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a b : Multiset α
bs : List (Multiset α)
ih : Disjoint (List.sum bs) a ↔ ∀ (b : Multiset α), b ∈ bs → Disjoint b a
⊢ Disjoint b a ∧ Disjoint (List.sum bs) a ↔ Disjoint b a ∧ ∀ (a_1 : Multiset α), a_1 ∈ bs → Disjoint a_1 a
[PROOFSTEP]
simp [and_congr_left_iff, iff_self_iff, ih]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
l : List (Multiset α)
⊢ Disjoint a (List.sum l) ↔ ∀ (b : Multiset α), b ∈ l → Disjoint a b
[PROOFSTEP]
simpa only [@disjoint_comm _ a] using disjoint_list_sum_left
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
i : Multiset (Multiset α)
l : List (Multiset α)
⊢ Disjoint (sum (Quotient.mk (List.isSetoid (Multiset α)) l)) a ↔
    ∀ (b : Multiset α), b ∈ Quotient.mk (List.isSetoid (Multiset α)) l → Disjoint b a
[PROOFSTEP]
rw [quot_mk_to_coe, Multiset.coe_sum]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
i : Multiset (Multiset α)
l : List (Multiset α)
⊢ Disjoint (List.sum l) a ↔ ∀ (b : Multiset α), b ∈ ↑l → Disjoint b a
[PROOFSTEP]
exact disjoint_list_sum_left
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f g : α → β
a : Multiset α
i : Multiset (Multiset α)
⊢ Disjoint a (sum i) ↔ ∀ (b : Multiset α), b ∈ i → Disjoint a b
[PROOFSTEP]
simpa only [@disjoint_comm _ a] using disjoint_sum_left
[GOAL]
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β✝
β : Type u_2
i : Finset β
f : β → Multiset α
a : Multiset α
⊢ Disjoint (Finset.sum i f) a ↔ ∀ (b : β), b ∈ i → Disjoint (f b) a
[PROOFSTEP]
convert @disjoint_sum_left _ a (map f i.val)
[GOAL]
case h.e'_2.a
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β✝
β : Type u_2
i : Finset β
f : β → Multiset α
a : Multiset α
⊢ (∀ (b : β), b ∈ i → Disjoint (f b) a) ↔ ∀ (b : Multiset α), b ∈ map f i.val → Disjoint b a
[PROOFSTEP]
simp [and_congr_left_iff, iff_self_iff]
[GOAL]
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β✝
β : Type u_2
i : Finset β
f : β → Multiset α
a : Multiset α
⊢ Disjoint a (Finset.sum i f) ↔ ∀ (b : β), b ∈ i → Disjoint a (f b)
[PROOFSTEP]
simpa only [disjoint_comm] using disjoint_finset_sum_left
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
⊢ z + x = z ∪ y ↔ Disjoint z x ∧ x = y
[PROOFSTEP]
rw [← add_eq_union_iff_disjoint]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
⊢ z + x = z ∪ y ↔ z + x = z ∪ x ∧ x = y
[PROOFSTEP]
constructor
[GOAL]
case mp
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
⊢ z + x = z ∪ y → z + x = z ∪ x ∧ x = y
[PROOFSTEP]
intro h0
[GOAL]
case mp
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
h0 : z + x = z ∪ y
⊢ z + x = z ∪ x ∧ x = y
[PROOFSTEP]
rw [and_iff_right_of_imp]
[GOAL]
case mp
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
h0 : z + x = z ∪ y
⊢ x = y
[PROOFSTEP]
exact (le_of_add_le_add_left <| h0.trans_le <| union_le_add z y).antisymm h
[GOAL]
case mp
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
h0 : z + x = z ∪ y
⊢ x = y → z + x = z ∪ x
[PROOFSTEP]
rintro rfl
[GOAL]
case mp
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x z : Multiset α
h : x ≤ x
h0 : z + x = z ∪ x
⊢ z + x = z ∪ x
[PROOFSTEP]
exact h0
[GOAL]
case mpr
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : y ≤ x
⊢ z + x = z ∪ x ∧ x = y → z + x = z ∪ y
[PROOFSTEP]
rintro ⟨h0, rfl⟩
[GOAL]
case mpr.intro
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x z : Multiset α
h0 : z + x = z ∪ x
h : x ≤ x
⊢ z + x = z ∪ x
[PROOFSTEP]
exact h0
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
x y z : Multiset α
h : z ≤ y
⊢ x + y = x ∪ z ↔ y = z ∧ Disjoint x y
[PROOFSTEP]
simpa only [and_comm] using add_eq_union_left_of_le h
[GOAL]
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
i : Finset β
f : β → Multiset α
⊢ Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
[PROOFSTEP]
induction' i using Finset.cons_induction_on with z i hz hr
[GOAL]
case h₁
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
⊢ Finset.sum ∅ f = Finset.sup ∅ f ↔ ∀ (x : β), x ∈ ∅ → ∀ (y : β), y ∈ ∅ → x ≠ y → Disjoint (f x) (f y)
[PROOFSTEP]
simp only [Finset.not_mem_empty, IsEmpty.forall_iff, imp_true_iff, Finset.sum_empty, Finset.sup_empty, bot_eq_zero,
  eq_self_iff_true]
[GOAL]
case h₂
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
z : β
i : Finset β
hz : ¬z ∈ i
hr : Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
⊢ Finset.sum (Finset.cons z i hz) f = Finset.sup (Finset.cons z i hz) f ↔
    ∀ (x : β), x ∈ Finset.cons z i hz → ∀ (y : β), y ∈ Finset.cons z i hz → x ≠ y → Disjoint (f x) (f y)
[PROOFSTEP]
simp_rw [Finset.sum_cons hz, Finset.sup_cons, Finset.mem_cons, Multiset.sup_eq_union, forall_eq_or_imp, Ne.def,
  IsEmpty.forall_iff, true_and_iff, imp_and, forall_and, ← hr, @eq_comm _ z]
[GOAL]
case h₂
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
z : β
i : Finset β
hz : ¬z ∈ i
hr : Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
⊢ f z + ∑ x in i, f x = f z ∪ Finset.sup i f ↔
    (∀ (a : β), a ∈ i → ¬a = z → Disjoint (f z) (f a)) ∧
      (∀ (x : β), x ∈ i → ¬x = z → Disjoint (f x) (f z)) ∧ Finset.sum i f = Finset.sup i f
[PROOFSTEP]
have := fun x (H : x ∈ i) => ne_of_mem_of_not_mem H hz
[GOAL]
case h₂
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
z : β
i : Finset β
hz : ¬z ∈ i
hr : Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
this : ∀ (x : β), x ∈ i → x ≠ z
⊢ f z + ∑ x in i, f x = f z ∪ Finset.sup i f ↔
    (∀ (a : β), a ∈ i → ¬a = z → Disjoint (f z) (f a)) ∧
      (∀ (x : β), x ∈ i → ¬x = z → Disjoint (f x) (f z)) ∧ Finset.sum i f = Finset.sup i f
[PROOFSTEP]
simp (config := { contextual := true }) only [this, not_false_iff, true_imp_iff]
[GOAL]
case h₂
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
z : β
i : Finset β
hz : ¬z ∈ i
hr : Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
this : ∀ (x : β), x ∈ i → x ≠ z
⊢ f z + ∑ x in i, f x = f z ∪ Finset.sup i f ↔
    (∀ (a : β), a ∈ i → Disjoint (f z) (f a)) ∧
      (∀ (x : β), x ∈ i → Disjoint (f x) (f z)) ∧ Finset.sum i f = Finset.sup i f
[PROOFSTEP]
simp_rw [← disjoint_finset_sum_left, ← disjoint_finset_sum_right, disjoint_comm, ← and_assoc, and_self_iff]
[GOAL]
case h₂
ι : Type u_1
β✝ : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β✝
inst✝ : DecidableEq α
β : Type u_2
f : β → Multiset α
z : β
i : Finset β
hz : ¬z ∈ i
hr : Finset.sum i f = Finset.sup i f ↔ ∀ (x : β), x ∈ i → ∀ (y : β), y ∈ i → x ≠ y → Disjoint (f x) (f y)
this : ∀ (x : β), x ∈ i → x ≠ z
⊢ f z + ∑ x in i, f x = f z ∪ Finset.sup i f ↔ Disjoint (f z) (∑ x in i, f x) ∧ Finset.sum i f = Finset.sup i f
[PROOFSTEP]
exact add_eq_union_left_of_le (Finset.sup_le fun x hx => le_sum_of_mem (mem_map_of_mem f hx))
[GOAL]
ι : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
inst✝ : DecidableEq α
x : Multiset α
⊢ (Finset.sup (Finset.range (↑card x + 1)) fun k => powersetLen k x) = powerset x
[PROOFSTEP]
convert bind_powerset_len x using 1
[GOAL]
case h.e'_2
ι : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
inst✝ : DecidableEq α
x : Multiset α
⊢ (Finset.sup (Finset.range (↑card x + 1)) fun k => powersetLen k x) =
    bind (range (↑card x + 1)) fun k => powersetLen k x
[PROOFSTEP]
rw [Multiset.bind, Multiset.join, ← Finset.range_val, ← Finset.sum_eq_multiset_sum]
[GOAL]
case h.e'_2
ι : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
inst✝ : DecidableEq α
x : Multiset α
⊢ (Finset.sup (Finset.range (↑card x + 1)) fun k => powersetLen k x) =
    ∑ x_1 in Finset.range (↑card x + 1), powersetLen x_1 x
[PROOFSTEP]
exact Eq.symm (finset_sum_eq_sup_iff_disjoint.mpr fun _ _ _ _ h => pairwise_disjoint_powersetLen x h)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
⊢ ∑ a in toFinset s, count a s = ∑ a in toFinset s, count a s • 1
[PROOFSTEP]
{simp only [smul_eq_mul, mul_one]
}
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
⊢ ∑ a in toFinset s, count a s = ∑ a in toFinset s, count a s • 1
[PROOFSTEP]
simp only [smul_eq_mul, mul_one]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
⊢ sum (map (fun x => 1) s) = ↑card s
[PROOFSTEP]
simp
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : DecidableEq α
s : Finset β
a : α
f : β → Multiset α
⊢ count a (∑ x in s, f x) = ∑ x in s, count a (f x)
[PROOFSTEP]
dsimp only [Finset.sum]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a✝ : α
f✝ g : α → β
inst✝ : DecidableEq α
s : Finset β
a : α
f : β → Multiset α
⊢ count a (sum (map (fun x => f x) s.val)) = sum (map (fun x => count a (f x)) s.val)
[PROOFSTEP]
rw [count_sum]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
⊢ ∑ a in toFinset s, count a s • {a} = s
[PROOFSTEP]
rw [← Finset.sum_multiset_map_count, Multiset.sum_map_singleton]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
⊢ ∃ u, s = k • u
[PROOFSTEP]
use∑ a in s.toFinset, (s.count a / k) • { a }
[GOAL]
case h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
⊢ s = k • ∑ a in toFinset s, (count a s / k) • {a}
[PROOFSTEP]
have h₂ :
  (∑ x : α in s.toFinset, k • (count x s / k) • ({ x } : Multiset α)) = ∑ x : α in s.toFinset, count x s • { x } :=
  by
  apply Finset.sum_congr rfl
  intro x hx
  rw [← mul_nsmul', Nat.mul_div_cancel' (h x (mem_toFinset.mp hx))]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
⊢ ∑ x in toFinset s, k • (count x s / k) • {x} = ∑ x in toFinset s, count x s • {x}
[PROOFSTEP]
apply Finset.sum_congr rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
⊢ ∀ (x : α), x ∈ toFinset s → k • (count x s / k) • {x} = count x s • {x}
[PROOFSTEP]
intro x hx
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
x : α
hx : x ∈ toFinset s
⊢ k • (count x s / k) • {x} = count x s • {x}
[PROOFSTEP]
rw [← mul_nsmul', Nat.mul_div_cancel' (h x (mem_toFinset.mp hx))]
[GOAL]
case h
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : DecidableEq α
s : Multiset α
k : ℕ
h : ∀ (a : α), a ∈ s → k ∣ count a s
h₂ : ∑ x in toFinset s, k • (count x s / k) • {x} = ∑ x in toFinset s, count x s • {x}
⊢ s = k • ∑ a in toFinset s, (count a s / k) • {a}
[PROOFSTEP]
rw [← Finset.sum_nsmul, h₂, toFinset_sum_count_nsmul_eq]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
S : Multiset α
⊢ Finset.prod (toFinset S) id ∣ prod S
[PROOFSTEP]
rw [Finset.prod_eq_multiset_prod]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
S : Multiset α
⊢ prod (map (fun x => id x) (toFinset S).val) ∣ prod S
[PROOFSTEP]
refine' Multiset.prod_dvd_prod_of_le _
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f g : α → β
inst✝¹ : DecidableEq α
inst✝ : CommMonoid α
S : Multiset α
⊢ map (fun x => id x) (toFinset S).val ≤ S
[PROOFSTEP]
simp [Multiset.dedup_le S]
[GOAL]
ι✝ : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
ι : Type u_3
inst✝ : CommMonoid α
f : ι → Multiset α
s : Finset ι
⊢ prod (∑ x in s, f x) = ∏ x in s, prod (f x)
[PROOFSTEP]
classical
induction' s using Finset.induction_on with a t hat ih
· rw [Finset.sum_empty, Finset.prod_empty, Multiset.prod_zero]
· rw [Finset.sum_insert hat, Finset.prod_insert hat, Multiset.prod_add, ih]
[GOAL]
ι✝ : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s✝ s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
ι : Type u_3
inst✝ : CommMonoid α
f : ι → Multiset α
s : Finset ι
⊢ prod (∑ x in s, f x) = ∏ x in s, prod (f x)
[PROOFSTEP]
induction' s using Finset.induction_on with a t hat ih
[GOAL]
case empty
ι✝ : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a : α✝
f✝ g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
ι : Type u_3
inst✝ : CommMonoid α
f : ι → Multiset α
⊢ prod (∑ x in ∅, f x) = ∏ x in ∅, prod (f x)
[PROOFSTEP]
rw [Finset.sum_empty, Finset.prod_empty, Multiset.prod_zero]
[GOAL]
case insert
ι✝ : Type u_1
β : Type u
α✝ : Type v
γ : Type w
s s₁ s₂ : Finset α✝
a✝ : α✝
f✝ g : α✝ → β
inst✝¹ : DecidableEq α✝
α : Type u_2
ι : Type u_3
inst✝ : CommMonoid α
f : ι → Multiset α
a : ι
t : Finset ι
hat : ¬a ∈ t
ih : prod (∑ x in t, f x) = ∏ x in t, prod (f x)
⊢ prod (∑ x in insert a t, f x) = ∏ x in insert a t, prod (f x)
[PROOFSTEP]
rw [Finset.sum_insert hat, Finset.prod_insert hat, Multiset.prod_add, ih]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommGroupWithZero β
s : Finset α
f : α → β
h : ∏ b in s, f b ≠ 0
⊢ mk0 (∏ b in s, f b) h = ∏ b in Finset.attach s, mk0 (f ↑b) (_ : f ↑b = 0 → False)
[PROOFSTEP]
classical induction s using Finset.induction_on <;> simp [*]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommGroupWithZero β
s : Finset α
f : α → β
h : ∏ b in s, f b ≠ 0
⊢ mk0 (∏ b in s, f b) h = ∏ b in Finset.attach s, mk0 (f ↑b) (_ : f ↑b = 0 → False)
[PROOFSTEP]
induction s using Finset.induction_on
[GOAL]
case empty
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommGroupWithZero β
f : α → β
h : ∏ b in ∅, f b ≠ 0
⊢ mk0 (∏ b in ∅, f b) h = ∏ b in Finset.attach ∅, mk0 (f ↑b) (_ : f ↑b = 0 → False)
[PROOFSTEP]
simp [*]
[GOAL]
case insert
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
inst✝ : CommGroupWithZero β
f : α → β
a✝² : α
s✝ : Finset α
a✝¹ : ¬a✝² ∈ s✝
a✝ : ∀ (h : ∏ b in s✝, f b ≠ 0), mk0 (∏ b in s✝, f b) h = ∏ b in Finset.attach s✝, mk0 (f ↑b) (_ : f ↑b = 0 → False)
h : ∏ b in insert a✝² s✝, f b ≠ 0
⊢ mk0 (∏ b in insert a✝² s✝, f b) h = ∏ b in Finset.attach (insert a✝² s✝), mk0 (f ↑b) (_ : f ↑b = 0 → False)
[PROOFSTEP]
simp [*]
[GOAL]
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
ι : Type u_2
s : Finset ι
f : ι → ℤ
⊢ Int.natAbs (∑ i in s, f i) ≤ ∑ i in s, Int.natAbs (f i)
[PROOFSTEP]
classical
induction' s using Finset.induction_on with i s his IH
· simp only [Finset.sum_empty, Int.natAbs_zero]
· simp only [his, Finset.sum_insert, not_false_iff]
  exact (Int.natAbs_add_le _ _).trans (add_le_add le_rfl IH)
[GOAL]
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
ι : Type u_2
s : Finset ι
f : ι → ℤ
⊢ Int.natAbs (∑ i in s, f i) ≤ ∑ i in s, Int.natAbs (f i)
[PROOFSTEP]
induction' s using Finset.induction_on with i s his IH
[GOAL]
case empty
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s s₁ s₂ : Finset α
a : α
f✝ g : α → β
ι : Type u_2
f : ι → ℤ
⊢ Int.natAbs (∑ i in ∅, f i) ≤ ∑ i in ∅, Int.natAbs (f i)
[PROOFSTEP]
simp only [Finset.sum_empty, Int.natAbs_zero]
[GOAL]
case insert
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
ι : Type u_2
f : ι → ℤ
i : ι
s : Finset ι
his : ¬i ∈ s
IH : Int.natAbs (∑ i in s, f i) ≤ ∑ i in s, Int.natAbs (f i)
⊢ Int.natAbs (∑ i in insert i s, f i) ≤ ∑ i in insert i s, Int.natAbs (f i)
[PROOFSTEP]
simp only [his, Finset.sum_insert, not_false_iff]
[GOAL]
case insert
ι✝ : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f✝ g : α → β
ι : Type u_2
f : ι → ℤ
i : ι
s : Finset ι
his : ¬i ∈ s
IH : Int.natAbs (∑ i in s, f i) ≤ ∑ i in s, Int.natAbs (f i)
⊢ Int.natAbs (f i + ∑ i in s, f i) ≤ Int.natAbs (f i) + ∑ i in s, Int.natAbs (f i)
[PROOFSTEP]
exact (Int.natAbs_add_le _ _).trans (add_le_add le_rfl IH)
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : Monoid α
s : List α
⊢ ↑ofMul (List.prod s) = List.sum (List.map (↑ofMul) s)
[PROOFSTEP]
simp [ofMul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : Monoid α
s : List α
⊢ List.prod s = List.sum s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : Monoid α
s : List (Additive α)
⊢ ↑toMul (List.sum s) = List.prod (List.map (↑toMul) s)
[PROOFSTEP]
simp [toMul, ofMul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : Monoid α
s : List (Additive α)
⊢ List.sum s = List.prod s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddMonoid α
s : List α
⊢ ↑ofAdd (List.sum s) = List.prod (List.map (↑ofAdd) s)
[PROOFSTEP]
simp [ofAdd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddMonoid α
s : List α
⊢ List.sum s = List.prod s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddMonoid α
s : List (Multiplicative α)
⊢ ↑toAdd (List.prod s) = List.sum (List.map (↑toAdd) s)
[PROOFSTEP]
simp [toAdd, ofAdd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddMonoid α
s : List (Multiplicative α)
⊢ List.prod s = List.sum s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid α
s : Multiset α
⊢ ↑ofMul (Multiset.prod s) = Multiset.sum (Multiset.map (↑ofMul) s)
[PROOFSTEP]
simp [ofMul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid α
s : Multiset α
⊢ Multiset.prod s = Multiset.sum s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid α
s : Multiset (Additive α)
⊢ ↑toMul (Multiset.sum s) = Multiset.prod (Multiset.map (↑toMul) s)
[PROOFSTEP]
simp [toMul, ofMul]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : CommMonoid α
s : Multiset (Additive α)
⊢ Multiset.sum s = Multiset.prod s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddCommMonoid α
s : Multiset α
⊢ ↑ofAdd (Multiset.sum s) = Multiset.prod (Multiset.map (↑ofAdd) s)
[PROOFSTEP]
simp [ofAdd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddCommMonoid α
s : Multiset α
⊢ Multiset.sum s = Multiset.prod s
[PROOFSTEP]
rfl
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddCommMonoid α
s : Multiset (Multiplicative α)
⊢ ↑toAdd (Multiset.prod s) = Multiset.sum (Multiset.map (↑toAdd) s)
[PROOFSTEP]
simp [toAdd, ofAdd]
[GOAL]
ι : Type u_1
β : Type u
α : Type v
γ : Type w
s✝ s₁ s₂ : Finset α
a : α
f g : α → β
inst✝ : AddCommMonoid α
s : Multiset (Multiplicative α)
⊢ Multiset.prod s = Multiset.sum s
[PROOFSTEP]
rfl
