-
Notifications
You must be signed in to change notification settings - Fork 6
/
NBE.agda
98 lines (77 loc) · 2.8 KB
/
NBE.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
module NBE where
open import Ex1Prelude
data Ty : Set where
base : Ty
_>>_ : Ty -> Ty -> Ty
data Cx : Set where
C0 : Cx
_/_ : Cx -> Ty -> Cx
infixl 4 _/_
infixl 3 _<:_
data _<:_ (T : Ty) : Cx -> Set where
zero : {G : Cx} -> T <: G / T
suc : {G : Cx}{S : Ty} -> T <: G -> T <: G / S
data Term (G : Cx) : Ty -> Set where
lam : {S T : Ty} ->
Term (G / S) T -> Term G (S >> T)
var : {S : Ty} -> S <: G -> Term G S
_$_ : {S T : Ty} -> Term G (S >> T) ->
Term G S -> Term G T
data Form : Set where normal neutral : Form
data Result (G : Cx) : Form -> Ty -> Set where
lam : {S T : Ty} ->
Result (G / S) normal T -> Result G normal (S >> T)
[_] : {T : Ty} -> Result G neutral T -> Result G normal T
var : {S : Ty} -> S <: G -> Result G neutral S
_$_ : {S T : Ty} -> Result G neutral (S >> T) ->
Result G normal S -> Result G neutral T
Renaming : Cx -> Cx -> Set
Renaming G G' = {T : Ty} -> T <: G -> T <: G'
pushRen : {G G' : Cx}{S : Ty} ->
Renaming G G' -> Renaming (G / S) (G' / S)
pushRen r zero = zero
pushRen r (suc x) = suc (r x)
Semantics : Cx -> Ty -> Set
Computing : Cx -> Ty -> Set
Semantics G T = Result G neutral T /+/ Computing G T
Computing G base = Zero
Computing G (S >> T) = {G' : Cx} -> Renaming G G' ->
Semantics G' S -> Semantics G' T
wkRes : {G G' : Cx}{f : Form} -> Renaming G G' -> {T : Ty} ->
Result G f T -> Result G' f T
wkRes r (lam t) = lam (wkRes (pushRen r) t)
wkRes r [ t ] = [ wkRes r t ]
wkRes r (var x) = var (r x)
wkRes r (f $ s) = wkRes r f $ wkRes r s
wkSem : {G G' : Cx} -> Renaming G G' -> (T : Ty) ->
Semantics G T -> Semantics G' T
wkSem r T (inl e) = inl (wkRes r e)
wkSem r base (inr ())
wkSem r (S >> T) (inr f) = inr \ r' -> f (r' o r)
Env : Cx -> Cx -> Set
Env G G' = {T : Ty} -> T <: G -> Semantics G' T
wkEnv : {G0 G1 G2 : Cx} -> Renaming G1 G2 -> Env G0 G1 -> Env G0 G2
wkEnv r g x = wkSem r _ (g x)
_//_ : {G G' : Cx}{T : Ty} -> Env G G' -> Semantics G' T ->
Env (G / T) G'
_//_ g v zero = v
_//_ g v (suc x) = g x
_$$_ : {G : Cx}{S T : Ty} -> Semantics G (S >> T) ->
Semantics G S -> Semantics G T
stop : {G : Cx}(S : Ty) -> Semantics G S -> Result G normal S
inl e $$ s = inl (e $ stop _ s)
inr f $$ s = f id s
stop base (inl e) = [ e ]
stop base (inr ())
stop (S >> T) v = lam (stop T
(wkSem suc (S >> T) v $$ inl (var zero)))
semantics : {G G' : Cx}{T : Ty} ->
({T : Ty} -> T <: G -> Semantics G' T) ->
Term G T -> Semantics G' T
semantics g (lam t) = inr \ r s -> semantics (wkEnv r g // s) t
semantics g (var x) = g x
semantics g (f $ s) = semantics g f $$ semantics g s
value : {G : Cx}{T : Ty} -> Term G T -> Result G normal T
value {G}{T} t = stop T (semantics (inl o var) t)
myTerm : Term (C0 / base) base
myTerm = lam (var zero $ (var zero $ var (suc zero))) $ lam (var zero)