1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
|
(************************************************************************)
(* * 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
|