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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
module Obs.NormalForm
import Data.List.Elem
import Obs.Substitution
import Obs.Universe
import Text.Bounded
import Text.PrettyPrint.Prettyprinter
%default total
-- Definition ------------------------------------------------------------------
data NormalForm : Sorted.Family Relevance
public export
TypeNormalForm : Unsorted.Family Relevance
TypeNormalForm = NormalForm Relevant
public export
data Constructor : Unsorted.Family Relevance where
Universe : (s : Universe) -> Constructor ctx
Pi : (s, s' : Universe)
-> (var : String)
-> (a : TypeNormalForm ctx)
-> (b : TypeNormalForm (relevance s :: ctx))
-> Constructor ctx
Lambda : (s : Universe)
-> (var : String)
-> NormalForm Relevant (relevance s :: ctx)
-> Constructor ctx
Sigma : (s, s' : Universe)
-> (var : String)
-> (a : TypeNormalForm ctx)
-> (b : TypeNormalForm (relevance s :: ctx))
-> Constructor ctx
Pair : (s, s' : Universe)
-> (prf : IsRelevant (max s s'))
-> NormalForm (relevance s) ctx
-> NormalForm (relevance s') ctx
-> Constructor ctx
Bool : Constructor ctx
True : Constructor ctx
False : Constructor ctx
Top : Constructor ctx
Bottom : Constructor ctx
public export
data Neutral : Unsorted.Family Relevance where
Var : (var : String)
-> (sort : Universe)
-> (prf : IsRelevant sort)
-> (i : Elem Relevant ctx)
-> Neutral ctx
App : (r : Relevance) -> Neutral ctx -> NormalForm r ctx -> Neutral ctx
Fst : (r : Relevance) -> Neutral ctx -> Neutral ctx
Snd : (r : Relevance) -> Neutral ctx -> Neutral ctx
If : Neutral ctx -> (f, g : NormalForm Relevant ctx) -> Neutral ctx
Absurd : Neutral ctx
Equal : Neutral ctx -> NormalForm Relevant ctx -> NormalForm Relevant ctx -> Neutral ctx
EqualL : (a : Neutral ctx) -> (b : TypeNormalForm ctx) -> Neutral ctx
EqualR : (a : Constructor ctx) -> (b : Neutral ctx) -> Neutral ctx
EqualStuck : (a, b : Constructor ctx) -> Neutral ctx
CastL : (a : Neutral ctx) ->
(b : TypeNormalForm ctx) ->
NormalForm Relevant ctx ->
Neutral ctx
CastR : (a : Constructor ctx) -> (b : Neutral ctx) -> NormalForm Relevant ctx -> Neutral ctx
CastStuck : (a, b : Constructor ctx) -> NormalForm Relevant ctx -> Neutral ctx
public export
data NormalForm : Sorted.Family Relevance where
Ntrl : Neutral ~|> NormalForm Relevant
Cnstr : Constructor ~|> NormalForm Relevant
Irrel : NormalForm Irrelevant ctx
%name Constructor t, u, v
%name Neutral t, u, v
%name NormalForm t, u, v
public export
record Definition (ctx : List Relevance) where
constructor MkDefinition
name : WithBounds String
sort : Universe
ty : TypeNormalForm ctx
tm : NormalForm (relevance sort) ctx
public export
data Context : List Relevance -> Type where
Nil : Context []
(:<) : Context ctx -> (def : Definition ctx) -> Context (relevance def.sort :: ctx)
%name Context ctx, ctx', ctx''
-- Convenience Casts -----------------------------------------------------------
public export
Cast Universe (Constructor ctx) where
cast s = Universe s
public export
Cast Universe (NormalForm Relevant ctx) where
cast s = Cnstr $ cast s
-- Pretty Print ----------------------------------------------------------------
prettyPrec : Prec -> NormalForm b ctx -> Doc ann
prettyPrecCnstr : Prec -> Constructor ctx -> Doc ann
prettyPrecCnstr d (Universe s) = prettyPrec d s
prettyPrecCnstr d (Pi s s' var a b) =
let lhs = case var of
"" => align (prettyPrec App a)
_ => parens (pretty var <++> colon <+> softline <+> align (prettyPrec Open a))
in
parenthesise (d > Open) $
group $
lhs <++> pretty "->" <+> line <+> align (prettyPrec Open b)
prettyPrecCnstr d (Lambda _ var t) =
parenthesise (d > Open) $
group $
backslash <+> pretty var <++>
pretty "=>" <+> line <+>
align (prettyPrec Open t)
prettyPrecCnstr d (Sigma s s' var a b) =
let lhs = case var of
"" => align (prettyPrec App a)
_ => parens (pretty var <++> colon <+> softline <+> align (prettyPrec Open a))
in
parenthesise (d > Open) $
group $
lhs <++> pretty "**" <+> line <+> align (prettyPrec Open b)
prettyPrecCnstr d (Pair s s' prf t u) =
angles $
group $
neutral <++> prettyPrec Open t <+> comma <+> line <+> prettyPrec Open u <++> neutral
prettyPrecCnstr d Bool = pretty "Bool"
prettyPrecCnstr d True = pretty "True"
prettyPrecCnstr d False = pretty "False"
prettyPrecCnstr d Top = pretty "()"
prettyPrecCnstr d Bottom = pretty "Void"
prettyPrecNtrl : Prec -> Neutral ctx -> Doc ann
prettyPrecNtrl d (Var var sort prf i) = pretty "\{var}@\{show $ elemToNat i}"
prettyPrecNtrl d (App _ t u) =
parenthesise (d >= App) $
group $
vsep [prettyPrecNtrl Open t, prettyPrec App u]
prettyPrecNtrl d (Fst _ t) =
parenthesise (d >= App) $
group $
vsep [pretty "fst", prettyPrecNtrl App t]
prettyPrecNtrl d (Snd _ t) =
parenthesise (d >= App) $
group $
vsep [pretty "snd", prettyPrecNtrl App t]
prettyPrecNtrl d (If t f g) =
parenthesise (d >= App) $
group $
vsep [pretty "if", prettyPrecNtrl App t, prettyPrec App f, prettyPrec App g]
prettyPrecNtrl d Absurd = pretty "absurd"
prettyPrecNtrl d (Equal a t u) =
parenthesise (d >= Equal) $
group $
prettyPrec Equal t <++> pretty "~" <+> line <+> prettyPrec Equal u
prettyPrecNtrl d (EqualL a b) =
parenthesise (d >= Equal) $
group $
prettyPrecNtrl Equal a <++> pretty "~" <+> line <+> prettyPrec Equal b
prettyPrecNtrl d (EqualR a b) =
parenthesise (d >= Equal) $
group $
prettyPrecCnstr Equal a <++> pretty "~" <+> line <+> prettyPrecNtrl Equal b
prettyPrecNtrl d (EqualStuck a b) =
parenthesise (d >= Equal) $
group $
prettyPrecCnstr Equal a <++> pretty "~" <+> line <+> prettyPrecCnstr Equal b
prettyPrecNtrl d (CastL a b t) =
parenthesise (d >= App) $
group $
vsep [pretty "cast", prettyPrecNtrl App a, prettyPrec App b, prettyPrec App t]
prettyPrecNtrl d (CastR a b t) =
parenthesise (d >= App) $
group $
vsep [pretty "cast", prettyPrecCnstr App a, prettyPrecNtrl App b, prettyPrec App t]
prettyPrecNtrl d (CastStuck a b t) =
parenthesise (d >= App) $
group $
vsep [pretty "cast", prettyPrecCnstr App a, prettyPrecCnstr App b, prettyPrec App t]
prettyPrec d (Ntrl t) = prettyPrecNtrl d t
prettyPrec d (Cnstr t) = prettyPrecCnstr d t
prettyPrec d Irrel = pretty "_"
export
Pretty (Constructor ctx) where
prettyPrec = prettyPrecCnstr
export
Pretty (Neutral ctx) where
prettyPrec = prettyPrecNtrl
export
Pretty (NormalForm b ctx) where
prettyPrec = NormalForm.prettyPrec
-- Renaming --------------------------------------------------------------------
rename : NormalForm ~|> Hom Elem NormalForm
renameCnstr : Constructor ~|> Hom Elem Constructor
renameCnstr (Universe s) f = Universe s
renameCnstr (Pi s s' var a b) f = Pi s s' var (rename a f) (rename b (lift [(_ ** ())] f))
renameCnstr (Lambda s var t) f = Lambda s var (rename t (lift [(_ ** ())] f))
renameCnstr (Sigma s s' var a b) f =
Sigma s s' var (rename a f) (rename b (lift [(_ ** ())] f))
renameCnstr (Pair s s' prf t u) f = Pair s s' prf (rename t f) (rename u f)
renameCnstr Bool f = Bool
renameCnstr True f = True
renameCnstr False f = False
renameCnstr Top f = Top
renameCnstr Bottom f = Bottom
renameNtrl : Neutral ~|> Hom Elem Neutral
renameNtrl (Var var sort prf i) f = Var var sort prf (f i)
renameNtrl (App b t u) f = App b (renameNtrl t f) (rename u f)
renameNtrl (Fst b t) f = Fst b (renameNtrl t f)
renameNtrl (Snd b t) f = Snd b (renameNtrl t f)
renameNtrl (If t u v) f = If (renameNtrl t f) (rename u f) (rename v f)
renameNtrl Absurd f = Absurd
renameNtrl (Equal a t u) f = Equal (renameNtrl a f) (rename t f) (rename u f)
renameNtrl (EqualL a b) f = EqualL (renameNtrl a f) (rename b f)
renameNtrl (EqualR a b) f = EqualR (renameCnstr a f) (renameNtrl b f)
renameNtrl (EqualStuck a b) f = EqualStuck (renameCnstr a f) (renameCnstr b f)
renameNtrl (CastL a b t) f = CastL (renameNtrl a f) (rename b f) (rename t f)
renameNtrl (CastR a b t) f = CastR (renameCnstr a f) (renameNtrl b f) (rename t f)
renameNtrl (CastStuck a b t) f = CastStuck (renameCnstr a f) (renameCnstr b f) (rename t f)
rename (Ntrl t) f = Ntrl $ renameNtrl t f
rename (Cnstr t) f = Cnstr $ renameCnstr t f
rename Irrel f = Irrel
export
Unsorted.Rename Relevance Constructor where
rename = renameCnstr
export
Unsorted.Rename Relevance Neutral where
rename = renameNtrl
export
Sorted.Rename Relevance NormalForm where
rename = NormalForm.rename
export
PointedRename Relevance (\r => (String, (s : Universe ** relevance s = r))) NormalForm where
point {s = Irrelevant} _ _ = Irrel
point {s = Relevant} (var, (s@(Set _) ** prf)) i = Ntrl (Var var s Set i)
|