let _ = Mltop.add_known_module "coq-core.plugins.ltac"

# 13 "plugins/ltac/g_ltac.mlg"
 

open Util
open Pp
open Constrexpr
open Tacexpr
open Genarg
open Genredexpr
open Names
open Attributes

open Pcoq
open Pcoq.Prim
open Pcoq.Constr
open Pvernac.Vernac_
open Pltac

let fail_default_value = Locus.ArgArg 0

let arg_of_expr = function
    { CAst.v=(TacArg v) } -> v
  | e -> Tacexp (e:raw_tactic_expr)

let genarg_of_unit () = in_gen (rawwit Stdarg.wit_unit) ()
let genarg_of_int n = in_gen (rawwit Stdarg.wit_int) n
let genarg_of_ipattern pat = in_gen (rawwit Tacarg.wit_simple_intropattern) pat
let genarg_of_uconstr c = in_gen (rawwit Stdarg.wit_uconstr) c
let in_tac tac = in_gen (rawwit Tacarg.wit_ltac) tac

let reference_to_id qid =
  if Libnames.qualid_is_ident qid then
    CAst.make ?loc:qid.CAst.loc @@ Libnames.qualid_basename qid
  else
    CErrors.user_err ?loc:qid.CAst.loc
      (str "This expression should be a simple identifier.")

let tactic_mode = Entry.make "tactic_command"

let tacdef_body = Entry.make "tacdef_body"

(* Registers [tactic_mode] as a parser for proof editing *)
let classic_proof_mode = Pvernac.register_proof_mode "Classic" tactic_mode

(* Tactics grammar rules *)

let hint = G_proofs.hint

let for_extraargs = ()

let goal_selector = G_vernac.goal_selector
let toplevel_selector = G_vernac.toplevel_selector
let subprf = G_vernac.subprf
let subprf_with_selector = G_vernac.subprf_with_selector



let _ = let tactic_then_last = Pcoq.Entry.make "tactic_then_last"
        and for_each_goal = Pcoq.Entry.make "for_each_goal"
        and tactic_then_locality = Pcoq.Entry.make "tactic_then_locality"
        and failkw = Pcoq.Entry.make "failkw"
        and tactic_arg = Pcoq.Entry.make "tactic_arg"
        and fresh_id = Pcoq.Entry.make "fresh_id"
        and tactic_atom = Pcoq.Entry.make "tactic_atom"
        and match_key = Pcoq.Entry.make "match_key"
        and input_fun = Pcoq.Entry.make "input_fun"
        and let_clause = Pcoq.Entry.make "let_clause"
        and match_pattern = Pcoq.Entry.make "match_pattern"
        and match_hyp = Pcoq.Entry.make "match_hyp"
        and match_context_rule = Pcoq.Entry.make "match_context_rule"
        and match_context_list = Pcoq.Entry.make "match_context_list"
        and match_rule = Pcoq.Entry.make "match_rule"
        and match_list = Pcoq.Entry.make "match_list"
        and message_token = Pcoq.Entry.make "message_token"
        and ltac_def_kind = Pcoq.Entry.make "ltac_def_kind"
        in
        let () = assert (Pcoq.Entry.is_empty tactic_then_last) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:0")
        tactic_then_last
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make (Pcoq.Rule.stop)
                                  (fun loc -> 
# 77 "plugins/ltac/g_ltac.mlg"
             [||] 
                                              );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("|")))))
                                                 ((Pcoq.Symbol.list0sep ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm ltac_expr))) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                 (fun lta _ loc -> 
# 76 "plugins/ltac/g_ltac.mlg"
          Array.map (function None -> CAst.make ~loc (TacId []) | Some t -> t) (Array.of_list lta) 
                                                   )])]))
        in let () = assert (Pcoq.Entry.is_empty for_each_goal) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:1")
        for_each_goal
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make (Pcoq.Rule.stop)
                                  (fun loc -> 
# 86 "plugins/ltac/g_ltac.mlg"
             ([CAst.make ~loc (TacId [])], None) 
                                              );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("|")))))
                                                 ((Pcoq.Symbol.nterm for_each_goal)))
                                 (fun tg _ loc -> 
# 85 "plugins/ltac/g_ltac.mlg"
                                     let (first,last) = tg in (CAst.make ~loc (TacId []) :: first, last) 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun ta loc -> 
# 84 "plugins/ltac/g_ltac.mlg"
                            ([ta], None) 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("..")))))
                                                 ((Pcoq.Symbol.nterm tactic_then_last)))
                                 (fun l _ loc -> 
# 83 "plugins/ltac/g_ltac.mlg"
                                        ([], Some (CAst.make ~loc (TacId []), l)) 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("..")))))
                                                 ((Pcoq.Symbol.nterm tactic_then_last)))
                                 (fun l _ ta loc -> 
# 82 "plugins/ltac/g_ltac.mlg"
                                                        ([], Some (ta, l)) 
                                                    );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("|")))))
                                                 ((Pcoq.Symbol.nterm for_each_goal)))
                                 (fun tg _ ta loc -> 
# 81 "plugins/ltac/g_ltac.mlg"
                                                     let (first,last) = tg in (ta::first, last) 
                                                     )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic_then_locality)
        in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:2")
        tactic_then_locality
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                  ((Pcoq.Symbol.opt (Pcoq.Symbol.token (Tok.PKEYWORD (">"))))))
                                  (fun l _ loc -> 
# 91 "plugins/ltac/g_ltac.mlg"
                            if Option.is_empty l then true else false 
                                                  )])]))
        in let () = assert (Pcoq.Entry.is_empty ltac_expr) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:3")
        ltac_expr
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(Some ("5"), Some (Gramlib.Gramext.RightA),
                                 []);
                                (Some ("4"), Some (Gramlib.Gramext.LeftA),
                                [Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (";")))))
                                                                 ((Pcoq.Symbol.nterm tactic_then_locality)))
                                                                 ((Pcoq.Symbol.nterm for_each_goal)))
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                 (fun _ tg l _ ta0 loc -> 
# 98 "plugins/ltac/g_ltac.mlg"
                                                                                    
          let (first,tail) = tg in
          match l , tail with
          | false , Some (t,last) -> CAst.make ~loc (TacThen (ta0,
              CAst.make ~loc (TacExtendTac (Array.of_list first, t, last))))
          | true  , Some (t,last) -> CAst.make ~loc (TacThens3parts (ta0, Array.of_list first, t, last))
          | false , None -> CAst.make ~loc (TacThen (ta0, CAst.make ~loc (TacDispatch first)))
          | true  , None -> CAst.make ~loc (TacThens (ta0,first)) 
                                                          );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD (";")))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta1 _ ta0 loc -> 
