diff options
Diffstat (limited to 'contrib/xml/xmlcommand.ml4')
| -rw-r--r-- | contrib/xml/xmlcommand.ml4 | 1037 |
1 files changed, 1037 insertions, 0 deletions
diff --git a/contrib/xml/xmlcommand.ml4 b/contrib/xml/xmlcommand.ml4 new file mode 100644 index 0000000000..7b6303130b --- /dev/null +++ b/contrib/xml/xmlcommand.ml4 @@ -0,0 +1,1037 @@ +(***********************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *) +(* \VV/ *************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(***********************************************************************) +(******************************************************************************) +(* *) +(* PROJECT HELM *) +(* *) +(* A module to print Coq objects in XML *) +(* *) +(* Claudio Sacerdoti Coen <sacerdot@cs.unibo.it> *) +(* 06/12/2000 *) +(* *) +(******************************************************************************) + + +(* CONFIGURATION PARAMETERS *) + +let dtdname = "http://www.cs.unibo.it/helm/dtd/cic.dtd";; +let typesdtdname = "http://www.cs.unibo.it/helm/dtd/cictypes.dtd";; +let verbose = ref false;; (* always set to true during a "Print XML All" *) + +(* UTILITY FUNCTIONS *) + +let print_if_verbose s = if !verbose then print_string s;; + +type tag = + Constant + | Inductive + | Variable +;; + +(* Next exception is used only inside print_object and tag_of_string_tag *) +exception Uninteresting;; + +let tag_of_string_tag = + function + "CONSTANT" + | "PARAMETER" -> Constant + | "INDUCTIVE" -> Inductive + | "VARIABLE" -> Variable + | _ -> raise Uninteresting +;; + +let ext_of_tag = + function + Constant -> "con" + | Inductive -> "ind" + | Variable -> "var" +;; + +(* Internally, for Coq V7, params of inductive types are associated *) +(* not to the whole block of mutual inductive (as it was in V6) but to *) +(* each member of the block; but externally, all params are required *) +(* to be the same; the following function checks that the parameters *) +(* of each inductive of a same block are all the same, then returns *) +(* this number; it fails otherwise *) +let extract_nparams pack = + let module D = Declarations in + let module U = Util in + let module S = Sign in + + let {D.mind_nparams=nparams0} = pack.(0) in + let arity0 = pack.(0).D.mind_user_arity in + let params0, _ = S.decompose_prod_n_assum nparams0 arity0 in + for i = 1 to Array.length pack - 1 do + let {D.mind_nparams=nparamsi} = pack.(i) in + let arityi = pack.(i).D.mind_user_arity in + let paramsi, _ = S.decompose_prod_n_assum nparamsi arityi in + if params0 <> paramsi then U.error "Cannot convert a block of inductive definitions with parameters specific to each inductive to a block of mutual inductive definitions with parameters global to the whole block" + done; + nparams0 + +(* 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 + print_if_verbose ("Object tag: " ^ tag ^ "\n") ; + match tag with + "CONSTANT" -> + (match D.constant_strength sp with + | D.DischargeAt _ -> false (* a local definition *) + | D.NotDeclare -> false (* not a definition *) + | D.NeverDischarge -> true (* a non-local one *) + ) + | "PARAMETER" (* axioms and *) + | "INDUCTIVE" -> true (* mutual inductive types are never local *) + | "VARIABLE" -> false (* variables are local, so no namesakes *) + | _ -> 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 tag = + let module N = Names in + let module No = Nameops in + let ext_of_sp sp = ext_of_tag tag in + let dir0 = No.extend_dirpath (No.dirpath sp) (No.basename sp) in + let dir = List.map N.string_of_id (List.rev (N.repr_dirpath dir0)) in + "cic:/" ^ (String.concat "/" dir) ^ "." ^ (ext_of_sp sp) +;; + +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 ([[]] : string list list);; +let cumenv = ref Environ.empty_env;; + +let string_of_vars_list = + let add_prefix n s = string_of_int n ^ ": " ^ s in + let rec aux = + function + [n,v] -> (n,v) + | (n,v)::tl -> + let (k,s) = aux tl in + if k = n then (k, v ^ " " ^ s) else (n, v ^ " " ^ add_prefix k s) + | [] -> assert false + in + function + [] -> "" + | vl -> let (k,s) = aux vl in add_prefix k s +;; + +(* +let string_of_pvars pvars hyps = + 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)) +;; +*) + +let string_of_pvars pvars hyps = + let find_depth pvars v = + let rec aux n = + function + [] -> assert false +(* (-1,"?") For Print XML *) +(* +print_string "\nPVARS:" ; +List.iter (List.iter print_string) pvars ; +print_string "\nHYPS:" ; +List.iter print_string hyps ; +print_string "\n" ; +flush stdout ; +assert false +*) + | l::_ when List.mem v l -> (n,v) + | _::tl -> aux (n+1) tl + in + aux 0 pvars + in + string_of_vars_list (List.map (find_depth pvars) (List.rev hyps)) +;; + +type variables_type = + Definition of string * Term.constr * Term.types + | Assumption of string * Term.constr +;; + +let add_to_pvars x = + let module E = Environ in + let v = + match x with + Definition (v, bod, typ) -> + cumenv := + E.push_named_decl (Names.id_of_string v, Some bod, typ) !cumenv ; + v + | Assumption (v, typ) -> + cumenv := + E.push_named_decl (Names.id_of_string v, None, typ) !cumenv ; + v + in + match !pvars with + [] -> assert false + | (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_cic = ref 0;; +let next_id_types = ref 0;; + +(* reset_ids () reset the identifier seed to 0 *) +let reset_ids () = + next_id_cic := 0 ; + next_id_types := 0 +;; + +(* get_next_id () returns fresh identifier *) +let get_next_id = + function + `T -> + let res = + "t" ^ string_of_int !next_id_types + in + incr next_id_types ; + res + | `I -> + let res = + "i" ^ string_of_int !next_id_cic + in + incr next_id_cic ; + res +;; + +type innersort = + InnerProp of Term.constr (* the constr is the type of the term *) + | InnerSet + | InnerType +;; + +(* 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 inner_types l env csr = + let module N = Names in + let module E = Environ in + let module T = Term in + let module X = Xml in + let module R = Retyping in + let rec names_to_ids = + function + [] -> [] + | (N.Name id)::l -> id::(names_to_ids l) + | _ -> names_to_ids l + in + + let inner_type_display env term = + let type_of_term = + Reduction.nf_betaiota (R.get_type_of env (Evd.empty) term) + in + match R.get_sort_family_of env (Evd.empty) type_of_term with + T.InProp -> InnerProp type_of_term + | T.InSet -> InnerSet + | T.InType -> InnerType + in + +(*WHICH FORCE FUNCTION DEPENDS ON THE ORDERING YOU WANT + let rec force = + parser + [< 'he ; tl >] -> let tl = (force tl) in [< 'he ; tl >] + | [< >] -> [<>] + in +*) + let force x = x in + + let rec term_display idradix in_lambda l env cstr = + let next_id = get_next_id idradix in + let add_sort_attribute do_output_type l' = + let xmlinnertype = inner_type_display env cstr in + match xmlinnertype with + InnerProp type_of_term -> + if do_output_type & idradix = `I then + begin + let pp_cmds = term_display `T false l env type_of_term in + inner_types := (next_id, pp_cmds)::!inner_types ; + end ; + ("sort","Prop")::l' + | InnerSet -> ("sort","Set")::l' + | InnerType -> ("sort","Type")::l' + in + let add_type_attribute l' = + ("type", string_of_sort (R.get_sort_of env (Evd.empty) cstr))::l' + in + (* 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.Rel n -> + let id = + match List.nth l (n - 1) with + N.Name id -> id + | N.Anonymous -> Nameops.make_ident "_" None + in + X.xml_empty "REL" + (add_sort_attribute false + ["value",(string_of_int n) ; + "binder",(N.string_of_id id) ; + "id", next_id]) + | T.Var 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 *) +(*V7 posso usare nametab, forse*) + | Some n -> string_of_int n + in + X.xml_empty "VAR" + (add_sort_attribute false + ["relUri",depth ^ "," ^ (N.string_of_id id) ; + "id", next_id]) + | T.Meta n -> + X.xml_empty "META" + (add_sort_attribute false ["no",(string_of_int n) ; "id", next_id]) + | T.Sort s -> + X.xml_empty "SORT" ["value",(string_of_sort s) ; "id", next_id] + | T.Cast (t1,t2) -> + X.xml_nempty "CAST" (add_sort_attribute false ["id", next_id]) +(force + [< X.xml_nempty "term" [] (term_display idradix false l env t1) ; + X.xml_nempty "type" [] (term_display idradix false l env t2) + >] +) + | T.LetIn (nid,s,t,d)-> + let nid' = Nameops.next_name_away nid (names_to_ids l) in + X.xml_nempty "LETIN" (add_sort_attribute true ["id", next_id]) +(force + [< X.xml_nempty "term" [] (term_display idradix false l env s) ; + X.xml_nempty "letintarget" ["binder",(N.string_of_id nid')] + (term_display idradix false + ((N.Name nid')::l) + (E.push_rel (N.Name nid', Some s, t) env) + d + ) + >] +) + | T.Prod (N.Name _ as nid, t1, t2) -> + let nid' = Nameops.next_name_away nid (names_to_ids l) in + X.xml_nempty "PROD" (add_type_attribute ["id", next_id]) +(force + [< X.xml_nempty "source" [] (term_display idradix false l env t1) ; + X.xml_nempty "target" + (if idradix = `T && + T.noccurn 1 t2 + then [] + else ["binder",(N.string_of_id nid')]) + (term_display idradix false + ((N.Name nid')::l) + (E.push_rel (N.Name nid', None, t1) env) + t2 + ) + >] +) + | T.Prod (N.Anonymous as nid, t1, t2) -> + X.xml_nempty "PROD" (add_type_attribute ["id", next_id]) +(force + [< X.xml_nempty "source" [] (term_display idradix false l env t1) ; + X.xml_nempty "target" [] + (term_display idradix false + (nid::l) + (E.push_rel (nid, None, t1) env) + t2 + ) + >] +) + | T.Lambda (N.Name _ as nid, t1, t2) -> + let nid' = Nameops.next_name_away nid (names_to_ids l) in + X.xml_nempty "LAMBDA" (add_sort_attribute (not in_lambda) ["id",next_id]) +(force + [< X.xml_nempty "source" [] (term_display idradix false l env t1) ; + X.xml_nempty "target" ["binder",(N.string_of_id nid')] + (term_display idradix true + ((N.Name nid')::l) + (E.push_rel (N.Name nid', None, t1) env) + t2 + ) + >] +) + | T.Lambda (N.Anonymous as nid, t1, t2) -> + X.xml_nempty "LAMBDA" (add_sort_attribute (not in_lambda) ["id", next_id]) +(force + [< X.xml_nempty "source" [] (term_display idradix false l env t1) ; + X.xml_nempty "target" [] + (term_display idradix true + (nid::l) + (E.push_rel (nid, None, t1) env) + t2 + ) + >] +) + | T.App (h,t) -> + X.xml_nempty "APPLY" (add_sort_attribute true ["id", next_id]) +(force + [< (term_display idradix false l env h) ; + (Array.fold_right + (fun x i -> [< (term_display idradix false l env x); i >]) t [<>]) + >] +) + | T.Const sp -> + X.xml_empty "CONST" + (add_sort_attribute false + ["uri",(uri_of_path sp Constant) ; "id", next_id]) + | T.Ind (sp,i) -> + X.xml_empty "MUTIND" + ["uri",(uri_of_path sp Inductive) ; + "noType",(string_of_int i) ; + "id", next_id] + | T.Construct ((sp,i),j) -> + X.xml_empty "MUTCONSTRUCT" + (add_sort_attribute false + ["uri",(uri_of_path sp Inductive) ; + "noType",(string_of_int i) ; + "noConstr",(string_of_int j) ; + "id", next_id]) + | T.Case ({T.ci_ind=(sp,i)},ty,term,a) -> + let (uri, typeno) = (uri_of_path sp Inductive),i in + X.xml_nempty "MUTCASE" + (add_sort_attribute true + ["uriType",uri ; "noType",(string_of_int typeno) ; "id",next_id]) +(force + [< X.xml_nempty "patternsType" [] + [< (term_display idradix false l env ty) >] ; + X.xml_nempty "inductiveTerm" [] + [< (term_display idradix false l env term)>]; + Array.fold_right + (fun x i -> + [< X.xml_nempty "pattern" [] + [<term_display idradix false l env x >] ; i>] + ) a [<>] + >] +) + | T.Fix ((ai,i),((f,t,b) as rec_decl)) -> + X.xml_nempty "FIX" + (add_sort_attribute true ["noFun", (string_of_int i) ; "id",next_id]) +(force + [< 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 idradix false l env ti >] ; + X.xml_nempty "body" [] [< + term_display idradix false + ((Array.to_list f)@l) + (E.push_rec_types rec_decl env) + bi + >] + >] ; + i + >] + ) + (Array.mapi (fun j x -> (x,t.(j),b.(j),ai.(j)) ) f ) + [<>] + >] +) + | T.CoFix (i,((f,t,b) as rec_decl)) -> + X.xml_nempty "COFIX" + (add_sort_attribute true ["noFun", (string_of_int i) ; "id",next_id]) +(force + [< Array.fold_right + (fun (fi,ti,bi) i -> + [< X.xml_nempty "CofixFunction" ["name", (string_of_name fi)] + [< X.xml_nempty "type" [] + [< term_display idradix false l env ti >] ; + X.xml_nempty "body" [] [< + term_display idradix false + ((Array.to_list f)@l) + (E.push_rec_types rec_decl env) + bi + >] + >] ; + i + >] + ) + (Array.mapi (fun j x -> (x,t.(j),b.(j)) ) f ) [<>] + >] +) + | T.Evar _ -> + Util.anomaly "Evar node in a term!!!" + in + (*CSC: ad l vanno andrebbero aggiunti i nomi da non *) + (*CSC: mascherare (costanti? variabili?) *) + term_display `I false l env 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 inner_types = + let module X = Xml in + let env = (Safe_typing.env_of_safe_env (Global.safe_env ())) in + [< 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 `I] + [< List.fold_right + (fun (j,t) i -> + [< X.xml_nempty "Conjecture" ["no",(string_of_int j)] + [< print_term inner_types [] env t >] ; i >]) + mv [<>] ; + X.xml_nempty "body" [] [< print_term inner_types [] env c >] ; + X.xml_nempty "type" [] [< print_term inner_types [] env 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 hyps env inner_types = + let module X = Xml in + let module N = Names in + [< 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 `I ; + "params",(string_of_pvars fv hyps)] + [< X.xml_nempty "type" [] (print_term inner_types [] env typ) >] + >] +;; + +(* print_definition id term type params hyps *) +(* 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 hyps env inner_types = + let module X = Xml in + let module N = Names in + [< 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 `I ; + "params",(string_of_pvars fv hyps)] + [< X.xml_nempty "body" [] (print_term inner_types [] env c) ; + X.xml_nempty "type" [] (print_term inner_types [] env 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 body typ env inner_types = + let module X = Xml in + let module N = Names in + [< 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 `I] + [< (match body with + None -> [<>] + | Some body -> + X.xml_nempty "body" [] (print_term inner_types [] env body) + ) ; + X.xml_nempty "type" [] (print_term inner_types [] env 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 inner_types names env finite 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} = p + in + [< X.xml_nempty "InductiveType" + ["name",(N.string_of_id typename) ; + "inductive",(string_of_bool finite) + ] + [< + X.xml_nempty "arity" [] + (print_term inner_types [] env (T.body_of_type arity)) ; + (Array.fold_right + (fun (name,lc) i -> + [< X.xml_nempty "Constructor" ["name",(N.string_of_id name)] + (print_term inner_types names env 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 finite packs fv hyps env inner_types = + let module D = Declarations in + let module E = Environ in + let module X = Xml in + let module N = Names in + let nparams = extract_nparams packs in + let names = + List.map + (fun p -> let {D.mind_typename=typename} = p in N.Name(typename)) + (Array.to_list packs) + in + let env = + List.fold_right + (fun {D.mind_typename=typename ; D.mind_nf_arity=arity} env -> + E.push_rel (N.Name typename, None, arity) env) + (Array.to_list packs) + env + in + [< 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 `I ; + "params",(string_of_pvars fv hyps)] + [< (Array.fold_right + (fun x i -> + [< print_mutual_inductive_packet + inner_types names env finite x ; i >] + ) packs [< >] + ) + >] + >] +;; + +let string_list_of_named_context_list = + List.map + (function (n,_,_) -> Names.string_of_id n) +;; + +let types_filename_of_filename = + function + Some f -> Some (f ^ ".types") + | None -> None +;; + +let pp_cmds_of_inner_types inner_types target_uri = + let module X = Xml in + let rec stream_of_list = + function + [] -> [<>] + | he::tl -> [< he ; stream_of_list tl >] + in + [< X.xml_cdata "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" ; + X.xml_cdata ("<!DOCTYPE InnerTypes SYSTEM \"" ^ typesdtdname ^ "\">\n\n"); + X.xml_nempty "InnerTypes" ["of",target_uri] + (stream_of_list + (List.map + (function + (id,type_pp_cmds) -> X.xml_nempty "TYPE" ["of",id] type_pp_cmds) + (List.rev inner_types) + )) + >] +;; + +(* print id dest *) +(* where sp is the qualified identifier (section path) of a *) +(* definition/theorem, variable or 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 qid fn = + let module D = Declarations in + let module G = Global in + let module N = Names in + let module Nt = Nametab in + let module T = Term in + let module X = Xml in + let (_,id) = Nt.repr_qualid qid in + let glob_ref = Nametab.locate qid in + let env = (Safe_typing.env_of_safe_env (G.safe_env ())) in + reset_ids () ; + let inner_types = ref [] in + let sp,tag,pp_cmds = + match glob_ref with + Nt.VarRef id -> + let sp = Declare.find_section_variable id in + let (_,body,typ) = G.lookup_named id in + sp,Variable,print_variable id body (T.body_of_type typ) env inner_types + | Nt.ConstRef sp -> + let {D.const_body=val0 ; D.const_type = typ ; D.const_hyps = hyps} = + G.lookup_constant sp in + let hyps = string_list_of_named_context_list hyps in + let typ = T.body_of_type typ in + sp,Constant, + begin + match val0 with + None -> print_axiom id typ [] hyps env inner_types + | Some c -> print_definition id c typ [] hyps env inner_types + end + | Nt.IndRef (sp,_) -> + let {D.mind_packets=packs ; + D.mind_hyps=hyps; + D.mind_finite=finite} = G.lookup_mind sp in + let hyps = string_list_of_named_context_list hyps in + sp,Inductive, + print_mutual_inductive finite packs [] hyps env inner_types + | Nt.ConstructRef _ -> + Util.anomaly ("print: this should not happen") + in + Xml.pp pp_cmds fn ; + Xml.pp (pp_cmds_of_inner_types !inner_types (uri_of_path sp tag)) + (types_filename_of_filename 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 str = Names.string_of_id (Pfedit.get_current_proof_name ()) in + let pf = Tacmach.proof_of_pftreestate pftst in + let typ = (Proof_trees.goal_of_proof pf).Evd.evar_concl in + let val0,mv = Tacmach.extract_open_pftreestate pftst in + reset_ids () ; + let inner_types = ref [] in + Xml.pp + (print_current_proof val0 typ str mv inner_types) + fn ; + Xml.pp (pp_cmds_of_inner_types !inner_types ("?" ^ str ^ "?")) + (types_filename_of_filename 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 printed = ref [];; + +(* makes a filename from a directory name, a section path and an extension *) +let mkfilename dn sp ext = + let dir_list_of_dirpath s = + let rec aux n = + try + let pos = String.index_from s n '/' in + let head = String.sub s n (pos - n) in + head::(aux (pos + 1)) + with + Not_found -> [String.sub s n (String.length s - n)] + in + aux 0 + in + let rec join_dirs cwd = + function + [] -> assert false + | [he] -> "/" ^ he + | 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 L = Library in + let module S = System in + let module N = Names in + let module No = Nameops in + match dn with + None -> None + | Some basedir -> + let dir0 = No.extend_dirpath (No.dirpath sp) (No.basename sp) in + let dir = List.map N.string_of_id (List.rev (N.repr_dirpath dir0)) in + Some (basedir ^ join_dirs basedir dir ^ "." ^ ext) +;; + +(* 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 lobj id sp dn fv env = + let module D = Declarations in + let module E = Environ in + let module G = Global in + let module N = Names in + let module T = Term in + let module X = Xml in + let strtag = Libobject.object_tag lobj in + try + let tag = tag_of_string_tag strtag in + reset_ids () ; + let inner_types = ref [] in + let pp_cmds = + match strtag with + "CONSTANT" (* = Definition, Theorem *) + | "PARAMETER" (* = Axiom *) -> + let {D.const_body=val0 ; D.const_type = typ ; D.const_hyps = hyps} = + G.lookup_constant sp + in + let hyps = string_list_of_named_context_list hyps in + let typ = T.body_of_type typ in + begin + match val0 with + None -> print_axiom id typ fv hyps env inner_types + | Some c -> print_definition id c typ fv hyps env inner_types + end + | "INDUCTIVE" -> + let + {D.mind_packets=packs ; + D.mind_hyps = hyps; + D.mind_finite = finite + } = G.lookup_mind sp + in + let hyps = string_list_of_named_context_list hyps in + print_mutual_inductive finite packs fv hyps env inner_types + | "VARIABLE" -> + let (_,(_,varentry,_)) = Declare.out_variable lobj in + begin + match varentry with + Declare.SectionLocalDef (body,optt) -> + let typ = match optt with + | None -> Retyping.get_type_of env Evd.empty body + | Some t -> t in + add_to_pvars (Definition (N.string_of_id id, body, typ)) ; + print_variable id (Some body) typ env inner_types + | Declare.SectionLocalAssum typ -> + add_to_pvars (Assumption (N.string_of_id id, typ)) ; + print_variable id None (T.body_of_type typ) env inner_types + end + | "CLASS" + | "COERCION" + | _ -> raise Uninteresting + and fileext () = ext_of_tag tag in + let fn = (mkfilename dn sp (fileext ())) in + Xml.pp pp_cmds fn ; + Xml.pp (pp_cmds_of_inner_types !inner_types (uri_of_path sp tag)) + (types_filename_of_filename fn) + 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 ("Print_library_segment: " ^ Names.string_of_path sp ^ "\n") ; + print_node node (Nameops.basename sp) sp bprintleaf dn ; + print_if_verbose "\n" + ) (List.rev 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 + if not (List.mem id !printed) then + (* this is an uncooked term or a local (with no namesakes) term *) + begin +try + if could_have_namesakes o sp then + begin + (* this is an uncooked term *) + print_if_verbose ("OK, stampo solo questa volta " ^ Names.string_of_id id ^ "\n") ; + print_object o id sp dn !pvars !cumenv ; + printed := id::!printed + end + else + begin + (* this is a local term *) + print_if_verbose ("OK, stampo " ^ Names.string_of_id id ^ "\n") ; + print_object o id sp dn !pvars !cumenv + end +with _ -> print_if_verbose ("EXCEPTION RAISED!!!\n"); + end + else + begin + (* update the least cooked sp *) + print_if_verbose ("Suppongo gia' stampato " ^ Names.string_of_id id ^ "\n") + end + end + | L.OpenedSection (dir,_) -> + let id = snd (Nameops.split_dirpath dir) in + print_if_verbose ("OpenDir " ^ Names.string_of_id id ^ "\n") + | L.ClosedSection (_,dir,state) -> + let id = snd (Nameops.split_dirpath dir) in + print_if_verbose("ClosedDir " ^ Names.string_of_id id ^ "\n") ; + if bprintleaf then + begin + (* open a new scope *) + pvars := []::!pvars ; + print_library_segment state bprintleaf dn ; + (* close the scope *) + match !pvars with + [] -> assert false + | he::tl -> pvars := tl + end ; + print_if_verbose "/ClosedDir\n" + | L.Module s -> + print_if_verbose ("Module " ^ (Names.string_of_dirpath 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 + printed := [] ; + pvars := [[]] ; + cumenv := Safe_typing.env_of_safe_env (Global.safe_env ()) ; + print_if_verbose ("Module " ^ s ^ ":\n") ; + print_library_segment ls true dn ; + 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 qid dn = + let module L = Library in + let module N = Nametab in + let module X = Xml in + + let (_,dir_path,_) = L.locate_qualified_library qid in + + let str = N.string_of_qualid qid in + let ls = L.module_segment (Some dir_path) in + print_if_verbose ("MODULE_BEGIN " ^ str ^ " " ^ + (L.module_full_filename dir_path) ^ "\n") ; + print_closed_section str (List.rev ls) dn ; + print_if_verbose ("MODULE_END " ^ str ^ " " ^ + (L.module_full_filename dir_path) ^ "\n") +;; + +(* printSection identifier directory_name *) +(* where identifier is the name of a closed 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 closed section d *) +(* Note: the terms are printed in their uncooked form plus the informations *) +(* on the parameters of their most cooked form *) +let printSection id dn = + let module L = Library in + let module N = Names in + let module No = Nameops in + let module X = Xml in + let sp = Lib.make_path id in + let ls = + let rec find_closed_section = + function + [] -> raise Not_found + | (_,Lib.ClosedSection (_,dir,ls))::_ when snd (No.split_dirpath dir) = id + -> ls + | _::t -> find_closed_section t + in + print_string ("Searching " ^ Names.string_of_path sp ^ "\n") ; + find_closed_section (Lib.contents_after None) + in + let str = N.string_of_id id in + print_if_verbose ("SECTION_BEGIN " ^ str ^ " " ^ N.string_of_path sp ^ "\n"); + print_closed_section str ls dn ; + print_if_verbose ("SECTION_END " ^ str ^ " " ^ N.string_of_path sp ^ "\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 +;; |
