aboutsummaryrefslogtreecommitdiff
path: root/tactics
diff options
context:
space:
mode:
Diffstat (limited to 'tactics')
-rw-r--r--tactics/class_tactics.ml97
-rw-r--r--tactics/class_tactics.mli2
-rw-r--r--tactics/declare.ml15
-rw-r--r--tactics/declare.mli5
-rw-r--r--tactics/hints.ml51
-rw-r--r--tactics/pfedit.ml16
-rw-r--r--tactics/proof_global.ml251
-rw-r--r--tactics/proof_global.mli21
-rw-r--r--tactics/redexpr.ml17
-rw-r--r--tactics/tactics.ml2
10 files changed, 223 insertions, 254 deletions
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 92d56d2904..57eab7ddf8 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -38,33 +38,48 @@ let typeclasses_db = "typeclass_instances"
(** Options handling *)
let typeclasses_debug = ref 0
-let typeclasses_depth = ref None
+
+let typeclasses_depth_opt_name = ["Typeclasses";"Depth"]
+let get_typeclasses_depth =
+ Goptions.declare_intopt_option_and_ref
+ ~depr:false
+ ~key:typeclasses_depth_opt_name
+
+let set_typeclasses_depth =
+ Goptions.set_int_option_value typeclasses_depth_opt_name
(** When this flag is enabled, the resolution of type classes tries to avoid
useless introductions. This is no longer useful since we have eta, but is
here for compatibility purposes. Another compatibility issues is that the
cost (in terms of search depth) can differ. *)
-let typeclasses_limit_intros = ref true
-let set_typeclasses_limit_intros d = (:=) typeclasses_limit_intros d
-let get_typeclasses_limit_intros () = !typeclasses_limit_intros
-
-let typeclasses_dependency_order = ref false
-let set_typeclasses_dependency_order d = (:=) typeclasses_dependency_order d
-let get_typeclasses_dependency_order () = !typeclasses_dependency_order
-
-let typeclasses_iterative_deepening = ref false
-let set_typeclasses_iterative_deepening d = (:=) typeclasses_iterative_deepening d
-let get_typeclasses_iterative_deepening () = !typeclasses_iterative_deepening
+let get_typeclasses_limit_intros =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Typeclasses";"Limit";"Intros"]
+ ~value:true
+
+let get_typeclasses_dependency_order =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Typeclasses";"Dependency";"Order"]
+ ~value:false
+
+let iterative_deepening_opt_name = ["Typeclasses";"Iterative";"Deepening"]
+let get_typeclasses_iterative_deepening =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:iterative_deepening_opt_name
+ ~value:false
(** [typeclasses_filtered_unif] governs the unification algorithm used by type
classes. If enabled, a new algorithm based on pattern filtering and refine
will be used. When disabled, the previous algorithm based on apply will be
used. *)
-let typeclasses_filtered_unification = ref false
-let set_typeclasses_filtered_unification d =
- (:=) typeclasses_filtered_unification d
-let get_typeclasses_filtered_unification () =
- !typeclasses_filtered_unification
+let get_typeclasses_filtered_unification =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Typeclasses";"Filtered";"Unification"]
+ ~value:false
let set_typeclasses_debug d = (:=) typeclasses_debug (if d then 1 else 0)
let get_typeclasses_debug () = if !typeclasses_debug > 0 then true else false
@@ -75,40 +90,8 @@ let set_typeclasses_verbose =
let get_typeclasses_verbose () =
if !typeclasses_debug = 0 then None else Some !typeclasses_debug
-let set_typeclasses_depth d = (:=) typeclasses_depth d
-let get_typeclasses_depth () = !typeclasses_depth
-
-open Goptions
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["Typeclasses";"Limit";"Intros"];
- optread = get_typeclasses_limit_intros;
- optwrite = set_typeclasses_limit_intros; }
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["Typeclasses";"Dependency";"Order"];
- optread = get_typeclasses_dependency_order;
- optwrite = set_typeclasses_dependency_order; }
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["Typeclasses";"Iterative";"Deepening"];
- optread = get_typeclasses_iterative_deepening;
- optwrite = set_typeclasses_iterative_deepening; }
-
-let () =
- declare_bool_option
- { optdepr = false;
- optkey = ["Typeclasses";"Filtered";"Unification"];
- optread = get_typeclasses_filtered_unification;
- optwrite = set_typeclasses_filtered_unification; }
-
let () =
+ let open Goptions in
declare_bool_option
{ optdepr = false;
optkey = ["Typeclasses";"Debug"];
@@ -116,24 +99,18 @@ let () =
optwrite = set_typeclasses_debug; }
let _ =
+ let open Goptions in
declare_int_option
{ optdepr = false;
optkey = ["Typeclasses";"Debug";"Verbosity"];
optread = get_typeclasses_verbose;
optwrite = set_typeclasses_verbose; }
-let () =
- declare_int_option
- { optdepr = false;
- optkey = ["Typeclasses";"Depth"];
- optread = get_typeclasses_depth;
- optwrite = set_typeclasses_depth; }
-
type search_strategy = Dfs | Bfs
let set_typeclasses_strategy = function
- | Dfs -> set_typeclasses_iterative_deepening false
- | Bfs -> set_typeclasses_iterative_deepening true
+ | Dfs -> Goptions.set_bool_option_value iterative_deepening_opt_name false
+ | Bfs -> Goptions.set_bool_option_value iterative_deepening_opt_name true
let pr_ev evs ev =
Printer.pr_econstr_env (Goal.V82.env evs ev) evs (Goal.V82.concl evs ev)
@@ -977,7 +954,7 @@ module Search = struct
| None -> None (* This happens only because there's no evar having p *)
| Some (goals, nongoals) ->
let goalsl =
- if !typeclasses_dependency_order then
+ if get_typeclasses_dependency_order () then
top_sort evm goals
else Evar.Set.elements goals
in
diff --git a/tactics/class_tactics.mli b/tactics/class_tactics.mli
index e26338436d..b97b90d777 100644
--- a/tactics/class_tactics.mli
+++ b/tactics/class_tactics.mli
@@ -19,10 +19,8 @@ val catchable : exn -> bool
[@@ocaml.deprecated "Use instead CErrors.noncritical, or the exact name of the exception that matters in the corresponding case."]
val set_typeclasses_debug : bool -> unit
-val get_typeclasses_debug : unit -> bool
val set_typeclasses_depth : int option -> unit
-val get_typeclasses_depth : unit -> int option
type search_strategy = Dfs | Bfs
diff --git a/tactics/declare.ml b/tactics/declare.ml
index 5e6f78be6f..5135d72f7b 100644
--- a/tactics/declare.ml
+++ b/tactics/declare.ml
@@ -93,13 +93,14 @@ let load_constant i ((sp,kn), obj) =
Dumpglob.add_constant_kind con obj.cst_kind
(* Opening means making the name without its module qualification available *)
-let open_constant i ((sp,kn), obj) =
+let open_constant f i ((sp,kn), obj) =
(* Never open a local definition *)
match obj.cst_locl with
| ImportNeedQualified -> ()
| ImportDefaultBehavior ->
let con = Global.constant_of_delta_kn kn in
- Nametab.push (Nametab.Exactly i) sp (GlobRef.ConstRef con)
+ if in_filter_ref (GlobRef.ConstRef con) f then
+ Nametab.push (Nametab.Exactly i) sp (GlobRef.ConstRef con)
let exists_name id =
Decls.variable_exists id || Global.exists_objlabel (Label.of_id id)
@@ -187,14 +188,14 @@ let record_aux env s_ty s_bo =
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);
- proof_entry_secctx = None;
+let definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?feedback_id ?section_vars ?types
+ ?(univs=default_univ_entry) ?(eff=Evd.empty_side_effects) ?(univsbody=Univ.ContextSet.empty) body =
+ { proof_entry_body = Future.from_val ?fix_exn ((body,univsbody), eff);
+ proof_entry_secctx = section_vars;
proof_entry_type = types;
proof_entry_universes = univs;
proof_entry_opaque = opaque;
- proof_entry_feedback = None;
+ proof_entry_feedback = feedback_id;
proof_entry_inline_code = inline}
let pure_definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
diff --git a/tactics/declare.mli b/tactics/declare.mli
index 0068b9842a..615cffeae7 100644
--- a/tactics/declare.mli
+++ b/tactics/declare.mli
@@ -59,9 +59,14 @@ val definition_entry
: ?fix_exn:Future.fix_exn
-> ?opaque:bool
-> ?inline:bool
+ -> ?feedback_id:Stateid.t
+ -> ?section_vars:Id.Set.t
-> ?types:types
-> ?univs:Entries.universes_entry
-> ?eff:Evd.side_effects
+ -> ?univsbody:Univ.ContextSet.t
+ (** Universe-constraints attached to the body-only, used in
+ vio-delayed opaque constants and private poly universes *)
-> constr
-> Evd.side_effects proof_entry
diff --git a/tactics/hints.ml b/tactics/hints.ml
index a907b9e783..2118b4f231 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -188,27 +188,26 @@ type hints_expr =
| HintsConstructors of qualid list
| HintsExtern of int * Constrexpr.constr_expr option * Genarg.raw_generic_argument
-type import_level = [ `LAX | `WARN | `STRICT ]
-
-let warn_hint : import_level ref = ref `LAX
-let read_warn_hint () = match !warn_hint with
-| `LAX -> "Lax"
-| `WARN -> "Warn"
-| `STRICT -> "Strict"
-
-let write_warn_hint = function
-| "Lax" -> warn_hint := `LAX
-| "Warn" -> warn_hint := `WARN
-| "Strict" -> warn_hint := `STRICT
-| _ -> user_err Pp.(str "Only the following flags are accepted: Lax, Warn, Strict.")
-
-let () =
- Goptions.(declare_string_option
- { optdepr = false;
- optkey = ["Loose"; "Hint"; "Behavior"];
- optread = read_warn_hint;
- optwrite = write_warn_hint;
- })
+type import_level = HintLax | HintWarn | HintStrict
+
+let warn_hint_to_string = function
+| HintLax -> "Lax"
+| HintWarn -> "Warn"
+| HintStrict -> "Strict"
+
+let string_to_warn_hint = function
+| "Lax" -> HintLax
+| "Warn" -> HintWarn
+| "Strict" -> HintStrict
+| _ -> user_err Pp.(str "Only the following values are accepted: Lax, Warn, Strict.")
+
+let warn_hint =
+ Goptions.declare_interpreted_string_option_and_ref
+ ~depr:false
+ ~key:["Loose"; "Hint"; "Behavior"]
+ ~value:HintLax
+ string_to_warn_hint
+ warn_hint_to_string
let fresh_key =
let id = Summary.ref ~name:"HINT-COUNTER" 0 in
@@ -1164,7 +1163,7 @@ let inAutoHint : hint_obj -> obj =
declare_object {(default_object "AUTOHINT") with
cache_function = cache_autohint;
load_function = load_autohint;
- open_function = open_autohint;
+ open_function = simple_open open_autohint;
subst_function = subst_autohint;
classify_function = classify_autohint; }
@@ -1690,12 +1689,12 @@ let wrap_hint_warning_fun env sigma t =
in
(ans, set_extra_data store sigma)
-let run_hint tac k = match !warn_hint with
-| `LAX -> k tac.obj
-| `WARN ->
+let run_hint tac k = match warn_hint () with
+| HintLax -> k tac.obj
+| HintWarn ->
if is_imported tac then k tac.obj
else Proofview.tclTHEN (log_hint tac) (k tac.obj)
-| `STRICT ->
+| HintStrict ->
if is_imported tac then k tac.obj
else Proofview.tclZERO (UserError (None, (str "Tactic failure.")))
diff --git a/tactics/pfedit.ml b/tactics/pfedit.ml
index b228a04298..c139594f13 100644
--- a/tactics/pfedit.ml
+++ b/tactics/pfedit.ml
@@ -14,15 +14,11 @@ open Names
open Environ
open Evd
-let use_unification_heuristics_ref = ref true
-let () = Goptions.(declare_bool_option {
- optdepr = false;
- optkey = ["Solve";"Unification";"Constraints"];
- optread = (fun () -> !use_unification_heuristics_ref);
- optwrite = (fun a -> use_unification_heuristics_ref:=a);
-})
-
-let use_unification_heuristics () = !use_unification_heuristics_ref
+let use_unification_heuristics =
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Solve";"Unification";"Constraints"]
+ ~value:true
exception NoSuchGoal
let () = CErrors.register_handler begin function
@@ -122,7 +118,7 @@ let build_constant_by_tactic ~name ?(opaque=Proof_global.Transparent) ~uctx ~sig
let pf = Proof_global.start_proof ~name ~poly ~udecl:UState.default_univ_decl evd goals in
let pf, status = by tac pf in
let open Proof_global in
- let { entries; uctx } = close_proof ~opaque ~keep_body_ucst_separate:false (fun x -> x) pf in
+ let { entries; uctx } = close_proof ~opaque ~keep_body_ucst_separate:false pf in
match entries with
| [entry] ->
entry, status, uctx
diff --git a/tactics/proof_global.ml b/tactics/proof_global.ml
index 623e6b8a42..98de0c848b 100644
--- a/tactics/proof_global.ml
+++ b/tactics/proof_global.ml
@@ -18,9 +18,9 @@ module NamedDecl = Context.Named.Declaration
type proof_object =
{ name : Names.Id.t
+ (* [name] only used in the STM *)
; entries : Evd.side_effects Declare.proof_entry list
; uctx: UState.t
- ; udecl : UState.universe_decl
}
type opacity_flag = Opaque | Transparent
@@ -118,8 +118,7 @@ let set_used_variables ps l =
Environ.fold_named_context aux env ~init:(ctx,ctx_set) in
if not (Option.is_empty ps.section_vars) then
CErrors.user_err Pp.(str "Used section variables can be declared only once");
- (* EJGA: This is always empty thus we should modify the type *)
- (ctx, []), { ps with section_vars = Some (Context.Named.to_vars ctx) }
+ ctx, { ps with section_vars = Some (Context.Named.to_vars ctx) }
let get_open_goals ps =
let Proof.{ goals; stack; shelf } = Proof.data ps.proof in
@@ -131,130 +130,27 @@ let get_open_goals ps =
type closed_proof_output = (Constr.t * Evd.side_effects) list * UState.t
let private_poly_univs =
- let b = ref true in
- let _ = Goptions.(declare_bool_option {
- optdepr = false;
- optkey = ["Private";"Polymorphic";"Universes"];
- optread = (fun () -> !b);
- optwrite = ((:=) b);
- })
- in
- fun () -> !b
+ Goptions.declare_bool_option_and_ref
+ ~depr:false
+ ~key:["Private";"Polymorphic";"Universes"]
+ ~value:true
-let close_proof ~opaque ~keep_body_ucst_separate ?feedback_id ~now
- (fpl : closed_proof_output Future.computation) ps =
- let { section_vars; proof; udecl; initial_euctx } = ps in
- let Proof.{ name; poly; entry } = Proof.data proof in
- let opaque = match opaque with Opaque -> true | Transparent -> false in
- let constrain_variables ctx =
- UState.constrain_variables (fst (UState.context_set initial_euctx)) ctx
- in
- let fpl, univs = Future.split2 fpl in
- let uctx = if poly || now then Future.force univs else initial_euctx in
- (* Because of dependent subgoals at the beginning of proofs, we could
- have existential variables in the initial types of goals, we need to
- normalise them for the kernel. *)
- let subst_evar k =
- let { Proof.sigma } = Proof.data proof in
- Evd.existential_opt_value0 sigma k in
- let nf = UnivSubst.nf_evars_and_universes_opt_subst subst_evar
- (UState.subst uctx) in
-
- let make_body =
- if poly || now then
- let make_body t (c, eff) =
- let body = c in
- let allow_deferred =
- not poly && (keep_body_ucst_separate ||
- not (Safe_typing.empty_private_constants = eff.Evd.seff_private))
- in
- let typ = if allow_deferred then t else nf t in
- let used_univs_body = Vars.universes_of_constr body in
- let used_univs_typ = Vars.universes_of_constr typ in
- if allow_deferred then
- let initunivs = UState.univ_entry ~poly initial_euctx in
- let ctx = constrain_variables uctx in
- (* For vi2vo compilation proofs are computed now but we need to
- complement the univ constraints of the typ with the ones of
- the body. So we keep the two sets distinct. *)
- let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
- let ctx_body = UState.restrict ctx used_univs in
- let univs = UState.check_mono_univ_decl ctx_body udecl in
- (initunivs, typ), ((body, univs), eff)
- else if poly && opaque && private_poly_univs () then
- let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
- let universes = UState.restrict uctx used_univs in
- let typus = UState.restrict universes used_univs_typ in
- let udecl = UState.check_univ_decl ~poly typus udecl in
- let ubody = Univ.ContextSet.diff
- (UState.context_set universes)
- (UState.context_set typus)
- in
- (udecl, typ), ((body, ubody), eff)
- else
- (* Since the proof is computed now, we can simply have 1 set of
- constraints in which we merge the ones for the body and the ones
- for the typ. We recheck the declaration after restricting with
- the actually used universes.
- TODO: check if restrict is really necessary now. *)
- let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
- let ctx = UState.restrict uctx used_univs in
- let univs = UState.check_univ_decl ~poly ctx udecl in
- (univs, typ), ((body, Univ.ContextSet.empty), eff)
- in
- fun t p -> Future.split2 (Future.chain p (make_body t))
- else
- fun t p ->
- (* Already checked the univ_decl for the type universes when starting the proof. *)
- let univctx = UState.univ_entry ~poly:false uctx in
- let t = nf t in
- Future.from_val (univctx, t),
- Future.chain p (fun (pt,eff) ->
- (* Deferred proof, we already checked the universe declaration with
- the initial universes, ensure that the final universes respect
- the declaration as well. If the declaration is non-extensible,
- this will prevent the body from adding universes and constraints. *)
- let univs = Future.force univs in
- let univs = constrain_variables univs in
- let used_univs = Univ.LSet.union
- (Vars.universes_of_constr t)
- (Vars.universes_of_constr pt)
- in
- let univs = UState.restrict univs used_univs in
- let univs = UState.check_mono_univ_decl univs udecl in
- (pt,univs),eff)
- in
- let entry_fn p (_, t) =
- let t = EConstr.Unsafe.to_constr t in
- let univstyp, body = make_body t p in
- let univs, typ = Future.force univstyp in
- 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; uctx; udecl }
-
-let return_proof ?(allow_partial=false) ps =
- let { proof } = ps in
- if allow_partial then begin
- let proofs = Proof.partial_proof proof in
- let Proof.{sigma=evd} = Proof.data proof in
- let eff = Evd.eval_side_effects evd in
- (* ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
- side-effects... This may explain why one need to uniquize side-effects
- thereafter... *)
- let proofs = List.map (fun c -> EConstr.Unsafe.to_constr c, eff) proofs in
- proofs, Evd.evar_universe_context evd
- end else
- let Proof.{name=pid;entry} = Proof.data proof in
+(* XXX: This is still separate from close_proof below due to drop_pt in the STM *)
+(* XXX: Unsafe_typ:true is needed by vio files, see bf0499bc507d5a39c3d5e3bf1f69191339270729 *)
+let prepare_proof ~unsafe_typ { proof } =
+ let Proof.{name=pid;entry;poly} = Proof.data proof in
let initial_goals = Proofview.initial_goals entry in
let evd = Proof.return ~pid proof in
let eff = Evd.eval_side_effects evd in
let evd = Evd.minimize_universes evd in
- let proof_opt c =
+ let to_constr_body c =
match EConstr.to_constr_opt evd c with
| Some p -> p
| None -> CErrors.user_err Pp.(str "Some unresolved existential variables remain")
in
+ let to_constr_typ t =
+ if unsafe_typ then EConstr.Unsafe.to_constr t else to_constr_body t
+ in
(* ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
side-effects... This may explain why one need to uniquize side-effects
thereafter... *)
@@ -266,16 +162,119 @@ let return_proof ?(allow_partial=false) ps =
code-paths that generate several proof entries are derive and
equations and so far there is no code in the CI that will
actually call those and do a side-effect, TTBOMK *)
- let proofs =
- List.map (fun (c, _) -> (proof_opt c, eff)) initial_goals in
- proofs, Evd.evar_universe_context evd
+ (* EJGA: likely the right solution is to attach side effects to the first constant only? *)
+ let proofs = List.map (fun (body, typ) -> (to_constr_body body, eff), to_constr_typ typ) initial_goals in
+ proofs, Evd.evar_universe_context evd
+
+let close_proof ~opaque ~keep_body_ucst_separate ps =
+
+ let { section_vars; proof; udecl; initial_euctx } = ps in
+ let { Proof.name; poly } = Proof.data proof in
+ let unsafe_typ = keep_body_ucst_separate && not poly in
+ let elist, uctx = prepare_proof ~unsafe_typ ps in
+ let opaque = match opaque with Opaque -> true | Transparent -> false in
-let close_future_proof ~opaque ~feedback_id ps proof =
- close_proof ~opaque ~keep_body_ucst_separate:true ~feedback_id ~now:false proof ps
+ let make_entry ((body, eff), typ) =
+
+ let allow_deferred =
+ not poly &&
+ (keep_body_ucst_separate
+ || not (Safe_typing.is_empty_private_constants eff.Evd.seff_private))
+ in
+ let used_univs_body = Vars.universes_of_constr body in
+ let used_univs_typ = Vars.universes_of_constr typ in
+ let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
+ let utyp, ubody =
+ if allow_deferred then
+ let utyp = UState.univ_entry ~poly initial_euctx in
+ let uctx = UState.constrain_variables (fst (UState.context_set initial_euctx)) uctx in
+ (* For vi2vo compilation proofs are computed now but we need to
+ complement the univ constraints of the typ with the ones of
+ the body. So we keep the two sets distinct. *)
+ let uctx_body = UState.restrict uctx used_univs in
+ let ubody = UState.check_mono_univ_decl uctx_body udecl in
+ utyp, ubody
+ else if poly && opaque && private_poly_univs () then
+ let universes = UState.restrict uctx used_univs in
+ let typus = UState.restrict universes used_univs_typ in
+ let utyp = UState.check_univ_decl ~poly typus udecl in
+ let ubody = Univ.ContextSet.diff
+ (UState.context_set universes)
+ (UState.context_set typus)
+ in
+ utyp, ubody
+ else
+ (* Since the proof is computed now, we can simply have 1 set of
+ constraints in which we merge the ones for the body and the ones
+ for the typ. We recheck the declaration after restricting with
+ the actually used universes.
+ TODO: check if restrict is really necessary now. *)
+ let ctx = UState.restrict uctx used_univs in
+ let utyp = UState.check_univ_decl ~poly ctx udecl in
+ utyp, Univ.ContextSet.empty
+ in
+ Declare.definition_entry ~opaque ?section_vars ~univs:utyp ~univsbody:ubody ~types:typ ~eff body
+ in
+ let entries = CList.map make_entry elist in
+ { name; entries; uctx }
+
+let close_proof_delayed ~feedback_id ps (fpl : closed_proof_output Future.computation) =
+ let { section_vars; proof; udecl; initial_euctx } = ps in
+ let { Proof.name; poly; entry; sigma } = Proof.data proof in
+
+ (* We don't allow poly = true in this path *)
+ if poly then
+ CErrors.anomaly (Pp.str "Cannot delay universe-polymorphic constants.");
+
+ let fpl, uctx = Future.split2 fpl in
+ (* Because of dependent subgoals at the beginning of proofs, we could
+ have existential variables in the initial types of goals, we need to
+ normalise them for the kernel. *)
+ let subst_evar k = Evd.existential_opt_value0 sigma k in
+ let nf = UnivSubst.nf_evars_and_universes_opt_subst subst_evar (UState.subst initial_euctx) in
+
+ (* We only support opaque proofs, this will be enforced by using
+ different entries soon *)
+ let opaque = true in
+ let make_entry p (_, types) =
+ (* Already checked the univ_decl for the type universes when starting the proof. *)
+ let univs = UState.univ_entry ~poly:false initial_euctx in
+ let types = nf (EConstr.Unsafe.to_constr types) in
+
+ Future.chain p (fun (pt,eff) ->
+ (* Deferred proof, we already checked the universe declaration with
+ the initial universes, ensure that the final universes respect
+ the declaration as well. If the declaration is non-extensible,
+ this will prevent the body from adding universes and constraints. *)
+ let uctx = Future.force uctx in
+ let uctx = UState.constrain_variables (fst (UState.context_set initial_euctx)) uctx in
+ let used_univs = Univ.LSet.union
+ (Vars.universes_of_constr types)
+ (Vars.universes_of_constr pt)
+ in
+ let univs = UState.restrict uctx used_univs in
+ let univs = UState.check_mono_univ_decl univs udecl in
+ (pt,univs),eff)
+ |> Declare.delayed_definition_entry ~opaque ~feedback_id ?section_vars ~univs ~types
+ in
+ let entries = Future.map2 make_entry fpl (Proofview.initial_goals entry) in
+ { name; entries; uctx = initial_euctx }
+
+let close_future_proof = close_proof_delayed
+
+let return_partial_proof { proof } =
+ let proofs = Proof.partial_proof proof in
+ let Proof.{sigma=evd} = Proof.data proof in
+ let eff = Evd.eval_side_effects evd in
+ (* ppedrot: FIXME, this is surely wrong. There is no reason to duplicate
+ side-effects... This may explain why one need to uniquize side-effects
+ thereafter... *)
+ let proofs = List.map (fun c -> EConstr.Unsafe.to_constr c, eff) proofs in
+ proofs, Evd.evar_universe_context evd
-let close_proof ~opaque ~keep_body_ucst_separate fix_exn ps =
- close_proof ~opaque ~keep_body_ucst_separate ~now:true
- (Future.from_val ~fix_exn (return_proof ps)) ps
+let return_proof ps =
+ let p, uctx = prepare_proof ~unsafe_typ:false ps in
+ List.map fst p, uctx
let update_global_env =
map_proof (fun p ->
diff --git a/tactics/proof_global.mli b/tactics/proof_global.mli
index e1c75c0649..874708ded8 100644
--- a/tactics/proof_global.mli
+++ b/tactics/proof_global.mli
@@ -33,8 +33,6 @@ type proof_object =
(** list of the proof terms (in a form suitable for definitions). *)
; uctx: UState.t
(** universe state *)
- ; udecl : UState.universe_decl
- (** universe declaration *)
}
type opacity_flag = Opaque | Transparent
@@ -69,7 +67,7 @@ val update_global_env : t -> t
(* Takes a function to add to the exceptions data relative to the
state in which the proof was built *)
-val close_proof : opaque:opacity_flag -> keep_body_ucst_separate:bool -> Future.fix_exn -> t -> proof_object
+val close_proof : opaque:opacity_flag -> keep_body_ucst_separate:bool -> t -> proof_object
(* Intermediate step necessary to delegate the future.
* Both access the current proof state. The former is supposed to be
@@ -77,11 +75,13 @@ val close_proof : opaque:opacity_flag -> keep_body_ucst_separate:bool -> Future.
type closed_proof_output
-(* If allow_partial is set (default no) then an incomplete proof
- * is allowed (no error), and a warn is given if the proof is complete. *)
-val return_proof : ?allow_partial:bool -> t -> closed_proof_output
-val close_future_proof : opaque:opacity_flag -> feedback_id:Stateid.t -> t ->
- closed_proof_output Future.computation -> proof_object
+(** Requires a complete proof. *)
+val return_proof : t -> closed_proof_output
+
+(** An incomplete proof is allowed (no error), and a warn is given if
+ the proof is complete. *)
+val return_partial_proof : t -> closed_proof_output
+val close_future_proof : feedback_id:Stateid.t -> t -> closed_proof_output Future.computation -> proof_object
val get_open_goals : t -> int
@@ -93,7 +93,6 @@ val map_fold_proof_endline : (unit Proofview.tactic -> Proof.t -> Proof.t * 'a)
val set_endline_tactic : Genarg.glob_generic_argument -> t -> t
(** Sets the section variables assumed by the proof, returns its closure
- * (w.r.t. type dependencies and let-ins covered by it) + a list of
- * ids to be cleared *)
+ * (w.r.t. type dependencies and let-ins covered by it) *)
val set_used_variables : t ->
- Names.Id.t list -> (Constr.named_context * Names.lident list) * t
+ Names.Id.t list -> Constr.named_context * t
diff --git a/tactics/redexpr.ml b/tactics/redexpr.ml
index 250c80d9a5..f681e4e99e 100644
--- a/tactics/redexpr.ml
+++ b/tactics/redexpr.ml
@@ -37,7 +37,7 @@ let warn_native_compute_disabled =
strbrk "native_compute disabled at configure time; falling back to vm_compute.")
let cbv_native env sigma c =
- if Coq_config.native_compiler then
+ if Flags.get_native_compiler () then
let ctyp = Retyping.get_type_of env sigma c in
Nativenorm.native_norm env sigma c ctyp
else
@@ -53,13 +53,8 @@ let whd_cbn flags env sigma t =
let strong_cbn flags =
strong_with_flags whd_cbn flags
-let simplIsCbn = ref (false)
-let () = Goptions.(declare_bool_option {
- optdepr = false;
- optkey = ["SimplIsCbn"];
- optread = (fun () -> !simplIsCbn);
- optwrite = (fun a -> simplIsCbn:=a);
-})
+let simplIsCbn =
+ Goptions.declare_bool_option_and_ref ~depr:false ~key:["SimplIsCbn"] ~value:false
let set_strategy_one ref l =
let k =
@@ -228,10 +223,10 @@ let reduction_of_red_expr env =
else (e_red red_product,DEFAULTcast)
| Hnf -> (e_red hnf_constr,DEFAULTcast)
| Simpl (f,o) ->
- let whd_am = if !simplIsCbn then whd_cbn (make_flag f) else whd_simpl in
- let am = if !simplIsCbn then strong_cbn (make_flag f) else simpl in
+ let whd_am = if simplIsCbn () then whd_cbn (make_flag f) else whd_simpl in
+ let am = if simplIsCbn () then strong_cbn (make_flag f) else simpl in
let () =
- if not (!simplIsCbn || List.is_empty f.rConst) then
+ if not (simplIsCbn () || List.is_empty f.rConst) then
warn_simpl_unfolding_modifiers () in
(contextualize (if head_style then whd_am else am) am o,DEFAULTcast)
| Cbv f -> (e_red (cbv_norm_flags (make_flag f)),DEFAULTcast)
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 30ca024a2f..c79aca3d3c 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -1223,7 +1223,7 @@ let rec intros_move = function
or a term with bindings *)
let tactic_infer_flags with_evar = {
- Pretyping.use_typeclasses = true;
+ Pretyping.use_typeclasses = Pretyping.UseTC;
Pretyping.solve_unification_constraints = true;
Pretyping.fail_evar = not with_evar;
Pretyping.expand_evars = true;