Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit d77ac51

Browse files
committed
chore(data/fintype/card): review API (#4287)
API changes: * `finset.filter_mem_eq_inter` now takes `[Π i, decidable (i ∈ t)]`; this way it works better with `classical`; * add `finset.mem_compl` and `finset.coe_compl`; * [DRY] drop `finset.prod_range_eq_prod_fin` and `finset.sum_range_eq_sum_fin`: use `fin.prod_univ_eq_prod_range` and `fin.sum_univ_eq_sum_range` instead; * rename `finset.prod_equiv` to `equiv.prod_comp` to enable dot notation; * add `fintype.prod_dite`: a specialized version of `finset.prod_dite`. Also golf a proof in `analysis/normed_space/multilinear`
1 parent 66c87c0 commit d77ac51

File tree

11 files changed

+63
-80
lines changed

11 files changed

+63
-80
lines changed

src/analysis/analytic/composition.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ calc ∥q.comp_along_composition_multilinear p c v∥ = ∥q c.length (p.apply_c
168168
∏ i (j : fin (c.blocks_fun i)), ∥(v ∘ (c.embedding i)) j∥ :
169169
by rw [finset.prod_mul_distrib, mul_assoc]
170170
... = ∥q c.length∥ * (∏ i, ∥p (c.blocks_fun i)∥) * (∏ i : fin n, ∥v i∥) :
171-
by { rw [← finset.prod_equiv c.blocks_fin_equiv, ← finset.univ_sigma_univ, finset.prod_sigma],
171+
by { rw [← c.blocks_fin_equiv.prod_comp, ← finset.univ_sigma_univ, finset.prod_sigma],
172172
congr }
173173

174174
/-- Given two formal multilinear series `q` and `p` and a composition `c` of `n`, one may
@@ -1073,7 +1073,7 @@ begin
10731073
exact A },
10741074
/- Now, we use `composition.sigma_equiv_sigma_pi n` to change
10751075
variables in the second sum, and check that we get exactly the same sums. -/
1076-
rw ← finset.sum_equiv (sigma_equiv_sigma_pi n),
1076+
rw ← (sigma_equiv_sigma_pi n).sum_comp,
10771077
/- To check that we have the same terms, we should check that we apply the same component of
10781078
`r`, and the same component of `q`, and the same component of `p`, to the same coordinate of
10791079
`v`. This is true by definition, but at each step one needs to convince Lean that the types

src/analysis/normed_space/multilinear.lean

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -252,32 +252,14 @@ lemma restr_norm_le {k n : ℕ} (f : (multilinear_map 𝕜 (λ i : fin n, G) E
252252
(s : finset (fin n)) (hk : s.card = k) (z : G) {C : ℝ}
253253
(H : ∀ m, ∥f m∥ ≤ C * ∏ i, ∥m i∥) (v : fin k → G) :
254254
∥f.restr s hk z v∥ ≤ C * ∥z∥ ^ (n - k) * ∏ i, ∥v i∥ :=
255-
calc ∥f.restr s hk z v∥
256-
≤ C * ∏ j, ∥(if h : j ∈ s then v ((s.mono_equiv_of_fin hk).symm ⟨j, h⟩) else z)∥ : H _
257-
... = C * ((∏ j in finset.univ \ s,
258-
∥(if h : j ∈ s then v ((s.mono_equiv_of_fin hk).symm ⟨j, h⟩) else z)∥)
259-
* (∏ j in s,
260-
∥(if h : j ∈ s then v ((s.mono_equiv_of_fin hk).symm ⟨j, h⟩) else z)∥)) :
261-
by rw ← finset.prod_sdiff (finset.subset_univ _)
262-
... = C * (∥z∥ ^ (n - k) * ∏ i, ∥v i∥) :
263-
begin
264-
congr' 2,
265-
{ have : ∥z∥ ^ (n - k) = ∏ j in finset.univ \ s, ∥z∥,
266-
by simp [finset.card_sdiff (finset.subset_univ _), hk],
267-
rw this,
268-
exact finset.prod_congr rfl (λ i hi, by rw dif_neg (finset.mem_sdiff.1 hi).2) },
269-
{ apply finset.prod_bij (λ (i : fin n) (hi : i ∈ s), (s.mono_equiv_of_fin hk).symm ⟨i, hi⟩),
270-
{ exact λ _ _, finset.mem_univ _ },
271-
{ exact λ i hi, by simp [hi] },
272-
{ exact λ i j hi hi hij, subtype.mk.inj ((s.mono_equiv_of_fin hk).symm.injective hij) },
273-
{ assume i hi,
274-
rcases (s.mono_equiv_of_fin hk).symm.surjective i with ⟨j, hj⟩,
275-
refine ⟨j.1, j.2, _⟩,
276-
unfold_coes,
277-
convert hj.symm,
278-
rw subtype.ext_iff_val } }
279-
end
280-
... = C * ∥z∥ ^ (n - k) * ∏ i, ∥v i∥ : by rw mul_assoc
255+
begin
256+
rw mul_assoc,
257+
convert H _ using 2,
258+
simp only [apply_dite norm, fintype.prod_dite, prod_const (∥z∥), finset.card_univ,
259+
fintype.card_of_subtype sᶜ (λ x, mem_compl), card_compl, fintype.card_fin, hk, mk_coe,
260+
(s.mono_equiv_of_fin hk).symm.prod_comp (λ x, ∥v x∥)],
261+
apply mul_comm
262+
end
281263

282264
end multilinear_map
283265

src/data/finset/basic.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,8 @@ theorem filter_union_right (p q : α → Prop) [decidable_pred p] [decidable_pre
965965
s.filter p ∪ s.filter q = s.filter (λx, p x ∨ q x) :=
966966
ext $ λ x, by simp only [mem_filter, mem_union, and_or_distrib_left.symm]
967967

968-
lemma filter_mem_eq_inter {s t : finset α} : s.filter (λ i, i ∈ t) = s ∩ t :=
968+
lemma filter_mem_eq_inter {s t : finset α} [Π i, decidable (i ∈ t)] :
969+
s.filter (λ i, i ∈ t) = s ∩ t :=
969970
ext $ λ i, by rw [mem_filter, mem_inter]
970971

971972
theorem filter_inter {s t : finset α} : filter p s ∩ t = filter p (s ∩ t) :=

src/data/fintype/basic.lean

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ instance [decidable_eq α] : boolean_algebra (finset α) :=
5757

5858
lemma compl_eq_univ_sdiff [decidable_eq α] (s : finset α) : sᶜ = univ \ s := rfl
5959

60+
@[simp] lemma mem_compl [decidable_eq α] {s : finset α} {x : α} : x ∈ sᶜ ↔ x ∉ s :=
61+
by simp [compl_eq_univ_sdiff]
62+
63+
@[simp, norm_cast] lemma coe_compl [decidable_eq α] (s : finset α) : ↑(sᶜ) = (↑s : set α)ᶜ :=
64+
set.ext $ λ x, mem_compl
65+
6066
theorem eq_univ_iff_forall {s : finset α} : s = univ ↔ ∀ x, x ∈ s :=
6167
by simp [ext_iff]
6268

@@ -179,7 +185,7 @@ multiset.card_pmap _ _ _
179185
theorem card_of_subtype {p : α → Prop} (s : finset α)
180186
(H : ∀ x : α, x ∈ s ↔ p x) [fintype {x // p x}] :
181187
card {x // p x} = s.card :=
182-
by rw ← subtype_card s H; congr
188+
by { rw ← subtype_card s H, congr }
183189

184190
/-- Construct a fintype from a finset with the same elements. -/
185191
def of_finset {p : set α} (s : finset α) (H : ∀ x, x ∈ s ↔ x ∈ p) : fintype p :=

src/data/fintype/card.lean

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -157,34 +157,11 @@ by rw [fintype.card_pi, finset.prod_const]; refl
157157
fintype.card (vector α n) = fintype.card α ^ n :=
158158
by rw fintype.of_equiv_card; simp
159159

160-
161160
@[simp, to_additive]
162161
lemma finset.prod_attach_univ [fintype α] [comm_monoid β] (f : {a : α // a ∈ @univ α _} → β) :
163162
∏ x in univ.attach, f x = ∏ x, f ⟨x, (mem_univ _)⟩ :=
164163
prod_bij (λ x _, x.1) (λ _ _, mem_univ _) (λ _ _ , by simp) (by simp) (λ b _, ⟨⟨b, mem_univ _⟩, by simp⟩)
165164

166-
@[to_additive]
167-
lemma finset.prod_range_eq_prod_fin [comm_monoid β] (n : ℕ) (f : ℕ → β) :
168-
∏ k in range n, f k = ∏ k : fin n, f k :=
169-
begin
170-
symmetry,
171-
refine prod_bij (λ k hk, k) _ _ _ _,
172-
{ rintro ⟨k, hk⟩ _, simp * },
173-
{ rintro ⟨k, hk⟩ _, simp * },
174-
{ intros, rwa fin.eq_iff_veq },
175-
{ intros k hk, rw mem_range at hk,
176-
exact ⟨⟨k, hk⟩, mem_univ _, rfl⟩ }
177-
end
178-
179-
@[to_additive]
180-
lemma finset.prod_fin_eq_prod_range [comm_monoid β] {n : ℕ} (c : fin n → β) :
181-
∏ i, c i = ∏ i in finset.range n, if h : i < n then c ⟨i, h⟩ else 1 :=
182-
begin
183-
rw [finset.prod_range_eq_prod_fin, finset.prod_congr rfl],
184-
rintros ⟨i, hi⟩ _,
185-
simp only [fin.coe_eq_val, hi, dif_pos]
186-
end
187-
188165
/-- Taking a product over `univ.pi t` is the same as taking the product over `fintype.pi_finset t`.
189166
`univ.pi t` and `fintype.pi_finset t` are essentially the same `finset`, but differ
190167
in the type of their element, `univ.pi t` is a `finset (Π a ∈ univ, t a)` and
@@ -227,20 +204,8 @@ lemma fin.sum_pow_mul_eq_add_pow {n : ℕ} {R : Type*} [comm_semiring R] (a b :
227204
(a + b) ^ n :=
228205
by simpa using fintype.sum_pow_mul_eq_add_pow (fin n) a b
229206

230-
/-- It is equivalent to sum a function over `fin n` or `finset.range n`. -/
231207
@[to_additive]
232-
lemma fin.prod_univ_eq_prod_range [comm_monoid α] (f : ℕ → α) (n : ℕ) :
233-
∏ i : fin n, f i.val = ∏ i in finset.range n, f i :=
234-
begin
235-
apply finset.prod_bij (λ (a : fin n) ha, a.val),
236-
{ assume a ha, simp [a.is_lt] },
237-
{ assume a ha, refl },
238-
{ assume a b ha hb H, exact (fin.ext_iff _ _).2 H },
239-
{ assume b hb, exact ⟨⟨b, list.mem_range.mp hb⟩, finset.mem_univ _, rfl⟩, }
240-
end
241-
242-
@[to_additive]
243-
lemma finset.prod_equiv [fintype α] [fintype β] [comm_monoid γ] (e : α ≃ β) (f : β → γ) :
208+
lemma equiv.prod_comp [fintype α] [fintype β] [comm_monoid γ] (e : α ≃ β) (f : β → γ) :
244209
∏ i, f (e i) = ∏ i, f i :=
245210
begin
246211
apply prod_bij (λ i hi, e i) (λ i hi, mem_univ _) _ (λ a b _ _ h, e.injective h),
@@ -250,16 +215,33 @@ begin
250215
{ simp }
251216
end
252217

218+
/-- It is equivalent to sum a function over `fin n` or `finset.range n`. -/
219+
@[to_additive]
220+
lemma fin.prod_univ_eq_prod_range [comm_monoid α] (f : ℕ → α) (n : ℕ) :
221+
∏ i : fin n, f i = ∏ i in range n, f i :=
222+
calc (∏ i : fin n, f i) = ∏ i : {x // x ∈ range n}, f i :
223+
((equiv.fin_equiv_subtype n).trans
224+
(equiv.subtype_congr_right (λ _, mem_range.symm))).prod_comp (f ∘ coe)
225+
... = ∏ i in range n, f i : by rw [← attach_eq_univ, prod_attach]
226+
227+
@[to_additive]
228+
lemma finset.prod_fin_eq_prod_range [comm_monoid β] {n : ℕ} (c : fin n → β) :
229+
∏ i, c i = ∏ i in finset.range n, if h : i < n then c ⟨i, h⟩ else 1 :=
230+
begin
231+
rw [← fin.prod_univ_eq_prod_range, finset.prod_congr rfl],
232+
rintros ⟨i, hi⟩ _,
233+
simp only [fin.coe_eq_val, hi, dif_pos]
234+
end
235+
253236
@[to_additive]
254237
lemma finset.prod_subtype {M : Type*} [comm_monoid M]
255238
{p : α → Prop} {F : fintype (subtype p)} {s : finset α} (h : ∀ x, x ∈ s ↔ p x) (f : α → M) :
256239
∏ a in s, f a = ∏ a : subtype p, f a :=
257240
have (∈ s) = p, from set.ext h,
258241
begin
259-
rw ← prod_attach,
242+
rw [← prod_attach, attach_eq_univ],
260243
substI p,
261-
congr,
262-
simp [finset.ext_iff]
244+
congr
263245
end
264246

265247
@[to_additive] lemma finset.prod_fiberwise [decidable_eq β] [fintype β] [comm_monoid γ]
@@ -284,10 +266,22 @@ lemma fintype.prod_fiberwise [fintype α] [decidable_eq β] [fintype β] [comm_m
284266
(f : α → β) (g : α → γ) :
285267
(∏ b : β, ∏ a : {a // f a = b}, g (a : α)) = ∏ a, g a :=
286268
begin
287-
rw [← finset.prod_equiv (equiv.sigma_preimage_equiv f) _, ← univ_sigma_univ, prod_sigma],
269+
rw [← (equiv.sigma_preimage_equiv f).prod_comp, ← univ_sigma_univ, prod_sigma],
288270
refl
289271
end
290272

273+
lemma fintype.prod_dite [fintype α] {p : α → Prop} [decidable_pred p]
274+
[comm_monoid β] (f : Π (a : α) (ha : p a), β) (g : Π (a : α) (ha : ¬p a), β) :
275+
(∏ a, dite (p a) (f a) (g a)) = (∏ a : {a // p a}, f a a.2) * (∏ a : {a // ¬p a}, g a a.2) :=
276+
begin
277+
simp only [prod_dite, attach_eq_univ],
278+
congr' 1,
279+
{ convert (equiv.subtype_congr_right _).prod_comp (λ x : {x // p x}, f x x.2),
280+
simp },
281+
{ convert (equiv.subtype_congr_right _).prod_comp (λ x : {x // ¬p x}, g x x.2),
282+
simp }
283+
end
284+
291285
section
292286
open finset
293287

src/field_theory/chevalley_warning.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ begin
6666
intros x₀,
6767
let e : K ≃ {x // x ∘ coe = x₀} := (equiv.subtype_equiv_codomain _).symm,
6868
calc (∑ x : {x : σ → K // x ∘ coe = x₀}, ∏ j, (x : σ → K) j ^ d j)
69-
= ∑ a : K, ∏ j : σ, (e a : σ → K) j ^ d j : (finset.sum_equiv e _).symm
69+
= ∑ a : K, ∏ j : σ, (e a : σ → K) j ^ d j : (e.sum_comp _).symm
7070
... = ∑ a : K, (∏ j, x₀ j ^ d j) * a ^ d i : fintype.sum_congr _ _ _
7171
... = (∏ j, x₀ j ^ d j) * ∑ a : K, a ^ d i : by rw mul_sum
7272
... = 0 : by rw [sum_pow_lt_card_sub_one _ hi, mul_zero],
@@ -76,7 +76,7 @@ begin
7676
{ default := ⟨i, rfl⟩, uniq := λ ⟨j, h⟩, subtype.val_injective h },
7777
calc (∏ j : σ, (e a : σ → K) j ^ d j)
7878
= (e a : σ → K) i ^ d i * (∏ (j : {j // j ≠ i}), (e a : σ → K) j ^ d j) :
79-
by { rw [← finset.prod_equiv e', fintype.prod_sum_type, univ_unique, prod_singleton], refl }
79+
by { rw [← e'.prod_comp, fintype.prod_sum_type, univ_unique, prod_singleton], refl }
8080
... = a ^ d i * (∏ (j : {j // j ≠ i}), (e a : σ → K) j ^ d j) : by rw equiv.subtype_equiv_codomain_symm_apply_eq
8181
... = a ^ d i * (∏ j, x₀ j ^ d j) : congr_arg _ (fintype.prod_congr _ _ _) -- see below
8282
... = (∏ j, x₀ j ^ d j) * a ^ d i : mul_comm _ _,

src/linear_algebra/determinant.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ calc det (M ⬝ N) = ∑ p : n → n, ∑ σ : perm n, ε σ * ∏ i, (M (σ i)
8989
sum_congr rfl (λ σ _, sum_bij (λ τ _, τ * σ⁻¹) (λ _ _, mem_univ _)
9090
(λ τ _,
9191
have ∏ j, M (τ j) (σ j) = ∏ j, M ((τ * σ⁻¹) j) j,
92-
by rw ← finset.prod_equiv σ⁻¹; simp [mul_apply],
92+
by rw ← σ⁻¹.prod_comp; simp [mul_apply],
9393
have h : ε σ * ε (τ * σ⁻¹) = ε τ :=
9494
calc ε σ * ε (τ * σ⁻¹) = ε ((τ * σ⁻¹) * σ) :
9595
by rw [mul_comm, sign_mul (τ * σ⁻¹)]; simp [sign_mul]

src/linear_algebra/matrix.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ theorem to_lin_of_equiv {p q : Type*} [fintype p] [fintype q] (e₁ : m ≃ p) (
101101
linear_map.ext $ λ v, funext $ λ i,
102102
calc ∑ j : n, f (e₁ i) (e₂ j) * v j
103103
= ∑ j : n, f (e₁ i) (e₂ j) * v (e₂.symm (e₂ j)) : by simp_rw e₂.symm_apply_apply
104-
... = ∑ k : q, f (e₁ i) k * v (e₂.symm k) : finset.sum_equiv e₂ (λ k, f (e₁ i) k * v (e₂.symm k))
104+
... = ∑ k : q, f (e₁ i) k * v (e₂.symm k) : e₂.sum_comp (λ k, f (e₁ i) k * v (e₂.symm k))
105105

106106
lemma to_lin_add (M N : matrix m n R) : (M + N).to_lin = M.to_lin + N.to_lin :=
107107
matrix.eval.map_add M N
@@ -266,9 +266,9 @@ begin
266266
refine function.left_inverse.injective linear_equiv.symm_symm _; ext x;
267267
simp_rw [linear_equiv.symm_trans_apply, is_basis.equiv_fun_symm_apply, fun_congr_left_symm,
268268
fun_congr_left_apply, fun_left_apply],
269-
convert (finset.sum_equiv (equiv.of_injective _ hv₁.injective) _).symm,
269+
convert ((equiv.of_injective _ hv₁.injective).sum_comp _).symm,
270270
simp_rw [equiv.symm_apply_apply, equiv.of_injective_apply, subtype.coe_mk],
271-
convert (finset.sum_equiv (equiv.of_injective _ hv₂.injective) _).symm,
271+
convert ((equiv.of_injective _ hv₂.injective).sum_comp _).symm,
272272
simp_rw [equiv.symm_apply_apply, equiv.of_injective_apply, subtype.coe_mk]
273273
end
274274

@@ -752,7 +752,7 @@ linear_map.ext $ λ f, if H : 0 = 1 then eq_of_zero_eq_one H _ _ else
752752
begin
753753
haveI : nontrivial R := ⟨⟨0, 1, H⟩⟩,
754754
change ∑ i : set.range b, _ = ∑ i : ι, _, simp_rw [matrix.diag_apply], symmetry,
755-
convert finset.sum_equiv (equiv.of_injective _ hb.injective) _, ext i,
755+
convert (equiv.of_injective _ hb.injective).sum_comp _, ext i,
756756
exact (linear_equiv_matrix_range hb hb f i i).symm
757757
end
758758

src/number_theory/bernoulli.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ well_founded.fix_eq _ _ _
3838

3939
lemma bernoulli_def (n : ℕ) :
4040
bernoulli n = 1 - ∑ k in finset.range n, (n.choose k) * (bernoulli k) / (n + 1 - k) :=
41-
by { rw [bernoulli_def', finset.sum_range_eq_sum_fin], refl }
41+
by { rw [bernoulli_def', ← fin.sum_univ_eq_sum_range], refl }
4242

4343
@[simp] lemma bernoulli_zero : bernoulli 0 = 1 := rfl
4444
@[simp] lemma bernoulli_one : bernoulli 1 = 1/2 :=

src/number_theory/sum_four_squares.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ let ⟨x, hx⟩ := h01 in let ⟨y, hy⟩ := h23 in
9494
← int.sum_two_squares_of_two_mul_sum_two_squares hy.symm,
9595
← mul_right_inj' (show (2 : ℤ) ≠ 0, from dec_trivial), ← h, mul_add, ← hx, ← hy],
9696
have : ∑ x, f (σ x)^2 = ∑ x, f x^2,
97-
{ conv_rhs { rw ← finset.sum_equiv σ } },
97+
{ conv_rhs { rw ← σ.sum_comp } },
9898
have fin4univ : (univ : finset (fin 4)).1 = 0::1::2::3::0, from dec_trivial,
9999
simpa [finset.sum_eq_multiset_sum, fin4univ, multiset.sum_cons, f, add_assoc]
100100
end

0 commit comments

Comments
 (0)