~ubuntu-branches/ubuntu/wily/coq-doc/wily

« back to all changes in this revision

Viewing changes to parsing/prettyp.ml

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu, Stéphane Glondu, Samuel Mimram
  • Date: 2010-01-07 22:50:39 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100107225039-n3cq82589u0qt0s2
Tags: 8.2pl1-1
[ Stéphane Glondu ]
* New upstream release (Closes: #563669)
  - remove patches
* Packaging overhaul:
  - use git, advertise it in Vcs-* fields of debian/control
  - use debhelper 7 and dh with override
  - use source format 3.0 (quilt)
* debian/control:
  - set Maintainer to d-o-m, set Uploaders to Sam and myself
  - add Homepage field
  - bump Standards-Version to 3.8.3
* Register PDF documentation into doc-base
* Add debian/watch
* Update debian/copyright

[ Samuel Mimram ]
* Change coq-doc's description to mention that it provides documentation in
  pdf format, not postscript, closes: #543545.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(************************************************************************)
 
2
(*  v      *   The Coq Proof Assistant  /  The Coq Development Team     *)
 
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
 
4
(*   \VV/  **************************************************************)
 
5
(*    //   *      This file is distributed under the terms of the       *)
 
6
(*         *       GNU Lesser General Public License Version 2.1        *)
 
7
(************************************************************************)
 
8
 
 
9
(* Changed by (and thus parts copyright ©) by Lionel Elie Mamane <lionel@mamane.lu>
 
10
 * on May-June 2006 for implementation of abstraction of pretty-printing of objects.
 
11
 *)
 
12
 
 
13
(* $Id: prettyp.ml 12187 2009-06-13 19:36:59Z msozeau $ *)
 
14
 
 
15
open Pp
 
16
open Util
 
17
open Names
 
18
open Nameops
 
19
open Term
 
20
open Termops
 
21
open Declarations
 
22
open Inductive
 
23
open Inductiveops
 
24
open Sign
 
25
open Reduction
 
26
open Environ
 
27
open Declare
 
28
open Impargs
 
29
open Libobject
 
30
open Printer
 
31
open Printmod
 
32
open Libnames
 
33
open Nametab
 
34
open Recordops
 
35
 
 
36
type object_pr = {
 
37
  print_inductive           : mutual_inductive -> std_ppcmds;
 
38
  print_constant_with_infos : constant -> std_ppcmds;
 
39
  print_section_variable    : variable -> std_ppcmds;
 
40
  print_syntactic_def       : kernel_name -> std_ppcmds;
 
41
  print_module              : bool -> Names.module_path -> std_ppcmds;
 
42
  print_modtype             : module_path -> std_ppcmds;
 
43
  print_named_decl          : identifier * constr option * types -> std_ppcmds;
 
44
  print_leaf_entry          : bool -> Libnames.object_name * Libobject.obj -> Pp.std_ppcmds;
 
45
  print_library_entry       : bool -> (object_name * Lib.node) -> std_ppcmds option;
 
46
  print_context             : bool -> int option -> Lib.library_segment -> std_ppcmds;
 
47
  print_typed_value_in_env  : Environ.env -> Term.constr * Term.types -> Pp.std_ppcmds;
 
48
  print_eval                : Reductionops.reduction_function -> env -> Evd.evar_map -> Topconstr.constr_expr -> unsafe_judgment -> std_ppcmds;
 
49
}
 
50
 
 
51
let gallina_print_module  = print_module
 
52
let gallina_print_modtype = print_modtype
 
53
 
 
54
(*********************)
 
55
(** Basic printing   *)
 
56
 
 
57
let print_basename sp = pr_global (ConstRef sp)
 
58
 
 
59
let print_closed_sections = ref false
 
60
 
 
61
let with_line_skip p = if ismt p then mt() else (fnl () ++ p)
 
62
 
 
63
(********************************)
 
64
(** Printing implicit arguments *)
 
65
                                          
 
66
let conjugate_to_be = function [_] -> "is" | _ -> "are"
 
67
 
 
68
let pr_implicit imp = pr_id (name_of_implicit imp)
 
69
 
 
70
let print_impl_args_by_name max = function
 
71
  | []  -> mt ()
 
72
  | impls -> 
 
73
      hov 0 (str (plural (List.length impls) "Argument") ++ spc() ++ 
 
74
      prlist_with_sep pr_coma pr_implicit impls ++ spc() ++ 
 
75
      str (conjugate_to_be impls) ++ str" implicit" ++
 
76
      (if max then strbrk " and maximally inserted" else mt())) ++ fnl()
 
77
 
 
78
let print_impl_args l = 
 
79
  let imps = List.filter is_status_implicit l in
 
80
  let maximps = List.filter Impargs.maximal_insertion_of imps in
 
81
  let nonmaximps = list_subtract imps maximps in
 
82
  print_impl_args_by_name false nonmaximps ++
 
83
  print_impl_args_by_name true maximps
 
84
 
 
85
(*********************)
 
86
(** Printing Scopes  *)
 
87
 
 
88
let print_ref reduce ref =
 
89
  let typ = Global.type_of_global ref in
 
90
  let typ = 
 
91
    if reduce then
 
92
      let ctx,ccl = Reductionops.splay_prod_assum (Global.env()) Evd.empty typ
 
93
      in it_mkProd_or_LetIn ccl ctx 
 
94
    else typ in
 
95
  hov 0 (pr_global ref ++ str " :" ++ spc () ++ pr_ltype typ) ++ fnl ()
 
96
 
 
97
let print_argument_scopes = function
 
98
  | [Some sc] -> str"Argument scope is [" ++ str sc ++ str"]" ++ fnl()
 
99
  | l when not (List.for_all ((=) None) l) ->
 
100
      hov 2 (str"Argument scopes are" ++ spc() ++ 
 
101
      str "[" ++ 
 
102
      prlist_with_sep spc (function Some sc -> str sc | None -> str "_") l ++
 
103
      str "]") ++ fnl()
 
104
  | _  -> mt()
 
105
 
 
106
let need_expansion impl ref = 
 
107
  let typ = Global.type_of_global ref in
 
108
  let ctx = fst (decompose_prod_assum typ) in
 
109
  let nprods = List.length (List.filter (fun (_,b,_) -> b=None) ctx) in
 
110
  impl <> [] & List.length impl >= nprods &
 
111
    let _,lastimpl = list_chop nprods impl in
 
112
      List.filter is_status_implicit lastimpl <> []
 
113
 
 
114
type opacity =
 
115
  | FullyOpaque
 
116
  | TransparentMaybeOpacified of Conv_oracle.level
 
117
 
 
118
let opacity env = function
 
119
  | VarRef v when pi2 (Environ.lookup_named v env) <> None -> 
 
120
      Some(TransparentMaybeOpacified (Conv_oracle.get_strategy(VarKey v)))
 
121
  | ConstRef cst ->
 
122
      let cb = Environ.lookup_constant cst env in
 
123
      if cb.const_body = None then None
 
124
      else if cb.const_opaque then Some FullyOpaque
 
125
      else Some
 
126
        (TransparentMaybeOpacified (Conv_oracle.get_strategy(ConstKey cst)))
 
127
  | _ -> None
 
128
 
 
129
let print_opacity ref =
 
130
  match opacity (Global.env()) ref with
 
131
    | None -> mt ()
 
132
    | Some s -> pr_global ref ++ str " is " ++ 
 
133
        str (match s with
 
134
          | FullyOpaque -> "opaque"
 
135
          | TransparentMaybeOpacified Conv_oracle.Opaque ->
 
136
              "basically transparent but considered opaque for reduction"
 
137
          | TransparentMaybeOpacified lev when lev = Conv_oracle.transparent ->
 
138
              "transparent"
 
139
          | TransparentMaybeOpacified (Conv_oracle.Level n) ->
 
140
              "transparent (with expansion weight "^string_of_int n^")"
 
141
          | TransparentMaybeOpacified Conv_oracle.Expand ->
 
142
              "transparent (with minimal expansion weight)") ++ fnl()
 
143
    
 
144
let print_name_infos ref =
 
145
  let impl = implicits_of_global ref in
 
146
  let scopes = Notation.find_arguments_scope ref in
 
147
  let type_for_implicit = 
 
148
    if need_expansion impl ref then
 
149
      (* Need to reduce since implicits are computed with products flattened *)
 
150
      str "Expanded type for implicit arguments" ++ fnl () ++ 
 
151
      print_ref true ref ++ fnl()
 
152
    else mt() in
 
153
  type_for_implicit ++ print_impl_args impl ++ print_argument_scopes scopes
 
154
 
 
155
let print_id_args_data test pr id l =
 
156
  if List.exists test l then
 
157
    str"For " ++ pr_id id ++ str": " ++ pr l
 
158
  else 
 
159
    mt()
 
160
 
 
161
let print_args_data_of_inductive_ids get test pr sp mipv =
 
162
  prvecti
 
163
    (fun i mip -> 
 
164
      print_id_args_data test pr mip.mind_typename (get (IndRef (sp,i))) ++
 
165
      prvecti 
 
166
        (fun j idc ->
 
167
          print_id_args_data test pr idc (get (ConstructRef ((sp,i),j+1))))
 
168
        mip.mind_consnames)
 
169
    mipv
 
170
 
 
171
let print_inductive_implicit_args =
 
172
  print_args_data_of_inductive_ids
 
173
    implicits_of_global is_status_implicit print_impl_args
 
174
 
 
175
let print_inductive_argument_scopes =
 
176
  print_args_data_of_inductive_ids 
 
177
    Notation.find_arguments_scope ((<>) None) print_argument_scopes
 
178
 
 
179
(*********************)
 
180
(* "Locate" commands *)
 
181
 
 
182
type logical_name =
 
183
  | Term of global_reference
 
184
  | Dir of global_dir_reference
 
185
  | Syntactic of kernel_name
 
186
  | ModuleType of qualid * module_path
 
187
  | Undefined of qualid
 
188
 
 
189
let locate_any_name ref =
 
190
  let module N = Nametab in
 
191
  let (loc,qid) = qualid_of_reference ref in
 
192
  try Term (N.locate qid)
 
193
  with Not_found -> 
 
194
  try Syntactic (N.locate_syntactic_definition qid)
 
195
  with Not_found ->
 
196
  try Dir (N.locate_dir qid)
 
197
  with Not_found ->
 
198
  try ModuleType (qid, N.locate_modtype qid)
 
199
  with Not_found -> Undefined qid
 
200
 
 
201
let pr_located_qualid = function
 
202
  | Term ref ->
 
203
      let ref_str = match ref with
 
204
          ConstRef _ -> "Constant"
 
205
        | IndRef _ -> "Inductive"
 
206
        | ConstructRef _ -> "Constructor"
 
207
        | VarRef _ -> "Variable" in
 
208
      str ref_str ++ spc () ++ pr_sp (Nametab.sp_of_global ref)
 
209
  | Syntactic kn ->
 
210
      str "Notation" ++ spc () ++ pr_sp (Nametab.sp_of_syntactic_definition kn)
 
211
  | Dir dir ->
 
212
      let s,dir = match dir with
 
213
        | DirOpenModule (dir,_) -> "Open Module", dir
 
214
        | DirOpenModtype (dir,_) -> "Open Module Type", dir
 
215
        | DirOpenSection (dir,_) -> "Open Section", dir
 
216
        | DirModule (dir,_) -> "Module", dir
 
217
        | DirClosedSection dir -> "Closed Section", dir
 
218
      in
 
219
      str s ++ spc () ++ pr_dirpath dir
 
220
  | ModuleType (qid,_) ->
 
221
      str "Module Type" ++ spc () ++ pr_sp (Nametab.full_name_modtype qid)
 
222
  | Undefined qid ->    
 
223
      pr_qualid qid ++ spc () ++ str "not a defined object."
 
224
 
 
225
let print_located_qualid ref =
 
226
  let (loc,qid) = qualid_of_reference ref in
 
227
  let module N = Nametab in
 
228
  let expand = function
 
229
    | TrueGlobal ref ->
 
230
        Term ref, N.shortest_qualid_of_global Idset.empty ref
 
231
    | SyntacticDef kn ->
 
232
        Syntactic kn, N.shortest_qualid_of_syndef Idset.empty kn in
 
233
  match List.map expand (N.extended_locate_all qid) with
 
234
    | [] -> 
 
235
        let (dir,id) = repr_qualid qid in
 
236
        if dir = empty_dirpath then
 
237
          str "No object of basename " ++ pr_id id
 
238
        else
 
239
          str "No object of suffix " ++ pr_qualid qid
 
240
    | l ->
 
241
        prlist_with_sep fnl
 
242
        (fun (o,oqid) ->
 
243
          hov 2 (pr_located_qualid o ++
 
244
          (if oqid <> qid then
 
245
            spc() ++ str "(shorter name to refer to it in current context is " ++ pr_qualid oqid ++ str")"
 
246
          else
 
247
            mt ()))) l
 
248
 
 
249
(******************************************)
 
250
(**** Printing declarations and judgments *)
 
251
(****  Gallina layer                  *****)
 
252
 
 
253
let gallina_print_typed_value_in_env env (trm,typ) =
 
254
  (pr_lconstr_env env trm ++ fnl () ++
 
255
     str "     : " ++ pr_ltype_env env typ ++ fnl ())
 
256
 
 
257
(* To be improved; the type should be used to provide the types in the
 
258
   abstractions. This should be done recursively inside pr_lconstr, so that
 
259
   the pretty-print of a proposition (P:(nat->nat)->Prop)(P [u]u)
 
260
   synthesizes the type nat of the abstraction on u *)
 
261
 
 
262
let print_named_def name body typ =
 
263
  let pbody = pr_lconstr body in
 
264
  let ptyp = pr_ltype typ in
 
265
  let pbody = if isCast body then surround pbody else pbody in
 
266
  (str "*** [" ++ str name ++ str " " ++
 
267
     hov 0 (str ":=" ++ brk (1,2) ++ pbody ++ spc () ++
 
268
              str ":" ++ brk (1,2) ++ ptyp) ++
 
269
           str "]")
 
270
 
 
271
let print_named_assum name typ =
 
272
  str "*** [" ++ str name ++ str " : " ++ pr_ltype typ ++ str "]"
 
273
 
 
274
let gallina_print_named_decl (id,c,typ) =
 
275
  let s = string_of_id id in
 
276
  match c with
 
277
    | Some body -> print_named_def s body typ
 
278
    | None -> print_named_assum s typ
 
279
 
 
280
let assumptions_for_print lna =
 
281
  List.fold_right (fun na env -> add_name na env) lna empty_names_context
 
282
 
 
283
(*********************)
 
284
(* *)
 
285
 
 
286
let print_params env params =
 
287
  if params = [] then mt () else pr_rel_context env params ++ brk(1,2)
 
288
 
 
289
let print_constructors envpar names types =
 
290
  let pc =
 
291
    prlist_with_sep (fun () -> brk(1,0) ++ str "| ")
 
292
      (fun (id,c) -> pr_id id ++ str " : " ++ pr_lconstr_env envpar c)
 
293
      (Array.to_list (array_map2 (fun n t -> (n,t)) names types))
 
294
  in 
 
295
  hv 0 (str "  " ++ pc)
 
296
 
 
297
let build_inductive sp tyi =
 
298
  let (mib,mip) = Global.lookup_inductive (sp,tyi) in
 
299
  let params = mib.mind_params_ctxt in
 
300
  let args = extended_rel_list 0 params in
 
301
  let env = Global.env() in
 
302
  let fullarity = match mip.mind_arity with
 
303
    | Monomorphic ar -> ar.mind_user_arity 
 
304
    | Polymorphic ar ->
 
305
        it_mkProd_or_LetIn (mkSort (Type ar.poly_level)) mip.mind_arity_ctxt in
 
306
  let arity = hnf_prod_applist env fullarity args in
 
307
  let cstrtypes = type_of_constructors env (sp,tyi) in
 
308
  let cstrtypes =
 
309
    Array.map (fun c -> hnf_prod_applist env c args) cstrtypes in
 
310
  let cstrnames = mip.mind_consnames in
 
311
  (IndRef (sp,tyi), params, arity, cstrnames, cstrtypes)
 
312
 
 
313
let print_one_inductive (sp,tyi) =
 
314
  let (ref, params, arity, cstrnames, cstrtypes) = build_inductive sp tyi in
 
315
  let env = Global.env () in
 
316
  let envpar = push_rel_context params env in
 
317
  hov 0 (
 
318
    pr_global (IndRef (sp,tyi)) ++ brk(1,4) ++ print_params env params ++
 
319
    str ": " ++ pr_lconstr_env envpar arity ++ str " :=") ++
 
320
  brk(0,2) ++ print_constructors envpar cstrnames cstrtypes
 
321
 
 
322
let pr_mutual_inductive finite indl =
 
323
  hov 0 (
 
324
    str (if finite then "Inductive " else "CoInductive ") ++
 
325
    prlist_with_sep (fun () -> fnl () ++ str"  with ")
 
326
      print_one_inductive indl)
 
327
 
 
328
let get_fields =
 
329
  let rec prodec_rec l subst c =
 
330
    match kind_of_term c with
 
331
    | Prod (na,t,c) ->
 
332
        let id = match na with Name id -> id | Anonymous -> id_of_string "_" in
 
333
        prodec_rec ((id,true,substl subst t)::l) (mkVar id::subst) c
 
334
    | LetIn (na,b,_,c) ->
 
335
        let id = match na with Name id -> id | Anonymous -> id_of_string "_" in
 
336
        prodec_rec ((id,false,substl subst b)::l) (mkVar id::subst) c
 
337
    | _               -> List.rev l
 
338
  in 
 
339
  prodec_rec [] []
 
340
 
 
341
let pr_record (sp,tyi) =
 
342
  let (ref, params, arity, cstrnames, cstrtypes) = build_inductive sp tyi in
 
343
  let env = Global.env () in
 
344
  let envpar = push_rel_context params env in
 
345
  let fields = get_fields cstrtypes.(0) in
 
346
  hov 0 (
 
347
    hov 0 (
 
348
      str "Record " ++ pr_global (IndRef (sp,tyi)) ++ brk(1,4) ++ 
 
349
      print_params env params ++
 
350
      str ": " ++ pr_lconstr_env envpar arity ++ brk(1,2) ++ 
 
351
      str ":= " ++ pr_id cstrnames.(0)) ++ 
 
352
    brk(1,2) ++
 
353
    hv 2 (str "{" ++
 
354
      prlist_with_sep (fun () -> str ";" ++ brk(1,0))
 
355
        (fun (id,b,c) -> 
 
356
          str " " ++ pr_id id ++ str (if b then " : " else " := ") ++ 
 
357
          pr_lconstr_env envpar c) fields) ++ str" }")
 
358
 
 
359
let gallina_print_inductive sp =
 
360
  let (mib,mip) = Global.lookup_inductive (sp,0) in
 
361
  let mipv = mib.mind_packets in
 
362
  let names = list_tabulate (fun x -> (sp,x)) (Array.length mipv) in
 
363
  (if mib.mind_record & not !Flags.raw_print then
 
364
    pr_record (List.hd names)
 
365
  else
 
366
    pr_mutual_inductive mib.mind_finite names) ++ fnl () ++
 
367
  with_line_skip 
 
368
    (print_inductive_implicit_args sp mipv ++
 
369
     print_inductive_argument_scopes sp mipv)
 
370
 
 
371
let print_named_decl id = 
 
372
  gallina_print_named_decl (Global.lookup_named id) ++ fnl ()
 
373
 
 
374
let gallina_print_section_variable id =
 
375
  print_named_decl id ++
 
376
  with_line_skip (print_name_infos (VarRef id))
 
377
 
 
378
let print_body = function
 
379
  | Some lc  -> pr_lconstr (Declarations.force lc)
 
380
  | None -> (str"<no body>")
 
381
 
 
382
let print_typed_body (val_0,typ) =
 
383
  (print_body val_0 ++ fnl () ++ str "     : " ++ pr_ltype typ)
 
384
 
 
385
let ungeneralized_type_of_constant_type = function
 
386
  | PolymorphicArity (ctx,a) -> mkArity (ctx, Type a.poly_level)
 
387
  | NonPolymorphicType t -> t
 
388
 
 
389
let print_constant with_values sep sp =
 
390
  let cb = Global.lookup_constant sp in
 
391
  let val_0 = cb.const_body in
 
392
  let typ = ungeneralized_type_of_constant_type cb.const_type in
 
393
  hov 0 (
 
394
    match val_0 with 
 
395
    | None -> 
 
396
        str"*** [ " ++ 
 
397
        print_basename sp ++ str " : " ++ cut () ++ pr_ltype typ ++ 
 
398
        str" ]"
 
399
    | _ -> 
 
400
        print_basename sp ++ str sep ++ cut () ++
 
401
        (if with_values then print_typed_body (val_0,typ) else pr_ltype typ))
 
402
  ++ fnl ()
 
403
 
 
404
let gallina_print_constant_with_infos sp =
 
405
  print_constant true " = " sp ++ 
 
406
  with_line_skip (print_name_infos (ConstRef sp))
 
407
 
 
408
let gallina_print_syntactic_def kn =
 
409
  let sep = " := "
 
410
  and qid = Nametab.shortest_qualid_of_syndef Idset.empty kn
 
411
  and (vars,a) = Syntax_def.search_syntactic_definition dummy_loc kn in 
 
412
  let c = Topconstr.rawconstr_of_aconstr dummy_loc a in
 
413
  str "Notation " ++ pr_qualid qid ++ 
 
414
  prlist_with_sep spc pr_id (List.map fst vars) ++ str sep ++
 
415
  Constrextern.without_symbols pr_lrawconstr c ++ fnl ()
 
416
 
 
417
let gallina_print_leaf_entry with_values ((sp,kn as oname),lobj) =
 
418
  let sep = if with_values then " = " else " : "
 
419
  and tag = object_tag lobj in
 
420
    match (oname,tag) with
 
421
      | (_,"VARIABLE") ->
 
422
          (* Outside sections, VARIABLES still exist but only with universes 
 
423
             constraints *)
 
424
          (try Some(print_named_decl (basename sp)) with Not_found -> None)
 
425
      | (_,"CONSTANT") ->
 
426
          Some (print_constant with_values sep (constant_of_kn kn))
 
427
      | (_,"INDUCTIVE") ->
 
428
          Some (gallina_print_inductive kn)
 
429
      | (_,"MODULE") ->
 
430
          let (mp,_,l) = repr_kn kn in 
 
431
            Some (print_module with_values (MPdot (mp,l)))
 
432
      | (_,"MODULE TYPE") ->
 
433
          let (mp,_,l) = repr_kn kn in 
 
434
          Some (print_modtype (MPdot (mp,l)))
 
435
      | (_,("AUTOHINT"|"GRAMMAR"|"SYNTAXCONSTANT"|"PPSYNTAX"|"TOKEN"|"CLASS"|
 
436
            "COERCION"|"REQUIRE"|"END-SECTION"|"STRUCTURE")) -> None
 
437
      (* To deal with forgotten cases... *)
 
438
      | (_,s) -> None
 
439
 
 
440
let gallina_print_library_entry with_values ent = 
 
441
  let pr_name (sp,_) = pr_id (basename sp) in
 
442
  match ent with
 
443
    | (oname,Lib.Leaf lobj) -> 
 
444
        gallina_print_leaf_entry with_values (oname,lobj)
 
445
    | (oname,Lib.OpenedSection (dir,_)) -> 
 
446
        Some (str " >>>>>>> Section " ++ pr_name oname)
 
447
    | (oname,Lib.ClosedSection _) -> 
 
448
        Some (str " >>>>>>> Closed Section " ++ pr_name oname)
 
449
    | (_,Lib.CompilingLibrary (dir,_)) ->
 
450
        Some (str " >>>>>>> Library " ++ pr_dirpath dir)
 
451
    | (oname,Lib.OpenedModule _) ->
 
452
        Some (str " >>>>>>> Module " ++ pr_name oname)
 
453
    | (oname,Lib.ClosedModule _) -> 
 
454
        Some (str " >>>>>>> Closed Module " ++ pr_name oname)
 
455
    | (oname,Lib.OpenedModtype _) ->
 
456
        Some (str " >>>>>>> Module Type " ++ pr_name oname)
 
457
    | (oname,Lib.ClosedModtype _) -> 
 
458
        Some (str " >>>>>>> Closed Module Type " ++ pr_name oname)
 
459
    | (_,Lib.FrozenState _) ->
 
460
        None
 
461
 
 
462
let gallina_print_leaf_entry with_values c =
 
463
  match gallina_print_leaf_entry with_values c with
 
464
    | None    -> mt ()
 
465
    | Some pp -> pp ++ fnl()
 
466
 
 
467
let gallina_print_context with_values = 
 
468
  let rec prec n = function
 
469
    | h::rest when n = None or Option.get n > 0 -> 
 
470
        (match gallina_print_library_entry with_values h with
 
471
          | None -> prec n rest
 
472
          | Some pp -> prec (Option.map ((+) (-1)) n) rest ++ pp ++ fnl ())
 
473
    | _ -> mt ()
 
474
  in 
 
475
  prec
 
476
 
 
477
let gallina_print_eval red_fun env evmap _ {uj_val=trm;uj_type=typ} =
 
478
  let ntrm = red_fun env evmap trm in
 
479
  (str "     = " ++ gallina_print_typed_value_in_env env (ntrm,typ))
 
480
 
 
481
(******************************************)
 
482
(**** Printing abstraction layer          *)
 
483
 
 
484
let default_object_pr = {
 
485
  print_inductive           = gallina_print_inductive;
 
486
  print_constant_with_infos = gallina_print_constant_with_infos;
 
487
  print_section_variable    = gallina_print_section_variable;
 
488
  print_syntactic_def       = gallina_print_syntactic_def;
 
489
  print_module              = gallina_print_module;
 
490
  print_modtype             = gallina_print_modtype;
 
491
  print_named_decl          = gallina_print_named_decl;
 
492
  print_leaf_entry          = gallina_print_leaf_entry;
 
493
  print_library_entry       = gallina_print_library_entry;
 
494
  print_context             = gallina_print_context;
 
495
  print_typed_value_in_env  = gallina_print_typed_value_in_env;
 
496
  print_eval                = gallina_print_eval;
 
497
}
 
498
 
 
499
let object_pr = ref default_object_pr
 
500
let set_object_pr = (:=) object_pr
 
501
 
 
502
let print_inductive x = !object_pr.print_inductive x
 
503
let print_constant_with_infos c = !object_pr.print_constant_with_infos c
 
504
let print_section_variable c = !object_pr.print_section_variable c
 
505
let print_syntactic_def x = !object_pr.print_syntactic_def x
 
506
let print_module x  = !object_pr.print_module  x
 
507
let print_modtype x = !object_pr.print_modtype x
 
508
let print_named_decl x = !object_pr.print_named_decl x
 
509
let print_leaf_entry x = !object_pr.print_leaf_entry x
 
510
let print_library_entry x = !object_pr.print_library_entry x
 
511
let print_context x = !object_pr.print_context x
 
512
let print_typed_value_in_env x = !object_pr.print_typed_value_in_env x
 
513
let print_eval x = !object_pr.print_eval x
 
514
 
 
515
(******************************************)
 
516
(**** Printing declarations and judgments *)
 
517
(****  Abstract layer                 *****)
 
518
 
 
519
let print_typed_value x = print_typed_value_in_env (Global.env ()) x
 
520
 
 
521
let print_judgment env {uj_val=trm;uj_type=typ} =
 
522
  print_typed_value_in_env env (trm, typ)
 
523
    
 
524
let print_safe_judgment env j =
 
525
  let trm = Safe_typing.j_val j in
 
526
  let typ = Safe_typing.j_type j in
 
527
  print_typed_value_in_env env (trm, typ)
 
528
    
 
529
(*********************)
 
530
(* *)
 
531
 
 
532
let print_full_context () = 
 
533
  print_context true None (Lib.contents_after None)
 
534
 
 
535
let print_full_context_typ () =
 
536
  print_context false None (Lib.contents_after None)
 
537
 
 
538
let print_full_pure_context () =
 
539
  let rec prec = function
 
540
  | ((_,kn),Lib.Leaf lobj)::rest ->
 
541
      let pp = match object_tag lobj with
 
542
      | "CONSTANT" ->
 
543
          let con = constant_of_kn kn in
 
544
          let cb = Global.lookup_constant con in
 
545
          let val_0 = cb.const_body in
 
546
          let typ = ungeneralized_type_of_constant_type cb.const_type in
 
547
          hov 0 (
 
548
            match val_0 with 
 
549
            | None ->
 
550
                str (if cb.const_opaque then "Axiom " else "Parameter ") ++
 
551
                print_basename con ++ str " : " ++ cut () ++ pr_ltype typ
 
552
            | Some v ->
 
553
                if cb.const_opaque then
 
554
                  str "Theorem " ++ print_basename con ++ cut () ++ 
 
555
                  str " : " ++ pr_ltype typ ++ str "." ++ fnl () ++
 
556
                  str "Proof " ++ print_body val_0
 
557
                else
 
558
                  str "Definition " ++ print_basename con ++ cut () ++ 
 
559
                  str "  : " ++ pr_ltype typ ++ cut () ++ str " := " ++
 
560
                  print_body val_0) ++ str "." ++ fnl () ++ fnl ()
 
561
      | "INDUCTIVE" ->
 
562
          let (mib,mip) = Global.lookup_inductive (kn,0) in
 
563
          let mipv = mib.mind_packets in
 
564
          let names = list_tabulate (fun x -> (kn,x)) (Array.length mipv) in
 
565
          pr_mutual_inductive mib.mind_finite names ++ str "." ++ 
 
566
          fnl () ++ fnl ()
 
567
      | "MODULE" ->
 
568
          (* TODO: make it reparsable *)
 
569
          let (mp,_,l) = repr_kn kn in 
 
570
          print_module true (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
 
571
      | "MODULE TYPE" ->
 
572
          (* TODO: make it reparsable *)
 
573
          (* TODO: make it reparsable *)
 
574
          let (mp,_,l) = repr_kn kn in
 
575
          print_modtype (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
 
576
      | _ -> mt () in
 
577
      prec rest ++ pp
 
578
  | _::rest -> prec rest
 
579
  | _ -> mt () in 
 
580
  prec (Lib.contents_after None)
 
581
 
 
582
(* For printing an inductive definition with
 
583
   its constructors and elimination,
 
584
   assume that the declaration of constructors and eliminations
 
585
   follows the definition of the inductive type *)
 
586
 
 
587
let list_filter_vec f vec = 
 
588
  let rec frec n lf = 
 
589
    if n < 0 then lf 
 
590
    else if f vec.(n) then 
 
591
      frec (n-1) (vec.(n)::lf)
 
592
    else 
 
593
      frec (n-1) lf
 
594
  in 
 
595
  frec (Array.length vec -1) []
 
596
 
 
597
(* This is designed to print the contents of an opened section *)
 
598
let read_sec_context r =
 
599
  let loc,qid = qualid_of_reference r in
 
600
  let dir =
 
601
    try Nametab.locate_section qid
 
602
    with Not_found ->
 
603
      user_err_loc (loc,"read_sec_context", str "Unknown section.") in
 
604
  let rec get_cxt in_cxt = function
 
605
    | (_,Lib.OpenedSection ((dir',_),_) as hd)::rest ->
 
606
        if dir = dir' then (hd::in_cxt) else get_cxt (hd::in_cxt) rest
 
607
    | (_,Lib.ClosedSection _)::rest ->
 
608
        error "Cannot print the contents of a closed section."
 
609
        (* LEM: Actually, we could if we wanted to. *)
 
610
    | [] -> []
 
611
    | hd::rest -> get_cxt (hd::in_cxt) rest 
 
612
  in
 
613
  let cxt = (Lib.contents_after None) in
 
614
  List.rev (get_cxt [] cxt)
 
615
 
 
616
let print_sec_context sec = 
 
617
  print_context true None (read_sec_context sec)
 
618
 
 
619
let print_sec_context_typ sec =
 
620
  print_context false None (read_sec_context sec)
 
621
 
 
622
let print_name ref = 
 
623
  match locate_any_name ref with
 
624
  | Term (ConstRef sp) -> print_constant_with_infos sp
 
625
  | Term (IndRef (sp,_)) -> print_inductive sp
 
626
  | Term (ConstructRef ((sp,_),_)) -> print_inductive sp
 
627
  | Term (VarRef sp) -> print_section_variable sp
 
628
  | Syntactic kn -> print_syntactic_def kn
 
629
  | Dir (DirModule(dirpath,(mp,_))) -> print_module (printable_body dirpath) mp
 
630
  | Dir _ -> mt ()
 
631
  | ModuleType (_,kn) -> print_modtype kn
 
632
  | Undefined qid ->
 
633
  try  (* Var locale de but, pas var de section... donc pas d'implicits *)
 
634
    let dir,str = repr_qualid qid in 
 
635
    if (repr_dirpath dir) <> [] then raise Not_found;
 
636
    let (_,c,typ) = Global.lookup_named str in 
 
637
    (print_named_decl (str,c,typ))
 
638
  with Not_found ->
 
639
  try 
 
640
    let sp = Nametab.locate_obj qid in
 
641
    let (oname,lobj) = 
 
642
      let (oname,entry) =
 
643
        List.find (fun en -> (fst (fst en)) = sp) (Lib.contents_after None)
 
644
      in
 
645
      match entry with
 
646
        | Lib.Leaf obj -> (oname,obj)
 
647
        | _ -> raise Not_found
 
648
    in
 
649
    print_leaf_entry true (oname,lobj)
 
650
  with Not_found ->
 
651
    errorlabstrm
 
652
      "print_name" (pr_qualid qid ++ spc () ++ str "not a defined object.")
 
653
 
 
654
let print_opaque_name qid = 
 
655
  let env = Global.env () in
 
656
  match global qid with
 
657
    | ConstRef cst ->
 
658
        let cb = Global.lookup_constant cst in
 
659
        if cb.const_body <> None then
 
660
          print_constant_with_infos cst
 
661
        else 
 
662
          error "Not a defined constant."
 
663
    | IndRef (sp,_) ->
 
664
        print_inductive sp
 
665
    | ConstructRef cstr -> 
 
666
        let ty = Inductiveops.type_of_constructor env cstr in
 
667
        print_typed_value (mkConstruct cstr, ty)
 
668
    | VarRef id ->
 
669
        let (_,c,ty) = lookup_named id env in 
 
670
        print_named_decl (id,c,ty)
 
671
 
 
672
let print_about ref = 
 
673
  let k = locate_any_name ref in
 
674
  begin match k with
 
675
  | Term ref ->
 
676
      print_ref false ref ++ fnl () ++ print_name_infos ref ++ 
 
677
      print_opacity ref
 
678
  | Syntactic kn ->
 
679
      print_syntactic_def kn
 
680
  | Dir _ | ModuleType _ | Undefined _ ->
 
681
      mt () end
 
682
  ++
 
683
  hov 0 (str "Expands to: " ++ pr_located_qualid k)
 
684
 
 
685
let print_impargs ref =
 
686
  let ref = Nametab.global ref in
 
687
  let impl = implicits_of_global ref in
 
688
  let has_impl = List.filter is_status_implicit impl <> [] in
 
689
  (* Need to reduce since implicits are computed with products flattened *)
 
690
  print_ref (need_expansion impl ref) ref ++ fnl() ++
 
691
  (if has_impl then print_impl_args impl 
 
692
   else (str "No implicit arguments" ++ fnl ()))
 
693
 
 
694
let unfold_head_fconst = 
 
695
  let rec unfrec k = match kind_of_term k with
 
696
    | Const cst -> constant_value (Global.env ()) cst 
 
697
    | Lambda (na,t,b) -> mkLambda (na,t,unfrec b)
 
698
    | App (f,v) -> appvect (unfrec f,v)
 
699
    | _ -> k
 
700
  in 
 
701
  unfrec
 
702
 
 
703
(* for debug *)
 
704
let inspect depth = 
 
705
  print_context false (Some depth) (Lib.contents_after None)
 
706
 
 
707
 
 
708
(*************************************************************************)
 
709
(* Pretty-printing functions coming from classops.ml                     *)
 
710
 
 
711
open Classops
 
712
 
 
713
let print_coercion_value v = pr_lconstr (get_coercion_value v)
 
714
 
 
715
let print_class i =
 
716
  let cl,_ = class_info_from_index i in
 
717
  pr_class cl
 
718
  
 
719
let print_path ((i,j),p) = 
 
720
  hov 2 (
 
721
    str"[" ++ hov 0 (prlist_with_sep pr_semicolon print_coercion_value p) ++
 
722
    str"] : ") ++
 
723
  print_class i ++ str" >-> " ++ print_class j
 
724
 
 
725
let _ = Classops.install_path_printer print_path
 
726
 
 
727
let print_graph () = 
 
728
  prlist_with_sep pr_fnl print_path (inheritance_graph())
 
729
 
 
730
let print_classes () = 
 
731
  prlist_with_sep pr_spc pr_class (classes())
 
732
 
 
733
let print_coercions () = 
 
734
  prlist_with_sep pr_spc print_coercion_value (coercions())
 
735
  
 
736
let index_of_class cl =
 
737
  try 
 
738
    fst (class_info cl)
 
739
  with _ -> 
 
740
    errorlabstrm "index_of_class"
 
741
      (pr_class cl ++ spc() ++ str "not a defined class.")
 
742
 
 
743
let print_path_between cls clt = 
 
744
  let i = index_of_class cls in
 
745
  let j = index_of_class clt in
 
746
  let p = 
 
747
    try 
 
748
      lookup_path_between_class (i,j) 
 
749
    with _ -> 
 
750
      errorlabstrm "index_cl_of_id"
 
751
        (str"No path between " ++ pr_class cls ++ str" and " ++ pr_class clt
 
752
         ++ str ".")
 
753
  in
 
754
  print_path ((i,j),p)
 
755
 
 
756
let pr_cs_pattern = function  
 
757
    Const_cs c -> pr_global c
 
758
  | Prod_cs -> str "_ -> _"
 
759
  | Default_cs -> str "_"
 
760
  | Sort_cs s -> pr_sort_family s
 
761
 
 
762
let print_canonical_projections () =
 
763
  prlist_with_sep pr_fnl 
 
764
    (fun ((r1,r2),o) -> pr_cs_pattern r2 ++ 
 
765
    str " <- " ++ 
 
766
    pr_global r1 ++ str " ( " ++ pr_lconstr o.o_DEF ++ str " )")
 
767
    (canonical_projections ())
 
768
 
 
769
(*************************************************************************)
 
770
 
 
771
(*************************************************************************)
 
772
(* Pretty-printing functions for type classes                     *)
 
773
 
 
774
open Typeclasses
 
775
 
 
776
let pr_typeclass env t = 
 
777
  print_ref false t.cl_impl
 
778
 
 
779
let print_typeclasses () =
 
780
  let env = Global.env () in
 
781
    prlist_with_sep fnl (pr_typeclass env) (typeclasses ())
 
782
      
 
783
let pr_instance env i = 
 
784
  (*   gallina_print_constant_with_infos i.is_impl *)
 
785
  (* lighter *)
 
786
  print_ref false (ConstRef (instance_impl i))
 
787
    
 
788
let print_all_instances () =
 
789
  let env = Global.env () in
 
790
  let inst = all_instances () in 
 
791
    prlist_with_sep fnl (pr_instance env) inst
 
792
 
 
793
let print_instances r =
 
794
  let env = Global.env () in
 
795
  let inst = instances r in 
 
796
    prlist_with_sep fnl (pr_instance env) inst
 
797