Skip to content

Commit 99b8e71

Browse files
committed
feat(Data/*/Sort): lemmas on sorted lists (#16078)
The main thing we prove is that if `l` is a list, and `a` is smaller than all elements on it, then `sort r (a :: l) = a :: sort r l`.
1 parent 435c3d7 commit 99b8e71

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

Mathlib/Data/Finset/Basic.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,6 +2912,11 @@ theorem toList_toFinset [DecidableEq α] (s : Finset α) : s.toList.toFinset = s
29122912
ext
29132913
simp
29142914

2915+
theorem _root_.List.toFinset_toList [DecidableEq α] {s : List α} (hs : s.Nodup) :
2916+
s.toFinset.toList.Perm s := by
2917+
apply List.perm_of_nodup_nodup_toFinset_eq (nodup_toList _) hs
2918+
rw [toList_toFinset]
2919+
29152920
@[simp]
29162921
theorem toList_eq_singleton_iff {a : α} {s : Finset α} : s.toList = [a] ↔ s = {a} := by
29172922
rw [toList, Multiset.toList_eq_singleton_iff, val_eq_singleton_iff]

Mathlib/Data/Finset/Sort.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ variable (r : α → α → Prop) [DecidableRel r] [IsTrans α r] [IsAntisymm α
3232
def sort (s : Finset α) : List α :=
3333
Multiset.sort r s.1
3434

35+
@[simp]
36+
theorem sort_val (s : Finset α) : Multiset.sort r s.val = sort r s :=
37+
rfl
38+
3539
@[simp]
3640
theorem sort_sorted (s : Finset α) : List.Sorted r (sort r s) :=
3741
Multiset.sort_sorted _ _
@@ -64,11 +68,27 @@ theorem sort_empty : sort r ∅ = [] :=
6468
theorem sort_singleton (a : α) : sort r {a} = [a] :=
6569
Multiset.sort_singleton r a
6670

71+
theorem sort_cons {a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) :
72+
sort r (cons a s h₂) = a :: sort r s := by
73+
rw [sort, cons_val, Multiset.sort_cons r a _ h₁, sort_val]
74+
75+
theorem sort_insert [DecidableEq α] {a : α} {s : Finset α} (h₁ : ∀ b ∈ s, r a b) (h₂ : a ∉ s) :
76+
sort r (insert a s) = a :: sort r s := by
77+
rw [← cons_eq_insert _ _ h₂, sort_cons r h₁]
78+
6779
open scoped List in
6880
theorem sort_perm_toList (s : Finset α) : sort r s ~ s.toList := by
6981
rw [← Multiset.coe_eq_coe]
7082
simp only [coe_toList, sort_eq]
7183

84+
theorem _root_.List.toFinset_sort [DecidableEq α] {l : List α} (hl : l.Nodup) :
85+
sort r l.toFinset = l ↔ l.Sorted r := by
86+
refine ⟨?_, List.eq_of_perm_of_sorted ((sort_perm_toList r _).trans (List.toFinset_toList hl))
87+
(sort_sorted r _)⟩
88+
intro h
89+
rw [← h]
90+
exact sort_sorted r _
91+
7292
end sort
7393

7494
section SortLinearOrder

Mathlib/Data/List/Sort.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ def orderedInsert (a : α) : List α → List α
198198
| [] => [a]
199199
| b :: l => if a ≼ b then a :: b :: l else b :: orderedInsert a l
200200

201+
theorem orderedInsert_of_le {a b : α} (l : List α) (h : a ≼ b) :
202+
orderedInsert r a (b :: l) = a :: b :: l :=
203+
dif_pos h
204+
201205
/-- `insertionSort l` returns `l` sorted using the insertion sort algorithm. -/
202206
@[simp]
203207
def insertionSort : List α → List α
@@ -281,6 +285,17 @@ theorem mem_insertionSort {l : List α} {x : α} : x ∈ l.insertionSort r ↔ x
281285
theorem length_insertionSort (l : List α) : (insertionSort r l).length = l.length :=
282286
(perm_insertionSort r _).length_eq
283287

288+
theorem insertionSort_cons {a : α} {l : List α} (h : ∀ b ∈ l, r a b) :
289+
insertionSort r (a :: l) = a :: insertionSort r l := by
290+
rw [insertionSort]
291+
cases hi : insertionSort r l with
292+
| nil => rfl
293+
| cons b m =>
294+
rw [orderedInsert_of_le]
295+
apply h b <| (mem_insertionSort r).1 _
296+
rw [hi]
297+
exact mem_cons_self b m
298+
284299
theorem map_insertionSort (f : α → β) (l : List α) (hl : ∀ a ∈ l, ∀ b ∈ l, a ≼ b ↔ f a ≼ f b) :
285300
(l.insertionSort r).map f = (l.map f).insertionSort s := by
286301
induction l with

Mathlib/Data/Multiset/Sort.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ theorem map_sort (f : α → β) (s : Multiset α)
6262
revert s
6363
exact Quot.ind fun _ => List.map_mergeSort' _ _ _ _
6464

65+
theorem sort_cons (a : α) (s : Multiset α) :
66+
(∀ b ∈ s, r a b) → sort r (a ::ₘ s) = a :: sort r s := by
67+
refine Quot.inductionOn s fun l => ?_
68+
simpa [mergeSort'_eq_insertionSort] using insertionSort_cons r
69+
6570
end sort
6671

6772
-- TODO: use a sort order if available, gh-18166

0 commit comments

Comments
 (0)