-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathMultipleTransitivity.lean
More file actions
284 lines (230 loc) · 10.4 KB
/
MultipleTransitivity.lean
File metadata and controls
284 lines (230 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/-
Copyright (c) 2025 Antoine Chambert-Loir. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Antoine Chambert-Loir
-/
import Mathlib.GroupTheory.GroupAction.Embedding
import Mathlib.GroupTheory.GroupAction.Primitive
import Mathlib.SetTheory.Cardinal.Embedding
/-! # Multiple transitivity
* `MulAction.IsMultiplyPretransitive`:
A multiplicative action of a group `G` on a type `α` is n-transitive
if the action of `G` on `Fin n ↪ α` is pretransitive.
* `MulAction.is_zero_pretransitive` : any action is 0-pretransitive
* `MulAction.is_one_pretransitive_iff` :
An action is 1-pretransitive iff it is pretransitive
* `MulAction.is_two_pretransitive_iff` :
An action is 2-pretransitive if for any `a`, `b`, `c`, `d`, such that
`a ≠ b` and `c ≠ d`, there exist `g : G` such that `g • a = b` and `g • c = d`.
* `MulAction.isPreprimitive_of_is_two_pretransitive` :
A 2-transitive action is preprimitive
* `MulAction.isMultiplyPretransitive_of_le` :
If an action is `n`-pretransitive, then it is `m`-pretransitive for all `m ≤ n`,
provided `α` has at least `n` elements.
## Remarks on implementation
These results are results about actions on types `n ↪ α` induced by an action
on `α`, and some results are developed in this context.
-/
open MulAction MulActionHom Function.Embedding Fin Set Nat
section Functoriality
variable {G α : Type*} [Group G] [MulAction G α]
variable {H β : Type*} [Group H] [MulAction H β]
variable {σ : G → H} {f : α →ₑ[σ] β} {ι : Type*}
variable (ι) in
/-- An injective equivariant map `α →ₑ[σ] β` induces
an equivariant map on embedding types `(ι ↪ α) → (ι ↪ β)`. -/
@[to_additive "An injective equivariant map `α →ₑ[σ] β` induces
an equivariant map on embedding types `(ι ↪ α) → (ι ↪ β)`."]
def Function.Injective.mulActionHom_embedding (hf : Function.Injective f) :
(ι ↪ α) →ₑ[σ] (ι ↪ β) where
toFun x := ⟨f.toFun ∘ x.toFun, hf.comp x.inj'⟩
map_smul' m x := by ext; simp [f.map_smul']
@[to_additive (attr := simp)]
theorem Function.Injective.mulActionHom_embedding_apply
(hf : Function.Injective f) {x : ι ↪ α} {i : ι} :
hf.mulActionHom_embedding ι x i = f (x i) := rfl
@[to_additive]
theorem Function.Injective.mulActionHom_embedding_isInjective
(hf : Function.Injective f) :
Function.Injective (hf.mulActionHom_embedding ι) := by
intro _ _ hxy
ext
apply hf
simp only [← hf.mulActionHom_embedding_apply, hxy]
variable (hf' : Function.Bijective f)
@[to_additive]
theorem Function.Bijective.mulActionHom_embedding_isBijective (hf : Function.Bijective f) :
Function.Bijective (hf.injective.mulActionHom_embedding ι) := by
refine ⟨hf.injective.mulActionHom_embedding_isInjective, ?_⟩
intro y
obtain ⟨g, _, hfg⟩ := Function.bijective_iff_has_inverse.mp hf
use ⟨g ∘ y, hfg.injective.comp (EmbeddingLike.injective y)⟩
ext
simp only [hf.injective.mulActionHom_embedding_apply, coeFn_mk, comp_apply]
exact hfg (y _)
end Functoriality
namespace MulAction
open scoped BigOperators Pointwise Cardinal
variable (G α : Type*) [Group G] [MulAction G α]
/-- An action of a group on a type `α` is `n`-pretransitive
if the associated action on `Fin n ↪ α` is pretransitive. -/
@[to_additive "An additive action of an additive group on a type `α`
is `n`-pretransitive if the associated action on `Fin n ↪ α` is pretransitive."]
abbrev IsMultiplyPretransitive (n : ℕ) := IsPretransitive G (Fin n ↪ α)
variable {G H α β : Type*} [Group G] [MulAction G α] [Group H] [MulAction H β]
{σ : G → H} {f : α →ₑ[σ] β} (hf : Function.Injective f)
/- If there exists a surjective equivariant map `α →ₑ[σ] β`
then pretransitivity descends from `n ↪ α` to `n ↪ β`.
The subtlety is that if it is not injective, this map does not induce
an equivariant map from `n ↪ α` to `n ↪ β`. -/
@[to_additive]
theorem IsPretransitive.of_embedding {n : Type*}
(hf : Function.Surjective f) [IsPretransitive G (n ↪ α)] :
IsPretransitive H (n ↪ β) where
exists_smul_eq x y := by
let aux (x : n ↪ β) : (n ↪ α) :=
x.trans (Function.Embedding.ofSurjective (⇑f) hf)
have aux_apply (x : n ↪ β) (i : n) : f.toFun (aux x i) = x i := by
simp only [trans_apply, aux]
apply Function.surjInv_eq
obtain ⟨g, hg⟩ := exists_smul_eq (M := G) (aux x) (aux y)
use σ g
ext i
rw [DFunLike.ext_iff] at hg
rw [smul_apply]
simp [← aux_apply, ← hg, MulActionHom.map_smul']
@[to_additive]
theorem IsPretransitive.of_embedding_congr {n : Type*}
(hσ : Function.Surjective σ) (hf : Function.Bijective f) :
IsPretransitive G (n ↪ α) ↔ IsPretransitive H (n ↪ β) :=
isPretransitive_congr hσ hf.mulActionHom_embedding_isBijective
section Zero
/-- Any action is 0-pretransitive. -/
@[to_additive]
theorem is_zero_pretransitive {n : Type*} [IsEmpty n] :
IsPretransitive G (n ↪ α) := inferInstance
/-- Any action is 0-pretransitive. -/
@[to_additive]
theorem is_zero_pretransitive' :
IsMultiplyPretransitive G α 0 := inferInstance
end Zero
section One
variable {one : Type*} [Unique one]
/-- For `Unique one`, the equivariant map from `one ↪ α` to `α`. -/
@[to_additive "For `Unique one`, the equivariant map from `one ↪ α` to `α`"]
def _root_.MulActionHom.oneEmbeddingMap :
(one ↪ α) →[G] α := {
oneEmbeddingEquiv with
map_smul' _ _ := rfl }
@[to_additive]
theorem _root_.MulActionHom.oneEmbeddingMap_bijective :
Function.Bijective (oneEmbeddingMap (one := one) (G := G) (α := α)) :=
oneEmbeddingEquiv.bijective
/-- An action is `1`-pretransitive iff it is pretransitive. -/
@[to_additive "An additive action is `1`-pretransitive iff it is pretransitive."]
theorem oneEmbedding_isPretransitive_iff :
IsPretransitive G (one ↪ α) ↔ IsPretransitive G α :=
isPretransitive_congr Function.surjective_id oneEmbeddingMap_bijective
/-- An action is `1`-pretransitive iff it is pretransitive. -/
@[to_additive "An additive action is `1`-pretransitive iff it is pretransitive."]
theorem is_one_pretransitive_iff :
IsMultiplyPretransitive G α 1 ↔ IsPretransitive G α :=
oneEmbedding_isPretransitive_iff
end One
section Two
/-- An action is `2`-pretransitive iff
it can move any two distinct elements to any two distinct elements. -/
@[to_additive "An additive action is `2`-pretransitive iff
it can move any two distinct elements to any two distinct elements."]
theorem is_two_pretransitive_iff :
IsMultiplyPretransitive G α 2 ↔
∀ {a b c d : α} (_ : a ≠ b) (_ : c ≠ d), ∃ g : G, g • a = c ∧ g • b = d := by
constructor
· intro _ a b c d h h'
obtain ⟨m, e⟩ := exists_smul_eq (M := G) (embFinTwo h) (embFinTwo h')
exact ⟨m,
by rw [← embFinTwo_apply_zero h, ← smul_apply, e, embFinTwo_apply_zero],
by rw [← embFinTwo_apply_one h, ← smul_apply, e, embFinTwo_apply_one]⟩
· intro H
constructor
intro j j'
obtain ⟨g, h, h'⟩ :=
H (j.injective.ne_iff.mpr Fin.zero_ne_one) (j'.injective.ne_iff.mpr Fin.zero_ne_one)
use g
ext i
by_cases hi : i = 0
· simp [hi, h]
· simp [eq_one_of_ne_zero i hi, h']
/-- A `2`-pretransitive action is pretransitive. -/
@[to_additive "A `2`-pretransitive additive action is pretransitive."]
theorem isPretransitive_of_is_two_pretransitive
[h2 : IsMultiplyPretransitive G α 2] : IsPretransitive G α where
exists_smul_eq a b := by
by_cases h : a = b
· exact ⟨1, by simp [h]⟩
· rw [is_two_pretransitive_iff] at h2
obtain ⟨g, h, _⟩ := h2 h (Ne.symm h)
exact ⟨g, h⟩
/-- A `2`-transitive action is primitive. -/
@[to_additive "A `2`-transitive additive action is primitive."]
theorem isPreprimitive_of_is_two_pretransitive
(h2 : IsMultiplyPretransitive G α 2) : IsPreprimitive G α := by
have : IsPretransitive G α := isPretransitive_of_is_two_pretransitive
apply IsPreprimitive.mk
intro B hB
rcases B.subsingleton_or_nontrivial with h | h
· left
exact h
· right
obtain ⟨a, ha, b, hb, h⟩ := h
rw [← top_eq_univ, eq_top_iff]
intro c _
by_cases h' : a = c
· rw [← h']; exact ha
· rw [is_two_pretransitive_iff] at h2
obtain ⟨g, hga, hgb⟩ := h2 h h'
rw [MulAction.isBlock_iff_smul_eq_of_mem] at hB
rw [← hB (g := g) ha (by rw [hga]; exact ha), ← hgb]
exact smul_mem_smul_set hb
end Two
section Higher
variable (G α) in
/-- The natural equivariant map from `n ↪ α` to `m ↪ α` given by an embedding
`e : m ↪ n`. -/
@[to_additive
"The natural equivariant map from `n ↪ α` to `m ↪ α` given by an embedding `e : m ↪ n`."]
def _root_.MulActionHom.embMap {m n : Type*} (e : m ↪ n) :
(n ↪ α) →[G] (m ↪ α) where
toFun i := e.trans i
map_smul' _ _ := rfl
/-- If `α` has at least `n` elements, then any `n`-pretransitive action on `α`
is `m`-pretransitive for any `m ≤ n`.
This version allows `α` to be infinite and uses `ENat.card`.
For `Finite α`, use `MulAction.isMultiplyPretransitive_of_le` -/
@[to_additive
"If `α` has at least `n` elements, then any `n`-pretransitive action on `α`
is `n`-pretransitive for any `m ≤ n`.
This version allows `α` to be infinite and uses `ENat.card`.
For `Finite α`, use `AddAction.isMultiplyPretransitive_of_le`."]
theorem isMultiplyPretransitive_of_le' {m n : ℕ} [IsMultiplyPretransitive G α n]
(hmn : m ≤ n) (hα : n ≤ ENat.card α) :
IsMultiplyPretransitive G α m := by
obtain ⟨p, rfl⟩ := Nat.exists_eq_add_of_le hmn
exact IsPretransitive.of_surjective_map
(f := embMap G α (castAddEmb p))
(Fin.Embedding.restrictSurjective_of_add_le_ENatCard hα) inferInstance
/-- If `α` has at least `n` elements, then an `n`-pretransitive action
is `m`-pretransitive for any `m ≤ n`.
For an infinite `α`, use `MulAction.isMultiplyPretransitive_of_le'`. -/
@[to_additive
"If `α` has at least `n` elements, then an `n`-pretransitive action
is `m`-pretransitive for any `m ≤ n`.
For an infinite `α`, use `MulAction.isMultiplyPretransitive_of_le'`."]
theorem isMultiplyPretransitive_of_le {m n : ℕ} [IsMultiplyPretransitive G α n]
(hmn : m ≤ n) (hα : n ≤ Nat.card α) [Finite α] :
IsMultiplyPretransitive G α m := by
obtain ⟨p, rfl⟩ := Nat.exists_eq_add_of_le hmn
exact IsPretransitive.of_surjective_map (f := embMap G α (castAddEmb p))
(Fin.Embedding.restrictSurjective_of_add_le_natCard hα) inferInstance
end Higher
end MulAction