mathlib documentation

data.list.sort

Sorting algorithms on lists #

In this file we define list.sorted r l to be an alias for pairwise r l. This alias is preferred in the case that r is a < or -like relation. Then we define two sorting algorithms: list.insertion_sort and list.merge_sort, and prove their correctness.

The predicate list.sorted #

def list.sorted {α : Type u_1} (R : α → α → Prop) :
list α → Prop

sorted r l is the same as pairwise r l, preferred in the case that r is a < or -like relation (transitive and antisymmetric or asymmetric)

Equations
@[protected, instance]
def list.decidable_sorted {α : Type uu} {r : α → α → Prop} [decidable_rel r] (l : list α) :
Equations
@[simp]
theorem list.sorted_nil {α : Type uu} {r : α → α → Prop} :
theorem list.sorted.of_cons {α : Type uu} {r : α → α → Prop} {a : α} {l : list α} :
list.sorted r (a :: l)list.sorted r l
theorem list.sorted.tail {α : Type uu} {r : α → α → Prop} {l : list α} (h : list.sorted r l) :
theorem list.rel_of_sorted_cons {α : Type uu} {r : α → α → Prop} {a : α} {l : list α} :
list.sorted r (a :: l)∀ (b : α), b lr a b
@[simp]
theorem list.sorted_cons {α : Type uu} {r : α → α → Prop} {a : α} {l : list α} :
list.sorted r (a :: l) (∀ (b : α), b lr a b) list.sorted r l
@[protected]
theorem list.sorted.nodup {α : Type uu} {r : α → α → Prop} [is_irrefl α r] {l : list α} (h : list.sorted r l) :
theorem list.eq_of_perm_of_sorted {α : Type uu} {r : α → α → Prop} [is_antisymm α r] {l₁ l₂ : list α} (p : l₁ ~ l₂) (s₁ : list.sorted r l₁) (s₂ : list.sorted r l₂) :
l₁ = l₂
theorem list.sublist_of_subperm_of_sorted {α : Type uu} {r : α → α → Prop} [is_antisymm α r] {l₁ l₂ : list α} (p : l₁ <+~ l₂) (s₁ : list.sorted r l₁) (s₂ : list.sorted r l₂) :
l₁ <+ l₂
@[simp]
theorem list.sorted_singleton {α : Type uu} {r : α → α → Prop} (a : α) :
theorem list.sorted.rel_nth_le_of_lt {α : Type uu} {r : α → α → Prop} {l : list α} (h : list.sorted r l) {a b : } (ha : a < l.length) (hb : b < l.length) (hab : a < b) :
r (l.nth_le a ha) (l.nth_le b hb)
theorem list.sorted.rel_nth_le_of_le {α : Type uu} {r : α → α → Prop} [is_refl α r] {l : list α} (h : list.sorted r l) {a b : } (ha : a < l.length) (hb : b < l.length) (hab : a b) :
r (l.nth_le a ha) (l.nth_le b hb)
theorem list.sorted.rel_of_mem_take_of_mem_drop {α : Type uu} {r : α → α → Prop} {l : list α} (h : list.sorted r l) {k : } {x y : α} (hx : x list.take k l) (hy : y list.drop k l) :
r x y

Insertion sort #

@[simp]
def list.ordered_insert {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) :
list αlist α

ordered_insert a l inserts a into l at such that ordered_insert a l is sorted if l is.

Equations
@[simp]
def list.insertion_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] :
list αlist α

insertion_sort l returns l sorted using the insertion sort algorithm.

Equations
@[simp]
theorem list.ordered_insert_nil {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) :
theorem list.ordered_insert_length {α : Type uu} (r : α → α → Prop) [decidable_rel r] (L : list α) (a : α) :
theorem list.ordered_insert_eq_take_drop {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) (l : list α) :
list.ordered_insert r a l = list.take_while (λ (b : α), ¬r a b) l ++ a :: list.drop_while (λ (b : α), ¬r a b) l

An alternative definition of ordered_insert using take_while and drop_while.

