28 lines
1 KiB
Text
28 lines
1 KiB
Text
/-
|
||
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import Init.Data.Array.Basic
|
||
|
||
@[inline] def Array.insertionSort (a : Array α) (lt : α → α → Bool) : Array α :=
|
||
traverse a 0 a.size
|
||
where
|
||
@[specialize] traverse (a : Array α) (i : Nat) (fuel : Nat) : Array α :=
|
||
match fuel with
|
||
| 0 => a
|
||
| fuel+1 =>
|
||
if h : i < a.size then
|
||
traverse (swapLoop a i h) (i+1) fuel
|
||
else
|
||
a
|
||
@[specialize] swapLoop (a : Array α) (j : Nat) (h : j < a.size) : Array α :=
|
||
match (generalizing := false) he:j with -- using `generalizing` because we don't want to refine the type of `h`
|
||
| 0 => a
|
||
| j'+1 =>
|
||
have h' : j' < a.size := by subst j; exact Nat.lt_trans (Nat.lt_succ_self _) h
|
||
if lt (a.get ⟨j, h⟩) (a.get ⟨j', h'⟩) then
|
||
swapLoop (a.swap ⟨j, h⟩ ⟨j', h'⟩) j' (by rw [size_swap]; assumption done)
|
||
else
|
||
a
|