# 97 "plugins/ltac/g_ltac.mlg"
                                                   CAst.make ~loc (TacThen (ta0,ta1)) 
                                                      )]);
                                (Some ("3"), Some (Gramlib.Gramext.RightA),
                                [Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("only"))))))
                                                                 ((Pcoq.Symbol.nterm goal_selector)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun ta _ sel _ loc -> 
# 119 "plugins/ltac/g_ltac.mlg"
                                                                    CAst.make ~loc (TacSelect (sel, ta)) 
                                                        );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("abstract"))))))
                                                                (Pcoq.Symbol.next))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("using")))))
                                                ((Pcoq.Symbol.nterm ident)))
                                (fun s _ tc _ loc -> 
# 118 "plugins/ltac/g_ltac.mlg"
          CAst.make ~loc (TacAbstract (tc,Some s)) 
                                                     );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("abstract"))))))
                                                (Pcoq.Symbol.next))
                                (fun tc _ loc -> 
# 116 "plugins/ltac/g_ltac.mlg"
                                         CAst.make ~loc (TacAbstract (tc,None)) 
                                                 );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("exactly_once"))))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta _ loc -> 
# 114 "plugins/ltac/g_ltac.mlg"
                                                  CAst.make ~loc (TacExactlyOnce ta) 
                                                 );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("once"))))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta _ loc -> 
# 113 "plugins/ltac/g_ltac.mlg"
                                          CAst.make ~loc (TacOnce  ta) 
                                                 );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("progress"))))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta _ loc -> 
# 112 "plugins/ltac/g_ltac.mlg"
                                              CAst.make ~loc (TacProgress ta) 
                                                 );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("repeat"))))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta _ loc -> 
# 111 "plugins/ltac/g_ltac.mlg"
                                            CAst.make ~loc (TacRepeat ta) 
                                                 );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("time"))))))
                                                                ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm string))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta s _ loc -> 
# 110 "plugins/ltac/g_ltac.mlg"
                                                          CAst.make ~loc (TacTime (s,ta)) 
                                                   );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("timeout"))))))
                                                                ((Pcoq.Symbol.nterm nat_or_var)))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta n _ loc -> 
# 109 "plugins/ltac/g_ltac.mlg"
                                                             CAst.make ~loc (TacTimeout (n,ta)) 
                                                   );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("do"))))))
                                                                ((Pcoq.Symbol.nterm nat_or_var)))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta n _ loc -> 
# 108 "plugins/ltac/g_ltac.mlg"
                                                        CAst.make ~loc (TacDo (n,ta)) 
                                                   );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("try"))))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta _ loc -> 
