aboutsummaryrefslogtreecommitdiffhomepage
path: root/contrib/xml/xmlcommand.ml
diff options
context:
space:
mode:
authorGravatar sacerdot <sacerdot@85f007b7-540e-0410-9357-904b9bb8a0f7>2000-10-25 09:15:24 +0000
committerGravatar sacerdot <sacerdot@85f007b7-540e-0410-9357-904b9bb8a0f7>2000-10-25 09:15:24 +0000
commitff249870a9db77a6cbf20bcd839a346b2b749fec (patch)
tree965eb5b28c1904571b9acaa223e6a60901ae5121 /contrib/xml/xmlcommand.ml
parent0f754594a7452e9157b6fb1fdb9842d85e171f2f (diff)
xml contribution created.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@756 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'contrib/xml/xmlcommand.ml')
-rw-r--r--contrib/xml/xmlcommand.ml766
1 files changed, 766 insertions, 0 deletions
diff --git a/contrib/xml/xmlcommand.ml b/contrib/xml/xmlcommand.ml
new file mode 100644
index 000000000..4440c5063
--- /dev/null
+++ b/contrib/xml/xmlcommand.ml
@@ -0,0 +1,766 @@
+(******************************************************************************)
+(* *)
+(* PROJECT HELM *)
+(* *)
+(* A tactic to print Coq objects in XML *)
+(* *)
+(* Claudio Sacerdoti Coen <sacerdot@cs.unibo.it> *)
+(* 02/12/1999 *)
+(* *)
+(* This module defines the functions that implements the new commands *)
+(* *)
+(******************************************************************************)
+
+
+(* CONFIGURATION PARAMETERS *)
+
+let dtdname = "http://localhost:8081/getdtd?url=cic.dtd";;
+let verbose = ref false;; (* always set to true during a "Print XML All" *)
+
+
+
+exception ImpossiblePossible;;
+type formal_parameters =
+ Actual of string
+ | Possible of string
+;;
+
+
+(* LOCAL MODULES *)
+
+(* Next local module because I can't use the standard module Str in a tactic, *)
+(* so I reimplement the part of it I need *)
+module Str =
+ struct
+ exception WrongTermSuffix of string;;
+
+ (* substitute character c1 with c2 in string str *)
+ let rec substitute str c1 c2 =
+ try
+ let pos = String.index str c1 in
+ str.[pos] <- c2 ;
+ substitute str c1 c2
+ with
+ Not_found -> str ;;
+
+ (* change the suffix suf1 with suf2 in the string str *)
+ let change_suffix str suf1 suf2 =
+ let module S = String in
+ let len = S.length str
+ and lens = S.length suf1 in
+ if S.sub str (len - lens) lens = suf1 then
+ (S.sub str 0 (len - lens)) ^ suf2
+ else
+ raise (WrongTermSuffix str) ;;
+ end
+;;
+
+(* UTILITY FUNCTIONS *)
+
+let print_if_verbose s = if !verbose then print_string s;;
+
+let ext_of_tag =
+ function
+ "CONSTANT" -> "con"
+ | "MUTUALINDUCTIVE" -> "ind"
+ | "VARIABLE" -> "var"
+ | _ -> "err" (* uninteresting thing that won't be printed *)
+;;
+
+(* could_have_namesakes sp = true iff o is an object that could be cooked and *)
+(* than that could exists in cooked form with the same name in a super *)
+(* section of the actual section *)
+let could_have_namesakes o sp = (* namesake = omonimo in italian *)
+ let module D = Declare in
+ let tag = Libobject.object_tag o in
+ match tag with
+ "CONSTANT" ->
+ (match D.constant_strength sp with
+ D.DischargeAt _ -> false (* a local definition *)
+ | D.NeverDischarge -> true (* a non-local one *)
+ )
+ | "VARIABLE" -> false (* variables are local, so no namesakes *)
+ | "MUTUALINDUCTIVE" -> true (* mutual inductive types are never local *)
+ | _ -> false (* uninteresting thing that won't be printed*)
+;;
+
+(* uri_of_path sp is a broken (wrong) uri pointing to the object whose *)
+(* section path is sp *)
+let uri_of_path sp =
+(*CSCV7
+ let ext_of_sp sp =
+ let module N = Names in
+ try
+ let lobj = Lib.map_leaf (N.objsp_of sp) in
+ let tag = Libobject.object_tag lobj in
+ ext_of_tag tag
+ with _ -> Util.anomaly ("wrong search of term " ^ N.string_of_path sp)
+*) let ext_of_sp sp = "v7"
+ in
+ let module S = String in
+ let str = Names.string_of_path sp in
+ let uri = Str.substitute str '#' '/' in
+ let uri' = "cic:" ^ uri in
+ let uri'' = Str.change_suffix uri' ".cci" ("." ^ ext_of_sp sp) in
+ uri''
+;;
+
+let string_of_sort =
+ let module T = Term in
+ function
+ T.Prop(T.Pos) -> "Set"
+ | T.Prop(T.Null) -> "Prop"
+ | T.Type(_) -> "Type"
+;;
+
+let string_of_name =
+ let module N = Names in
+ function
+ N.Name id -> N.string_of_id id
+ | _ -> Util.anomaly "this should not happen"
+;;
+
+(* A SIMPLE DATA STRUCTURE AND SOME FUNCTIONS TO MANAGE THE CURRENT *)
+(* ENVIRONMENT (= [l1, ..., ln] WHERE li IS THE LIST OF VARIABLES *)
+(* DECLARED IN THE i-th SUPER-SECTION OF THE CURRENT SECTION *)
+
+(*CSC: commento sbagliato ed obsoleto *)
+(* list of variables availables in the actual section *)
+let pvars = ref [];;
+
+let pvars_to_string pvars =
+ let rec aux =
+ function
+ [] -> (0, "")
+ | he::tl ->
+ let (n,s) = aux tl in
+ (n + 1,
+ string_of_int n ^ ": " ^ (String.concat " ") (List.rev he) ^
+ match s with "" -> "" | _ -> " " ^ s
+ )
+ in
+ snd (aux (List.rev pvars))
+;;
+
+exception XmlCommandInternalError;;
+
+let add_to_pvars v =
+ match !pvars with
+ [] -> raise XmlCommandInternalError
+ | (he::tl) -> pvars := (v::he)::tl
+;;
+
+let get_depth_of_var v =
+ let rec aux n =
+ function
+ [] -> None
+ | (he::tl) -> if List.mem v he then Some n else aux (n + 1) tl
+ in
+ aux 0 !pvars
+;;
+
+(* FUNCTIONS TO CREATE IDENTIFIERS *)
+
+(* seed to create the next identifier *)
+let next_id = ref 0;;
+
+(* reset_id () reset the identifier seed to 0 *)
+let reset_id () =
+ next_id := 0
+;;
+
+(* get_next_id () returns fresh identifier *)
+let get_next_id () =
+ let res =
+ "i" ^ string_of_int !next_id
+ in
+ incr next_id ;
+ res
+;;
+
+(* FUNCTION TO PRINT A SINGLE TERM OF CIC *)
+
+(* print_term t l where t is a term of Cic returns a stream of XML tokens *)
+(* suitable to be printed via the pretty printer Xml.pp. l is the list of *)
+(* bound names *)
+let print_term l csr =
+ let module N = Names in
+ let module T = Term in
+ let module X = Xml in
+ let rec names_to_ids =
+ function
+ [] -> []
+ | (N.Name id)::l -> id::(names_to_ids l)
+ | _ -> names_to_ids l
+ in
+ let rec term_display l cstr =
+ (* kind_of_term helps doing pattern matching hiding the lower level of *)
+ (* coq coding of terms (the one of the logical framework) *)
+ match T.kind_of_term cstr with
+ T.IsRel n ->
+ (match List.nth l (n - 1) with
+ N.Name id ->
+ X.xml_empty "REL"
+ ["value",(string_of_int n) ;
+ "binder",(N.string_of_id id) ;
+ "id", get_next_id ()]
+ | N.Anonymous -> raise XmlCommandInternalError
+ )
+ | T.IsVar id ->
+ let depth =
+ match get_depth_of_var (N.string_of_id id) with
+ None -> "?" (* when printing via Show XML Proof or Print XML id *)
+ (* no infos about variables uri are known *)
+ | Some n -> string_of_int n
+ in
+ X.xml_empty "VAR"
+ ["relUri",depth ^ "," ^ (N.string_of_id id) ;
+ "id", get_next_id ()]
+ | T.IsMeta n ->
+ X.xml_empty "META" ["no",(string_of_int n) ; "id", get_next_id ()]
+ | T.IsSort s ->
+ X.xml_empty "SORT" ["value",(string_of_sort s) ; "id", get_next_id ()]
+ | T.IsCast (t1,t2) ->
+ X.xml_nempty "CAST" ["id", get_next_id ()]
+ [< X.xml_nempty "term" [] (term_display l t1) ;
+ X.xml_nempty "type" [] (term_display l t2)
+ >]
+ | T.IsLetIn (nid,s,_,d)->
+ let nid' = N.next_name_away nid (names_to_ids l) in
+ X.xml_nempty "LETIN" ["id", get_next_id ()]
+ [< X.xml_nempty "term" [] (term_display l s) ;
+ X.xml_nempty "target" ["binder",(N.string_of_id nid')]
+ (term_display ((N.Name nid')::l) d)
+ >]
+ | T.IsProd (N.Name _ as nid, t1, t2) ->
+ let nid' = N.next_name_away nid (names_to_ids l) in
+ X.xml_nempty "PROD" ["id", get_next_id ()]
+ [< X.xml_nempty "source" [] (term_display l t1) ;
+ X.xml_nempty "target" ["binder",(N.string_of_id nid')]
+ (term_display ((N.Name nid')::l) t2)
+ >]
+ | T.IsProd (N.Anonymous as nid, t1, t2) ->
+ X.xml_nempty "PROD" ["id", get_next_id ()]
+ [< X.xml_nempty "source" [] (term_display l t1) ;
+ X.xml_nempty "target" [] (term_display (nid::l) t2)
+ >]
+ | T.IsLambda (N.Name _ as nid, t1, t2) ->
+ let nid' = N.next_name_away nid (names_to_ids l) in
+ X.xml_nempty "LAMBDA" ["id", get_next_id ()]
+ [< X.xml_nempty "source" [] (term_display l t1) ;
+ X.xml_nempty "target" ["binder",(N.string_of_id nid')]
+ (term_display ((N.Name nid')::l) t2)
+ >]
+ | T.IsLambda (N.Anonymous as nid, t1, t2) ->
+ X.xml_nempty "LAMBDA" ["id", get_next_id ()]
+ [< X.xml_nempty "source" [] (term_display l t1) ;
+ X.xml_nempty "target" [] (term_display (nid::l) t2) >]
+ | T.IsApp (h,t) ->
+ X.xml_nempty "APPLY" ["id", get_next_id ()]
+ [< (term_display l h) ;
+ (Array.fold_right (fun x i -> [< (term_display l x) ; i >]) t [<>])
+ >]
+ | T.IsConst (sp,_) ->
+ X.xml_empty "CONST" ["uri",(uri_of_path sp) ; "id", get_next_id ()]
+ | T.IsMutInd ((sp,i),_) ->
+ X.xml_empty "MUTIND"
+ ["uri",(uri_of_path sp) ;
+ "noType",(string_of_int i) ;
+ "id", get_next_id ()]
+ | T.IsMutConstruct (((sp,i),j),_) ->
+ X.xml_empty "MUTCONSTRUCT"
+ ["uri",(uri_of_path sp) ;
+ "noType",(string_of_int i) ;
+ "noConstr",(string_of_int j) ;
+ "id", get_next_id ()]
+ | T.IsMutCase ((_,((sp,i),_,_,_,_)),ty,term,a) ->
+ let (uri, typeno) = (uri_of_path sp),i in
+ X.xml_nempty "MUTCASE"
+ ["uriType",uri ; "noType",(string_of_int typeno) ; "id",get_next_id ()]
+ [< X.xml_nempty "patternsType" [] [< (term_display l ty) >] ;
+ X.xml_nempty "inductiveTerm" [] [< (term_display l term) >] ;
+ Array.fold_right
+ (fun x i ->
+ [< X.xml_nempty "pattern" [] [< term_display l x >] ; i>]
+ ) a [<>]
+ >]
+ | T.IsFix ((ai,i),(t,f,b)) ->
+ X.xml_nempty "FIX" ["noFun", (string_of_int i) ; "id",get_next_id ()]
+ [< Array.fold_right
+ (fun (fi,ti,bi,ai) i ->
+ [< X.xml_nempty "FixFunction"
+ ["name", (string_of_name fi); "recIndex", (string_of_int ai)]
+ [< X.xml_nempty "type" [] [< term_display l ti >] ;
+ X.xml_nempty "body" [] [< term_display ((List.rev f)@l) bi >]
+ >] ;
+ i
+ >]
+ )
+ (Array.mapi (fun j x -> (x,t.(j),b.(j),ai.(j)) ) (Array.of_list f) )
+ [<>]
+ >]
+ | T.IsCoFix (i,(t,f,b)) ->
+ X.xml_nempty "COFIX" ["noFun", (string_of_int i) ; "id",get_next_id ()]
+ [< Array.fold_right
+ (fun (fi,ti,bi) i ->
+ [< X.xml_nempty "CofixFunction" ["name", (string_of_name fi)]
+ [< X.xml_nempty "type" [] [< term_display l ti >] ;
+ X.xml_nempty "body" [] [< term_display ((List.rev f)@l) bi >]
+ >] ;
+ i
+ >]
+ )
+ (Array.mapi (fun j x -> (x,t.(j),b.(j)) ) (Array.of_list f) ) [<>]
+ >]
+ | T.IsXtra _ ->
+ Util.anomaly "Xtra node in a term!!!"
+ | T.IsEvar _ ->
+ Util.anomaly "Evar node in a term!!!"
+ in
+ (*CSC: ad l vanno andrebbero aggiunti i nomi da non *)
+ (*CSC: mascherare (costanti? variabili?) *)
+ term_display l csr
+;;
+
+(* FUNCTIONS TO PRINT A SINGLE OBJECT OF COQ *)
+
+(* print_current_proof term type id conjectures *)
+(* where term is the term of the proof in progress p *)
+(* and type is the type of p *)
+(* and id is the identifier (name) of p *)
+(* and conjectures is the list of conjectures (cic terms) *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+let print_current_proof c typ id mv =
+ let module X = Xml in
+ reset_id () ;
+ [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+ X.xml_cdata ("<!DOCTYPE CurrentProof SYSTEM \"" ^ dtdname ^ "\">\n\n") ;
+ X.xml_nempty "CurrentProof" ["name",id ; "id", get_next_id ()]
+ [< List.fold_right
+ (fun (j,t) i ->
+ [< X.xml_nempty "Conjecture" ["no",(string_of_int j)]
+ [< print_term [] t >] ; i >])
+ mv [<>] ;
+ X.xml_nempty "body" [] [< print_term [] c >] ;
+ X.xml_nempty "type" [] [< print_term [] typ >]
+ >]
+ >]
+;;
+
+(* print_axiom id type params *)
+(* where type is the type of an axiom a *)
+(* and id is the identifier (name) of a *)
+(* and params is the list of formal params for a *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+let print_axiom id typ fv =
+ let module X = Xml in
+ let module N = Names in
+ reset_id () ;
+ [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+ X.xml_cdata ("<!DOCTYPE Axiom SYSTEM \"" ^ dtdname ^ "\">\n\n") ;
+ X.xml_nempty "Axiom"
+ (["name",(N.string_of_id id) ; "id", get_next_id ()] @
+ match fv with
+ Possible _ -> raise ImpossiblePossible
+ | Actual fv' -> ["params",fv']
+ ) [< X.xml_nempty "type" [] (print_term [] typ) >]
+ >]
+;;
+
+(* print_definition id term type params *)
+(* where id is the identifier (name) of a definition d *)
+(* and term is the term (body) of d *)
+(* and type is the type of d *)
+(* and params is the list of formal params for d *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+let print_definition id c typ fv =
+ let module X = Xml in
+ let module N = Names in
+ reset_id () ;
+ [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+ X.xml_cdata ("<!DOCTYPE Definition SYSTEM \"" ^ dtdname ^ "\">\n\n") ;
+ X.xml_nempty "Definition"
+ (["name",(N.string_of_id id) ; "id", get_next_id ()] @
+ match fv with
+ Possible fv' -> ["params",fv' ; "paramMode","POSSIBLE"]
+ | Actual fv' -> ["params",fv'])
+ [< X.xml_nempty "body" [] (print_term [] c) ;
+ X.xml_nempty "type" [] (print_term [] typ) >]
+ >]
+;;
+
+(* print_variable id type *)
+(* where id is the identifier (name) of a variable v *)
+(* and type is the type of v *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+let print_variable id typ =
+ let module X = Xml in
+ let module N = Names in
+ reset_id () ;
+ [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+ X.xml_cdata ("<!DOCTYPE Variable SYSTEM \"" ^ dtdname ^ "\">\n\n") ;
+ X.xml_nempty "Variable" ["name",(N.string_of_id id) ; "id", get_next_id ()]
+ (X.xml_nempty "type" [] (print_term [] typ))
+ >]
+;;
+
+(* print_mutual_inductive_packet p *)
+(* where p is a mutual inductive packet (an inductive definition in a block *)
+(* of mutual inductive definitions) *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+(* Used only by print_mutual_inductive *)
+let print_mutual_inductive_packet names p =
+ let module D = Declarations in
+ let module N = Names in
+ let module T = Term in
+ let module X = Xml in
+ let {D.mind_consnames=consnames ;
+ D.mind_typename=typename ;
+ D.mind_nf_lc=lc ;
+ D.mind_nf_arity=arity ;
+ D.mind_finite=finite} = p
+ in
+ [< X.xml_nempty "InductiveType"
+ ["name",(N.string_of_id typename) ;
+ "inductive",(string_of_bool finite)
+ ]
+ [<
+ X.xml_nempty "arity" [] (print_term [] (T.body_of_type arity)) ;
+ (Array.fold_right
+ (fun (name,lc) i ->
+ [< X.xml_nempty "Constructor" ["name",(N.string_of_id name)]
+ (print_term names lc) ;
+ i
+ >])
+ (Array.mapi (fun j x -> (x,T.body_of_type lc.(j)) ) consnames )
+ [<>]
+ )
+ >]
+ >]
+;;
+
+(* print_mutual_inductive packs params nparams *)
+(* where packs is the list of inductive definitions in the block of *)
+(* mutual inductive definitions b *)
+(* and params is the list of formal params for b *)
+(* and nparams is the number of "parameters" in the arity of the *)
+(* mutual inductive types *)
+(* returns a stream of XML tokens suitable to be pretty printed via Xml.pp *)
+let print_mutual_inductive packs fv nparams =
+ let module D = Declarations in
+ let module X = Xml in
+ let module N = Names in
+ let names =
+ List.map
+ (fun p -> let {D.mind_typename=typename} = p in N.Name(typename))
+ (Array.to_list packs)
+ in
+ reset_id () ;
+ [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ;
+ X.xml_cdata ("<!DOCTYPE InductiveDefinition SYSTEM \"" ^
+ dtdname ^ "\">\n\n") ;
+ X.xml_nempty "InductiveDefinition"
+ (["noParams",string_of_int nparams ; "id",get_next_id ()] @
+ (match fv with
+ Possible fv' -> ["params",fv' ; "paramMode","POSSIBLE"]
+ | Actual fv' -> ["params",fv']))
+ [< (Array.fold_right
+ (fun x i -> [< print_mutual_inductive_packet names x ; i >])
+ packs
+ [< >]
+ )
+ >]
+ >]
+;;
+
+(* print id dest *)
+(* where id is the identifier (name) of a definition/theorem or of an *)
+(* inductive definition *)
+(* and dest is either None (for stdout) or (Some filename) *)
+(* pretty prints via Xml.pp the object whose identifier is id on dest *)
+(* Note: it is printed only (and directly) the most cooked available *)
+(* form of the definition (all the parameters are *)
+(* lambda-abstracted, but the object can still refer to variables) *)
+let print id fn =
+ let module D = Declarations in
+ let module G = Global in
+ let module N = Names in
+ let module T = Term in
+ let module X = Xml in
+ let str = N.string_of_id id in
+ let sp = Nametab.sp_of_id N.CCI id in
+ let pp_cmds =
+ begin
+ try
+ let {D.const_body=val0 ; D.const_type = typ} = G.lookup_constant sp in
+ let typ = T.body_of_type typ in
+ begin
+ match val0 with
+ None -> print_axiom id typ (Actual "")
+ | Some lcvr ->
+ match !lcvr with
+ D.Cooked c -> print_definition id c typ (Actual "")
+ | D.Recipe _ ->
+ print_string " COOKING THE RECIPE\n" ;
+ ignore (D.cook_constant lcvr) ;
+ let {D.const_body=val0 ; D.const_type = typ} =
+ G.lookup_constant sp in
+ let typ = T.body_of_type typ in
+ begin
+ match val0 with
+ Some {contents= D.Cooked c} ->
+ print_definition id c typ (Actual "")
+ | _ -> Util.error "COOKING FAILED"
+ end
+ end
+ with
+ Not_found ->
+ try
+ let {D.mind_packets=packs ; D.mind_nparams=nparams} =
+ G.lookup_mind sp
+ in
+ print_mutual_inductive packs (Actual "") nparams
+ with
+ Not_found ->
+ Util.anomaly ("print: this should not happen")
+ end
+ in
+ Xml.pp pp_cmds fn
+;;
+
+(* show dest *)
+(* where dest is either None (for stdout) or (Some filename) *)
+(* pretty prints via Xml.pp the proof in progress on dest *)
+let show fn =
+(*
+ let pftst = Pfedit.get_pftreestate () in
+ let id = Pfedit.get_proof () in
+ let pf = Tacmach.proof_of_pftreestate pftst in
+ let typ = (Proof_trees.goal_of_proof pf).Evd.concl in
+ (*CSC: ntrefiner copied verbatim from natural, used, but _not_ understood *)
+ let val0, mv = Ntrefiner.nt_extract_open_proof (Vartab.initial_sign ()) pf in
+ let mv_t = List.map (function i, (t, _) -> i,t) mv in
+ Xml.pp (print_current_proof val0 typ id mv_t) fn
+*) ()
+;;
+
+(* FUNCTIONS TO PRINT AN ENTIRE SECTION OF COQ *)
+
+(* list of (name, uncooked sp, most cooked sp, uncooked leaf object, *)
+(* list of possible variables, directory name) *)
+(* used to collect informations on the uncooked and most cooked forms *)
+(* of objects that could be cooked (have namesakes) *)
+let toprint = ref [];;
+
+(* makes a filename from a directory name, a section path and an extension *)
+let mkfilename dn sp ext =
+ let rec join_dirs cwd =
+ function
+ [] -> ""
+ | he::tail ->
+ let newcwd = cwd ^ "/" ^ he in
+ (try
+ Unix.mkdir newcwd 0o775
+ with _ -> () (* Let's ignore the errors on mkdir *)
+ ) ;
+ he ^ "/" ^ join_dirs newcwd tail
+ in
+ let module N = Names in
+ match dn with
+ None -> None
+ | Some basedir ->
+ let (dirs, filename, _) = N.repr_path sp in
+ let dirs = List.rev dirs in (* misteries of Coq *)
+ Some (basedir ^ "/" ^ join_dirs basedir dirs ^
+ N.string_of_id filename ^ "." ^ ext ^ ".xml")
+;;
+
+(* Next exception is used only inside print_object *)
+exception Uninteresting;;
+
+(* print_object leaf_object id section_path directory_name formal_vars *)
+(* where leaf_object is a leaf object *)
+(* and id is the identifier (name) of the definition/theorem *)
+(* or of the inductive definition o *)
+(* and section_path is the section path of o *)
+(* and directory_name is the base directory in which putting the print *)
+(* and formal_vars is the list of parameters (variables) of o *)
+(* pretty prints via Xml.pp the object o in the right directory deduced *)
+(* from directory_name and section_path *)
+(* Note: it is printed only the uncooked available form of the object plus *)
+(* the list of parameters of the object deduced from it's most cooked *)
+(* form *)
+let print_object o id sp dn fv =
+ let module D = Declarations in
+ let module G = Global in
+ let module N = Names in
+ let module T = Term in
+ let module X = Xml in
+ let lobj = o in
+ let tag = Libobject.object_tag lobj in
+ let pp_cmds () =
+ match tag with
+ "CONSTANT" ->
+ (*CSC: QUI CI SONO ANCHE LE VARIABILI, CREDO, CHIAMATE const_hyps *)
+ let {D.const_body=val0 ; D.const_type = typ} = G.lookup_constant sp in
+ let typ = T.body_of_type typ in
+ begin
+ match val0 with
+ None -> print_axiom id typ fv
+ | Some lcvr ->
+ match !lcvr with
+ D.Cooked c -> print_definition id c typ fv
+ | D.Recipe _ -> Util.anomaly "trying to print a recipe"
+ end
+ | "MUTUALINDUCTIVE" ->
+ (*CSC: QUI CI SONO ANCHE LE VARIABILI, CREDO, CHIAMATE mind_hyps *)
+ let {D.mind_packets=packs ; D.mind_nparams=nparams} =
+ G.lookup_mind sp
+ in
+ print_mutual_inductive packs fv nparams
+ | "VARIABLE" ->
+ (*CHE COSA E' IL PRIMO ARGOMENTO?*)
+ let (_,typ) = G.lookup_named id in
+ add_to_pvars (N.string_of_id id) ;
+ print_variable id (T.body_of_type typ)
+ | "CLASS"
+ | "COERCION"
+ | _ -> raise Uninteresting
+ and fileext = ext_of_tag tag
+ in
+ try
+ Xml.pp (pp_cmds ()) (mkfilename dn sp fileext)
+ with
+ Uninteresting -> ()
+;;
+
+(* print_library_segment state bprintleaf directory_name *)
+(* where state is a list of (section-path, node) *)
+(* and bprintleaf is true iff the leaf objects should be printed *)
+(* and directory_name is the name of the base directory in which to print *)
+(* the files *)
+(* print via print_node all the nodes (leafs excluded if bprintleaf is false) *)(* in state *)
+let rec print_library_segment state bprintleaf dn =
+ List.iter
+ (function (sp, node) ->
+ print_if_verbose (Names.string_of_path sp ^ "\n") ;
+ print_node node (Names.basename sp) sp bprintleaf dn ;
+ print_if_verbose "\n"
+ ) state
+(* print_node node id section_path bprintleaf directory_name *)
+(* prints a single node (and all it's subnodes via print_library_segment *)
+and print_node n id sp bprintleaf dn =
+ let module L = Lib in
+ match n with
+ L.Leaf o ->
+ print_if_verbose "LEAF\n" ;
+ if bprintleaf then
+ begin
+ let to_print =
+ try
+ let _ =
+ List.find (function (x,_,_,_,_,_) -> x=id) !toprint
+ in
+ false
+ with Not_found -> true
+ in
+ if to_print then
+ (* this is an uncooked term or a local (with no namesakes) term *)
+ begin
+ if could_have_namesakes o sp then
+ (* this is an uncooked term *)
+ toprint := (id,sp,sp,o,!pvars,dn)::!toprint
+ else
+ (* this is a local term *)
+ print_object o id sp dn (Possible (pvars_to_string !pvars)) ;
+ print_if_verbose ("OK, stampo " ^ Names.string_of_id id ^ "\n")
+ end
+ else
+ (* update the least cooked sp *)
+ toprint :=
+ List.map
+ (function
+ (id',usp,_,uo,pv,dn) when id' = id -> (id,usp,sp,uo,pv,dn)
+ | t -> t
+ ) !toprint
+ end
+ | L.OpenedSection s -> print_if_verbose ("OpenDir " ^ s ^ "\n")
+ | L.ClosedSection (s,state) ->
+ print_if_verbose("ClosedDir " ^ s ^ "\n") ;
+ if bprintleaf then
+ begin
+ (* open a new scope *)
+ pvars := []::!pvars ;
+ print_library_segment state bprintleaf dn ;
+ (* close the scope *)
+ match !pvars with
+ [] -> raise XmlCommandInternalError
+ | he::tl -> pvars := tl
+ end ;
+ print_if_verbose "/ClosedDir\n"
+ | L.Module s ->
+ print_if_verbose ("Module " ^ s ^ "\n")
+ | L.FrozenState _ ->
+ print_if_verbose ("FrozenState\n")
+;;
+
+(* print_closed_section module_name node directory_name *)
+(* where module_name is the name of a module *)
+(* and node is the library segment of the module *)
+(* and directory_name is the base directory in which to put the xml files *)
+(* prints all the leaf objects of the tree rooted in node using *)
+(* print_library_segment on all its sons *)
+let print_closed_section s ls dn =
+ let module L = Lib in
+ let module C = Cooking in
+ toprint := [] ;
+ (*CSC: this should always be empty yet! But just to be sure... :-) *)
+ pvars := [] ;
+ print_if_verbose ("Module " ^ s ^ ":\n") ;
+ print_library_segment ls true dn ;
+ print_if_verbose "\nNow saving cooking information: " ;
+ List.iter
+ (function
+ (id,usp,csp,uo,pv,dn) ->
+ print_if_verbose ("\nCooked=" ^ (Names.string_of_path csp) ^
+ "\tUncooked=" ^ (Names.string_of_path usp)) ;
+ let formal_vars = C.add_cooking_information csp pv in
+ pvars := pv ;
+ (*CSC Actual was Some *)
+ print_object uo id usp dn (Actual formal_vars)
+ ) !toprint ;
+ print_if_verbose "\n/Module\n" ;
+;;
+
+(* printModule identifier directory_name *)
+(* where identifier is the name of a module (section) d *)
+(* and directory_name is the directory in which to root all the xml files *)
+(* prints all the xml files and directories corresponding to the subsections *)
+(* and terms of the module d *)
+(* Note: the terms are printed in their uncooked form plus the informations *)
+(* on the parameters of their most cooked form *)
+let printModule id dn =
+ let module L = Library in
+ let module N = Names in
+ let module X = Xml in
+ let str = N.string_of_id id in
+ let sp = Lib.make_path id N.OBJ in
+ let ls = L.module_segment (Some str) in
+ print_if_verbose ("MODULE_BEGIN " ^ str ^ " " ^ N.string_of_path sp ^ " " ^
+ L.module_filename str ^ "\n") ;
+ print_closed_section str ls dn ;
+ print_if_verbose ("MODULE_END " ^ str ^ " " ^ N.string_of_path sp ^ " " ^
+ L.module_filename str ^ "\n")
+;;
+
+(* print All () prints what is the structure of the current environment of *)
+(* Coq. No terms are printed. Useful only for debugging *)
+let printAll () =
+ let state = Library.module_segment None in
+ let oldverbose = !verbose in
+ verbose := true ;
+ print_library_segment state false None ;
+ let ml = Library.loaded_modules () in
+ List.iter (function i -> printModule (Names.id_of_string i) None) ml ;
+ verbose := oldverbose
+;;