aboutsummaryrefslogtreecommitdiff
path: root/plugins/ssr/ssrparser.ml4
diff options
context:
space:
mode:
authorPierre-Marie Pédrot2018-10-12 09:22:56 +0200
committerPierre-Marie Pédrot2018-10-15 22:55:55 +0200
commit4da233a9685cd193a84def037ec18a27c9225dce (patch)
treee4ba7de73cc815d9f4ead92a83dc18c28883d316 /plugins/ssr/ssrparser.ml4
parent8e7131b65894e9e549422cb47aab5a3a357a6352 (diff)
Port remaining EXTEND ml4 files to coqpp.
Almost all of ml4 were removed in the process. The only remaining files are in the test-suite and probably need a bit of fiddling with coq_makefile, and there only two really remaning ml4 files containing code.
Diffstat (limited to 'plugins/ssr/ssrparser.ml4')
-rw-r--r--plugins/ssr/ssrparser.ml42348
1 files changed, 0 insertions, 2348 deletions
diff --git a/plugins/ssr/ssrparser.ml4 b/plugins/ssr/ssrparser.ml4
deleted file mode 100644
index 319f58931a..0000000000
--- a/plugins/ssr/ssrparser.ml4
+++ /dev/null
@@ -1,2348 +0,0 @@
-(************************************************************************)
-(* * The Coq Proof Assistant / The Coq Development Team *)
-(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
-(* <O___,, * (see CREDITS file for the list of authors) *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(* * (see LICENSE file for the text of the license) *)
-(************************************************************************)
-
-(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
-
-let _vmcast = Constr.VMcast
-open Names
-open Pp
-open Pcoq
-open Ltac_plugin
-open Stdarg
-open Tacarg
-open Libnames
-open Tactics
-open Tacmach
-open Util
-open Locus
-open Tacexpr
-open Tacinterp
-open Pltac
-open Extraargs
-open Ppconstr
-
-open Namegen
-open Tactypes
-open Decl_kinds
-open Constrexpr
-open Constrexpr_ops
-
-open Proofview
-open Proofview.Notations
-
-open Ssrprinters
-open Ssrcommon
-open Ssrtacticals
-open Ssrbwd
-open Ssrequality
-open Ssripats
-
-(** Ssreflect load check. *)
-
-(* To allow ssrcoq to be fully compatible with the "plain" Coq, we only *)
-(* turn on its incompatible features (the new rewrite syntax, and the *)
-(* reserved identifiers) when the theory library (ssreflect.v) has *)
-(* has actually been required, or is being defined. Because this check *)
-(* needs to be done often (for each identifier lookup), we implement *)
-(* some caching, repeating the test only when the environment changes. *)
-(* We check for protect_term because it is the first constant loaded; *)
-(* ssr_have would ultimately be a better choice. *)
-let ssr_loaded = Summary.ref ~name:"SSR:loaded" false
-let is_ssr_loaded () =
- !ssr_loaded ||
- (if CLexer.is_keyword "SsrSyntax_is_Imported" then ssr_loaded:=true;
- !ssr_loaded)
-
-DECLARE PLUGIN "ssreflect_plugin"
-(* Defining grammar rules with "xx" in it automatically declares keywords too,
- * we thus save the lexer to restore it at the end of the file *)
-let frozen_lexer = CLexer.get_keyword_state () ;;
-
-let tacltop = (5,Notation_gram.E)
-
-let pr_ssrtacarg _ _ prt = prt tacltop
-ARGUMENT EXTEND ssrtacarg TYPED AS tactic PRINTED BY pr_ssrtacarg
-| [ "YouShouldNotTypeThis" ] -> [ CErrors.anomaly (Pp.str "Grammar placeholder match") ]
-END
-GEXTEND Gram
- GLOBAL: ssrtacarg;
- ssrtacarg: [[ tac = tactic_expr LEVEL "5" -> tac ]];
-END
-
-(* Lexically closed tactic for tacticals. *)
-let pr_ssrtclarg _ _ prt tac = prt tacltop tac
-ARGUMENT EXTEND ssrtclarg TYPED AS ssrtacarg
- PRINTED BY pr_ssrtclarg
-| [ ssrtacarg(tac) ] -> [ tac ]
-END
-
-open Genarg
-
-(** Adding a new uninterpreted generic argument type *)
-let add_genarg tag pr =
- let wit = Genarg.make0 tag in
- let tag = Geninterp.Val.create tag in
- let glob ist x = (ist, x) in
- let subst _ x = x in
- let interp ist x = Ftactic.return (Geninterp.Val.Dyn (tag, x)) in
- let gen_pr _ _ _ = pr in
- let () = Genintern.register_intern0 wit glob in
- let () = Genintern.register_subst0 wit subst in
- let () = Geninterp.register_interp0 wit interp in
- let () = Geninterp.register_val0 wit (Some (Geninterp.Val.Base tag)) in
- Pptactic.declare_extra_genarg_pprule wit gen_pr gen_pr gen_pr;
- wit
-
-(** Primitive parsing to avoid syntax conflicts with basic tactics. *)
-
-let accept_before_syms syms strm =
- match Util.stream_nth 1 strm with
- | Tok.KEYWORD sym when List.mem sym syms -> ()
- | _ -> raise Stream.Failure
-
-let accept_before_syms_or_any_id syms strm =
- match Util.stream_nth 1 strm with
- | Tok.KEYWORD sym when List.mem sym syms -> ()
- | Tok.IDENT _ -> ()
- | _ -> raise Stream.Failure
-
-let accept_before_syms_or_ids syms ids strm =
- match Util.stream_nth 1 strm with
- | Tok.KEYWORD sym when List.mem sym syms -> ()
- | Tok.IDENT id when List.mem id ids -> ()
- | _ -> raise Stream.Failure
-
-open Ssrast
-let pr_id = Ppconstr.pr_id
-let pr_name = function Name id -> pr_id id | Anonymous -> str "_"
-let pr_spc () = str " "
-let pr_list = prlist_with_sep
-
-(**************************** ssrhyp **************************************)
-
-let pr_ssrhyp _ _ _ = pr_hyp
-
-let wit_ssrhyprep = add_genarg "ssrhyprep" pr_hyp
-
-let intern_hyp ist (SsrHyp (loc, id) as hyp) =
- let _ = Tacintern.intern_genarg ist (in_gen (rawwit wit_var) CAst.(make ?loc id)) in
- if not_section_id id then hyp else
- hyp_err ?loc "Can't clear section hypothesis " id
-
-open Pcoq.Prim
-
-ARGUMENT EXTEND ssrhyp TYPED AS ssrhyprep PRINTED BY pr_ssrhyp
- INTERPRETED BY interp_hyp
- GLOBALIZED BY intern_hyp
- | [ ident(id) ] -> [ SsrHyp (Loc.tag ~loc id) ]
-END
-
-
-let pr_hoi = hoik pr_hyp
-let pr_ssrhoi _ _ _ = pr_hoi
-
-let wit_ssrhoirep = add_genarg "ssrhoirep" pr_hoi
-
-let intern_ssrhoi ist = function
- | Hyp h -> Hyp (intern_hyp ist h)
- | Id (SsrHyp (_, id)) as hyp ->
- let _ = Tacintern.intern_genarg ist (in_gen (rawwit wit_ident) id) in
- hyp
-
-let interp_ssrhoi ist gl = function
- | Hyp h -> let s, h' = interp_hyp ist gl h in s, Hyp h'
- | Id (SsrHyp (loc, id)) ->
- let s, id' = interp_wit wit_ident ist gl id in
- s, Id (SsrHyp (loc, id'))
-
-ARGUMENT EXTEND ssrhoi_hyp TYPED AS ssrhoirep PRINTED BY pr_ssrhoi
- INTERPRETED BY interp_ssrhoi
- GLOBALIZED BY intern_ssrhoi
- | [ ident(id) ] -> [ Hyp (SsrHyp(Loc.tag ~loc id)) ]
-END
-ARGUMENT EXTEND ssrhoi_id TYPED AS ssrhoirep PRINTED BY pr_ssrhoi
- INTERPRETED BY interp_ssrhoi
- GLOBALIZED BY intern_ssrhoi
- | [ ident(id) ] -> [ Id (SsrHyp(Loc.tag ~loc id)) ]
-END
-
-
-let pr_ssrhyps _ _ _ = pr_hyps
-
-ARGUMENT EXTEND ssrhyps TYPED AS ssrhyp list PRINTED BY pr_ssrhyps
- INTERPRETED BY interp_hyps
- | [ ssrhyp_list(hyps) ] -> [ check_hyps_uniq [] hyps; hyps ]
-END
-
-(** Rewriting direction *)
-
-
-let pr_rwdir = function L2R -> mt() | R2L -> str "-"
-
-let wit_ssrdir = add_genarg "ssrdir" pr_dir
-
-(** Simpl switch *)
-
-let pr_ssrsimpl _ _ _ = pr_simpl
-
-let wit_ssrsimplrep = add_genarg "ssrsimplrep" pr_simpl
-
-let test_ssrslashnum b1 b2 strm =
- match Util.stream_nth 0 strm with
- | Tok.KEYWORD "/" ->
- (match Util.stream_nth 1 strm with
- | Tok.INT _ when b1 ->
- (match Util.stream_nth 2 strm with
- | Tok.KEYWORD "=" | Tok.KEYWORD "/=" when not b2 -> ()
- | Tok.KEYWORD "/" ->
- if not b2 then () else begin
- match Util.stream_nth 3 strm with
- | Tok.INT _ -> ()
- | _ -> raise Stream.Failure
- end
- | _ -> raise Stream.Failure)
- | Tok.KEYWORD "/" when not b1 ->
- (match Util.stream_nth 2 strm with
- | Tok.KEYWORD "=" when not b2 -> ()
- | Tok.INT _ when b2 ->
- (match Util.stream_nth 3 strm with
- | Tok.KEYWORD "=" -> ()
- | _ -> raise Stream.Failure)
- | _ when not b2 -> ()
- | _ -> raise Stream.Failure)
- | Tok.KEYWORD "=" when not b1 && not b2 -> ()
- | _ -> raise Stream.Failure)
- | Tok.KEYWORD "//" when not b1 ->
- (match Util.stream_nth 1 strm with
- | Tok.KEYWORD "=" when not b2 -> ()
- | Tok.INT _ when b2 ->
- (match Util.stream_nth 2 strm with
- | Tok.KEYWORD "=" -> ()
- | _ -> raise Stream.Failure)
- | _ when not b2 -> ()
- | _ -> raise Stream.Failure)
- | _ -> raise Stream.Failure
-
-let test_ssrslashnum10 = test_ssrslashnum true false
-let test_ssrslashnum11 = test_ssrslashnum true true
-let test_ssrslashnum01 = test_ssrslashnum false true
-let test_ssrslashnum00 = test_ssrslashnum false false
-
-let negate_parser f x =
- let rc = try Some (f x) with Stream.Failure -> None in
- match rc with
- | None -> ()
- | Some _ -> raise Stream.Failure
-
-let test_not_ssrslashnum =
- Pcoq.Gram.Entry.of_parser
- "test_not_ssrslashnum" (negate_parser test_ssrslashnum10)
-let test_ssrslashnum00 =
- Pcoq.Gram.Entry.of_parser "test_ssrslashnum01" test_ssrslashnum00
-let test_ssrslashnum10 =
- Pcoq.Gram.Entry.of_parser "test_ssrslashnum10" test_ssrslashnum10
-let test_ssrslashnum11 =
- Pcoq.Gram.Entry.of_parser "test_ssrslashnum11" test_ssrslashnum11
-let test_ssrslashnum01 =
- Pcoq.Gram.Entry.of_parser "test_ssrslashnum01" test_ssrslashnum01
-
-
-ARGUMENT EXTEND ssrsimpl_ne TYPED AS ssrsimplrep PRINTED BY pr_ssrsimpl
-| [ "//=" ] -> [ SimplCut (~-1,~-1) ]
-| [ "/=" ] -> [ Simpl ~-1 ]
-END
-
-Pcoq.(Prim.(
-GEXTEND Gram
- GLOBAL: ssrsimpl_ne;
- ssrsimpl_ne: [
- [ test_ssrslashnum11; "/"; n = natural; "/"; m = natural; "=" -> SimplCut(n,m)
- | test_ssrslashnum10; "/"; n = natural; "/" -> Cut n
- | test_ssrslashnum10; "/"; n = natural; "=" -> Simpl n
- | test_ssrslashnum10; "/"; n = natural; "/=" -> SimplCut (n,~-1)
- | test_ssrslashnum10; "/"; n = natural; "/"; "=" -> SimplCut (n,~-1)
- | test_ssrslashnum01; "//"; m = natural; "=" -> SimplCut (~-1,m)
- | test_ssrslashnum00; "//" -> Cut ~-1
- ]];
-
-END
-))
-
-ARGUMENT EXTEND ssrsimpl TYPED AS ssrsimplrep PRINTED BY pr_ssrsimpl
-| [ ssrsimpl_ne(sim) ] -> [ sim ]
-| [ ] -> [ Nop ]
-END
-
-
-let pr_ssrclear _ _ _ = pr_clear mt
-
-ARGUMENT EXTEND ssrclear_ne TYPED AS ssrhyps PRINTED BY pr_ssrclear
-| [ "{" ne_ssrhyp_list(clr) "}" ] -> [ check_hyps_uniq [] clr; clr ]
-END
-
-ARGUMENT EXTEND ssrclear TYPED AS ssrclear_ne PRINTED BY pr_ssrclear
-| [ ssrclear_ne(clr) ] -> [ clr ]
-| [ ] -> [ [] ]
-END
-
-(** Indexes *)
-
-(* Since SSR indexes are always positive numbers, we use the 0 value *)
-(* to encode an omitted index. We reuse the in or_var type, but we *)
-(* supply our own interpretation function, which checks for non *)
-(* positive values, and allows the use of constr numerals, so that *)
-(* e.g., "let n := eval compute in (1 + 3) in (do n!clear)" works. *)
-
-
-let pr_index = function
- | ArgVar {CAst.v=id} -> pr_id id
- | ArgArg n when n > 0 -> int n
- | _ -> mt ()
-let pr_ssrindex _ _ _ = pr_index
-
-let noindex = ArgArg 0
-
-let check_index ?loc i =
- if i > 0 then i else CErrors.user_err ?loc (str"Index not positive")
-let mk_index ?loc = function
- | ArgArg i -> ArgArg (check_index ?loc i)
- | iv -> iv
-
-let interp_index ist gl idx =
- Tacmach.project gl,
- match idx with
- | ArgArg _ -> idx
- | ArgVar id ->
- let i =
- try
- let v = Id.Map.find id.CAst.v ist.Tacinterp.lfun in
- begin match Tacinterp.Value.to_int v with
- | Some i -> i
- | None ->
- begin match Tacinterp.Value.to_constr v with
- | Some c ->
- let rc = Detyping.detype Detyping.Now false Id.Set.empty (pf_env gl) (project gl) c in
- begin match Notation.uninterp_prim_token rc with
- | _, Constrexpr.Numeral (s,b) ->
- let n = int_of_string s in if b then n else -n
- | _ -> raise Not_found
- end
- | None -> raise Not_found
- end end
- with _ -> CErrors.user_err ?loc:id.CAst.loc (str"Index not a number") in
- ArgArg (check_index ?loc:id.CAst.loc i)
-
-open Pltac
-
-ARGUMENT EXTEND ssrindex PRINTED BY pr_ssrindex
- INTERPRETED BY interp_index
-| [ int_or_var(i) ] -> [ mk_index ~loc i ]
-END
-
-
-(** Occurrence switch *)
-
-(* The standard syntax of complemented occurrence lists involves a single *)
-(* initial "-", e.g., {-1 3 5}. An initial *)
-(* "+" may be used to indicate positive occurrences (the default). The *)
-(* "+" is optional, except if the list of occurrences starts with a *)
-(* variable or is empty (to avoid confusion with a clear switch). The *)
-(* empty positive switch "{+}" selects no occurrences, while the empty *)
-(* negative switch "{-}" selects all occurrences explicitly; this is the *)
-(* default, but "{-}" prevents the implicit clear, and can be used to *)
-(* force dependent elimination -- see ndefectelimtac below. *)
-
-
-let pr_ssrocc _ _ _ = pr_occ
-
-open Pcoq.Prim
-
-ARGUMENT EXTEND ssrocc TYPED AS (bool * int list) option PRINTED BY pr_ssrocc
-| [ natural(n) natural_list(occ) ] -> [
- Some (false, List.map (check_index ~loc) (n::occ)) ]
-| [ "-" natural_list(occ) ] -> [ Some (true, occ) ]
-| [ "+" natural_list(occ) ] -> [ Some (false, occ) ]
-END
-
-
-(* modality *)
-
-
-let pr_mmod = function May -> str "?" | Must -> str "!" | Once -> mt ()
-
-let wit_ssrmmod = add_genarg "ssrmmod" pr_mmod
-let ssrmmod = Pcoq.create_generic_entry Pcoq.utactic "ssrmmod" (Genarg.rawwit wit_ssrmmod);;
-
-GEXTEND Gram
- GLOBAL: ssrmmod;
- ssrmmod: [[ "!" -> Must | LEFTQMARK -> May | "?" -> May]];
-END
-
-(** Rewrite multiplier: !n ?n *)
-
-let pr_mult (n, m) =
- if n > 0 && m <> Once then int n ++ pr_mmod m else pr_mmod m
-
-let pr_ssrmult _ _ _ = pr_mult
-
-ARGUMENT EXTEND ssrmult_ne TYPED AS int * ssrmmod PRINTED BY pr_ssrmult
- | [ natural(n) ssrmmod(m) ] -> [ check_index ~loc n, m ]
- | [ ssrmmod(m) ] -> [ notimes, m ]
-END
-
-ARGUMENT EXTEND ssrmult TYPED AS ssrmult_ne PRINTED BY pr_ssrmult
- | [ ssrmult_ne(m) ] -> [ m ]
- | [ ] -> [ nomult ]
-END
-
-(** Discharge occ switch (combined occurrence / clear switch *)
-
-let pr_docc = function
- | None, occ -> pr_occ occ
- | Some clr, _ -> pr_clear mt clr
-
-let pr_ssrdocc _ _ _ = pr_docc
-
-ARGUMENT EXTEND ssrdocc TYPED AS ssrclear option * ssrocc PRINTED BY pr_ssrdocc
-| [ "{" ssrocc(occ) "}" ] -> [ mkocc occ ]
-| [ "{" ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
-END
-
-(* Old kinds of terms *)
-
-let input_ssrtermkind strm = match Util.stream_nth 0 strm with
- | Tok.KEYWORD "(" -> xInParens
- | Tok.KEYWORD "@" -> xWithAt
- | _ -> xNoFlag
-
-let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind
-
-(* New kinds of terms *)
-
-let input_term_annotation strm =
- match Stream.npeek 2 strm with
- | Tok.KEYWORD "(" :: Tok.KEYWORD "(" :: _ -> `DoubleParens
- | Tok.KEYWORD "(" :: _ -> `Parens
- | Tok.KEYWORD "@" :: _ -> `At
- | _ -> `None
-let term_annotation =
- Gram.Entry.of_parser "term_annotation" input_term_annotation
-
-(* terms *)
-
-(** Terms parsing. ********************************************************)
-
-(* Because we allow wildcards in term references, we need to stage the *)
-(* interpretation of terms so that it occurs at the right time during *)
-(* the execution of the tactic (e.g., so that we don't report an error *)
-(* for a term that isn't actually used in the execution). *)
-(* The term representation tracks whether the concrete initial term *)
-(* started with an opening paren, which might avoid a conflict between *)
-(* the ssrreflect term syntax and Gallina notation. *)
-
-(* Old terms *)
-let pr_ssrterm _ _ _ = pr_term
-let glob_ssrterm gs = function
- | k, (_, Some c) -> k, Tacintern.intern_constr gs c
- | ct -> ct
-let subst_ssrterm s (k, c) = k, Tacsubst.subst_glob_constr_and_expr s c
-let interp_ssrterm _ gl t = Tacmach.project gl, t
-
-open Pcoq.Constr
-
-ARGUMENT EXTEND ssrterm
- PRINTED BY pr_ssrterm
- INTERPRETED BY interp_ssrterm
- GLOBALIZED BY glob_ssrterm SUBSTITUTED BY subst_ssrterm
- RAW_PRINTED BY pr_ssrterm
- GLOB_PRINTED BY pr_ssrterm
-| [ "YouShouldNotTypeThis" constr(c) ] -> [ mk_lterm c ]
-END
-
-
-GEXTEND Gram
- GLOBAL: ssrterm;
- ssrterm: [[ k = ssrtermkind; c = Pcoq.Constr.constr -> mk_term k c ]];
-END
-
-(* New terms *)
-
-let pp_ast_closure_term _ _ _ = pr_ast_closure_term
-
-ARGUMENT EXTEND ast_closure_term
- PRINTED BY pp_ast_closure_term
- INTERPRETED BY interp_ast_closure_term
- GLOBALIZED BY glob_ast_closure_term
- SUBSTITUTED BY subst_ast_closure_term
- RAW_PRINTED BY pp_ast_closure_term
- GLOB_PRINTED BY pp_ast_closure_term
- | [ term_annotation(a) constr(c) ] -> [ mk_ast_closure_term a c ]
-END
-ARGUMENT EXTEND ast_closure_lterm
- PRINTED BY pp_ast_closure_term
- INTERPRETED BY interp_ast_closure_term
- GLOBALIZED BY glob_ast_closure_term
- SUBSTITUTED BY subst_ast_closure_term
- RAW_PRINTED BY pp_ast_closure_term
- GLOB_PRINTED BY pp_ast_closure_term
- | [ term_annotation(a) lconstr(c) ] -> [ mk_ast_closure_term a c ]
-END
-
-(* Old Views *)
-
-let pr_view = pr_list mt (fun c -> str "/" ++ pr_term c)
-
-let pr_ssrbwdview _ _ _ = pr_view
-
-ARGUMENT EXTEND ssrbwdview TYPED AS ssrterm list
- PRINTED BY pr_ssrbwdview
-| [ "YouShouldNotTypeThis" ] -> [ [] ]
-END
-
-Pcoq.(
-GEXTEND Gram
- GLOBAL: ssrbwdview;
- ssrbwdview: [
- [ test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr -> [mk_term xNoFlag c]
- | test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr; w = ssrbwdview ->
- (mk_term xNoFlag c) :: w ]];
-END
-)
-
-(* New Views *)
-
-
-let pr_ssrfwdview _ _ _ = pr_view2
-
-ARGUMENT EXTEND ssrfwdview TYPED AS ast_closure_term list
- PRINTED BY pr_ssrfwdview
-| [ "YouShouldNotTypeThis" ] -> [ [] ]
-END
-
-Pcoq.(
-GEXTEND Gram
- GLOBAL: ssrfwdview;
- ssrfwdview: [
- [ test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr ->
- [mk_ast_closure_term `None c]
- | test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr; w = ssrfwdview ->
- (mk_ast_closure_term `None c) :: w ]];
-END
-)
-
-(* }}} *)
-
-(* ipats *)
-
-
-let remove_loc x = x.CAst.v
-
-let ipat_of_intro_pattern p = Tactypes.(
- let rec ipat_of_intro_pattern = function
- | IntroNaming (IntroIdentifier id) -> IPatId id
- | IntroAction IntroWildcard -> IPatAnon Drop
- | IntroAction (IntroOrAndPattern (IntroOrPattern iorpat)) ->
- IPatCase
- (List.map (List.map ipat_of_intro_pattern)
- (List.map (List.map remove_loc) iorpat))
- | IntroAction (IntroOrAndPattern (IntroAndPattern iandpat)) ->
- IPatCase
- [List.map ipat_of_intro_pattern (List.map remove_loc iandpat)]
- | IntroNaming IntroAnonymous -> IPatAnon One
- | IntroAction (IntroRewrite b) -> IPatRewrite (allocc, if b then L2R else R2L)
- | IntroNaming (IntroFresh id) -> IPatAnon One
- | IntroAction (IntroApplyOn _) -> (* to do *) CErrors.user_err (Pp.str "TO DO")
- | IntroAction (IntroInjection ips) ->
- IPatInj [List.map ipat_of_intro_pattern (List.map remove_loc ips)]
- | IntroForthcoming _ ->
- (* Unable to determine which kind of ipat interp_introid could
- * return [HH] *)
- assert false
- in
- ipat_of_intro_pattern p
-)
-
-let rec map_ipat map_id map_ssrhyp map_ast_closure_term = function
- | (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x
- | IPatId id -> IPatId (map_id id)
- | IPatAbstractVars l -> IPatAbstractVars (List.map map_id l)
- | IPatClear clr -> IPatClear (List.map map_ssrhyp clr)
- | IPatCase iorpat -> IPatCase (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatDispatch iorpat -> IPatDispatch (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatInj iorpat -> IPatInj (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat)
- | IPatView (clr,v) -> IPatView (clr,List.map map_ast_closure_term v)
- | IPatTac _ -> assert false (*internal usage only *)
-
-let wit_ssripatrep = add_genarg "ssripatrep" pr_ipat
-
-let pr_ssripat _ _ _ = pr_ipat
-let pr_ssripats _ _ _ = pr_ipats
-let pr_ssriorpat _ _ _ = pr_iorpat
-
-let intern_ipat ist =
- map_ipat
- (fun id -> id)
- (intern_hyp ist)
- (glob_ast_closure_term ist)
-
-let intern_ipats ist = List.map (intern_ipat ist)
-
-let interp_intro_pattern = interp_wit wit_intro_pattern
-
-let interp_introid ist gl id =
- try IntroNaming (IntroIdentifier (hyp_id (snd (interp_hyp ist gl (SsrHyp (Loc.tag id))))))
- with _ -> (snd (interp_intro_pattern ist gl (CAst.make @@ IntroNaming (IntroIdentifier id)))).CAst.v
-
-let get_intro_id = function
- | IntroNaming (IntroIdentifier id) -> id
- | _ -> assert false
-
-let rec add_intro_pattern_hyps ipat hyps =
- let {CAst.loc=loc;v=ipat} = ipat in
- match ipat with
- | IntroNaming (IntroIdentifier id) ->
- if not_section_id id then SsrHyp (loc, id) :: hyps else
- hyp_err ?loc "Can't delete section hypothesis " id
- | IntroAction IntroWildcard -> hyps
- | IntroAction (IntroOrAndPattern (IntroOrPattern iorpat)) ->
- List.fold_right (List.fold_right add_intro_pattern_hyps) iorpat hyps
- | IntroAction (IntroOrAndPattern (IntroAndPattern iandpat)) ->
- List.fold_right add_intro_pattern_hyps iandpat hyps
- | IntroNaming IntroAnonymous -> []
- | IntroNaming (IntroFresh _) -> []
- | IntroAction (IntroRewrite _) -> hyps
- | IntroAction (IntroInjection ips) -> List.fold_right add_intro_pattern_hyps ips hyps
- | IntroAction (IntroApplyOn (c,pat)) -> add_intro_pattern_hyps pat hyps
- | IntroForthcoming _ ->
- (* As in ipat_of_intro_pattern, was unable to determine which kind
- of ipat interp_introid could return [HH] *) assert false
-
-(* We interp the ipat using the standard ltac machinery for ids, since
- * we have no clue what a name could be bound to (maybe another ipat) *)
-let interp_ipat ist gl =
- let ltacvar id = Id.Map.mem id ist.Tacinterp.lfun in
- let rec interp = function
- | IPatId id when ltacvar id ->
- ipat_of_intro_pattern (interp_introid ist gl id)
- | IPatId _ as x -> x
- | IPatClear clr ->
- let add_hyps (SsrHyp (loc, id) as hyp) hyps =
- if not (ltacvar id) then hyp :: hyps else
- add_intro_pattern_hyps CAst.(make ?loc (interp_introid ist gl id)) hyps in
- let clr' = List.fold_right add_hyps clr [] in
- check_hyps_uniq [] clr'; IPatClear clr'
- | IPatCase(iorpat) ->
- IPatCase(List.map (List.map interp) iorpat)
- | IPatDispatch(iorpat) ->
- IPatDispatch(List.map (List.map interp) iorpat)
- | IPatInj iorpat -> IPatInj (List.map (List.map interp) iorpat)
- | IPatAbstractVars l ->
- IPatAbstractVars (List.map get_intro_id (List.map (interp_introid ist gl) l))
- | IPatView (clr,l) -> IPatView (clr,List.map (fun x -> snd(interp_ast_closure_term ist
- gl x)) l)
- | (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x
- | IPatTac _ -> assert false (*internal usage only *)
- in
- interp
-
-let interp_ipats ist gl l = project gl, List.map (interp_ipat ist gl) l
-
-let pushIPatRewrite = function
- | pats :: orpat -> (IPatRewrite (allocc, L2R) :: pats) :: orpat
- | [] -> []
-
-let pushIPatNoop = function
- | pats :: orpat -> (IPatNoop :: pats) :: orpat
- | [] -> []
-
-ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats
- INTERPRETED BY interp_ipats
- GLOBALIZED BY intern_ipats
- | [ "_" ] -> [ [IPatAnon Drop] ]
- | [ "*" ] -> [ [IPatAnon All] ]
- (*
- | [ "^" "*" ] -> [ [IPatFastMode] ]
- | [ "^" "_" ] -> [ [IPatSeed `Wild] ]
- | [ "^_" ] -> [ [IPatSeed `Wild] ]
- | [ "^" "?" ] -> [ [IPatSeed `Anon] ]
- | [ "^?" ] -> [ [IPatSeed `Anon] ]
- | [ "^" ident(id) ] -> [ [IPatSeed (`Id(id,`Pre))] ]
- | [ "^" "~" ident(id) ] -> [ [IPatSeed (`Id(id,`Post))] ]
- | [ "^~" ident(id) ] -> [ [IPatSeed (`Id(id,`Post))] ]
- *)
- | [ ident(id) ] -> [ [IPatId id] ]
- | [ "?" ] -> [ [IPatAnon One] ]
-(* TODO | [ "+" ] -> [ [IPatAnon Temporary] ] *)
- | [ ssrsimpl_ne(sim) ] -> [ [IPatSimpl sim] ]
- | [ ssrdocc(occ) "->" ] -> [ match occ with
- | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
- | None, occ -> [IPatRewrite (occ, L2R)]
- | Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, L2R)]]
- | [ ssrdocc(occ) "<-" ] -> [ match occ with
- | Some [], _ -> CErrors.user_err ~loc (str"occ_switch expected")
- | None, occ -> [IPatRewrite (occ, R2L)]
- | Some clr, _ -> [IPatClear clr; IPatRewrite (allocc, R2L)]]
- | [ ssrdocc(occ) ssrfwdview(v) ] -> [ match occ with
- | Some [], _ -> [IPatView (true,v)]
- | Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl;IPatView (false,v)]
- | _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here") ]
- | [ ssrdocc(occ) ] -> [ match occ with
- | Some cl, _ -> check_hyps_uniq [] cl; [IPatClear cl]
- | _ -> CErrors.user_err ~loc (str"Only identifiers are allowed here")]
- | [ "->" ] -> [ [IPatRewrite (allocc, L2R)] ]
- | [ "<-" ] -> [ [IPatRewrite (allocc, R2L)] ]
- | [ "-" ] -> [ [IPatNoop] ]
- | [ "-/" "=" ] -> [ [IPatNoop;IPatSimpl(Simpl ~-1)] ]
- | [ "-/=" ] -> [ [IPatNoop;IPatSimpl(Simpl ~-1)] ]
- | [ "-/" "/" ] -> [ [IPatNoop;IPatSimpl(Cut ~-1)] ]
- | [ "-//" ] -> [ [IPatNoop;IPatSimpl(Cut ~-1)] ]
- | [ "-/" integer(n) "/" ] -> [ [IPatNoop;IPatSimpl(Cut n)] ]
- | [ "-/" "/=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (~-1,~-1))] ]
- | [ "-//" "=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (~-1,~-1))] ]
- | [ "-//=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (~-1,~-1))] ]
- | [ "-/" integer(n) "/=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (n,~-1))] ]
- | [ "-/" integer(n) "/" integer (m) "=" ] ->
- [ [IPatNoop;IPatSimpl(SimplCut(n,m))] ]
- | [ ssrfwdview(v) ] -> [ [IPatView (false,v)] ]
- | [ "[" ":" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
- | [ "[:" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ]
-END
-
-ARGUMENT EXTEND ssripats TYPED AS ssripat PRINTED BY pr_ssripats
- | [ ssripat(i) ssripats(tl) ] -> [ i @ tl ]
- | [ ] -> [ [] ]
-END
-
-ARGUMENT EXTEND ssriorpat TYPED AS ssripat list PRINTED BY pr_ssriorpat
-| [ ssripats(pats) "|" ssriorpat(orpat) ] -> [ pats :: orpat ]
-| [ ssripats(pats) "|-" ">" ssriorpat(orpat) ] -> [ pats :: pushIPatRewrite orpat ]
-| [ ssripats(pats) "|-" ssriorpat(orpat) ] -> [ pats :: pushIPatNoop orpat ]
-| [ ssripats(pats) "|->" ssriorpat(orpat) ] -> [ pats :: pushIPatRewrite orpat ]
-| [ ssripats(pats) "||" ssriorpat(orpat) ] -> [ pats :: [] :: orpat ]
-| [ ssripats(pats) "|||" ssriorpat(orpat) ] -> [ pats :: [] :: [] :: orpat ]
-| [ ssripats(pats) "||||" ssriorpat(orpat) ] -> [ [pats; []; []; []] @ orpat ]
-| [ ssripats(pats) ] -> [ [pats] ]
-END
-
-let reject_ssrhid strm =
- match Util.stream_nth 0 strm with
- | Tok.KEYWORD "[" ->
- (match Util.stream_nth 1 strm with
- | Tok.KEYWORD ":" -> raise Stream.Failure
- | _ -> ())
- | _ -> ()
-
-let test_nohidden = Pcoq.Gram.Entry.of_parser "test_ssrhid" reject_ssrhid
-
-ARGUMENT EXTEND ssrcpat TYPED AS ssripatrep PRINTED BY pr_ssripat
- | [ "YouShouldNotTypeThis" ssriorpat(x) ] -> [ IPatCase(x) ]
-END
-
-Pcoq.(
-GEXTEND Gram
- GLOBAL: ssrcpat;
- ssrcpat: [
- [ test_nohidden; "["; iorpat = ssriorpat; "]" ->
-(* check_no_inner_seed !@loc false iorpat;
- IPatCase (understand_case_type iorpat) *)
- IPatCase iorpat
-(*
- | test_nohidden; "("; iorpat = ssriorpat; ")" ->
-(* check_no_inner_seed !@loc false iorpat;
- IPatCase (understand_case_type iorpat) *)
- IPatDispatch iorpat
-*)
- | test_nohidden; "[="; iorpat = ssriorpat; "]" ->
-(* check_no_inner_seed !@loc false iorpat; *)
- IPatInj iorpat ]];
-END
-);;
-
-Pcoq.(
-GEXTEND Gram
- GLOBAL: ssripat;
- ssripat: [[ pat = ssrcpat -> [pat] ]];
-END
-)
-
-ARGUMENT EXTEND ssripats_ne TYPED AS ssripat PRINTED BY pr_ssripats
- | [ ssripat(i) ssripats(tl) ] -> [ i @ tl ]
- END
-
-(* subsets of patterns *)
-
-(* TODO: review what this function does, it looks suspicious *)
-let check_ssrhpats loc w_binders ipats =
- let err_loc s = CErrors.user_err ~loc ~hdr:"ssreflect" s in
- let clr, ipats =
- let rec aux clr = function
- | IPatClear cl :: tl -> aux (clr @ cl) tl
-(* | IPatSimpl (cl, sim) :: tl -> clr @ cl, IPatSimpl ([], sim) :: tl *)
- | tl -> clr, tl
- in aux [] ipats in
- let simpl, ipats =
- match List.rev ipats with
- | IPatSimpl _ as s :: tl -> [s], List.rev tl
- | _ -> [], ipats in
- if simpl <> [] && not w_binders then
- err_loc (str "No s-item allowed here: " ++ pr_ipats simpl);
- let ipat, binders =
- let rec loop ipat = function
- | [] -> ipat, []
- | ( IPatId _| IPatAnon _| IPatCase _ | IPatDispatch _ | IPatRewrite _ as i) :: tl ->
- if w_binders then
- if simpl <> [] && tl <> [] then
- err_loc(str"binders XOR s-item allowed here: "++pr_ipats(tl@simpl))
- else if not (List.for_all (function IPatId _ -> true | _ -> false) tl)
- then err_loc (str "Only binders allowed here: " ++ pr_ipats tl)
- else ipat @ [i], tl
- else
- if tl = [] then ipat @ [i], []
- else err_loc (str "No binder or s-item allowed here: " ++ pr_ipats tl)
- | hd :: tl -> loop (ipat @ [hd]) tl
- in loop [] ipats in
- ((clr, ipat), binders), simpl
-
-let pr_hpats (((clr, ipat), binders), simpl) =
- pr_clear mt clr ++ pr_ipats ipat ++ pr_ipats binders ++ pr_ipats simpl
-let pr_ssrhpats _ _ _ = pr_hpats
-let pr_ssrhpats_wtransp _ _ _ (_, x) = pr_hpats x
-
-ARGUMENT EXTEND ssrhpats TYPED AS ((ssrclear * ssripat) * ssripat) * ssripat
-PRINTED BY pr_ssrhpats
- | [ ssripats(i) ] -> [ check_ssrhpats loc true i ]
-END
-
-ARGUMENT EXTEND ssrhpats_wtransp
- TYPED AS bool * (((ssrclear * ssripats) * ssripats) * ssripats)
- PRINTED BY pr_ssrhpats_wtransp
- | [ ssripats(i) ] -> [ false,check_ssrhpats loc true i ]
- | [ ssripats(i) "@" ssripats(j) ] -> [ true,check_ssrhpats loc true (i @ j) ]
-END
-
-ARGUMENT EXTEND ssrhpats_nobs
-TYPED AS ((ssrclear * ssripats) * ssripats) * ssripats PRINTED BY pr_ssrhpats
- | [ ssripats(i) ] -> [ check_ssrhpats loc false i ]
-END
-
-ARGUMENT EXTEND ssrrpat TYPED AS ssripatrep PRINTED BY pr_ssripat
- | [ "->" ] -> [ IPatRewrite (allocc, L2R) ]
- | [ "<-" ] -> [ IPatRewrite (allocc, R2L) ]
-END
-
-let pr_intros sep intrs =
- if intrs = [] then mt() else sep () ++ str "=>" ++ pr_ipats intrs
-let pr_ssrintros _ _ _ = pr_intros mt
-
-ARGUMENT EXTEND ssrintros_ne TYPED AS ssripat
- PRINTED BY pr_ssrintros
- | [ "=>" ssripats_ne(pats) ] -> [ pats ]
-(* TODO | [ "=>" ">" ssripats_ne(pats) ] -> [ IPatFastMode :: pats ]
- | [ "=>>" ssripats_ne(pats) ] -> [ IPatFastMode :: pats ] *)
-END
-
-ARGUMENT EXTEND ssrintros TYPED AS ssrintros_ne PRINTED BY pr_ssrintros
- | [ ssrintros_ne(intrs) ] -> [ intrs ]
- | [ ] -> [ [] ]
-END
-
-let pr_ssrintrosarg _ _ prt (tac, ipats) =
- prt tacltop tac ++ pr_intros spc ipats
-
-ARGUMENT EXTEND ssrintrosarg TYPED AS tactic * ssrintros
- PRINTED BY pr_ssrintrosarg
-| [ "YouShouldNotTypeThis" ssrtacarg(arg) ssrintros_ne(ipats) ] -> [ arg, ipats ]
-END
-
-TACTIC EXTEND ssrtclintros
-| [ "YouShouldNotTypeThis" ssrintrosarg(arg) ] ->
- [ let tac, intros = arg in
- ssrevaltac ist tac <*> tclIPATssr intros ]
-END
-
-(** Defined identifier *)
-let pr_ssrfwdid id = pr_spc () ++ pr_id id
-
-let pr_ssrfwdidx _ _ _ = pr_ssrfwdid
-
-(* We use a primitive parser for the head identifier of forward *)
-(* tactis to avoid syntactic conflicts with basic Coq tactics. *)
-ARGUMENT EXTEND ssrfwdid TYPED AS ident PRINTED BY pr_ssrfwdidx
- | [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-let accept_ssrfwdid strm =
- match stream_nth 0 strm with
- | Tok.IDENT id -> accept_before_syms_or_any_id [":"; ":="; "("] strm
- | _ -> raise Stream.Failure
-
-
-let test_ssrfwdid = Gram.Entry.of_parser "test_ssrfwdid" accept_ssrfwdid
-
-GEXTEND Gram
- GLOBAL: ssrfwdid;
- ssrfwdid: [[ test_ssrfwdid; id = Prim.ident -> id ]];
- END
-
-
-(* by *)
-(** Tactical arguments. *)
-
-(* We have four kinds: simple tactics, [|]-bracketed lists, hints, and swaps *)
-(* The latter two are used in forward-chaining tactics (have, suffice, wlog) *)
-(* and subgoal reordering tacticals (; first & ; last), respectively. *)
-
-
-let pr_ortacs prt =
- let rec pr_rec = function
- | [None] -> spc() ++ str "|" ++ spc()
- | None :: tacs -> spc() ++ str "|" ++ pr_rec tacs
- | Some tac :: tacs -> spc() ++ str "| " ++ prt tacltop tac ++ pr_rec tacs
- | [] -> mt() in
- function
- | [None] -> spc()
- | None :: tacs -> pr_rec tacs
- | Some tac :: tacs -> prt tacltop tac ++ pr_rec tacs
- | [] -> mt()
-let pr_ssrortacs _ _ = pr_ortacs
-
-ARGUMENT EXTEND ssrortacs TYPED AS tactic option list PRINTED BY pr_ssrortacs
-| [ ssrtacarg(tac) "|" ssrortacs(tacs) ] -> [ Some tac :: tacs ]
-| [ ssrtacarg(tac) "|" ] -> [ [Some tac; None] ]
-| [ ssrtacarg(tac) ] -> [ [Some tac] ]
-| [ "|" ssrortacs(tacs) ] -> [ None :: tacs ]
-| [ "|" ] -> [ [None; None] ]
-END
-
-let pr_hintarg prt = function
- | true, tacs -> hv 0 (str "[ " ++ pr_ortacs prt tacs ++ str " ]")
- | false, [Some tac] -> prt tacltop tac
- | _, _ -> mt()
-
-let pr_ssrhintarg _ _ = pr_hintarg
-
-
-ARGUMENT EXTEND ssrhintarg TYPED AS bool * ssrortacs PRINTED BY pr_ssrhintarg
-| [ "[" "]" ] -> [ nullhint ]
-| [ "[" ssrortacs(tacs) "]" ] -> [ mk_orhint tacs ]
-| [ ssrtacarg(arg) ] -> [ mk_hint arg ]
-END
-
-ARGUMENT EXTEND ssrortacarg TYPED AS ssrhintarg PRINTED BY pr_ssrhintarg
-| [ "[" ssrortacs(tacs) "]" ] -> [ mk_orhint tacs ]
-END
-
-
-let pr_hint prt arg =
- if arg = nohint then mt() else str "by " ++ pr_hintarg prt arg
-let pr_ssrhint _ _ = pr_hint
-
-ARGUMENT EXTEND ssrhint TYPED AS ssrhintarg PRINTED BY pr_ssrhint
-| [ ] -> [ nohint ]
-END
-(** The "in" pseudo-tactical *)(* {{{ **********************************************)
-
-(* We can't make "in" into a general tactical because this would create a *)
-(* crippling conflict with the ltac let .. in construct. Hence, we add *)
-(* explicitly an "in" suffix to all the extended tactics for which it is *)
-(* relevant (including move, case, elim) and to the extended do tactical *)
-(* below, which yields a general-purpose "in" of the form do [...] in ... *)
-
-(* This tactical needs to come before the intro tactics because the latter *)
-(* must take precautions in order not to interfere with the discharged *)
-(* assumptions. This is especially difficult for discharged "let"s, which *)
-(* the default simpl and unfold tactics would erase blindly. *)
-
-open Ssrmatching_plugin.Ssrmatching
-open Ssrmatching_plugin.G_ssrmatching
-
-let pr_wgen = function
- | (clr, Some((id,k),None)) -> spc() ++ pr_clear mt clr ++ str k ++ pr_hoi id
- | (clr, Some((id,k),Some p)) ->
- spc() ++ pr_clear mt clr ++ str"(" ++ str k ++ pr_hoi id ++ str ":=" ++
- pr_cpattern p ++ str ")"
- | (clr, None) -> spc () ++ pr_clear mt clr
-let pr_ssrwgen _ _ _ = pr_wgen
-
-(* no globwith for char *)
-ARGUMENT EXTEND ssrwgen
- TYPED AS ssrclear * ((ssrhoi_hyp * string) * cpattern option) option
- PRINTED BY pr_ssrwgen
-| [ ssrclear_ne(clr) ] -> [ clr, None ]
-| [ ssrhoi_hyp(hyp) ] -> [ [], Some((hyp, " "), None) ]
-| [ "@" ssrhoi_hyp(hyp) ] -> [ [], Some((hyp, "@"), None) ]
-| [ "(" ssrhoi_id(id) ":=" lcpattern(p) ")" ] ->
- [ [], Some ((id," "),Some p) ]
-| [ "(" ssrhoi_id(id) ")" ] -> [ [], Some ((id,"("), None) ]
-| [ "(@" ssrhoi_id(id) ":=" lcpattern(p) ")" ] ->
- [ [], Some ((id,"@"),Some p) ]
-| [ "(" "@" ssrhoi_id(id) ":=" lcpattern(p) ")" ] ->
- [ [], Some ((id,"@"),Some p) ]
-END
-
-let pr_clseq = function
- | InGoal | InHyps -> mt ()
- | InSeqGoal -> str "|- *"
- | InHypsSeqGoal -> str " |- *"
- | InHypsGoal -> str " *"
- | InAll -> str "*"
- | InHypsSeq -> str " |-"
- | InAllHyps -> str "* |-"
-
-let wit_ssrclseq = add_genarg "ssrclseq" pr_clseq
-let pr_clausehyps = pr_list pr_spc pr_wgen
-let pr_ssrclausehyps _ _ _ = pr_clausehyps
-
-ARGUMENT EXTEND ssrclausehyps
-TYPED AS ssrwgen list PRINTED BY pr_ssrclausehyps
-| [ ssrwgen(hyp) "," ssrclausehyps(hyps) ] -> [ hyp :: hyps ]
-| [ ssrwgen(hyp) ssrclausehyps(hyps) ] -> [ hyp :: hyps ]
-| [ ssrwgen(hyp) ] -> [ [hyp] ]
-END
-
-(* type ssrclauses = ssrahyps * ssrclseq *)
-
-let pr_clauses (hyps, clseq) =
- if clseq = InGoal then mt ()
- else str "in " ++ pr_clausehyps hyps ++ pr_clseq clseq
-let pr_ssrclauses _ _ _ = pr_clauses
-
-ARGUMENT EXTEND ssrclauses TYPED AS ssrwgen list * ssrclseq
- PRINTED BY pr_ssrclauses
- | [ "in" ssrclausehyps(hyps) "|-" "*" ] -> [ hyps, InHypsSeqGoal ]
- | [ "in" ssrclausehyps(hyps) "|-" ] -> [ hyps, InHypsSeq ]
- | [ "in" ssrclausehyps(hyps) "*" ] -> [ hyps, InHypsGoal ]
- | [ "in" ssrclausehyps(hyps) ] -> [ hyps, InHyps ]
- | [ "in" "|-" "*" ] -> [ [], InSeqGoal ]
- | [ "in" "*" ] -> [ [], InAll ]
- | [ "in" "*" "|-" ] -> [ [], InAllHyps ]
- | [ ] -> [ [], InGoal ]
-END
-
-
-
-
-(** Definition value formatting *)
-
-(* We use an intermediate structure to correctly render the binder list *)
-(* abbreviations. We use a list of hints to extract the binders and *)
-(* base term from a term, for the two first levels of representation of *)
-(* of constr terms. *)
-
-let pr_binder prl = function
- | Bvar x ->
- pr_name x
- | Bdecl (xs, t) ->
- str "(" ++ pr_list pr_spc pr_name xs ++ str " : " ++ prl t ++ str ")"
- | Bdef (x, None, v) ->
- str "(" ++ pr_name x ++ str " := " ++ prl v ++ str ")"
- | Bdef (x, Some t, v) ->
- str "(" ++ pr_name x ++ str " : " ++ prl t ++
- str " := " ++ prl v ++ str ")"
- | Bstruct x ->
- str "{struct " ++ pr_name x ++ str "}"
- | Bcast t ->
- str ": " ++ prl t
-
-let rec format_local_binders h0 bl0 = match h0, bl0 with
- | BFvar :: h, CLocalAssum ([{CAst.v=x}], _, _) :: bl ->
- Bvar x :: format_local_binders h bl
- | BFdecl _ :: h, CLocalAssum (lxs, _, t) :: bl ->
- Bdecl (List.map (fun x -> x.CAst.v) lxs, t) :: format_local_binders h bl
- | BFdef :: h, CLocalDef ({CAst.v=x}, v, oty) :: bl ->
- Bdef (x, oty, v) :: format_local_binders h bl
- | _ -> []
-
-let rec format_constr_expr h0 c0 = let open CAst in match h0, c0 with
- | BFvar :: h, { v = CLambdaN ([CLocalAssum([{CAst.v=x}], _, _)], c) } ->
- let bs, c' = format_constr_expr h c in
- Bvar x :: bs, c'
- | BFdecl _:: h, { v = CLambdaN ([CLocalAssum(lxs, _, t)], c) } ->
- let bs, c' = format_constr_expr h c in
- Bdecl (List.map (fun x -> x.CAst.v) lxs, t) :: bs, c'
- | BFdef :: h, { v = CLetIn({CAst.v=x}, v, oty, c) } ->
- let bs, c' = format_constr_expr h c in
- Bdef (x, oty, v) :: bs, c'
- | [BFcast], { v = CCast (c, Glob_term.CastConv t) } ->
- [Bcast t], c
- | BFrec (has_str, has_cast) :: h,
- { v = CFix ( _, [_, (Some locn, CStructRec), bl, t, c]) } ->
- let bs = format_local_binders h bl in
- let bstr = if has_str then [Bstruct (Name locn.CAst.v)] else [] in
- bs @ bstr @ (if has_cast then [Bcast t] else []), c
- | BFrec (_, has_cast) :: h, { v = CCoFix ( _, [_, bl, t, c]) } ->
- format_local_binders h bl @ (if has_cast then [Bcast t] else []), c
- | _, c ->
- [], c
-
-(** Forward chaining argument *)
-
-(* There are three kinds of forward definitions: *)
-(* - Hint: type only, cast to Type, may have proof hint. *)
-(* - Have: type option + value, no space before type *)
-(* - Pose: binders + value, space before binders. *)
-
-let pr_fwdkind = function
- | FwdHint (s,_) -> str (s ^ " ") | _ -> str " :=" ++ spc ()
-let pr_fwdfmt (fk, _ : ssrfwdfmt) = pr_fwdkind fk
-
-let wit_ssrfwdfmt = add_genarg "ssrfwdfmt" pr_fwdfmt
-
-(* type ssrfwd = ssrfwdfmt * ssrterm *)
-
-let mkFwdVal fk c = ((fk, []), c)
-let mkssrFwdVal fk c = ((fk, []), (c,None))
-let dC t = Glob_term.CastConv t
-
-let same_ist { interp_env = x } { interp_env = y } =
- match x,y with
- | None, None -> true
- | Some a, Some b -> a == b
- | _ -> false
-
-let mkFwdCast fk ?loc ?c t =
- let c = match c with
- | None -> mkCHole loc
- | Some c -> assert (same_ist t c); c.body in
- ((fk, [BFcast]),
- { t with annotation = `None;
- body = (CAst.make ?loc @@ CCast (c, dC t.body)) })
-
-let mkssrFwdCast fk loc t c = ((fk, [BFcast]), (c, Some t))
-
-let mkFwdHint s t =
- let loc = Constrexpr_ops.constr_loc t.body in
- mkFwdCast (FwdHint (s,false)) ?loc t
-let mkFwdHintNoTC s t =
- let loc = Constrexpr_ops.constr_loc t.body in
- mkFwdCast (FwdHint (s,true)) ?loc t
-
-let pr_gen_fwd prval prc prlc fk (bs, c) =
- let prc s = str s ++ spc () ++ prval prc prlc c in
- match fk, bs with
- | FwdHint (s,_), [Bcast t] -> str s ++ spc () ++ prlc t
- | FwdHint (s,_), _ -> prc (s ^ "(* typeof *)")
- | FwdHave, [Bcast t] -> str ":" ++ spc () ++ prlc t ++ prc " :="
- | _, [] -> prc " :="
- | _, _ -> spc () ++ pr_list spc (pr_binder prlc) bs ++ prc " :="
-
-let pr_fwd_guarded prval prval' = function
-| (fk, h), c ->
- pr_gen_fwd prval pr_constr_expr prl_constr_expr fk (format_constr_expr h c.body)
-
-let pr_unguarded prc prlc = prlc
-
-let pr_fwd = pr_fwd_guarded pr_unguarded pr_unguarded
-let pr_ssrfwd _ _ _ = pr_fwd
-
-ARGUMENT EXTEND ssrfwd TYPED AS (ssrfwdfmt * ast_closure_lterm) PRINTED BY pr_ssrfwd
- | [ ":=" ast_closure_lterm(c) ] -> [ mkFwdVal FwdPose c ]
- | [ ":" ast_closure_lterm (t) ":=" ast_closure_lterm(c) ] -> [ mkFwdCast FwdPose ~loc t ~c ]
-END
-
-(** Independent parsing for binders *)
-
-(* The pose, pose fix, and pose cofix tactics use these internally to *)
-(* parse argument fragments. *)
-
-let pr_ssrbvar prc _ _ v = prc v
-
-ARGUMENT EXTEND ssrbvar TYPED AS constr PRINTED BY pr_ssrbvar
-| [ ident(id) ] -> [ mkCVar ~loc id ]
-| [ "_" ] -> [ mkCHole (Some loc) ]
-END
-
-let bvar_lname = let open CAst in function
- | { v = CRef (qid, _) } when qualid_is_ident qid ->
- CAst.make ?loc:qid.CAst.loc @@ Name (qualid_basename qid)
- | { loc = loc } -> CAst.make ?loc Anonymous
-
-let pr_ssrbinder prc _ _ (_, c) = prc c
-
-ARGUMENT EXTEND ssrbinder TYPED AS ssrfwdfmt * constr PRINTED BY pr_ssrbinder
- | [ ssrbvar(bv) ] ->
- [ let { CAst.loc=xloc } as x = bvar_lname bv in
- (FwdPose, [BFvar]),
- CAst.make ~loc @@ CLambdaN ([CLocalAssum([x],Default Explicit,mkCHole xloc)],mkCHole (Some loc)) ]
- | [ "(" ssrbvar(bv) ")" ] ->
- [ let { CAst.loc=xloc } as x = bvar_lname bv in
- (FwdPose, [BFvar]),
- CAst.make ~loc @@ CLambdaN ([CLocalAssum([x],Default Explicit,mkCHole xloc)],mkCHole (Some loc)) ]
- | [ "(" ssrbvar(bv) ":" lconstr(t) ")" ] ->
- [ let x = bvar_lname bv in
- (FwdPose, [BFdecl 1]),
- CAst.make ~loc @@ CLambdaN ([CLocalAssum([x], Default Explicit, t)], mkCHole (Some loc)) ]
- | [ "(" ssrbvar(bv) ne_ssrbvar_list(bvs) ":" lconstr(t) ")" ] ->
- [ let xs = List.map bvar_lname (bv :: bvs) in
- let n = List.length xs in
- (FwdPose, [BFdecl n]),
- CAst.make ~loc @@ CLambdaN ([CLocalAssum (xs, Default Explicit, t)], mkCHole (Some loc)) ]
- | [ "(" ssrbvar(id) ":" lconstr(t) ":=" lconstr(v) ")" ] ->
- [ (FwdPose,[BFdef]), CAst.make ~loc @@ CLetIn (bvar_lname id, v, Some t, mkCHole (Some loc)) ]
- | [ "(" ssrbvar(id) ":=" lconstr(v) ")" ] ->
- [ (FwdPose,[BFdef]), CAst.make ~loc @@ CLetIn (bvar_lname id, v, None, mkCHole (Some loc)) ]
- END
-
-GEXTEND Gram
- GLOBAL: ssrbinder;
- ssrbinder: [
- [ ["of" | "&"]; c = operconstr LEVEL "99" ->
- let loc = !@loc in
- (FwdPose, [BFvar]),
- CAst.make ~loc @@ CLambdaN ([CLocalAssum ([CAst.make ~loc Anonymous],Default Explicit,c)],mkCHole (Some loc)) ]
- ];
-END
-
-let rec binders_fmts = function
- | ((_, h), _) :: bs -> h @ binders_fmts bs
- | _ -> []
-
-let push_binders c2 bs =
- let loc2 = constr_loc c2 in let mkloc loc1 = Loc.merge_opt loc1 loc2 in
- let open CAst in
- let rec loop ty c = function
- | (_, { loc = loc1; v = CLambdaN (b, _) } ) :: bs when ty ->
- CAst.make ?loc:(mkloc loc1) @@ CProdN (b, loop ty c bs)
- | (_, { loc = loc1; v = CLambdaN (b, _) } ) :: bs ->
- CAst.make ?loc:(mkloc loc1) @@ CLambdaN (b, loop ty c bs)
- | (_, { loc = loc1; v = CLetIn (x, v, oty, _) } ) :: bs ->
- CAst.make ?loc:(mkloc loc1) @@ CLetIn (x, v, oty, loop ty c bs)
- | [] -> c
- | _ -> anomaly "binder not a lambda nor a let in" in
- match c2 with
- | { loc; v = CCast (ct, Glob_term.CastConv cty) } ->
- CAst.make ?loc @@ (CCast (loop false ct bs, Glob_term.CastConv (loop true cty bs)))
- | ct -> loop false ct bs
-
-let rec fix_binders = let open CAst in function
- | (_, { v = CLambdaN ([CLocalAssum(xs, _, t)], _) } ) :: bs ->
- CLocalAssum (xs, Default Explicit, t) :: fix_binders bs
- | (_, { v = CLetIn (x, v, oty, _) } ) :: bs ->
- CLocalDef (x, v, oty) :: fix_binders bs
- | _ -> []
-
-let pr_ssrstruct _ _ _ = function
- | Some id -> str "{struct " ++ pr_id id ++ str "}"
- | None -> mt ()
-
-ARGUMENT EXTEND ssrstruct TYPED AS ident option PRINTED BY pr_ssrstruct
-| [ "{" "struct" ident(id) "}" ] -> [ Some id ]
-| [ ] -> [ None ]
-END
-
-(** The "pose" tactic *)
-
-(* The plain pose form. *)
-
-let bind_fwd bs ((fk, h), c) =
- (fk,binders_fmts bs @ h), { c with body = push_binders c.body bs }
-
-ARGUMENT EXTEND ssrposefwd TYPED AS ssrfwd PRINTED BY pr_ssrfwd
- | [ ssrbinder_list(bs) ssrfwd(fwd) ] -> [ bind_fwd bs fwd ]
-END
-
-(* The pose fix form. *)
-
-let pr_ssrfixfwd _ _ _ (id, fwd) = str " fix " ++ pr_id id ++ pr_fwd fwd
-
-let bvar_locid = function
- | { CAst.v = CRef (qid, _) } when qualid_is_ident qid ->
- CAst.make ?loc:qid.CAst.loc (qualid_basename qid)
- | _ -> CErrors.user_err (Pp.str "Missing identifier after \"(co)fix\"")
-
-
-ARGUMENT EXTEND ssrfixfwd TYPED AS ident * ssrfwd PRINTED BY pr_ssrfixfwd
- | [ "fix" ssrbvar(bv) ssrbinder_list(bs) ssrstruct(sid) ssrfwd(fwd) ] ->
- [ let { CAst.v=id } as lid = bvar_locid bv in
- let (fk, h), ac = fwd in
- let c = ac.body in
- let has_cast, t', c' = match format_constr_expr h c with
- | [Bcast t'], c' -> true, t', c'
- | _ -> false, mkCHole (constr_loc c), c in
- let lb = fix_binders bs in
- let has_struct, i =
- let rec loop = function
- | {CAst.loc=l'; v=Name id'} :: _ when Option.equal Id.equal sid (Some id') ->
- true, CAst.make ?loc:l' id'
- | [{CAst.loc=l';v=Name id'}] when sid = None ->
- false, CAst.make ?loc:l' id'
- | _ :: bn -> loop bn
- | [] -> CErrors.user_err (Pp.str "Bad structural argument") in
- loop (names_of_local_assums lb) in
- let h' = BFrec (has_struct, has_cast) :: binders_fmts bs in
- let fix = CAst.make ~loc @@ CFix (lid, [lid, (Some i, CStructRec), lb, t', c']) in
- id, ((fk, h'), { ac with body = fix }) ]
-END
-
-
-(* The pose cofix form. *)
-
-let pr_ssrcofixfwd _ _ _ (id, fwd) = str " cofix " ++ pr_id id ++ pr_fwd fwd
-
-ARGUMENT EXTEND ssrcofixfwd TYPED AS ssrfixfwd PRINTED BY pr_ssrcofixfwd
- | [ "cofix" ssrbvar(bv) ssrbinder_list(bs) ssrfwd(fwd) ] ->
- [ let { CAst.v=id } as lid = bvar_locid bv in
- let (fk, h), ac = fwd in
- let c = ac.body in
- let has_cast, t', c' = match format_constr_expr h c with
- | [Bcast t'], c' -> true, t', c'
- | _ -> false, mkCHole (constr_loc c), c in
- let h' = BFrec (false, has_cast) :: binders_fmts bs in
- let cofix = CAst.make ~loc @@ CCoFix (lid, [lid, fix_binders bs, t', c']) in
- id, ((fk, h'), { ac with body = cofix })
- ]
-END
-
-(* This does not print the type, it should be fixed... *)
-let pr_ssrsetfwd _ _ _ (((fk,_),(t,_)), docc) =
- pr_gen_fwd (fun _ _ -> pr_cpattern)
- (fun _ -> mt()) (fun _ -> mt()) fk ([Bcast ()],t)
-
-ARGUMENT EXTEND ssrsetfwd
-TYPED AS (ssrfwdfmt * (lcpattern * ast_closure_lterm option)) * ssrdocc
-PRINTED BY pr_ssrsetfwd
-| [ ":" ast_closure_lterm(t) ":=" "{" ssrocc(occ) "}" cpattern(c) ] ->
- [ mkssrFwdCast FwdPose loc t c, mkocc occ ]
-| [ ":" ast_closure_lterm(t) ":=" lcpattern(c) ] ->
- [ mkssrFwdCast FwdPose loc t c, nodocc ]
-| [ ":=" "{" ssrocc(occ) "}" cpattern(c) ] ->
- [ mkssrFwdVal FwdPose c, mkocc occ ]
-| [ ":=" lcpattern(c) ] -> [ mkssrFwdVal FwdPose c, nodocc ]
-END
-
-
-let pr_ssrhavefwd _ _ prt (fwd, hint) = pr_fwd fwd ++ pr_hint prt hint
-
-ARGUMENT EXTEND ssrhavefwd TYPED AS ssrfwd * ssrhint PRINTED BY pr_ssrhavefwd
-| [ ":" ast_closure_lterm(t) ssrhint(hint) ] -> [ mkFwdHint ":" t, hint ]
-| [ ":" ast_closure_lterm(t) ":=" ast_closure_lterm(c) ] -> [ mkFwdCast FwdHave ~loc t ~c, nohint ]
-| [ ":" ast_closure_lterm(t) ":=" ] -> [ mkFwdHintNoTC ":" t, nohint ]
-| [ ":=" ast_closure_lterm(c) ] -> [ mkFwdVal FwdHave c, nohint ]
-END
-
-let intro_id_to_binder = List.map (function
- | IPatId id ->
- let { CAst.loc=xloc } as x = bvar_lname (mkCVar id) in
- (FwdPose, [BFvar]),
- CAst.make @@ CLambdaN ([CLocalAssum([x], Default Explicit, mkCHole xloc)],
- mkCHole None)
- | _ -> anomaly "non-id accepted as binder")
-
-let binder_to_intro_id = CAst.(List.map (function
- | (FwdPose, [BFvar]), { v = CLambdaN ([CLocalAssum(ids,_,_)],_) }
- | (FwdPose, [BFdecl _]), { v = CLambdaN ([CLocalAssum(ids,_,_)],_) } ->
- List.map (function {v=Name id} -> IPatId id | _ -> IPatAnon One) ids
- | (FwdPose, [BFdef]), { v = CLetIn ({v=Name id},_,_,_) } -> [IPatId id]
- | (FwdPose, [BFdef]), { v = CLetIn ({v=Anonymous},_,_,_) } -> [IPatAnon One]
- | _ -> anomaly "ssrbinder is not a binder"))
-
-let pr_ssrhavefwdwbinders _ _ prt (tr,((hpats, (fwd, hint)))) =
- pr_hpats hpats ++ pr_fwd fwd ++ pr_hint prt hint
-
-ARGUMENT EXTEND ssrhavefwdwbinders
- TYPED AS bool * (ssrhpats * (ssrfwd * ssrhint))
- PRINTED BY pr_ssrhavefwdwbinders
-| [ ssrhpats_wtransp(trpats) ssrbinder_list(bs) ssrhavefwd(fwd) ] ->
- [ let tr, pats = trpats in
- let ((clr, pats), binders), simpl = pats in
- let allbs = intro_id_to_binder binders @ bs in
- let allbinders = binders @ List.flatten (binder_to_intro_id bs) in
- let hint = bind_fwd allbs (fst fwd), snd fwd in
- tr, ((((clr, pats), allbinders), simpl), hint) ]
-END
-
-
-let pr_ssrdoarg prc _ prt (((n, m), tac), clauses) =
- pr_index n ++ pr_mmod m ++ pr_hintarg prt tac ++ pr_clauses clauses
-
-ARGUMENT EXTEND ssrdoarg
- TYPED AS ((ssrindex * ssrmmod) * ssrhintarg) * ssrclauses
- PRINTED BY pr_ssrdoarg
-| [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-(* type ssrseqarg = ssrindex * (ssrtacarg * ssrtac option) *)
-
-let pr_seqtacarg prt = function
- | (is_first, []), _ -> str (if is_first then "first" else "last")
- | tac, Some dtac ->
- hv 0 (pr_hintarg prt tac ++ spc() ++ str "|| " ++ prt tacltop dtac)
- | tac, _ -> pr_hintarg prt tac
-
-let pr_ssrseqarg _ _ prt = function
- | ArgArg 0, tac -> pr_seqtacarg prt tac
- | i, tac -> pr_index i ++ str " " ++ pr_seqtacarg prt tac
-
-(* We must parse the index separately to resolve the conflict with *)
-(* an unindexed tactic. *)
-ARGUMENT EXTEND ssrseqarg TYPED AS ssrindex * (ssrhintarg * tactic option)
- PRINTED BY pr_ssrseqarg
-| [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-let sq_brace_tacnames =
- ["first"; "solve"; "do"; "rewrite"; "have"; "suffices"; "wlog"]
- (* "by" is a keyword *)
-let accept_ssrseqvar strm =
- match stream_nth 0 strm with
- | Tok.IDENT id when not (List.mem id sq_brace_tacnames) ->
- accept_before_syms_or_ids ["["] ["first";"last"] strm
- | _ -> raise Stream.Failure
-
-let test_ssrseqvar = Gram.Entry.of_parser "test_ssrseqvar" accept_ssrseqvar
-
-let swaptacarg (loc, b) = (b, []), Some (TacId [])
-
-let check_seqtacarg dir arg = match snd arg, dir with
- | ((true, []), Some (TacAtom (loc, _))), L2R ->
- CErrors.user_err ?loc (str "expected \"last\"")
- | ((false, []), Some (TacAtom (loc, _))), R2L ->
- CErrors.user_err ?loc (str "expected \"first\"")
- | _, _ -> arg
-
-let ssrorelse = Entry.create "ssrorelse"
-GEXTEND Gram
- GLOBAL: ssrorelse ssrseqarg;
- ssrseqidx: [
- [ test_ssrseqvar; id = Prim.ident -> ArgVar (CAst.make ~loc:!@loc id)
- | n = Prim.natural -> ArgArg (check_index ~loc:!@loc n)
- ] ];
- ssrswap: [[ IDENT "first" -> !@loc, true | IDENT "last" -> !@loc, false ]];
- ssrorelse: [[ "||"; tac = tactic_expr LEVEL "2" -> tac ]];
- ssrseqarg: [
- [ arg = ssrswap -> noindex, swaptacarg arg
- | i = ssrseqidx; tac = ssrortacarg; def = OPT ssrorelse -> i, (tac, def)
- | i = ssrseqidx; arg = ssrswap -> i, swaptacarg arg
- | tac = tactic_expr LEVEL "3" -> noindex, (mk_hint tac, None)
- ] ];
-END
-
-let tactic_expr = Pltac.tactic_expr
-
-(** 1. Utilities *)
-
-(** Tactic-level diagnosis *)
-
-(* debug *)
-
-(* Let's play with the new proof engine API *)
-let old_tac = V82.tactic
-
-
-(** Name generation *)(* {{{ *******************************************************)
-
-(* Since Coq now does repeated internal checks of its external lexical *)
-(* rules, we now need to carve ssreflect reserved identifiers out of *)
-(* out of the user namespace. We use identifiers of the form _id_ for *)
-(* this purpose, e.g., we "anonymize" an identifier id as _id_, adding *)
-(* an extra leading _ if this might clash with an internal identifier. *)
-(* We check for ssreflect identifiers in the ident grammar rule; *)
-(* when the ssreflect Module is present this is normally an error, *)
-(* but we provide a compatibility flag to reduce this to a warning. *)
-
-let ssr_reserved_ids = Summary.ref ~name:"SSR:idents" true
-
-let _ =
- Goptions.declare_bool_option
- { Goptions.optname = "ssreflect identifiers";
- Goptions.optkey = ["SsrIdents"];
- Goptions.optdepr = false;
- Goptions.optread = (fun _ -> !ssr_reserved_ids);
- Goptions.optwrite = (fun b -> ssr_reserved_ids := b)
- }
-
-let is_ssr_reserved s =
- let n = String.length s in n > 2 && s.[0] = '_' && s.[n - 1] = '_'
-
-let ssr_id_of_string loc s =
- if is_ssr_reserved s && is_ssr_loaded () then begin
- if !ssr_reserved_ids then
- CErrors.user_err ~loc (str ("The identifier " ^ s ^ " is reserved."))
- else if is_internal_name s then
- Feedback.msg_warning (str ("Conflict between " ^ s ^ " and ssreflect internal names."))
- else Feedback.msg_warning (str (
- "The name " ^ s ^ " fits the _xxx_ format used for anonymous variables.\n"
- ^ "Scripts with explicit references to anonymous variables are fragile."))
- end; Id.of_string s
-
-let ssr_null_entry = Gram.Entry.of_parser "ssr_null" (fun _ -> ())
-
-let (!@) = Pcoq.to_coqloc
-
-GEXTEND Gram
- GLOBAL: Prim.ident;
- Prim.ident: [[ s = IDENT; ssr_null_entry -> ssr_id_of_string !@loc s ]];
-END
-
-let perm_tag = "_perm_Hyp_"
-let _ = add_internal_name (is_tagged perm_tag)
-
-(* }}} *)
-
-(* We must not anonymize context names discharged by the "in" tactical. *)
-
-(** Tactical extensions. *)(* {{{ **************************************************)
-
-(* The TACTIC EXTEND facility can't be used for defining new user *)
-(* tacticals, because: *)
-(* - the concrete syntax must start with a fixed string *)
-(* We use the following workaround: *)
-(* - We use the (unparsable) "YouShouldNotTypeThis" token for tacticals that *)
-(* don't start with a token, then redefine the grammar and *)
-(* printer using GEXTEND and set_pr_ssrtac, respectively. *)
-
-type ssrargfmt = ArgSsr of string | ArgSep of string
-
-let ssrtac_name name = {
- mltac_plugin = "ssreflect_plugin";
- mltac_tactic = "ssr" ^ name;
-}
-
-let ssrtac_entry name n = {
- mltac_name = ssrtac_name name;
- mltac_index = n;
-}
-
-let set_pr_ssrtac name prec afmt = (* FIXME *) () (*
- let fmt = List.map (function
- | ArgSep s -> Egramml.GramTerminal s
- | ArgSsr s -> Egramml.GramTerminal s
- | ArgCoq at -> Egramml.GramTerminal "COQ_ARG") afmt in
- let tacname = ssrtac_name name in () *)
-
-let ssrtac_atom ?loc name args = TacML (Loc.tag ?loc (ssrtac_entry name 0, args))
-let ssrtac_expr ?loc name args = ssrtac_atom ?loc name args
-
-let tclintros_expr ?loc tac ipats =
- let args = [Tacexpr.TacGeneric (in_gen (rawwit wit_ssrintrosarg) (tac, ipats))] in
- ssrtac_expr ?loc "tclintros" args
-
-GEXTEND Gram
- GLOBAL: tactic_expr;
- tactic_expr: LEVEL "1" [ RIGHTA
- [ tac = tactic_expr; intros = ssrintros_ne -> tclintros_expr ~loc:!@loc tac intros
- ] ];
-END
-
-(* }}} *)
-
-
-(** Bracketing tactical *)
-
-(* The tactic pretty-printer doesn't know that some extended tactics *)
-(* are actually tacticals. To prevent it from improperly removing *)
-(* parentheses we override the parsing rule for bracketed tactic *)
-(* expressions so that the pretty-print always reflects the input. *)
-(* (Removing user-specified parentheses is dubious anyway). *)
-
-GEXTEND Gram
- GLOBAL: tactic_expr;
- ssrparentacarg: [[ "("; tac = tactic_expr; ")" -> Loc.tag ~loc:!@loc (Tacexp tac) ]];
- tactic_expr: LEVEL "0" [[ arg = ssrparentacarg -> TacArg arg ]];
-END
-
-(** The internal "done" and "ssrautoprop" tactics. *)
-
-(* For additional flexibility, "done" and "ssrautoprop" are *)
-(* defined in Ltac. *)
-(* Although we provide a default definition in ssreflect, *)
-(* we look up the definition dynamically at each call point, *)
-(* to allow for user extensions. "ssrautoprop" defaults to *)
-(* trivial. *)
-
-let ssrautoprop gl =
- try
- let tacname =
- try Tacenv.locate_tactic (qualid_of_ident (Id.of_string "ssrautoprop"))
- with Not_found -> Tacenv.locate_tactic (ssrqid "ssrautoprop") in
- let tacexpr = Loc.tag @@ Tacexpr.Reference (ArgArg (Loc.tag @@ tacname)) in
- V82.of_tactic (eval_tactic (Tacexpr.TacArg tacexpr)) gl
- with Not_found -> V82.of_tactic (Auto.full_trivial []) gl
-
-let () = ssrautoprop_tac := ssrautoprop
-
-let tclBY tac = Tacticals.tclTHEN tac (donetac ~-1)
-
-(** Tactical arguments. *)
-
-(* We have four kinds: simple tactics, [|]-bracketed lists, hints, and swaps *)
-(* The latter two are used in forward-chaining tactics (have, suffice, wlog) *)
-(* and subgoal reordering tacticals (; first & ; last), respectively. *)
-
-(* Force use of the tactic_expr parsing entry, to rule out tick marks. *)
-
-(** The "by" tactical. *)
-
-
-open Ssrfwd
-
-TACTIC EXTEND ssrtclby
-| [ "by" ssrhintarg(tac) ] -> [ V82.tactic (hinttac ist true tac) ]
-END
-
-(* }}} *)
-(* We can't parse "by" in ARGUMENT EXTEND because it will only be made *)
-(* into a keyword in ssreflect.v; so we anticipate this in GEXTEND. *)
-
-GEXTEND Gram
- GLOBAL: ssrhint simple_tactic;
- ssrhint: [[ "by"; arg = ssrhintarg -> arg ]];
-END
-
-(** The "do" tactical. ********************************************************)
-
-(*
-type ssrdoarg = ((ssrindex * ssrmmod) * ssrhint) * ssrclauses
-*)
-TACTIC EXTEND ssrtcldo
-| [ "YouShouldNotTypeThis" "do" ssrdoarg(arg) ] -> [ V82.tactic (ssrdotac ist arg) ]
-END
-set_pr_ssrtac "tcldo" 3 [ArgSep "do "; ArgSsr "doarg"]
-
-let ssrdotac_expr ?loc n m tac clauses =
- let arg = ((n, m), tac), clauses in
- ssrtac_expr ?loc "tcldo" [Tacexpr.TacGeneric (in_gen (rawwit wit_ssrdoarg) arg)]
-
-GEXTEND Gram
- GLOBAL: tactic_expr;
- ssrdotac: [
- [ tac = tactic_expr LEVEL "3" -> mk_hint tac
- | tacs = ssrortacarg -> tacs
- ] ];
- tactic_expr: LEVEL "3" [ RIGHTA
- [ IDENT "do"; m = ssrmmod; tac = ssrdotac; clauses = ssrclauses ->
- ssrdotac_expr ~loc:!@loc noindex m tac clauses
- | IDENT "do"; tac = ssrortacarg; clauses = ssrclauses ->
- ssrdotac_expr ~loc:!@loc noindex Once tac clauses
- | IDENT "do"; n = int_or_var; m = ssrmmod;
- tac = ssrdotac; clauses = ssrclauses ->
- ssrdotac_expr ~loc:!@loc (mk_index ~loc:!@loc n) m tac clauses
- ] ];
-END
-(* }}} *)
-
-
-(* We can't actually parse the direction separately because this *)
-(* would introduce conflicts with the basic ltac syntax. *)
-let pr_ssrseqdir _ _ _ = function
- | L2R -> str ";" ++ spc () ++ str "first "
- | R2L -> str ";" ++ spc () ++ str "last "
-
-ARGUMENT EXTEND ssrseqdir TYPED AS ssrdir PRINTED BY pr_ssrseqdir
-| [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-TACTIC EXTEND ssrtclseq
-| [ "YouShouldNotTypeThis" ssrtclarg(tac) ssrseqdir(dir) ssrseqarg(arg) ] ->
- [ V82.tactic (tclSEQAT ist tac dir arg) ]
-END
-set_pr_ssrtac "tclseq" 5 [ArgSsr "tclarg"; ArgSsr "seqdir"; ArgSsr "seqarg"]
-
-let tclseq_expr ?loc tac dir arg =
- let arg1 = in_gen (rawwit wit_ssrtclarg) tac in
- let arg2 = in_gen (rawwit wit_ssrseqdir) dir in
- let arg3 = in_gen (rawwit wit_ssrseqarg) (check_seqtacarg dir arg) in
- ssrtac_expr ?loc "tclseq" (List.map (fun x -> Tacexpr.TacGeneric x) [arg1; arg2; arg3])
-
-GEXTEND Gram
- GLOBAL: tactic_expr;
- ssr_first: [
- [ tac = ssr_first; ipats = ssrintros_ne -> tclintros_expr ~loc:!@loc tac ipats
- | "["; tacl = LIST0 tactic_expr SEP "|"; "]" -> TacFirst tacl
- ] ];
- ssr_first_else: [
- [ tac1 = ssr_first; tac2 = ssrorelse -> TacOrelse (tac1, tac2)
- | tac = ssr_first -> tac ]];
- tactic_expr: LEVEL "4" [ LEFTA
- [ tac1 = tactic_expr; ";"; IDENT "first"; tac2 = ssr_first_else ->
- TacThen (tac1, tac2)
- | tac = tactic_expr; ";"; IDENT "first"; arg = ssrseqarg ->
- tclseq_expr ~loc:!@loc tac L2R arg
- | tac = tactic_expr; ";"; IDENT "last"; arg = ssrseqarg ->
- tclseq_expr ~loc:!@loc tac R2L arg
- ] ];
-END
-(* }}} *)
-
-(** 5. Bookkeeping tactics (clear, move, case, elim) *)
-
-(** Generalization (discharge) item *)
-
-(* An item is a switch + term pair. *)
-
-(* type ssrgen = ssrdocc * ssrterm *)
-
-let pr_gen (docc, dt) = pr_docc docc ++ pr_cpattern dt
-
-let pr_ssrgen _ _ _ = pr_gen
-
-ARGUMENT EXTEND ssrgen TYPED AS ssrdocc * cpattern PRINTED BY pr_ssrgen
-| [ ssrdocc(docc) cpattern(dt) ] -> [
- match docc with
- | Some [], _ -> CErrors.user_err ~loc (str"Clear flag {} not allowed here")
- | _ -> docc, dt ]
-| [ cpattern(dt) ] -> [ nodocc, dt ]
-END
-
-let has_occ ((_, occ), _) = occ <> None
-
-(** Generalization (discharge) sequence *)
-
-(* A discharge sequence is represented as a list of up to two *)
-(* lists of d-items, plus an ident list set (the possibly empty *)
-(* final clear switch). The main list is empty iff the command *)
-(* is defective, and has length two if there is a sequence of *)
-(* dependent terms (and in that case it is the first of the two *)
-(* lists). Thus, the first of the two lists is never empty. *)
-
-(* type ssrgens = ssrgen list *)
-(* type ssrdgens = ssrgens list * ssrclear *)
-
-let gens_sep = function [], [] -> mt | _ -> spc
-
-let pr_dgens pr_gen (gensl, clr) =
- let prgens s gens = str s ++ pr_list spc pr_gen gens in
- let prdeps deps = prgens ": " deps ++ spc () ++ str "/" in
- match gensl with
- | [deps; []] -> prdeps deps ++ pr_clear pr_spc clr
- | [deps; gens] -> prdeps deps ++ prgens " " gens ++ pr_clear spc clr
- | [gens] -> prgens ": " gens ++ pr_clear spc clr
- | _ -> pr_clear pr_spc clr
-
-let pr_ssrdgens _ _ _ = pr_dgens pr_gen
-
-let cons_gen gen = function
- | gens :: gensl, clr -> (gen :: gens) :: gensl, clr
- | _ -> anomaly "missing gen list"
-
-let cons_dep (gensl, clr) =
- if List.length gensl = 1 then ([] :: gensl, clr) else
- CErrors.user_err (Pp.str "multiple dependents switches '/'")
-
-ARGUMENT EXTEND ssrdgens_tl TYPED AS ssrgen list list * ssrclear
- PRINTED BY pr_ssrdgens
-| [ "{" ne_ssrhyp_list(clr) "}" cpattern(dt) ssrdgens_tl(dgens) ] ->
- [ cons_gen (mkclr clr, dt) dgens ]
-| [ "{" ne_ssrhyp_list(clr) "}" ] ->
- [ [[]], clr ]
-| [ "{" ssrocc(occ) "}" cpattern(dt) ssrdgens_tl(dgens) ] ->
- [ cons_gen (mkocc occ, dt) dgens ]
-| [ "/" ssrdgens_tl(dgens) ] ->
- [ cons_dep dgens ]
-| [ cpattern(dt) ssrdgens_tl(dgens) ] ->
- [ cons_gen (nodocc, dt) dgens ]
-| [ ] ->
- [ [[]], [] ]
-END
-
-ARGUMENT EXTEND ssrdgens TYPED AS ssrdgens_tl PRINTED BY pr_ssrdgens
-| [ ":" ssrgen(gen) ssrdgens_tl(dgens) ] -> [ cons_gen gen dgens ]
-END
-
-(** Equations *)
-
-(* argument *)
-
-let pr_eqid = function Some pat -> str " " ++ pr_ipat pat | None -> mt ()
-let pr_ssreqid _ _ _ = pr_eqid
-
-(* We must use primitive parsing here to avoid conflicts with the *)
-(* basic move, case, and elim tactics. *)
-ARGUMENT EXTEND ssreqid TYPED AS ssripatrep option PRINTED BY pr_ssreqid
-| [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-let accept_ssreqid strm =
- match Util.stream_nth 0 strm with
- | Tok.IDENT _ -> accept_before_syms [":"] strm
- | Tok.KEYWORD ":" -> ()
- | Tok.KEYWORD pat when List.mem pat ["_"; "?"; "->"; "<-"] ->
- accept_before_syms [":"] strm
- | _ -> raise Stream.Failure
-
-let test_ssreqid = Gram.Entry.of_parser "test_ssreqid" accept_ssreqid
-
-GEXTEND Gram
- GLOBAL: ssreqid;
- ssreqpat: [
- [ id = Prim.ident -> IPatId id
- | "_" -> IPatAnon Drop
- | "?" -> IPatAnon One
- | occ = ssrdocc; "->" -> (match occ with
- | None, occ -> IPatRewrite (occ, L2R)
- | _ -> CErrors.user_err ~loc:!@loc (str"Only occurrences are allowed here"))
- | occ = ssrdocc; "<-" -> (match occ with
- | None, occ -> IPatRewrite (occ, R2L)
- | _ -> CErrors.user_err ~loc:!@loc (str "Only occurrences are allowed here"))
- | "->" -> IPatRewrite (allocc, L2R)
- | "<-" -> IPatRewrite (allocc, R2L)
- ]];
- ssreqid: [
- [ test_ssreqid; pat = ssreqpat -> Some pat
- | test_ssreqid -> None
- ]];
-END
-
-(** Bookkeeping (discharge-intro) argument *)
-
-(* Since all bookkeeping ssr commands have the same discharge-intro *)
-(* argument format we use a single grammar entry point to parse them. *)
-(* the entry point parses only non-empty arguments to avoid conflicts *)
-(* with the basic Coq tactics. *)
-
-(* type ssrarg = ssrbwdview * (ssreqid * (ssrdgens * ssripats)) *)
-
-let pr_ssrarg _ _ _ (view, (eqid, (dgens, ipats))) =
- let pri = pr_intros (gens_sep dgens) in
- pr_view2 view ++ pr_eqid eqid ++ pr_dgens pr_gen dgens ++ pri ipats
-
-ARGUMENT EXTEND ssrarg TYPED AS ssrfwdview * (ssreqid * (ssrdgens * ssrintros))
- PRINTED BY pr_ssrarg
-| [ ssrfwdview(view) ssreqid(eqid) ssrdgens(dgens) ssrintros(ipats) ] ->
- [ view, (eqid, (dgens, ipats)) ]
-| [ ssrfwdview(view) ssrclear(clr) ssrintros(ipats) ] ->
- [ view, (None, (([], clr), ipats)) ]
-| [ ssreqid(eqid) ssrdgens(dgens) ssrintros(ipats) ] ->
- [ [], (eqid, (dgens, ipats)) ]
-| [ ssrclear_ne(clr) ssrintros(ipats) ] ->
- [ [], (None, (([], clr), ipats)) ]
-| [ ssrintros_ne(ipats) ] ->
- [ [], (None, (([], []), ipats)) ]
-END
-
-(** The "clear" tactic *)
-
-(* We just add a numeric version that clears the n top assumptions. *)
-
-TACTIC EXTEND ssrclear
- | [ "clear" natural(n) ] -> [ tclIPAT (List.init n (fun _ -> IPatAnon Drop)) ]
-END
-
-(** The "move" tactic *)
-
-(* TODO: review this, in particular the => _ and => [] cases *)
-let rec improper_intros = function
- | IPatSimpl _ :: ipats -> improper_intros ipats
- | (IPatId _ | IPatAnon _ | IPatCase _ | IPatDispatch _) :: _ -> false
- | _ -> true (* FIXME *)
-
-let check_movearg = function
- | view, (eqid, _) when view <> [] && eqid <> None ->
- CErrors.user_err (Pp.str "incompatible view and equation in move tactic")
- | view, (_, (([gen :: _], _), _)) when view <> [] && has_occ gen ->
- CErrors.user_err (Pp.str "incompatible view and occurrence switch in move tactic")
- | _, (_, ((dgens, _), _)) when List.length dgens > 1 ->
- CErrors.user_err (Pp.str "dependents switch `/' in move tactic")
- | _, (eqid, (_, ipats)) when eqid <> None && improper_intros ipats ->
- CErrors.user_err (Pp.str "no proper intro pattern for equation in move tactic")
- | arg -> arg
-
-ARGUMENT EXTEND ssrmovearg TYPED AS ssrarg PRINTED BY pr_ssrarg
-| [ ssrarg(arg) ] -> [ check_movearg arg ]
-END
-
-let movearg_of_parsed_movearg (v,(eq,(dg,ip))) =
- (v,(eq,(ssrdgens_of_parsed_dgens dg,ip)))
-
-TACTIC EXTEND ssrmove
-| [ "move" ssrmovearg(arg) ssrrpat(pat) ] ->
- [ ssrmovetac (movearg_of_parsed_movearg arg) <*> tclIPAT [pat] ]
-| [ "move" ssrmovearg(arg) ssrclauses(clauses) ] ->
- [ tclCLAUSES (ssrmovetac (movearg_of_parsed_movearg arg)) clauses ]
-| [ "move" ssrrpat(pat) ] -> [ tclIPAT [pat] ]
-| [ "move" ] -> [ ssrsmovetac ]
-END
-
-let check_casearg = function
-| view, (_, (([_; gen :: _], _), _)) when view <> [] && has_occ gen ->
- CErrors.user_err (Pp.str "incompatible view and occurrence switch in dependent case tactic")
-| arg -> arg
-
-ARGUMENT EXTEND ssrcasearg TYPED AS ssrarg PRINTED BY pr_ssrarg
-| [ ssrarg(arg) ] -> [ check_casearg arg ]
-END
-
-TACTIC EXTEND ssrcase
-| [ "case" ssrcasearg(arg) ssrclauses(clauses) ] ->
- [ tclCLAUSES (ssrcasetac (movearg_of_parsed_movearg arg)) clauses ]
-| [ "case" ] -> [ ssrscasetoptac ]
-END
-
-(** The "elim" tactic *)
-
-TACTIC EXTEND ssrelim
-| [ "elim" ssrarg(arg) ssrclauses(clauses) ] ->
- [ tclCLAUSES (ssrelimtac (movearg_of_parsed_movearg arg)) clauses ]
-| [ "elim" ] -> [ ssrselimtoptac ]
-END
-
-(** 6. Backward chaining tactics: apply, exact, congr. *)
-
-(** The "apply" tactic *)
-
-let pr_agen (docc, dt) = pr_docc docc ++ pr_term dt
-let pr_ssragen _ _ _ = pr_agen
-let pr_ssragens _ _ _ = pr_dgens pr_agen
-
-ARGUMENT EXTEND ssragen TYPED AS ssrdocc * ssrterm PRINTED BY pr_ssragen
-| [ "{" ne_ssrhyp_list(clr) "}" ssrterm(dt) ] -> [ mkclr clr, dt ]
-| [ ssrterm(dt) ] -> [ nodocc, dt ]
-END
-
-ARGUMENT EXTEND ssragens TYPED AS ssragen list list * ssrclear
-PRINTED BY pr_ssragens
-| [ "{" ne_ssrhyp_list(clr) "}" ssrterm(dt) ssragens(agens) ] ->
- [ cons_gen (mkclr clr, dt) agens ]
-| [ "{" ne_ssrhyp_list(clr) "}" ] -> [ [[]], clr]
-| [ ssrterm(dt) ssragens(agens) ] ->
- [ cons_gen (nodocc, dt) agens ]
-| [ ] -> [ [[]], [] ]
-END
-
-let mk_applyarg views agens intros = views, (agens, intros)
-
-let pr_ssraarg _ _ _ (view, (dgens, ipats)) =
- let pri = pr_intros (gens_sep dgens) in
- pr_view view ++ pr_dgens pr_agen dgens ++ pri ipats
-
-ARGUMENT EXTEND ssrapplyarg
-TYPED AS ssrbwdview * (ssragens * ssrintros)
-PRINTED BY pr_ssraarg
-| [ ":" ssragen(gen) ssragens(dgens) ssrintros(intros) ] ->
- [ mk_applyarg [] (cons_gen gen dgens) intros ]
-| [ ssrclear_ne(clr) ssrintros(intros) ] ->
- [ mk_applyarg [] ([], clr) intros ]
-| [ ssrintros_ne(intros) ] ->
- [ mk_applyarg [] ([], []) intros ]
-| [ ssrbwdview(view) ":" ssragen(gen) ssragens(dgens) ssrintros(intros) ] ->
- [ mk_applyarg view (cons_gen gen dgens) intros ]
-| [ ssrbwdview(view) ssrclear(clr) ssrintros(intros) ] ->
- [ mk_applyarg view ([], clr) intros ]
- END
-
-TACTIC EXTEND ssrapply
-| [ "apply" ssrapplyarg(arg) ] -> [
- let views, (gens_clr, intros) = arg in
- inner_ssrapplytac views gens_clr ist <*> tclIPATssr intros ]
-| [ "apply" ] -> [ apply_top_tac ]
-END
-
-(** The "exact" tactic *)
-
-let mk_exactarg views dgens = mk_applyarg views dgens []
-
-ARGUMENT EXTEND ssrexactarg TYPED AS ssrapplyarg PRINTED BY pr_ssraarg
-| [ ":" ssragen(gen) ssragens(dgens) ] ->
- [ mk_exactarg [] (cons_gen gen dgens) ]
-| [ ssrbwdview(view) ssrclear(clr) ] ->
- [ mk_exactarg view ([], clr) ]
-| [ ssrclear_ne(clr) ] ->
- [ mk_exactarg [] ([], clr) ]
-END
-
-let vmexacttac pf =
- Goal.enter begin fun gl ->
- exact_no_check (EConstr.mkCast (pf, _vmcast, Tacmach.New.pf_concl gl))
- end
-
-TACTIC EXTEND ssrexact
-| [ "exact" ssrexactarg(arg) ] -> [
- let views, (gens_clr, _) = arg in
- V82.tactic (tclBY (V82.of_tactic (inner_ssrapplytac views gens_clr ist))) ]
-| [ "exact" ] -> [
- V82.tactic (Tacticals.tclORELSE (donetac ~-1) (tclBY (V82.of_tactic apply_top_tac))) ]
-| [ "exact" "<:" lconstr(pf) ] -> [ vmexacttac pf ]
-END
-
-(** The "congr" tactic *)
-
-(* type ssrcongrarg = open_constr * (int * constr) *)
-
-let pr_ssrcongrarg _ _ _ ((n, f), dgens) =
- (if n <= 0 then mt () else str " " ++ int n) ++
- str " " ++ pr_term f ++ pr_dgens pr_gen dgens
-
-ARGUMENT EXTEND ssrcongrarg TYPED AS (int * ssrterm) * ssrdgens
- PRINTED BY pr_ssrcongrarg
-| [ natural(n) constr(c) ssrdgens(dgens) ] -> [ (n, mk_term xNoFlag c), dgens ]
-| [ natural(n) constr(c) ] -> [ (n, mk_term xNoFlag c),([[]],[]) ]
-| [ constr(c) ssrdgens(dgens) ] -> [ (0, mk_term xNoFlag c), dgens ]
-| [ constr(c) ] -> [ (0, mk_term xNoFlag c), ([[]],[]) ]
-END
-
-
-
-TACTIC EXTEND ssrcongr
-| [ "congr" ssrcongrarg(arg) ] ->
-[ let arg, dgens = arg in
- V82.tactic begin
- match dgens with
- | [gens], clr -> Tacticals.tclTHEN (genstac (gens,clr)) (newssrcongrtac arg ist)
- | _ -> errorstrm (str"Dependent family abstractions not allowed in congr")
- end]
-END
-
-(** 7. Rewriting tactics (rewrite, unlock) *)
-
-(** Coq rewrite compatibility flag *)
-
-(** Rewrite clear/occ switches *)
-
-let pr_rwocc = function
- | None, None -> mt ()
- | None, occ -> pr_occ occ
- | Some clr, _ -> pr_clear_ne clr
-
-let pr_ssrrwocc _ _ _ = pr_rwocc
-
-ARGUMENT EXTEND ssrrwocc TYPED AS ssrdocc PRINTED BY pr_ssrrwocc
-| [ "{" ssrhyp_list(clr) "}" ] -> [ mkclr clr ]
-| [ "{" ssrocc(occ) "}" ] -> [ mkocc occ ]
-| [ ] -> [ noclr ]
-END
-
-(** Rewrite rules *)
-
-let pr_rwkind = function
- | RWred s -> pr_simpl s
- | RWdef -> str "/"
- | RWeq -> mt ()
-
-let wit_ssrrwkind = add_genarg "ssrrwkind" pr_rwkind
-
-let pr_rule = function
- | RWred s, _ -> pr_simpl s
- | RWdef, r-> str "/" ++ pr_term r
- | RWeq, r -> pr_term r
-
-let pr_ssrrule _ _ _ = pr_rule
-
-let noruleterm loc = mk_term xNoFlag (mkCProp loc)
-
-ARGUMENT EXTEND ssrrule_ne TYPED AS ssrrwkind * ssrterm PRINTED BY pr_ssrrule
- | [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-GEXTEND Gram
- GLOBAL: ssrrule_ne;
- ssrrule_ne : [
- [ test_not_ssrslashnum; x =
- [ "/"; t = ssrterm -> RWdef, t
- | t = ssrterm -> RWeq, t
- | s = ssrsimpl_ne -> RWred s, noruleterm (Some !@loc)
- ] -> x
- | s = ssrsimpl_ne -> RWred s, noruleterm (Some !@loc)
- ]];
-END
-
-ARGUMENT EXTEND ssrrule TYPED AS ssrrule_ne PRINTED BY pr_ssrrule
- | [ ssrrule_ne(r) ] -> [ r ]
- | [ ] -> [ RWred Nop, noruleterm (Some loc) ]
-END
-
-(** Rewrite arguments *)
-
-let pr_option f = function None -> mt() | Some x -> f x
-let pr_pattern_squarep= pr_option (fun r -> str "[" ++ pr_rpattern r ++ str "]")
-let pr_ssrpattern_squarep _ _ _ = pr_pattern_squarep
-let pr_rwarg ((d, m), ((docc, rx), r)) =
- pr_rwdir d ++ pr_mult m ++ pr_rwocc docc ++ pr_pattern_squarep rx ++ pr_rule r
-
-let pr_ssrrwarg _ _ _ = pr_rwarg
-
-ARGUMENT EXTEND ssrpattern_squarep
-TYPED AS rpattern option PRINTED BY pr_ssrpattern_squarep
- | [ "[" rpattern(rdx) "]" ] -> [ Some rdx ]
- | [ ] -> [ None ]
-END
-
-ARGUMENT EXTEND ssrpattern_ne_squarep
-TYPED AS rpattern option PRINTED BY pr_ssrpattern_squarep
- | [ "[" rpattern(rdx) "]" ] -> [ Some rdx ]
-END
-
-
-ARGUMENT EXTEND ssrrwarg
- TYPED AS (ssrdir * ssrmult) * ((ssrdocc * rpattern option) * ssrrule)
- PRINTED BY pr_ssrrwarg
- | [ "-" ssrmult(m) ssrrwocc(docc) ssrpattern_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg (R2L, m) (docc, rx) r ]
- | [ "-/" ssrterm(t) ] -> (* just in case '-/' should become a token *)
- [ mk_rwarg (R2L, nomult) norwocc (RWdef, t) ]
- | [ ssrmult_ne(m) ssrrwocc(docc) ssrpattern_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg (L2R, m) (docc, rx) r ]
- | [ "{" ne_ssrhyp_list(clr) "}" ssrpattern_ne_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg norwmult (mkclr clr, rx) r ]
- | [ "{" ne_ssrhyp_list(clr) "}" ssrrule(r) ] ->
- [ mk_rwarg norwmult (mkclr clr, None) r ]
- | [ "{" ssrocc(occ) "}" ssrpattern_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg norwmult (mkocc occ, rx) r ]
- | [ "{" "}" ssrpattern_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg norwmult (nodocc, rx) r ]
- | [ ssrpattern_ne_squarep(rx) ssrrule_ne(r) ] ->
- [ mk_rwarg norwmult (noclr, rx) r ]
- | [ ssrrule_ne(r) ] ->
- [ mk_rwarg norwmult norwocc r ]
-END
-
-TACTIC EXTEND ssrinstofruleL2R
-| [ "ssrinstancesofruleL2R" ssrterm(arg) ] -> [ V82.tactic (ssrinstancesofrule ist L2R arg) ]
-END
-TACTIC EXTEND ssrinstofruleR2L
-| [ "ssrinstancesofruleR2L" ssrterm(arg) ] -> [ V82.tactic (ssrinstancesofrule ist R2L arg) ]
-END
-
-(** Rewrite argument sequence *)
-
-(* type ssrrwargs = ssrrwarg list *)
-
-let pr_ssrrwargs _ _ _ rwargs = pr_list spc pr_rwarg rwargs
-
-ARGUMENT EXTEND ssrrwargs TYPED AS ssrrwarg list PRINTED BY pr_ssrrwargs
- | [ "YouShouldNotTypeThis" ] -> [ anomaly "Grammar placeholder match" ]
-END
-
-let ssr_rw_syntax = Summary.ref ~name:"SSR:rewrite" true
-
-let _ =
- Goptions.declare_bool_option
- { Goptions.optname = "ssreflect rewrite";
- Goptions.optkey = ["SsrRewrite"];
- Goptions.optread = (fun _ -> !ssr_rw_syntax);
- Goptions.optdepr = false;
- Goptions.optwrite = (fun b -> ssr_rw_syntax := b) }
-
-let test_ssr_rw_syntax =
- let test strm =
- if not !ssr_rw_syntax then raise Stream.Failure else
- if is_ssr_loaded () then () else
- match Util.stream_nth 0 strm with
- | Tok.KEYWORD key when List.mem key.[0] ['{'; '['; '/'] -> ()
- | _ -> raise Stream.Failure in
- Gram.Entry.of_parser "test_ssr_rw_syntax" test
-
-GEXTEND Gram
- GLOBAL: ssrrwargs;
- ssrrwargs: [[ test_ssr_rw_syntax; a = LIST1 ssrrwarg -> a ]];
-END
-
-(** The "rewrite" tactic *)
-
-TACTIC EXTEND ssrrewrite
- | [ "rewrite" ssrrwargs(args) ssrclauses(clauses) ] ->
- [ tclCLAUSES (old_tac (ssrrewritetac ist args)) clauses ]
-END
-
-(** The "unlock" tactic *)
-
-let pr_unlockarg (occ, t) = pr_occ occ ++ pr_term t
-let pr_ssrunlockarg _ _ _ = pr_unlockarg
-
-ARGUMENT EXTEND ssrunlockarg TYPED AS ssrocc * ssrterm
- PRINTED BY pr_ssrunlockarg
- | [ "{" ssrocc(occ) "}" ssrterm(t) ] -> [ occ, t ]
- | [ ssrterm(t) ] -> [ None, t ]
-END
-
-let pr_ssrunlockargs _ _ _ args = pr_list spc pr_unlockarg args
-
-ARGUMENT EXTEND ssrunlockargs TYPED AS ssrunlockarg list
- PRINTED BY pr_ssrunlockargs
- | [ ssrunlockarg_list(args) ] -> [ args ]
-END
-
-TACTIC EXTEND ssrunlock
- | [ "unlock" ssrunlockargs(args) ssrclauses(clauses) ] ->
- [ tclCLAUSES (old_tac (unlocktac ist args)) clauses ]
-END
-
-(** 8. Forward chaining tactics (pose, set, have, suffice, wlog) *)
-
-
-TACTIC EXTEND ssrpose
-| [ "pose" ssrfixfwd(ffwd) ] -> [ V82.tactic (ssrposetac ffwd) ]
-| [ "pose" ssrcofixfwd(ffwd) ] -> [ V82.tactic (ssrposetac ffwd) ]
-| [ "pose" ssrfwdid(id) ssrposefwd(fwd) ] -> [ V82.tactic (ssrposetac (id, fwd)) ]
-END
-
-(** The "set" tactic *)
-
-(* type ssrsetfwd = ssrfwd * ssrdocc *)
-
-TACTIC EXTEND ssrset
-| [ "set" ssrfwdid(id) ssrsetfwd(fwd) ssrclauses(clauses) ] ->
- [ tclCLAUSES (old_tac (ssrsettac id fwd)) clauses ]
-END
-
-(** The "have" tactic *)
-
-(* type ssrhavefwd = ssrfwd * ssrhint *)
-
-
-(* Pltac. *)
-
-(* The standard TACTIC EXTEND does not work for abstract *)
-GEXTEND Gram
- GLOBAL: tactic_expr;
- tactic_expr: LEVEL "3"
- [ RIGHTA [ IDENT "abstract"; gens = ssrdgens ->
- ssrtac_expr ~loc:!@loc "abstract"
- [Tacexpr.TacGeneric (Genarg.in_gen (Genarg.rawwit wit_ssrdgens) gens)] ]];
-END
-TACTIC EXTEND ssrabstract
-| [ "abstract" ssrdgens(gens) ] -> [
- if List.length (fst gens) <> 1 then
- errorstrm (str"dependents switches '/' not allowed here");
- Ssripats.ssrabstract (ssrdgens_of_parsed_dgens gens) ]
-END
-
-TACTIC EXTEND ssrhave
-| [ "have" ssrhavefwdwbinders(fwd) ] ->
- [ V82.tactic (havetac ist fwd false false) ]
-END
-
-TACTIC EXTEND ssrhavesuff
-| [ "have" "suff" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] ->
- [ V82.tactic (havetac ist (false,(pats,fwd)) true false) ]
-END
-
-TACTIC EXTEND ssrhavesuffices
-| [ "have" "suffices" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] ->
- [ V82.tactic (havetac ist (false,(pats,fwd)) true false) ]
-END
-
-TACTIC EXTEND ssrsuffhave
-| [ "suff" "have" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] ->
- [ V82.tactic (havetac ist (false,(pats,fwd)) true true) ]
-END
-
-TACTIC EXTEND ssrsufficeshave
-| [ "suffices" "have" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] ->
- [ V82.tactic (havetac ist (false,(pats,fwd)) true true) ]
-END
-
-(** The "suffice" tactic *)
-
-let pr_ssrsufffwdwbinders _ _ prt (hpats, (fwd, hint)) =
- pr_hpats hpats ++ pr_fwd fwd ++ pr_hint prt hint
-
-ARGUMENT EXTEND ssrsufffwd
- TYPED AS ssrhpats * (ssrfwd * ssrhint) PRINTED BY pr_ssrsufffwdwbinders
-| [ ssrhpats(pats) ssrbinder_list(bs) ":" ast_closure_lterm(t) ssrhint(hint) ] ->
- [ let ((clr, pats), binders), simpl = pats in
- let allbs = intro_id_to_binder binders @ bs in
- let allbinders = binders @ List.flatten (binder_to_intro_id bs) in
- let fwd = mkFwdHint ":" t in
- (((clr, pats), allbinders), simpl), (bind_fwd allbs fwd, hint) ]
-END
-
-
-TACTIC EXTEND ssrsuff
-| [ "suff" ssrsufffwd(fwd) ] -> [ V82.tactic (sufftac ist fwd) ]
-END
-
-TACTIC EXTEND ssrsuffices
-| [ "suffices" ssrsufffwd(fwd) ] -> [ V82.tactic (sufftac ist fwd) ]
-END
-
-(** The "wlog" (Without Loss Of Generality) tactic *)
-
-(* type ssrwlogfwd = ssrwgen list * ssrfwd *)
-
-let pr_ssrwlogfwd _ _ _ (gens, t) =
- str ":" ++ pr_list mt pr_wgen gens ++ spc() ++ pr_fwd t
-
-ARGUMENT EXTEND ssrwlogfwd TYPED AS ssrwgen list * ssrfwd
- PRINTED BY pr_ssrwlogfwd
-| [ ":" ssrwgen_list(gens) "/" ast_closure_lterm(t) ] -> [ gens, mkFwdHint "/" t]
-END
-
-
-TACTIC EXTEND ssrwlog
-| [ "wlog" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ V82.tactic (wlogtac ist pats fwd hint false `NoGen) ]
-END
-
-TACTIC EXTEND ssrwlogs
-| [ "wlog" "suff" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ]
-END
-
-TACTIC EXTEND ssrwlogss
-| [ "wlog" "suffices" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ]->
- [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ]
-END
-
-TACTIC EXTEND ssrwithoutloss
-| [ "without" "loss" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ V82.tactic (wlogtac ist pats fwd hint false `NoGen) ]
-END
-
-TACTIC EXTEND ssrwithoutlosss
-| [ "without" "loss" "suff"
- ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ]
-END
-
-TACTIC EXTEND ssrwithoutlossss
-| [ "without" "loss" "suffices"
- ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ]->
- [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ]
-END
-
-(* Generally have *)
-let pr_idcomma _ _ _ = function
- | None -> mt()
- | Some None -> str"_, "
- | Some (Some id) -> pr_id id ++ str", "
-
-ARGUMENT EXTEND ssr_idcomma TYPED AS ident option option PRINTED BY pr_idcomma
- | [ ] -> [ None ]
-END
-
-let accept_idcomma strm =
- match stream_nth 0 strm with
- | Tok.IDENT _ | Tok.KEYWORD "_" -> accept_before_syms [","] strm
- | _ -> raise Stream.Failure
-
-let test_idcomma = Gram.Entry.of_parser "test_idcomma" accept_idcomma
-
-GEXTEND Gram
- GLOBAL: ssr_idcomma;
- ssr_idcomma: [ [ test_idcomma;
- ip = [ id = IDENT -> Some (Id.of_string id) | "_" -> None ]; "," ->
- Some ip
- ] ];
-END
-
-let augment_preclr clr1 (((clr0, x),y),z) = (((clr1 @ clr0, x),y),z)
-
-TACTIC EXTEND ssrgenhave
-| [ "gen" "have" ssrclear(clr)
- ssr_idcomma(id) ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ let pats = augment_preclr clr pats in
- V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ]
-END
-
-TACTIC EXTEND ssrgenhave2
-| [ "generally" "have" ssrclear(clr)
- ssr_idcomma(id) ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] ->
- [ let pats = augment_preclr clr pats in
- V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ]
-END
-
-(* We wipe out all the keywords generated by the grammar rules we defined. *)
-(* The user is supposed to Require Import ssreflect or Require ssreflect *)
-(* and Import ssreflect.SsrSyntax to obtain these keywords and as a *)
-(* consequence the extended ssreflect grammar. *)
-let () = CLexer.set_keyword_state frozen_lexer ;;
-
-
-(* vim: set filetype=ocaml foldmethod=marker: *)