# 107 "plugins/ltac/g_ltac.mlg"
                                         CAst.make ~loc (TacTry ta) 
                                                 )]);
                                (Some ("2"), Some (Gramlib.Gramext.RightA),
                                [Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("||")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun ta1 _ ta0 loc -> 
# 126 "plugins/ltac/g_ltac.mlg"
                                                    CAst.make ~loc (TacOrelse (ta0,ta1)) 
                                                       );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("tryif"))))))
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("then")))))
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("else")))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun tae _ tat _ ta _ loc -> 
# 125 "plugins/ltac/g_ltac.mlg"
                                            CAst.make ~loc (TacIfThenCatch (ta,tat,tae)) 
                                                             );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("+")))))
                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                (fun ta1 _ ta0 loc -> 
# 122 "plugins/ltac/g_ltac.mlg"
                                                   CAst.make ~loc (TacOr (ta0,ta1)) 
                                                      )]);
                                (Some ("1"), Some (Gramlib.Gramext.RightA),
                                [Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm reference)))
                                                 ((Pcoq.Symbol.list0 (Pcoq.Symbol.nterm tactic_arg))))
                                 (fun la r loc -> 
# 150 "plugins/ltac/g_ltac.mlg"
          CAst.make ~loc @@ TacArg (TacCall (CAst.make ~loc (r,la))) 
                                                  );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                ((Pcoq.Symbol.nterm tactic_value)))
                                (fun a loc -> 
# 148 "plugins/ltac/g_ltac.mlg"
                              CAst.make ~loc (TacArg a) 
                                              );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                ((Pcoq.Symbol.nterm simple_tactic)))
                                (fun st loc -> 
# 147 "plugins/ltac/g_ltac.mlg"
                                st 
                                               );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm failkw)))
                                                                ((Pcoq.Symbol.rules 
                                                                [Pcoq.Rules.make 
                                                                (Pcoq.Rule.stop)
                                                                (fun loc -> 
                                                                
# 145 "plugins/ltac/g_ltac.mlg"
                                                       fail_default_value 
                                                                );
                                                                Pcoq.Rules.make 
                                                                (Pcoq.Rule.next_norec 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm nat_or_var)))
                                                                (fun n loc ->
                                                                
# 145 "plugins/ltac/g_ltac.mlg"
                                            n 
                                                                )])))
                                                ((Pcoq.Symbol.list0 (Pcoq.Symbol.nterm message_token))))
                                (fun l n g loc -> 
# 146 "plugins/ltac/g_ltac.mlg"
                                       CAst.make ~loc (TacFail (g,n,l)) 
                                                  );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("idtac"))))))
                                                ((Pcoq.Symbol.list0 (Pcoq.Symbol.nterm message_token))))
                                (fun l _ loc -> 
# 144 "plugins/ltac/g_ltac.mlg"
                                                    CAst.make ~loc (TacId l) 
                                                );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("solve"))))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                ((Pcoq.Symbol.list0sep ((Pcoq.Symbol.nterm ltac_expr)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                (fun _ l _ _ loc -> 
# 143 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacSolve l) 
                                                    );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("first"))))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                ((Pcoq.Symbol.list0sep ((Pcoq.Symbol.nterm ltac_expr)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                (fun _ l _ _ loc -> 
# 141 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacFirst l) 
                                                    );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm match_key)))
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("with")))))
                                                                ((Pcoq.Symbol.nterm match_list)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("end")))))
                                (fun _ mrl _ c b loc -> 
# 139 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacMatch (b,c,mrl)) 
                                                        );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm match_key)))
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("reverse"))))))
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("goal"))))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("with")))))
                                                                ((Pcoq.Symbol.nterm match_context_list)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("end")))))
                                (fun _ mrl _ _ _ b loc -> 
# 137 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacMatchGoal (b,true,mrl)) 
                                                          );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.nterm match_key)))
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("goal"))))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("with")))))
                                                                ((Pcoq.Symbol.nterm match_context_list)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("end")))))
                                (fun _ mrl _ _ b loc -> 
# 134 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacMatchGoal (b,false,mrl)) 
                                                        );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("let")))))
                                                                ((Pcoq.Symbol.rules 
                                                                [Pcoq.Rules.make 
                                                                (Pcoq.Rule.stop)
                                                                (fun loc -> 
                                                                
# 130 "plugins/ltac/g_ltac.mlg"
                                                       false 
                                                                );
                                                                Pcoq.Rules.make 
                                                                (Pcoq.Rule.next_norec 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("rec"))))))
                                                                (fun _ loc ->
                                                                
# 130 "plugins/ltac/g_ltac.mlg"
                                         true 
                                                                )])))
                                                                ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm let_clause)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("with"))])) false)))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("in")))))
                                                ((Pcoq.Symbol.nterml ltac_expr ("5"))))
                                (fun body _ llc isrec _ loc -> 
# 132 "plugins/ltac/g_ltac.mlg"
                                          CAst.make ~loc (TacLetIn (isrec,llc,body)) 
                                                               );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("fun")))))
                                                                ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm input_fun)))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                ((Pcoq.Symbol.nterml ltac_expr ("5"))))
                                (fun body _ it _ loc -> 
# 129 "plugins/ltac/g_ltac.mlg"
            CAst.make ~loc (TacFun (it,body)) 
                                                        )]);
                                (Some ("0"), None,
                                [Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm tactic_atom)))
                                 (fun a loc -> 
# 159 "plugins/ltac/g_ltac.mlg"
                             CAst.make ~loc (TacArg a) 
                                               );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD (">")))))
                                                                ((Pcoq.Symbol.nterm for_each_goal)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                (fun _ tg _ _ loc -> 
# 153 "plugins/ltac/g_ltac.mlg"
                                              
          let (tf,tail) = tg in
          begin match tail with
          | Some (t,tl) -> CAst.make ~loc (TacExtendTac (Array.of_list tf,t,tl))
          | None -> CAst.make ~loc (TacDispatch tf)
          end 
                                                     );
                                Pcoq.Production.make
                                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("(")))))
                                                                ((Pcoq.Symbol.nterm ltac_expr)))
                                                ((Pcoq.Symbol.token (Tok.PKEYWORD (")")))))
                                (fun _ a _ loc -> 
# 152 "plugins/ltac/g_ltac.mlg"
                                     a 
                                                  )])]))
        in let () = assert (Pcoq.Entry.is_empty failkw) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:4")
        failkw
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                  ("gfail"))))))
                                  (fun _ loc -> 
# 162 "plugins/ltac/g_ltac.mlg"
                                                        TacGlobal 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("fail"))))))
                                 (fun _ loc -> 
# 162 "plugins/ltac/g_ltac.mlg"
                        TacLocal 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic_arg) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:5")
        tactic_arg
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("()")))))
                                  (fun _ loc -> 
# 169 "plugins/ltac/g_ltac.mlg"
                  TacGeneric (None, genarg_of_unit ()) 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm Constr.constr)))
                                 (fun c loc -> 
# 167 "plugins/ltac/g_ltac.mlg"
                               (match c with { CAst.v = CRef (r,None) } -> Reference r | c -> ConstrMayEval (ConstrTerm c)) 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm tactic_value)))
                                 (fun a loc -> 
# 166 "plugins/ltac/g_ltac.mlg"
                              a 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic_value) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:6")
        tactic_value
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                  ("numgoals"))))))
                                  (fun _ loc -> 
# 176 "plugins/ltac/g_ltac.mlg"
                              TacNumgoals 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("type_term"))))))
                                                 ((Pcoq.Symbol.nterm uconstr)))
                                 (fun c _ loc -> 
# 175 "plugins/ltac/g_ltac.mlg"
                                          TacPretype c 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("fresh"))))))
                                                 ((Pcoq.Symbol.list0 (Pcoq.Symbol.nterm fresh_id))))
                                 (fun l _ loc -> 
# 174 "plugins/ltac/g_ltac.mlg"
                                               TacFreshId l 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm constr_eval)))
                                 (fun c loc -> 
# 173 "plugins/ltac/g_ltac.mlg"
                             ConstrMayEval c 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty fresh_id) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:7")
        fresh_id
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm qualid)))
                                  (fun qid loc -> 
# 183 "plugins/ltac/g_ltac.mlg"
                            Locus.ArgVar (CAst.make ~loc @@ Libnames.qualid_basename qid) 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PSTRING (None)))))
                                 (fun s loc -> 
# 182 "plugins/ltac/g_ltac.mlg"
                        Locus.ArgArg s (*| id = ident -> Locus.ArgVar (!@loc,id)*) 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty constr_eval) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:8")
        constr_eval
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                  ("type"))))))
                                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                  ("of"))))))
                                                  ((Pcoq.Symbol.nterm Constr.constr)))
                                  (fun c _ _ loc -> 
# 191 "plugins/ltac/g_ltac.mlg"
            ConstrTypeOf c 
                                                    );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("context"))))))
                                                                 ((Pcoq.Symbol.nterm identref)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                 ((Pcoq.Symbol.nterm Constr.lconstr)))
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                 (fun _ c _ id _ loc -> 
# 189 "plugins/ltac/g_ltac.mlg"
            ConstrContext (id,c) 
                                                        );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("eval"))))))
                                                                 ((Pcoq.Symbol.nterm red_expr)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("in")))))
                                                 ((Pcoq.Symbol.nterm Constr.constr)))
                                 (fun c _ rtc _ loc -> 
# 187 "plugins/ltac/g_ltac.mlg"
            ConstrEval (rtc,c) 
                                                       )])]))
        in let () = assert (Pcoq.Entry.is_empty constr_may_eval) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:9")
        constr_may_eval
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm Constr.constr)))
                                  (fun c loc -> 
# 195 "plugins/ltac/g_ltac.mlg"
                               ConstrTerm c 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm constr_eval)))
                                 (fun c loc -> 
# 194 "plugins/ltac/g_ltac.mlg"
                             c 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic_atom) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:10")
        tactic_atom
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("()")))))
                                  (fun _ loc -> 
# 200 "plugins/ltac/g_ltac.mlg"
                  TacGeneric (None, genarg_of_unit ()) 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm reference)))
                                 (fun r loc -> 
# 199 "plugins/ltac/g_ltac.mlg"
                           TacCall (CAst.make ~loc (r,[])) 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm integer)))
                                 (fun n loc -> 
# 198 "plugins/ltac/g_ltac.mlg"
                         TacGeneric (None, genarg_of_int n) 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty match_key) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:11")
        match_key
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                  ("multimatch"))))))
                                  (fun _ loc -> 
# 205 "plugins/ltac/g_ltac.mlg"
                                General 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("lazymatch"))))))
                                 (fun _ loc -> 
# 204 "plugins/ltac/g_ltac.mlg"
                               Select 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("match")))))
                                 (fun _ loc -> 
# 203 "plugins/ltac/g_ltac.mlg"
                     Once 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty input_fun) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:12")
        input_fun
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm ident)))
                                  (fun l loc -> 
# 209 "plugins/ltac/g_ltac.mlg"
                       Name.Name l 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("_")))))
                                 (fun _ loc -> 
# 208 "plugins/ltac/g_ltac.mlg"
                 Name.Anonymous 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty let_clause) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:13")
        let_clause
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm identref)))
                                                                  ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm input_fun)))))
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                                  ((Pcoq.Symbol.nterm ltac_expr)))
                                  (fun te _ args idr loc -> 
# 217 "plugins/ltac/g_ltac.mlg"
           (CAst.map (fun id -> Name id) idr, arg_of_expr (CAst.make ~loc (TacFun (args,te)))) 
                                                            );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.rules 
                                                                 [Pcoq.Rules.make 
                                                                 (Pcoq.Rule.next_norec 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("_")))))
                                                                 (fun _
                                                                 loc -> 
                                                                 
# 214 "plugins/ltac/g_ltac.mlg"
                       CAst.make ~loc Anonymous 
                                                                 )])))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun te _ na loc -> 
