Sorting algorithms on lists #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
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
#
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
Instances for list.sorted
Equations
A tuple is monotone if and only if the list obtained from it is sorted.
Insertion sort #
ordered_insert a l
inserts a
into l
at such that
ordered_insert a l
is sorted if l
is.
Equations
- list.ordered_insert r a (b :: l) = ite (r a b) (a :: b :: l) (b :: list.ordered_insert r a l)
- list.ordered_insert r a list.nil = [a]
insertion_sort l
returns l
sorted using the insertion sort algorithm.
Equations
- list.insertion_sort r (b :: l) = list.ordered_insert r b (list.insertion_sort r l)
- list.insertion_sort r list.nil = list.nil
An alternative definition of ordered_insert
using take_while
and drop_while
.
If l
is already list.sorted
with respect to r
, then insertion_sort
does not change
it.
The list list.insertion_sort r l
is list.sorted
with respect to r
.
Merge sort #
Split l
into two lists of approximately equal length.
split [1, 2, 3, 4, 5] = ([1, 3, 5], [2, 4])
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
- list.merge r (a :: l) (b :: l') = ite (r a b) (a :: list.merge r l (b :: l')) (b :: list.merge r (a :: l) l')
- list.merge r (hd :: tl) list.nil = hd :: tl
- list.merge r list.nil (hd :: tl) = hd :: tl
- list.merge r list.nil list.nil = list.nil
Implementation of a merge sort algorithm to sort a list.
Equations
- list.merge_sort r (a :: b :: l) = (λ (_x : list α × list α) (e : (a :: b :: l).split = _x), _x.cases_on (λ (l₁ l₂ : list α) (e : (a :: b :: l).split = (l₁, l₂)), _.dcases_on (λ (h₁ : l₁.length < (a :: b :: l).length) (h₂ : l₂.length < (a :: b :: l).length), list.merge r (list.merge_sort r l₁) (list.merge_sort r l₂))) e) (a :: b :: l).split _
- list.merge_sort r [a] = [a]
- list.merge_sort r list.nil = list.nil