-
Notifications
You must be signed in to change notification settings - Fork 2
/
InsertionSort.agda
144 lines (128 loc) · 5.58 KB
/
InsertionSort.agda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
{-# 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