# 215 "plugins/ltac/g_ltac.mlg"
           (na, arg_of_expr te) 
                                                     );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm identref)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun te _ idr loc -> 
# 213 "plugins/ltac/g_ltac.mlg"
           (CAst.map (fun id -> Name id) idr, arg_of_expr te) 
                                                      )])]))
        in let () = assert (Pcoq.Entry.is_empty match_pattern) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:14")
        match_pattern
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm Constr.cpattern)))
                                  (fun pc loc -> 
# 223 "plugins/ltac/g_ltac.mlg"
                                  Term pc 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("context"))))))
                                                                 ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm Constr.ident))))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                 ((Pcoq.Symbol.nterm Constr.cpattern)))
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                 (fun _ pc _ oid _ loc -> 
# 222 "plugins/ltac/g_ltac.mlg"
          Subterm (oid, pc) 
                                                          )])]))
        in let () = assert (Pcoq.Entry.is_empty match_hyp) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:15")
        match_hyp
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm name)))
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                                  ((Pcoq.Symbol.nterm match_pattern)))
                                  (fun mpv _ na loc -> 
# 229 "plugins/ltac/g_ltac.mlg"
          let t, ty =
            match mpv with
            | Term t -> (match t with
              | { CAst.v = CCast (t, Some DEFAULTcast, ty) } -> Term t, Some (Term ty)
              | _ -> mpv, None)
            | _ -> mpv, None
          in Def (na, t, Option.default (Term (CAst.make @@ CHole (None))) ty) 
                                                       );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm name)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":")))))
                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                 (fun mpt _ _ mpv _ _ na loc -> 
# 227 "plugins/ltac/g_ltac.mlg"
                                                                                      Def (na, mpv, mpt) 
                                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm name)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":")))))
                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                 (fun mp _ na loc -> 
# 226 "plugins/ltac/g_ltac.mlg"
                                                 Hyp (na, mp) 
                                                     )])]))
        in let () = assert (Pcoq.Entry.is_empty match_context_rule)
        in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:16")
        match_context_rule
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("_")))))
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                  ((Pcoq.Symbol.nterm ltac_expr)))
                                  (fun te _ _ loc -> 
# 243 "plugins/ltac/g_ltac.mlg"
                                       All te 
                                                     );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                 ((Pcoq.Symbol.list0sep ((Pcoq.Symbol.nterm match_hyp)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD (","))])) false)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("|-")))))
                                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun te _ _ mp _ largs _ loc -> 
# 242 "plugins/ltac/g_ltac.mlg"
                                       Pat (largs, mp, te) 
                                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.list0sep ((Pcoq.Symbol.nterm match_hyp)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD (","))])) false)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("|-")))))
                                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun te _ mp _ largs loc -> 
