-
Notifications
You must be signed in to change notification settings - Fork 3
/
Basic.agda
56 lines (47 loc) · 1.59 KB
/
Basic.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
{-# OPTIONS --rewriting #-}
module Examples.Decalf.Basic where
open import Algebra.Cost
costMonoid = ℕ-CostMonoid
open CostMonoid costMonoid using (ℂ)
open import Calf costMonoid
open import Calf.Data.Nat
import Data.Nat.Properties as Nat
open import Calf.Data.Equality as Eq using (_≡_; refl; module ≡-Reasoning)
open import Function
double : cmp $ Π nat λ _ → F nat
double zero = ret zero
double (suc n) =
step (F nat) 1 $
bind (F nat) (double n) λ n' →
ret (suc (suc n'))
double/bound : cmp $ Π nat λ _ → F nat
double/bound n = step (F nat) n (ret (2 * n))
double/has-cost : (n : val nat) → double n ≡ double/bound n
double/has-cost zero = refl
double/has-cost (suc n) =
let open ≡-Reasoning in
begin
(step (F nat) 1 $
bind (F nat) (double n) λ n' →
ret (suc (suc n')))
≡⟨
Eq.cong
(step (F nat) 1)
(begin
(bind (F nat) (double n) λ n' →
ret (suc (suc n')))
≡⟨ Eq.cong (λ e → bind (F nat) e λ n' → ret (suc (suc n'))) (double/has-cost n) ⟩
(bind (F nat) (step (F nat) n (ret (2 * n))) λ n' →
ret (suc (suc n')))
≡⟨⟩
step (F nat) n (ret (suc (suc (2 * n))))
≡˘⟨ Eq.cong (step (F nat) n ∘ ret ∘ suc) (Nat.+-suc n (n + 0)) ⟩
step (F nat) n (ret (2 * suc n))
∎)
⟩
step (F nat) 1 (step (F nat) n (ret (2 * suc n)))
≡⟨⟩
step (F nat) (suc n) (ret (2 * suc n))
∎
double/correct : ◯ ((n : val nat) → double n ≡ ret (2 * n))
double/correct u n = Eq.trans (double/has-cost n) (step/ext (F nat) (ret (2 * n)) n u)