Quelle g_indfun.mlg
Sprache: unbekannt
|
|
Untersuchungsergebnis.mlg Download desUnknown {[0] [0] [0]}zum Wurzelverzeichnis wechseln (************************************************************************)
(* * 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) *)
(************************************************************************)
{
open Ltac_plugin
open Util
open Pp
open Constrexpr
open Indfun_common
open Indfun
open Stdarg
open Tacarg
open Extraargs
open Tactypes
open Procq.Prim
open Procq.Constr
open Pltac
}
DECLARE PLUGIN "rocq-runtime.plugins.funind"
{
let pr_fun_ind_using env sigma prc prlc _ opt_c =
match opt_c with
| None -> mt ()
| Some b -> spc () ++ hov 2 (str "using" ++ spc () ++ Miscprint.pr_with_bindings (prc env sigma) (prlc env sigma) b)
(* Duplication of printing functions because "'a with_bindings" is
(internally) not uniform in 'a: indeed constr_with_bindings at the
"typed" level has type "open_constr with_bindings" instead of
"constr with_bindings"; hence, its printer cannot be polymorphic in
(prc,prlc)... *)
let pr_fun_ind_using_typed prc prlc _ opt_c =
match opt_c with
| None -> mt ()
| Some b ->
let env = Global.env () in
let evd = Evd.from_env env in
let (_, b) = b env evd in
spc () ++ hov 2 (str "using" ++ spc () ++ Miscprint.pr_with_bindings (prc env evd) (prlc env evd) b)
}
ARGUMENT EXTEND fun_ind_using
TYPED AS constr_with_bindings option
PRINTED BY { pr_fun_ind_using_typed }
RAW_PRINTED BY { pr_fun_ind_using env sigma }
GLOB_PRINTED BY { pr_fun_ind_using env sigma }
| [ "using" constr_with_bindings(c) ] -> { Some c }
| [ ] -> { None }
END
TACTIC EXTEND newfuninv
| [ "functional" "inversion" quantified_hypothesis(hyp) reference_opt(fname) ] ->
{
Invfun.invfun hyp fname
}
END
{
let pr_intro_as_pat prc pat =
match pat with
| Some pat ->
str "as" ++ spc () ++ Miscprint.pr_intro_pattern prc pat
| None -> mt ()
let out_disjunctive = CAst.map (function
| IntroAction (IntroOrAndPattern l) -> l
| _ -> CErrors.user_err Pp.(str "Disjunctive or conjunctive intro pattern expected."))
}
ARGUMENT EXTEND with_names TYPED AS intro_pattern option
PRINTED BY { fun prc _ _ -> pr_intro_as_pat (fun c -> prc env sigma @@ snd @@ c env sigma) }
RAW_PRINTED BY { fun prc _ _ -> pr_intro_as_pat (prc env sigma) }
GLOB_PRINTED BY { fun prc _ _ -> pr_intro_as_pat (prc env sigma) }
| [ "as" simple_intropattern(ipat) ] -> { Some ipat }
| [] -> { None }
END
{
let functional_induction b c x pat =
functional_induction true c x (Option.map out_disjunctive pat)
}
TACTIC EXTEND newfunind
| ["functional" "induction" lconstr(c) fun_ind_using(princl) with_names(pat)] ->
{
(Ltac_plugin.Internals.onSomeWithHoles
(fun x -> functional_induction true c x pat) princl)
}
END
(***** debug only ***)
TACTIC EXTEND snewfunind
| ["soft" "functional" "induction" ne_constr_list(cl) fun_ind_using(princl) with_names(pat)] ->
{
let c = match cl with
| [] -> assert false
| [c] -> c
| c::cl -> EConstr.applist(c,cl)
in
Ltac_plugin.Internals.onSomeWithHoles (fun x -> functional_induction false c x pat) princl }
END
{
module Vernac = Pvernac.Vernac_
let (wit_function_fix_definition : Vernacexpr.fixpoint_expr Loc.located Genarg.vernac_genarg_type) =
Genarg.create_arg "function_fix_definition"
let function_fix_definition =
Procq.create_generic_entry2 "function_fix_definition" (Genarg.rawwit wit_function_fix_definition)
}
GRAMMAR EXTEND Gram
GLOBAL: function_fix_definition ;
function_fix_definition:
[ [ g = Vernac.fix_definition -> { Loc.tag ~loc g } ]]
;
END
{
let () =
let raw_printer (_loc,body) = Genprint.PrinterBasic (fun env sigma -> Ppvernac.pr_rec_definition body) in
Genprint.register_vernac_print0 wit_function_fix_definition raw_printer
let is_proof_termination_interactively_checked recsl =
List.exists (function
| _, ( Some { CAst.v = (CMeasureRec _ | CWfRec _) }, _ ) -> true
| _, ( ( Some { CAst.v = CStructRec _ } | None), _) -> false) recsl
let classify_as_Fixpoint recsl =
Vernac_classifier.classify_vernac
(Vernacexpr.(CAst.make @@ { control = []; attrs = []; expr = VernacSynPure (VernacFixpoint(NoDischarge, List.split (List.map snd recsl)))}))
let classify_funind recsl =
match classify_as_Fixpoint recsl with
| Vernacextend.VtSideff (ids, _)
when is_proof_termination_interactively_checked recsl ->
Vernacextend.(VtStartProof (GuaranteesOpacity, ids))
| x -> x
let is_interactive recsl =
match classify_funind recsl with
| Vernacextend.VtStartProof _ -> true
| _ -> false
}
(* For usability we temporarily switch off some flags during the call
to Function. However this is not satisfactory:
1- Function should not warn "non-recursive" and call the Definition
mechanism instead of Fixpoint when needed
2- Only for automatically generated names should
unused-pattern-matching-variable be ignored. *)
VERNAC COMMAND EXTEND Function STATE CUSTOM
| ["Function" ne_function_fix_definition_list_sep(recsl,"with")]
=> { classify_funind recsl }
-> {
let warn = "-unused-pattern-matching-variable,-non-recursive" in
if is_interactive recsl then
Vernactypes.vtopenproof (fun () ->
CWarnings.with_warn warn
Gen_principle.do_generate_principle_interactive (List.split (List.map snd recsl)))
else
Vernactypes.vtdefault (fun () ->
CWarnings.with_warn warn
Gen_principle.do_generate_principle (List.split (List.map snd recsl)))
}
END
{
let pr_fun_scheme_arg (princ_name,fun_name,s) =
Names.Id.print princ_name.CAst.v ++ str " :=" ++ spc() ++ str "Induction for " ++
Libnames.pr_qualid fun_name ++ spc() ++ str "Sort " ++
UnivGen.QualityOrSet.pr Sorts.QVar.raw_pr s
}
VERNAC ARGUMENT EXTEND fun_scheme_arg
PRINTED BY { pr_fun_scheme_arg }
| [ identref(princ_name) ":=" "Induction" "for" reference(fun_name) "Sort" sort_quality_or_set(s) ] -> { (princ_name,fun_name,s) }
END
{
let warning_error names e =
match e with
| Building_graph e ->
let names = pr_enum Libnames.pr_qualid names in
let error = if do_observe () then (spc () ++ CErrors.print e) else mt () in
Gen_principle.warn_cannot_define_graph (names,error)
| Defining_principle e ->
let names = pr_enum Libnames.pr_qualid names in
let error = if do_observe () then CErrors.print e else mt () in
Gen_principle.warn_cannot_define_principle (names,error)
| _ -> assert false
}
VERNAC COMMAND EXTEND NewFunctionalScheme
| ["Functional" "Scheme" ne_fun_scheme_arg_list_sep(fas,"with") ]
=> { Vernacextend.(VtSideff(List.map (fun x -> (pi1 x).CAst.v) fas, VtLater)) }
->
{ begin
try
Gen_principle.build_scheme fas
with
| Gen_principle.No_graph_found ->
begin
match fas with
| (_,fun_name,_)::_ ->
begin
Gen_principle.make_graph (Smartlocate.global_with_alias fun_name);
try Gen_principle.build_scheme fas
with
| Gen_principle.No_graph_found ->
CErrors.user_err Pp.(str "Cannot generate induction principle(s)")
| Building_graph _ | Defining_principle _ as e ->
let names = List.map (fun (_,na,_) -> na) fas in
warning_error names e
end
| _ -> assert false (* we can only have non empty list *)
end
| Building_graph _ | Defining_principle _ as e ->
let names = List.map (fun (_,na,_) -> na) fas in
warning_error names e
end
}
END
(***** debug only ***)
VERNAC COMMAND EXTEND NewFunctionalCase
| ["Functional" "Case" fun_scheme_arg(fas) ]
=> { Vernacextend.(VtSideff([(pi1 fas).CAst.v], VtLater)) }
-> { Gen_principle.build_case_scheme fas }
END
(***** debug only ***)
VERNAC COMMAND EXTEND GenerateGraph CLASSIFIED AS QUERY
| ["Generate" "graph" "for" reference(c)] ->
{ Gen_principle.make_graph (Smartlocate.global_with_alias c) }
END
[ zur Elbe Produktseite wechseln0.96Quellennavigators
]
|
2026-03-28
|