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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
module Inky.Term.Pretty
import Data.List.Quantifiers
import Data.Singleton
import Data.String
import Data.These
import Inky.Decidable.Maybe
import Inky.Term
import Inky.Type.Pretty
import Text.Bounded
import Text.PrettyPrint.Prettyprinter
public export
data TermPrec = Atom | Prefix | Suffix | App | Annot | Open
%name TermPrec d
Eq TermPrec where
Atom == Atom = True
Prefix == Prefix = True
Suffix == Suffix = True
App == App = True
Annot == Annot = True
Open == Open = True
_ == _ = False
Ord TermPrec where
compare Atom Atom = EQ
compare Atom d2 = LT
compare Prefix Atom = GT
compare Prefix Prefix = EQ
compare Prefix d2 = LT
compare Suffix Atom = GT
compare Suffix Prefix = GT
compare Suffix Suffix = EQ
compare Suffix d2 = LT
compare App App = EQ
compare App Annot = LT
compare App Open = LT
compare App d2 = GT
compare Annot Annot = EQ
compare Annot Open = LT
compare Annot d2 = GT
compare Open Open = EQ
compare Open d2 = GT
export
prettyTerm : {tyCtx, tmCtx : SnocList String} -> Term m tyCtx tmCtx -> TermPrec -> Doc ann
prettyAllTerm : {tyCtx, tmCtx : SnocList String} -> List (Term m tyCtx tmCtx) -> TermPrec -> List (Doc ann)
prettyTermCtx : {tyCtx, tmCtx : SnocList String} -> Context (Term m tyCtx tmCtx) -> TermPrec -> SnocList (Doc ann)
prettyCases : {tyCtx, tmCtx : SnocList String} -> Context (x ** Term m tyCtx (tmCtx :< x)) -> SnocList (Doc ann)
prettyLet : Doc ann -> Doc ann -> Doc ann
lessPrettyTerm : {tyCtx, tmCtx : SnocList String} -> Term m tyCtx tmCtx -> TermPrec -> Doc ann
prettyTerm t d =
case isLit t <|> isCheckLit t of
Just k => pretty k
Nothing =>
if isSuc t
then pretty "suc"
else lessPrettyTerm t d
prettyAllTerm [] d = []
prettyAllTerm (t :: ts) d = prettyTerm t d :: prettyAllTerm ts d
prettyTermCtx [<] d = [<]
prettyTermCtx (ts :< (l :- t)) d = prettyTermCtx ts d :< (pretty l <+> ":" <++> prettyTerm t d)
prettyCases [<] = [<]
prettyCases (ts :< (l :- (x ** Abs _ (bound ** t)))) =
prettyCases ts :<
(group $ align $
pretty l <++> pretty x <++> "=>" <++>
"\\" <+> concatWith (surround $ "," <++> neutral) (map pretty bound) <++> "=>" <+> line <+>
prettyTerm t Open)
prettyCases (ts :< (l :- (x ** t))) =
prettyCases ts :<
(group $ align $
pretty l <++> pretty x <++> "=>" <+> line <+>
prettyTerm t Open)
prettyLet binding term =
(group $
pretty "let" <++>
(group $ hang (-2) $ binding) <+> line <+>
"in") <+> line <+>
term
lessPrettyTerm (Annot _ t a) d =
group $ align $ hang 2 $ parenthesise (d < Annot) $
prettyTerm t App <++> ":" <+> line <+> prettyType a Open
lessPrettyTerm (Var _ i) d = pretty (unVal $ nameOf i)
lessPrettyTerm (Let _ e (x ** t)) d =
-- TODO: pretty print annotated abstraction
group $ align $ parenthesise (d < Open) $
prettyLet
(pretty x <++> "=" <+> line <+> prettyTerm e Open)
(prettyTerm t Open)
lessPrettyTerm (LetTy _ a (x ** t)) d =
group $ align $ parenthesise (d < Open) $
prettyLet
(pretty x <++> "=" <+> line <+> prettyType a Open)
(prettyTerm t Open)
lessPrettyTerm (Abs _ (bound ** t)) d =
group $ hang 2 $ parenthesise (d < Open) $
"\\" <+> concatWith (surround $ "," <+> line) (map pretty bound) <++> "=>" <+> line <+>
prettyTerm t Open
lessPrettyTerm (App _ (Map _ (x ** a) b c) ts) d =
group $ align $ hang 2 $ parenthesise (d < App) $
concatWith (surround line)
( pretty "map"
:: parens (group $ align $ hang 2 $ "\\" <+> pretty x <++> "=>" <+> line <+> prettyType a Open)
:: prettyType b Atom
:: prettyType c Atom
:: prettyAllTerm ts Suffix)
lessPrettyTerm (App _ (GetChildren _ (x ** a) b) ts) d =
group $ align $ hang 2 $ parenthesise (d < App) $
concatWith (surround line)
( pretty "getChildren"
:: parens (group $ align $ hang 2 $ "\\" <+> pretty x <++> "=>" <+> line <+> prettyType a Open)
:: prettyType b Atom
:: prettyAllTerm ts Suffix)
lessPrettyTerm (App _ f ts) d =
group $ align $ hang 2 $ parenthesise (d < App) $
concatWith (surround line) (prettyTerm f Suffix :: prettyAllTerm ts Suffix)
lessPrettyTerm (Tup _ (MkRow ts _)) d =
let parts = prettyTermCtx ts Open <>> [] in
group $ align $ enclose "<" ">" $
flatAlt
(neutral <++> concatWith (surround $ line' <+> "," <++> neutral) parts <+> line)
(concatWith (surround $ "," <++> neutral) parts)
lessPrettyTerm (Prj _ e l) d =
group $ align $ hang 2 $ parenthesise (d < Suffix) $
prettyTerm e Suffix <+> line' <+> "." <+> pretty l
lessPrettyTerm (Inj _ l t) d =
group $ align $ hang 2 $ parenthesise (d < App) $
pretty l <+> line <+> prettyTerm t Suffix
lessPrettyTerm (Case _ e (MkRow ts _)) d =
let parts = prettyCases ts <>> [] in
group $ align $ hang 2 $ parenthesise (d < Open) $
(group $ hang (-2) $ "case" <++> prettyTerm e Open <+> line <+> "of") <+> line <+>
(braces $
flatAlt
(neutral <++> concatWith (surround $ line' <+> ";" <++> neutral) parts <+> line)
(concatWith (surround $ ";" <++> neutral) parts))
lessPrettyTerm (Roll _ t) d =
pretty "~" <+>
parenthesise (d < Prefix) (group $ align $ hang 2 $ prettyTerm t Prefix)
lessPrettyTerm (Unroll _ e) d =
pretty "!" <+>
parenthesise (d > Prefix) (group $ align $ hang 2 $ prettyTerm e Prefix)
lessPrettyTerm (Fold _ e (x ** t)) d =
-- TODO: foldcase
group $ align $ hang 2 $ parenthesise (d < Open) $
"fold" <++> prettyTerm e Open <++> "by" <+> hardline <+>
(group $ align $ hang 2 $ parens $
"\\" <+> pretty x <++> "=>" <+> line <+> prettyTerm t Open)
lessPrettyTerm (Map _ (x ** a) b c) d =
group $ align $ hang 2 $ parenthesise (d < App) $
concatWith (surround line)
[ pretty "map"
, group (align $ hang 2 $ parens $ "\\" <+> pretty x <++> "=>" <+> line <+> prettyType a Open)
, prettyType b Atom
, prettyType c Atom
]
lessPrettyTerm (GetChildren _ (x ** a) b) d =
group $ align $ hang 2 $ parenthesise (d < App) $
concatWith (surround line)
[ pretty "getChildren"
, group (align $ hang 2 $ parens $ "\\" <+> pretty x <++> "=>" <+> line <+> prettyType a Open)
, prettyType b Atom
]
-- Typing Errors ---------------------------------------------------------------
Pretty (ChecksOnly t) where
pretty Abs = "abstraction"
pretty Inj = "injection"
pretty Case = "case split"
pretty Roll = "rolling"
pretty Fold = "fold"
prettyNotSynths :
{tyCtx, tmCtx : SnocList String} ->
{e : Term m tyCtx tmCtx} ->
{tyEnv : _} -> {tmEnv : _} ->
NotSynths tyEnv tmEnv e ->
List (m, Doc ann)
export
prettyNotChecks :
{tyCtx, tmCtx : SnocList String} ->
{a : Ty [<]} ->
{t : Term m tyCtx tmCtx} ->
{tyEnv : _} -> {tmEnv : _} ->
NotChecks tyEnv tmEnv a t ->
List (m, Doc ann)
prettyNotCheckSpine :
{tyCtx, tmCtx : SnocList String} ->
{a : Ty [<]} ->
{ts : List (Term m tyCtx tmCtx)} ->
{tyEnv : _} -> {tmEnv : _} ->
NotCheckSpine tyEnv tmEnv a ts ->
List (m, Doc ann)
prettyAnyNotSynths :
{tyCtx, tmCtx : SnocList String} ->
{es : Context (Term m tyCtx tmCtx)} ->
{tyEnv : _} -> {tmEnv : _} ->
AnyNotSynths tyEnv tmEnv es ->
List (m, Doc ann)
prettyAnyNotChecks :
{tyCtx, tmCtx : SnocList String} ->
{ts : Context (Term m tyCtx tmCtx)} ->
{tyEnv : _} -> {tmEnv : _} -> {as : Context _} ->
(meta : m) ->
AnyNotChecks tyEnv tmEnv as ts ->
List (m, Doc ann)
prettyAnyNotBranches :
{tyCtx, tmCtx : SnocList String} ->
{ts : Context (x ** Term m tyCtx (tmCtx :< x))} ->
{tyEnv : _} -> {tmEnv : _} -> {as : Context _} -> {a : _} ->
(meta : m) ->
AnyNotBranches tyEnv tmEnv as a ts ->
List (m, Doc ann)
prettyNotSynths (ChecksNS shape) =
[(e.meta, pretty "cannot synthesise type of" <++> pretty shape)]
prettyNotSynths (AnnotNS {a} (This contra)) =
[(e.meta, pretty "ill-formed type" <+> line <+> prettyType a Open)]
prettyNotSynths (AnnotNS (That contra)) = prettyNotChecks contra
prettyNotSynths (AnnotNS {a} (Both contra1 contra2)) =
(e.meta, pretty "ill-formed type" <+> line <+> prettyType a Open) ::
prettyNotChecks contra2
prettyNotSynths (LetNS1 contra) = prettyNotSynths contra
prettyNotSynths (LetNS2 prf contra) =
case synthsRecompute prf of
Val a => prettyNotSynths contra
prettyNotSynths (LetTyNS {a} (This contra)) =
[(e.meta, pretty "ill-formed type" <+> line <+> prettyType a Open)]
prettyNotSynths (LetTyNS (That contra)) = prettyNotSynths contra
prettyNotSynths (LetTyNS {a} (Both contra1 contra2)) =
(e.meta, pretty "ill-formed type" <+> line <+> prettyType a Open)
:: prettyNotSynths contra2
prettyNotSynths (AppNS1 contra) = prettyNotSynths contra
prettyNotSynths (AppNS2 prf contras) =
case synthsRecompute prf of
Val a => prettyNotCheckSpine contras
prettyNotSynths (TupNS contras) = prettyAnyNotSynths contras
prettyNotSynths (PrjNS1 contra) = prettyNotSynths contra
prettyNotSynths (PrjNS2 prf f) =
case synthsRecompute prf of
Val a =>
[(e.meta
, pretty "cannot project non-product type" <+> line <+>
prettyType a Open
)]
prettyNotSynths (PrjNS3 {l, as} prf contra) =
case synthsRecompute prf of
Val (TProd as) =>
[(e.meta
, pretty "unknown label" <++> enclose "'" "'" (pretty l) <+> line <+>
pretty "in product type" <+> line <+>
prettyType (TProd as) Open
)]
prettyNotSynths (UnrollNS1 contra) = prettyNotSynths contra
prettyNotSynths (UnrollNS2 prf contra) =
case synthsRecompute prf of
Val a =>
[(e.meta
, pretty "cannot unroll non-inductive type" <+> line <+>
prettyType a Open
)]
prettyNotSynths (MapNS {a} {b} {c} contras) =
bifoldMap
(const [(e.meta, pretty "ill-formed functor" <+> line <+> prettyType a Open)])
(bifoldMap
(const [(e.meta, pretty "ill-formed source" <+> line <+> prettyType b Open)])
(const [(e.meta, pretty "ill-formed target" <+> line <+> prettyType c Open)]))
contras
prettyNotSynths (GetChildrenNS {a} {b} contras) =
bifoldMap
(const [(e.meta, pretty "ill-formed functor" <+> line <+> prettyType a Open)])
(const [(e.meta, pretty "ill-formed contents" <+> line <+> prettyType b Open)])
contras
prettyNotChecks (EmbedNC1 _ contra) = prettyNotSynths contra
prettyNotChecks (EmbedNC2 _ prf contra) =
case synthsRecompute prf of
Val b =>
[(t.meta
, pretty "cannot unify" <+> line <+>
prettyType a Open <+> line <+>
pretty "and" <+> line <+>
prettyType b Open
)]
prettyNotChecks (LetNC1 contra) = prettyNotSynths contra
prettyNotChecks (LetNC2 prf contra) =
case synthsRecompute prf of
Val _ => prettyNotChecks contra
prettyNotChecks (LetTyNC {a} (This contra)) =
[(t.meta, pretty "ill-formed type" <+> line <+> prettyType a Open)]
prettyNotChecks (LetTyNC (That contra)) = prettyNotChecks contra
prettyNotChecks (LetTyNC (Both contra1 contra2)) =
(t.meta, pretty "ill-formed type" <+> line <+> prettyType a Open) ::
prettyNotChecks contra2
prettyNotChecks (AbsNC1 contra) =
[(t.meta, pretty "cannot abstract to construct type" <+> line <+> prettyType a Open)]
prettyNotChecks (AbsNC2 prf contra) =
case isFunctionRecompute prf of
(Val _, Val _) => prettyNotChecks contra
prettyNotChecks (TupNC1 contra) =
[(t.meta, pretty "cannot tuple to construct type" <+> line <+> prettyType a Open)]
prettyNotChecks (TupNC2 contras) = prettyAnyNotChecks t.meta contras
prettyNotChecks (InjNC1 contra) =
[(t.meta, pretty "cannot inject to construct type" <+> line <+> prettyType a Open)]
prettyNotChecks (InjNC2 {l} contra) =
[(t.meta
, pretty "unknown label" <++> enclose "'" "'" (pretty l) <+> line <+>
pretty "in sum type" <+> line <+>
prettyType a Open
)]
prettyNotChecks (InjNC3 i contra) =
case [| (nameOf i).value |] of
Val _ => prettyNotChecks contra
prettyNotChecks (CaseNC1 contra) = prettyNotSynths contra
prettyNotChecks (CaseNC2 prf contra) =
case synthsRecompute prf of
Val a => [(t.meta, pretty "cannot case split on type" <+> line <+> prettyType a Open)]
prettyNotChecks (CaseNC3 prf contras) =
case synthsRecompute prf of
Val _ => prettyAnyNotBranches t.meta contras
prettyNotChecks (RollNC1 contra) =
[(t.meta, pretty "cannot roll to construct type" <+> line <+> prettyType a Open)]
prettyNotChecks (RollNC2 contra) = prettyNotChecks contra
prettyNotChecks (FoldNC1 contra) = prettyNotSynths contra
prettyNotChecks (FoldNC2 prf contra) =
case synthsRecompute prf of
Val a => [(t.meta, pretty "cannot fold over type" <+> line <+> prettyType a Open)]
prettyNotChecks (FoldNC3 prf contra) =
case synthsRecompute prf of
Val _ => prettyNotChecks contra
prettyNotCheckSpine (Step1 {t} contra) =
[(t.meta, pretty "cannot apply non-function type" <+> line <+> prettyType a Open)]
prettyNotCheckSpine (Step2 (This contra)) = prettyNotChecks contra
prettyNotCheckSpine (Step2 (That contra)) = prettyNotCheckSpine contra
prettyNotCheckSpine (Step2 (Both contra1 contra2)) =
prettyNotChecks contra1 ++ prettyNotCheckSpine contra2
prettyAnyNotSynths (Step (This contra)) = prettyNotSynths contra
prettyAnyNotSynths (Step (That contra)) = prettyAnyNotSynths contra
prettyAnyNotSynths (Step (Both contra1 contra2)) =
prettyNotSynths contra1 ++ prettyAnyNotSynths contra2
prettyAnyNotChecks meta Base1 =
[(meta
, pretty "missing components" <+> line <+>
concatWith (surround $ "," <++> neutral) (map pretty as.names <>> [])
)]
prettyAnyNotChecks meta (Step1 {t, l} contra) =
[(t.meta , pretty "unknown label" <++> enclose "'" "'" (pretty l))]
prettyAnyNotChecks meta (Step2 i (This contra)) =
case [| (nameOf i).value |] of
Val _ => prettyNotChecks contra
prettyAnyNotChecks meta (Step2 i (That contra)) = prettyAnyNotChecks meta contra
prettyAnyNotChecks meta (Step2 i (Both contra1 contra2)) =
case [| (nameOf i).value |] of
Val _ => prettyNotChecks contra1 ++ prettyAnyNotChecks meta contra2
prettyAnyNotBranches meta Base1 =
[(meta
, pretty "missing cases" <+> line <+>
concatWith (surround $ "," <++> neutral) (map pretty as.names <>> [])
)]
prettyAnyNotBranches meta (Step1 {t, l} contra) =
[(t.meta , pretty "unknown label" <++> enclose "'" "'" (pretty l))]
prettyAnyNotBranches meta (Step2 i (This contra)) =
case [| (nameOf i).value |] of
Val _ => prettyNotChecks contra
prettyAnyNotBranches meta (Step2 i (That contra)) = prettyAnyNotBranches meta contra
prettyAnyNotBranches meta (Step2 i (Both contra1 contra2)) =
case [| (nameOf i).value |] of
Val _ => prettyNotChecks contra1 ++ prettyAnyNotBranches meta contra2
|