# 240 "plugins/ltac/g_ltac.mlg"
                                  Pat (largs, mp, te) 
                                                             )])]))
        in let () = assert (Pcoq.Entry.is_empty match_context_list)
        in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:17")
        match_context_list
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("|")))))
                                                  ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm match_context_rule)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                  (fun mrl _ loc -> 
# 247 "plugins/ltac/g_ltac.mlg"
                                                         mrl 
                                                    );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm match_context_rule)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                 (fun mrl loc -> 
# 246 "plugins/ltac/g_ltac.mlg"
                                                    mrl 
                                                 )])]))
        in let () = assert (Pcoq.Entry.is_empty match_rule) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:18")
        match_rule
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("_")))))
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                  ((Pcoq.Symbol.nterm ltac_expr)))
                                  (fun te _ _ loc -> 
# 251 "plugins/ltac/g_ltac.mlg"
                                       All te 
                                                     );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm match_pattern)))
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun te _ mp loc -> 
# 250 "plugins/ltac/g_ltac.mlg"
                                                      Pat ([],mp,te) 
                                                     )])]))
        in let () = assert (Pcoq.Entry.is_empty match_list) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:19")
        match_list
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("|")))))
                                                  ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm match_rule)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                  (fun mrl _ loc -> 
# 255 "plugins/ltac/g_ltac.mlg"
                                                 mrl 
                                                    );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm match_rule)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD ("|"))])) false)))
                                 (fun mrl loc -> 
# 254 "plugins/ltac/g_ltac.mlg"
                                            mrl 
                                                 )])]))
        in let () = assert (Pcoq.Entry.is_empty message_token) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:20")
        message_token
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm natural)))
                                  (fun n loc -> 
# 260 "plugins/ltac/g_ltac.mlg"
                         MsgInt n 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PSTRING (None)))))
                                 (fun s loc -> 
# 259 "plugins/ltac/g_ltac.mlg"
                        MsgString s 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm identref)))
                                 (fun id loc -> 
# 258 "plugins/ltac/g_ltac.mlg"
                           MsgIdent id 
                                                )])]))
        in let () = assert (Pcoq.Entry.is_empty ltac_def_kind) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:21")
        ltac_def_kind
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PKEYWORD ("::=")))))
                                  (fun _ loc -> 
# 265 "plugins/ltac/g_ltac.mlg"
                   true 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD (":=")))))
                                 (fun _ loc -> 
# 264 "plugins/ltac/g_ltac.mlg"
                  false 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty tacdef_body) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:22")
        tacdef_body
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm Constr.global)))
                                                                  ((Pcoq.Symbol.nterm ltac_def_kind)))
                                                  ((Pcoq.Symbol.nterm ltac_expr)))
                                  (fun body redef name loc -> 
# 278 "plugins/ltac/g_ltac.mlg"
          if redef then Tacexpr.TacticRedefinition (name, body)
          else
            let id = reference_to_id name in
            Tacexpr.TacticDefinition (id, body) 
                                                              );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm Constr.global)))
                                                                 ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm input_fun)))))
                                                                 ((Pcoq.Symbol.nterm ltac_def_kind)))
                                                 ((Pcoq.Symbol.nterm ltac_expr)))
                                 (fun body redef it name loc -> 
# 272 "plugins/ltac/g_ltac.mlg"
          if redef then Tacexpr.TacticRedefinition (name, CAst.make ~loc (TacFun (it, body)))
          else
            let id = reference_to_id name in
            Tacexpr.TacticDefinition (id, CAst.make ~loc (TacFun (it, body))) 
                                                                )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:23")
        tactic
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm ltac_expr)))
                                  (fun tac loc -> 
# 285 "plugins/ltac/g_ltac.mlg"
                             tac 
                                                  )])]))
        in let () = assert (Pcoq.Entry.is_empty tactic_mode) in
        let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:24")
        tactic_mode
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm toplevel_selector))))
                                                  ((Pcoq.Symbol.nterm subprf_with_selector)))
                                  (fun p g loc -> 
# 289 "plugins/ltac/g_ltac.mlg"
                                                                 Vernacexpr.VernacSynPure (p g) 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm subprf)))
                                 (fun p loc -> 
# 288 "plugins/ltac/g_ltac.mlg"
                        Vernacexpr.VernacSynPure p 
                                               )])]))
        in let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:25")
        command
        (Pcoq.Reuse (None, [Pcoq.Production.make
                            (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                            (Pcoq.Rule.next 
                                                            (Pcoq.Rule.next 
                                                            (Pcoq.Rule.stop)
                                                            ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                            ("Proof"))))))
                                                            ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                            ("using"))))))
                                                            ((Pcoq.Symbol.nterm G_vernac.section_subset_expr)))
                                                            ((Pcoq.Symbol.token (Tok.PKEYWORD ("with")))))
                                            ((Pcoq.Symbol.nterm Pltac.tactic)))
                            (fun ta _ l _ _ loc -> 
# 298 "plugins/ltac/g_ltac.mlg"
            Vernacexpr.VernacSynPure (Vernacexpr.VernacProof (Some (in_tac ta),Some l)) 
                                                   );
                           Pcoq.Production.make
                           (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                           (Pcoq.Rule.next 
                                                           (Pcoq.Rule.stop)
                                                           ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                           ("Proof"))))))
                                                           ((Pcoq.Symbol.token (Tok.PKEYWORD ("with")))))
                                                           ((Pcoq.Symbol.nterm Pltac.tactic)))
                                           ((Pcoq.Symbol.opt (Pcoq.Symbol.rules 
                                           [Pcoq.Rules.make (Pcoq.Rule.next_norec 
                                                            (Pcoq.Rule.next_norec 
                                                            (Pcoq.Rule.stop)
                                                            ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                            ("using"))))))
                                                            ((Pcoq.Symbol.nterm G_vernac.section_subset_expr)))
                                                            (fun l _ loc -> 
                                                            
# 294 "plugins/ltac/g_ltac.mlg"
                                                                       l 
                                                            )]))))
                           (fun l ta _ _ loc -> 
# 295 "plugins/ltac/g_ltac.mlg"
            Vernacexpr.VernacSynPure (Vernacexpr.VernacProof (Some (in_tac ta), l)) 
                                                )]))
        in let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:26")
        hint
        (Pcoq.Reuse (None, [Pcoq.Production.make
                            (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                            (Pcoq.Rule.next 
                                                            (Pcoq.Rule.next 
                                                            (Pcoq.Rule.stop)
                                                            ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                            ("Extern"))))))
                                                            ((Pcoq.Symbol.nterm natural)))
                                                            ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm Constr.constr_pattern))))
                                                            ((Pcoq.Symbol.token (Tok.PKEYWORD ("=>")))))
                                            ((Pcoq.Symbol.nterm Pltac.tactic)))
                            (fun tac _ c n _ loc -> 
# 303 "plugins/ltac/g_ltac.mlg"
          Vernacexpr.HintsExtern (n,c, in_tac tac) 
                                                    )]))
        in let () =
        Egramml.grammar_extend ~plugin_uid:("coq-core.plugins.ltac", "g_ltac.mlg:27")
        term
        (Pcoq.Reuse (Some
        ("0"), [Pcoq.Production.make
                (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                (Pcoq.Rule.next 
                                                                (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                ("ltac"))))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD (":")))))
                                                                ((Pcoq.Symbol.token (Tok.PKEYWORD ("(")))))
                                                ((Pcoq.Symbol.nterm Pltac.ltac_expr)))
                                ((Pcoq.Symbol.token (Tok.PKEYWORD (")")))))
                (fun _ tac _ _ _ loc -> 
# 307 "plugins/ltac/g_ltac.mlg"
          let arg = Genarg.in_gen (Genarg.rawwit Tacarg.wit_tactic) tac in
          CAst.make ~loc @@ CGenarg arg 
                                        )]))
        in ()


