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
|
module Level0
import Data.SnocList.Elem
import NormalForm
import Term
import Thinning
record Cont (a : Type) where
constructor Then
runCont : forall res. (a -> res) -> res
Functor Cont where
map f (Then g) = Then (\k => k (g f))
Applicative Cont where
pure x = Then (\k => k x)
Then f <*> Then v = Then (\k => f (\j => v (k . j)))
Monad Cont where
join (Then f) = Then (\k => f (\c => runCont c k))
public export
data NormSubst : SnocList Ty -> SnocList Ty -> Type where
Base : ctx' `Thins` ctx -> NormSubst ctx ctx'
(:<) : NormSubst ctx ctx' -> Normal ctx ty -> NormSubst ctx (ctx' :< ty)
%name NormSubst sub
shift : NormSubst ctx ctx' -> NormSubst (ctx :< ty) ctx'
shift (Base thin) = Base (Drop thin)
shift (sub :< t) = shift sub :< wknNorm t (Drop Id)
lift : NormSubst ctx ctx' -> NormSubst (ctx :< ty) (ctx' :< ty)
lift (Base thin) = Base (keep thin)
lift (sub :< t) = shift (sub :< t) :< Ntrl (Var Here)
index : NormSubst ctx' ctx -> Elem ty ctx -> Normal ctx' ty
index (Base thin) i = Ntrl (Var $ index thin i)
index (sub :< t) Here = t
index (sub :< t) (There i) = index sub i
restrict : NormSubst ctx1 ctx2 -> ctx3 `Thins` ctx2 -> NormSubst ctx1 ctx3
restrict (Base thin') thin = Base (thin' . thin)
restrict (sub :< t) Id = sub :< t
restrict (sub :< t) (Drop thin) = restrict sub thin
restrict (sub :< t) (Keep thin) = restrict sub thin :< t
data Case : Type where
Eval : (0 ty : Ty) -> (0 ctx, ctx' : SnocList Ty) -> Case
EvalSub : (0 ctx, ctx', ctx'' : SnocList Ty) -> Case
App : (0 ty, ty' : Ty) -> (0 ctx : SnocList Ty) -> Case
Rec : (0 ty : Ty) -> (0 ctx : SnocList Ty) -> Case
0 Input : Case -> Type
Input (Eval ty ctx ctx') = (Term ctx ty, NormSubst ctx' ctx)
Input (EvalSub ctx ctx' ctx'') = (Subst ctx' ctx, NormSubst ctx'' ctx')
Input (App ty ty' ctx) = (Normal ctx (ty ~> ty'), Normal ctx ty)
Input (Rec ty ctx) = (Normal ctx N, Normal ctx ty, Normal (ctx :< ty) ty)
0 Output : Case -> Type
Output (Eval ty ctx ctx') = Normal ctx' ty
Output (EvalSub ctx ctx' ctx'') = NormSubst ctx'' ctx
Output (App ty ty' ctx) = Normal ctx ty'
Output (Rec ty ctx) = Normal ctx ty
partial
eval : (c : Case) -> Input c -> Cont (Output c)
eval (Eval _ _ _) (Var i, sub) = pure (index sub i)
eval (Eval _ _ _) (Abs t, sub) = [| Abs (eval (Eval _ _ _) (t, lift sub)) |]
eval (Eval _ _ _) (App t u, sub) = do
t <- eval (Eval _ _ _) (t, sub)
u <- eval (Eval _ _ _) (u, sub)
eval (App _ _ _) (t, u)
eval (Eval _ _ _) (Zero, sub) = pure Zero
eval (Eval _ _ _) (Succ t, sub) = [| Succ (eval (Eval _ _ _) (t, sub)) |]
eval (Eval _ _ _) (Rec t u v, sub) = do
t <- eval (Eval _ _ _) (t, sub)
u <- eval (Eval _ _ _) (u, sub)
v <- eval (Eval _ _ _) (v, lift sub)
eval (Rec _ _) (t, u, v)
eval (Eval _ _ _) (Sub t sub', sub) = do
sub' <- eval (EvalSub _ _ _) (sub', sub)
eval (Eval _ _ _) (t, sub')
eval (EvalSub _ _ _) (Base thin, sub') = pure (restrict sub' thin)
eval (EvalSub _ _ _) (sub :< t, sub') =
[| eval (EvalSub _ _ _) (sub, sub') :< eval (Eval _ _ _) (t, sub') |]
eval (App _ _ _) (Abs t, u) =
eval (Eval _ _ _) (forgetNorm t, Base Id :< u)
eval (App _ _ _) (Ntrl t, u) = pure (Ntrl $ App t u)
eval (Rec _ _) (Zero, u, v) = pure u
eval (Rec _ _) (Succ t, u, v) = do
val <- eval (Rec _ _) (t, u, v)
eval (Eval _ _ _) (forgetNorm v, Base Id :< val)
eval (Rec _ _) (Ntrl t, u, v) = pure (Ntrl $ Rec t u v)
|