Source file pp.ml
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
open Kernel
open Basic
open Term
open Rule
open Parsers
open Format
let print_db_enabled = ref false
let print_default_name = ref false
let print_module_name = ref false
module type Sig = sig
(** [get_name] get the current module defined for printing functions. *)
val get_name : unit -> mident
end
module type Printer = sig
(** [print_list sep printer] returns a printer for ['a list] using [printer] as
element printer and [sep] as separator between elements. *)
val print_list : string -> 'a printer -> 'a list printer
val print_ident : ident printer
val print_mident : mident printer
val print_name : name printer
val print_term : term printer
val print_typed_context : typed_context printer
val print_err_ctxt : typed_context printer
val print_pattern : Rule.pattern printer
val print_untyped_rule : 'a Rule.rule printer
val print_typed_rule : Rule.typed_rule printer
val print_rule_infos : Rule.rule_infos printer
val print_rule_name : Rule.rule_name printer
val print_red_cfg : Reduction.red_cfg printer
val print_entry : Entry.entry printer
val print_staticity : Signature.staticity printer
end
module Make (S : Sig) : Printer = struct
let print_list = pp_list
let print_mident = pp_mident
let print_name = pp_name
let is_dummy_ident i = (string_of_ident i).[0] = '$'
let print_ident fmt id =
if is_dummy_ident id then Format.fprintf fmt "__" else pp_ident fmt id
let print_const out cst =
let md = md cst in
if
(not !print_module_name)
&& (not (Basic.mident_eq (Basic.mk_mident "") (S.get_name ())))
&& mident_eq md (S.get_name ())
then print_ident out (id cst)
else fprintf out "%a" pp_name cst
let is_dummy_ident i = (string_of_ident i).[0] = '$'
let is_regular_decl (_, i, _) = (string_of_ident i).[0] <> '$'
let print_db out (x, n) =
if !print_db_enabled then fprintf out "%a[%i]" print_ident x n
else print_ident out x
let print_db_or_underscore out (x, _) =
if is_dummy_ident x then fprintf out "_" else print_ident out x
let fresh_name names base =
if List.mem base names then (
let i = ref 0 in
let name i = mk_ident (string_of_ident base ^ string_of_int i) in
while List.mem (name !i) names do
incr i
done;
name !i)
else base
let rec subst ctx = function
| DB (_, x, _) as t when is_dummy_ident x -> t
| DB (l, _, n) as t -> (
try mk_DB l (List.nth ctx n) n with Failure _ -> t)
| (Kind | Type _) as t -> t
| Const (l, cst) as t ->
let m, v = (md cst, id cst) in
if
(not !print_module_name) && List.mem v ctx
&& mident_eq (S.get_name ()) m
then
let v' = mk_ident (string_of_mident m ^ "." ^ string_of_ident v) in
mk_Const l (mk_name m v')
else t
| App (f, a, args) ->
mk_App (subst ctx f) (subst ctx a) (List.map (subst ctx) args)
| Lam (l, x, None, f) ->
let x' = fresh_name ctx x in
mk_Lam l x' None (subst (x' :: ctx) f)
| Lam (l, x, Some a, f) ->
let x' = fresh_name ctx x in
mk_Lam l x' (Some (subst ctx a)) (subst (x' :: ctx) f)
| Pi (l, x, a, b) ->
let x' = if is_dummy_ident x then x else fresh_name ctx x in
mk_Pi l x' (subst ctx a) (subst (x' :: ctx) b)
let rec pp_term fmt te =
match te with
| Kind -> fprintf fmt "Kind"
| Type _ -> fprintf fmt "Type"
| DB (_, x, n) -> fprintf fmt "%a" print_db (x, n)
| Const (_, n) -> fprintf fmt "%a" print_const n
| App (f, a, args) -> pp_list " " pp_term_wp fmt (f :: a :: args)
| Lam (_, x, None, f) -> fprintf fmt "%a => %a" print_ident x pp_term f
| Lam (_, x, Some a, f) ->
fprintf fmt "%a:%a => %a" print_ident x pp_term_wp a pp_term f
| Pi (_, x, a, b) ->
if ident_eq x dmark then fprintf fmt "%a -> %a" pp_term_wp a pp_term b
else fprintf fmt "%a:%a -> %a" print_ident x pp_term_wp a pp_term b
and pp_term_wp fmt te =
match te with
| (Kind | Type _ | DB _ | Const _) as t -> pp_term fmt t
| t -> fprintf fmt "(%a)" pp_term t
let rec print_term m out t =
let one_liner = asprintf "%a" pp_term t in
if String.length one_liner <= m then fprintf out "%s" one_liner
else
match t with
| Kind -> pp_print_string out "Kind"
| Type _ -> pp_print_string out "Type"
| DB (_, x, n) -> print_db out (x, n)
| Const (_, cst) -> print_const out cst
| App (f, a, args) ->
fprintf out "@[<v 2>%a@]"
(pp_print_list (print_term_wp (m - 2)))
(f :: a :: args)
| Lam (_, x, None, f) ->
fprintf out "@[%a =>@ @[%a@]@]" print_ident x (print_term m) f
| Lam (_, x, Some a, f) ->
fprintf out "@[<v>%a:%a =>@ @[%a@]@]" print_ident x
(print_term_wp (m - String.length (string_of_ident x) - 3))
a (print_term m) f
| Pi (_, x, a, b) when ident_eq x dmark ->
fprintf out "@[<v>%a ->@ @[%a@]@]"
(print_term_wp (m - 3))
a (print_term m) b
| Pi (_, x, a, b) ->
fprintf out "@[<v>%a:%a ->@ @[%a@]@]" print_ident x (print_term_wp m)
a (print_term m) b
and print_term_wp m out = function
| (Kind | Type _ | DB _ | Const _) as t -> print_term m out t
| t -> fprintf out "(%a)" (print_term (m - 2)) t
let n_print_term n out t = print_term n out (subst [] t)
let line_length = 100
let print_term out t = n_print_term line_length out (subst [] t)
let rec print_pattern out = function
| Var (_, id, i, []) -> print_db_or_underscore out (id, i)
| Var (_, id, i, lst) ->
fprintf out "%a %a" print_db_or_underscore (id, i)
(print_list " " print_pattern_wp)
lst
| Brackets t -> fprintf out "{ %a }" print_term t
| Pattern (_, cst, []) -> fprintf out "%a" print_const cst
| Pattern (_, cst, pats) ->
fprintf out "%a %a" print_const cst
(print_list " " print_pattern_wp)
pats
| Lambda (_, x, p) ->
fprintf out "@[%a => %a@]" print_ident x print_pattern p
and print_pattern_wp out = function
| (Pattern _ | Lambda _) as p -> fprintf out "(%a)" print_pattern p
| Var (_, id, i, (_ :: _ as lst)) ->
fprintf out "(%a %a)" print_db_or_underscore (id, i)
(print_list " " print_pattern_wp)
lst
| p -> print_pattern out p
let rec print_typed_context fmt = function
| [] -> ()
| (_, x, ty) :: decls ->
fprintf fmt " @[<hv2>%a : %a@]" print_ident x print_term ty;
(match decls with [] -> () | _ -> fprintf fmt ",@.");
print_typed_context fmt decls
let print_err_ctxt fmt = function
| [] -> ()
| ctx ->
fprintf fmt " in context:@.[\n%a@.]" print_typed_context (List.rev ctx)
let print_rule_name fmt rule =
let aux b cst =
if b || !print_default_name then
if mident_eq (md cst) (S.get_name ()) then
fprintf fmt "@[<h>{%a}@] " print_ident (id cst)
else fprintf fmt "@[<h>{%a}@] " print_name cst
in
match rule with
| Beta -> ()
| Delta cst -> aux true cst
| Gamma (b, cst) -> aux b cst
let print_decl fmt (_, id, _) = fprintf fmt "@[<hv>%a@]" print_ident id
let print_typed_decl fmt (_, id, ty) =
let l = line_length - 5 - String.length (string_of_ident id) in
fprintf fmt "@[<v>%a :@,%a@]" print_ident id (n_print_term l) ty
let print_part_typed_decl fmt (l, id, ty) =
match ty with
| None -> print_decl fmt (l, id, ())
| Some ty -> print_typed_decl fmt (l, id, ty)
let print_untyped_rule fmt (rule : 'a rule) =
fprintf fmt
"@[<hov2>%a@[<h>[%a]@]@ @[<hv>@[<hov2>%a@]@ -->@ @[<hov2>%a@]@]@]@]"
print_rule_name rule.name
(print_list ", " print_decl)
(List.filter is_regular_decl rule.ctx)
print_pattern rule.pat print_term rule.rhs
let print_rule (p : (loc * ident * 'a) printer) fmt (rule : 'a rule) =
fprintf fmt
"@[<hov2>@[<h>[%a]@]@ @[<hv>@[<hov2>%a@]@ -->@ @[<hov2>%a@]@]@]@]"
(print_list ", " p) rule.ctx print_pattern rule.pat print_term rule.rhs
let print_typed_rule = print_rule print_typed_decl
let print_part_typed_rule = print_rule print_part_typed_decl
let print_rule_infos out ri =
print_untyped_rule out
{
name = ri.name;
ctx =
[]
;
pat = pattern_of_rule_infos ri;
rhs = ri.rhs;
}
let print_red_cfg fmt cfg =
let open Reduction in
fprintf fmt "%a" pp_red_cfg cfg
let print_entry fmt e =
let open Format in
let open Entry in
let scope_to_string = function
| Signature.Public -> ""
| Signature.Private -> "private "
in
match e with
| Decl (_, id, scope, Static, ty) ->
fprintf fmt "@[<2>%s%a :@ %a.@]@.@." (scope_to_string scope) print_ident
id print_term ty
| Decl (_, id, scope, Definable Free, ty) ->
fprintf fmt "@[<2>%sdef %a :@ %a.@]@.@." (scope_to_string scope)
print_ident id print_term ty
| Decl (_, id, scope, Injective, ty) ->
fprintf fmt "@[<2>%sinjective %a :@ %a.@]@.@." (scope_to_string scope)
print_ident id print_term ty
| Decl (_, id, scope, Definable AC, ty) ->
fprintf fmt "@[<2>%sdefac %a [@ %a].@]@.@." (scope_to_string scope)
print_ident id print_term ty
| Decl (_, id, scope, Definable (ACU neu), ty) ->
fprintf fmt "@[<2>%sdefacu %a [@ %a, %a].@]@.@." (scope_to_string scope)
print_ident id print_term ty print_term neu
| Def (_, id, scope, opaque, ty, te) -> (
let key = if opaque then "thm" else "def" in
match ty with
| None ->
fprintf fmt "@[<hv2>%s%s %a@ :=@ %a.@]@.@." (scope_to_string scope)
key print_ident id print_term te
| Some ty ->
fprintf fmt "@[<hv2>%s%s %a :@ %a@ :=@ %a.@]@.@."
(scope_to_string scope) key print_ident id print_term ty
print_term te)
| Rules (_, rs) ->
fprintf fmt "@[<v0>%a@].@.@." (print_list "" print_part_typed_rule) rs
| Eval (_, cfg, te) ->
fprintf fmt "#EVAL%a %a.@." print_red_cfg cfg print_term te
| Infer (_, cfg, te) ->
fprintf fmt "#INFER%a %a.@." print_red_cfg cfg print_term te
| Check (_, assrt, neg, test) -> (
let cmd = if assrt then "#ASSERT" else "#CHECK" in
let neg = if neg then "NOT" else "" in
match test with
| Convert (t1, t2) ->
fprintf fmt "%s%s %a ==@ %a.@." cmd neg print_term t1 print_term t2
| HasType (te, ty) ->
fprintf fmt "%s%s %a ::@ %a.@." cmd neg print_term te print_term ty)
| DTree (_, m, v) -> (
match m with
| None -> fprintf fmt "#GDT %a.@." print_ident v
| Some m -> fprintf fmt "#GDT %a.%a.@." print_mident m print_ident v)
| Print (_, str) -> fprintf fmt "#PRINT %S.@." str
| Name (_, _) -> ()
| Require (_, md) -> fprintf fmt "#REQUIRE %a.@." print_mident md
(** The pretty printer for the type [Signature.staticity] *)
let print_staticity fmt s =
fprintf fmt "%s" (if s = Signature.Static then "Static" else "Definable")
end
module Default = Make (struct
let get_name () = Basic.mk_mident ""
end)