summaryrefslogtreecommitdiff
path: root/parsing/pptactic.ml
diff options
context:
space:
mode:
Diffstat (limited to 'parsing/pptactic.ml')
-rw-r--r--parsing/pptactic.ml758
1 files changed, 758 insertions, 0 deletions
diff --git a/parsing/pptactic.ml b/parsing/pptactic.ml
new file mode 100644
index 00000000..95e134ae
--- /dev/null
+++ b/parsing/pptactic.ml
@@ -0,0 +1,758 @@
+(************************************************************************)
+(* 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: pptactic.ml,v 1.54.2.2 2004/07/16 19:30:40 herbelin Exp $ *)
+
+open Pp
+open Names
+open Nameops
+open Util
+open Extend
+open Tacexpr
+open Rawterm
+open Topconstr
+open Genarg
+open Libnames
+open Pattern
+
+let pr_red_expr = Ppconstr.pr_red_expr
+let pr_may_eval = Ppconstr.pr_may_eval
+let pr_sort = Ppconstr.pr_sort
+let pr_global x =
+ if Options.do_translate () then (* for pr_gen *)
+ Ppconstrnew.pr_global Idset.empty x
+ else
+ Ppconstr.pr_global Idset.empty x
+let pr_name = Ppconstr.pr_name
+let pr_opt = Ppconstr.pr_opt
+let pr_occurrences = Ppconstr.pr_occurrences
+
+type grammar_terminals = string option list
+
+ (* Extensions *)
+let prtac_tab_v7 = Hashtbl.create 17
+let prtac_tab = Hashtbl.create 17
+
+let declare_extra_tactic_pprule for_v8 s (tags,prods) =
+ Hashtbl.add prtac_tab_v7 (s,tags) prods;
+ if for_v8 then Hashtbl.add prtac_tab (s,tags) prods
+
+type 'a raw_extra_genarg_printer =
+ (constr_expr -> std_ppcmds) -> (raw_tactic_expr -> std_ppcmds) ->
+ 'a -> std_ppcmds
+type 'a glob_extra_genarg_printer =
+ (rawconstr_and_expr -> std_ppcmds) -> (glob_tactic_expr -> std_ppcmds) ->
+ 'a -> std_ppcmds
+type 'a extra_genarg_printer =
+ (Term.constr -> std_ppcmds) -> (glob_tactic_expr -> std_ppcmds) ->
+ 'a -> std_ppcmds
+
+let genarg_pprule_v7 = ref Stringmap.empty
+let genarg_pprule = ref Stringmap.empty
+
+let declare_extra_genarg_pprule for_v8 (rawwit, f) (globwit, g) (wit, h) =
+ let s = match unquote wit with
+ | ExtraArgType s -> s
+ | _ -> error
+ "Can declare a pretty-printing rule only for extra argument types"
+ in
+ let f prc prtac x = f prc prtac (out_gen rawwit x) in
+ let g prc prtac x = g prc prtac (out_gen globwit x) in
+ let h prc prtac x = h prc prtac (out_gen wit x) in
+ genarg_pprule_v7 := Stringmap.add s (f,g,h) !genarg_pprule_v7;
+ if for_v8 then
+ genarg_pprule := Stringmap.add s (f,g,h) !genarg_pprule
+
+let pr_arg pr x = spc () ++ pr x
+
+let pr_or_var pr = function
+ | ArgArg x -> pr x
+ | ArgVar (_,s) -> pr_id s
+
+let pr_or_metaid pr = function
+ | AI x -> pr x
+ | _ -> failwith "pr_hyp_location: unexpected quotation meta-variable"
+
+let pr_and_short_name pr (c,_) = pr c
+
+let pr_located pr (loc,x) = pr x
+
+let pr_ltac_constant sp = pr_qualid (Nametab.shortest_qualid_of_tactic sp)
+
+let pr_evaluable_reference = function
+ | EvalVarRef id -> pr_id id
+ | EvalConstRef sp -> pr_global (Libnames.ConstRef sp)
+
+let pr_inductive ind = pr_global (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
+ | loc, NamedHyp id, c -> hov 1 (pr_id id ++ str " := " ++ cut () ++ prc c)
+ | loc, AnonHyp n, c -> hov 1 (int n ++ str " := " ++ cut () ++ prc c)
+
+let pr_bindings prc prlc = function
+ | ImplicitBindings l ->
+ brk (1,1) ++ str "with" ++ brk (1,1) ++
+ prlist_with_sep spc prc l
+ | ExplicitBindings l ->
+ brk (1,1) ++ str "with" ++ brk (1,1) ++
+ prlist_with_sep spc
+ (fun b -> if Options.do_translate () or not !Options.v7 then
+ str"(" ++ pr_binding prlc b ++ str")"
+ else
+ pr_binding prc b)
+ l
+ | NoBindings -> mt ()
+
+let pr_bindings_no_with prc prlc = function
+ | ImplicitBindings l ->
+ brk (1,1) ++
+ prlist_with_sep spc prc l
+ | ExplicitBindings l ->
+ brk (1,1) ++
+ prlist_with_sep spc
+ (fun b -> if Options.do_translate () or not !Options.v7 then
+ str"(" ++ pr_binding prlc b ++ str")"
+ else
+ pr_binding prc b)
+ l
+ | NoBindings -> mt ()
+
+let pr_with_bindings prc prlc (c,bl) =
+ if Options.do_translate () then
+ (* translator calls pr_with_bindings on rawconstr: we cast it! *)
+ let bl' = Ppconstrnew.translate_with_bindings (fst (Obj.magic c) : rawconstr) bl in
+ prc c ++ hv 0 (pr_bindings prc prlc bl')
+ else
+ prc c ++ hv 0 (pr_bindings prc prlc bl)
+
+let pr_with_constr prc = function
+ | None -> mt ()
+ | Some c -> spc () ++ hov 1 (str "with" ++ spc () ++ prc c)
+
+let pr_with_names = function
+ | None -> mt ()
+ | Some ipat -> spc () ++ hov 1 (str "as" ++ spc () ++ pr_intro_pattern ipat)
+
+let pr_hyp_location pr_id = function
+ | id, _, (InHyp,_) -> spc () ++ pr_id id
+ | id, _, (InHypTypeOnly,_) ->
+ spc () ++ str "(Type of " ++ pr_id id ++ str ")"
+ | id, _, _ -> error "Unsupported hyp location in v7"
+
+let pr_clause pr_id = function
+ | [] -> mt ()
+ | l -> spc () ++ hov 0 (str "in" ++ prlist (pr_hyp_location pr_id) l)
+
+
+let pr_clauses pr_id cls =
+ match cls with
+ { onhyps = Some l; onconcl = false } ->
+ spc () ++ hov 0 (str "in" ++ prlist (pr_hyp_location pr_id) l)
+ | { onhyps = Some []; onconcl = true } -> mt()
+ | _ -> error "this clause has both hypothesis and conclusion"
+
+let pr_simple_clause pr_id = function
+ | [] -> mt ()
+ | l -> spc () ++
+ hov 0 (str "in" ++ spc () ++ prlist_with_sep spc pr_id l)
+
+let pr_clause_pattern pr_id cls =
+ pr_opt
+ (prlist (fun (id,occs,_) ->
+ prlist (pr_arg int) occs ++ spc () ++ pr_id id)) cls.onhyps ++
+ if cls.onconcl then
+ prlist (pr_arg int) cls.concl_occs ++ spc() ++ str"Goal"
+ else mt()
+
+let pr_subterms pr occl =
+ hov 0 (pr_occurrences pr occl ++ spc () ++ str "with")
+
+let pr_induction_arg prc = function
+ | ElimOnConstr c -> prc c
+ | ElimOnIdent (_,id) -> 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 "[" ++ pr_pat a ++ str "]"
+ | Subterm (Some id,a) -> pr_id id ++ str "[" ++ pr_pat a ++ str "]"
+
+let pr_match_hyps pr_pat = function
+ | Hyp ((_,na),mp) -> pr_name na ++ str ":" ++ pr_match_pattern pr_pat mp
+
+let pr_match_rule m pr_pat pr = function
+ | Pat ([],mp,t) when m ->
+ str "[" ++ pr_match_pattern pr_pat mp ++ str "]"
+ ++ spc () ++ str "->" ++ brk (1,2) ++ pr t
+ | Pat (rl,mp,t) ->
+ str "[" ++ prlist_with_sep pr_semicolon
+ (pr_match_hyps pr_pat) rl ++ spc () ++
+ str "|-" ++ spc () ++ pr_match_pattern pr_pat mp ++ spc () ++ str "]" ++
+ spc () ++ str "->" ++ brk (1,2) ++ pr t
+ | All t -> str "_" ++ spc () ++ str "->" ++ brk (1,2) ++ 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) -> hv 0(str k ++ pr_id id ++ str " =" ++ brk (1,1) ++ pr t)
+ | ((_,id),Some c,t) -> str "TODO(LETCLAUSE)"
+
+let pr_let_clauses pr = function
+ | hd::tl ->
+ hv 0
+ (pr_let_clause "Let " pr hd ++
+ prlist (fun t -> spc () ++ pr_let_clause "And " pr t) tl)
+ | [] -> anomaly "LetIn must declare at least one binding"
+
+let pr_rec_clause pr ((_,id),(l,t)) =
+ pr_id id ++ prlist pr_funvar l ++ str "->" ++ spc () ++ pr t
+
+let pr_rec_clauses pr l =
+ prlist_with_sep (fun () -> fnl () ++ str "And ") (pr_rec_clause pr) l
+
+let pr_hintbases = function
+ | None -> spc () ++ str "with *"
+ | Some [] -> mt ()
+ | Some l ->
+ spc () ++ str "with" ++ hv 0 (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_raw_generic prc prlc prtac prref x =
+ match Genarg.genarg_tag x with
+ | BoolArgType -> pr_arg str (if out_gen rawwit_bool x then "true" else "false")
+ | IntArgType -> pr_arg int (out_gen rawwit_int x)
+ | IntOrVarArgType -> pr_arg (pr_or_var pr_int) (out_gen rawwit_int_or_var x)
+ | StringArgType -> spc () ++ str "\"" ++ str (out_gen rawwit_string x) ++ str "\""
+ | PreIdentArgType -> pr_arg str (out_gen rawwit_pre_ident x)
+ | IntroPatternArgType -> pr_arg pr_intro_pattern
+ (out_gen rawwit_intro_pattern x)
+ | IdentArgType -> pr_arg pr_id ((*Constrextern.v7_to_v8_id*) (out_gen rawwit_ident x))
+ | HypArgType -> pr_arg
+ (pr_located (fun id -> pr_id (Constrextern.v7_to_v8_id id))) (out_gen rawwit_var x)
+ | RefArgType -> pr_arg prref (out_gen rawwit_ref x)
+ | SortArgType -> pr_arg pr_sort (out_gen rawwit_sort x)
+ | ConstrArgType -> pr_arg prc (out_gen rawwit_constr x)
+ | ConstrMayEvalArgType ->
+ pr_arg (pr_may_eval prc prref)
+ (out_gen rawwit_constr_may_eval x)
+ | QuantHypArgType ->
+ pr_arg pr_quantified_hypothesis (out_gen rawwit_quant_hyp x)
+ | RedExprArgType ->
+ pr_arg (pr_red_expr
+ (prc,prref)) (out_gen rawwit_red_expr x)
+ | TacticArgType -> pr_arg prtac (out_gen rawwit_tactic x)
+ | CastedOpenConstrArgType ->
+ pr_arg prc (out_gen rawwit_casted_open_constr x)
+ | ConstrWithBindingsArgType ->
+ pr_arg (pr_with_bindings prc prlc) (out_gen rawwit_constr_with_bindings x)
+ | BindingsArgType ->
+ pr_arg (pr_bindings_no_with prc prlc) (out_gen rawwit_bindings x)
+ | List0ArgType _ ->
+ hov 0 (fold_list0 (fun x a -> pr_raw_generic prc prlc prtac prref x ++ a) x (mt()))
+ | List1ArgType _ ->
+ hov 0 (fold_list1 (fun x a -> pr_raw_generic prc prlc prtac prref x ++ a) x (mt()))
+ | OptArgType _ -> hov 0 (fold_opt (pr_raw_generic prc prlc prtac prref) (mt()) x)
+ | PairArgType _ ->
+ hov 0
+ (fold_pair
+ (fun a b -> pr_raw_generic prc prlc prtac prref a ++ spc () ++
+ pr_raw_generic prc prlc prtac prref b)
+ x)
+ | ExtraArgType s ->
+ let tab =
+ if Options.do_translate() or not !Options.v7 then !genarg_pprule
+ else !genarg_pprule_v7 in
+ try pi1 (Stringmap.find s tab) prc prtac x
+ with Not_found -> str " [no printer for " ++ str s ++ str "] "
+
+
+let rec pr_glob_generic prc prlc prtac x =
+ match Genarg.genarg_tag x with
+ | BoolArgType -> pr_arg str (if out_gen globwit_bool x then "true" else "false")
+ | IntArgType -> pr_arg int (out_gen globwit_int x)
+ | IntOrVarArgType -> pr_arg (pr_or_var pr_int) (out_gen globwit_int_or_var x)
+ | StringArgType -> spc () ++ str "\"" ++ str (out_gen globwit_string x) ++ str "\""
+ | PreIdentArgType -> pr_arg str (out_gen globwit_pre_ident x)
+ | IntroPatternArgType ->
+ pr_arg pr_intro_pattern (out_gen globwit_intro_pattern x)
+ | IdentArgType -> pr_arg pr_id ((*Constrextern.v7_to_v8_id*) (out_gen globwit_ident x))
+ | HypArgType -> pr_arg (pr_located (fun id -> pr_id (Constrextern.v7_to_v8_id id))) (out_gen globwit_var x)
+ | RefArgType -> pr_arg (pr_or_var (pr_located pr_global)) (out_gen globwit_ref x)
+ | SortArgType -> pr_arg pr_sort (out_gen globwit_sort x)
+ | ConstrArgType -> pr_arg prc (out_gen globwit_constr x)
+ | ConstrMayEvalArgType ->
+ pr_arg (pr_may_eval prc
+ (pr_or_var (pr_and_short_name pr_evaluable_reference))) (out_gen globwit_constr_may_eval x)
+ | QuantHypArgType ->
+ pr_arg pr_quantified_hypothesis (out_gen globwit_quant_hyp x)
+ | RedExprArgType ->
+ pr_arg (pr_red_expr
+ (prc,pr_or_var (pr_and_short_name pr_evaluable_reference))) (out_gen globwit_red_expr x)
+ | TacticArgType -> pr_arg prtac (out_gen globwit_tactic x)
+ | CastedOpenConstrArgType ->
+ pr_arg prc (out_gen globwit_casted_open_constr x)
+ | ConstrWithBindingsArgType ->
+ pr_arg (pr_with_bindings prc prlc) (out_gen globwit_constr_with_bindings x)
+ | BindingsArgType ->
+ pr_arg (pr_bindings_no_with prc prlc) (out_gen globwit_bindings x)
+ | List0ArgType _ ->
+ hov 0 (fold_list0 (fun x a -> pr_glob_generic prc prlc prtac x ++ a) x (mt()))
+ | List1ArgType _ ->
+ hov 0 (fold_list1 (fun x a -> pr_glob_generic prc prlc prtac x ++ a) x (mt()))
+ | OptArgType _ -> hov 0 (fold_opt (pr_glob_generic prc prlc prtac) (mt()) x)
+ | PairArgType _ ->
+ hov 0
+ (fold_pair
+ (fun a b -> pr_glob_generic prc prlc prtac a ++ spc () ++
+ pr_glob_generic prc prlc prtac b)
+ x)
+ | ExtraArgType s ->
+ let tab =
+ if Options.do_translate() or not !Options.v7 then !genarg_pprule
+ else !genarg_pprule_v7 in
+ try pi2 (Stringmap.find s tab) prc prtac x
+ with Not_found -> str " [no printer for " ++ str s ++ str "] "
+
+open Closure
+
+let rec pr_generic prc prlc prtac x =
+ match Genarg.genarg_tag x with
+ | BoolArgType -> pr_arg str (if out_gen wit_bool x then "true" else "false")
+ | IntArgType -> pr_arg int (out_gen wit_int x)
+ | IntOrVarArgType -> pr_arg (pr_or_var pr_int) (out_gen wit_int_or_var x)
+ | StringArgType -> spc () ++ str "\"" ++ str (out_gen wit_string x) ++ str "\""
+ | PreIdentArgType -> pr_arg str (out_gen wit_pre_ident x)
+ | IntroPatternArgType ->
+ pr_arg pr_intro_pattern (out_gen wit_intro_pattern x)
+ | IdentArgType -> pr_arg pr_id (Constrextern.v7_to_v8_id (out_gen wit_ident x))
+ | HypArgType -> pr_arg prc (out_gen wit_var x)
+ | RefArgType -> pr_arg pr_global (out_gen wit_ref x)
+ | SortArgType -> pr_arg prc (Term.mkSort (out_gen wit_sort x))
+ | ConstrArgType -> pr_arg prc (out_gen wit_constr x)
+ | ConstrMayEvalArgType ->
+ pr_arg prc (out_gen wit_constr_may_eval x)
+ | QuantHypArgType ->
+ pr_arg pr_quantified_hypothesis (out_gen wit_quant_hyp x)
+ | RedExprArgType ->
+ pr_arg (pr_red_expr (prc,pr_evaluable_reference)) (out_gen wit_red_expr x)
+ | TacticArgType -> pr_arg prtac (out_gen wit_tactic x)
+ | CastedOpenConstrArgType ->
+ pr_arg prc (snd (out_gen wit_casted_open_constr x))
+ | ConstrWithBindingsArgType ->
+ pr_arg (pr_with_bindings prc prlc) (out_gen wit_constr_with_bindings x)
+ | BindingsArgType ->
+ pr_arg (pr_bindings_no_with prc prlc) (out_gen wit_bindings x)
+ | List0ArgType _ ->
+ hov 0 (fold_list0 (fun x a -> pr_generic prc prlc prtac x ++ a) x (mt()))
+ | List1ArgType _ ->
+ hov 0 (fold_list1 (fun x a -> pr_generic prc prlc prtac x ++ a) x (mt()))
+ | OptArgType _ -> hov 0 (fold_opt (pr_generic prc prlc prtac) (mt()) x)
+ | PairArgType _ ->
+ hov 0
+ (fold_pair
+ (fun a b -> pr_generic prc prlc prtac a ++ spc () ++
+ pr_generic prc prlc prtac b)
+ x)
+ | ExtraArgType s ->
+ let tab =
+ if Options.do_translate() or not !Options.v7 then !genarg_pprule
+ else !genarg_pprule_v7 in
+ try pi3 (Stringmap.find s tab) prc prtac x
+ with Not_found -> str " [no printer for " ++ str s ++ str "]"
+
+let rec pr_tacarg_using_rule pr_gen = function
+ | Some s :: l, al -> spc () ++ str s ++ pr_tacarg_using_rule pr_gen (l,al)
+ | None :: l, a :: al -> pr_gen a ++ pr_tacarg_using_rule pr_gen (l,al)
+ | [], [] -> mt ()
+ | _ -> failwith "Inconsistent arguments of extended tactic"
+
+let pr_extend_gen prgen s l =
+ let tab =
+ if Options.do_translate() or not !Options.v7 then prtac_tab
+ else prtac_tab_v7
+ in
+ try
+ let tags = List.map genarg_tag l in
+ (* 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
+ let (s,pl) = Hashtbl.find tab (s,tags) in
+ str s ++ pr_tacarg_using_rule prgen (pl,l)
+ with Not_found ->
+ str s ++ prlist prgen l ++ str " (* Generic printer *)"
+
+let make_pr_tac (pr_tac,pr_tac0,pr_constr,pr_pat,pr_cst,pr_ind,pr_ref,pr_ident,pr_extend) =
+
+let pr_bindings = pr_bindings pr_constr pr_constr in
+let pr_bindings_no_with = pr_bindings_no_with pr_constr pr_constr in
+let pr_with_bindings = pr_with_bindings pr_constr pr_constr in
+let pr_eliminator cb = str "using" ++ pr_arg (pr_with_bindings) cb in
+let pr_constrarg c = spc () ++ pr_constr c in
+let pr_intarg n = spc () ++ int n in
+
+ (* Printing tactics as arguments *)
+let rec pr_atom0 = 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 t ++ str ")"
+
+ (* Main tactic printer *)
+and pr_atom1 = function
+ | TacExtend (_,s,l) -> pr_extend pr_constr pr_constr pr_tac s l
+ | TacAlias (_,s,l,_) ->
+ pr_extend pr_constr pr_constr pr_tac s (List.map snd l)
+
+ (* Basic tactics *)
+ | TacIntroPattern [] as t -> pr_atom0 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 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_id id2)
+ | TacAssumption as t -> pr_atom0 t
+ | TacExact c -> hov 1 (str "Exact" ++ pr_arg pr_constr c)
+ | TacApply cb -> hov 1 (str "Apply" ++ spc () ++ pr_with_bindings cb)
+ | TacElim (cb,cbo) ->
+ hov 1 (str "Elim" ++ pr_arg pr_with_bindings cb ++
+ pr_opt pr_eliminator cbo)
+ | TacElimType c -> hov 1 (str "ElimType" ++ pr_arg pr_constr c)
+ | TacCase cb -> hov 1 (str "Case" ++ spc () ++ pr_with_bindings cb)
+ | TacCaseType c -> hov 1 (str "CaseType" ++ pr_arg pr_constr 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 () ++
+ hov 0 (str "with" ++ brk (1,1) ++
+ prlist_with_sep spc
+ (fun (id,n,c) ->
+ spc () ++ pr_id id ++ pr_intarg n ++ pr_arg pr_constr c)
+ l))
+ | TacCofix ido -> hov 1 (str "Cofix" ++ pr_opt pr_id ido)
+ | TacMutualCofix (id,l) ->
+ hov 1 (str "Cofix" ++ spc () ++ pr_id id ++ spc () ++
+ hov 0 (str "with" ++ brk (1,1) ++
+ prlist (fun (id,c) -> spc () ++ pr_id id ++ pr_arg pr_constr c)
+ l))
+ | TacCut c -> hov 1 (str "Cut" ++ pr_arg pr_constr c)
+ | TacTrueCut (Anonymous,c) ->
+ hov 1 (str "Assert" ++ pr_arg pr_constr c)
+ | TacTrueCut (Name id,c) ->
+ hov 1 (str "Assert" ++ spc () ++ pr_id id ++ str ":" ++ pr_constr c)
+ | TacForward (false,na,c) ->
+ hov 1 (str "Assert" ++ pr_arg pr_name na ++ str ":=" ++ pr_constr c)
+ | TacForward (true,na,c) ->
+ hov 1 (str "Pose" ++ pr_arg pr_name na ++ str ":=" ++ pr_constr c)
+ | TacGeneralize l ->
+ hov 1 (str "Generalize" ++ spc () ++ prlist_with_sep spc pr_constr l)
+ | TacGeneralizeDep c ->
+ hov 1 (str "Generalize" ++ spc () ++ str "Dependent" ++ spc () ++
+ pr_constr c)
+ | TacLetTac (na,c,cl) ->
+ let pcl = match cl with
+ {onhyps=None;onconcl=true;concl_occs=[]} -> mt()
+ | _ -> pr_clauses pr_ident cl in
+ hov 1 (str "LetTac" ++ spc () ++ pr_name na ++ str ":=" ++
+ pr_constr c ++ pcl)
+ | TacInstantiate (n,c,cls) ->
+ hov 1 (str "Instantiate" ++ pr_arg int n ++ pr_arg pr_constr c ++
+ pr_clauses pr_ident cls)
+ (* Derived basic tactics *)
+ | TacSimpleInduction (h,_) ->
+ hov 1 (str "Induction" ++ pr_arg pr_quantified_hypothesis h)
+ | TacNewInduction (h,e,(ids,_)) ->
+ hov 1 (str "NewInduction" ++ spc () ++ pr_induction_arg pr_constr h ++
+ pr_opt pr_eliminator e ++ pr_with_names ids)
+ | TacSimpleDestruct h ->
+ hov 1 (str "Destruct" ++ pr_arg pr_quantified_hypothesis h)
+ | TacNewDestruct (h,e,(ids,_)) ->
+ hov 1 (str "NewDestruct" ++ spc () ++ pr_induction_arg pr_constr h ++
+ pr_opt pr_eliminator e ++ pr_with_names ids)
+ | 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_arg pr_constr c)
+ | TacDecomposeOr c ->
+ hov 1 (str "Decompose Sum" ++ pr_arg pr_constr c)
+ | TacDecompose (l,c) ->
+ hov 1 (str "Decompose" ++ spc () ++
+ hov 0 (str "[" ++ prlist_with_sep spc pr_ind l
+ ++ str "]" ++ pr_arg pr_constr c))
+ | TacSpecialize (n,c) ->
+ hov 1 (str "Specialize" ++ pr_opt int n ++ pr_with_bindings c)
+ | TacLApply c ->
+ hov 1 (str "LApply" ++ pr_constr c)
+
+ (* Automation tactics *)
+ | TacTrivial (Some []) as x -> pr_atom0 x
+ | TacTrivial db -> hov 0 (str "Trivial" ++ pr_hintbases db)
+ | TacAuto (None,Some []) as x -> pr_atom0 x
+ | TacAuto (n,db) -> hov 0 (str "Auto" ++ pr_opt int n ++ pr_hintbases db)
+ | TacAutoTDB None as x -> pr_atom0 x
+ | TacAutoTDB (Some n) -> hov 0 (str "AutoTDB" ++ spc () ++ int n)
+ | TacDestructHyp (true,(_,id)) -> hov 0 (str "CDHyp" ++ spc () ++ pr_id id)
+ | TacDestructHyp (false,(_,id)) -> hov 0 (str "DHyp" ++ spc () ++ pr_id id)
+ | TacDestructConcl as x -> pr_atom0 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 l)
+ | TacRight l -> hov 1 (str "Right" ++ pr_bindings l)
+ | TacSplit (_,l) -> hov 1 (str "Split" ++ pr_bindings l)
+ | TacAnyConstructor (Some t) ->
+ hov 1 (str "Constructor" ++ pr_arg pr_tac0 t)
+ | TacAnyConstructor None as t -> pr_atom0 t
+ | TacConstructor (n,l) ->
+ hov 1 (str "Constructor" ++ pr_or_metaid pr_intarg n ++ pr_bindings l)
+
+ (* Conversion *)
+ | TacReduce (r,h) ->
+ hov 1 (pr_red_expr (pr_constr,pr_cst) r ++ pr_clauses pr_ident h)
+ | TacChange (occl,c,h) ->
+ hov 1 (str "Change" ++ pr_opt (pr_subterms pr_constr) occl ++
+ brk (1,1) ++ pr_constr c ++ pr_clauses pr_ident h)
+
+ (* Equivalence relations *)
+ | TacReflexivity as x -> pr_atom0 x
+ | TacSymmetry cls -> str "Symmetry " ++ pr_clauses pr_ident cls
+ | TacTransitivity c -> str "Transitivity" ++ pr_arg pr_constr c
+
+ (* Equality and inversion *)
+ | TacInversion (DepInversion (k,c,ids),hyp) ->
+ hov 1 (str "Dependent " ++ pr_induction_kind k ++
+ pr_quantified_hypothesis hyp ++
+ pr_with_names ids ++ pr_with_constr pr_constr 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 ++
+ str "using" ++ spc () ++ pr_constr c ++
+ pr_simple_clause pr_ident cl)
+
+and pr_tactic_seq_body tl =
+ hv 0 (str "[ " ++
+ prlist_with_sep (fun () -> spc () ++ str "| ") prtac tl ++ str " ]")
+
+ (* Strictly closed atomic tactic expressions *)
+and pr0 = function
+ | TacFirst tl -> str "First" ++ spc () ++ pr_tactic_seq_body tl
+ | TacSolve tl -> str "Solve" ++ spc () ++ pr_tactic_seq_body tl
+ | TacId "" -> str "Idtac"
+ | TacFail (ArgArg 0,"") -> str "Fail"
+ | TacAtom (_,t) -> pr_atom0 t
+ | TacArg c -> pr_tacarg c
+ | t -> str "(" ++ prtac t ++ str ")"
+
+ (* Semi-closed atomic tactic expressions *)
+and pr1 = function
+ | TacAtom (_,t) -> pr_atom1 t
+ | TacId s -> str "Idtac \"" ++ str s ++ str "\""
+ | TacFail (ArgArg 0,s) -> str "Fail \"" ++ str s ++ str "\""
+ | TacFail (n,"") -> str "Fail " ++ pr_or_var int n
+ | TacFail (n,s) -> str "Fail " ++ pr_or_var int n ++ str " \"" ++ str s ++ str "\""
+ | t -> pr0 t
+
+ (* Orelse tactic expressions (printed as if parsed associating on the right
+ though the semantics is purely associative) *)
+and pr2 = function
+ | TacOrelse (t1,t2) ->
+ hov 1 (pr1 t1 ++ str " Orelse" ++ brk (1,1) ++ pr3 t2)
+ | t -> pr1 t
+
+ (* Non closed prefix tactic expressions *)
+and pr3 = function
+ | TacTry t -> hov 1 (str "Try" ++ spc () ++ pr3 t)
+ | TacDo (n,t) -> hov 1 (str "Do " ++ pr_or_var int n ++ spc () ++ pr3 t)
+ | TacRepeat t -> hov 1 (str "Repeat" ++ spc () ++ pr3 t)
+ | TacProgress t -> hov 1 (str "Progress" ++ spc () ++ pr3 t)
+ | TacInfo t -> hov 1 (str "Info" ++ spc () ++ pr3 t)
+ | t -> pr2 t
+
+and pr4 = function
+ | t -> pr3 t
+
+ (* THEN and THENS tactic expressions (printed as if parsed
+ associating on the left though the semantics is purely associative) *)
+and pr5 = function
+ | TacThens (t,tl) ->
+ hov 1 (pr5 t ++ str ";" ++ spc () ++ pr_tactic_seq_body tl)
+ | TacThen (t1,t2) ->
+ hov 1 (pr5 t1 ++ str ";" ++ spc () ++ pr4 t2)
+ | t -> pr4 t
+
+ (* Ltac tactic expressions *)
+and pr6 = function
+ |(TacAtom _
+ | TacThen _
+ | TacThens _
+ | TacFirst _
+ | TacSolve _
+ | TacTry _
+ | TacOrelse _
+ | TacDo _
+ | TacRepeat _
+ | TacProgress _
+ | TacId _
+ | TacFail _
+ | TacInfo _) as t -> pr5 t
+
+ | TacAbstract (t,None) -> str "Abstract " ++ pr6 t
+ | TacAbstract (t,Some s) ->
+ hov 0
+ (str "Abstract " ++ pr6 t ++ spc () ++ str "using" ++ spc () ++ pr_id s)
+ | TacLetRecIn (l,t) ->
+ hv 0
+ (str "Rec " ++ pr_rec_clauses prtac l ++
+ spc () ++ str "In" ++ fnl () ++ prtac t)
+ | TacLetIn (llc,u) ->
+ v 0
+ (hv 0 (pr_let_clauses pr_tacarg0 llc ++ spc () ++ str "In") ++ fnl () ++ prtac u)
+ | TacMatch (t,lrul) ->
+ hov 0 (str "Match" ++ spc () ++ pr6 t ++ spc()
+ ++ str "With"
+ ++ prlist
+ (fun r -> fnl () ++ str "|" ++ spc () ++
+ pr_match_rule true pr_pat prtac r)
+ lrul)
+ | TacMatchContext (lr,lrul) ->
+ hov 0 (
+ str (if lr then "Match Reverse Context With" else "Match Context With")
+ ++ prlist
+ (fun r -> fnl () ++ str "|" ++ spc () ++
+ pr_match_rule false pr_pat prtac r)
+ lrul)
+ | TacFun (lvar,body) ->
+ hov 0 (str "Fun" ++
+ prlist pr_funvar lvar ++ spc () ++ str "->" ++ spc () ++ prtac body)
+
+ | TacArg c -> pr_tacarg c
+
+and pr_tacarg0 = function
+ | TacDynamic (_,t) -> str ("<dynamic ["^(Dyn.tag t)^"]>")
+ | MetaIdArg (_,s) -> str ("$" ^ s)
+ | IntroPattern ipat -> pr_intro_pattern ipat
+ | TacVoid -> str "()"
+ | Reference r -> pr_ref r
+ | ConstrMayEval (ConstrTerm c) -> str "'" ++ pr_constr c
+ | ConstrMayEval c -> pr_may_eval pr_constr pr_cst c
+ | Integer n -> int n
+ | TacFreshId sopt -> str "FreshId" ++ pr_opt qstring sopt
+ | (TacCall _ | Tacexp _) as t -> str "(" ++ pr_tacarg1 t ++ str ")"
+
+and pr_tacarg1 = function
+ | TacCall (_,f,l) ->
+ hov 0 (pr_ref f ++ spc () ++ prlist_with_sep spc pr_tacarg0 l)
+ | Tacexp t -> pr_tac t
+ | t -> pr_tacarg0 t
+
+and pr_tacarg x = pr_tacarg1 x
+
+and prtac x = pr6 x
+
+in (prtac,pr0,pr_match_rule false pr_pat pr_tac)
+
+let pr_raw_extend prc prlc prtac =
+ pr_extend_gen (pr_raw_generic prc prlc prtac Ppconstrnew.pr_reference)
+let pr_glob_extend prc prlc prtac =
+ pr_extend_gen (pr_glob_generic prc prlc prtac)
+let pr_extend prc prlc prtac =
+ pr_extend_gen (pr_generic prc prlc prtac)
+
+let pr_and_constr_expr pr (c,_) = pr c
+
+let rec glob_printers =
+ (pr_glob_tactic,
+ pr_glob_tactic0,
+ pr_and_constr_expr Printer.pr_rawterm,
+ Printer.pr_pattern,
+ pr_or_var (pr_and_short_name pr_evaluable_reference),
+ pr_or_var pr_inductive,
+ pr_or_var (pr_located pr_ltac_constant),
+ pr_located pr_id,
+ pr_glob_extend)
+
+and pr_glob_tactic (t:glob_tactic_expr) = pi1 (make_pr_tac glob_printers) t
+
+and pr_glob_tactic0 t = pi2 (make_pr_tac glob_printers) t
+
+and pr_glob_match_context t = pi3 (make_pr_tac glob_printers) t
+
+let (pr_tactic,_,_) =
+ make_pr_tac
+ (pr_glob_tactic,
+ pr_glob_tactic0,
+ Printer.prterm,
+ Printer.pr_pattern,
+ pr_evaluable_reference,
+ pr_inductive,
+ pr_ltac_constant,
+ pr_id,
+ pr_extend)