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

Commit 69189d4

Browse files
committed
split(data/finset/prod): split off data.finset.basic (#10142)
Killing the giants. This moves `finset.product`, `finset.diag`, `finset.off_diag` to their own file, the theme being "finsets on `α × β`". The copyright header now credits: * Johannes Hölzl for ba95269 * Mario Carneiro * Oliver Nash for #4502
1 parent de79226 commit 69189d4

File tree

3 files changed

+128
-108
lines changed

3 files changed

+128
-108
lines changed

src/data/finset/basic.lean

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ and the empty finset otherwise. See `data.fintype.basic`.
6363
* `finset.range`: For any `n : ℕ`, `range n` is equal to `{0, 1, ... , n - 1} ⊆ ℕ`.
6464
This convention is consistent with other languages and normalizes `card (range n) = n`.
6565
Beware, `n` is not in `range n`.
66-
* `finset.diag`: Given `s`, `diag s` is the set of pairs `(a, a)` with `a ∈ s`. See also
67-
`finset.off_diag`: Given a finite set `s`, the off-diagonal,
68-
`s.off_diag` is the set of pairs `(a, b)` with `a ≠ b` for `a, b ∈ s`.
6966
* `finset.attach`: Given `s : finset α`, `attach s` forms a finset of elements of the subtype
7067
`{a // a ∈ s}`; in other words, it attaches elements to a proof of membership in the set.
7168
@@ -85,9 +82,9 @@ called `top` with `⊤ = univ`.
8582
8683
* `finset.subset`: Lots of API about lattices, otherwise behaves exactly as one would expect.
8784
* `finset.union`: Defines `s ∪ t` (or `s ⊔ t`) as the union of `s` and `t`.
88-
See `finset.bUnion` for finite unions.
85+
See `finset.sup`/`finset.bUnion` for finite unions.
8986
* `finset.inter`: Defines `s ∩ t` (or `s ⊓ t`) as the intersection of `s` and `t`.
90-
TODO: `finset.bInter` for finite intersections.
87+
See `finset.inf` for finite intersections.
9188
* `finset.disj_union`: Given a hypothesis `h` which states that finsets `s` and `t` are disjoint,
9289
`s.disj_union t h` is the set such that `a ∈ disj_union s t h` iff `a ∈ s` or `a ∈ t`; this does
9390
not require decidable equality on the type `α`.
@@ -2752,69 +2749,6 @@ bUnion_nonempty.2 $ hs.imp $ λ x hx, ⟨hx, ht x hx⟩
27522749

27532750
end bUnion
27542751

2755-
/-! ### prod -/
2756-
section prod
2757-
variables {s s' : finset α} {t t' : finset β}
2758-
2759-
/-- `product s t` is the set of pairs `(a, b)` such that `a ∈ s` and `b ∈ t`. -/
2760-
protected def product (s : finset α) (t : finset β) : finset (α × β) := ⟨_, nodup_product s.2 t.2
2761-
2762-
@[simp] theorem product_val : (s.product t).1 = s.1.product t.1 := rfl
2763-
2764-
@[simp] theorem mem_product {p : α × β} : p ∈ s.product t ↔ p.1 ∈ s ∧ p.2 ∈ t := mem_product
2765-
2766-
theorem subset_product [decidable_eq α] [decidable_eq β] {s : finset (α × β)} :
2767-
s ⊆ (s.image prod.fst).product (s.image prod.snd) :=
2768-
λ p hp, mem_product.2 ⟨mem_image_of_mem _ hp, mem_image_of_mem _ hp⟩
2769-
2770-
lemma product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s.product t ⊆ s'.product t' :=
2771-
λ ⟨x,y⟩ h, mem_product.2 ⟨hs (mem_product.1 h).1, ht (mem_product.1 h).2
2772-
2773-
lemma product_subset_product_left (hs : s ⊆ s') : s.product t ⊆ s'.product t :=
2774-
product_subset_product hs (subset.refl _)
2775-
2776-
lemma product_subset_product_right (ht : t ⊆ t') : s.product t ⊆ s.product t' :=
2777-
product_subset_product (subset.refl _) ht
2778-
2779-
theorem product_eq_bUnion [decidable_eq α] [decidable_eq β] (s : finset α) (t : finset β) :
2780-
s.product t = s.bUnion (λa, t.image $ λb, (a, b)) :=
2781-
ext $ λ ⟨x, y⟩, by simp only [mem_product, mem_bUnion, mem_image, exists_prop, prod.mk.inj_iff,
2782-
and.left_comm, exists_and_distrib_left, exists_eq_right, exists_eq_left]
2783-
2784-
@[simp] lemma product_bUnion {β γ : Type*} [decidable_eq γ]
2785-
(s : finset α) (t : finset β) (f : α × β → finset γ) :
2786-
(s.product t).bUnion f = s.bUnion (λ a, t.bUnion (λ b, f (a, b))) :=
2787-
by { classical, simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion] }
2788-
2789-
@[simp] theorem card_product (s : finset α) (t : finset β) : card (s.product t) = card s * card t :=
2790-
multiset.card_product _ _
2791-
2792-
theorem filter_product (p : α → Prop) (q : β → Prop) [decidable_pred p] [decidable_pred q] :
2793-
(s.product t).filter (λ (x : α × β), p x.1 ∧ q x.2) = (s.filter p).product (t.filter q) :=
2794-
by { ext ⟨a, b⟩, simp only [mem_filter, mem_product], finish, }
2795-
2796-
lemma filter_product_card (s : finset α) (t : finset β)
2797-
(p : α → Prop) (q : β → Prop) [decidable_pred p] [decidable_pred q] :
2798-
((s.product t).filter (λ (x : α × β), p x.1 ↔ q x.2)).card =
2799-
(s.filter p).card * (t.filter q).card + (s.filter (not ∘ p)).card * (t.filter (not ∘ q)).card :=
2800-
begin
2801-
classical,
2802-
rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq],
2803-
{ apply congr_arg, ext ⟨a, b⟩, simp only [filter_union_right, mem_filter, mem_product],
2804-
split; intros; finish, },
2805-
{ rw disjoint_iff, change _ ∩ _ = ∅, ext ⟨a, b⟩, rw mem_inter, finish, },
2806-
end
2807-
2808-
lemma empty_product (t : finset β) :
2809-
(∅ : finset α).product t = ∅ :=
2810-
rfl
2811-
2812-
lemma product_empty (s : finset α) :
2813-
s.product (∅ : finset β) = ∅ :=
2814-
eq_empty_of_forall_not_mem (λ x h, (finset.mem_product.1 h).2)
2815-
2816-
end prod
2817-
28182752
/-! ### sigma -/
28192753
section sigma
28202754
variables {σ : α → Type*} {s : finset α} {t : Πa, finset (σ a)}
@@ -2973,45 +2907,6 @@ by { classical, simp [← card_union_eq, filter_union_filter_neg_eq, disjoint_fi
29732907

29742908
end disjoint
29752909

2976-
section self_prod
2977-
variables (s : finset α) [decidable_eq α]
2978-
2979-
/-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for
2980-
`a ∈ s`. -/
2981-
def diag := (s.product s).filter (λ (a : α × α), a.fst = a.snd)
2982-
2983-
/-- Given a finite set `s`, the off-diagonal, `s.off_diag` is the set of pairs `(a, b)` with `a ≠ b`
2984-
for `a, b ∈ s`. -/
2985-
def off_diag := (s.product s).filter (λ (a : α × α), a.fst ≠ a.snd)
2986-
2987-
@[simp] lemma mem_diag (x : α × α) : x ∈ s.diag ↔ x.1 ∈ s ∧ x.1 = x.2 :=
2988-
by { simp only [diag, mem_filter, mem_product], split; intros; finish, }
2989-
2990-
@[simp] lemma mem_off_diag (x : α × α) : x ∈ s.off_diag ↔ x.1 ∈ s ∧ x.2 ∈ s ∧ x.1 ≠ x.2 :=
2991-
by { simp only [off_diag, mem_filter, mem_product], split; intros; finish, }
2992-
2993-
@[simp] lemma diag_card : (diag s).card = s.card :=
2994-
begin
2995-
suffices : diag s = s.image (λ a, (a, a)), { rw this, apply card_image_of_inj_on, finish, },
2996-
ext ⟨a₁, a₂⟩, rw mem_diag, split; intros; finish,
2997-
end
2998-
2999-
@[simp] lemma off_diag_card : (off_diag s).card = s.card * s.card - s.card :=
3000-
begin
3001-
suffices : (diag s).card + (off_diag s).card = s.card * s.card,
3002-
{ nth_rewrite 2 ← s.diag_card, finish, },
3003-
rw ← card_product,
3004-
apply filter_card_add_filter_neg_card_eq_card,
3005-
end
3006-
3007-
@[simp] lemma diag_empty : (∅ : finset α).diag = ∅ :=
3008-
eq_empty_of_forall_not_mem (by simp)
3009-
3010-
@[simp] lemma off_diag_empty : (∅ : finset α).off_diag = ∅ :=
3011-
eq_empty_of_forall_not_mem (by simp)
3012-
3013-
end self_prod
3014-
30152910
/--
30162911
Given a set A and a set B inside it, we can shrink A to any appropriate size, and keep B
30172912
inside it.

src/data/finset/prod.lean

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/-
2+
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Johannes Hölzl, Mario Carneiro, Oliver Nash
5+
-/
6+
import data.finset.basic
7+
8+
/-!
9+
# Finsets in product types
10+
11+
This file defines finset constructions on the product type `α × β`. Beware not to confuse with the
12+
`finset.prod` operation which computes the multiplicative product.
13+
14+
## Main declarations
15+
16+
* `finset.product`: Turns `s : finset α`, `t : finset β` into their product in `finset (α × β)`.
17+
* `finset.diag`: For `s : finset α`, `s.diag` is the `finset (α × α)` of pairs `(a, a)` with
18+
`a ∈ s`.
19+
* `finset.off_diag`: For `s : finset α`, `s.off_diag` is the `finset (α × α)` of pairs `(a, b)` with
20+
`a, b ∈ s` and `a ≠ b`.
21+
-/
22+
23+
open multiset
24+
25+
variables {α β γ : Type*}
26+
27+
namespace finset
28+
29+
/-! ### prod -/
30+
section prod
31+
variables {s s' : finset α} {t t' : finset β}
32+
33+
/-- `product s t` is the set of pairs `(a, b)` such that `a ∈ s` and `b ∈ t`. -/
34+
protected def product (s : finset α) (t : finset β) : finset (α × β) := ⟨_, nodup_product s.2 t.2
35+
36+
@[simp] lemma product_val : (s.product t).1 = s.1.product t.1 := rfl
37+
38+
@[simp] lemma mem_product {p : α × β} : p ∈ s.product t ↔ p.1 ∈ s ∧ p.2 ∈ t := mem_product
39+
40+
lemma subset_product [decidable_eq α] [decidable_eq β] {s : finset (α × β)} :
41+
s ⊆ (s.image prod.fst).product (s.image prod.snd) :=
42+
λ p hp, mem_product.2 ⟨mem_image_of_mem _ hp, mem_image_of_mem _ hp⟩
43+
44+
lemma product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s.product t ⊆ s'.product t' :=
45+
λ ⟨x,y⟩ h, mem_product.2 ⟨hs (mem_product.1 h).1, ht (mem_product.1 h).2
46+
47+
lemma product_subset_product_left (hs : s ⊆ s') : s.product t ⊆ s'.product t :=
48+
product_subset_product hs (subset.refl _)
49+
50+
lemma product_subset_product_right (ht : t ⊆ t') : s.product t ⊆ s.product t' :=
51+
product_subset_product (subset.refl _) ht
52+
53+
lemma product_eq_bUnion [decidable_eq α] [decidable_eq β] (s : finset α) (t : finset β) :
54+
s.product t = s.bUnion (λa, t.image $ λb, (a, b)) :=
55+
ext $ λ ⟨x, y⟩, by simp only [mem_product, mem_bUnion, mem_image, exists_prop, prod.mk.inj_iff,
56+
and.left_comm, exists_and_distrib_left, exists_eq_right, exists_eq_left]
57+
58+
@[simp] lemma product_bUnion [decidable_eq γ] (s : finset α) (t : finset β) (f : α × β → finset γ) :
59+
(s.product t).bUnion f = s.bUnion (λ a, t.bUnion (λ b, f (a, b))) :=
60+
by { classical, simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion] }
61+
62+
@[simp] lemma card_product (s : finset α) (t : finset β) : card (s.product t) = card s * card t :=
63+
multiset.card_product _ _
64+
65+
lemma filter_product (p : α → Prop) (q : β → Prop) [decidable_pred p] [decidable_pred q] :
66+
(s.product t).filter (λ (x : α × β), p x.1 ∧ q x.2) = (s.filter p).product (t.filter q) :=
67+
by { ext ⟨a, b⟩, simp only [mem_filter, mem_product], finish }
68+
69+
lemma filter_product_card (s : finset α) (t : finset β)
70+
(p : α → Prop) (q : β → Prop) [decidable_pred p] [decidable_pred q] :
71+
((s.product t).filter (λ (x : α × β), p x.1 ↔ q x.2)).card =
72+
(s.filter p).card * (t.filter q).card + (s.filter (not ∘ p)).card * (t.filter (not ∘ q)).card :=
73+
begin
74+
classical,
75+
rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq],
76+
{ apply congr_arg, ext ⟨a, b⟩, simp only [filter_union_right, mem_filter, mem_product],
77+
split; intros; finish },
78+
{ rw disjoint_iff, change _ ∩ _ = ∅, ext ⟨a, b⟩, rw mem_inter, finish }
79+
end
80+
81+
lemma empty_product (t : finset β) : (∅ : finset α).product t = ∅ := rfl
82+
83+
lemma product_empty (s : finset α) : s.product (∅ : finset β) = ∅ :=
84+
eq_empty_of_forall_not_mem (λ x h, (finset.mem_product.1 h).2)
85+
86+
end prod
87+
88+
section diag
89+
variables (s : finset α) [decidable_eq α]
90+
91+
/-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for
92+
`a ∈ s`. -/
93+
def diag := (s.product s).filter (λ (a : α × α), a.fst = a.snd)
94+
95+
/-- Given a finite set `s`, the off-diagonal, `s.off_diag` is the set of pairs `(a, b)` with `a ≠ b`
96+
for `a, b ∈ s`. -/
97+
def off_diag := (s.product s).filter (λ (a : α × α), a.fst ≠ a.snd)
98+
99+
@[simp] lemma mem_diag (x : α × α) : x ∈ s.diag ↔ x.1 ∈ s ∧ x.1 = x.2 :=
100+
by { simp only [diag, mem_filter, mem_product], split; intros; finish }
101+
102+
@[simp] lemma mem_off_diag (x : α × α) : x ∈ s.off_diag ↔ x.1 ∈ s ∧ x.2 ∈ s ∧ x.1 ≠ x.2 :=
103+
by { simp only [off_diag, mem_filter, mem_product], split; intros; finish }
104+
105+
@[simp] lemma diag_card : (diag s).card = s.card :=
106+
begin
107+
suffices : diag s = s.image (λ a, (a, a)), { rw this, apply card_image_of_inj_on, finish },
108+
ext ⟨a₁, a₂⟩, rw mem_diag, split; intros; finish,
109+
end
110+
111+
@[simp] lemma off_diag_card : (off_diag s).card = s.card * s.card - s.card :=
112+
begin
113+
suffices : (diag s).card + (off_diag s).card = s.card * s.card,
114+
{ nth_rewrite 2 ← s.diag_card, finish },
115+
rw ← card_product,
116+
apply filter_card_add_filter_neg_card_eq_card,
117+
end
118+
119+
@[simp] lemma diag_empty : (∅ : finset α).diag = ∅ := rfl
120+
121+
@[simp] lemma off_diag_empty : (∅ : finset α).off_diag = ∅ := rfl
122+
123+
end diag
124+
end finset

src/data/fintype/basic.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Mario Carneiro
55
-/
66
import data.array.lemmas
7+
import data.finset.option
78
import data.finset.pi
89
import data.finset.powerset
9-
import data.finset.option
10+
import data.finset.prod
1011
import data.sym.basic
1112
import data.ulift
1213
import group_theory.perm.basic

0 commit comments

Comments
 (0)