|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Yaël Dillies. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yaël Dillies |
| 5 | +-/ |
| 6 | +import data.finset.prod |
| 7 | +import data.sym.sym2 |
| 8 | + |
| 9 | +/-! |
| 10 | +# Symmetric powers of a finset |
| 11 | +
|
| 12 | +This file defines the symmetric powers of a finset as `finset (sym α n)` and `finset (sym2 α)`. |
| 13 | +
|
| 14 | +## Main declarations |
| 15 | +
|
| 16 | +* `finset.sym`: The symmetric power of a finset. `s.sym n` is all the multisets of cardinality `n` |
| 17 | + whose elements are in `s`. |
| 18 | +* `finset.sym2`: The symmetric square of a finset. `s.sym2` is all the pairs whose elements are in |
| 19 | + `s`. |
| 20 | +
|
| 21 | +## TODO |
| 22 | +
|
| 23 | +`finset.sym` forms a Galois connection between `finset α` and `finset (sym α n)`. Similar for |
| 24 | +`finset.sym2`. |
| 25 | +-/ |
| 26 | + |
| 27 | +namespace finset |
| 28 | +variables {α : Type*} [decidable_eq α] {s t : finset α} {a b : α} |
| 29 | + |
| 30 | +lemma is_diag_mk_of_mem_diag {a : α × α} (h : a ∈ s.diag) : sym2.is_diag ⟦a⟧ := |
| 31 | +(sym2.is_diag_iff_proj_eq _).2 ((mem_diag _ _).1 h).2 |
| 32 | + |
| 33 | +lemma not_is_diag_mk_of_mem_off_diag {a : α × α} (h : a ∈ s.off_diag) : ¬ sym2.is_diag ⟦a⟧ := |
| 34 | +by { rw sym2.is_diag_iff_proj_eq, exact ((mem_off_diag _ _).1 h).2.2 } |
| 35 | + |
| 36 | +section sym2 |
| 37 | +variables {m : sym2 α} |
| 38 | + |
| 39 | +/-- Lifts a finset to `sym2 α`. `s.sym2` is the finset of all pairs with elements in `s`. -/ |
| 40 | +protected def sym2 (s : finset α) : finset (sym2 α) := (s.product s).image quotient.mk |
| 41 | + |
| 42 | +@[simp] lemma mem_sym2_iff : m ∈ s.sym2 ↔ ∀ a ∈ m, a ∈ s := |
| 43 | +begin |
| 44 | + refine mem_image.trans |
| 45 | + ⟨_, λ h, ⟨m.out, mem_product.2 ⟨h _ m.out_fst_mem, h _ m.out_snd_mem⟩, m.out_eq⟩⟩, |
| 46 | + rintro ⟨⟨a, b⟩, h, rfl⟩, |
| 47 | + rw sym2.ball, |
| 48 | + rwa mem_product at h, |
| 49 | +end |
| 50 | + |
| 51 | +lemma mk_mem_sym2_iff : ⟦(a, b)⟧ ∈ s.sym2 ↔ a ∈ s ∧ b ∈ s := by rw [mem_sym2_iff, sym2.ball] |
| 52 | + |
| 53 | +@[simp] lemma sym2_empty : (∅ : finset α).sym2 = ∅ := rfl |
| 54 | + |
| 55 | +@[simp] lemma sym2_eq_empty : s.sym2 = ∅ ↔ s = ∅ := |
| 56 | +by rw [finset.sym2, image_eq_empty, product_eq_empty, or_self] |
| 57 | + |
| 58 | +@[simp] lemma sym2_nonempty : s.sym2.nonempty ↔ s.nonempty := |
| 59 | +by rw [finset.sym2, nonempty.image_iff, nonempty_product, and_self] |
| 60 | + |
| 61 | +alias sym2_nonempty ↔ _ finset.nonempty.sym2 |
| 62 | + |
| 63 | +attribute [protected] finset.nonempty.sym2 |
| 64 | + |
| 65 | +@[simp] lemma sym2_univ [fintype α] : (univ : finset α).sym2 = univ := rfl |
| 66 | + |
| 67 | +@[simp] lemma sym2_singleton (a : α) : ({a} : finset α).sym2 = {sym2.diag a} := |
| 68 | +by rw [finset.sym2, singleton_product_singleton, image_singleton, sym2.diag] |
| 69 | + |
| 70 | +@[simp] lemma diag_mem_sym2_iff : sym2.diag a ∈ s.sym2 ↔ a ∈ s := mk_mem_sym2_iff.trans $ and_self _ |
| 71 | + |
| 72 | +@[simp] lemma sym2_mono (h : s ⊆ t) : s.sym2 ⊆ t.sym2 := |
| 73 | +λ m he, mem_sym2_iff.2 $ λ a ha, h $ mem_sym2_iff.1 he _ ha |
| 74 | + |
| 75 | +lemma image_diag_union_image_off_diag : |
| 76 | + s.diag.image quotient.mk ∪ s.off_diag.image quotient.mk = s.sym2 := |
| 77 | +by { rw [←image_union, diag_union_off_diag], refl } |
| 78 | + |
| 79 | +end sym2 |
| 80 | + |
| 81 | +section sym |
| 82 | +variables {n : ℕ} {m : sym α n} |
| 83 | + |
| 84 | +/-- Lifts a finset to `sym α n`. `s.sym n` is the finset of all unordered tuples of cardinality `n` |
| 85 | +with elements in `s`. -/ |
| 86 | +protected def sym (s : finset α) : Π n, finset (sym α n) |
| 87 | +| 0 := {∅} |
| 88 | +| (n + 1) := s.sup $ λ a, (sym n).image $ _root_.sym.cons a |
| 89 | + |
| 90 | +@[simp] lemma sym_zero : s.sym 0 = {∅} := rfl |
| 91 | +@[simp] lemma sym_succ : s.sym (n + 1) = s.sup (λ a, (s.sym n).image $ sym.cons a) := rfl |
| 92 | + |
| 93 | +@[simp] lemma mem_sym_iff : m ∈ s.sym n ↔ ∀ a ∈ m, a ∈ s := |
| 94 | +begin |
| 95 | + induction n with n ih, |
| 96 | + { refine mem_singleton.trans ⟨_, λ _, sym.eq_nil_of_card_zero _⟩, |
| 97 | + rintro rfl, |
| 98 | + exact λ a ha, ha.elim }, |
| 99 | + refine mem_sup.trans ⟨_, λ h, _⟩, |
| 100 | + { rintro ⟨a, ha, he⟩ b hb, |
| 101 | + rw mem_image at he, |
| 102 | + obtain ⟨m, he, rfl⟩ := he, |
| 103 | + rw sym.mem_cons at hb, |
| 104 | + obtain rfl | hb := hb, |
| 105 | + { exact ha }, |
| 106 | + { exact ih.1 he _ hb } }, |
| 107 | + { obtain ⟨a, m, rfl⟩ := m.exists_eq_cons_of_succ, |
| 108 | + exact ⟨a, h _ $ sym.mem_cons_self _ _, |
| 109 | + mem_image_of_mem _ $ ih.2 $ λ b hb, h _ $ sym.mem_cons_of_mem hb⟩ } |
| 110 | +end |
| 111 | + |
| 112 | +@[simp] lemma sym_empty (n : ℕ) : (∅ : finset α).sym (n + 1) = ∅ := rfl |
| 113 | + |
| 114 | +lemma repeat_mem_sym (ha : a ∈ s) (n : ℕ) : sym.repeat a n ∈ s.sym n := |
| 115 | +mem_sym_iff.2 $ λ b hb, by rwa (sym.mem_repeat.1 hb).2 |
| 116 | + |
| 117 | +protected lemma nonempty.sym (h : s.nonempty) (n : ℕ) : (s.sym n).nonempty := |
| 118 | +let ⟨a, ha⟩ := h in ⟨_, repeat_mem_sym ha n⟩ |
| 119 | + |
| 120 | +@[simp] lemma sym_singleton (a : α) (n : ℕ) : ({a} : finset α).sym n = {sym.repeat a n} := |
| 121 | +eq_singleton_iff_nonempty_unique_mem.2 ⟨(singleton_nonempty _).sym n, |
| 122 | + λ s hs, sym.eq_repeat_iff.2 $ λ b hb, eq_of_mem_singleton $ mem_sym_iff.1 hs _ hb⟩ |
| 123 | + |
| 124 | +lemma eq_empty_of_sym_eq_empty (h : s.sym n = ∅) : s = ∅ := |
| 125 | +begin |
| 126 | + rw ←not_nonempty_iff_eq_empty at ⊢ h, |
| 127 | + exact λ hs, h (hs.sym _), |
| 128 | +end |
| 129 | + |
| 130 | +@[simp] lemma sym_eq_empty : s.sym n = ∅ ↔ n ≠ 0 ∧ s = ∅ := |
| 131 | +begin |
| 132 | + cases n, |
| 133 | + { exact iff_of_false (singleton_ne_empty _) (λ h, (h.1 rfl).elim) }, |
| 134 | + { refine ⟨λ h, ⟨n.succ_ne_zero, eq_empty_of_sym_eq_empty h⟩, _⟩, |
| 135 | + rintro ⟨_, rfl⟩, |
| 136 | + exact sym_empty _ } |
| 137 | +end |
| 138 | + |
| 139 | +@[simp] lemma sym_nonempty : (s.sym n).nonempty ↔ n = 0 ∨ s.nonempty := |
| 140 | +by simp_rw [nonempty_iff_ne_empty, ne.def, sym_eq_empty, not_and_distrib, not_ne_iff] |
| 141 | + |
| 142 | +alias sym2_nonempty ↔ _ finset.nonempty.sym2 |
| 143 | + |
| 144 | +attribute [protected] finset.nonempty.sym2 |
| 145 | + |
| 146 | +@[simp] lemma sym_univ [fintype α] (n : ℕ) : (univ : finset α).sym n = univ := |
| 147 | +eq_univ_iff_forall.2 $ λ s, mem_sym_iff.2 $ λ a _, mem_univ _ |
| 148 | + |
| 149 | +@[simp] lemma sym_mono (h : s ⊆ t) (n : ℕ): s.sym n ⊆ t.sym n := |
| 150 | +λ m hm, mem_sym_iff.2 $ λ a ha, h $ mem_sym_iff.1 hm _ ha |
| 151 | + |
| 152 | +@[simp] lemma sym_inter (s t : finset α) (n : ℕ) : (s ∩ t).sym n = s.sym n ∩ t.sym n := |
| 153 | +by { ext m, simp only [mem_inter, mem_sym_iff, imp_and_distrib, forall_and_distrib] } |
| 154 | + |
| 155 | +@[simp] lemma sym_union (s t : finset α) (n : ℕ) : s.sym n ∪ t.sym n ⊆ (s ∪ t).sym n := |
| 156 | +union_subset (sym_mono (subset_union_left s t) n) (sym_mono (subset_union_right s t) n) |
| 157 | + |
| 158 | +end sym |
| 159 | +end finset |
0 commit comments