theorem list.insertion_sort_cons_eq_take_drop {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) (l : list α) :
list.insertion_sort r (a :: l) = list.take_while (λ (b : α), ¬r a b) (list.insertion_sort r l) ++ a :: list.drop_while (λ (b : α), ¬r a b) (list.insertion_sort r l)
theorem list.perm_ordered_insert {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) (l : list α) :
theorem list.ordered_insert_count {α : Type uu} (r : α → α → Prop) [decidable_rel r] [decidable_eq α] (L : list α) (a b : α) :
list.count a (list.ordered_insert r b L) = list.count a L + ite (a = b) 1 0
theorem list.perm_insertion_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] (l : list α) :
theorem list.sorted.insertion_sort_eq {α : Type uu} {r : α → α → Prop} [decidable_rel r] {l : list α} (h : list.sorted r l) :

If l is already list.sorted with respect to r, then insertion_sort does not change it.

theorem list.sorted.ordered_insert {α : Type uu} {r : α → α → Prop} [decidable_rel r] [is_total α r] [is_trans α r] (a : α) (l : list α) :
theorem list.sorted_insertion_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] [is_total α r] [is_trans α r] (l : list α) :

The list list.insertion_sort r l is list.sorted with respect to r.

Merge sort #

@[simp]
def list.split {α : Type uu} :
list αlist α × list α

Split l into two lists of approximately equal length.

split [1, 2, 3, 4, 5] = ([1, 3, 5], [2, 4])
Equations
theorem list.split_cons_of_eq {α : Type uu} (a : α) {l l₁ l₂ : list α} (h : l.split = (l₁, l₂)) :
(a :: l).split = (a :: l₂, l₁)
theorem list.length_split_le {α : Type uu} {l l₁ l₂ : list α} :
l.split = (l₁, l₂)l₁.length l.length l₂.length l.length
theorem list.length_split_lt {α : Type uu} {a b : α} {l l₁ l₂ : list α} (h : (a :: b :: l).split = (l₁, l₂)) :
l₁.length < (a :: b :: l).length l₂.length < (a :: b :: l).length
theorem list.perm_split {α : Type uu} {l l₁ l₂ : list α} :
l.split = (l₁, l₂)l ~ l₁ ++ l₂
def list.merge {α : Type uu} (r : α → α → Prop) [decidable_rel r] :
list αlist αlist α

Merge two sorted lists into one in linear time.

merge [1, 2, 4, 5] [0, 1, 3, 4] = [0, 1, 1, 2, 3, 4, 4, 5]
Equations
def list.merge_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] :
list αlist α

Implementation of a merge sort algorithm to sort a list.

Equations
theorem list.merge_sort_cons_cons {α : Type uu} (r : α → α → Prop) [decidable_rel r] {a b : α} {l l₁ l₂ : list α} (h : (a :: b :: l).split = (l₁, l₂)) :
theorem list.perm_merge {α : Type uu} (r : α → α → Prop) [decidable_rel r] (l l' : list α) :
list.merge r l l' ~ l ++ l'
theorem list.perm_merge_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] (l : list α) :
@[simp]
theorem list.length_merge_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] (l : list α) :
theorem list.sorted.merge {α : Type uu} {r : α → α → Prop} [decidable_rel r] [is_total α r] [is_trans α r] {l l' : list α} :
list.sorted r llist.sorted r l'list.sorted r (list.merge r l l')
theorem list.sorted_merge_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] [is_total α r] [is_trans α r] (l : list α) :
theorem list.merge_sort_eq_self {α : Type uu} (r : α → α → Prop) [decidable_rel r] [is_total α r] [is_trans α r] [is_antisymm α r] {l : list α} :
theorem list.merge_sort_eq_insertion_sort {α : Type uu} (r : α → α → Prop) [decidable_rel r] [is_total α r] [is_trans α r] [is_antisymm α r] (l : list α) :
@[simp]
theorem list.merge_sort_nil {α : Type uu} (r : α → α → Prop) [decidable_rel r] :
@[simp]
theorem list.merge_sort_singleton {α : Type uu} (r : α → α → Prop) [decidable_rel r] (a : α) :
list.merge_sort r [a] = [a]