aboutsummaryrefslogtreecommitdiff
path: root/tactics
diff options
context:
space:
mode:
Diffstat (limited to 'tactics')
-rw-r--r--tactics/abstract.ml111
-rw-r--r--tactics/abstract.mli8
-rw-r--r--tactics/declare.ml93
-rw-r--r--tactics/declare.mli63
-rw-r--r--tactics/declareScheme.ml42
-rw-r--r--tactics/declareScheme.mli12
-rw-r--r--tactics/ind_tables.ml49
-rw-r--r--tactics/ind_tables.mli4
-rw-r--r--tactics/pfedit.ml22
-rw-r--r--tactics/pfedit.mli5
-rw-r--r--tactics/proof_global.ml14
-rw-r--r--tactics/tactics.mllib1
12 files changed, 259 insertions, 165 deletions
diff --git a/tactics/abstract.ml b/tactics/abstract.ml
index 03ab0a1c13..1e18028e7b 100644
--- a/tactics/abstract.ml
+++ b/tactics/abstract.ml
@@ -8,14 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-module CVars = Vars
-
open Util
open Termops
open EConstr
open Evarutil
-module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
(* tactical to save as name a subproof such that the generalisation of
@@ -23,67 +20,21 @@ module NamedDecl = Context.Named.Declaration
is solved by tac *)
(** d1 is the section variable in the global context, d2 in the goal context *)
-let interpretable_as_section_decl env evd d1 d2 =
+let interpretable_as_section_decl env sigma d1 d2 =
let open Context.Named.Declaration in
- let e_eq_constr_univs sigma c1 c2 = match eq_constr_universes env !sigma c1 c2 with
- | None -> false
- | Some cstr ->
- try ignore (Evd.add_universe_constraints !sigma cstr); true
- with UState.UniversesDiffer -> false
+ let e_eq_constr_univs sigma c1 c2 = match eq_constr_universes env sigma c1 c2 with
+ | None -> false
+ | Some cstr ->
+ try
+ let _sigma = Evd.add_universe_constraints sigma cstr in
+ true
+ with UState.UniversesDiffer -> false
in
match d2, d1 with
| LocalDef _, LocalAssum _ -> false
| LocalDef (_,b1,t1), LocalDef (_,b2,t2) ->
- e_eq_constr_univs evd b1 b2 && e_eq_constr_univs evd t1 t2
- | LocalAssum (_,t1), d2 -> e_eq_constr_univs evd t1 (NamedDecl.get_type d2)
-
-let rec decompose len c t accu =
- let open Constr in
- let open Context.Rel.Declaration in
- if len = 0 then (c, t, accu)
- else match kind c, kind t with
- | Lambda (na, u, c), Prod (_, _, t) ->
- decompose (pred len) c t (LocalAssum (na, u) :: accu)
- | LetIn (na, b, u, c), LetIn (_, _, _, t) ->
- decompose (pred len) c t (LocalDef (na, b, u) :: accu)
- | _ -> assert false
-
-let rec shrink ctx sign c t accu =
- let open Constr in
- let open CVars in
- match ctx, sign with
- | [], [] -> (c, t, accu)
- | p :: ctx, decl :: sign ->
- if noccurn 1 c && noccurn 1 t then
- let c = subst1 mkProp c in
- let t = subst1 mkProp t in
- shrink ctx sign c t accu
- else
- let c = Term.mkLambda_or_LetIn p c in
- let t = Term.mkProd_or_LetIn p t in
- let accu = if RelDecl.is_local_assum p
- then mkVar (NamedDecl.get_id decl) :: accu
- else accu
- in
- shrink ctx sign c t accu
-| _ -> assert false
-
-let shrink_entry sign const =
- let open Declare in
- let typ = match const.proof_entry_type with
- | None -> assert false
- | Some t -> t
- in
- (* The body has been forced by the call to [build_constant_by_tactic] *)
- let () = assert (Future.is_over const.proof_entry_body) in
- let ((body, uctx), eff) = Future.force const.proof_entry_body in
- let (body, typ, ctx) = decompose (List.length sign) body typ [] in
- let (body, typ, args) = shrink ctx sign body typ [] in
- let const = { const with
- proof_entry_body = Future.from_val ((body, uctx), eff);
- proof_entry_type = Some typ;
- } in
- (const, args)
+ e_eq_constr_univs sigma b1 b2 && e_eq_constr_univs sigma t1 t2
+ | LocalAssum (_,t1), d2 -> e_eq_constr_univs sigma t1 (NamedDecl.get_type d2)
let name_op_to_name ~name_op ~name suffix =
match name_op with
@@ -101,22 +52,22 @@ let cache_term_by_tactic_then ~opaque ~name_op ?(goal_type=None) tac tacK =
redundancy on constant declaration. This opens up an interesting
question, how does abstract behave when discharge is local for example?
*)
- let suffix = if opaque
- then "_subproof"
- else "_subterm" in
+ let suffix, kind = if opaque
+ then "_subproof", Decls.(IsProof Lemma)
+ else "_subterm", Decls.(IsDefinition Definition)
+ in
let name = name_op_to_name ~name_op ~name suffix in
Proofview.Goal.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Proofview.Goal.sigma gl in
let current_sign = Global.named_context_val ()
and global_sign = Proofview.Goal.hyps gl in
- let evdref = ref sigma in
let sign,secsign =
List.fold_right
(fun d (s1,s2) ->
let id = NamedDecl.get_id d in
if mem_named_context_val id current_sign &&
- interpretable_as_section_decl env evdref (lookup_named_val id current_sign) d
+ interpretable_as_section_decl env sigma (lookup_named_val id current_sign) d
then (s1,push_named_context_val d s2)
else (Context.Named.add d s1,s2))
global_sign (Context.Named.empty, Environ.empty_named_context_val) in
@@ -126,21 +77,21 @@ let cache_term_by_tactic_then ~opaque ~name_op ?(goal_type=None) tac tacK =
| Some ty -> ty in
let concl = it_mkNamedProd_or_LetIn concl sign in
let concl =
- try flush_and_check_evars !evdref concl
+ try flush_and_check_evars sigma concl
with Uninstantiated_evar _ ->
CErrors.user_err Pp.(str "\"abstract\" cannot handle existentials.") in
- let evd, ctx, concl =
+ let sigma, ctx, concl =
(* FIXME: should be done only if the tactic succeeds *)
- let evd = Evd.minimize_universes !evdref in
- let ctx = Evd.universe_context_set evd in
- evd, ctx, Evarutil.nf_evars_universes evd concl
+ let sigma = Evd.minimize_universes sigma in
+ let ctx = Evd.universe_context_set sigma in
+ sigma, ctx, Evarutil.nf_evars_universes sigma concl
in
let concl = EConstr.of_constr concl in
let solve_tac = tclCOMPLETE (tclTHEN (tclDO (List.length sign) Tactics.intro) tac) in
- let ectx = Evd.evar_universe_context evd in
+ let ectx = Evd.evar_universe_context sigma in
let (const, safe, ectx) =
- try Pfedit.build_constant_by_tactic ~poly ~name ectx secsign concl solve_tac
+ try Pfedit.build_constant_by_tactic ~name ~opaque:Proof_global.Transparent ~poly ectx secsign concl solve_tac
with Logic_monad.TacticFailure e as src ->
(* if the tactic [tac] fails, it reports a [TacticFailure e],
which is an error irrelevant to the proof system (in fact it
@@ -151,16 +102,20 @@ let cache_term_by_tactic_then ~opaque ~name_op ?(goal_type=None) tac tacK =
in
let body, effs = Future.force const.Declare.proof_entry_body in
(* We drop the side-effects from the entry, they already exist in the ambient environment *)
- let const = { const with Declare.proof_entry_body = Future.from_val (body, ()) } in
- let const, args = shrink_entry sign const in
+ let const = Declare.Internal.map_entry_body const ~f:(fun _ -> body, ()) in
+ (* EJGA: Hack related to the above call to
+ `build_constant_by_tactic` with `~opaque:Transparent`. Even if
+ the abstracted term is destined to be opaque, if we trigger the
+ `if poly && opaque && private_poly_univs ()` in `Proof_global`
+ kernel will boom. This deserves more investigation. *)
+ let const = Declare.Internal.set_opacity ~opaque const in
+ let const, args = Declare.Internal.shrink_entry sign const in
let args = List.map EConstr.of_constr args in
- let cd = { const with Declare.proof_entry_opaque = opaque } in
- let kind = if opaque then Decls.(IsProof Lemma) else Decls.(IsDefinition Definition) in
let cst () =
(* do not compute the implicit arguments, it may be costly *)
let () = Impargs.make_implicit_args false in
(* ppedrot: seems legit to have abstracted subproofs as local*)
- Declare.declare_private_constant ~local:Declare.ImportNeedQualified ~name ~kind cd
+ Declare.declare_private_constant ~local:Declare.ImportNeedQualified ~name ~kind const
in
let cst, eff = Impargs.with_implicit_protection cst () in
let inst = match const.Declare.proof_entry_universes with
@@ -174,14 +129,14 @@ let cache_term_by_tactic_then ~opaque ~name_op ?(goal_type=None) tac tacK =
EInstance.make (Univ.UContext.instance ctx)
in
let lem = mkConstU (cst, inst) in
- let evd = Evd.set_universe_context evd ectx in
+ let sigma = Evd.set_universe_context sigma ectx in
let effs = Evd.concat_side_effects eff effs in
let solve =
Proofview.tclEFFECTS effs <*>
tacK lem args
in
let tac = if not safe then Proofview.mark_as_unsafe <*> solve else solve in
- Proofview.tclTHEN (Proofview.Unsafe.tclEVARS evd) tac
+ Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma) tac
end
let abstract_subproof ~opaque tac =
diff --git a/tactics/abstract.mli b/tactics/abstract.mli
index 96ddbea7b2..779e46cd49 100644
--- a/tactics/abstract.mli
+++ b/tactics/abstract.mli
@@ -20,11 +20,3 @@ val cache_term_by_tactic_then
-> unit Proofview.tactic
val tclABSTRACT : ?opaque:bool -> Id.t option -> unit Proofview.tactic -> unit Proofview.tactic
-
-(* Internal but used in a few places; should likely be made intro a
- proper library function, or incorporated into the generic constant
- save path *)
-val shrink_entry
- : ('a, 'b) Context.Named.Declaration.pt list
- -> 'c Declare.proof_entry
- -> 'c Declare.proof_entry * Constr.t list
diff --git a/tactics/declare.ml b/tactics/declare.ml
index 57eeddb847..fb06bb8a4f 100644
--- a/tactics/declare.ml
+++ b/tactics/declare.ml
@@ -139,9 +139,6 @@ let (inConstant : constant_obj -> obj) =
subst_function = ident_subst_function;
discharge_function = discharge_constant }
-let declare_scheme = ref (fun _ _ -> assert false)
-let set_declare_scheme f = declare_scheme := f
-
let update_tables c =
Impargs.declare_constant_implicits c;
Notation.declare_ref_arguments_scope Evd.empty (GlobRef.ConstRef c)
@@ -159,7 +156,7 @@ let register_side_effect (c, role) =
let () = register_constant c Decls.(IsProof Theorem) ImportDefaultBehavior in
match role with
| None -> ()
- | Some (Evd.Schema (ind, kind)) -> !declare_scheme kind [|ind,c|]
+ | Some (Evd.Schema (ind, kind)) -> DeclareScheme.declare_scheme kind [|ind,c|]
let record_aux env s_ty s_bo =
let open Environ in
@@ -174,6 +171,7 @@ let record_aux env s_ty s_bo =
Aux_file.record_in_aux "context_used" v
let default_univ_entry = Monomorphic_entry Univ.ContextSet.empty
+
let definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
?(univs=default_univ_entry) ?(eff=Evd.empty_side_effects) body =
{ proof_entry_body = Future.from_val ?fix_exn ((body,Univ.ContextSet.empty), eff);
@@ -184,6 +182,26 @@ let definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
proof_entry_feedback = None;
proof_entry_inline_code = inline}
+let pure_definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
+ ?(univs=default_univ_entry) body =
+ { proof_entry_body = Future.from_val ?fix_exn ((body,Univ.ContextSet.empty), ());
+ proof_entry_secctx = None;
+ proof_entry_type = types;
+ proof_entry_universes = univs;
+ proof_entry_opaque = opaque;
+ proof_entry_feedback = None;
+ proof_entry_inline_code = inline}
+
+let delayed_definition_entry ?(opaque=false) ?(inline=false) ?feedback_id ?section_vars ?(univs=default_univ_entry) ?types body =
+ { proof_entry_body = body
+ ; proof_entry_secctx = section_vars
+ ; proof_entry_type = types
+ ; proof_entry_universes = univs
+ ; proof_entry_opaque = opaque
+ ; proof_entry_feedback = feedback_id
+ ; proof_entry_inline_code = inline
+ }
+
let cast_proof_entry e =
let (body, ctx), () = Future.force e.proof_entry_body in
let univs =
@@ -326,6 +344,12 @@ let declare_private_constant ?role ?(local = ImportDefaultBehavior) ~name ~kind
let eff = { Evd.seff_private = eff; Evd.seff_roles; } in
kn, eff
+let inline_private_constants ~univs env ce =
+ let body, eff = Future.force ce.proof_entry_body in
+ let cb, ctx = Safe_typing.inline_private_constants env (body, eff.Evd.seff_private) in
+ let univs = UState.merge ~sideff:true Evd.univ_rigid univs ctx in
+ cb, univs
+
(** Declaration of section variables and local definitions *)
type variable_declaration =
| SectionLocalDef of Evd.side_effects proof_entry
@@ -413,3 +437,64 @@ let assumption_message id =
the type of the object than to the name of the object (see
discussion on coqdev: "Chapter 4 of the Reference Manual", 8/10/2015) *)
Flags.if_verbose Feedback.msg_info (Id.print id ++ str " is declared")
+
+module Internal = struct
+
+ let map_entry_body ~f entry =
+ { entry with proof_entry_body = Future.chain entry.proof_entry_body f }
+
+ let map_entry_type ~f entry =
+ { entry with proof_entry_type = f entry.proof_entry_type }
+
+ let set_opacity ~opaque entry =
+ { entry with proof_entry_opaque = opaque }
+
+ let get_fix_exn entry = Future.fix_exn_of entry.proof_entry_body
+
+ let rec decompose len c t accu =
+ let open Constr in
+ let open Context.Rel.Declaration in
+ if len = 0 then (c, t, accu)
+ else match kind c, kind t with
+ | Lambda (na, u, c), Prod (_, _, t) ->
+ decompose (pred len) c t (LocalAssum (na, u) :: accu)
+ | LetIn (na, b, u, c), LetIn (_, _, _, t) ->
+ decompose (pred len) c t (LocalDef (na, b, u) :: accu)
+ | _ -> assert false
+
+ let rec shrink ctx sign c t accu =
+ let open Constr in
+ let open Vars in
+ match ctx, sign with
+ | [], [] -> (c, t, accu)
+ | p :: ctx, decl :: sign ->
+ if noccurn 1 c && noccurn 1 t then
+ let c = subst1 mkProp c in
+ let t = subst1 mkProp t in
+ shrink ctx sign c t accu
+ else
+ let c = Term.mkLambda_or_LetIn p c in
+ let t = Term.mkProd_or_LetIn p t in
+ let accu = if Context.Rel.Declaration.is_local_assum p
+ then mkVar (NamedDecl.get_id decl) :: accu
+ else accu
+ in
+ shrink ctx sign c t accu
+ | _ -> assert false
+
+ let shrink_entry sign const =
+ let typ = match const.proof_entry_type with
+ | None -> assert false
+ | Some t -> t
+ in
+ (* The body has been forced by the call to [build_constant_by_tactic] *)
+ let () = assert (Future.is_over const.proof_entry_body) in
+ let ((body, uctx), eff) = Future.force const.proof_entry_body in
+ let (body, typ, ctx) = decompose (List.length sign) body typ [] in
+ let (body, typ, args) = shrink ctx sign body typ [] in
+ { const with
+ proof_entry_body = Future.from_val ((body, uctx), eff)
+ ; proof_entry_type = Some typ
+ }, args
+
+end
diff --git a/tactics/declare.mli b/tactics/declare.mli
index 1a037ef937..c646d2f85b 100644
--- a/tactics/declare.mli
+++ b/tactics/declare.mli
@@ -20,7 +20,7 @@ open Entries
[Nametab] and [Impargs]. *)
(** Proof entries *)
-type 'a proof_entry = {
+type 'a proof_entry = private {
proof_entry_body : 'a Entries.const_entry_body;
(* List of section variables *)
proof_entry_secctx : Id.Set.t option;
@@ -55,10 +55,35 @@ val declare_variable
i.e. Definition/Theorem/Axiom/Parameter/... *)
(* Default definition entries, transparent with no secctx or proj information *)
-val definition_entry : ?fix_exn:Future.fix_exn ->
- ?opaque:bool -> ?inline:bool -> ?types:types ->
- ?univs:Entries.universes_entry ->
- ?eff:Evd.side_effects -> constr -> Evd.side_effects proof_entry
+val definition_entry
+ : ?fix_exn:Future.fix_exn
+ -> ?opaque:bool
+ -> ?inline:bool
+ -> ?types:types
+ -> ?univs:Entries.universes_entry
+ -> ?eff:Evd.side_effects
+ -> constr
+ -> Evd.side_effects proof_entry
+
+val pure_definition_entry
+ : ?fix_exn:Future.fix_exn
+ -> ?opaque:bool
+ -> ?inline:bool
+ -> ?types:types
+ -> ?univs:Entries.universes_entry
+ -> constr
+ -> unit proof_entry
+
+(* Delayed definition entries *)
+val delayed_definition_entry
+ : ?opaque:bool
+ -> ?inline:bool
+ -> ?feedback_id:Stateid.t
+ -> ?section_vars:Id.Set.t
+ -> ?univs:Entries.universes_entry
+ -> ?types:types
+ -> 'a Entries.const_entry_body
+ -> 'a proof_entry
type import_status = ImportDefaultBehavior | ImportNeedQualified
@@ -83,10 +108,14 @@ val declare_private_constant
-> unit proof_entry
-> Constant.t * Evd.side_effects
-(** Since transparent constants' side effects are globally declared, we
- * need that *)
-val set_declare_scheme :
- (string -> (inductive * Constant.t) array -> unit) -> unit
+(** [inline_private_constants ~sideff ~univs env ce] will inline the
+ constants in [ce]'s body and return the body plus the updated
+ [UState.t]. *)
+val inline_private_constants
+ : univs:UState.t
+ -> Environ.env
+ -> Evd.side_effects proof_entry
+ -> Constr.t * UState.t
(** Declaration messages *)
@@ -101,3 +130,19 @@ val check_exists : Id.t -> unit
(* Used outside this module only in indschemes *)
exception AlreadyDeclared of (string option * Id.t)
+
+(* For legacy support, do not use *)
+module Internal : sig
+
+ val map_entry_body : f:('a Entries.proof_output -> 'b Entries.proof_output) -> 'a proof_entry -> 'b proof_entry
+ val map_entry_type : f:(Constr.t option -> Constr.t option) -> 'a proof_entry -> 'a proof_entry
+ (* Overriding opacity is indeed really hacky *)
+ val set_opacity : opaque:bool -> 'a proof_entry -> 'a proof_entry
+
+ (* TODO: This is only used in DeclareDef to forward the fix to
+ hooks, should eventually go away *)
+ val get_fix_exn : 'a proof_entry -> Future.fix_exn
+
+ val shrink_entry : EConstr.named_context -> 'a proof_entry -> 'a proof_entry * Constr.constr list
+
+end
diff --git a/tactics/declareScheme.ml b/tactics/declareScheme.ml
new file mode 100644
index 0000000000..5f4626fcb2
--- /dev/null
+++ b/tactics/declareScheme.ml
@@ -0,0 +1,42 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <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) *)
+(************************************************************************)
+
+open Names
+
+let scheme_map = Summary.ref Indmap.empty ~name:"Schemes"
+
+let cache_one_scheme kind (ind,const) =
+ let map = try Indmap.find ind !scheme_map with Not_found -> CString.Map.empty in
+ scheme_map := Indmap.add ind (CString.Map.add kind const map) !scheme_map
+
+let cache_scheme (_,(kind,l)) =
+ Array.iter (cache_one_scheme kind) l
+
+let subst_one_scheme subst (ind,const) =
+ (* Remark: const is a def: the result of substitution is a constant *)
+ (Mod_subst.subst_ind subst ind, Mod_subst.subst_constant subst const)
+
+let subst_scheme (subst,(kind,l)) =
+ (kind, CArray.Smart.map (subst_one_scheme subst) l)
+
+let discharge_scheme (_,(kind,l)) =
+ Some (kind, l)
+
+let inScheme : string * (inductive * Constant.t) array -> Libobject.obj =
+ let open Libobject in
+ declare_object @@ superglobal_object "SCHEME"
+ ~cache:cache_scheme
+ ~subst:(Some subst_scheme)
+ ~discharge:discharge_scheme
+
+let declare_scheme kind indcl =
+ Lib.add_anonymous_leaf (inScheme (kind,indcl))
+
+let lookup_scheme kind ind = CString.Map.find kind (Indmap.find ind !scheme_map)
diff --git a/tactics/declareScheme.mli b/tactics/declareScheme.mli
new file mode 100644
index 0000000000..f2ae5e41c8
--- /dev/null
+++ b/tactics/declareScheme.mli
@@ -0,0 +1,12 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <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) *)
+(************************************************************************)
+
+val declare_scheme : string -> (Names.inductive * Names.Constant.t) array -> unit
+val lookup_scheme : string -> Names.inductive -> Names.Constant.t
diff --git a/tactics/ind_tables.ml b/tactics/ind_tables.ml
index 3f824a94bf..9c94f3c319 100644
--- a/tactics/ind_tables.ml
+++ b/tactics/ind_tables.ml
@@ -15,8 +15,6 @@
declaring schemes and generating schemes on demand *)
open Names
-open Mod_subst
-open Libobject
open Nameops
open Declarations
open Constr
@@ -40,33 +38,8 @@ type individual_scheme_object_function =
type 'a scheme_kind = string
-let scheme_map = Summary.ref Indmap.empty ~name:"Schemes"
-
let pr_scheme_kind = Pp.str
-let cache_one_scheme kind (ind,const) =
- let map = try Indmap.find ind !scheme_map with Not_found -> String.Map.empty in
- scheme_map := Indmap.add ind (String.Map.add kind const map) !scheme_map
-
-let cache_scheme (_,(kind,l)) =
- Array.iter (cache_one_scheme kind) l
-
-let subst_one_scheme subst (ind,const) =
- (* Remark: const is a def: the result of substitution is a constant *)
- (subst_ind subst ind,subst_constant subst const)
-
-let subst_scheme (subst,(kind,l)) =
- (kind,Array.Smart.map (subst_one_scheme subst) l)
-
-let discharge_scheme (_,(kind,l)) =
- Some (kind, l)
-
-let inScheme : string * (inductive * Constant.t) array -> obj =
- declare_object @@ superglobal_object "SCHEME"
- ~cache:cache_scheme
- ~subst:(Some subst_scheme)
- ~discharge:discharge_scheme
-
(**********************************************************************)
(* The table of scheme building functions *)
@@ -104,11 +77,6 @@ let declare_individual_scheme_object s ?(aux="") f =
(**********************************************************************)
(* Defining/retrieving schemes *)
-let declare_scheme kind indcl =
- Lib.add_anonymous_leaf (inScheme (kind,indcl))
-
-let () = Declare.set_declare_scheme declare_scheme
-
let is_visible_name id =
try ignore (Nametab.locate (Libnames.qualid_of_ident id)); true
with Not_found -> false
@@ -124,16 +92,7 @@ let define internal role id c poly univs =
let ctx = UState.minimize univs in
let c = UnivSubst.nf_evars_and_universes_opt_subst (fun _ -> None) (UState.subst ctx) c in
let univs = UState.univ_entry ~poly ctx in
- let entry = {
- Declare.proof_entry_body =
- Future.from_val ((c,Univ.ContextSet.empty), ());
- proof_entry_secctx = None;
- proof_entry_type = None;
- proof_entry_universes = univs;
- proof_entry_opaque = false;
- proof_entry_inline_code = false;
- proof_entry_feedback = None;
- } in
+ let entry = Declare.pure_definition_entry ~univs c in
let kn, eff = Declare.declare_private_constant ~role ~kind:Decls.(IsDefinition Scheme) ~name:id entry in
let () = match internal with
| InternalTacticRequest -> ()
@@ -149,7 +108,7 @@ let define_individual_scheme_base kind suff f mode idopt (mind,i as ind) =
| None -> add_suffix mib.mind_packets.(i).mind_typename suff in
let role = Evd.Schema (ind, kind) in
let const, neff = define mode role id c (Declareops.inductive_is_polymorphic mib) ctx in
- declare_scheme kind [|ind,const|];
+ DeclareScheme.declare_scheme kind [|ind,const|];
const, Evd.concat_side_effects neff eff
let define_individual_scheme kind mode names (mind,i as ind) =
@@ -171,7 +130,7 @@ let define_mutual_scheme_base kind suff f mode names mind =
in
let (eff, consts) = Array.fold_left2_map_i fold eff ids cl in
let schemes = Array.mapi (fun i cst -> ((mind,i),cst)) consts in
- declare_scheme kind schemes;
+ DeclareScheme.declare_scheme kind schemes;
consts, eff
let define_mutual_scheme kind mode names mind =
@@ -181,7 +140,7 @@ let define_mutual_scheme kind mode names mind =
define_mutual_scheme_base kind s f mode names mind
let find_scheme_on_env_too kind ind =
- let s = String.Map.find kind (Indmap.find ind !scheme_map) in
+ let s = DeclareScheme.lookup_scheme kind ind in
s, Evd.empty_side_effects
let find_scheme ?(mode=InternalTacticRequest) kind (mind,i as ind) =
diff --git a/tactics/ind_tables.mli b/tactics/ind_tables.mli
index 17e9c7ef42..e9a792c264 100644
--- a/tactics/ind_tables.mli
+++ b/tactics/ind_tables.mli
@@ -30,7 +30,9 @@ type mutual_scheme_object_function =
type individual_scheme_object_function =
internal_flag -> inductive -> constr Evd.in_evar_universe_context * Evd.side_effects
-(** Main functions to register a scheme builder *)
+(** Main functions to register a scheme builder. Note these functions
+ are not safe to be used by plugins as their effects won't be undone
+ on backtracking *)
val declare_mutual_scheme_object : string -> ?aux:string ->
mutual_scheme_object_function -> mutual scheme_kind
diff --git a/tactics/pfedit.ml b/tactics/pfedit.ml
index 413c6540a3..3c9803432a 100644
--- a/tactics/pfedit.ml
+++ b/tactics/pfedit.ml
@@ -55,8 +55,7 @@ let get_current_goal_context pf =
let env = Global.env () in
Evd.from_env env, env
-let get_current_context pf =
- let p = Proof_global.get_proof pf in
+let get_proof_context p =
try get_goal_context_gen p 1
with
| NoSuchGoal ->
@@ -64,6 +63,10 @@ let get_current_context pf =
let { Proof.sigma } = Proof.data p in
sigma, Global.env ()
+let get_current_context pf =
+ let p = Proof_global.get_proof pf in
+ get_proof_context p
+
let solve ?with_end_tac gi info_lvl tac pr =
let tac = match with_end_tac with
| None -> tac
@@ -114,14 +117,14 @@ let by tac = Proof_global.map_fold_proof (solve (Goal_select.SelectNth 1) None t
let next = let n = ref 0 in fun () -> incr n; !n
-let build_constant_by_tactic ~name ctx sign ~poly typ tac =
+let build_constant_by_tactic ~name ?(opaque=Proof_global.Transparent) ctx sign ~poly typ tac =
let evd = Evd.from_ctx ctx in
let goals = [ (Global.env_of_context sign , typ) ] in
let pf = Proof_global.start_proof ~name ~poly ~udecl:UState.default_univ_decl evd goals in
try
let pf, status = by tac pf in
let open Proof_global in
- let { entries; universes } = close_proof ~opaque:Transparent ~keep_body_ucst_separate:false (fun x -> x) pf in
+ let { entries; universes } = close_proof ~opaque ~keep_body_ucst_separate:false (fun x -> x) pf in
match entries with
| [entry] ->
entry, status, universes
@@ -135,12 +138,13 @@ let build_by_tactic ?(side_eff=true) env sigma ~poly typ tac =
let name = Id.of_string ("temporary_proof"^string_of_int (next())) in
let sign = val_of_named_context (named_context env) in
let ce, status, univs = build_constant_by_tactic ~name sigma sign ~poly typ tac in
- let body, eff = Future.force ce.Declare.proof_entry_body in
- let (cb, ctx) =
- if side_eff then Safe_typing.inline_private_constants env (body, eff.Evd.seff_private)
- else body
+ let cb, univs =
+ if side_eff then Declare.inline_private_constants ~univs env ce
+ else
+ (* GG: side effects won't get reset: no need to treat their universes specially *)
+ let (cb, ctx), _eff = Future.force ce.Declare.proof_entry_body in
+ cb, UState.merge ~sideff:false Evd.univ_rigid univs ctx
in
- let univs = UState.merge ~sideff:side_eff Evd.univ_rigid univs ctx in
cb, status, univs
let refine_by_tactic ~name ~poly env sigma ty tac =
diff --git a/tactics/pfedit.mli b/tactics/pfedit.mli
index 30514191fa..a2e742c0d7 100644
--- a/tactics/pfedit.mli
+++ b/tactics/pfedit.mli
@@ -27,6 +27,10 @@ val get_goal_context : Proof_global.t -> int -> Evd.evar_map * env
(** [get_current_goal_context ()] works as [get_goal_context 1] *)
val get_current_goal_context : Proof_global.t -> Evd.evar_map * env
+(** [get_proof_context ()] gets the goal context for the first subgoal
+ of the proof *)
+val get_proof_context : Proof.t -> Evd.evar_map * env
+
(** [get_current_context ()] returns the context of the
current focused goal. If there is no focused goal but there
is a proof in progress, it returns the corresponding evar_map.
@@ -59,6 +63,7 @@ val use_unification_heuristics : unit -> bool
val build_constant_by_tactic
: name:Id.t
+ -> ?opaque:Proof_global.opacity_flag
-> UState.t
-> named_context_val
-> poly:bool
diff --git a/tactics/proof_global.ml b/tactics/proof_global.ml
index b723922642..b1fd34e43c 100644
--- a/tactics/proof_global.ml
+++ b/tactics/proof_global.ml
@@ -238,18 +238,10 @@ let close_proof ~opaque ~keep_body_ucst_separate ?feedback_id ~now
let t = EConstr.Unsafe.to_constr t in
let univstyp, body = make_body t p in
let univs, typ = Future.force univstyp in
- let open Declare in
- {
- proof_entry_body = body;
- proof_entry_secctx = section_vars;
- proof_entry_feedback = feedback_id;
- proof_entry_type = Some typ;
- proof_entry_inline_code = false;
- proof_entry_opaque = opaque;
- proof_entry_universes = univs; }
+ Declare.delayed_definition_entry ~opaque ?feedback_id ?section_vars ~univs ~types:typ body
in
- let entries = Future.map2 entry_fn fpl Proofview.(initial_goals entry) in
- { name; entries = entries; poly; universes; udecl }
+ let entries = Future.map2 entry_fn fpl (Proofview.initial_goals entry) in
+ { name; entries; poly; universes; udecl }
let return_proof ?(allow_partial=false) ps =
let { proof } = ps in
diff --git a/tactics/tactics.mllib b/tactics/tactics.mllib
index c5c7969a09..0c4e496650 100644
--- a/tactics/tactics.mllib
+++ b/tactics/tactics.mllib
@@ -1,3 +1,4 @@
+DeclareScheme
Declare
Proof_global
Pfedit