PageRenderTime 53ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/parsing/prettyp.ml

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