|
(************************************************************************)
(* * The Rocq Prover / The Rocq Development Team *)
(* v * Copyright INRIA, CNRS and contributors *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(* \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) *)
(************************************************************************)
DECLARE PLUGIN "rocq-runtime.plugins.ltac"
{
open Pp
open Stdarg
open Tacarg
open Procq.Prim
open Procq.Constr
open Names
open Taccoerce
open Tacinterp
open Locus
(** Adding scopes for generic arguments not defined through ARGUMENT EXTEND *)
(** We need g_ltac to initialize tactic_value *)
let () = G_ltac.for_extraargs
let create_generic_quotation name e wit =
let inject (loc, v) = Tacexpr.TacGeneric (Some name, Genarg.in_gen (Genarg.rawwit wit) v) in
Tacentries.create_ltac_quotation ~plugin:"rocq-runtime.plugins.ltac" name inject (e, None)
let () = create_generic_quotation "integer" Procq.Prim.integer Stdarg.wit_int
let () = create_generic_quotation "string" Procq.Prim.string Stdarg.wit_string
let () = create_generic_quotation "smart_global" Procq.Prim.smart_global Stdarg.wit_smart_global
let () = create_generic_quotation "ident" Procq.Prim.ident Stdarg.wit_ident
let () = create_generic_quotation "reference" Procq.Prim.reference Stdarg.wit_ref
let () = create_generic_quotation "uconstr" Procq.Constr.lconstr Stdarg.wit_uconstr
let () = create_generic_quotation "constr" Procq.Constr.lconstr Stdarg.wit_constr
let () = create_generic_quotation "ipattern" Pltac.simple_intropattern wit_simple_intropattern
let () = create_generic_quotation "open_constr" Procq.Constr.lconstr Stdarg.wit_open_constr
let () =
let inject (loc, v) = Tacexpr.Tacexp v in
Tacentries.create_ltac_quotation ~plugin:"rocq-runtime.plugins.ltac" "ltac" inject (Pltac.ltac_expr, Some 5)
(** Backward-compatible tactic notation entry names *)
let () =
let register name entry = Tacentries.register_tactic_notation_entry name entry in
register "hyp" wit_hyp;
register "simple_intropattern" wit_simple_intropattern;
register "integer" wit_integer;
register "reference" wit_ref;
()
(* Rewriting orientation *)
let pr_orient _prc _prlc _prt = function
| true -> Pp.mt ()
| false -> Pp.str " <-"
}
ARGUMENT EXTEND orient TYPED AS bool PRINTED BY { pr_orient }
| [ "->" ] -> { true }
| [ "<-" ] -> { false }
| [ ] -> { true }
END
{
let pr_int _ _ _ i = Pp.int i
let _natural = Procq.Prim.natural
}
ARGUMENT EXTEND natural TYPED AS int PRINTED BY { pr_int }
| [ _natural(i) ] -> { i }
END
{
let pr_orient = pr_orient () () ()
let pr_int_list = Pp.pr_sequence Pp.int
let pr_int_list_full _prc _prlc _prt l = pr_int_list l
let pr_occurrences _prc _prlc _prt l =
match l with
| ArgArg x -> pr_int_list x
| ArgVar { CAst.loc = loc; v=id } -> Id.print id
let occurrences_of = function
| [] -> NoOccurrences
| n::_ as nl when n < 0 -> AllOccurrencesBut (List.map abs nl)
| nl ->
if List.exists (fun n -> n < 0) nl then
CErrors.user_err Pp.(str "Illegal negative occurrence number.");
OnlyOccurrences nl
let coerce_to_int v = match Value.to_int v with
| None -> raise (CannotCoerceTo "an integer")
| Some n -> n
let int_list_of_VList v = match Value.to_list v with
| Some l -> List.map (fun n -> coerce_to_int n) l
| _ -> raise (CannotCoerceTo "an integer")
let interp_occs ist env sigma l =
match l with
| ArgArg x -> x
| ArgVar ({ CAst.v = id } as locid) ->
(try int_list_of_VList (Id.Map.find id ist.lfun)
with Not_found | CannotCoerceTo _ -> [interp_int ist locid])
let glob_occs ist l = l
let subst_occs evm l = l
}
ARGUMENT EXTEND occurrences
TYPED AS int list
PRINTED BY { pr_int_list_full }
INTERPRETED BY { interp_occs }
GLOBALIZED BY { glob_occs }
SUBSTITUTED BY { subst_occs }
RAW_PRINTED BY { pr_occurrences }
GLOB_PRINTED BY { pr_occurrences }
| [ ne_integer_list(l) ] -> { ArgArg l }
| [ hyp(id) ] -> { ArgVar id }
END
{
let pr_occurrences = pr_occurrences () () ()
let pr_gen env sigma prc _prlc _prtac x = prc env sigma x
let pr_globc env sigma lvl _prc _prlc _prtac glob =
Printer.pr_closed_glob_n_env env sigma lvl glob
let interp_glob ist env sigma t = Tacinterp.interp_glob_closure ist env sigma t
let glob_glob = Tacintern.intern_constr
let pr_lconstr env sigma _ prc _ c = prc env sigma c
let subst_glob = Tacsubst.subst_glob_constr_and_expr
}
ARGUMENT EXTEND glob
PRINTED BY { fun c -> pr_globc env sigma Ppconstr.lsimpleconstr c }
INTERPRETED BY { interp_glob }
GLOBALIZED BY { glob_glob }
SUBSTITUTED BY { subst_glob }
RAW_PRINTED BY { pr_gen env sigma }
GLOB_PRINTED BY { pr_gen env sigma }
| [ constr(c) ] -> { c }
END
{
let l_constr = Procq.Constr.lconstr
}
ARGUMENT EXTEND lconstr
TYPED AS constr
PRINTED BY { pr_lconstr env sigma }
| [ l_constr(c) ] -> { c }
END
ARGUMENT EXTEND lglob
TYPED AS glob
PRINTED BY { fun c -> pr_globc env sigma Ppconstr.ltop c }
INTERPRETED BY { interp_glob }
GLOBALIZED BY { glob_glob }
SUBSTITUTED BY { subst_glob }
RAW_PRINTED BY { pr_gen env sigma }
GLOB_PRINTED BY { pr_gen env sigma }
| [ lconstr(c) ] -> { c }
END
{
type 'id gen_place = ('id * hyp_location_flag) option
type loc_place = lident gen_place
type place = Id.t gen_place
let pr_gen_place pr_id = function
| None -> Pp.mt ()
| Some (id, InHyp) -> str "in " ++ pr_id id
| Some (id, InHypTypeOnly) ->
str "in (type of " ++ pr_id id ++ str ")"
| Some (id, InHypValueOnly) ->
str "in (value of " ++ pr_id id ++ str ")"
let pr_loc_place _ _ _ = pr_gen_place (fun { CAst.v = id } -> Id.print id)
let pr_place _ _ _ = pr_gen_place Id.print
let pr_hloc = pr_loc_place () () ()
let intern_place ist = function
| None -> None
| Some (id, hl) -> Some (Tacintern.intern_hyp ist id, hl)
let interp_place ist env sigma = function
| None -> None
| Some (id, hl) -> Some (Tacinterp.interp_hyp ist env sigma id, hl)
let subst_place subst pl = pl
}
ARGUMENT EXTEND hloc
PRINTED BY { pr_place }
INTERPRETED BY { interp_place }
GLOBALIZED BY { intern_place }
SUBSTITUTED BY { subst_place }
RAW_PRINTED BY { pr_loc_place }
GLOB_PRINTED BY { pr_loc_place }
| [ ] ->
{ None }
| [ "in" "|-" "*" ] ->
{ None }
| [ "in" ident(id) ] ->
{ Some ((CAst.make id), InHyp) }
| [ "in" "(" "type" "of" ident(id) ")" ] ->
{ Some ((CAst.make id), InHypTypeOnly) }
| [ "in" "(" "value" "of" ident(id) ")" ] ->
{ Some ((CAst.make id), InHypValueOnly) }
END
{
let pr_rename _ _ _ (n, m) = Id.print n ++ str " into " ++ Id.print m
}
ARGUMENT EXTEND rename
TYPED AS (ident * ident)
PRINTED BY { pr_rename }
| [ ident(n) "into" ident(m) ] -> { (n, m) }
END
(* Julien: Mise en commun des differentes version de replace with in by *)
{
let pr_by_arg_tac env sigma _prc _prlc prtac opt_c =
match opt_c with
| None -> mt ()
| Some t -> hov 2 (str "by" ++ spc () ++ prtac env sigma (Constrexpr.LevelLe 3) t)
}
ARGUMENT EXTEND by_arg_tac
TYPED AS tactic option
PRINTED BY { pr_by_arg_tac env sigma }
| [ "by" tactic3(c) ] -> { Some c }
| [ ] -> { None }
END
{
let pr_by_arg_tac env sigma prtac opt_c = pr_by_arg_tac env sigma () () prtac opt_c
let pr_in_clause _ _ _ cl = Pptactic.pr_in_clause Pputils.pr_lident cl
let pr_in_top_clause _ _ _ cl = Pptactic.pr_in_clause Id.print cl
let in_clause' = Pltac.in_clause
}
ARGUMENT EXTEND in_clause
TYPED AS clause_dft_concl
PRINTED BY { pr_in_top_clause }
RAW_PRINTED BY { pr_in_clause }
GLOB_PRINTED BY { pr_in_clause }
| [ in_clause'(cl) ] -> { cl }
END
{
let local_test_lpar_id_colon =
let open Procq.Lookahead in
to_entry "lpar_id_colon" begin
lk_kw "(" >> lk_ident >> lk_kw ":"
end
let pr_lpar_id_colon _ _ _ _ = mt ()
}
ARGUMENT EXTEND test_lpar_id_colon TYPED AS unit PRINTED BY { pr_lpar_id_colon }
| [ local_test_lpar_id_colon(x) ] -> { () }
END
{
(* Work around a limitation of the macro system *)
let strategy_level0 = Procq.Prim.strategy_level
let pr_strategy _ _ _ v = Conv_oracle.pr_level v
}
ARGUMENT EXTEND strategy_level PRINTED BY { pr_strategy }
| [ strategy_level0(n) ] -> { n }
END
{
let intern_strategy ist v = match v with
| ArgVar id -> ArgVar (Tacintern.intern_hyp ist id)
| ArgArg v -> ArgArg v
let subst_strategy _ v = v
let interp_strategy ist env sigma = function
| ArgArg n -> n
| ArgVar { CAst.v = id; CAst.loc } ->
let v =
try Id.Map.find id ist.lfun
with Not_found ->
CErrors.user_err ?loc
(str "Unbound variable " ++ Id.print id ++ str".")
in
let v =
try Tacinterp.Value.cast (Genarg.topwit wit_strategy_level) v
with CErrors.UserError _ -> Taccoerce.error_ltac_variable ?loc id None v "a strategy_level"
in
v
let pr_loc_strategy _ _ _ v = Pputils.pr_or_var Conv_oracle.pr_level v
}
ARGUMENT EXTEND strategy_level_or_var
TYPED AS strategy_level
PRINTED BY { pr_strategy }
INTERPRETED BY { interp_strategy }
GLOBALIZED BY { intern_strategy }
SUBSTITUTED BY { subst_strategy }
RAW_PRINTED BY { pr_loc_strategy }
GLOB_PRINTED BY { pr_loc_strategy }
| [ strategy_level(n) ] -> { ArgArg n }
| [ identref(id) ] -> { ArgVar id }
END
[ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet)
]
|