-
Notifications
You must be signed in to change notification settings - Fork 2
/
HigherOrderFunction.agda
129 lines (119 loc) · 3.9 KB
/
HigherOrderFunction.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
{-# OPTIONS --rewriting #-}
module Examples.Decalf.HigherOrderFunction where
open import Algebra.Cost
costMonoid = ℕ-CostMonoid
open CostMonoid costMonoid using (ℂ)
open import Calf costMonoid
open import Calf.Data.Nat as Nat using (nat; zero; suc; _+_; _*_)
import Data.Nat.Properties as Nat
open import Data.Nat.Square
open import Calf.Data.List using (list; []; _∷_; [_]; _++_; length)
open import Calf.Data.Bool using (bool; if_then_else_)
open import Calf.Data.Product using (unit)
open import Calf.Data.Equality as Eq using (_≡_; refl; module ≡-Reasoning)
open import Calf.Data.IsBoundedG costMonoid
open import Calf.Data.IsBounded costMonoid
open import Function
module Twice where
twice : cmp $ Π (U (F nat)) λ _ → F nat
twice e =
bind (F nat) e λ x₁ →
bind (F nat) e λ x₂ →
ret (x₁ + x₂)
twice/is-bounded : (e : cmp (F nat)) → IsBounded nat e 1 → IsBounded nat (twice e) 2
twice/is-bounded e e≤step⋆1 =
let open ≤⁻-Reasoning cost in
begin
bind cost
( bind (F nat) e λ x₁ →
bind (F nat) e λ x₂ →
ret (x₁ + x₂)
)
(λ _ → ret triv)
≡⟨⟩
( bind cost e λ _ →
bind cost e λ _ →
ret triv
)
≲⟨ ≤⁻-mono₂ (λ e₁ e₂ → bind (F _) e₁ λ _ → bind (F _) e₂ λ _ → ret triv) e≤step⋆1 e≤step⋆1 ⟩
( bind cost (step⋆ 1) λ _ →
bind cost (step⋆ 1) λ _ →
ret triv
)
≡⟨⟩
step⋆ 2
∎
module Map where
map : cmp $ Π (U (Π nat λ _ → F nat)) λ _ → Π (list nat) λ _ → F (list nat)
map f [] = ret []
map f (x ∷ xs) =
bind (F (list nat)) (f x) λ y →
bind (F (list nat)) (map f xs) λ ys →
ret (y ∷ ys)
map/is-bounded :
(f : cmp (Π nat λ _ → F nat)) →
((x : val nat) → IsBounded nat (f x) c) →
(l : val (list nat)) →
IsBounded (list nat) (map f l) (length l * c)
map/is-bounded f f-bound [] = ≤⁻-refl
map/is-bounded {c} f f-bound (x ∷ xs) =
let open ≤⁻-Reasoning cost in
begin
bind cost
( bind (F (list nat)) (f x) λ y →
bind (F (list nat)) (map f xs) λ ys →
ret (y ∷ ys)
)
(λ _ → ret triv)
≡⟨⟩
( bind cost (f x) λ _ →
bind cost (map f xs) λ _ →
ret triv
)
≲⟨
≤⁻-mono₂ (λ e₁ e₂ → bind cost e₁ λ _ → bind cost e₂ λ _ → ret triv)
(f-bound x)
(map/is-bounded f f-bound xs)
⟩
( bind cost (step⋆ c) λ _ →
bind cost (step⋆ (length xs * c)) λ _ →
ret triv
)
≡⟨⟩
step⋆ (length (x ∷ xs) * c)
∎
open import Examples.Decalf.ProbabilisticChoice
map/is-bounded' :
(f : cmp (Π nat λ _ → F nat)) →
{n : val nat} →
((x : val nat) → IsBoundedG nat (f x) (binomial n)) →
(l : val (list nat)) →
IsBoundedG (list nat) (map f l) (binomial (length l * n))
map/is-bounded' f {n} f-bound [] = ≤⁻-refl
map/is-bounded' f {n} f-bound (x ∷ xs) =
let open ≤⁻-Reasoning cost in
begin
bind cost
( bind (F (list nat)) (f x) λ y →
bind (F (list nat)) (map f xs) λ ys →
ret (y ∷ ys)
)
(λ _ → ret triv)
≡⟨⟩
( bind cost (f x) λ _ →
bind cost (map f xs) λ _ →
ret triv
)
≲⟨ ≤⁻-mono (λ e → bind cost (f x) λ _ → e) (map/is-bounded' f f-bound xs) ⟩
( bind cost (f x) λ _ →
binomial (length xs * n)
)
≲⟨ ≤⁻-mono (λ e → bind cost e λ _ → binomial (length xs * n)) (f-bound x) ⟩
( bind cost (binomial n) λ _ →
binomial (length xs * n)
)
≡⟨ binomial/+ n (length xs * n) ⟩
binomial (n + length xs * n)
≡⟨⟩
binomial (length (x ∷ xs) * n)
∎