@@ -28,15 +28,15 @@ symmetric powers
28
28
29
29
-/
30
30
31
- universes u
31
+ open function
32
32
33
33
/--
34
34
The nth symmetric power is n-tuples up to permutation. We define it
35
35
as a subtype of `multiset` since these are well developed in the
36
36
library. We also give a definition `sym.sym'` in terms of vectors, and we
37
37
show these are equivalent in `sym.sym_equiv_sym'`.
38
38
-/
39
- def sym (α : Type u ) (n : ℕ) := {s : multiset α // s.card = n}
39
+ def sym (α : Type * ) (n : ℕ) := {s : multiset α // s.card = n}
40
40
41
41
instance sym.has_coe (α : Type *) (n : ℕ) : has_coe (sym α n) (multiset α) := coe_subtype
42
42
@@ -46,14 +46,25 @@ This is the `list.perm` setoid lifted to `vector`.
46
46
See note [reducible non-instances].
47
47
-/
48
48
@[reducible]
49
- def vector.perm.is_setoid (α : Type u ) (n : ℕ) : setoid (vector α n) :=
49
+ def vector.perm.is_setoid (α : Type * ) (n : ℕ) : setoid (vector α n) :=
50
50
(list.is_setoid α).comap subtype.val
51
51
52
52
local attribute [instance] vector.perm.is_setoid
53
53
54
54
namespace sym
55
55
56
- variables {α : Type u} {n : ℕ} {s : sym α n} {a b : α}
56
+ variables {α β : Type *} {n : ℕ} {s : sym α n} {a b : α}
57
+
58
+ lemma coe_injective : injective (coe : sym α n → multiset α) := subtype.coe_injective
59
+
60
+ @[simp, norm_cast] lemma coe_inj {s₁ s₂ : sym α n} : (s₁ : multiset α) = s₂ ↔ s₁ = s₂ :=
61
+ coe_injective.eq_iff
62
+
63
+ /--
64
+ Construct an element of the `n`th symmetric power from a multiset of cardinality `n`.
65
+ -/
66
+ @[simps, pattern]
67
+ abbreviation mk (m : multiset α) (h : m.card = n) : sym α n := ⟨m, h⟩
57
68
58
69
/--
59
70
The unique element in `sym α 0`.
@@ -63,7 +74,7 @@ The unique element in `sym α 0`.
63
74
/--
64
75
Inserts an element into the term of `sym α n`, increasing the length by one.
65
76
-/
66
- @[pattern] def cons (a : α) (s : sym α n) : sym α (nat .succ n) :=
77
+ @[pattern] def cons (a : α) (s : sym α n) : sym α n .succ :=
67
78
⟨a ::ₘ s.1 , by rw [multiset.card_cons, s.2 ]⟩
68
79
69
80
notation a :: b := cons a b
@@ -79,6 +90,8 @@ subtype.ext_iff.trans $ multiset.cons_inj_left _
79
90
lemma cons_swap (a b : α) (s : sym α n) : a :: b :: s = b :: a :: s :=
80
91
subtype.ext $ multiset.cons_swap a b s.1
81
92
93
+ lemma coe_cons (s : sym α n) (a : α) : (a :: s : multiset α) = a ::ₘ s := rfl
94
+
82
95
/--
83
96
This is the quotient map that takes a list of n elements as an n-tuple and produces an nth
84
97
symmetric power.
@@ -99,6 +112,9 @@ instance : has_mem α (sym α n) := ⟨λ a s, a ∈ s.1⟩
99
112
instance decidable_mem [decidable_eq α] (a : α) (s : sym α n) : decidable (a ∈ s) :=
100
113
s.1 .decidable_mem _
101
114
115
+ @[simp]
116
+ lemma mem_mk (a : α) (s : multiset α) (h : s.card = n) : a ∈ mk s h ↔ a ∈ s := iff.rfl
117
+
102
118
@[simp] lemma mem_cons {a b : α} {s : sym α n} : a ∈ b :: s ↔ a = b ∨ a ∈ s :=
103
119
multiset.mem_cons
104
120
@@ -119,29 +135,40 @@ subtype.ext $ quotient.sound h
119
135
def erase [decidable_eq α] (s : sym α (n + 1 )) (a : α) (h : a ∈ s) : sym α n :=
120
136
⟨s.val.erase a, (multiset.card_erase_of_mem h).trans $ s.property.symm ▸ n.pred_succ⟩
121
137
122
- @[simp] lemma cons_erase [decidable_eq α] (s : sym α (n + 1 )) (a : α) (h : a ∈ s) :
123
- a :: s.erase a h = s := subtype.ext $ multiset.cons_erase h
138
+ @[simp] lemma erase_mk [decidable_eq α] (m : multiset α) (hc : m.card = n + 1 ) (a : α) (h : a ∈ m) :
139
+ (mk m hc).erase a h = mk (m.erase a) (by { rw [multiset.card_erase_of_mem h, hc], refl }) := rfl
140
+
141
+ @[simp] lemma coe_erase [decidable_eq α] {s : sym α n.succ} {a : α} (h : a ∈ s) :
142
+ (s.erase a h : multiset α) = multiset.erase s a := rfl
143
+
144
+ @[simp] lemma cons_erase [decidable_eq α] {s : sym α n.succ} {a : α} (h : a ∈ s) :
145
+ a :: s.erase a h = s :=
146
+ coe_injective $ multiset.cons_erase h
147
+
148
+ @[simp] lemma erase_cons_head [decidable_eq α] (s : sym α n) (a : α)
149
+ (h : a ∈ a :: s := mem_cons_self a s) : (a :: s).erase a h = s :=
150
+ coe_injective $ multiset.erase_cons_head a s.1
124
151
125
152
/--
126
153
Another definition of the nth symmetric power, using vectors modulo permutations. (See `sym`.)
127
154
-/
128
- def sym' (α : Type u ) (n : ℕ) := quotient (vector.perm.is_setoid α n)
155
+ def sym' (α : Type * ) (n : ℕ) := quotient (vector.perm.is_setoid α n)
129
156
130
157
/--
131
158
This is `cons` but for the alternative `sym'` definition.
132
159
-/
133
- def cons' {α : Type u } {n : ℕ} : α → sym' α n → sym' α (nat.succ n) :=
160
+ def cons' {α : Type * } {n : ℕ} : α → sym' α n → sym' α (nat.succ n) :=
134
161
λ a, quotient.map (vector.cons a) (λ ⟨l₁, h₁⟩ ⟨l₂, h₂⟩ h, list.perm.cons _ h)
135
162
136
163
notation a :: b := cons' a b
137
164
138
165
/--
139
166
Multisets of cardinality n are equivalent to length-n vectors up to permutations.
140
167
-/
141
- def sym_equiv_sym' {α : Type u } {n : ℕ} : sym α n ≃ sym' α n :=
168
+ def sym_equiv_sym' {α : Type * } {n : ℕ} : sym α n ≃ sym' α n :=
142
169
equiv.subtype_quotient_equiv_quotient_subtype _ _ (λ _, by refl) (λ _ _, by refl)
143
170
144
- lemma cons_equiv_eq_equiv_cons (α : Type u ) (n : ℕ) (a : α) (s : sym α n) :
171
+ lemma cons_equiv_eq_equiv_cons (α : Type * ) (n : ℕ) (a : α) (s : sym α n) :
145
172
a :: sym_equiv_sym' s = sym_equiv_sym' (a :: s) :=
146
173
by { rcases s with ⟨⟨l⟩, _⟩, refl, }
147
174
@@ -177,7 +204,7 @@ lemma exists_eq_cons_of_succ (s : sym α n.succ) : ∃ (a : α) (s' : sym α n),
177
204
begin
178
205
obtain ⟨a, ha⟩ := exists_mem s,
179
206
classical,
180
- exact ⟨a, s.erase a ha, (s. cons_erase _ _ ).symm⟩,
207
+ exact ⟨a, s.erase a ha, (cons_erase ha ).symm⟩,
181
208
end
182
209
183
210
lemma eq_repeat {a : α} {n : ℕ} {s : sym α n} : s = repeat a n ↔ ∀ b ∈ s, b = a :=
@@ -217,33 +244,72 @@ instance (n : ℕ) [nontrivial α] : nontrivial (sym α (n + 1)) :=
217
244
218
245
/-- A function `α → β` induces a function `sym α n → sym β n` by applying it to every element of
219
246
the underlying `n`-tuple. -/
220
- def map {α β : Type *} { n : ℕ} (f : α → β) (x : sym α n) : sym β n :=
247
+ def map {n : ℕ} (f : α → β) (x : sym α n) : sym β n :=
221
248
⟨x.val.map f, by simpa [multiset.card_map] using x.property⟩
222
249
223
- @[simp] lemma mem_map {α β : Type *} { n : ℕ} {f : α → β} {b : β} {l : sym α n} :
250
+ @[simp] lemma mem_map {n : ℕ} {f : α → β} {b : β} {l : sym α n} :
224
251
b ∈ sym.map f l ↔ ∃ a, a ∈ l ∧ f a = b := multiset.mem_map
225
252
226
- @[simp] lemma map_id {α : Type *} {n : ℕ} (s : sym α n) : sym.map id s = s :=
253
+ /-- Note: `sym.map_id` is not simp-normal, as simp ends up unfolding `id` with `sym.map_congr` -/
254
+ @[simp] lemma map_id' {α : Type *} {n : ℕ} (s : sym α n) : sym.map (λ (x : α), x) s = s :=
255
+ by simp [sym.map]
256
+
257
+ lemma map_id {α : Type *} {n : ℕ} (s : sym α n) : sym.map id s = s :=
227
258
by simp [sym.map]
228
259
229
260
@[simp] lemma map_map {α β γ : Type *} {n : ℕ} (g : β → γ) (f : α → β) (s : sym α n) :
230
261
sym.map g (sym.map f s) = sym.map (g ∘ f) s :=
231
262
by simp [sym.map]
232
263
233
- @[simp] lemma map_zero {α β : Type *} (f : α → β) :
264
+ @[simp] lemma map_zero (f : α → β) :
234
265
sym.map f (0 : sym α 0 ) = (0 : sym β 0 ) := rfl
235
266
236
- @[simp] lemma map_cons {α β : Type *} { n : ℕ} (f : α → β) (a : α) (s : sym α n) :
267
+ @[simp] lemma map_cons {n : ℕ} (f : α → β) (a : α) (s : sym α n) :
237
268
(a :: s).map f = (f a) :: s.map f :=
238
269
by simp [map, cons]
239
270
271
+ @[congr] lemma map_congr {f g : α → β} {s : sym α n} (h : ∀ x ∈ s, f x = g x) :
272
+ map f s = map g s := subtype.ext $ multiset.map_congr rfl h
273
+
274
+ @[simp] lemma map_mk {f : α → β} {m : multiset α} {hc : m.card = n} :
275
+ map f (mk m hc) = mk (m.map f) (by simp [hc]) := rfl
276
+
277
+ @[simp] lemma coe_map (s : sym α n) (f : α → β) : ↑(s.map f) = multiset.map f s := rfl
278
+
279
+ lemma map_injective {f : α → β} (hf : injective f) (n : ℕ) :
280
+ injective (map f : sym α n → sym β n) :=
281
+ λ s t h, coe_injective $ multiset.map_injective hf $ coe_inj.2 h
282
+
240
283
/-- Mapping an equivalence `α ≃ β` using `sym.map` gives an equivalence between `sym α n` and
241
284
`sym β n`. -/
242
285
@[simps]
243
- def equiv_congr {β : Type u} (e : α ≃ β) : sym α n ≃ sym β n :=
286
+ def equiv_congr (e : α ≃ β) : sym α n ≃ sym β n :=
244
287
{ to_fun := map e,
245
288
inv_fun := map e.symm,
246
289
left_inv := λ x, by rw [map_map, equiv.symm_comp_self, map_id],
247
290
right_inv := λ x, by rw [map_map, equiv.self_comp_symm, map_id] }
248
291
292
+ /-- "Attach" a proof that `a ∈ s` to each element `a` in `s` to produce
293
+ an element of the symmetric power on `{x // x ∈ s}`. -/
294
+ def attach (s : sym α n) : sym {x // x ∈ s} n := ⟨s.val.attach, by rw [multiset.card_attach, s.2 ]⟩
295
+
296
+ @[simp] lemma attach_mk {m : multiset α} {hc : m.card = n} :
297
+ attach (mk m hc) = mk m.attach (multiset.card_attach.trans hc) := rfl
298
+
299
+ @[simp] lemma coe_attach (s : sym α n) : (s.attach : multiset {a // a ∈ s}) = multiset.attach s :=
300
+ rfl
301
+
302
+ lemma attach_map_coe (s : sym α n) : s.attach.map coe = s :=
303
+ coe_injective $ multiset.attach_map_val _
304
+
305
+ @[simp] lemma mem_attach (s : sym α n) (x : {x // x ∈ s}) : x ∈ s.attach :=
306
+ multiset.mem_attach _ _
307
+
308
+ @[simp] lemma attach_nil : (nil : sym α 0 ).attach = nil := rfl
309
+
310
+ @[simp] lemma attach_cons (x : α) (s : sym α n) :
311
+ (cons x s).attach = cons ⟨x, mem_cons_self _ _⟩ (s.attach.map (λ x, ⟨x, mem_cons_of_mem x.prop⟩))
312
+ :=
313
+ coe_injective $ multiset.attach_cons _ _
314
+
249
315
end sym
0 commit comments