Module docstring
{"# Construct a sorted list from a finset. ","### sort "}
{"# Construct a sorted list from a finset. ","### sort "}
Finset.sort
definition
(s : Finset α) : List α
/-- `sort s` constructs a sorted list from the unordered set `s`.
(Uses merge sort algorithm.) -/
def sort (s : Finset α) : List α :=
Multiset.sort r s.1
Finset.sort_val
theorem
(s : Finset α) : Multiset.sort r s.val = sort r s
Finset.sort_mk
theorem
{s : Multiset α} (h : s.Nodup) : sort r ⟨s, h⟩ = s.sort r
Finset.sort_sorted
theorem
(s : Finset α) : List.Sorted r (sort r s)
@[simp]
theorem sort_sorted (s : Finset α) : List.Sorted r (sort r s) :=
Multiset.sort_sorted _ _
Finset.sort_eq
theorem
(s : Finset α) : ↑(sort r s) = s.1
@[simp]
theorem sort_eq (s : Finset α) : ↑(sort r s) = s.1 :=
Multiset.sort_eq _ _
Finset.sort_nodup
theorem
(s : Finset α) : (sort r s).Nodup
Finset.sort_toFinset
theorem
[DecidableEq α] (s : Finset α) : (sort r s).toFinset = s
@[simp]
theorem sort_toFinset [DecidableEq α] (s : Finset α) : (sort r s).toFinset = s :=
List.toFinset_eq (sort_nodup r s) ▸ eq_of_veq (sort_eq r s)
Finset.mem_sort
theorem
{s : Finset α} {a : α} : a ∈ sort r s ↔ a ∈ s
@[simp]
theorem mem_sort {s : Finset α} {a : α} : a ∈ sort r sa ∈ sort r s ↔ a ∈ s :=
Multiset.mem_sort _
Finset.length_sort
theorem
{s : Finset α} : (sort r s).length = s.card
@[simp]
theorem length_sort {s : Finset α} : (sort r s).length = s.card :=
Multiset.length_sort _
Finset.sort_empty
theorem
: sort r ∅ = []
@[simp]
theorem sort_empty : sort r ∅ = [] :=
Multiset.sort_zero r
Finset.sort_singleton
theorem
(a : α) : sort r { a } = [a]
@[simp]
theorem sort_singleton (a : α) : sort r {a} = [a] :=
Multiset.sort_singleton r a
Finset.sort_cons
theorem
{a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) : sort r (cons a s h₂) = a :: sort r s
theorem sort_cons {a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) :
sort r (cons a s h₂) = a :: sort r s := by
rw [sort, cons_val, Multiset.sort_cons r a _ h₁, sort_val]
Finset.sort_insert
theorem
[DecidableEq α] {a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) : sort r (insert a s) = a :: sort r s
theorem sort_insert [DecidableEq α] {a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) :
sort r (insert a s) = a :: sort r s := by
rw [← cons_eq_insert _ _ h₂, sort_cons r h₁]
Finset.sort_range
theorem
(n : ℕ) : sort (· ≤ ·) (range n) = List.range n
@[simp]
theorem sort_range (n : ℕ) : sort (· ≤ ·) (range n) = List.range n :=
Multiset.sort_range n
Finset.sort_perm_toList
theorem
(s : Finset α) : sort r s ~ s.toList
theorem sort_perm_toList (s : Finset α) : sortsort r s ~ s.toList := by
rw [← Multiset.coe_eq_coe]
simp only [coe_toList, sort_eq]
List.toFinset_sort
theorem
[DecidableEq α] {l : List α} (hl : l.Nodup) : sort r l.toFinset = l ↔ l.Sorted r
theorem _root_.List.toFinset_sort [DecidableEq α] {l : List α} (hl : l.Nodup) :
sortsort r l.toFinset = l ↔ l.Sorted r := by
refine ⟨?_, List.eq_of_perm_of_sorted ((sort_perm_toList r _).trans (List.toFinset_toList hl))
(sort_sorted r _)⟩
intro h
rw [← h]
exact sort_sorted r _
Finset.sort_sorted_lt
theorem
(s : Finset α) : List.Sorted (· < ·) (sort (· ≤ ·) s)
theorem sort_sorted_lt (s : Finset α) : List.Sorted (· < ·) (sort (· ≤ ·) s) :=
(sort_sorted _ _).lt_of_le (sort_nodup _ _)
Finset.sort_sorted_gt
theorem
(s : Finset α) : List.Sorted (· > ·) (sort (· ≥ ·) s)
theorem sort_sorted_gt (s : Finset α) : List.Sorted (· > ·) (sort (· ≥ ·) s) :=
(sort_sorted _ _).gt_of_ge (sort_nodup _ _)
Finset.sorted_zero_eq_min'_aux
theorem
(s : Finset α) (h : 0 < (s.sort (· ≤ ·)).length) (H : s.Nonempty) : (s.sort (· ≤ ·)).get ⟨0, h⟩ = s.min' H
theorem sorted_zero_eq_min'_aux (s : Finset α) (h : 0 < (s.sort (· ≤ ·)).length) (H : s.Nonempty) :
(s.sort (· ≤ ·)).get ⟨0, h⟩ = s.min' H := by
let l := s.sort (· ≤ ·)
apply le_antisymm
· have : s.min' H ∈ l := (Finset.mem_sort (α := α) (· ≤ ·)).mpr (s.min'_mem H)
obtain ⟨i, hi⟩ : ∃ i, l.get i = s.min' H := List.mem_iff_get.1 this
rw [← hi]
exact (s.sort_sorted (· ≤ ·)).rel_get_of_le (Nat.zero_le i)
· have : l.get ⟨0, h⟩ ∈ s := (Finset.mem_sort (α := α) (· ≤ ·)).1 (List.get_mem l _)
exact s.min'_le _ this
Finset.sorted_zero_eq_min'
theorem
{s : Finset α} {h : 0 < (s.sort (· ≤ ·)).length} :
(s.sort (· ≤ ·))[0] = s.min' (card_pos.1 <| by rwa [length_sort] at h)
theorem sorted_zero_eq_min' {s : Finset α} {h : 0 < (s.sort (· ≤ ·)).length} :
(s.sort (· ≤ ·))[0] = s.min' (card_pos.1 <| by rwa [length_sort] at h) :=
sorted_zero_eq_min'_aux _ _ _
Finset.min'_eq_sorted_zero
theorem
{s : Finset α} {h : s.Nonempty} : s.min' h = (s.sort (· ≤ ·))[0]'(by rw [length_sort]; exact card_pos.2 h)
theorem min'_eq_sorted_zero {s : Finset α} {h : s.Nonempty} :
s.min' h = (s.sort (· ≤ ·))[0]'(by rw [length_sort]; exact card_pos.2 h) :=
(sorted_zero_eq_min'_aux _ _ _).symm
Finset.sorted_last_eq_max'_aux
theorem
(s : Finset α) (h : (s.sort (· ≤ ·)).length - 1 < (s.sort (· ≤ ·)).length) (H : s.Nonempty) :
(s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1] = s.max' H
theorem sorted_last_eq_max'_aux (s : Finset α)
(h : (s.sort (· ≤ ·)).length - 1 < (s.sort (· ≤ ·)).length) (H : s.Nonempty) :
(s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1] = s.max' H := by
let l := s.sort (· ≤ ·)
apply le_antisymm
· have : l.get ⟨(s.sort (· ≤ ·)).length - 1, h⟩ ∈ s :=
(Finset.mem_sort (α := α) (· ≤ ·)).1 (List.get_mem l _)
exact s.le_max' _ this
· have : s.max' H ∈ l := (Finset.mem_sort (α := α) (· ≤ ·)).mpr (s.max'_mem H)
obtain ⟨i, hi⟩ : ∃ i, l.get i = s.max' H := List.mem_iff_get.1 this
rw [← hi]
exact (s.sort_sorted (· ≤ ·)).rel_get_of_le (Nat.le_sub_one_of_lt i.prop)
Finset.sorted_last_eq_max'
theorem
{s : Finset α} {h : (s.sort (· ≤ ·)).length - 1 < (s.sort (· ≤ ·)).length} :
(s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1] =
s.max' (by rw [length_sort] at h; exact card_pos.1 (lt_of_le_of_lt bot_le h))
theorem sorted_last_eq_max' {s : Finset α}
{h : (s.sort (· ≤ ·)).length - 1 < (s.sort (· ≤ ·)).length} :
(s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1] =
s.max' (by rw [length_sort] at h; exact card_pos.1 (lt_of_le_of_lt bot_le h)) :=
sorted_last_eq_max'_aux _ h _
Finset.max'_eq_sorted_last
theorem
{s : Finset α} {h : s.Nonempty} :
s.max' h = (s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1]'(by simpa using Nat.sub_lt (card_pos.mpr h) Nat.zero_lt_one)
theorem max'_eq_sorted_last {s : Finset α} {h : s.Nonempty} :
s.max' h =
(s.sort (· ≤ ·))[(s.sort (· ≤ ·)).length - 1]'
(by simpa using Nat.sub_lt (card_pos.mpr h) Nat.zero_lt_one) :=
(sorted_last_eq_max'_aux _ (by simpa using Nat.sub_lt (card_pos.mpr h) Nat.zero_lt_one) _).symm
Finset.orderIsoOfFin
definition
(s : Finset α) {k : ℕ} (h : s.card = k) : Fin k ≃o s
/-- Given a finset `s` of cardinality `k` in a linear order `α`, the map `orderIsoOfFin s h`
is the increasing bijection between `Fin k` and `s` as an `OrderIso`. Here, `h` is a proof that
the cardinality of `s` is `k`. We use this instead of an iso `Fin s.card ≃o s` to avoid
casting issues in further uses of this function. -/
def orderIsoOfFin (s : Finset α) {k : ℕ} (h : s.card = k) : FinFin k ≃o s :=
OrderIso.trans (Fin.castOrderIso ((length_sort (α := α) (· ≤ ·)).trans h).symm) <|
(s.sort_sorted_lt.getIso _).trans <| OrderIso.setCongr _ _ <| Set.ext fun _ => mem_sort _
Finset.orderEmbOfFin
definition
(s : Finset α) {k : ℕ} (h : s.card = k) : Fin k ↪o α
/-- Given a finset `s` of cardinality `k` in a linear order `α`, the map `orderEmbOfFin s h` is
the increasing bijection between `Fin k` and `s` as an order embedding into `α`. Here, `h` is a
proof that the cardinality of `s` is `k`. We use this instead of an embedding `Fin s.card ↪o α` to
avoid casting issues in further uses of this function. -/
def orderEmbOfFin (s : Finset α) {k : ℕ} (h : s.card = k) : FinFin k ↪o α :=
(orderIsoOfFin s h).toOrderEmbedding.trans (OrderEmbedding.subtype _)
Finset.coe_orderIsoOfFin_apply
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) : ↑(orderIsoOfFin s h i) = orderEmbOfFin s h i
@[simp]
theorem coe_orderIsoOfFin_apply (s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) :
↑(orderIsoOfFin s h i) = orderEmbOfFin s h i :=
rfl
Finset.orderIsoOfFin_symm_apply
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) (x : s) : ↑((s.orderIsoOfFin h).symm x) = (s.sort (· ≤ ·)).idxOf ↑x
theorem orderIsoOfFin_symm_apply (s : Finset α) {k : ℕ} (h : s.card = k) (x : s) :
↑((s.orderIsoOfFin h).symm x) = (s.sort (· ≤ ·)).idxOf ↑x :=
rfl
Finset.orderEmbOfFin_apply
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) :
s.orderEmbOfFin h i = (s.sort (· ≤ ·))[i]'(by rw [length_sort, h]; exact i.2)
theorem orderEmbOfFin_apply (s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) :
s.orderEmbOfFin h i = (s.sort (· ≤ ·))[i]'(by rw [length_sort, h]; exact i.2) :=
rfl
Finset.orderEmbOfFin_mem
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) : s.orderEmbOfFin h i ∈ s
@[simp]
theorem orderEmbOfFin_mem (s : Finset α) {k : ℕ} (h : s.card = k) (i : Fin k) :
s.orderEmbOfFin h i ∈ s :=
(s.orderIsoOfFin h i).2
Finset.range_orderEmbOfFin
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) : Set.range (s.orderEmbOfFin h) = s
@[simp]
theorem range_orderEmbOfFin (s : Finset α) {k : ℕ} (h : s.card = k) :
Set.range (s.orderEmbOfFin h) = s := by
simp only [orderEmbOfFin, Set.range_comp ((↑) : _ → α) (s.orderIsoOfFin h),
RelEmbedding.coe_trans, Set.image_univ, Finset.orderEmbOfFin, RelIso.range_eq,
OrderEmbedding.coe_subtype, OrderIso.coe_toOrderEmbedding, eq_self_iff_true,
Subtype.range_coe_subtype, Finset.setOf_mem, Finset.coe_inj]
Finset.image_orderEmbOfFin_univ
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) : Finset.image (s.orderEmbOfFin h) Finset.univ = s
@[simp]
theorem image_orderEmbOfFin_univ (s : Finset α) {k : ℕ} (h : s.card = k) :
Finset.image (s.orderEmbOfFin h) Finset.univ = s := by
apply Finset.coe_injective
simp
Finset.map_orderEmbOfFin_univ
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) : Finset.map (s.orderEmbOfFin h).toEmbedding Finset.univ = s
@[simp]
theorem map_orderEmbOfFin_univ (s : Finset α) {k : ℕ} (h : s.card = k) :
Finset.map (s.orderEmbOfFin h).toEmbedding Finset.univ = s := by
simp [map_eq_image]
Finset.listMap_orderEmbOfFin_finRange
theorem
(s : Finset α) {k : ℕ} (h : s.card = k) : (List.finRange k).map (s.orderEmbOfFin h) = s.sort (· ≤ ·)
@[simp]
theorem listMap_orderEmbOfFin_finRange (s : Finset α) {k : ℕ} (h : s.card = k) :
(List.finRange k).map (s.orderEmbOfFin h) = s.sort (· ≤ ·) := by
obtain rfl : k = (s.sort (· ≤ ·)).length := by simp [h]
exact List.finRange_map_getElem (s.sort (· ≤ ·))
Finset.orderEmbOfFin_zero
theorem
{s : Finset α} {k : ℕ} (h : s.card = k) (hz : 0 < k) : orderEmbOfFin s h ⟨0, hz⟩ = s.min' (card_pos.mp (h.symm ▸ hz))
/-- The bijection `orderEmbOfFin s h` sends `0` to the minimum of `s`. -/
theorem orderEmbOfFin_zero {s : Finset α} {k : ℕ} (h : s.card = k) (hz : 0 < k) :
orderEmbOfFin s h ⟨0, hz⟩ = s.min' (card_pos.mp (h.symm ▸ hz)) := by
simp only [orderEmbOfFin_apply, Fin.getElem_fin, sorted_zero_eq_min']
Finset.orderEmbOfFin_last
theorem
{s : Finset α} {k : ℕ} (h : s.card = k) (hz : 0 < k) :
orderEmbOfFin s h ⟨k - 1, Nat.sub_lt hz (Nat.succ_pos 0)⟩ = s.max' (card_pos.mp (h.symm ▸ hz))
/-- The bijection `orderEmbOfFin s h` sends `k-1` to the maximum of `s`. -/
theorem orderEmbOfFin_last {s : Finset α} {k : ℕ} (h : s.card = k) (hz : 0 < k) :
orderEmbOfFin s h ⟨k - 1, Nat.sub_lt hz (Nat.succ_pos 0)⟩ =
s.max' (card_pos.mp (h.symm ▸ hz)) := by
simp [orderEmbOfFin_apply, max'_eq_sorted_last, h]
Finset.orderEmbOfFin_singleton
theorem
(a : α) (i : Fin 1) : orderEmbOfFin { a } (card_singleton a) i = a
/-- `orderEmbOfFin {a} h` sends any argument to `a`. -/
@[simp]
theorem orderEmbOfFin_singleton (a : α) (i : Fin 1) :
orderEmbOfFin {a} (card_singleton a) i = a := by
rw [Subsingleton.elim i ⟨0, Nat.zero_lt_one⟩, orderEmbOfFin_zero _ Nat.zero_lt_one,
min'_singleton]
Finset.orderEmbOfFin_unique
theorem
{s : Finset α} {k : ℕ} (h : s.card = k) {f : Fin k → α} (hfs : ∀ x, f x ∈ s) (hmono : StrictMono f) :
f = s.orderEmbOfFin h
/-- Any increasing map `f` from `Fin k` to a finset of cardinality `k` has to coincide with
the increasing bijection `orderEmbOfFin s h`. -/
theorem orderEmbOfFin_unique {s : Finset α} {k : ℕ} (h : s.card = k) {f : Fin k → α}
(hfs : ∀ x, f x ∈ s) (hmono : StrictMono f) : f = s.orderEmbOfFin h := by
rw [← hmono.range_inj (s.orderEmbOfFin h).strictMono, range_orderEmbOfFin, ← Set.image_univ,
← coe_univ, ← coe_image, coe_inj]
refine eq_of_subset_of_card_le (fun x hx => ?_) ?_
· rcases mem_image.1 hx with ⟨x, _, rfl⟩
exact hfs x
· rw [h, card_image_of_injective _ hmono.injective, card_univ, Fintype.card_fin]
Finset.orderEmbOfFin_unique'
theorem
{s : Finset α} {k : ℕ} (h : s.card = k) {f : Fin k ↪o α} (hfs : ∀ x, f x ∈ s) : f = s.orderEmbOfFin h
/-- An order embedding `f` from `Fin k` to a finset of cardinality `k` has to coincide with
the increasing bijection `orderEmbOfFin s h`. -/
theorem orderEmbOfFin_unique' {s : Finset α} {k : ℕ} (h : s.card = k) {f : FinFin k ↪o α}
(hfs : ∀ x, f x ∈ s) : f = s.orderEmbOfFin h :=
RelEmbedding.ext <| funext_iff.1 <| orderEmbOfFin_unique h hfs f.strictMono
Finset.orderEmbOfFin_eq_orderEmbOfFin_iff
theorem
{k l : ℕ} {s : Finset α} {i : Fin k} {j : Fin l} {h : s.card = k} {h' : s.card = l} :
s.orderEmbOfFin h i = s.orderEmbOfFin h' j ↔ (i : ℕ) = (j : ℕ)
/-- Two parametrizations `orderEmbOfFin` of the same set take the same value on `i` and `j` if
and only if `i = j`. Since they can be defined on a priori not defeq types `Fin k` and `Fin l`
(although necessarily `k = l`), the conclusion is rather written `(i : ℕ) = (j : ℕ)`. -/
@[simp]
theorem orderEmbOfFin_eq_orderEmbOfFin_iff {k l : ℕ} {s : Finset α} {i : Fin k} {j : Fin l}
{h : s.card = k} {h' : s.card = l} :
s.orderEmbOfFin h i = s.orderEmbOfFin h' j ↔ (i : ℕ) = (j : ℕ) := by
substs k l
exact (s.orderEmbOfFin rfl).eq_iff_eq.trans Fin.ext_iff
Finset.orderEmbOfCardLe
definition
(s : Finset α) {k : ℕ} (h : k ≤ s.card) : Fin k ↪o α
/-- Given a finset `s` of size at least `k` in a linear order `α`, the map `orderEmbOfCardLe`
is an order embedding from `Fin k` to `α` whose image is contained in `s`. Specifically, it maps
`Fin k` to an initial segment of `s`. -/
def orderEmbOfCardLe (s : Finset α) {k : ℕ} (h : k ≤ s.card) : FinFin k ↪o α :=
(Fin.castLEOrderEmb h).trans (s.orderEmbOfFin rfl)
Finset.orderEmbOfCardLe_mem
theorem
(s : Finset α) {k : ℕ} (h : k ≤ s.card) (a) : orderEmbOfCardLe s h a ∈ s
theorem orderEmbOfCardLe_mem (s : Finset α) {k : ℕ} (h : k ≤ s.card) (a) :
orderEmbOfCardLeorderEmbOfCardLe s h a ∈ s := by
simp only [orderEmbOfCardLe, RelEmbedding.coe_trans, Finset.orderEmbOfFin_mem,
Function.comp_apply]
Finset.instRepr
instance
[Repr α] : Repr (Finset α)
unsafe instance [Repr α] : Repr (Finset α) where
reprPrec s _ :=
-- multiset uses `0` not `∅` for empty sets
if s.card = 0 then "∅" else repr s.1
Fin.sort_univ
theorem
(n : ℕ) : Finset.univ.sort (fun x y : Fin n => x ≤ y) = List.finRange n
theorem sort_univ (n : ℕ) : Finset.univ.sort (fun x y : Fin n => x ≤ y) = List.finRange n :=
List.eq_of_perm_of_sorted
(List.perm_of_nodup_nodup_toFinset_eq
(Finset.univ.sort_nodup _) (List.nodup_finRange n) (by simp))
(Finset.univ.sort_sorted LE.le)
(List.pairwise_le_finRange n)
Fintype.orderIsoFinOfCardEq
definition
(α : Type*) [LinearOrder α] [Fintype α] {k : ℕ} (h : Fintype.card α = k) : Fin k ≃o α
/-- Given a `Fintype` `α` of cardinality `k`, the map `orderIsoFinOfCardEq s h` is the increasing
bijection between `Fin k` and `α` as an `OrderIso`. Here, `h` is a proof that the cardinality of `α`
is `k`. We use this instead of an iso `Fin (Fintype.card α) ≃o α` to avoid casting issues in further
uses of this function. -/
def Fintype.orderIsoFinOfCardEq
(α : Type*) [LinearOrder α] [Fintype α] {k : ℕ} (h : Fintype.card α = k) :
FinFin k ≃o α :=
(Finset.univ.orderIsoOfFin h).trans
((OrderIso.setCongr _ _ Finset.coe_univ).trans OrderIso.Set.univ)
nonempty_orderEmbedding_of_finite_infinite
theorem
(α : Type*) [LinearOrder α] [hα : Finite α] (β : Type*) [LinearOrder β] [hβ : Infinite β] : Nonempty (α ↪o β)
/-- Any finite linear order order-embeds into any infinite linear order. -/
lemma nonempty_orderEmbedding_of_finite_infinite
(α : Type*) [LinearOrder α] [hα : Finite α]
(β : Type*) [LinearOrder β] [hβ : Infinite β] : Nonempty (α ↪o β) := by
haveI := Fintype.ofFinite α
obtain ⟨s, hs⟩ := Infinite.exists_subset_card_eq β (Fintype.card α)
exact ⟨((Fintype.orderIsoFinOfCardEq α rfl).symm.toOrderEmbedding).trans (s.orderEmbOfFin hs)⟩