# 312 "plugins/ltac/g_ltac.mlg"
 

open Stdarg
open Tacarg
open Vernacextend
open Libnames

let pr_ltac_selector s = Pp.(Goal_select.pr_goal_selector s ++ str ":")



let (wit_ltac_selector, ltac_selector) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_selector" 
                                         {
                                         Vernacextend.arg_parsing = Vernacextend.Arg_alias (toplevel_selector);
                                         Vernacextend.arg_printer = fun env sigma -> 
                                         
# 323 "plugins/ltac/g_ltac.mlg"
                                                  pr_ltac_selector 
                                         ;
                                         }
let _ = (wit_ltac_selector, ltac_selector)


# 327 "plugins/ltac/g_ltac.mlg"
 

let pr_ltac_info n = str "Info" ++ spc () ++ int n



let (wit_ltac_info, ltac_info) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_info" 
                                 {
                                 Vernacextend.arg_parsing = Vernacextend.Arg_rules (
                                                            [(Pcoq.Production.make
                                                              (Pcoq.Rule.next 
                                                              (Pcoq.Rule.next 
                                                              (Pcoq.Rule.stop)
                                                              ((Pcoq.Symbol.token (Pcoq.terminal "Info"))))
                                                              ((Pcoq.Symbol.nterm natural)))
                                                              (fun n _ loc ->
                                                              
# 334 "plugins/ltac/g_ltac.mlg"
                             n 
                                                              ))]);
                                 Vernacextend.arg_printer = fun env sigma -> 
                                 
# 333 "plugins/ltac/g_ltac.mlg"
                                              pr_ltac_info 
                                 ;
                                 }
let _ = (wit_ltac_info, ltac_info)


# 337 "plugins/ltac/g_ltac.mlg"
 

let pr_ltac_use_default b =
  if b then (* Bug: a space is inserted before "..." *) str ".." else mt ()



let (wit_ltac_use_default, ltac_use_default) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_use_default" 
                                               {
                                               Vernacextend.arg_parsing = 
                                               Vernacextend.Arg_rules (
                                               [(Pcoq.Production.make
                                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Pcoq.terminal "..."))))
                                                 (fun _ loc -> 
# 346 "plugins/ltac/g_ltac.mlg"
                 true 
                                                               ));
                                               (Pcoq.Production.make
                                                (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                ((Pcoq.Symbol.token (Pcoq.terminal "."))))
                                                (fun _ loc -> 
# 345 "plugins/ltac/g_ltac.mlg"
               false 
                                                              ))]);
                                               Vernacextend.arg_printer = fun env sigma -> 
                                               
# 344 "plugins/ltac/g_ltac.mlg"
                                                     pr_ltac_use_default 
                                               ;
                                               }
let _ = (wit_ltac_use_default, ltac_use_default)


# 349 "plugins/ltac/g_ltac.mlg"
 

let rm_abstract tac =
  let (loc, tac2) = CAst.(tac.loc, tac.v) in
  match tac2 with
  | TacAbstract (t,_) -> t, true
  | TacSolve [ {CAst.loc; v=TacAbstract(t,_)} ] -> CAst.make ?loc (TacSolve [t]), true
  | _ -> tac, false

let is_explicit_terminator = function
  | {CAst.v=(TacSolve _)} -> true
  | _ -> false



let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacSolve"  ?entry:(Some ( tactic_mode )) 
         [(Vernacextend.TyML (false, Vernacextend.TyNonTerminal (Extend.TUopt (
                                                                 Extend.TUentry (Genarg.get_arg_tag wit_ltac_selector)), 
                                     Vernacextend.TyNonTerminal (Extend.TUopt (
                                                                 Extend.TUentry (Genarg.get_arg_tag wit_ltac_info)), 
                                     Vernacextend.TyNonTerminal (Extend.TUentry (Genarg.get_arg_tag wit_tactic), 
                                     Vernacextend.TyNonTerminal (Extend.TUentry (Genarg.get_arg_tag wit_ltac_use_default), 
                                     Vernacextend.TyNil)))), (let coqpp_body g
                                                             info t
                                                             with_end_tac
                                                             () = Vernactypes.vtmodifyproof (fun ~pstate -> (
                                                                  
# 366 "plugins/ltac/g_ltac.mlg"
                                  
    let g = Option.default (Goal_select.get_default_goal_selector ()) g in
    let global = match g with Goal_select.SelectAll | Goal_select.SelectList _ -> true | _ -> false in
    let t = Tacinterp.hide_interp { Tacinterp.global; ast = t; } in
    ComTactic.solve g ~info t ~with_end_tac
  
                                                                  ) ~pstate) in fun g
                                                             info t
                                                             with_end_tac
                                                             ?loc ~atts ()
                                                             -> coqpp_body g
                                                             info t
                                                             with_end_tac
                                                             (Attributes.unsupported_attributes atts)), Some 
         (fun g info t with_end_tac -> 
# 366 "plugins/ltac/g_ltac.mlg"
      classify_as_proofstep 
         )))]

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacSolveParallel"  ?entry:(Some ( tactic_mode )) 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("par", 
                                     Vernacextend.TyTerminal (":", Vernacextend.TyNonTerminal (
                                                                   Extend.TUopt (
                                                                   Extend.TUentry (Genarg.get_arg_tag wit_ltac_info)), 
                                                                   Vernacextend.TyNonTerminal (
                                                                   Extend.TUentry (Genarg.get_arg_tag wit_tactic), 
                                                                   Vernacextend.TyNonTerminal (
                                                                   Extend.TUentry (Genarg.get_arg_tag wit_ltac_use_default), 
                                                                   Vernacextend.TyNil))))), 
         (let coqpp_body info t with_end_tac
         () = Vernactypes.vtmodifyproof (fun ~pstate -> (
# 380 "plugins/ltac/g_ltac.mlg"
          
      let t, abstract = rm_abstract t in
      let t = Tacinterp.hide_interp { Tacinterp.global = true; ast = t; } in
      ComTactic.solve_parallel ~info t ~abstract ~with_end_tac
    
              ) ~pstate) in fun info
         t with_end_tac ?loc ~atts () -> coqpp_body info t with_end_tac
         (Attributes.unsupported_attributes atts)), Some (fun info t
                                                         with_end_tac -> 
                                                         
# 376 "plugins/ltac/g_ltac.mlg"
     
      let solving_tac = is_explicit_terminator t in
      let pbr = if solving_tac then Some "par" else None in
      VtProofStep{ proof_block_detection = pbr }
    
                                                         )))]


