diff options
author | Samuel Mimram <samuel.mimram@ens-lyon.org> | 2004-07-28 21:54:47 +0000 |
---|---|---|
committer | Samuel Mimram <samuel.mimram@ens-lyon.org> | 2004-07-28 21:54:47 +0000 |
commit | 6b649aba925b6f7462da07599fe67ebb12a3460e (patch) | |
tree | 43656bcaa51164548f3fa14e5b10de5ef1088574 /translate |
Imported Upstream version 8.0pl1upstream/8.0pl1
Diffstat (limited to 'translate')
-rw-r--r-- | translate/ppconstrnew.ml | 958 | ||||
-rw-r--r-- | translate/ppconstrnew.mli | 100 | ||||
-rw-r--r-- | translate/pptacticnew.ml | 903 | ||||
-rw-r--r-- | translate/pptacticnew.mli | 28 | ||||
-rw-r--r-- | translate/ppvernacnew.ml | 1123 | ||||
-rw-r--r-- | translate/ppvernacnew.mli | 34 |
6 files changed, 3146 insertions, 0 deletions
diff --git a/translate/ppconstrnew.ml b/translate/ppconstrnew.ml new file mode 100644 index 00000000..7d2feaf2 --- /dev/null +++ b/translate/ppconstrnew.ml @@ -0,0 +1,958 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: ppconstrnew.ml,v 1.62.2.2 2004/07/16 20:48:17 herbelin Exp $ *) + +(*i*) +open Ast +open Util +open Pp +open Nametab +open Names +open Nameops +open Libnames +open Coqast +open Ppextend +open Topconstr +open Term +open Pattern +(*i*) + +let pr_id id = Nameops.pr_id (Constrextern.v7_to_v8_id id) + +let sep_p = fun _ -> str"." +let sep_v = fun _ -> str"," ++ spc() +let sep_pp = fun _ -> str":" +let sep_bar = fun _ -> spc() ++ str"| " +let pr_tight_coma () = str "," ++ cut () + +let latom = 0 +let lannot = 100 +let lprod = 200 +let llambda = 200 +let lif = 200 +let lletin = 200 +let lfix = 200 +let larrow = 90 +let lcast = 100 +let larg = 9 +let lapp = 10 +let lposint = 0 +let lnegint = 35 (* must be consistent with Notation "- x" *) +let ltop = (200,E) +let lproj = 1 +let lsimple = (1,E) + +let prec_less child (parent,assoc) = + if parent < 0 && child = lprod then true + else + let parent = abs parent in + match assoc with + | E -> (<=) child parent + | L -> (<) child parent + | Prec n -> child<=n + | Any -> true + +let env_assoc_value v env = + try List.nth env (v-1) + with Not_found -> anomaly ("Inconsistent environment for pretty-print rule") + +let decode_constrlist_value = function + | CAppExpl (_,_,l) -> l + | CApp (_,_,l) -> List.map fst l + | _ -> anomaly "Ill-formed list argument of notation" + +let decode_patlist_value = function + | CPatCstr (_,_,l) -> l + | _ -> anomaly "Ill-formed list argument of notation" + +open Symbols + +let rec print_hunk n decode pr env = function + | UnpMetaVar (e,prec) -> pr (n,prec) (env_assoc_value e env) + | UnpListMetaVar (e,prec,sl) -> + prlist_with_sep (fun () -> prlist (print_hunk n decode pr env) sl) + (pr (n,prec)) (decode (env_assoc_value e env)) + | UnpTerminal s -> str s + | UnpBox (b,sub) -> ppcmd_of_box b (prlist (print_hunk n decode pr env) sub) + | UnpCut cut -> ppcmd_of_cut cut + +let pr_notation_gen decode pr s env = + let unpl, level = find_notation_printing_rule s in + prlist (print_hunk level decode pr env) unpl, level + +let pr_notation = pr_notation_gen decode_constrlist_value +let pr_patnotation = pr_notation_gen decode_patlist_value + +let pr_delimiters key strm = + strm ++ str ("%"^key) + +let surround p = hov 1 (str"(" ++ p ++ str")") + +let pr_located pr ((b,e),x) = + if Options.do_translate() && (b,e)<>dummy_loc then + let (b,e) = unloc (b,e) in + comment b ++ pr x ++ comment e + else pr x + +let pr_com_at n = + if Options.do_translate() && n <> 0 then comment n + else mt() + +let pr_with_comments loc pp = pr_located (fun x -> x) (loc,pp) + +let pr_sep_com sep f c = pr_with_comments (constr_loc c) (sep() ++ f c) + +open Rawterm + +let pr_opt pr = function + | None -> mt () + | Some x -> spc() ++ pr x + +let pr_optc pr = function + | None -> mt () + | Some x -> pr_sep_com spc pr x + +let pr_universe u = str "<univ>" + +let pr_sort = function + | RProp Term.Null -> str "Prop" + | RProp Term.Pos -> str "Set" + | RType u -> str "Type" ++ pr_opt pr_universe u + +let pr_expl_args pr (a,expl) = + match expl with + | None -> pr (lapp,L) a + | Some (_,ExplByPos n) -> + anomaly("Explicitation by position not implemented") + | Some (_,ExplByName id) -> + str "(" ++ pr_id id ++ str ":=" ++ pr ltop a ++ str ")" + +let pr_opt_type pr = function + | CHole _ -> mt () + | t -> cut () ++ str ":" ++ pr t + +let pr_opt_type_spc pr = function + | CHole _ -> mt () + | t -> str " :" ++ pr_sep_com (fun()->brk(1,2)) (pr ltop) t + +let pr_name = function + | Anonymous -> str"_" + | Name id -> pr_id id + +let pr_lident (b,_ as loc,id) = + if loc <> dummy_loc then + let (b,_) = unloc loc in + pr_located pr_id (make_loc (b,b+String.length(string_of_id id)),id) + else pr_id id + +let pr_lname = function + (loc,Name id) -> pr_lident (loc,id) + | lna -> pr_located pr_name lna + +let pr_or_var pr = function + | Genarg.ArgArg x -> pr x + | Genarg.ArgVar (loc,s) -> pr_lident (loc,s) + +let las = lapp + +let rec pr_patt sep inh p = + let (strm,prec) = match p with + | CPatAlias (_,p,id) -> + pr_patt mt (las,E) p ++ str " as " ++ pr_id id, las + | CPatCstr (_,c,[]) -> pr_reference c, latom + | CPatCstr (_,c,args) -> + pr_reference c ++ prlist (pr_patt spc (lapp,L)) args, lapp + | CPatAtom (_,None) -> str "_", latom + | CPatAtom (_,Some r) -> pr_reference r, latom + | CPatNotation (_,"( _ )",[p]) -> + pr_patt (fun()->str"(") (max_int,E) p ++ str")", latom + | CPatNotation (_,s,env) -> pr_patnotation (pr_patt mt) s env + | CPatNumeral (_,i) -> Bignat.pr_bigint i, latom + | CPatDelimiters (_,k,p) -> pr_delimiters k (pr_patt mt lsimple p), 1 + in + let loc = cases_pattern_loc p in + pr_with_comments loc + (sep() ++ if prec_less prec inh then strm else surround strm) + +let pr_patt = pr_patt mt + + +let pr_eqn pr (loc,pl,rhs) = + spc() ++ hov 4 + (pr_with_comments loc + (str "| " ++ + hov 0 (prlist_with_sep sep_v (pr_patt ltop) pl ++ str " =>") ++ + pr_sep_com spc (pr ltop) rhs)) + +let begin_of_binder = function + LocalRawDef((loc,_),_) -> fst (unloc loc) + | LocalRawAssum((loc,_)::_,_) -> fst (unloc loc) + | _ -> assert false + +let begin_of_binders = function + | b::_ -> begin_of_binder b + | _ -> 0 + +let pr_binder many pr (nal,t) = + match t with + | CHole _ -> prlist_with_sep spc pr_lname nal + | _ -> + let s = prlist_with_sep spc pr_lname nal ++ str" : " ++ pr t in + hov 1 (if many then surround s else s) + +let pr_binder_among_many pr_c = function + | LocalRawAssum (nal,t) -> + pr_binder true pr_c (nal,t) + | LocalRawDef (na,c) -> + let c,topt = match c with + | CCast(_,c,t) -> c, t + | _ -> c, CHole dummy_loc in + hov 1 (surround + (pr_lname na ++ pr_opt_type pr_c topt ++ + str":=" ++ cut() ++ pr_c c)) + +let pr_undelimited_binders pr_c = + prlist_with_sep spc (pr_binder_among_many pr_c) + +let pr_delimited_binders kw pr_c bl = + let n = begin_of_binders bl in + match bl with + | [LocalRawAssum (nal,t)] -> + pr_com_at n ++ kw() ++ pr_binder false pr_c (nal,t) + | LocalRawAssum _ :: _ as bdl -> + pr_com_at n ++ kw() ++ pr_undelimited_binders pr_c bdl + | _ -> assert false + +let pr_let_binder pr x a = + hov 0 (hov 0 (pr_name x ++ brk(0,1) ++ str ":=") ++ + pr_sep_com (fun () -> brk(0,1)) (pr ltop) a) + +let rec extract_prod_binders = function +(* | CLetIn (loc,na,b,c) as x -> + let bl,c = extract_prod_binders c in + if bl = [] then [], x else LocalRawDef (na,b) :: bl, c*) + | CProdN (loc,[],c) -> + extract_prod_binders c + | CProdN (loc,(nal,t)::bl,c) -> + let bl,c = extract_prod_binders (CProdN(loc,bl,c)) in + LocalRawAssum (nal,t) :: bl, c + | c -> [], c + +let rec extract_lam_binders = function +(* | CLetIn (loc,na,b,c) as x -> + let bl,c = extract_lam_binders c in + if bl = [] then [], x else LocalRawDef (na,b) :: bl, c*) + | CLambdaN (loc,[],c) -> + extract_lam_binders c + | CLambdaN (loc,(nal,t)::bl,c) -> + let bl,c = extract_lam_binders (CLambdaN(loc,bl,c)) in + LocalRawAssum (nal,t) :: bl, c + | c -> [], c + +let pr_global vars ref = + (* pr_global_env vars ref *) + let s = string_of_qualid (Constrextern.shortest_qualid_of_v7_global vars ref) in + (str s) + +let split_lambda = function + | CLambdaN (loc,[[na],t],c) -> (na,t,c) + | CLambdaN (loc,([na],t)::bl,c) -> (na,t,CLambdaN(loc,bl,c)) + | CLambdaN (loc,(na::nal,t)::bl,c) -> (na,t,CLambdaN(loc,(nal,t)::bl,c)) + | _ -> anomaly "ill-formed fixpoint body" + +let rename na na' t c = + match (na,na') with + | (_,Name id), (_,Name id') -> (na',t,replace_vars_constr_expr [id,id'] c) + | (_,Name id), (_,Anonymous) -> (na,t,c) + | _ -> (na',t,c) + +let split_product na' = function + | CArrow (loc,t,c) -> (na',t,c) + | CProdN (loc,[[na],t],c) -> rename na na' t c + | CProdN (loc,([na],t)::bl,c) -> rename na na' t (CProdN(loc,bl,c)) + | CProdN (loc,(na::nal,t)::bl,c) -> + rename na na' t (CProdN(loc,(nal,t)::bl,c)) + | _ -> anomaly "ill-formed fixpoint body" + +let merge_binders (na1,ty1) cofun (na2,ty2) codom = + let na = + match snd na1, snd na2 with + Anonymous, Name id -> + if occur_var_constr_expr id cofun then + failwith "avoid capture" + else na2 + | Name id, Anonymous -> + if occur_var_constr_expr id codom then + failwith "avoid capture" + else na1 + | Anonymous, Anonymous -> na1 + | Name id1, Name id2 -> + if id1 <> id2 then failwith "not same name" else na1 in + let ty = + match ty1, ty2 with + CHole _, _ -> ty2 + | _, CHole _ -> ty1 + | _ -> + Constrextern.check_same_type ty1 ty2; + ty2 in + (LocalRawAssum ([na],ty), codom) + +let rec strip_domain bvar cofun c = + match c with + | CArrow(loc,a,b) -> + merge_binders bvar cofun ((dummy_loc,Anonymous),a) b + | CProdN(loc,[([na],ty)],c') -> + merge_binders bvar cofun (na,ty) c' + | CProdN(loc,([na],ty)::bl,c') -> + merge_binders bvar cofun (na,ty) (CProdN(loc,bl,c')) + | CProdN(loc,(na::nal,ty)::bl,c') -> + merge_binders bvar cofun (na,ty) (CProdN(loc,(nal,ty)::bl,c')) + | _ -> failwith "not a product" + +(* Note: binder sharing is lost *) +let rec strip_domains (nal,ty) cofun c = + match nal with + [] -> assert false + | [na] -> + let bnd, c' = strip_domain (na,ty) cofun c in + ([bnd],None,c') + | na::nal -> + let f = CLambdaN(dummy_loc,[(nal,ty)],cofun) in + let bnd, c1 = strip_domain (na,ty) f c in + (try + let bl, rest, c2 = strip_domains (nal,ty) cofun c1 in + (bnd::bl, rest, c2) + with Failure _ -> ([bnd],Some (nal,ty), c1)) + +(* Re-share binders *) +let rec factorize_binders = function + | ([] | [_] as l) -> l + | LocalRawAssum (nal,ty) as d :: (LocalRawAssum (nal',ty')::l as l') -> + (try + let _ = Constrextern.check_same_type ty ty' in + factorize_binders (LocalRawAssum (nal@nal',ty)::l) + with _ -> + d :: factorize_binders l') + | d :: l -> d :: factorize_binders l + +(* Extract lambdas when a type constraint occurs *) +let rec extract_def_binders c ty = + match c with + | CLambdaN(loc,bvar::lams,b) -> + (try + let f = CLambdaN(loc,lams,b) in + let bvar', rest, ty' = strip_domains bvar f ty in + let c' = + match rest, lams with + None,[] -> b + | None, _ -> f + | Some bvar,_ -> CLambdaN(loc,bvar::lams,b) in + let (bl,c2,ty2) = extract_def_binders c' ty' in + (factorize_binders (bvar'@bl), c2, ty2) + with Failure _ -> + ([],c,ty)) + | _ -> ([],c,ty) + +let rec split_fix n typ def = + if n = 0 then ([],typ,def) + else + let (na,_,def) = split_lambda def in + let (na,t,typ) = split_product na typ in + let (bl,typ,def) = split_fix (n-1) typ def in + (LocalRawAssum ([na],t)::bl,typ,def) + +let pr_recursive_decl pr id bl annot t c = + pr_id id ++ str" " ++ + hov 0 (pr_undelimited_binders (pr ltop) bl ++ annot) ++ + pr_opt_type_spc pr t ++ str " :=" ++ + pr_sep_com (fun () -> brk(1,2)) (pr ltop) c + +let pr_fixdecl pr (id,n,bl,t,c) = + let annot = + let ids = names_of_local_assums bl in + if List.length ids > 1 then + spc() ++ str "{struct " ++ pr_name (snd (List.nth ids n)) ++ str"}" + else mt() in + pr_recursive_decl pr id bl annot t c + +let pr_cofixdecl pr (id,bl,t,c) = + pr_recursive_decl pr id bl (mt()) t c + +let pr_recursive pr_decl id = function + | [] -> anomaly "(co)fixpoint with no definition" + | [d1] -> pr_decl d1 + | dl -> + prlist_with_sep (fun () -> fnl() ++ str "with ") pr_decl dl ++ + fnl() ++ str "for " ++ pr_id id + +let pr_arg pr x = spc () ++ pr x + +let is_var id = function + | CRef (Ident (_,id')) when id=id' -> true + | _ -> false + +let tm_clash = function + | (CRef (Ident (_,id)), Some (CApp (_,_,nal))) + when List.exists (function CRef (Ident (_,id')),_ -> id=id' | _ -> false) + nal + -> Some id + | (CRef (Ident (_,id)), Some (CAppExpl (_,_,nal))) + when List.exists (function CRef (Ident (_,id')) -> id=id' | _ -> false) + nal + -> Some id + | _ -> None + +let pr_case_item pr (tm,(na,indnalopt)) = + hov 0 (pr (lcast,E) tm ++ +(* + (match na with + | Name id when not (is_var id tm) -> spc () ++ str "as " ++ pr_id id + | Anonymous when tm_clash (tm,indnalopt) <> None -> + (* hide [tm] name to avoid conflicts *) + spc () ++ str "as _" (* ++ pr_id (out_some (tm_clash (tm,indnalopt)))*) + | _ -> mt ()) ++ +*) + (match na with (* Decision of printing "_" or not moved to constrextern.ml *) + | Some na -> spc () ++ str "as " ++ pr_name na + | None -> mt ()) ++ + (match indnalopt with + | None -> mt () +(* + | Some (_,ind,nal) -> + spc () ++ str "in " ++ + hov 0 (pr_reference ind ++ prlist (pr_arg pr_name) nal)) +*) + | Some t -> spc () ++ str "in " ++ pr lsimple t)) + +let pr_case_type pr po = + match po with + | None | Some (CHole _) -> mt() + | Some p -> + spc() ++ hov 2 (str "return" ++ pr_sep_com spc (pr lsimple) p) + +let pr_return_type pr po = pr_case_type pr po + +let pr_simple_return_type pr na po = + (match na with + | Some (Name id) -> + spc () ++ str "as " ++ pr_id id + | _ -> mt ()) ++ + pr_case_type pr po + +let pr_proj pr pr_app a f l = + hov 0 (pr lsimple a ++ cut() ++ str ".(" ++ pr_app pr f l ++ str ")") + +let pr_appexpl pr f l = + hov 2 ( + str "@" ++ pr_reference f ++ + prlist (pr_sep_com spc (pr (lapp,L))) l) + +let pr_app pr a l = + hov 2 ( + pr (lapp,L) a ++ + prlist (fun a -> spc () ++ pr_expl_args pr a) l) + +let rec pr sep inherited a = + let (strm,prec) = match a with + | CRef r -> pr_reference r, latom + | CFix (_,id,fix) -> + let p = hov 0 (str"fix " ++ + pr_recursive (pr_fixdecl (pr mt)) (snd id) fix) in + if List.length fix = 1 & prec_less (fst inherited) ltop + then surround p, latom else p, lfix + | CCoFix (_,id,cofix) -> + let p = + hov 0 (str "cofix " ++ + pr_recursive (pr_cofixdecl (pr mt)) (snd id) cofix) in + if List.length cofix = 1 & prec_less (fst inherited) ltop + then surround p, latom else p, lfix + | CArrow (_,a,b) -> + hov 0 (pr mt (larrow,L) a ++ str " ->" ++ + pr (fun () ->brk(1,0)) (-larrow,E) b), + larrow + | CProdN _ -> + let (bl,a) = extract_prod_binders a in + hov 0 ( + hov 2 (pr_delimited_binders (fun () -> str"forall" ++ spc()) + (pr mt ltop) bl) ++ + str "," ++ pr spc ltop a), + lprod + | CLambdaN _ -> + let (bl,a) = extract_lam_binders a in + hov 0 ( + hov 2 (pr_delimited_binders (fun () -> str"fun" ++ spc()) + (pr mt ltop) bl) ++ + + str " =>" ++ pr spc ltop a), + llambda + | CLetIn (_,(_,Name x),(CFix(_,(_,x'),[_])|CCoFix(_,(_,x'),[_]) as fx), b) + when x=x' -> + hv 0 ( + hov 2 (str "let " ++ pr mt ltop fx ++ str " in") ++ + pr spc ltop b), + lletin + | CLetIn (_,x,a,b) -> + hv 0 ( + hov 2 (str "let " ++ pr_lname x ++ str " :=" ++ + pr spc ltop a ++ str " in") ++ + pr spc ltop b), + lletin + | CAppExpl (_,(Some i,f),l) -> + let l1,l2 = list_chop i l in + let c,l1 = list_sep_last l1 in + let p = pr_proj (pr mt) pr_appexpl c f l1 in + if l2<>[] then + p ++ prlist (pr spc (lapp,L)) l2, lapp + else + p, lproj + | CAppExpl (_,(None,Ident (_,var)),[t]) + | CApp (_,(_,CRef(Ident(_,var))),[t,None]) + when var = Topconstr.ldots_var -> + hov 0 (str ".." ++ pr spc (latom,E) t ++ spc () ++ str ".."), larg + | CAppExpl (_,(None,f),l) -> pr_appexpl (pr mt) f l, lapp + | CApp (_,(Some i,f),l) -> + let l1,l2 = list_chop i l in + let c,l1 = list_sep_last l1 in + assert (snd c = None); + let p = pr_proj (pr mt) pr_app (fst c) f l1 in + if l2<>[] then + p ++ prlist (fun a -> spc () ++ pr_expl_args (pr mt) a) l2, lapp + else + p, lproj + | CApp (_,(None,a),l) -> pr_app (pr mt) a l, lapp + | CCases (_,(po,rtntypopt),c,eqns) -> + v 0 + (hv 0 (str "match" ++ brk (1,2) ++ + hov 0 ( + prlist_with_sep sep_v (pr_case_item (pr mt)) c + ++ pr_case_type (pr mt) rtntypopt) ++ + spc () ++ str "with") ++ + prlist (pr_eqn (pr mt)) eqns ++ spc() ++ str "end"), + latom + | CLetTuple (_,nal,(na,po),c,b) -> + hv 0 ( + str "let " ++ + hov 0 (str "(" ++ + prlist_with_sep sep_v pr_name nal ++ + str ")" ++ + pr_simple_return_type (pr mt) na po ++ str " :=" ++ + pr spc ltop c ++ str " in") ++ + pr spc ltop b), + lletin + | CIf (_,c,(na,po),b1,b2) -> + (* On force les parenthèses autour d'un "if" sous-terme (même si le + parsing est lui plus tolérant) *) + hv 0 ( + hov 1 (str "if " ++ pr mt ltop c ++ pr_simple_return_type (pr mt) na po) ++ + spc () ++ + hov 0 (str "then" ++ pr (fun () -> brk (1,1)) ltop b1) ++ spc () ++ + hov 0 (str "else" ++ pr (fun () -> brk (1,1)) ltop b2)), + lif + + | COrderedCase (_,st,po,c,[b1;b2]) when st = IfStyle -> + (* On force les parenthèses autour d'un "if" sous-terme (même si le + parsing est lui plus tolérant) *) + hv 0 ( + hov 1 (str "if " ++ pr mt ltop c ++ + pr_return_type (pr mt) po) ++ spc () ++ + hov 0 (str "then" ++ pr (fun () -> brk (1,1)) ltop b1) ++ spc () ++ + hov 0 (str "else" ++ pr (fun () -> brk (1,1)) ltop b2)), + lif + | COrderedCase (_,st,po,c,[CLambdaN(_,[nal,_],b)]) when st = LetStyle -> + hv 0 ( + str "let " ++ + hov 0 (str "(" ++ + prlist_with_sep sep_v (fun (_,n) -> pr_name n) nal ++ + str ")" ++ + pr_return_type (pr mt) po ++ str " :=" ++ + pr spc ltop c ++ str " in") ++ + pr spc ltop b), + lletin + + | COrderedCase (_,style,po,c,bl) -> + hv 0 ( + str (if style=MatchStyle then "old_match " else "match ") ++ + pr mt ltop c ++ + pr_return_type (pr mt) po ++ + str " with" ++ brk (1,0) ++ + hov 0 (prlist + (fun b -> str "| ??? =>" ++ pr spc ltop b ++ fnl ()) bl) ++ + str "end"), + latom + | CHole _ -> str "_", latom + | CEvar (_,n) -> str (Evd.string_of_existential n), latom + | CPatVar (_,(_,p)) -> str "?" ++ pr_patvar p, latom + | CSort (_,s) -> pr_sort s, latom + | CCast (_,a,b) -> + hv 0 (pr mt (lcast,L) a ++ cut () ++ str ":" ++ pr mt (-lcast,E) b), + lcast + | CNotation (_,"( _ )",[t]) -> + pr (fun()->str"(") (max_int,L) t ++ str")", latom + | CNotation (_,s,env) -> pr_notation (pr mt) s env + | CNumeral (_,(Bignat.POS _ as p)) -> Bignat.pr_bigint p, lposint + | CNumeral (_,(Bignat.NEG _ as p)) -> Bignat.pr_bigint p, lnegint + | CDelimiters (_,sc,a) -> pr_delimiters sc (pr mt lsimple a), 1 + | CDynamic _ -> str "<dynamic>", latom + in + let loc = constr_loc a in + pr_with_comments loc + (sep() ++ if prec_less prec inherited then strm else surround strm) + +let pr = pr mt + +let rec abstract_constr_expr c = function + | [] -> c + | LocalRawDef (x,b)::bl -> mkLetInC(x,b,abstract_constr_expr c bl) + | LocalRawAssum (idl,t)::bl -> + List.fold_right (fun x b -> mkLambdaC([x],t,b)) idl + (abstract_constr_expr c bl) + +let rec prod_constr_expr c = function + | [] -> c + | LocalRawDef (x,b)::bl -> mkLetInC(x,b,prod_constr_expr c bl) + | LocalRawAssum (idl,t)::bl -> + List.fold_right (fun x b -> mkProdC([x],t,b)) idl + (prod_constr_expr c bl) + +let rec strip_context n iscast t = + if n = 0 then + [], if iscast then match t with CCast (_,c,_) -> c | _ -> t else t + else match t with + | CLambdaN (loc,(nal,t)::bll,c) -> + let n' = List.length nal in + if n' > n then + let nal1,nal2 = list_chop n nal in + [LocalRawAssum (nal1,t)], CLambdaN (loc,(nal2,t)::bll,c) + else + let bl', c = strip_context (n-n') iscast + (if bll=[] then c else CLambdaN (loc,bll,c)) in + LocalRawAssum (nal,t) :: bl', c + | CProdN (loc,(nal,t)::bll,c) -> + let n' = List.length nal in + if n' > n then + let nal1,nal2 = list_chop n nal in + [LocalRawAssum (nal1,t)], CProdN (loc,(nal2,t)::bll,c) + else + let bl', c = strip_context (n-n') iscast + (if bll=[] then c else CProdN (loc,bll,c)) in + LocalRawAssum (nal,t) :: bl', c + | CArrow (loc,t,c) -> + let bl', c = strip_context (n-1) iscast c in + LocalRawAssum ([loc,Anonymous],t) :: bl', c + | CCast (_,c,_) -> strip_context n false c + | CLetIn (_,na,b,c) -> + let bl', c = strip_context (n-1) iscast c in + LocalRawDef (na,b) :: bl', c + | _ -> anomaly "ppconstrnew: strip_context" + +let transf istype env iscast bl c = + let c' = + if istype then prod_constr_expr c bl + else abstract_constr_expr c bl in + if Options.do_translate() then + let r = + Constrintern.for_grammar + (Constrintern.interp_rawconstr_gen istype Evd.empty env false ([],[])) + c' in + begin try + (* Try to infer old case and type annotations *) + let _ = Pretyping.understand_gen_tcc Evd.empty env [] None r in + (*msgerrnl (str "Typage OK");*) () + with e -> (*msgerrnl (str "Warning: can't type")*) () end; + let c = + (if istype then Constrextern.extern_rawtype + else Constrextern.extern_rawconstr) + (Termops.vars_of_env env) r in + let n = local_binders_length bl in + strip_context n iscast c + else bl, c + +let pr_constr_env env c = pr lsimple (snd (transf false env false [] c)) +let pr_lconstr_env env c = pr ltop (snd (transf false env false [] c)) +let pr_constr c = pr_constr_env (Global.env()) c +let pr_lconstr c = pr_lconstr_env (Global.env()) c + +let pr_binders = pr_undelimited_binders (pr ltop) + +let is_Eval_key c = + Options.do_translate () & + (let f id = let s = string_of_id id in s = "Eval" in + let g = function + | Ident(_,id) -> f id + | Qualid (_,qid) -> let d,id = repr_qualid qid in d = empty_dirpath & f id + in + match c with + | CRef ref | CApp (_,(_,CRef ref),_) when g ref -> true + | _ -> false) + +let pr_protect_eval c = + if is_Eval_key c then h 0 (str "(" ++ pr ltop c ++ str ")") else pr ltop c + +let pr_lconstr_env_n env iscast bl c = + let bl, c = transf false env iscast bl c in + bl, pr_protect_eval c +let pr_type_env_n env bl c = pr ltop (snd (transf true env false bl c)) +let pr_type c = pr ltop (snd (transf true (Global.env()) false [] c)) + +let transf_pattern env c = + if Options.do_translate() then + Constrextern.extern_rawconstr (Termops.vars_of_env env) + (Constrintern.for_grammar + (Constrintern.interp_rawconstr_gen false Evd.empty env true ([],[])) + c) + else c + +let pr_pattern c = pr lsimple (transf_pattern (Global.env()) c) + +let pr_rawconstr_env env c = + pr_constr (Constrextern.extern_rawconstr (Termops.vars_of_env env) c) +let pr_lrawconstr_env env c = + pr_lconstr (Constrextern.extern_rawconstr (Termops.vars_of_env env) c) + +let pr_cases_pattern = pr_patt ltop + +let pr_pattern_occ prc = function + ([],c) -> prc c + | (nl,c) -> hov 1 (prc c ++ spc() ++ str"at " ++ + hov 0 (prlist_with_sep spc int nl)) + +let pr_unfold_occ pr_ref = function + ([],qid) -> pr_ref qid + | (nl,qid) -> hov 1 (pr_ref qid ++ spc() ++ str"at " ++ + hov 0 (prlist_with_sep spc int nl)) + +let pr_qualid qid = str (string_of_qualid qid) + +open Rawterm + +let pr_arg pr x = spc () ++ pr x + +let pr_red_flag pr r = + (if r.rBeta then pr_arg str "beta" else mt ()) ++ + (if r.rIota then pr_arg str "iota" else mt ()) ++ + (if r.rZeta then pr_arg str "zeta" else mt ()) ++ + (if r.rConst = [] then + if r.rDelta then pr_arg str "delta" + else mt () + else + pr_arg str "delta " ++ (if r.rDelta then str "-" else mt ()) ++ + hov 0 (str "[" ++ prlist_with_sep spc pr r.rConst ++ str "]")) + +open Genarg + +let pr_metaid id = str"?" ++ pr_id id + +let pr_red_expr (pr_constr,pr_lconstr,pr_ref) = function + | Red false -> str "red" + | Hnf -> str "hnf" + | Simpl o -> str "simpl" ++ pr_opt (pr_pattern_occ pr_constr) o + | Cbv f -> + if f = {rBeta=true;rIota=true;rZeta=true;rDelta=true;rConst=[]} then + str "compute" + else + hov 1 (str "cbv" ++ pr_red_flag pr_ref f) + | Lazy f -> + hov 1 (str "lazy" ++ pr_red_flag pr_ref f) + | Unfold l -> + hov 1 (str "unfold" ++ spc() ++ + prlist_with_sep pr_coma (pr_unfold_occ pr_ref) l) + | Fold l -> hov 1 (str "fold" ++ prlist (pr_arg pr_constr) l) + | Pattern l -> + hov 1 (str "pattern" ++ + pr_arg (prlist_with_sep pr_coma (pr_pattern_occ pr_constr)) l) + + | Red true -> error "Shouldn't be accessible from user" + | ExtraRedExpr (s,c) -> + hov 1 (str s ++ pr_arg pr_constr c) + +let rec pr_may_eval test prc prlc pr2 = function + | ConstrEval (r,c) -> + hov 0 + (str "eval" ++ brk (1,1) ++ + pr_red_expr (prc,prlc,pr2) r ++ + str " in" ++ spc() ++ prc c) + | ConstrContext ((_,id),c) -> + hov 0 + (str "context " ++ pr_id id ++ spc () ++ + str "[" ++ prlc c ++ str "]") + | ConstrTypeOf c -> hov 1 (str "type of" ++ spc() ++ prc c) + | ConstrTerm c when test c -> h 0 (str "(" ++ prc c ++ str ")") + | ConstrTerm c -> prc c + +let pr_may_eval a = pr_may_eval (fun _ -> false) a + +let pr_rawconstr_env_no_translate env c = + pr lsimple (Constrextern.extern_rawconstr (Termops.vars_of_env env) c) +let pr_lrawconstr_env_no_translate env c = + pr ltop (Constrextern.extern_rawconstr (Termops.vars_of_env env) c) + +(* Printing reference with translation *) + +let pr_reference r = + let loc = loc_of_reference r in + try match Nametab.extended_locate (snd (qualid_of_reference r)) with + | TrueGlobal ref -> + pr_with_comments loc + (pr_reference (Constrextern.extern_reference loc Idset.empty ref)) + | SyntacticDef kn -> + let is_coq_root d = + let d = repr_dirpath d in + d <> [] & string_of_id (list_last d) = "Coq" in + let dir,id = repr_path (sp_of_syntactic_definition kn) in + let r = + if (is_coq_root (Lib.library_dp()) or is_coq_root dir) then + (match Syntax_def.search_syntactic_definition loc kn with + | RRef (_,ref) -> + Constrextern.extern_reference dummy_loc Idset.empty ref + | _ -> r) + else r + in pr_with_comments loc (pr_reference r) + with Not_found -> + error_global_not_found (snd (qualid_of_reference r)) + +(** constr printers *) + +let pr_term_env env c = pr lsimple (Constrextern.extern_constr false env c) +let pr_lterm_env env c = pr ltop (Constrextern.extern_constr false env c) +let pr_term c = pr_term_env (Global.env()) c +let pr_lterm c = pr_lterm_env (Global.env()) c + +let pr_constr_pattern_env env c = + pr lsimple (Constrextern.extern_pattern env Termops.empty_names_context c) + +let pr_constr_pattern t = + pr lsimple + (Constrextern.extern_pattern (Global.env()) Termops.empty_names_context t) + + +(************************************************************************) +(* Automatic standardisation of names in Arith and ZArith by translator *) +(* Very not robust *) + +let is_to_rename dir id = + let dirs = List.map string_of_id (repr_dirpath dir) in + match List.rev dirs with + | "Coq"::"Arith"::"Between"::_ -> false + | "Coq"::"ZArith":: + ("Wf_Z"|"Zpower"|"Zlogarithm"|"Zbinary"|"Zdiv"|"Znumtheory")::_ -> false + | "Coq"::("Arith"|"NArith"|"ZArith")::_ -> true + | "Coq"::"Init"::"Peano"::_ -> true + | "Coq"::"Init"::"Logic"::_ when string_of_id id = "iff_trans" -> true + | "Coq"::"Reals"::"RIneq"::_ -> true + | _ -> false + +let is_ref_to_rename ref = + let sp = sp_of_global ref in + is_to_rename (dirpath sp) (basename sp) + +let get_name (ln,lp,lz,ll,lr,lr') id refbase n = + let id' = string_of_id n in + (match id' with + | "nat" -> (id_of_string (List.hd ln),(List.tl ln,lp,lz,ll,lr,lr')) + | "positive" -> (id_of_string (List.hd lp),(ln,List.tl lp,lz,ll,lr,lr')) + | "Z" -> (id_of_string (List.hd lz),(ln,lp,List.tl lz,ll,lr,lr')) + | "Prop" when List.mem (string_of_id id) ["a";"b";"c"] -> + (* pour iff_trans *) + (id_of_string (List.hd ll),(ln,lp,lz,List.tl ll,lr,lr')) + | "R" when (* Noms r,r1,r2 *) + refbase = "Rle_refl" or + refbase = "Rlt_monotony_contra" or + refbase = "Rmult_le_reg_l" or + refbase = "Rle_monotony_contra" or + refbase = "Rge_monotony" -> + (id_of_string (List.hd lr')),(ln,lp,lz,ll,lr,List.tl lr') + | "R" when (* Noms r1,r2,r3,r4 *) + List.mem (string_of_id id) + ["x";"y";"x'";"y'";"z";"t";"n";"m";"a";"b";"c";"p";"q"] + & refbase <> "sum_inequa_Rle_lt" + -> + (id_of_string (List.hd lr),(ln,lp,lz,ll,List.tl lr,lr')) + | _ -> id,(ln,lp,lz,ll,lr,lr')) + +let get_name_constr names id refbase t = match kind_of_term t with + | Ind ind -> + let n = basename (sp_of_global (IndRef ind)) in + get_name names id refbase n + | Const sp -> + let n = basename (sp_of_global (ConstRef sp)) in + get_name names id refbase n + | Sort _ -> get_name names id refbase (id_of_string "Prop") + | _ -> id,names + +let names = + (["n";"m";"p";"q"],["p";"q";"r";"s"],["n";"m";"p";"q"],["A";"B";"C"], + ["r1";"r2";"r3";"r4"],["r";"r1";"r2"]) + +let znames refbase t = + let rec aux c names = match kind_of_term c with + | Prod (Name id as na,t,c) -> + let (id,names) = get_name_constr names id refbase t in + (na,id) :: aux c names + | Prod (Anonymous,t,c) -> + (Anonymous,id_of_string "ZZ") :: aux c names + | _ -> [] + in aux t names + +let get_name_raw names id refbase t = match t with + | CRef(Ident (_,n)) -> get_name names id refbase n + | CSort _ -> get_name names id refbase (id_of_string "Prop") + | _ -> id,names + +let rename_bound_variables id0 t = + if is_to_rename (Lib.library_dp()) id0 then + let refbase = string_of_id id0 in + let rec aux c names subst = match c with + | CProdN (loc,bl,c) -> + let rec aux2 names subst = function + | (nal,t)::bl -> + let rec aux3 names subst = function + | (loc,Name id)::nal -> + let (id',names) = get_name_raw names id refbase t in + let (nal,names,subst) = aux3 names ((id,id')::subst) nal in + (loc,Name id')::nal, names, subst + | x::nal -> + let (nal,names,subst) = aux3 names subst nal in + x::nal,names,subst + | [] -> [],names,subst in + let t = replace_vars_constr_expr subst t in + let nal,names,subst = aux3 names subst nal in + let bl,names,subst = aux2 names subst bl in + (nal,t)::bl, names, subst + | [] -> [],names,subst in + let bl,names,subst = aux2 names subst bl in + CProdN (loc,bl,aux c names subst) + | CArrow (loc,t,u) -> + let u = aux u names subst in + CArrow (loc,replace_vars_constr_expr subst t,u) + | _ -> replace_vars_constr_expr subst c + in aux t names [] + else t + +let translate_binding kn n ebl = + let t = Retyping.get_type_of (Global.env()) Evd.empty (mkConst kn) in + let subst= znames (string_of_id (basename (sp_of_global (ConstRef kn)))) t in + try + let _,subst' = list_chop n subst in + List.map (function + | (x,NamedHyp id,c) -> (x,NamedHyp (List.assoc (Name id) subst'),c) + | x -> x) ebl + with _ -> ebl + +let translate_with_bindings c bl = + match bl with + | ExplicitBindings l -> + let l = match c with + | RRef (_,(ConstRef kn as ref)) when is_ref_to_rename ref -> + translate_binding kn 0 l + | RApp (_,RRef (_,(ConstRef kn as ref)),args) when is_ref_to_rename ref + -> translate_binding kn (List.length args) l + | _ -> + l + in ExplicitBindings l + | x -> x diff --git a/translate/ppconstrnew.mli b/translate/ppconstrnew.mli new file mode 100644 index 00000000..4477728c --- /dev/null +++ b/translate/ppconstrnew.mli @@ -0,0 +1,100 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: ppconstrnew.mli,v 1.16.2.1 2004/07/16 19:31:52 herbelin Exp $ *) + +open Pp +open Environ +open Term +open Libnames +open Pcoq +open Rawterm +open Extend +open Coqast +open Topconstr +open Names +open Util +open Genarg + +val extract_lam_binders : + constr_expr -> local_binder list * constr_expr +val extract_prod_binders : + constr_expr -> local_binder list * constr_expr +val extract_def_binders : + constr_expr -> constr_expr -> + local_binder list * constr_expr * constr_expr +val split_fix : + int -> constr_expr -> constr_expr -> + local_binder list * constr_expr * constr_expr +val pr_binders : local_binder list -> std_ppcmds + +val prec_less : int -> int * Ppextend.parenRelation -> bool + +val pr_global : Idset.t -> global_reference -> std_ppcmds + +val pr_tight_coma : unit -> std_ppcmds +val pr_located : + ('a -> std_ppcmds) -> 'a located -> std_ppcmds +val pr_lident : identifier located -> std_ppcmds +val pr_lname : name located -> std_ppcmds + +val pr_with_comments : loc -> std_ppcmds -> std_ppcmds +val pr_com_at : int -> std_ppcmds +val pr_sep_com : + (unit -> std_ppcmds) -> + (constr_expr -> std_ppcmds) -> + constr_expr -> std_ppcmds +val pr_opt : ('a -> std_ppcmds) -> 'a option -> std_ppcmds +val pr_id : identifier -> std_ppcmds +val pr_name : name -> std_ppcmds +val pr_qualid : qualid -> std_ppcmds +val pr_or_var : ('a -> std_ppcmds) -> 'a or_var -> std_ppcmds +val pr_metaid : identifier -> std_ppcmds +val pr_red_expr : + ('a -> std_ppcmds) * ('a -> std_ppcmds) * ('b -> std_ppcmds) -> + ('a,'b) red_expr_gen -> std_ppcmds + +val pr_sort : rawsort -> std_ppcmds +val pr_pattern : Tacexpr.pattern_expr -> std_ppcmds +val pr_constr : constr_expr -> std_ppcmds +val pr_lconstr : constr_expr -> std_ppcmds +val pr_constr_env : env -> constr_expr -> std_ppcmds +val pr_lconstr_env : env -> constr_expr -> std_ppcmds +val pr_lconstr_env_n : env -> bool -> local_binder list -> constr_expr -> + local_binder list * std_ppcmds +val pr_type_env_n : env -> local_binder list -> constr_expr -> std_ppcmds +val pr_type : constr_expr -> std_ppcmds +val pr_cases_pattern : cases_pattern_expr -> std_ppcmds +val pr_may_eval : + ('a -> std_ppcmds) -> ('a -> std_ppcmds) -> ('b -> std_ppcmds) -> ('a,'b) may_eval + -> std_ppcmds +val abstract_constr_expr : constr_expr -> local_binder list -> constr_expr +val prod_constr_expr : constr_expr -> local_binder list -> constr_expr + + +val pr_rawconstr_env : env -> rawconstr -> std_ppcmds +val pr_lrawconstr_env : env -> rawconstr -> std_ppcmds + +val pr_rawconstr_env_no_translate : env -> rawconstr -> std_ppcmds +val pr_lrawconstr_env_no_translate : env -> rawconstr -> std_ppcmds + +val pr_reference : reference -> std_ppcmds + +(** constr printers *) + +val pr_term_env : env -> constr -> std_ppcmds +val pr_lterm_env : env -> constr -> std_ppcmds +val pr_term : constr -> std_ppcmds +val pr_lterm : constr -> std_ppcmds + +val pr_constr_pattern_env : env -> Pattern.constr_pattern -> std_ppcmds +val pr_constr_pattern : Pattern.constr_pattern -> std_ppcmds + +(* To translate names in ZArith *) +val translate_with_bindings : rawconstr -> 'a bindings -> 'a bindings +val rename_bound_variables : identifier -> constr_expr -> constr_expr diff --git a/translate/pptacticnew.ml b/translate/pptacticnew.ml new file mode 100644 index 00000000..80298c3e --- /dev/null +++ b/translate/pptacticnew.ml @@ -0,0 +1,903 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: pptacticnew.ml,v 1.57.2.2 2004/07/16 19:31:52 herbelin Exp $ *) + +open Pp +open Names +open Nameops +open Environ +open Util +open Extend +open Ppextend +open Ppconstrnew +open Tacexpr +open Rawterm +open Topconstr +open Genarg +open Libnames +open Pptactic + +let sep_v = fun _ -> str"," ++ spc() + +let strip_prod_binders_expr n ty = + let rec strip_ty acc n ty = + match ty with + Topconstr.CProdN(_,bll,a) -> + let nb = + List.fold_left (fun i (nal,_) -> i + List.length nal) 0 bll in + if nb >= n then (List.rev (bll@acc), a) + else strip_ty (bll@acc) (n-nb) a + | Topconstr.CArrow(_,a,b) -> + if n=1 then + (List.rev (([(dummy_loc,Anonymous)],a)::acc), b) + else strip_ty (([(dummy_loc,Anonymous)],a)::acc) (n-1) b + | _ -> error "Cannot translate fix tactic: not enough products" in + strip_ty [] n ty + + +(* In v8 syntax only double quote char is escaped by repeating it *) +let rec escape_string_v8 s = + let rec escape_at s i = + if i<0 then s + else if s.[i] == '"' then + let s' = String.sub s 0 i^"\""^String.sub s i (String.length s - i) in + escape_at s' (i-1) + else escape_at s (i-1) in + escape_at s (String.length s - 1) + +let qstringnew s = str ("\""^escape_string_v8 s^"\"") +let qsnew = qstringnew + +let translate_v7_ltac = function + | "DiscrR" -> "discrR" + | "Sup0" -> "prove_sup0" + | "SupOmega" -> "omega_sup" + | "Sup" -> "prove_sup" + | "RCompute" -> "Rcompute" + | "IntroHypG" -> "intro_hyp_glob" + | "IntroHypL" -> "intro_hyp_pt" + | "IsDiff_pt" -> "is_diff_pt" + | "IsDiff_glob" -> "is_diff_glob" + | "IsCont_pt" -> "is_cont_pt" + | "IsCont_glob" -> "is_cont_glob" + | "RewTerm" -> "rew_term" + | "ConsProof" -> "deriv_proof" + | "SimplifyDerive" -> "simplify_derive" + | "Reg" -> "reg" (* ??? *) + | "SplitAbs" -> "split_case_Rabs" + | "SplitAbsolu" -> "split_Rabs" + | "SplitRmult" -> "split_Rmult" + | "CaseEqk" -> "case_eq" + | "SqRing" -> "ring_Rsqr" + | "TailSimpl" -> "tail_simpl" + | "CoInduction" -> "coinduction" + | "ElimCompare" -> "elim_compare" + | "CCsolve" -> "CCsolve" (* ?? *) + | "ArrayAccess" -> "array_access" + | "MemAssoc" -> "mem_assoc" + | "SeekVarAux" -> "seek_var_aux" + | "SeekVar" -> "seek_var" + | "NumberAux" -> "number_aux" + | "Number" -> "number" + | "BuildVarList" -> "build_varlist" + | "Assoc" -> "assoc" + | "Remove" -> "remove" + | "Union" -> "union" + | "RawGiveMult" -> "raw_give_mult" + | "GiveMult" -> "give_mult" + | "ApplyAssoc" -> "apply_assoc" + | "ApplyDistrib" -> "apply_distrib" + | "GrepMult" -> "grep_mult" + | "WeakReduce" -> "weak_reduce" + | "Multiply" -> "multiply" + | "ApplyMultiply" -> "apply_multiply" + | "ApplyInverse" -> "apply_inverse" + | "StrongFail" -> "strong_fail" + | "InverseTestAux" -> "inverse_test_aux" + | "InverseTest" -> "inverse_test" + | "ApplySimplif" -> "apply_simplif" + | "Unfolds" -> "unfolds" + | "Reduce" -> "reduce" + | "Field_Gen_Aux" -> "field_gen_aux" + | "Field_Gen" -> "field_gen" + | "EvalWeakReduce" -> "eval_weak_reduce" + | "Field_Term" -> "field_term" + | "Fourier" -> "fourier" (* ou Fourier ?? *) + | "FourierEq" -> "fourier_eq" + | "S_to_plus" -> "rewrite_S_to_plus_term" + | "S_to_plus_eq" -> "rewrite_S_to_plus" + | "NatRing" -> "ring_nat" + | "Solve1" -> "solve1" + | "Solve2" -> "solve2" + | "Elim_eq_term" -> "elim_eq_term" + | "Elim_eq_Z" -> "elim_eq_Z" + | "Elim_eq_pos" -> "elim_eq_pos" + | "Elim_Zcompare" -> "elim_Zcompare" + | "ProveStable" -> "prove_stable" + | "interp_A" -> "interp_A" + | "InitExp" -> "init_exp" + | "SimplInv" -> "simpl_inv" + | "Map" -> "map_tactic" + | "BuildMonomAux" -> "build_monom_aux" + | "BuildMonom" -> "build_monom" + | "SimplMonomAux" -> "simpl_monom_aux" + | "SimplMonom" -> "simpl_monom" + | "SimplAllMonoms" -> "simpl_all_monomials" + | "AssocDistrib" -> "assoc_distrib" + | "NowShow" -> "now_show" + | ("subst"|"simpl"|"elim"|"destruct"|"apply"|"intro" (* ... *)) as x -> + let x' = x^"_" in + msgerrnl + (str ("Warning: '"^ + x^"' is now a primitive tactic; it has been translated to '"^x'^"'")); + x' + | x -> x + +let id_of_ltac_v7_id id = + id_of_string (translate_v7_ltac (string_of_id id)) + +let pr_ltac_or_var pr = function + | ArgArg x -> pr x + | ArgVar (loc,id) -> + pr_with_comments loc (pr_id (id_of_ltac_v7_id id)) + +let pr_arg pr x = spc () ++ pr x + +let pr_ltac_constant sp = + (* Source de bug: le nom le plus court n'est pas forcement correct + apres renommage *) + let qid = Nametab.shortest_qualid_of_tactic sp in + let dir,id = repr_qualid qid in + pr_qualid (make_qualid dir (id_of_ltac_v7_id id)) + +let pr_evaluable_reference_env env = function + | EvalVarRef id -> pr_id (Constrextern.v7_to_v8_id id) + | EvalConstRef sp -> pr_global (Termops.vars_of_env env) (Libnames.ConstRef sp) + +let pr_inductive vars ind = pr_global vars (Libnames.IndRef ind) + +let pr_quantified_hypothesis = function + | AnonHyp n -> int n + | NamedHyp id -> pr_id id + +let pr_quantified_hypothesis_arg h = spc () ++ pr_quantified_hypothesis h + +(* +let pr_binding prc = function + | NamedHyp id, c -> hov 1 (pr_id id ++ str " := " ++ cut () ++ prc c) + | AnonHyp n, c -> hov 1 (int n ++ str " := " ++ cut () ++ prc c) +*) + +let pr_esubst prc l = + let pr_qhyp = function + (_,AnonHyp n,c) -> str "(" ++ int n ++ str" := " ++ prc c ++ str ")" + | (_,NamedHyp id,c) -> + str "(" ++ pr_id id ++ str" := " ++ prc c ++ str ")" + in + prlist_with_sep spc pr_qhyp l + +let pr_bindings_gen for_ex prlc prc = function + | ImplicitBindings l -> + spc () ++ + hv 2 ((if for_ex then mt() else str "with" ++ spc ()) ++ + prlist_with_sep spc prc l) + | ExplicitBindings l -> + spc () ++ + hv 2 ((if for_ex then mt() else str "with" ++ spc ()) ++ + pr_esubst prlc l) + | NoBindings -> mt () + +let pr_bindings prlc prc = pr_bindings_gen false prlc prc + +let pr_with_bindings prlc prc (c,bl) = + if Options.do_translate () then + (* translator calls pr_with_bindings on rawconstr: we cast it! *) + let bl' = translate_with_bindings (fst (Obj.magic c) : rawconstr) bl in + hov 1 (prc c ++ pr_bindings prlc prc bl') + else + hov 1 (prc c ++ pr_bindings prlc prc bl) + +let pr_with_constr prc = function + | None -> mt () + | Some c -> spc () ++ hov 1 (str "with" ++ spc () ++ prc c) + +(* Translator copy of pr_intro_pattern based on a translating "pr_id" *) +let rec pr_intro_pattern = function + | IntroOrAndPattern pll -> pr_case_intro_pattern pll + | IntroWildcard -> str "_" + | IntroIdentifier id -> pr_id id +and pr_case_intro_pattern = function + | [_::_ as pl] -> + str "(" ++ hov 0 (prlist_with_sep pr_coma pr_intro_pattern pl) ++ str ")" + | pll -> + str "[" ++ + hv 0 (prlist_with_sep pr_bar + (fun l -> hov 0 (prlist_with_sep spc pr_intro_pattern l)) pll) + ++ str "]" + +let pr_with_names = function + | None -> mt () + | Some ipat -> spc () ++ hov 1 (str "as" ++ spc () ++ pr_intro_pattern ipat) + +let pr_occs pp = function + [] -> pp + | nl -> hov 1 (pp ++ spc() ++ str"at " ++ + hov 0 (prlist_with_sep spc int nl)) + +let pr_hyp_location pr_id = function + | id, occs, InHyp -> spc () ++ pr_occs (pr_id id) occs + | id, occs, InHypTypeOnly -> + spc () ++ pr_occs (str "(type of " ++ pr_id id ++ str ")") occs + | id, occs, InHypValueOnly -> + spc () ++ pr_occs (str "(value of " ++ pr_id id ++ str ")") occs + +let pr_hyp_location pr_id (id,occs,(hl,hl')) = + if !hl' <> None then pr_hyp_location pr_id (id,occs,out_some !hl') + else + (if hl = InHyp && Options.do_translate () then + msgerrnl (h 0 (str "Translator warning: Unable to detect if " ++ pr_id id ++ spc () ++ str "denotes a local definition")); + pr_hyp_location pr_id (id,occs,hl)) + +let pr_in pp = spc () ++ hov 0 (str "in" ++ pp) + +let pr_simple_clause pr_id = function + | [] -> mt () + | l -> pr_in (spc () ++ prlist_with_sep spc pr_id l) + +let pr_clauses pr_id = function + { onhyps=None; onconcl=true; concl_occs=nl } -> + pr_in (pr_occs (str " *") nl) + | { onhyps=None; onconcl=false } -> pr_in (str " * |-") + | { onhyps=Some l; onconcl=true; concl_occs=nl } -> + pr_in (prlist_with_sep (fun () -> str",") (pr_hyp_location pr_id) l + ++ pr_occs (str" |- *") nl) + | { onhyps=Some l; onconcl=false } -> + pr_in (prlist_with_sep (fun()->str",") (pr_hyp_location pr_id) l) + +let pr_clause_pattern pr_id = function + | (None, []) -> mt () + | (glopt,l) -> + str " in" ++ + prlist + (fun (id,nl) -> prlist (pr_arg int) nl + ++ spc () ++ pr_id id) l ++ + pr_opt (fun nl -> prlist_with_sep spc int nl ++ str " Goal") glopt + +let pr_induction_arg prc = function + | ElimOnConstr c -> prc c + | ElimOnIdent (loc,id) -> pr_with_comments loc (pr_id id) + | ElimOnAnonHyp n -> int n + +let pr_induction_kind = function + | SimpleInversion -> str "simple inversion" + | FullInversion -> str "inversion" + | FullInversionClear -> str "inversion_clear" + +let pr_match_pattern pr_pat = function + | Term a -> pr_pat a + | Subterm (None,a) -> str "context [" ++ pr_pat a ++ str "]" + | Subterm (Some id,a) -> + str "context " ++ pr_id id ++ str "[" ++ pr_pat a ++ str "]" + +let pr_match_hyps pr_pat = function + | Hyp (nal,mp) -> pr_lname nal ++ str ":" ++ pr_match_pattern pr_pat mp + +let pr_match_rule m pr pr_pat = function + | Pat ([],mp,t) when m -> + pr_match_pattern pr_pat mp ++ + spc () ++ str "=>" ++ brk (1,4) ++ pr t + | Pat (rl,mp,t) -> + prlist_with_sep (fun () -> str",") (pr_match_hyps pr_pat) rl ++ + spc () ++ str "|-" ++ spc () ++ pr_match_pattern pr_pat mp ++ spc () ++ + str "=>" ++ brk (1,4) ++ pr t + | All t -> str "_" ++ spc () ++ str "=>" ++ brk (1,4) ++ pr t + +let pr_funvar = function + | None -> spc () ++ str "_" + | Some id -> spc () ++ pr_id id + +let pr_let_clause k pr = function + | (id,None,t) -> + hov 0 (str k ++ pr_lident id ++ str " :=" ++ brk (1,1) ++ + pr (TacArg t)) + | (id,Some c,t) -> + hv 0 (str k ++ pr_lident id ++ str" :" ++ brk(1,2) ++ + pr c ++ + str " :=" ++ brk (1,1) ++ pr (TacArg t)) + +let pr_let_clauses pr = function + | hd::tl -> + hv 0 + (pr_let_clause "let " pr hd ++ + prlist (fun t -> spc () ++ pr_let_clause "with " pr t) tl) + | [] -> anomaly "LetIn must declare at least one binding" + +let pr_rec_clause pr (id,(l,t)) = + hov 0 + (pr_lident id ++ prlist pr_funvar l ++ str " :=") ++ spc () ++ pr t + +let pr_rec_clauses pr l = + prlist_with_sep (fun () -> fnl () ++ str "with ") (pr_rec_clause pr) l + +let pr_seq_body pr tl = + hv 0 (str "[ " ++ + prlist_with_sep (fun () -> spc () ++ str "| ") pr tl ++ + str " ]") + +let pr_as_names_force force ids (pp,ids') = + pr_with_names + (if (!pp or force) & List.exists ((<>) (ref [])) ids' + then Some (IntroOrAndPattern (List.map (fun x -> !x) ids')) + else ids) + +let duplicate force nodup ids pr = function + | [] -> pr (pr_as_names_force force ids (ref false,[])) + | x::l when List.for_all (fun y -> snd x=snd y) l -> + pr (pr_as_names_force force ids x) + | l -> + if List.exists (fun (b,ids) -> !b) l & (force or + List.exists (fun (_,ids) -> ids <> (snd (List.hd l))) (List.tl l)) + then + if nodup then begin + msgerrnl + (h 0 (str "Translator warning: Unable to enforce v7 names while translating Induction/NewDestruct/NewInduction. Names in the different branches are") ++ brk (0,0) ++ + hov 0 (prlist_with_sep spc + (fun id -> hov 0 (pr_as_names_force true ids id)) + (List.rev l))); + pr (pr_as_names_force force ids (ref false,[])) + end + else + pr_seq_body (fun x -> pr (pr_as_names_force force ids x)) (List.rev l) + else pr (pr_as_names_force force ids (ref false,[])) + +let pr_hintbases = function + | None -> spc () ++ str "with *" + | Some [] -> mt () + | Some l -> + spc () ++ hov 2 (str "with" ++ prlist (fun s -> spc () ++ str s) l) + +let pr_autoarg_adding = function + | [] -> mt () + | l -> + spc () ++ str "adding [" ++ + hv 0 (prlist_with_sep spc pr_reference l) ++ str "]" + +let pr_autoarg_destructing = function + | true -> spc () ++ str "destructing" + | false -> mt () + +let pr_autoarg_usingTDB = function + | true -> spc () ++ str "using tdb" + | false -> mt () + +let rec pr_tacarg_using_rule pr_gen = function + | Egrammar.TacTerm s :: l, al -> spc () ++ str s ++ pr_tacarg_using_rule pr_gen (l,al) + | Egrammar.TacNonTerm _ :: l, a :: al -> pr_gen a ++ pr_tacarg_using_rule pr_gen (l,al) + | [], [] -> mt () + | _ -> failwith "Inconsistent arguments of extended tactic" + +let pr_then () = str ";" + + +open Closure + +let make_pr_tac (pr_tac,pr_tac0,pr_constr,pr_lconstr,pr_pat,pr_cst,pr_ind,pr_ref,pr_ident,pr_extend,strip_prod_binders) = + +let pr_bindings env = pr_bindings (pr_lconstr env) (pr_constr env) in +let pr_ex_bindings env = pr_bindings_gen true (pr_lconstr env) (pr_constr env) in +let pr_with_bindings env = pr_with_bindings (pr_lconstr env) (pr_constr env) in +let pr_eliminator env cb = str "using" ++ pr_arg (pr_with_bindings env) cb in +let pr_constrarg env c = spc () ++ pr_constr env c in +let pr_lconstrarg env c = spc () ++ pr_lconstr env c in + +let pr_intarg n = spc () ++ int n in + +let pr_binder_fix env (nal,t) = +(* match t with + | CHole _ -> spc() ++ prlist_with_sep spc (pr_lname) nal + | _ ->*) + let s = + prlist_with_sep spc (pr_lname) nal ++ str ":" ++ + pr_lconstr env t in + spc() ++ hov 1 (str"(" ++ s ++ str")") in + +let pr_fix_tac env (id,n,c) = + let rec set_nth_name avoid n = function + (nal,ty)::bll -> + if n <= List.length nal then + match list_chop (n-1) nal with + _, (_,Name id) :: _ -> id, (nal,ty)::bll + | bef, (loc,Anonymous) :: aft -> + let id = next_ident_away_from (id_of_string"y") avoid in + id, ((bef@(loc,Name id)::aft, ty)::bll) + | _ -> assert false + else + let (id,bll') = set_nth_name avoid (n-List.length nal) bll in + (id,(nal,ty)::bll') + | [] -> assert false in + let (bll,ty) = strip_prod_binders n c in + let names = + List.fold_left + (fun ln (nal,_) -> List.fold_left + (fun ln na -> match na with (_,Name id) -> id::ln | _ -> ln) + ln nal) + [] bll in + let idarg,bll = set_nth_name names n bll in + let annot = + if List.length names = 1 then mt() + else spc() ++ str"{struct " ++ pr_id idarg ++ str"}" in + hov 1 (str"(" ++ pr_id id ++ + prlist (pr_binder_fix env) bll ++ annot ++ str" :" ++ + pr_lconstrarg env ty ++ str")") in +(* spc() ++ + hov 0 (pr_id id ++ pr_intarg n ++ str":" ++ pr_constrarg + env c) +*) +let pr_cofix_tac env (id,c) = + hov 1 (str"(" ++ pr_id id ++ str" :" ++ pr_lconstrarg env c ++ str")") in + + + (* Printing tactics as arguments *) +let rec pr_atom0 env = function + | TacIntroPattern [] -> str "intros" + | TacIntroMove (None,None) -> str "intro" + | TacAssumption -> str "assumption" + | TacAnyConstructor None -> str "constructor" + | TacTrivial (Some []) -> str "trivial" + | TacAuto (None,Some []) -> str "auto" +(* | TacAutoTDB None -> str "autotdb" + | TacDestructConcl -> str "dconcl"*) + | TacReflexivity -> str "reflexivity" + | t -> str "(" ++ pr_atom1 env t ++ str ")" + + (* Main tactic printer *) +and pr_atom1 env = function + | TacAutoTDB _ | TacDestructHyp _ | TacDestructConcl + | TacSuperAuto _ | TacExtend (_, + ("GTauto"|"GIntuition"|"TSimplif"| + "LinearIntuition"),_) -> + errorlabstrm "Obsolete V8" (str "Tactic is not ported to V8.0") + | TacExtend (loc,s,l) -> + pr_with_comments loc + (pr_extend (pr_constr env) (pr_lconstr env) (pr_tac env) s l) + | TacAlias (loc,s,l,_) -> + pr_with_comments loc + (pr_extend (pr_constr env) (pr_lconstr env) (pr_tac env) s + (List.map snd l)) + + (* Basic tactics *) + | TacIntroPattern [] as t -> pr_atom0 env t + | TacIntroPattern (_::_ as p) -> + hov 1 (str "intros" ++ spc () ++ prlist_with_sep spc pr_intro_pattern p) + | TacIntrosUntil h -> + hv 1 (str "intros until" ++ pr_arg pr_quantified_hypothesis h) + | TacIntroMove (None,None) as t -> pr_atom0 env t + | TacIntroMove (Some id1,None) -> str "intro " ++ pr_id id1 + | TacIntroMove (ido1,Some id2) -> + hov 1 + (str "intro" ++ pr_opt pr_id ido1 ++ spc () ++ str "after " ++ + pr_lident id2) + | TacAssumption as t -> pr_atom0 env t + | TacExact c -> hov 1 (str "exact" ++ pr_constrarg env c) + | TacApply cb -> hov 1 (str "apply" ++ spc () ++ pr_with_bindings env cb) + | TacElim (cb,cbo) -> + hov 1 (str "elim" ++ pr_arg (pr_with_bindings env) cb ++ + pr_opt (pr_eliminator env) cbo) + | TacElimType c -> hov 1 (str "elimtype" ++ pr_constrarg env c) + | TacCase cb -> hov 1 (str "case" ++ spc () ++ pr_with_bindings env cb) + | TacCaseType c -> hov 1 (str "casetype" ++ pr_constrarg env c) + | TacFix (ido,n) -> hov 1 (str "fix" ++ pr_opt pr_id ido ++ pr_intarg n) + | TacMutualFix (id,n,l) -> + hov 1 (str "fix" ++ spc () ++ pr_id id ++ pr_intarg n ++ spc() ++ + str"with " ++ prlist_with_sep spc (pr_fix_tac env) l) + | TacCofix ido -> hov 1 (str "cofix" ++ pr_opt pr_id ido) + | TacMutualCofix (id,l) -> + hov 1 (str "cofix" ++ spc () ++ pr_id id ++ spc() ++ + str"with " ++ prlist_with_sep spc (pr_cofix_tac env) l) + | TacCut c -> hov 1 (str "cut" ++ pr_constrarg env c) + | TacTrueCut (Anonymous,c) -> + hov 1 (str "assert" ++ pr_constrarg env c) + | TacTrueCut (Name id,c) -> + hov 1 (str "assert" ++ spc () ++ + hov 1 (str"(" ++ pr_id id ++ str " :" ++ + pr_lconstrarg env c ++ str")")) + | TacForward (false,na,c) -> + hov 1 (str "assert" ++ spc () ++ + hov 1 (str"(" ++ pr_name na ++ str " :=" ++ + pr_lconstrarg env c ++ str")")) + | TacForward (true,Anonymous,c) -> + if Options.do_translate () then + (* Pose was buggy and was wrongly substituted in conclusion in v7 *) + hov 1 (str "set" ++ pr_constrarg env c) + else + hov 1 (str "pose" ++ pr_constrarg env c) + | TacForward (true,Name id,c) -> + if Options.do_translate () then + hov 1 (str "set" ++ spc() ++ + hov 1 (str"(" ++ pr_id id ++ str " :=" ++ + pr_lconstrarg env c ++ str")")) + else + hov 1 (str "pose" ++ spc() ++ + hov 1 (str"(" ++ pr_id id ++ str " :=" ++ + pr_lconstrarg env c ++ str")")) + | TacGeneralize l -> + hov 1 (str "generalize" ++ spc () ++ + prlist_with_sep spc (pr_constr env) l) + | TacGeneralizeDep c -> + hov 1 (str "generalize" ++ spc () ++ str "dependent" ++ + pr_constrarg env c) + | TacLetTac (Anonymous,c,cl) -> + hov 1 (str "set" ++ pr_constrarg env c) ++ pr_clauses pr_ident cl + | TacLetTac (Name id,c,cl) -> + hov 1 (str "set" ++ spc () ++ + hov 1 (str"(" ++ pr_id id ++ str " :=" ++ + pr_lconstrarg env c ++ str")") ++ + pr_clauses pr_ident cl) + | TacInstantiate (n,c,cls) -> + hov 1 (str "instantiate" ++ spc() ++ + hov 1 (str"(" ++ pr_arg int n ++ str" :=" ++ + pr_lconstrarg env c ++ str ")" ++ + pr_clauses pr_ident cls)) + (* Derived basic tactics *) + | TacSimpleInduction (h,l) -> + if List.exists (fun (pp,_) -> !pp) !l then + duplicate true true None (fun pnames -> + hov 1 (str "induction" ++ pr_arg pr_quantified_hypothesis h ++ + pnames)) !l + else + hov 1 (str "simple induction" ++ pr_arg pr_quantified_hypothesis h) + | TacNewInduction (h,e,(ids,l)) -> + duplicate false true ids (fun pnames -> + hov 1 (str "induction" ++ spc () ++ + pr_induction_arg (pr_constr env) h ++ pnames ++ + pr_opt (pr_eliminator env) e)) !l + | TacSimpleDestruct h -> + hov 1 (str "simple destruct" ++ pr_arg pr_quantified_hypothesis h) + | TacNewDestruct (h,e,(ids,l)) -> + duplicate false true ids (fun pnames -> + hov 1 (str "destruct" ++ spc () ++ + pr_induction_arg (pr_constr env) h ++ pnames ++ + pr_opt (pr_eliminator env) e)) !l + | TacDoubleInduction (h1,h2) -> + hov 1 + (str "double induction" ++ + pr_arg pr_quantified_hypothesis h1 ++ + pr_arg pr_quantified_hypothesis h2) + | TacDecomposeAnd c -> + hov 1 (str "decompose record" ++ pr_constrarg env c) + | TacDecomposeOr c -> + hov 1 (str "decompose sum" ++ pr_constrarg env c) + | TacDecompose (l,c) -> + let vars = Termops.vars_of_env env in + hov 1 (str "decompose" ++ spc () ++ + hov 0 (str "[" ++ prlist_with_sep spc (pr_ind vars) l + ++ str "]" ++ pr_constrarg env c)) + | TacSpecialize (n,c) -> + hov 1 (str "specialize" ++ spc () ++ pr_opt int n ++ pr_with_bindings env c) + | TacLApply c -> + hov 1 (str "lapply" ++ pr_constrarg env c) + + (* Automation tactics *) + | TacTrivial (Some []) as x -> pr_atom0 env x + | TacTrivial db -> hov 0 (str "trivial" ++ pr_hintbases db) + | TacAuto (None,Some []) as x -> pr_atom0 env x + | TacAuto (n,db) -> hov 0 (str "auto" ++ pr_opt int n ++ pr_hintbases db) +(* | TacAutoTDB None as x -> pr_atom0 env x + | TacAutoTDB (Some n) -> hov 0 (str "autotdb" ++ spc () ++ int n) + | TacDestructHyp (true,id) -> + hov 0 (str "cdhyp" ++ spc () ++ pr_lident id) + | TacDestructHyp (false,id) -> + hov 0 (str "dhyp" ++ spc () ++ pr_lident id) + | TacDestructConcl as x -> pr_atom0 env x + | TacSuperAuto (n,l,b1,b2) -> + hov 1 (str "superauto" ++ pr_opt int n ++ pr_autoarg_adding l ++ + pr_autoarg_destructing b1 ++ pr_autoarg_usingTDB b2)*) + | TacDAuto (n,p) -> + hov 1 (str "auto" ++ pr_opt int n ++ str "decomp" ++ pr_opt int p) + + (* Context management *) + | TacClear l -> + hov 1 (str "clear" ++ spc () ++ prlist_with_sep spc pr_ident l) + | TacClearBody l -> + hov 1 (str "clearbody" ++ spc () ++ prlist_with_sep spc pr_ident l) + | TacMove (b,id1,id2) -> + (* Rem: only b = true is available for users *) + assert b; + hov 1 + (str "move" ++ brk (1,1) ++ pr_ident id1 ++ spc () ++ + str "after" ++ brk (1,1) ++ pr_ident id2) + | TacRename (id1,id2) -> + hov 1 + (str "rename" ++ brk (1,1) ++ pr_ident id1 ++ spc () ++ + str "into" ++ brk (1,1) ++ pr_ident id2) + + (* Constructors *) + | TacLeft l -> hov 1 (str "left" ++ pr_bindings env l) + | TacRight l -> hov 1 (str "right" ++ pr_bindings env l) + | TacSplit (false,l) -> hov 1 (str "split" ++ pr_bindings env l) + | TacSplit (true,l) -> hov 1 (str "exists" ++ pr_ex_bindings env l) + | TacAnyConstructor (Some t) -> + hov 1 (str "constructor" ++ pr_arg (pr_tac0 env) t) + | TacAnyConstructor None as t -> pr_atom0 env t + | TacConstructor (n,l) -> + hov 1 (str "constructor" ++ pr_or_metaid pr_intarg n ++ + pr_bindings env l) + + (* Conversion *) + | TacReduce (r,h) -> + hov 1 (pr_red_expr (pr_constr env,pr_lconstr env,pr_cst env) r ++ + pr_clauses pr_ident h) + | TacChange (occ,c,h) -> + hov 1 (str "change" ++ brk (1,1) ++ + (match occ with + None -> mt() + | Some([],c1) -> + hov 1 (pr_constr env c1 ++ spc() ++ str "with ") + | Some(ocl,c1) -> + hov 1 (pr_constr env c1 ++ spc() ++ + str "at " ++ prlist_with_sep spc int ocl) ++ spc() ++ + str "with ") ++ + pr_constr env c ++ pr_clauses pr_ident h) + + (* Equivalence relations *) + | TacReflexivity as x -> pr_atom0 env x + | TacSymmetry cls -> str "symmetry " ++ pr_clauses pr_ident cls + | TacTransitivity c -> str "transitivity" ++ pr_constrarg env c + + (* Equality and inversion *) + | TacInversion (DepInversion (k,c,ids),hyp) -> + hov 1 (str "dependent " ++ pr_induction_kind k ++ spc () ++ + pr_quantified_hypothesis hyp ++ + pr_with_names ids ++ pr_with_constr (pr_constr env) c) + | TacInversion (NonDepInversion (k,cl,ids),hyp) -> + hov 1 (pr_induction_kind k ++ spc () ++ + pr_quantified_hypothesis hyp ++ + pr_with_names ids ++ pr_simple_clause pr_ident cl) + | TacInversion (InversionUsing (c,cl),hyp) -> + hov 1 (str "inversion" ++ spc() ++ pr_quantified_hypothesis hyp ++ + spc () ++ str "using" ++ spc () ++ pr_constr env c ++ + pr_simple_clause pr_ident cl) + +in + +let ltop = (5,E) in +let lseq = 5 in +let ltactical = 3 in +let lorelse = 2 in +let llet = 1 in +let lfun = 1 in +let labstract = 3 in +let lmatch = 1 in +let latom = 0 in +let lcall = 1 in +let leval = 1 in +let ltatom = 1 in + +let rec pr_tac env inherited tac = + let (strm,prec) = match tac with + | TacAbstract (t,None) -> + str "abstract " ++ pr_tac env (labstract,L) t, labstract + | TacAbstract (t,Some s) -> + hov 0 + (str "abstract (" ++ pr_tac env (labstract,L) t ++ str")" ++ spc () ++ + str "using " ++ pr_id s), + labstract + | TacLetRecIn (l,t) -> + hv 0 + (str "let rec " ++ pr_rec_clauses (pr_tac env ltop) l ++ str " in" ++ + fnl () ++ pr_tac env (llet,E) t), + llet + | TacLetIn (llc,u) -> + v 0 + (hv 0 (pr_let_clauses (pr_tac env ltop) llc + ++ str " in") ++ + fnl () ++ pr_tac env (llet,E) u), + llet + | TacMatch (t,lrul) -> + hov 0 (str "match " ++ pr_tac env ltop t ++ str " with" + ++ prlist + (fun r -> fnl () ++ str "| " ++ + pr_match_rule true (pr_tac env ltop) pr_pat r) + lrul + ++ fnl() ++ str "end"), + lmatch + | TacMatchContext (lr,lrul) -> + hov 0 ( + str (if lr then "match reverse goal with" else "match goal with") + ++ prlist + (fun r -> fnl () ++ str "| " ++ + pr_match_rule false (pr_tac env ltop) pr_pat r) + lrul + ++ fnl() ++ str "end"), + lmatch + | TacFun (lvar,body) -> + hov 2 (str "fun" ++ + prlist pr_funvar lvar ++ str " =>" ++ spc () ++ + pr_tac env (lfun,E) body), + lfun + | TacThens (t,tl) -> + hov 1 (pr_tac env (lseq,E) t ++ pr_then () ++ spc () ++ + pr_seq_body (pr_tac env ltop) tl), + lseq + | TacThen (t1,t2) -> + let pp2 = + (* Hook for translation names in induction/destruct *) + match t2 with + | TacAtom (_,TacSimpleInduction (h,l)) -> + if List.exists (fun (pp,ids) -> !pp) !l then + duplicate true false None (fun pnames -> + hov 1 + (str "induction" ++ pr_arg pr_quantified_hypothesis h ++ + pnames)) !l + else + hov 1 + (str "simple induction" ++ pr_arg pr_quantified_hypothesis h) + | TacAtom (_,TacNewInduction (h,e,(ids,l))) -> + duplicate false false ids (fun pnames -> + hov 1 (str "induction" ++ spc () ++ + pr_induction_arg (pr_constr env) h ++ pnames ++ + pr_opt (pr_eliminator env) e)) !l + | TacAtom (_,TacNewDestruct (h,e,(ids,l))) -> + duplicate false false ids (fun pnames -> + hov 1 (str "destruct" ++ spc () ++ + pr_induction_arg (pr_constr env) h ++ pnames ++ + pr_opt (pr_eliminator env) e)) !l + (* end hook *) + | _ -> pr_tac env (lseq,L) t2 in + hov 1 (pr_tac env (lseq,E) t1 ++ pr_then () ++ spc () ++ pp2), + lseq + | TacTry t -> + hov 1 (str "try" ++ spc () ++ pr_tac env (ltactical,E) t), + ltactical + | TacDo (n,t) -> + hov 1 (str "do " ++ pr_or_var int n ++ spc () ++ pr_tac env (ltactical,E) t), + ltactical + | TacRepeat t -> + hov 1 (str "repeat" ++ spc () ++ pr_tac env (ltactical,E) t), + ltactical + | TacProgress t -> + hov 1 (str "progress" ++ spc () ++ pr_tac env (ltactical,E) t), + ltactical + | TacInfo t -> + hov 1 (str "info" ++ spc () ++ pr_tac env (ltactical,E) t), + ltactical + | TacOrelse (t1,t2) -> + hov 1 (pr_tac env (lorelse,L) t1 ++ str " ||" ++ brk (1,1) ++ + pr_tac env (lorelse,E) t2), + lorelse + | TacFail (ArgArg 0,"") -> str "fail", latom + | TacFail (n,s) -> + str "fail" ++ (if n=ArgArg 0 then mt () else pr_arg (pr_or_var int) n) ++ + (if s="" then mt() else qsnew s), latom + | TacFirst tl -> + str "first" ++ spc () ++ pr_seq_body (pr_tac env ltop) tl, llet + | TacSolve tl -> + str "solve" ++ spc () ++ pr_seq_body (pr_tac env ltop) tl, llet + | TacId "" -> str "idtac", latom + | TacId s -> str "idtac" ++ (qsnew s), latom + | TacAtom (loc,t) -> + pr_with_comments loc (hov 1 (pr_atom1 env t)), ltatom + | TacArg(Tacexp e) -> pr_tac0 env e, latom + | TacArg(ConstrMayEval (ConstrTerm c)) -> + str "constr:" ++ pr_constr env c, latom + | TacArg(ConstrMayEval c) -> + pr_may_eval (pr_constr env) (pr_lconstr env) (pr_cst env) c, leval + | TacArg(TacFreshId sopt) -> str "fresh" ++ pr_opt qsnew sopt, latom + | TacArg(Integer n) -> int n, latom + | TacArg(TacCall(loc,f,l)) -> + pr_with_comments loc + (hov 1 (pr_ref f ++ spc () ++ + prlist_with_sep spc (pr_tacarg env) l)), + lcall + | TacArg a -> pr_tacarg env a, latom + in + if prec_less prec inherited then strm + else str"(" ++ strm ++ str")" + +and pr_tacarg env = function + | TacDynamic (loc,t) -> + pr_with_comments loc (str ("<dynamic ["^(Dyn.tag t)^"]>")) + | MetaIdArg (loc,s) -> pr_with_comments loc (str ("$" ^ s)) + | IntroPattern ipat -> str "ipattern:" ++ pr_intro_pattern ipat + | TacVoid -> str "()" + | Reference r -> pr_ref r + | ConstrMayEval c -> + pr_may_eval (pr_constr env) (pr_lconstr env) (pr_cst env) c + | TacFreshId sopt -> str "fresh" ++ pr_opt qsnew sopt + | (TacCall _|Tacexp _|Integer _) as a -> + str "ltac:" ++ pr_tac env (latom,E) (TacArg a) + +in ((fun env -> pr_tac env ltop), + (fun env -> pr_tac env (latom,E)), + pr_match_rule) + +let pi1 (a,_,_) = a +let pi2 (_,a,_) = a +let pi3 (_,_,a) = a + +let strip_prod_binders_rawterm n (ty,_) = + let rec strip_ty acc n ty = + if n=0 then (List.rev acc, (ty,None)) else + match ty with + Rawterm.RProd(loc,na,a,b) -> + strip_ty (([dummy_loc,na],(a,None))::acc) (n-1) b + | _ -> error "Cannot translate fix tactic: not enough products" in + strip_ty [] n ty + +let strip_prod_binders_constr n ty = + let rec strip_ty acc n ty = + if n=0 then (List.rev acc, ty) else + match Term.kind_of_term ty with + Term.Prod(na,a,b) -> + strip_ty (([dummy_loc,na],a)::acc) (n-1) b + | _ -> error "Cannot translate fix tactic: not enough products" in + strip_ty [] n ty + + +let rec raw_printers = + (pr_raw_tactic, + pr_raw_tactic0, + Ppconstrnew.pr_constr_env, + Ppconstrnew.pr_lconstr_env, + Ppconstrnew.pr_pattern, + (fun _ -> pr_reference), + (fun _ -> pr_reference), + pr_reference, + pr_or_metaid pr_lident, + Pptactic.pr_raw_extend, + strip_prod_binders_expr) + +and pr_raw_tactic env (t:raw_tactic_expr) = + pi1 (make_pr_tac raw_printers) env t + +and pr_raw_tactic0 env t = + pi2 (make_pr_tac raw_printers) env t + +and pr_raw_match_rule env t = + pi3 (make_pr_tac raw_printers) env t + +let pr_and_constr_expr pr (c,_) = pr c + + +let rec glob_printers = + (pr_glob_tactic, + pr_glob_tactic0, + (fun env -> pr_and_constr_expr (Ppconstrnew.pr_rawconstr_env_no_translate env)), + (fun env -> pr_and_constr_expr (Ppconstrnew.pr_lrawconstr_env_no_translate env)), + (fun c -> Ppconstrnew.pr_constr_pattern_env (Global.env()) c), + (fun env -> pr_or_var (pr_and_short_name (pr_evaluable_reference_env env))), + (fun vars -> pr_or_var (pr_inductive vars)), + pr_ltac_or_var (pr_located pr_ltac_constant), + pr_lident, + Pptactic.pr_glob_extend, + strip_prod_binders_rawterm) + +and pr_glob_tactic env (t:glob_tactic_expr) = + pi1 (make_pr_tac glob_printers) env t + +and pr_glob_tactic0 env t = + pi2 (make_pr_tac glob_printers) env t + +and pr_glob_match_rule env t = + pi3 (make_pr_tac glob_printers) env t + +let (pr_tactic,_,_) = + make_pr_tac + (pr_glob_tactic, + pr_glob_tactic0, + pr_term_env, + pr_lterm_env, + Ppconstrnew.pr_constr_pattern, + pr_evaluable_reference_env, + pr_inductive, + pr_ltac_constant, + pr_id, + Pptactic.pr_extend, + strip_prod_binders_constr) + diff --git a/translate/pptacticnew.mli b/translate/pptacticnew.mli new file mode 100644 index 00000000..2558413f --- /dev/null +++ b/translate/pptacticnew.mli @@ -0,0 +1,28 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: pptacticnew.mli,v 1.6.2.1 2004/07/16 19:31:52 herbelin Exp $ *) + +open Pp +open Genarg +open Tacexpr +open Proof_type +open Topconstr +open Names + +val qsnew : string -> std_ppcmds + +val pr_raw_tactic : Environ.env -> raw_tactic_expr -> std_ppcmds + +val pr_glob_tactic : Environ.env -> glob_tactic_expr -> std_ppcmds + +val pr_tactic : Environ.env -> Proof_type.tactic_expr -> std_ppcmds + +val id_of_ltac_v7_id : identifier -> identifier + + diff --git a/translate/ppvernacnew.ml b/translate/ppvernacnew.ml new file mode 100644 index 00000000..246253eb --- /dev/null +++ b/translate/ppvernacnew.ml @@ -0,0 +1,1123 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: ppvernacnew.ml,v 1.95.2.2 2004/07/16 20:48:17 herbelin Exp $ *) + +open Pp +open Names +open Nameops +open Nametab +open Util +open Extend +open Vernacexpr +open Ppconstrnew +open Pptacticnew +open Rawterm +open Coqast +open Genarg +open Pcoq +open Ast +open Libnames +open Ppextend +open Topconstr +open Decl_kinds +open Tacinterp + +let pr_spc_type = pr_sep_com spc pr_type + +let pr_lident (b,_ as loc,id) = + if loc <> dummy_loc then + let (b,_) = unloc loc in + pr_located pr_id (make_loc (b,b+String.length(string_of_id id)),id) + else pr_id id + +let pr_lname = function + (loc,Name id) -> pr_lident (loc,id) + | lna -> pr_located pr_name lna + +let pr_ltac_id id = Nameops.pr_id (id_of_ltac_v7_id id) + +let pr_module r = + let update_ref s = match r with + | Ident (loc,_) -> + Ident (loc,id_of_string s) + | Qualid (loc,qid) -> + Qualid (loc,make_qualid (fst (repr_qualid qid)) (id_of_string s)) in + let (_,dir,_) = + try + Library.locate_qualified_library (snd (qualid_of_reference r)) + with _ -> + errorlabstrm "" (str"Translator cannot find " ++ Libnames.pr_reference r) + in + let r = match List.rev (List.map string_of_id (repr_dirpath dir)) with + | [ "Coq"; "Lists"; "List" ] -> update_ref "MonoList" + | [ "Coq"; "Lists"; "PolyList" ] -> update_ref "List" + | _ -> r in + Libnames.pr_reference r + +let pr_import_module = + (* We assume List is never imported with "Import" ... *) + Libnames.pr_reference + +let pr_reference = Ppconstrnew.pr_reference + +let sep_end () = str"." + +(* Warning: [pr_raw_tactic] globalises and fails if globalisation fails *) +(* +let pr_raw_tactic_env l env t = + Pptacticnew.pr_raw_tactic env t +*) +let pr_raw_tactic_env l env t = + Pptacticnew.pr_glob_tactic env (Tacinterp.glob_tactic_env l env t) + +let pr_gen env t = + Pptactic.pr_raw_generic (Ppconstrnew.pr_constr_env env) + (Ppconstrnew.pr_lconstr_env env) + (Pptacticnew.pr_raw_tactic env) pr_reference t + +let pr_raw_tactic tac = + pr_raw_tactic_env [] (Global.env()) tac + +let rec extract_signature = function + | [] -> [] + | Egrammar.TacNonTerm (_,(_,t),_) :: l -> t :: extract_signature l + | _::l -> extract_signature l + +let rec match_vernac_rule tys = function + [] -> raise Not_found + | (s,pargs)::rls -> + if extract_signature pargs = tys then (s,pargs) + else match_vernac_rule tys rls + +let sep = fun _ -> spc() +let sep_p = fun _ -> str"." +let sep_v = fun _ -> str"," +let sep_v2 = fun _ -> str"," ++ spc() +let sep_pp = fun _ -> str":" + +let pr_ne_sep sep pr = function + [] -> mt() + | l -> sep() ++ pr l + +let pr_entry_prec = function + | Some Gramext.LeftA -> str"LEFTA " + | Some Gramext.RightA -> str"RIGHTA " + | Some Gramext.NonA -> str"NONA " + | None -> mt() + +let pr_prec = function + | Some Gramext.LeftA -> str", left associativity" + | Some Gramext.RightA -> str", right associativity" + | Some Gramext.NonA -> str", no associativity" + | None -> mt() + +let pr_set_entry_type = function + | ETIdent -> str"ident" + | ETReference -> str"global" + | ETPattern -> str"pattern" + | ETConstr _ -> str"constr" + | ETOther (_,e) -> str e + | ETBigint -> str "bigint" + | ETConstrList _ -> failwith "Internal entry type" + +let pr_non_terminal = function + | NtQual (u,nt) -> (* no more qualified entries *) str nt + | NtShort "constrarg" -> str "constr" + | NtShort nt -> str nt + +let strip_meta id = + let s = string_of_id id in + if s.[0]='$' then id_of_string (String.sub s 1 (String.length s - 1)) + else id + +let pr_production_item = function + | VNonTerm (loc,nt,Some p) -> pr_non_terminal nt ++ str"(" ++ pr_id (strip_meta p) ++ str")" + | VNonTerm (loc,nt,None) -> pr_non_terminal nt + | VTerm s -> qsnew s + +let pr_comment pr_c = function + | CommentConstr c -> pr_c c + | CommentString s -> qsnew s + | CommentInt n -> int n + +let pr_in_out_modules = function + | SearchInside l -> spc() ++ str"inside" ++ spc() ++ prlist_with_sep sep pr_module l + | SearchOutside [] -> mt() + | SearchOutside l -> spc() ++ str"outside" ++ spc() ++ prlist_with_sep sep pr_module l + +let pr_search_about = function + | SearchRef r -> pr_reference r + | SearchString s -> qsnew s + +let pr_search a b pr_p = match a with + | SearchHead qid -> str"Search" ++ spc() ++ pr_reference qid ++ pr_in_out_modules b + | SearchPattern c -> str"SearchPattern" ++ spc() ++ pr_p c ++ pr_in_out_modules b + | SearchRewrite c -> str"SearchRewrite" ++ spc() ++ pr_p c ++ pr_in_out_modules b + | SearchAbout sl -> str"SearchAbout" ++ spc() ++ str "[" ++ prlist_with_sep spc pr_search_about sl ++ str "]" ++ pr_in_out_modules b + +let pr_locality local = if local then str "Local " else str "" + +let pr_explanation imps = function + | ExplByPos n -> pr_id (Impargs.name_of_implicit (List.nth imps (n-1))) + | ExplByName id -> pr_id id + +let pr_class_rawexpr = function + | FunClass -> str"Funclass" + | SortClass -> str"Sortclass" + | RefClass qid -> pr_reference qid + +let pr_option_ref_value = function + | QualidRefValue id -> pr_reference id + | StringRefValue s -> qsnew s + +let pr_printoption a b = match a with + | Goptions.PrimaryTable table -> str table ++ pr_opt (prlist_with_sep sep pr_option_ref_value) b + | Goptions.SecondaryTable (table,field) -> str table ++ spc() ++ str field ++ pr_opt (prlist_with_sep sep pr_option_ref_value) b + +let pr_set_option a b = + let pr_opt_value = function + | IntValue n -> spc() ++ int n + | StringValue s -> spc() ++ str s + | BoolValue b -> mt() + in pr_printoption a None ++ pr_opt_value b + +let pr_topcmd _ = str"(* <Warning> : No printer for toplevel commands *)" + +let pr_destruct_location = function + | Tacexpr.ConclLocation () -> str"Conclusion" + | Tacexpr.HypLocation b -> if b then str"Discardable Hypothesis" else str"Hypothesis" + +let pr_opt_hintbases l = match l with + | [] -> mt() + | _ as z -> str":" ++ spc() ++ prlist_with_sep sep str z + +let pr_hints local db h pr_c pr_pat = + let opth = pr_opt_hintbases db in + let pr_aux = function + | CAppExpl (_,(_,qid),[]) -> pr_reference qid + | _ -> mt () in + let pph = + match h with + | HintsResolve l -> + str "Resolve " ++ + prlist_with_sep sep pr_c (List.map snd l) + | HintsImmediate l -> + str"Immediate" ++ spc() ++ + prlist_with_sep sep pr_c (List.map snd l) + | HintsUnfold l -> + str "Unfold " ++ + prlist_with_sep sep pr_reference (List.map snd l) + | HintsConstructors (n,c) -> + str"Constructors" ++ spc() ++ + prlist_with_sep spc pr_reference c + | HintsExtern (name,n,c,tac) -> + str "Extern" ++ spc() ++ int n ++ spc() ++ pr_pat c ++ str" =>" ++ + spc() ++ pr_raw_tactic tac + | HintsDestruct(name,i,loc,c,tac) -> + str "Destruct " ++ pr_id name ++ str" :=" ++ spc() ++ + hov 0 (int i ++ spc() ++ pr_destruct_location loc ++ spc() ++ + pr_c c ++ str " =>") ++ spc() ++ + pr_raw_tactic tac in + hov 2 (str"Hint "++pr_locality local ++ pph ++ opth) + +let pr_with_declaration pr_c = function + | CWith_Definition (id,c) -> + let p = pr_c c in + str"Definition" ++ spc() ++ pr_lident id ++ str" := " ++ p + | CWith_Module (id,qid) -> + str"Module" ++ spc() ++ pr_lident id ++ str" := " ++ + pr_located pr_qualid qid + +let rec pr_module_type pr_c = function + | CMTEident qid -> spc () ++ pr_located pr_qualid qid + | CMTEwith (mty,decl) -> + let m = pr_module_type pr_c mty in + let p = pr_with_declaration pr_c decl in + m ++ spc() ++ str"with" ++ spc() ++ p + +let pr_of_module_type prc (mty,b) = + str (if b then ":" else "<:") ++ + pr_module_type prc mty + +let pr_module_vardecls pr_c (idl,mty) = + let m = pr_module_type pr_c mty in + (* Update the Nametab for interpreting the body of module/modtype *) + let lib_dir = Lib.library_dp() in + List.iter (fun (_,id) -> + Declaremods.process_module_bindings [id] + [make_mbid lib_dir (string_of_id id), + Modintern.interp_modtype (Global.env()) mty]) idl; + (* Builds the stream *) + spc() ++ + hov 1 (str"(" ++ prlist_with_sep spc pr_lident idl ++ str":" ++ m ++ str")") + +let pr_module_binders l pr_c = + (* Effet de bord complexe pour garantir la declaration des noms des + modules parametres dans la Nametab des l'appel de pr_module_binders + malgre l'aspect paresseux des streams *) + let ml = List.map (pr_module_vardecls pr_c) l in + prlist (fun id -> id) ml + +let pr_module_binders_list l pr_c = pr_module_binders l pr_c + +let rec pr_module_expr = function + | CMEident qid -> pr_located pr_qualid qid + | CMEapply (me1,(CMEident _ as me2)) -> + pr_module_expr me1 ++ spc() ++ pr_module_expr me2 + | CMEapply (me1,me2) -> + pr_module_expr me1 ++ spc() ++ + hov 1 (str"(" ++ pr_module_expr me2 ++ str")") + +(* +let pr_opt_casted_constr pr_c = function + | CCast (loc,c,t) -> pr_c c ++ str":" ++ pr_c t + | _ as c -> pr_c c +*) + +let pr_type_option pr_c = function + | CHole loc -> mt() + | _ as c -> brk(0,2) ++ str":" ++ pr_c c + +let without_translation f x = + let old = Options.do_translate () in + let oldv7 = !Options.v7 in + Options.make_translate false; + try let r = f x in Options.make_translate old; Options.v7:=oldv7; r + with e -> Options.make_translate old; Options.v7:=oldv7; raise e + +let pr_decl_notation prc = + pr_opt (fun (ntn,c,scopt) -> fnl () ++ + str "where " ++ qsnew ntn ++ str " := " ++ without_translation prc c ++ + pr_opt (fun sc -> str ": " ++ str sc) scopt) + +let pr_vbinders l = + hv 0 (pr_binders l) + +let pr_binders_arg = + pr_ne_sep spc pr_binders + +let pr_and_type_binders_arg bl = + let bl, _ = pr_lconstr_env_n (Global.env()) false bl (CHole dummy_loc) in + pr_binders_arg bl + +let pr_onescheme (id,dep,ind,s) = + hov 0 (pr_lident id ++ str" :=") ++ spc() ++ + hov 0 ((if dep then str"Induction for" else str"Minimality for") + ++ spc() ++ pr_reference ind) ++ spc() ++ + hov 0 (str"Sort" ++ spc() ++ pr_sort s) + +let begin_of_inductive = function + [] -> 0 + | (_,((loc,_),_))::_ -> fst (unloc loc) + +let pr_class_rawexpr = function + | FunClass -> str"Funclass" + | SortClass -> str"Sortclass" + | RefClass qid -> pr_reference qid + +let pr_assumption_token many = function + | (Local,Logical) -> + str (if many then "Hypotheses" else "Hypothesis") + | (Local,Definitional) -> + str (if many then "Variables" else "Variable") + | (Global,Logical) -> + str (if many then "Axioms" else "Axiom") + | (Global,Definitional) -> + str (if many then "Parameters" else "Parameter") + | (Global,Conjectural) -> str"Conjecture" + | (Local,Conjectural) -> + anomaly "Don't know how to translate a local conjecture" + +let pr_params pr_c (xl,(c,t)) = + hov 2 (prlist_with_sep sep pr_lident xl ++ spc() ++ + (if c then str":>" else str":" ++ + spc() ++ pr_c t)) + +let rec factorize = function + | [] -> [] + | (c,(idl,t))::l -> + match factorize l with + | (xl,t')::l' when t' = (c,t) -> (idl@xl,t')::l' + | l' -> (idl,(c,t))::l' + +let pr_ne_params_list pr_c l = + match factorize l with + | [p] -> pr_params pr_c p + | l -> + prlist_with_sep spc + (fun p -> hov 1 (str "(" ++ pr_params pr_c p ++ str ")")) l +(* + prlist_with_sep pr_semicolon (pr_params pr_c) +*) + +let pr_thm_token = function + | Theorem -> str"Theorem" + | Lemma -> str"Lemma" + | Fact -> str"Fact" + | Remark -> str"Remark" + +let pr_require_token = function + | Some true -> str " Export" + | Some false -> str " Import" + | None -> mt() + +let pr_syntax_modifier = function + | SetItemLevel (l,NextLevel) -> + prlist_with_sep sep_v2 str l ++ + spc() ++ str"at next level" + | SetItemLevel (l,NumLevel n) -> + prlist_with_sep sep_v2 str l ++ + spc() ++ str"at level" ++ spc() ++ int n + | SetLevel n -> str"at level" ++ spc() ++ int n + | SetAssoc Gramext.LeftA -> str"left associativity" + | SetAssoc Gramext.RightA -> str"right associativity" + | SetAssoc Gramext.NonA -> str"no associativity" + | SetEntryType (x,typ) -> str x ++ spc() ++ pr_set_entry_type typ + | SetOnlyParsing -> str"only parsing" + | SetFormat s -> str"format " ++ pr_located qsnew s + +let pr_syntax_modifiers = function + | [] -> mt() + | l -> spc() ++ + hov 1 (str"(" ++ prlist_with_sep sep_v2 pr_syntax_modifier l ++ str")") + +let pr_grammar_tactic_rule (name,(s,pil),t) = +(* + hov 0 ( + (* str name ++ spc() ++ *) + hov 0 (str"[" ++ qsnew s ++ spc() ++ + prlist_with_sep sep pr_production_item pil ++ str"]") ++ + spc() ++ hov 0 (str"->" ++ spc() ++ str"[" ++ pr_raw_tactic t ++ str"]")) +*) + hov 2 (str "Tactic Notation" ++ spc() ++ + hov 0 (qsnew s ++ spc() ++ prlist_with_sep sep pr_production_item pil ++ + spc() ++ str":=" ++ spc() ++ pr_raw_tactic t)) + +let pr_box b = let pr_boxkind = function + | PpHB n -> str"h" ++ spc() ++ int n + | PpVB n -> str"v" ++ spc() ++ int n + | PpHVB n -> str"hv" ++ spc() ++ int n + | PpHOVB n -> str"hov" ++ spc() ++ int n + | PpTB -> str"t" +in str"<" ++ pr_boxkind b ++ str">" + +let pr_paren_reln_or_extern = function + | None,L -> str"L" + | None,E -> str"E" + | Some pprim,Any -> qsnew pprim + | Some pprim,Prec p -> qsnew pprim ++ spc() ++ str":" ++ spc() ++ int p + | _ -> mt() + +let rec pr_next_hunks = function + | UNP_FNL -> str"FNL" + | UNP_TAB -> str"TAB" + | RO c -> qsnew c + | UNP_BOX (b,ll) -> str"[" ++ pr_box b ++ prlist_with_sep sep pr_next_hunks ll ++ str"]" + | UNP_BRK (n,m) -> str"[" ++ int n ++ spc() ++ int m ++ str"]" + | UNP_TBRK (n,m) -> str"[ TBRK" ++ int n ++ spc() ++ int m ++ str"]" + | PH (e,None,_) -> print_ast e + | PH (e,Some ext,pr) -> print_ast e ++ spc() ++ str":" ++ spc() ++ pr_paren_reln_or_extern (Some ext,pr) + | UNP_SYMBOLIC _ -> mt() + +let pr_unparsing u = + str "[ " ++ prlist_with_sep sep pr_next_hunks u ++ str " ]" + +let pr_astpat a = str"<<" ++ print_ast a ++ str">>" + +let pr_syntax_rule (nm,s,u) = str nm ++ spc() ++ str"[" ++ pr_astpat s ++ str"]" ++ spc() ++ str"->" ++ spc() ++ pr_unparsing u + +let pr_syntax_entry (p,rl) = + str"level" ++ spc() ++ int p ++ str" :" ++ fnl() ++ + prlist_with_sep (fun _ -> fnl() ++ str"| ") pr_syntax_rule rl + +let pr_vernac_solve (i,env,tac,deftac) = + (if i = 1 then mt() else int i ++ str ": ") ++ + Pptacticnew.pr_glob_tactic env tac + ++ (try if deftac & Pfedit.get_end_tac() <> None then str ".." else mt () + with UserError _|Stdpp.Exc_located _ -> mt()) + +(**************************************) +(* Pretty printer for vernac commands *) +(**************************************) +let make_pr_vernac pr_constr pr_lconstr = + +let pr_constrarg c = spc () ++ pr_constr c in +let pr_lconstrarg c = spc () ++ pr_lconstr c in +let pr_intarg n = spc () ++ int n in + +let rec pr_vernac = function + + (* Proof management *) + | VernacAbortAll -> str "Abort All" + | VernacRestart -> str"Restart" + | VernacSuspend -> str"Suspend" + | VernacUnfocus -> str"Unfocus" + | VernacGoal c -> str"Goal" ++ pr_lconstrarg c + | VernacAbort id -> str"Abort" ++ pr_opt pr_lident id + | VernacResume id -> str"Resume" ++ pr_opt pr_lident id + | VernacUndo i -> if i=1 then str"Undo" else str"Undo" ++ pr_intarg i + | VernacFocus i -> str"Focus" ++ pr_opt int i + | VernacGo g -> + let pr_goable = function + | GoTo i -> int i + | GoTop -> str"top" + | GoNext -> str"next" + | GoPrev -> str"prev" + in str"Go" ++ spc() ++ pr_goable g + | VernacShow s -> + let pr_showable = function + | ShowGoal n -> str"Show" ++ pr_opt int n + | ShowGoalImplicitly n -> str"Show Implicit Arguments" ++ pr_opt int n + | ShowProof -> str"Show Proof" + | ShowNode -> str"Show Node" + | ShowScript -> str"Show Script" + | ShowExistentials -> str"Show Existentials" + | ShowTree -> str"Show Tree" + | ShowProofNames -> str"Show Conjectures" + | ShowIntros b -> str"Show " ++ (if b then str"Intros" else str"Intro") + | ExplainProof l -> str"Explain Proof" ++ spc() ++ prlist_with_sep sep int l + | ExplainTree l -> str"Explain Proof Tree" ++ spc() ++ prlist_with_sep sep int l + in pr_showable s + | VernacCheckGuard -> str"Guarded" + | VernacDebug b -> pr_topcmd b + + (* Resetting *) + | VernacResetName id -> str"Reset" ++ spc() ++ pr_lident id + | VernacResetInitial -> str"Reset Initial" + | VernacBack i -> if i=1 then str"Back" else str"Back" ++ pr_intarg i + + (* State management *) + | VernacWriteState s -> str"Write State" ++ spc () ++ qsnew s + | VernacRestoreState s -> str"Restore State" ++ spc() ++ qsnew s + + (* Control *) + | VernacList l -> + hov 2 (str"[" ++ spc() ++ + prlist (fun v -> pr_located pr_vernac v ++ sep_end () ++ fnl()) l + ++ spc() ++ str"]") + | VernacLoad (f,s) -> str"Load" ++ if f then (spc() ++ str"Verbose" + ++ spc()) else spc() ++ qsnew s + | VernacTime v -> str"Time" ++ spc() ++ pr_vernac v + | VernacVar id -> pr_lident id + + (* Syntax *) + | VernacGrammar _ -> + msgerrnl (str"Warning : constr Grammar is discontinued; use Notation"); + str"(* <Warning> : Grammar is replaced by Notation *)" + | VernacTacticGrammar l -> + prlist_with_sep (fun () -> sep_end() ++ fnl()) pr_grammar_tactic_rule l +(* + hov 1 (str"Grammar tactic simple_tactic :=" ++ spc() ++ prlist_with_sep (fun _ -> brk(1,1) ++ str"|") pr_grammar_tactic_rule l) (***) +*) + | VernacSyntax (u,el) -> + msgerrnl (str"Warning : Syntax is discontinued; use Notation"); + str"(* <Warning> : Syntax is discontinued" ++ +(* + fnl () ++ + hov 1 (str"Syntax " ++ str u ++ spc() ++ + prlist_with_sep sep_v2 pr_syntax_entry el) ++ +*) + str " *)" + | VernacOpenCloseScope (local,opening,sc) -> + str (if opening then "Open " else "Close ") ++ pr_locality local ++ + str "Scope" ++ spc() ++ str sc + | VernacDelimiters (sc,key) -> + str"Delimit Scope" ++ spc () ++ str sc ++ + spc() ++ str "with " ++ str key + | VernacBindScope (sc,cll) -> + str"Bind Scope" ++ spc () ++ str sc ++ + spc() ++ str "with " ++ prlist_with_sep spc pr_class_rawexpr cll + | VernacArgumentsScope (q,scl) -> let pr_opt_scope = function + | None -> str"_" + | Some sc -> str sc in + str"Arguments Scope" ++ spc() ++ pr_reference q ++ spc() ++ str"[" ++ prlist_with_sep sep pr_opt_scope scl ++ str"]" + | VernacInfix (local,(s,_),q,ov8,sn) -> (* A Verifier *) + let s,mv8 = match ov8 with Some smv8 -> smv8 | None -> (s,[]) in + hov 0 (hov 0 (str"Infix " ++ pr_locality local + ++ qsnew s ++ str " :=" ++ spc() ++ pr_reference q) ++ + pr_syntax_modifiers mv8 ++ + (match sn with + | None -> mt() + | Some sc -> spc() ++ str":" ++ spc() ++ str sc)) + | VernacDistfix (local,a,p,s,q,sn) -> + hov 0 (str"Distfix " ++ pr_locality local ++ pr_entry_prec a ++ int p + ++ spc() ++ qsnew s ++ spc() ++ pr_reference q ++ (match sn with + | None -> mt() + | Some sc -> spc() ++ str":" ++ spc() ++ str sc)) + | VernacNotation (local,c,sl,mv8,opt) -> + let (s,l) = match mv8 with + None -> fst (out_some sl), [] + | Some ml -> ml in + let ps = + let n = String.length s in + if n > 2 & s.[0] = '\'' & s.[n-1] = '\'' + then + let s' = String.sub s 1 (n-2) in + if String.contains s' '\'' then qsnew s else str s' + else qsnew s in + hov 2( str"Notation" ++ spc() ++ pr_locality local ++ ps ++ + str " :=" ++ pr_constrarg c ++ pr_syntax_modifiers l ++ + (match opt with + | None -> mt() + | Some sc -> str" :" ++ spc() ++ str sc)) + | VernacSyntaxExtension (local,sl,mv8) -> + let (s,l) = match mv8 with + None -> out_some sl + | Some ml -> ml in + str"Reserved Notation" ++ spc() ++ pr_locality local ++ qsnew s ++ + pr_syntax_modifiers l + + (* Gallina *) + | VernacDefinition (d,id,b,f) -> (* A verifier... *) + let pr_def_token = function + | Local, Coercion -> str"Coercion Local" + | Global, Coercion -> str"Coercion" + | Local, Definition -> str"Let" + | Global, Definition -> str"Definition" + | Local, SubClass -> str"Local SubClass" + | Global, SubClass -> str"SubClass" + | Global, CanonicalStructure -> str"Canonical Structure" + | Local, CanonicalStructure -> + anomaly "Don't know how to translate a local canonical structure" in + let pr_reduce = function + | None -> mt() + | Some r -> + str"Eval" ++ spc() ++ + pr_red_expr (pr_constr, pr_lconstr, pr_reference) r ++ + str" in" ++ spc() in + let mkLambdaCit = List.fold_right (fun (x,a) b -> mkLambdaC(x,a,b)) in + let mkProdCit = List.fold_right (fun (x,a) b -> mkProdC(x,a,b)) in + let pr_def_body = function + | DefineBody (bl,red,c,d) -> + let (bl2,body,ty) = match d with + | None -> + let bl2,body = extract_lam_binders c in + (bl2,body,mt()) + | Some ty -> + let bl2,body,ty' = extract_def_binders c ty in + (bl2,CCast (dummy_loc,body,ty'), + spc() ++ str":" ++ + pr_sep_com spc + (pr_type_env_n (Global.env()) (bl@bl2)) ty') in + let iscast = d <> None in + let bindings,ppred = + pr_lconstr_env_n (Global.env()) iscast (bl@bl2) body in + (pr_binders_arg bindings,ty,Some (pr_reduce red ++ ppred)) + | ProveBody (bl,t) -> + (pr_and_type_binders_arg bl, str" :" ++ pr_spc_type t, None) + in + let (binds,typ,c) = pr_def_body b in + hov 2 (pr_def_token d ++ spc() ++ pr_lident id ++ binds ++ typ ++ + (match c with + | None -> mt() + | Some cc -> str" :=" ++ spc() ++ cc)) + + | VernacStartTheoremProof (ki,id,(bl,c),b,d) -> + hov 1 (pr_thm_token ki ++ spc() ++ pr_lident id ++ spc() ++ + (match bl with + | [] -> mt() + | _ -> error "Statements with local binders no longer supported") + ++ str":" ++ pr_spc_type (rename_bound_variables (snd id) c)) + | VernacEndProof Admitted -> str"Admitted" + | VernacEndProof (Proved (opac,o)) -> (match o with + | None -> if opac then str"Qed" else str"Defined" + | Some (id,th) -> (match th with + | None -> (if opac then str"Save" else str"Defined") ++ spc() ++ pr_lident id + | Some tok -> str"Save" ++ spc() ++ pr_thm_token tok ++ spc() ++ pr_lident id)) + | VernacExactProof c -> + hov 2 (str"Proof" ++ pr_lconstrarg c) + | VernacAssumption (stre,l) -> + hov 2 + (pr_assumption_token (List.length l > 1) stre ++ spc() ++ + pr_ne_params_list pr_type l) + | VernacInductive (f,l) -> + + (* Copie simplifiée de command.ml pour recalculer les implicites, *) + (* les notations, et le contexte d'evaluation *) + let lparams = match l with [] -> assert false | (_,_,la,_,_)::_ -> la in + let nparams = local_binders_length lparams + and sigma = Evd.empty + and env0 = Global.env() in + let (env_params,params) = + List.fold_left + (fun (env,params) d -> match d with + | LocalRawAssum (nal,t) -> + let t = Constrintern.interp_type sigma env t in + let ctx = list_map_i (fun i (_,na) -> (na,None,Term.lift i t)) 0 nal + in let ctx = List.rev ctx in + (Environ.push_rel_context ctx env, ctx@params) + | LocalRawDef ((_,na),c) -> + let c = Constrintern.judgment_of_rawconstr sigma env c in + let d = (na, Some c.Environ.uj_val, c.Environ.uj_type) in + (Environ.push_rel d env,d::params)) + (env0,[]) lparams in + + let (ind_env,ind_impls,arityl) = + List.fold_left + (fun (env, ind_impls, arl) ((_,recname), _, _, arityc, _) -> + let arity = Constrintern.interp_type sigma env_params arityc in + let fullarity = Termops.it_mkProd_or_LetIn arity params in + let env' = Termops.push_rel_assum (Name recname,fullarity) env in + let impls = + if Impargs.is_implicit_args() + then Impargs.compute_implicits false env_params fullarity + else [] in + (env', (recname,impls)::ind_impls, (arity::arl))) + (env0, [], []) l + in + let lparnames = List.map (fun (na,_,_) -> na) params in + let notations = + List.fold_right (fun (_,ntnopt,_,_,_) l ->option_cons ntnopt l) l [] in + let ind_env_params = Environ.push_rel_context params ind_env in + + let lparnames = List.map (fun (na,_,_) -> na) params in + let impl = List.map + (fun ((_,recname),_,_,arityc,_) -> + let arity = Constrintern.interp_type sigma env_params arityc in + let fullarity = + Termops.prod_it arity (List.map (fun (id,_,ty) -> (id,ty)) params) + in + let impl_in = + if Impargs.is_implicit_args() + then Impargs.compute_implicits false env_params fullarity + else [] in + let impl_out = + if Impargs.is_implicit_args_out() + then Impargs.compute_implicits true env_params fullarity + else [] in + (recname,impl_in,impl_out)) l in + let impls_in = List.map (fun (id,a,_) -> (id,a)) impl in + let impls_out = List.map (fun (id,_,a) -> (id,a)) impl in + Constrintern.set_temporary_implicits_in impls_in; + Constrextern.set_temporary_implicits_out impls_out; + (* Fin calcul implicites *) + + let pr_constructor (coe,(id,c)) = + hov 2 (pr_lident id ++ str" " ++ + (if coe then str":>" else str":") ++ + pr_sep_com spc (pr_type_env_n ind_env_params []) c) in + let pr_constructor_list l = match l with + | [] -> mt() + | _ -> + pr_com_at (begin_of_inductive l) ++ + fnl() ++ + str (if List.length l = 1 then " " else " | ") ++ + prlist_with_sep (fun _ -> fnl() ++ str" | ") pr_constructor l in + let pr_oneind key (id,ntn,indpar,s,lc) = + hov 0 ( + str key ++ spc() ++ + pr_lident id ++ pr_and_type_binders_arg indpar ++ spc() ++ str":" ++ + spc() ++ pr_type s ++ + str" :=") ++ pr_constructor_list lc ++ + pr_decl_notation pr_constr ntn in + + (* Copie simplifiée de command.ml pour déclarer les notations locales *) + List.iter (fun (df,c,scope) -> + Metasyntax.add_notation_interpretation df [] c scope) notations; + + hov 1 (pr_oneind (if f then "Inductive" else "CoInductive") (List.hd l)) + ++ + (prlist (fun ind -> fnl() ++ hov 1 (pr_oneind "with" ind)) (List.tl l)) + + + | VernacFixpoint recs -> + + (* Copie simplifiée de command.ml pour recalculer les implicites *) + (* les notations, et le contexte d'evaluation *) + let sigma = Evd.empty + and env0 = Global.env() in + let notations = + List.fold_right (fun (_,ntnopt) l -> option_cons ntnopt l) recs [] in + let impl = List.map + (fun ((recname,_, bl, arityc,_),_) -> + let arity = + Constrintern.interp_type sigma env0 + (prod_constr_expr arityc bl) in + let impl_in = + if Impargs.is_implicit_args() + then Impargs.compute_implicits false env0 arity + else [] in + let impl_out = + if Impargs.is_implicit_args_out() + then Impargs.compute_implicits true env0 arity + else [] in + (recname,impl_in,impl_out)) recs in + let impls_in = List.map (fun (id,a,_) -> (id,a)) impl in + let impls_out = List.map (fun (id,_,a) -> (id,a)) impl in + Constrintern.set_temporary_implicits_in impls_in; + Constrextern.set_temporary_implicits_out impls_out; + + (* Copie simplifiée de command.ml pour déclarer les notations locales *) + List.iter (fun (df,c,scope) -> + Metasyntax.add_notation_interpretation df [] c None) notations; + + let rec_sign = + List.fold_left + (fun env ((recname,_,bl,arityc,_),_) -> + let arity = + Constrintern.interp_type sigma env0 + (prod_constr_expr arityc bl) in + Environ.push_named (recname,None,arity) env) + (Global.env()) recs in + + let name_of_binder = function + | LocalRawAssum (nal,_) -> nal + | LocalRawDef (_,_) -> [] in + let pr_onerec = function + | (id,n,bl,type_,def),ntn -> + let (bl',def,type_) = + if Options.do_translate() then extract_def_binders def type_ + else ([],def,type_) in + let bl = bl @ bl' in + let ids = List.flatten (List.map name_of_binder bl) in + let name = + try snd (List.nth ids n) + with Failure _ -> + warn (str "non-printable fixpoint \""++pr_id id++str"\""); + Anonymous in + let annot = + if List.length ids > 1 then + spc() ++ str "{struct " ++ pr_name name ++ str"}" + else mt() in + let bl,ppc = + pr_lconstr_env_n rec_sign true bl (CCast(dummy_loc,def,type_)) in + pr_id id ++ pr_binders_arg bl ++ annot ++ spc() + ++ pr_type_option (fun c -> spc() ++ pr_type c) type_ + ++ str" :=" ++ brk(1,1) ++ ppc ++ + pr_decl_notation pr_constr ntn + in + hov 1 (str"Fixpoint" ++ spc() ++ + prlist_with_sep (fun _ -> fnl() ++ fnl() ++ str"with ") pr_onerec recs) + + | VernacCoFixpoint corecs -> + let pr_onecorec (id,bl,c,def) = + let (bl',def,c) = + if Options.do_translate() then extract_def_binders def c + else ([],def,c) in + let bl = bl @ bl' in + pr_id id ++ spc() ++ pr_binders bl ++ spc() ++ str":" ++ + spc() ++ pr_type c ++ + str" :=" ++ brk(1,1) ++ pr_lconstr def in + hov 1 (str"CoFixpoint" ++ spc() ++ + prlist_with_sep (fun _ -> fnl() ++ str"with ") pr_onecorec corecs) + | VernacScheme l -> + hov 2 (str"Scheme" ++ spc() ++ + prlist_with_sep (fun _ -> fnl() ++ str"with ") pr_onescheme l) + + (* Gallina extensions *) + | VernacRecord (b,(oc,name),ps,s,c,fs) -> + let pr_record_field = function + | (oc,AssumExpr (id,t)) -> + hov 1 (pr_lname id ++ + (if oc then str" :>" else str" :") ++ spc() ++ + pr_type t) + | (oc,DefExpr(id,b,opt)) -> (match opt with + | Some t -> + hov 1 (pr_lname id ++ + (if oc then str" :>" else str" :") ++ spc() ++ + pr_type t ++ str" :=" ++ pr_lconstr b) + | None -> + hov 1 (pr_lname id ++ str" :=" ++ spc() ++ + pr_lconstr b)) in + hov 2 + (str (if b then "Record" else "Structure") ++ + (if oc then str" > " else str" ") ++ pr_lident name ++ + pr_and_type_binders_arg ps ++ str" :" ++ spc() ++ pr_type s ++ + str" := " ++ + (match c with + | None -> mt() + | Some sc -> pr_lident sc) ++ + spc() ++ str"{" ++ + hv 0 (prlist_with_sep pr_semicolon pr_record_field fs ++ str"}")) + | VernacBeginSection id -> hov 2 (str"Section" ++ spc () ++ pr_lident id) + | VernacEndSegment id -> hov 2 (str"End" ++ spc() ++ pr_lident id) + | VernacRequire (exp,spe,l) -> hov 2 + (str "Require" ++ pr_require_token exp ++ spc() ++ + (match spe with + | None -> mt() + | Some flag -> + (if flag then str"Specification" else str"Implementation") ++ + spc ()) ++ + prlist_with_sep sep pr_module l) + | VernacImport (f,l) -> + (if f then str"Export" else str"Import") ++ spc() ++ + prlist_with_sep sep pr_import_module l + | VernacCanonical q -> str"Canonical Structure" ++ spc() ++ pr_reference q + | VernacCoercion (s,id,c1,c2) -> + hov 1 ( + str"Coercion" ++ (match s with | Local -> spc() ++ + str"Local" ++ spc() | Global -> spc()) ++ + pr_reference id ++ spc() ++ str":" ++ spc() ++ pr_class_rawexpr c1 ++ + spc() ++ str">->" ++ spc() ++ pr_class_rawexpr c2) + | VernacIdentityCoercion (s,id,c1,c2) -> + hov 1 ( + str"Identity Coercion" ++ (match s with | Local -> spc() ++ + str"Local" ++ spc() | Global -> spc()) ++ pr_lident id ++ + spc() ++ str":" ++ spc() ++ pr_class_rawexpr c1 ++ spc() ++ str">->" ++ + spc() ++ pr_class_rawexpr c2) + + (* Modules and Module Types *) + | VernacDefineModule (m,bl,ty,bd) -> + let b = pr_module_binders_list bl pr_lconstr in + hov 2 (str"Module " ++ pr_lident m ++ b ++ + pr_opt (pr_of_module_type pr_lconstr) ty ++ + pr_opt (fun me -> str ":= " ++ pr_module_expr me) bd) + | VernacDeclareModule (id,bl,m1,m2) -> + let b = pr_module_binders_list bl pr_lconstr in + hov 2 (str"Declare Module " ++ pr_lident id ++ b ++ + pr_opt (pr_of_module_type pr_lconstr) m1 ++ + pr_opt (fun me -> str ":= " ++ pr_module_expr me) m2) + | VernacDeclareModuleType (id,bl,m) -> + let b = pr_module_binders_list bl pr_lconstr in + hov 2 (str"Module Type " ++ pr_lident id ++ b ++ + pr_opt (fun mt -> str ":= " ++ pr_module_type pr_lconstr mt) m) + + (* Solving *) + | VernacSolve (i,tac,deftac) -> + (* Normally shunted by vernac.ml *) + let env = + try snd (Pfedit.get_goal_context i) + with UserError _ -> Global.env() in + let tac = + Options.with_option Options.translate_syntax + (Constrintern.for_grammar (Tacinterp.glob_tactic_env [] env)) tac in + pr_vernac_solve (i,env,tac,deftac) + + | VernacSolveExistential (i,c) -> + str"Existential " ++ int i ++ pr_lconstrarg c + + (* Auxiliary file and library management *) + | VernacRequireFrom (exp,spe,f) -> hov 2 + (str"Require " ++ pr_require_token exp ++ spc() ++ + (match spe with + | None -> mt() + | Some false -> str"Implementation" ++ spc() + | Some true -> str"Specification" ++ spc ()) ++ + qsnew f) + | VernacAddLoadPath (fl,s,d) -> hov 2 + (str"Add" ++ + (if fl then str" Rec " else spc()) ++ + str"LoadPath" ++ spc() ++ qsnew s ++ + (match d with + | None -> mt() + | Some dir -> spc() ++ str"as" ++ spc() ++ pr_dirpath dir)) + | VernacRemoveLoadPath s -> str"Remove LoadPath" ++ qsnew s + | VernacAddMLPath (fl,s) -> + str"Add" ++ (if fl then str" Rec " else spc()) ++ str"ML Path" ++ qsnew s + | VernacDeclareMLModule l -> + hov 2 (str"Declare ML Module" ++ spc() ++ prlist_with_sep sep qsnew l) + | VernacChdir s -> str"Cd" ++ pr_opt qsnew s + + (* Commands *) + | VernacDeclareTacticDefinition (rc,l) -> + let pr_tac_body (id, body) = + let idl, body = + match body with + | Tacexpr.TacFun (idl,b) -> idl,b + | _ -> [], body in + pr_located pr_ltac_id id ++ + prlist (function None -> str " _" + | Some id -> spc () ++ pr_id id) idl + ++ str" :=" ++ brk(1,1) ++ + let idl = List.map out_some (List.filter (fun x -> not (x=None)) idl)in + pr_raw_tactic_env + (idl @ List.map snd (List.map fst l)) + (Global.env()) + body in + hov 1 + (((*if !Options.p1 then + (if rc then str "Recursive " else mt()) ++ + str "Tactic Definition " else*) + (* Rec by default *) str "Ltac ") ++ + prlist_with_sep (fun () -> fnl() ++ str"with ") pr_tac_body l) + | VernacHints (local,dbnames,h) -> + pr_hints local dbnames h pr_constr pr_pattern + | VernacSyntacticDefinition (id,c,local,onlyparsing) -> + hov 2 + (str"Notation " ++ pr_locality local ++ pr_id id ++ str" :=" ++ + pr_constrarg c ++ + pr_syntax_modifiers (if onlyparsing then [SetOnlyParsing] else [])) + | VernacDeclareImplicits (q,None) -> + hov 2 (str"Implicit Arguments" ++ spc() ++ pr_reference q) + | VernacDeclareImplicits (q,Some l) -> + let r = Nametab.global q in + Impargs.declare_manual_implicits r l; + let imps = Impargs.implicits_of_global r in + hov 1 (str"Implicit Arguments" ++ spc() ++ pr_reference q ++ spc() ++ + str"[" ++ prlist_with_sep sep (pr_explanation imps) l ++ str"]") + | VernacReserve (idl,c) -> + hov 1 (str"Implicit Type" ++ + str (if List.length idl > 1 then "s " else " ") ++ + prlist_with_sep spc pr_lident idl ++ str " :" ++ spc () ++ pr_type c) + | VernacSetOpacity (fl,l) -> + hov 1 ((if fl then str"Opaque" else str"Transparent") ++ + spc() ++ prlist_with_sep sep pr_reference l) + + | VernacSetOption (Goptions.SecondaryTable ("Implicit","Arguments"),BoolValue true) -> + str"Set Implicit Arguments" + ++ + (if !Options.translate_strict_impargs then + sep_end () ++ fnl () ++ str"Unset Strict Implicit" + else mt ()) + | VernacUnsetOption (Goptions.SecondaryTable ("Implicit","Arguments")) + | VernacSetOption (Goptions.SecondaryTable ("Implicit","Arguments"),BoolValue false) -> + (if !Options.translate_strict_impargs then + str"Set Strict Implicit" ++ sep_end () ++ fnl () + else mt ()) + ++ + str"Unset Implicit Arguments" + + | VernacSetOption (Goptions.SecondaryTable (a,"Implicits"),BoolValue true) -> + str("Set "^a^" Implicit") + | VernacUnsetOption (Goptions.SecondaryTable (a,"Implicits")) -> + str("Unset "^a^" Implicit") + + | VernacUnsetOption na -> + hov 1 (str"Unset" ++ spc() ++ pr_printoption na None) + | VernacSetOption (na,v) -> hov 2 (str"Set" ++ spc() ++ pr_set_option na v) + | VernacAddOption (na,l) -> hov 2 (str"Add" ++ spc() ++ pr_printoption na (Some l)) + | VernacRemoveOption (na,l) -> hov 2 (str"Remove" ++ spc() ++ pr_printoption na (Some l)) + | VernacMemOption (na,l) -> hov 2 (str"Test" ++ spc() ++ pr_printoption na (Some l)) + | VernacPrintOption na -> hov 2 (str"Test" ++ spc() ++ pr_printoption na None) + | VernacCheckMayEval (r,io,c) -> + let pr_mayeval r c = match r with + | Some r0 -> + hov 2 (str"Eval" ++ spc() ++ + pr_red_expr (pr_constr,pr_lconstr,pr_reference) r0 ++ + spc() ++ str"in" ++ spc () ++ pr_constr c) + | None -> hov 2 (str"Check" ++ spc() ++ pr_constr c) + in + (if io = None then mt() else int (out_some io) ++ str ": ") ++ + pr_mayeval r c + | VernacGlobalCheck c -> hov 2 (str"Type" ++ pr_constrarg c) + | VernacPrint p -> + let pr_printable = function + | PrintFullContext -> str"Print All" + | PrintSectionContext s -> + str"Print Section" ++ spc() ++ Libnames.pr_reference s + | PrintGrammar (uni,ent) -> + msgerrnl (str "warning: no direct translation of Print Grammar entry"); + str"Print Grammar" ++ spc() ++ str ent + | PrintLoadPath -> str"Print LoadPath" + | PrintModules -> str"Print Modules" + | PrintMLLoadPath -> str"Print ML Path" + | PrintMLModules -> str"Print ML Modules" + | PrintGraph -> str"Print Graph" + | PrintClasses -> str"Print Classes" + | PrintCoercions -> str"Print Coercions" + | PrintCoercionPaths (s,t) -> str"Print Coercion Paths" ++ spc() ++ pr_class_rawexpr s ++ spc() ++ pr_class_rawexpr t + | PrintTables -> str"Print Tables" + | PrintOpaqueName qid -> str"Print Term" ++ spc() ++ pr_reference qid + | PrintHintGoal -> str"Print Hint" + | PrintHint qid -> str"Print Hint" ++ spc() ++ pr_reference qid + | PrintHintDb -> str"Print Hint *" + | PrintHintDbName s -> str"Print HintDb" ++ spc() ++ str s + | PrintUniverses fopt -> str"Dump Universes" ++ pr_opt str fopt + | PrintName qid -> str"Print" ++ spc() ++ pr_reference qid + | PrintLocalContext -> assert false + (* str"Print" *) + | PrintModuleType qid -> str"Print Module Type" ++ spc() ++ pr_reference qid + | PrintModule qid -> str"Print Module" ++ spc() ++ pr_reference qid + | PrintInspect n -> str"Inspect" ++ spc() ++ int n + | PrintScopes -> str"Print Scopes" + | PrintScope s -> str"Print Scope" ++ spc() ++ str s + | PrintVisibility s -> str"Print Visibility" ++ pr_opt str s + | PrintAbout qid -> str"About" ++ spc() ++ pr_reference qid + | PrintImplicit qid -> str"Print Implicit" ++ spc() ++ pr_reference qid + in pr_printable p + | VernacSearch (sea,sea_r) -> pr_search sea sea_r pr_pattern + | VernacLocate loc -> + let pr_locate =function + | LocateTerm qid -> pr_reference qid + | LocateFile f -> str"File" ++ spc() ++ qsnew f + | LocateLibrary qid -> str"Library" ++ spc () ++ pr_module qid + | LocateNotation s -> qsnew s + in str"Locate" ++ spc() ++ pr_locate loc + | VernacComments l -> + hov 2 + (str"Comments" ++ spc() ++ prlist_with_sep sep (pr_comment pr_constr) l) + | VernacNop -> mt() + + (* Toplevel control *) + | VernacToplevelControl exn -> pr_topcmd exn + + (* For extension *) + | VernacExtend (s,c) -> pr_extend s c + | VernacV7only _ -> mt() + | VernacV8only com -> pr_vernac com + | VernacProof Tacexpr.TacId _ -> str "Proof" + | VernacProof te -> str "Proof with" ++ spc() ++ pr_raw_tactic te + +and pr_extend s cl = + let pr_arg a = + try pr_gen (Global.env()) a + with Failure _ -> str ("<error in "^s^">") in + try + (* Hack pour les syntaxes changeant non uniformément en passant a la V8 *) + let s = + let n = String.length s in + if Options.do_translate() & n > 2 & String.sub s (n-2) 2 = "V7" + then String.sub s 0 (n-2) ^ "V8" + else s in + (* "Hint Rewrite in using" changes the order of its args in v8 !! *) + let cl = match s, cl with + | "HintRewriteV8", [a;b;c;d] -> [a;b;d;c] + | _ -> cl in + let rls = List.assoc s (Egrammar.get_extend_vernac_grammars()) in + let (hd,rl) = match_vernac_rule (List.map Genarg.genarg_tag cl) rls in + let (pp,_) = + List.fold_left + (fun (strm,args) pi -> + match pi with + Egrammar.TacNonTerm _ -> + (strm ++ pr_gen (Global.env()) (List.hd args), + List.tl args) + | Egrammar.TacTerm s -> (strm ++ spc() ++ str s, args)) + (str hd,cl) rl in + hov 1 pp + ++ (if s = "Correctness" then sep_end () ++ fnl() ++ str "Proof" else mt()) + with Not_found -> + hov 1 (str ("TODO("^s) ++ prlist_with_sep sep pr_arg cl ++ str ")") + +in pr_vernac + +let pr_vernac = make_pr_vernac Ppconstrnew.pr_constr Ppconstrnew.pr_lconstr + +let pr_vernac = function + | VernacRequire (_,_,[Ident(_,r)]) when + (* Obsolete modules *) + List.mem (string_of_id r) + ["Refine"; "Inv"; "Equality"; "EAuto"; "AutoRewrite"; "EqDecide"; + "Xml"; "Extraction"; "Tauto"; "Setoid_replace";"Elimdep"; + "DatatypesSyntax"; "LogicSyntax"; "Logic_TypeSyntax"; + "SpecifSyntax"; "PeanoSyntax"; "TypeSyntax"; "PolyListSyntax"; + "Zsyntax"] -> + warning ("Forgetting obsolete module "^(string_of_id r)); + mt() + | VernacRequire (exp,spe,[Ident(_,r)]) when + (* Renamed modules *) + List.mem (string_of_id r) ["zarith_aux";"fast_integer"] -> + warning ("Replacing obsolete module "^(string_of_id r)^" with ZArith"); + (str "Require" ++ pr_require_token exp ++ spc() ++ + (match spe with + | None -> mt() + | Some flag -> + (if flag then str"Specification" else str"Implementation") ++ + spc ()) ++ + str "ZArith.") + | VernacImport (false,[Libnames.Ident (_,a)]) when + (* Pour ceux qui ont utilisé la couche "Import *_scope" de compat *) + let a = Names.string_of_id a in + a = "nat_scope" or a = "Z_scope" or a = "R_scope" -> mt() + | VernacSyntax _ | VernacGrammar _ as x -> pr_vernac x + | VernacPrint PrintLocalContext -> + warning ("\"Print.\" is discontinued"); + mt () + | x -> pr_vernac x ++ sep_end () + diff --git a/translate/ppvernacnew.mli b/translate/ppvernacnew.mli new file mode 100644 index 00000000..73101a1a --- /dev/null +++ b/translate/ppvernacnew.mli @@ -0,0 +1,34 @@ +(************************************************************************) +(* v * The Coq Proof Assistant / The Coq Development Team *) +(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *) +(* \VV/ **************************************************************) +(* // * This file is distributed under the terms of the *) +(* * GNU Lesser General Public License Version 2.1 *) +(************************************************************************) + +(* $Id: ppvernacnew.mli,v 1.3.2.1 2004/07/16 19:31:52 herbelin Exp $ *) + +open Pp +open Genarg +open Vernacexpr +open Names +open Nameops +open Nametab +open Util +open Extend +open Ppconstr +open Pptactic +open Rawterm +open Coqast +open Pcoq +open Ast +open Libnames +open Ppextend +open Topconstr + +val sep_end : unit -> std_ppcmds + +val pr_vernac : vernac_expr -> std_ppcmds + +val pr_vernac_solve : + int * Environ.env * Tacexpr.glob_tactic_expr * bool -> std_ppcmds |