{-# OPTIONS --rewriting #-}
open import Examples.Sorting.Sequential.Comparable
module Examples.Sorting.Sequential.InsertionSort (M : Comparable) where
open Comparable M
open import Examples.Sorting.Sequential.Core M
open import Calf costMonoid hiding (A)
open import Calf.Data.Bool using (bool)
open import Calf.Data.List
open import Calf.Data.Equality using (_≡_; refl)
open import Calf.Data.IsBoundedG costMonoid
open import Calf.Data.IsBounded costMonoid
open import Calf.Data.BigO costMonoid
open import Relation.Nullary
open import Relation.Nullary.Negation
open import Relation.Binary.PropositionalEquality as Eq using (_≡_; refl; module ≡-Reasoning)
open import Data.Product using (∃)
open import Data.Sum using (inj₁; inj₂)
open import Function
open import Data.Nat as Nat using (ℕ; zero; suc; z≤n; s≤s; _+_; _*_)
import Data.Nat.Properties as N
open import Data.Nat.Square
insert : cmp (Π A λ x → Π (list A) λ l → Π (sorted l) λ _ → F (Σ⁺ (list A) λ l' → sorted-of (x ∷ l) l'))
insert x [] [] = ret ([ x ] , refl , [] ∷ [])
insert x (y ∷ ys) (h ∷ hs) =
bind (F _) (x ≤? y) $ case-≤
(λ x≤y → ret (x ∷ (y ∷ ys) , refl , (x≤y ∷ ≤-≤* x≤y h) ∷ (h ∷ hs)))
(λ x≰y →
bind (F _) (insert x ys hs) λ (x∷ys' , x∷ys↭x∷ys' , sorted-x∷ys') →
ret
( y ∷ x∷ys'
, ( let open PermutationReasoning in
begin
x ∷ y ∷ ys
<<⟨ refl ⟩
y ∷ (x ∷ ys)
<⟨ x∷ys↭x∷ys' ⟩
y ∷ x∷ys'
∎
)
, All-resp-↭ x∷ys↭x∷ys' (≰⇒≥ x≰y ∷ h) ∷ sorted-x∷ys'
))
insert/total : ∀ x l h → IsValuable (insert x l h)
insert/total x [] [] u = ↓ refl
insert/total x (y ∷ ys) (h ∷ hs) u with ≤?-total x y u
... | yes x≤y , ≡ret rewrite ≡ret = ↓ refl
... | no x≰y , ≡ret rewrite ≡ret | Valuable.proof (insert/total x ys hs u) = ↓ refl
insert/cost : cmp (Π A λ _ → Π (list A) λ _ → cost)
insert/cost x l = step⋆ (length l)
insert/is-bounded : ∀ x l h → IsBoundedG (Σ⁺ (list A) λ l' → sorted-of (x ∷ l) l') (insert x l h) (insert/cost x l)
insert/is-bounded x [] [] = ≤⁻-refl
insert/is-bounded x (y ∷ ys) (h ∷ hs) =
bound/bind/const {_} {Σ⁺ (list A) λ l' → sorted-of (x ∷ (y ∷ ys)) l'}
{x ≤? y}
{case-≤ _ _}
1
(length ys)
(h-cost x y)
λ { (yes x≤y) → step-monoˡ-≤⁻ (ret _) (z≤n {length ys})
; (no ¬x≤y) → insert/is-bounded x ys hs
}
sort : cmp sorting
sort [] = ret ([] , refl , [])
sort (x ∷ xs) =
bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) (sort xs) λ (xs' , xs↭xs' , sorted-xs') →
bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) (insert x xs' sorted-xs') λ (x∷xs' , x∷xs↭x∷xs' , sorted-x∷xs') →
ret (x∷xs' , trans (prep x xs↭xs') x∷xs↭x∷xs' , sorted-x∷xs')
sort/total : IsTotal sort
sort/total [] u = ↓ refl
sort/total (x ∷ xs) u = ↓
let (xs' , xs↭xs' , sorted-xs') = Valuable.value (sort/total xs u) in
let (x∷xs' , x∷xs↭x∷xs' , sorted-x∷xs') = Valuable.value (insert/total x xs' sorted-xs' u) in
let open ≡-Reasoning in
begin
sort (x ∷ xs)
≡⟨
Eq.cong
(λ e →
bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) e λ (xs' , xs↭xs' , sorted-xs') →
bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) (insert x xs' sorted-xs') λ (x∷xs' , x∷xs↭x∷xs' , sorted-x∷xs') →
ret (x∷xs' , trans (prep x xs↭xs') x∷xs↭x∷xs' , sorted-x∷xs'))
(Valuable.proof (sort/total xs u))
⟩
( bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) (insert x xs' sorted-xs') λ (x∷xs' , x∷xs↭x∷xs' , sorted-x∷xs') →
ret (x∷xs' , _ , sorted-x∷xs')
)
≡⟨
Eq.cong
(λ e →
bind (F (Σ⁺ (list A) (sorted-of (x ∷ xs)))) e λ (x∷xs' , x∷xs↭x∷xs' , sorted-x∷xs') →
ret (x∷xs' , trans (prep x xs↭xs') x∷xs↭x∷xs' , sorted-x∷xs'))
(Valuable.proof (insert/total x xs' sorted-xs' u))
⟩
ret _
∎
sort/cost : cmp (Π (list A) λ _ → cost)
sort/cost l = step⋆ (length l ²)
sort/is-bounded : ∀ l → IsBoundedG (Σ⁺ (list A) (sorted-of l)) (sort l) (sort/cost l)
sort/is-bounded [] = ≤⁻-refl
sort/is-bounded (x ∷ xs) =
let open ≤⁻-Reasoning cost in
begin
( bind cost (sort xs) λ (xs' , xs↭xs' , sorted-xs') →
bind cost (insert x xs' sorted-xs') λ _ →
step⋆ zero
)
≲⟨ bind-monoʳ-≤⁻ (sort xs) (λ (xs' , xs↭xs' , sorted-xs') → insert/is-bounded x xs' sorted-xs') ⟩
( bind cost (sort xs) λ (xs' , xs↭xs' , sorted-xs') →
step⋆ (length xs')
)
≡˘⟨
Eq.cong
(bind cost (sort xs))
(funext λ (xs' , xs↭xs' , sorted-xs') → Eq.cong step⋆ (↭-length xs↭xs'))
⟩
( bind cost (sort xs) λ _ →
step⋆ (length xs)
)
≲⟨ bind-monoˡ-≤⁻ (λ _ → step⋆ (length xs)) (sort/is-bounded xs) ⟩
step⋆ ((length xs ²) + length xs)
≲⟨ step⋆-mono-≤⁻ (N.+-mono-≤ (N.*-monoʳ-≤ (length xs) (N.n≤1+n (length xs))) (N.n≤1+n (length xs))) ⟩
step⋆ (length xs * length (x ∷ xs) + length (x ∷ xs))
≡⟨ Eq.cong step⋆ (N.+-comm (length xs * length (x ∷ xs)) (length (x ∷ xs))) ⟩
step⋆ (length (x ∷ xs) ²)
≡⟨⟩
sort/cost (x ∷ xs)
∎
sort/asymptotic : given (list A) measured-via length , sort ∈𝓞(λ n → n ²)
sort/asymptotic = f[n]≤g[n]via sort/is-bounded