
# 13 "vernac/g_redexpr.mlg"
 
open Pcoq
open Pcoq.Prim
open Pcoq.Constr
open Pvernac.Vernac_

open Util
open Locus
open Genredexpr

let all_with ~head delta =
  let all = [FBeta;FMatch;FFix;FCofix;FZeta;delta] in
  Redops.make_red_flag (if head then FHead :: all else all)

let int_or_var = Entry.make "int_or_var"
let nat_or_var = Entry.make "nat_or_var"
let pattern_occ = Entry.make "pattern_occ"
let unfold_occ = Entry.make "unfold_occ"
let ref_or_pattern_occ = Entry.make "ref_or_pattern_occ"
let occs_nums = Entry.make "occs_nums"
let occs = Entry.make "occs"
let delta_flag = Entry.make "delta_flag"
let strategy_flag = Entry.make "strategy_flag"


let _ = let red_flag = Pcoq.Entry.make "red_flag"
        in
        let () = assert (Pcoq.Entry.is_empty int_or_var) in
        let () =
        Pcoq.grammar_extend int_or_var
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm identref)))
                                  (fun id loc -> 
# 45 "vernac/g_redexpr.mlg"
                           ArgVar id 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm integer)))
                                 (fun n loc -> 
# 44 "vernac/g_redexpr.mlg"
                          ArgArg n 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty nat_or_var) in
        let () =
        Pcoq.grammar_extend nat_or_var
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.nterm identref)))
                                  (fun id loc -> 
# 49 "vernac/g_redexpr.mlg"
                           ArgVar id 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.nterm natural)))
                                 (fun n loc -> 
# 48 "vernac/g_redexpr.mlg"
                          ArgArg n 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty occs_nums) in
        let () =
        Pcoq.grammar_extend occs_nums
        (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.list1 ((Pcoq.Symbol.nterm nat_or_var)))))
                                  (fun nl _ loc -> 
# 54 "vernac/g_redexpr.mlg"
                                        AllOccurrencesBut nl 
                                                   );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm nat_or_var)))))
                                 (fun nl loc -> 
# 53 "vernac/g_redexpr.mlg"
                                   OnlyOccurrences nl 
                                                )])]))
        in let () = assert (Pcoq.Entry.is_empty occs) in
        let () =
        Pcoq.grammar_extend occs
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make (Pcoq.Rule.stop)
                                  (fun loc -> 
# 57 "vernac/g_redexpr.mlg"
                                                  AllOccurrences 
                                              );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("at")))))
                                                 ((Pcoq.Symbol.nterm occs_nums)))
                                 (fun occs _ loc -> 
# 57 "vernac/g_redexpr.mlg"
                                    occs 
                                                    )])]))
        in let () = assert (Pcoq.Entry.is_empty pattern_occ) in
        let () =
        Pcoq.grammar_extend pattern_occ
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm constr)))
                                                  ((Pcoq.Symbol.nterm occs)))
                                  (fun nl c loc -> 
# 60 "vernac/g_redexpr.mlg"
                                   (nl,c) 
                                                   )])]))
        in let () = assert (Pcoq.Entry.is_empty ref_or_pattern_occ)
        in
        let () =
        Pcoq.grammar_extend ref_or_pattern_occ
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm constr)))
                                                  ((Pcoq.Symbol.nterm occs)))
                                  (fun nl c loc -> 
# 66 "vernac/g_redexpr.mlg"
                                   nl,Inr c 
                                                   );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.nterm smart_global)))
                                                 ((Pcoq.Symbol.nterm occs)))
                                 (fun nl c loc -> 
# 65 "vernac/g_redexpr.mlg"
                                         nl,Inl c 
                                                  )])]))
        in let () = assert (Pcoq.Entry.is_empty unfold_occ) in
        let () =
        Pcoq.grammar_extend unfold_occ
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.nterm smart_global)))
                                                  ((Pcoq.Symbol.nterm occs)))
                                  (fun nl c loc -> 
# 69 "vernac/g_redexpr.mlg"
                                         (nl,c) 
                                                   )])]))
        in let () = assert (Pcoq.Entry.is_empty red_flag) in
        let () =
        Pcoq.grammar_extend red_flag
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                  ("head"))))))
                                  (fun _ loc -> 
# 79 "vernac/g_redexpr.mlg"
                          [FHead] 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("delta"))))))
                                                 ((Pcoq.Symbol.nterm delta_flag)))
                                 (fun d _ loc -> 
# 78 "vernac/g_redexpr.mlg"
                                           [d] 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("zeta"))))))
                                 (fun _ loc -> 
# 77 "vernac/g_redexpr.mlg"
                          [FZeta] 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("cofix"))))))
                                 (fun _ loc -> 
# 76 "vernac/g_redexpr.mlg"
                           [FCofix] 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("fix"))))))
                                 (fun _ loc -> 
# 75 "vernac/g_redexpr.mlg"
                         [FFix] 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("match"))))))
                                 (fun _ loc -> 
# 74 "vernac/g_redexpr.mlg"
                           [FMatch] 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("iota"))))))
                                 (fun _ loc -> 
# 73 "vernac/g_redexpr.mlg"
                          [FMatch;FFix;FCofix] 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("beta"))))))
                                 (fun _ loc -> 
# 72 "vernac/g_redexpr.mlg"
                          [FBeta] 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty delta_flag) in
        let () =
        Pcoq.grammar_extend delta_flag
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make (Pcoq.Rule.stop)
                                  (fun loc -> 
# 85 "vernac/g_redexpr.mlg"
             FDeltaBut [] 
                                              );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("[")))))
                                                                 ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm smart_global)))))
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                 (fun _ idl _ loc -> 
# 84 "vernac/g_redexpr.mlg"
                                                FConst idl 
                                                     );
                                 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.list1 ((Pcoq.Symbol.nterm smart_global)))))
                                                 ((Pcoq.Symbol.token (Tok.PKEYWORD ("]")))))
                                 (fun _ idl _ _ loc -> 
# 83 "vernac/g_redexpr.mlg"
                                                     FDeltaBut idl 
                                                       )])]))
        in let () = assert (Pcoq.Entry.is_empty strategy_flag) in
        let () =
        Pcoq.grammar_extend strategy_flag
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.opt (Pcoq.Symbol.rules 
                                                                  [Pcoq.Rules.make 
                                                                  (Pcoq.Rule.next_norec 
                                                                  (Pcoq.Rule.stop)
                                                                  ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                  ("head"))))))
                                                                  (fun _
                                                                  loc -> 
                                                                  
# 90 "vernac/g_redexpr.mlg"
                                    () 
                                                                  )]))))
                                                  ((Pcoq.Symbol.nterm delta_flag)))
                                  (fun d h loc -> 
# 90 "vernac/g_redexpr.mlg"
                                                                all_with ~head:(Option.has_some h) d 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm red_flag)))))
                                 (fun s loc -> 
# 89 "vernac/g_redexpr.mlg"
                                Redops.make_red_flag (List.flatten s) 
                                               )])]))
        in let () = assert (Pcoq.Entry.is_empty red_expr) in
        let () =
        Pcoq.grammar_extend red_expr
        (Pcoq.Fresh
        (Gramlib.Gramext.First, [(None, None,
                                 [Pcoq.Production.make
                                  (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                  ((Pcoq.Symbol.token (Tok.PIDENT (None)))))
                                  (fun s loc -> 
# 108 "vernac/g_redexpr.mlg"
                       ExtraRedExpr s 
                                                );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("pattern"))))))
                                                 ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm pattern_occ)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD (","))])) false)))
                                 (fun pl _ loc -> 
# 107 "vernac/g_redexpr.mlg"
                                                            Pattern pl 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("fold"))))))
                                                 ((Pcoq.Symbol.list1 ((Pcoq.Symbol.nterm constr)))))
                                 (fun cl _ loc -> 
# 106 "vernac/g_redexpr.mlg"
                                             Fold cl 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("unfold"))))))
                                                 ((Pcoq.Symbol.list1sep ((Pcoq.Symbol.nterm unfold_occ)) ((Pcoq.Symbol.tokens [Pcoq.TPattern (Tok.PKEYWORD (","))])) false)))
                                 (fun ul _ loc -> 
# 105 "vernac/g_redexpr.mlg"
                                                           Unfold ul 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("native_compute"))))))
                                                 ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm ref_or_pattern_occ))))
                                 (fun po _ loc -> 
# 104 "vernac/g_redexpr.mlg"
                                                                 CbvNative po 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("vm_compute"))))))
                                                 ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm ref_or_pattern_occ))))
                                 (fun po _ loc -> 
# 103 "vernac/g_redexpr.mlg"
                                                             CbvVm po 
                                                  );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("compute"))))))
                                                 ((Pcoq.Symbol.nterm delta_flag)))
                                 (fun delta _ loc -> 
# 102 "vernac/g_redexpr.mlg"
                                                 Cbv (all_with ~head:false delta) 
                                                     );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("lazy"))))))
                                                 ((Pcoq.Symbol.nterm strategy_flag)))
                                 (fun s _ loc -> 
# 101 "vernac/g_redexpr.mlg"
                                             Lazy s 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("cbn"))))))
                                                 ((Pcoq.Symbol.nterm strategy_flag)))
                                 (fun s _ loc -> 
# 100 "vernac/g_redexpr.mlg"
                                            Cbn s 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("cbv"))))))
                                                 ((Pcoq.Symbol.nterm strategy_flag)))
                                 (fun s _ loc -> 
# 99 "vernac/g_redexpr.mlg"
                                            Cbv s 
                                                 );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.next (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.next 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("simpl"))))))
                                                                 ((Pcoq.Symbol.opt (Pcoq.Symbol.rules 
                                                                 [Pcoq.Rules.make 
                                                                 (Pcoq.Rule.next_norec 
                                                                 (Pcoq.Rule.stop)
                                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                                 ("head"))))))
                                                                 (fun _
                                                                 loc -> 
                                                                 
# 97 "vernac/g_redexpr.mlg"
                                                   () 
                                                                 )]))))
                                                                 ((Pcoq.Symbol.nterm delta_flag)))
                                                 ((Pcoq.Symbol.opt (Pcoq.Symbol.nterm ref_or_pattern_occ))))
                                 (fun po d h _ loc -> 
# 98 "vernac/g_redexpr.mlg"
                                                         Simpl (all_with ~head:(Option.has_some h) d,po) 
                                                      );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("hnf"))))))
                                 (fun _ loc -> 
# 96 "vernac/g_redexpr.mlg"
                         Hnf 
                                               );
                                 Pcoq.Production.make
                                 (Pcoq.Rule.next (Pcoq.Rule.stop)
                                                 ((Pcoq.Symbol.token (Tok.PIDENT (Some
                                                 ("red"))))))
                                 (fun _ loc -> 
# 95 "vernac/g_redexpr.mlg"
                         Red 
                                               )])]))
        in ()