# 387 "plugins/ltac/g_ltac.mlg"
 

let pr_ltac_tactic_level n = str "(at level " ++ int n ++ str ")"



let (wit_ltac_tactic_level, ltac_tactic_level) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_tactic_level" 
                                                 {
                                                 Vernacextend.arg_parsing = 
                                                 Vernacextend.Arg_rules (
                                                 [(Pcoq.Production.make
                                                   (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                   (Pcoq.Rule.next 
                                                                   (Pcoq.Rule.next 
                                                                   (Pcoq.Rule.next 
                                                                   (Pcoq.Rule.stop)
                                                                   ((Pcoq.Symbol.token (Pcoq.terminal "("))))
                                                                   ((Pcoq.Symbol.token (Pcoq.terminal "at"))))
                                                                   ((Pcoq.Symbol.token (Pcoq.terminal "level"))))
                                                                   ((Pcoq.Symbol.nterm natural)))
                                                                   ((Pcoq.Symbol.token (Pcoq.terminal ")"))))
                                                   (fun _ n _ _ _ loc -> 
# 394 "plugins/ltac/g_ltac.mlg"
                                           n 
                                                                    ))]);
                                                 Vernacextend.arg_printer = fun env sigma -> 
                                                 
# 393 "plugins/ltac/g_ltac.mlg"
                                                      pr_ltac_tactic_level 
                                                 ;
                                                 }
let _ = (wit_ltac_tactic_level, ltac_tactic_level)

let (wit_ltac_production_sep, ltac_production_sep) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_production_sep" 
                                                     {
                                                     Vernacextend.arg_parsing = 
                                                     Vernacextend.Arg_rules (
                                                     [(Pcoq.Production.make
                                                       (Pcoq.Rule.next 
                                                       (Pcoq.Rule.next 
                                                       (Pcoq.Rule.stop)
                                                       ((Pcoq.Symbol.token (Pcoq.terminal ","))))
                                                       ((Pcoq.Symbol.nterm string)))
                                                       (fun sep _ loc -> 
# 398 "plugins/ltac/g_ltac.mlg"
                           sep 
                                                                    ))]);
                                                     Vernacextend.arg_printer = fun env sigma -> 
                                                     fun _ -> Pp.str "missing printer";
                                                     }
let _ = (wit_ltac_production_sep, ltac_production_sep)


# 401 "plugins/ltac/g_ltac.mlg"
 

let pr_ltac_production_item = function
| Tacentries.TacTerm s -> quote (str s)
| Tacentries.TacNonTerm (_, ((arg, None), None)) -> str arg
| Tacentries.TacNonTerm (_, ((arg, Some _), None)) -> assert false
| Tacentries.TacNonTerm (_, ((arg, sep), Some id)) ->
  let sep = match sep with
  | None -> mt ()
  | Some sep -> str "," ++ spc () ++ quote (str sep)
  in
  str arg ++ str "(" ++ Id.print id ++ sep ++ str ")"

let check_non_empty_string ?loc s =
  if String.is_empty s then CErrors.user_err ?loc (str "Invalid empty string.")



let (wit_ltac_production_item, ltac_production_item) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_production_item" 
                                                       {
                                                       Vernacextend.arg_parsing = 
                                                       Vernacextend.Arg_rules (
                                                       [(Pcoq.Production.make
                                                         (Pcoq.Rule.next 
                                                         (Pcoq.Rule.stop)
                                                         ((Pcoq.Symbol.nterm ident)))
                                                         (fun nt loc -> 
# 424 "plugins/ltac/g_ltac.mlg"
    Tacentries.TacNonTerm (Loc.tag ~loc ((Id.to_string nt, None), None)) 
                                                                    ));
                                                       (Pcoq.Production.make
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.stop)
                                                        ((Pcoq.Symbol.nterm ident)))
                                                        ((Pcoq.Symbol.token (Pcoq.terminal "("))))
                                                        ((Pcoq.Symbol.nterm ident)))
                                                        ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm ltac_production_sep))))
                                                        ((Pcoq.Symbol.token (Pcoq.terminal ")"))))
                                                        (fun _ sep p _ nt
                                                        loc -> 
# 422 "plugins/ltac/g_ltac.mlg"
    Tacentries.TacNonTerm (Loc.tag ~loc ((Id.to_string nt, sep), Some p)) 
                                                               ));
                                                       (Pcoq.Production.make
                                                        (Pcoq.Rule.next 
                                                        (Pcoq.Rule.stop)
                                                        ((Pcoq.Symbol.nterm string)))
                                                        (fun s loc -> 
# 420 "plugins/ltac/g_ltac.mlg"
                     check_non_empty_string ~loc s; Tacentries.TacTerm s 
                                                                    ))]);
                                                       Vernacextend.arg_printer = fun env sigma -> 
                                                       
# 419 "plugins/ltac/g_ltac.mlg"
                                                         pr_ltac_production_item 
                                                       ;
                                                       }
