Defines `mergeSort`, a naive stable merge sort algorithm, replaces it via a `@[csimp]` lemma with something faster at runtime, and proves the following results: * `mergeSort_sorted`: `mergeSort` produces a sorted list. * `mergeSort_perm`: `mergeSort` is a permutation of the input list. * `mergeSort_of_sorted`: `mergeSort` does not change a sorted list. * `mergeSort_cons`: proves `mergeSort le (x :: xs) = l₁ ++ x :: l₂` for some `l₁, l₂` so that `mergeSort le xs = l₁ ++ l₂`, and no `a ∈ l₁` satisfies `le a x`. * `mergeSort_stable`: if `c` is a sorted sublist of `l`, then `c` is still a sublist of `mergeSort le l`.
18 lines
941 B
Text
18 lines
941 B
Text
open List.MergeSort.Internal
|
|
|
|
def main (args : List String) : IO Unit := do
|
|
let k := 5
|
|
let some arg := args[0]? | throw <| IO.userError s!"specify length of test data in multiples of 10^{k}"
|
|
let some i := arg.toNat? | throw <| IO.userError s!"specify length of test data in multiples of 10^{k}"
|
|
let n := i * (10^k)
|
|
let i₁ := List.iota n
|
|
let i₂ := List.range n
|
|
let i₃ ← (List.range n).mapM (fun _ => IO.rand 0 1000)
|
|
let i₄ := (List.range (i * (10^(k-3)))).bind (fun k => (k * 1000 + 1) :: (k * 1000) :: List.range' (k * 1000 + 2) 998)
|
|
let start ← IO.monoMsNow
|
|
let o₁ := (mergeSortTR₂ (· ≤ ·) i₁).length == n
|
|
let o₂ := (mergeSortTR₂ (· ≤ ·) i₂).length == n
|
|
let o₃ := (mergeSortTR₂ (· ≤ ·) i₃).length == n
|
|
let o₄ := (mergeSortTR₂ (· ≤ ·) i₄).length == n
|
|
IO.println (((← IO.monoMsNow) - start)/4)
|
|
IO.Process.exit (if o₁ && o₂ && o₃ && o₄ then 0 else 1)
|