let _ = (wit_ltac_production_item, ltac_production_item)

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacTacticNotation"  ?entry:None 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("Tactic", 
                                     Vernacextend.TyTerminal ("Notation", 
                                     Vernacextend.TyNonTerminal (Extend.TUopt (
                                                                 Extend.TUentry (Genarg.get_arg_tag wit_ltac_tactic_level)), 
                                     Vernacextend.TyNonTerminal (Extend.TUlist1 (
                                                                 Extend.TUentry (Genarg.get_arg_tag wit_ltac_production_item)), 
                                     Vernacextend.TyTerminal (":=", Vernacextend.TyNonTerminal (
                                                                    Extend.TUentry (Genarg.get_arg_tag wit_tactic), 
                                                                    Vernacextend.TyNil)))))), 
         (let coqpp_body n r e
         (deprecation, locality) = (let tacobj = 
# 430 "plugins/ltac/g_ltac.mlg"
                                              
    let n = Option.default 0 n in
    let local = Locality.make_module_locality locality in
    Tacentries.add_tactic_notation_syntax local n ?deprecation r
  
                                    in Vernactypes.vtdefault (fun () -> 
                                   
# 435 "plugins/ltac/g_ltac.mlg"
   
    Tacentries.add_tactic_notation ?deprecation tacobj e
  
                                   )) in fun n
         r e ?loc ~atts () -> coqpp_body n r e
         (Attributes.parse Attributes.Notations.(
# 428 "plugins/ltac/g_ltac.mlg"
      deprecation
          ++ 
# 428 "plugins/ltac/g_ltac.mlg"
                   locality
         ) atts)), Some (fun n r e -> 
# 430 "plugins/ltac/g_ltac.mlg"
    VtSideff ([], VtNow) 
                        )))]

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacPrintLtac" ~classifier:(fun _ -> Vernacextend.classify_as_query) ?entry:None 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("Print", 
                                     Vernacextend.TyTerminal ("Ltac", 
                                     Vernacextend.TyNonTerminal (Extend.TUentry (Genarg.get_arg_tag wit_reference), 
                                     Vernacextend.TyNil))), (let coqpp_body r
                                                            () = Vernactypes.vtdefault (fun () -> 
                                                                 
# 442 "plugins/ltac/g_ltac.mlg"
    Feedback.msg_notice (Tacentries.print_ltac r) 
                                                                 ) in fun r
                                                            ?loc ~atts ()
                                                            -> coqpp_body r
                                                            (Attributes.unsupported_attributes atts)), None))]

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacLocateLtac" ~classifier:(fun _ -> Vernacextend.classify_as_query) ?entry:None 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("Locate", 
                                     Vernacextend.TyTerminal ("Ltac", 
                                     Vernacextend.TyNonTerminal (Extend.TUentry (Genarg.get_arg_tag wit_reference), 
                                     Vernacextend.TyNil))), (let coqpp_body r
                                                            () = Vernactypes.vtdefault (fun () -> 
                                                                 
# 447 "plugins/ltac/g_ltac.mlg"
    Tacentries.print_located_tactic r 
                                                                 ) in fun r
                                                            ?loc ~atts ()
                                                            -> coqpp_body r
                                                            (Attributes.unsupported_attributes atts)), None))]


# 450 "plugins/ltac/g_ltac.mlg"
 

let pr_ltac_ref = Libnames.pr_qualid

let pr_tacdef_body env sigma tacdef_body =
  let id, redef, body =
    match tacdef_body with
    | TacticDefinition ({CAst.v=id}, body) -> Id.print id, false, body
    | TacticRedefinition (id, body) -> pr_ltac_ref id, true, body
  in
  let idl, body =
    match body with
      | {CAst.v=(Tacexpr.TacFun (idl,b))} -> idl,b
      | _ -> [], body in
  id ++
    prlist (function Name.Anonymous -> str " _"
      | Name.Name id -> spc () ++ Id.print id) idl
  ++ (if redef then str" ::=" else str" :=") ++ brk(1,1)
  ++ Pptactic.pr_raw_tactic env sigma body



let (wit_ltac_tacdef_body, ltac_tacdef_body) = Vernacextend.vernac_argument_extend ~plugin:"coq-core.plugins.ltac" ~name:"ltac_tacdef_body" 
                                               {
                                               Vernacextend.arg_parsing = 
                                               Vernacextend.Arg_alias (tacdef_body);
                                               Vernacextend.arg_printer = fun env sigma -> 
                                               
# 473 "plugins/ltac/g_ltac.mlg"
             pr_tacdef_body env sigma 
                                               ;
                                               }
let _ = (wit_ltac_tacdef_body, ltac_tacdef_body)

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacDeclareTacticDefinition"  ?entry:None 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("Ltac", 
                                     Vernacextend.TyNonTerminal (Extend.TUlist1sep (
                                                                 Extend.TUentry (Genarg.get_arg_tag wit_ltac_tacdef_body), "with"), 
                                     Vernacextend.TyNil)), (let coqpp_body l
                                                           (deprecation, locality) = 
                                                           Vernactypes.vtdefault (fun () -> 
                                                           
# 482 "plugins/ltac/g_ltac.mlg"
        
         Tacentries.register_ltac (Locality.make_module_locality locality) ?deprecation l;
  
                                                           ) in fun l
                                                           ?loc ~atts ()
                                                           -> coqpp_body l
                                                           (Attributes.parse Attributes.Notations.(
                                                           
# 478 "plugins/ltac/g_ltac.mlg"
      deprecation
                                                            ++ 
# 478 "plugins/ltac/g_ltac.mlg"
                   locality
                                                           ) atts)), Some 
         (fun l -> 
# 478 "plugins/ltac/g_ltac.mlg"
                                                                                     
    VtSideff (List.map (function
      | TacticDefinition ({CAst.v=r},_) -> r
      | TacticRedefinition (qid,_) -> qualid_basename qid) l, VtLater)
  
         )))]

let () = Vernacextend.static_vernac_extend ~plugin:(Some "coq-core.plugins.ltac") ~command:"VernacPrintLtacs" ~classifier:(fun _ -> Vernacextend.classify_as_query) ?entry:None 
         [(Vernacextend.TyML (false, Vernacextend.TyTerminal ("Print", 
                                     Vernacextend.TyTerminal ("Ltac", 
                                     Vernacextend.TyTerminal ("Signatures", 
                                     Vernacextend.TyNil))), (let coqpp_body () = 
                                                            Vernactypes.vtdefault (fun () -> 
                                                            
# 488 "plugins/ltac/g_ltac.mlg"
                                       Tacentries.print_ltacs () 
                                                            ) in fun ?loc ~atts ()
                                                            -> coqpp_body (Attributes.unsupported_attributes atts)), None))]

