aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/eConstr.ml15
-rw-r--r--engine/eConstr.mli16
-rw-r--r--engine/evarutil.ml135
-rw-r--r--engine/evarutil.mli15
-rw-r--r--engine/evd.ml89
-rw-r--r--engine/evd.mli35
-rw-r--r--engine/ftactic.ml10
-rw-r--r--engine/ftactic.mli14
-rw-r--r--engine/logic_monad.ml11
-rw-r--r--engine/logic_monad.mli11
-rw-r--r--engine/namegen.ml67
-rw-r--r--engine/namegen.mli17
-rw-r--r--engine/nameops.ml10
-rw-r--r--engine/nameops.mli10
-rw-r--r--engine/proofview.ml163
-rw-r--r--engine/proofview.mli70
-rw-r--r--engine/proofview_monad.ml40
-rw-r--r--engine/proofview_monad.mli31
-rw-r--r--engine/termops.ml29
-rw-r--r--engine/termops.mli27
-rw-r--r--engine/uState.ml50
-rw-r--r--engine/uState.mli17
-rw-r--r--engine/universes.ml103
-rw-r--r--engine/universes.mli23
-rw-r--r--engine/univops.ml10
-rw-r--r--engine/univops.mli10
26 files changed, 665 insertions, 363 deletions
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index a65b3941ef..b95068ebf4 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 CErrors
@@ -695,6 +697,10 @@ let cast_rel_context :
type a b. (a,b) eq -> (a, a) Rel.pt -> (b, b) Rel.pt =
fun Refl x -> x
+let cast_rec_decl :
+ type a b. (a,b) eq -> (a, a) Constr.prec_declaration -> (b, b) Constr.prec_declaration =
+ fun Refl x -> x
+
let cast_named_decl :
type a b. (a,b) eq -> (a, a) Named.Declaration.pt -> (b, b) Named.Declaration.pt =
fun Refl x -> x
@@ -817,6 +823,7 @@ let it_mkLambda_or_LetIn t ctx = List.fold_left (fun c d -> mkLambda_or_LetIn d
let push_rel d e = push_rel (cast_rel_decl unsafe_eq d) e
let push_rel_context d e = push_rel_context (cast_rel_context unsafe_eq d) e
+let push_rec_types d e = push_rec_types (cast_rec_decl unsafe_eq d) e
let push_named d e = push_named (cast_named_decl unsafe_eq d) e
let push_named_context d e = push_named_context (cast_named_context unsafe_eq d) e
let push_named_context_val d e = push_named_context_val (cast_named_decl unsafe_eq d) e
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index 30de748a19..36b6093d0f 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 CSig
@@ -67,7 +69,10 @@ val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_ter
val kind_upto : Evd.evar_map -> Constr.t -> (Constr.t, Constr.t, Sorts.t, Univ.Instance.t) Constr.kind_of_term
val to_constr : Evd.evar_map -> t -> Constr.t
-(** Returns the evar-normal form of the argument. See {!Evarutil.nf_evar}. *)
+(** Returns the evar-normal form of the argument, and cast it as a theoretically
+ evar-free term. In practice this function does not check that the result
+ is actually evar-free, it is currently the duty of the caller to do so.
+ This might change in the future. *)
val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
@@ -251,6 +256,7 @@ end
val push_rel : rel_declaration -> env -> env
val push_rel_context : rel_context -> env -> env
+val push_rec_types : (t, t) Constr.prec_declaration -> env -> env
val push_named : named_declaration -> env -> env
val push_named_context : named_context -> env -> env
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 374fdce722..6b3ce048f7 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 CErrors
@@ -87,15 +89,15 @@ let nf_evars_universes evm =
(Evd.universe_subst evm)
let nf_evars_and_universes evm =
- let evm = Evd.nf_constraints evm in
+ let evm = Evd.minimize_universes evm in
evm, nf_evars_universes evm
let e_nf_evars_and_universes evdref =
- evdref := Evd.nf_constraints !evdref;
+ evdref := Evd.minimize_universes !evdref;
nf_evars_universes !evdref, Evd.universe_subst !evdref
let nf_evar_map_universes evm =
- let evm = Evd.nf_constraints evm in
+ let evm = Evd.minimize_universes evm in
let subst = Evd.universe_subst evm in
if Univ.LMap.is_empty subst then evm, nf_evar0 evm
else
@@ -257,22 +259,6 @@ let make_pure_subst evi args =
* we have the property that u and phi(t) are convertible in env.
*)
-let csubst_subst (k, s) c =
- (** Safe because this is a substitution *)
- let c = EConstr.Unsafe.to_constr c in
- let rec subst n c = match Constr.kind c with
- | Rel m ->
- if m <= n then c
- else if m - n <= k then EConstr.Unsafe.to_constr (Int.Map.find (k - m + n) s)
- else mkRel (m - k)
- | _ -> Constr.map_with_binders succ subst n c
- in
- let c = if k = 0 then c else subst 0 c in
- EConstr.of_constr c
-
-let subst2 subst vsubst c =
- csubst_subst subst (EConstr.Vars.replace_vars vsubst c)
-
let next_ident_away id avoid =
let avoid id = Id.Set.mem id avoid in
next_ident_away_from id avoid
@@ -282,19 +268,79 @@ let next_name_away na avoid =
let id = match na with Name id -> id | Anonymous -> default_non_dependent_ident in
next_ident_away_from id avoid
-type csubst = int * EConstr.t Int.Map.t
+type subst_val =
+| SRel of int
+| SVar of Id.t
+
+type csubst = {
+ csubst_len : int;
+ (** Cardinal of [csubst_rel] *)
+ csubst_var : Constr.t Id.Map.t;
+ (** A mapping of variables to variables. We use the more general
+ [Constr.t] to share allocations, but all values are of shape [Var _]. *)
+ csubst_rel : Constr.t Int.Map.t;
+ (** A contiguous mapping of integers to variables. Same remark for values. *)
+ csubst_rev : subst_val Id.Map.t;
+ (** Reverse mapping of the substitution *)
+}
+(** This type represent a name substitution for the named and De Bruijn parts of
+ a environment. For efficiency we also store the reverse substitution.
+ Invariant: all identifiers in the codomain of [csubst_var] and [csubst_rel]
+ must be pairwise distinct. *)
+
+let empty_csubst = {
+ csubst_len = 0;
+ csubst_rel = Int.Map.empty;
+ csubst_var = Id.Map.empty;
+ csubst_rev = Id.Map.empty;
+}
-let empty_csubst = (0, Int.Map.empty)
+let csubst_subst { csubst_len = k; csubst_var = v; csubst_rel = s } c =
+ (** Safe because this is a substitution *)
+ let c = EConstr.Unsafe.to_constr c in
+ let rec subst n c = match Constr.kind c with
+ | Rel m ->
+ if m <= n then c
+ else if m - n <= k then Int.Map.find (k - m + n) s
+ else mkRel (m - k)
+ | Var id ->
+ begin try Id.Map.find id v with Not_found -> c end
+ | _ -> Constr.map_with_binders succ subst n c
+ in
+ let c = if k = 0 && Id.Map.is_empty v then c else subst 0 c in
+ EConstr.of_constr c
type ext_named_context =
- csubst * (Id.t * EConstr.constr) list *
- Id.Set.t * EConstr.named_context
-
-let push_var id (n, s) =
- let s = Int.Map.add n (EConstr.mkVar id) s in
- (succ n, s)
-
-let push_rel_decl_to_named_context sigma decl (subst, vsubst, avoid, nc) =
+ csubst * Id.Set.t * EConstr.named_context
+
+let push_var id { csubst_len = n; csubst_var = v; csubst_rel = s; csubst_rev = r } =
+ let s = Int.Map.add n (Constr.mkVar id) s in
+ let r = Id.Map.add id (SRel n) r in
+ { csubst_len = succ n; csubst_var = v; csubst_rel = s; csubst_rev = r }
+
+(** Post-compose the substitution with the generator [src ↦ tgt] *)
+let update_var src tgt subst =
+ let cur =
+ try Some (Id.Map.find src subst.csubst_rev)
+ with Not_found -> None
+ in
+ match cur with
+ | None ->
+ (** Missing keys stand for identity substitution [src ↦ src] *)
+ let csubst_var = Id.Map.add src (Constr.mkVar tgt) subst.csubst_var in
+ let csubst_rev = Id.Map.add tgt (SVar src) subst.csubst_rev in
+ { subst with csubst_var; csubst_rev }
+ | Some bnd ->
+ let csubst_rev = Id.Map.add tgt bnd (Id.Map.remove src subst.csubst_rev) in
+ match bnd with
+ | SRel m ->
+ let csubst_rel = Int.Map.add m (Constr.mkVar tgt) subst.csubst_rel in
+ { subst with csubst_rel; csubst_rev }
+ | SVar id ->
+ let csubst_var = Id.Map.add id (Constr.mkVar tgt) subst.csubst_var in
+ { subst with csubst_var; csubst_rev }
+
+let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let open EConstr in
let open Vars in
let map_decl f d =
@@ -330,18 +376,17 @@ let push_rel_decl_to_named_context sigma decl (subst, vsubst, avoid, nc) =
binding named [id], we will keep [id0] (the name given
by the user) and rename [id0] into [id] in the named
context. Unless [id] is a section variable. *)
- let subst = (fst subst, Int.Map.map (replace_vars [id0,mkVar id]) (snd subst)) in
- let vsubst = (id0,mkVar id)::vsubst in
- let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (subst2 subst vsubst) in
+ let subst = update_var id0 id subst in
+ let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (csubst_subst subst) in
let nc = List.map (replace_var_named_declaration id0 id) nc in
- (push_var id0 subst, vsubst, Id.Set.add id avoid, d :: nc)
+ (push_var id0 subst, Id.Set.add id avoid, d :: nc)
| _ ->
(* spiwack: if [id0] is a section variable renaming it is
incorrect. We revert to a less robust behaviour where
the new binder has name [id]. Which amounts to the same
behaviour than when [id=id0]. *)
- let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (subst2 subst vsubst) in
- (push_var id subst, vsubst, Id.Set.add id avoid, d :: nc)
+ let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (csubst_subst subst) in
+ (push_var id subst, Id.Set.add id avoid, d :: nc)
let push_rel_context_to_named_context env sigma typ =
(* compute the instances relative to the named context and rel_context *)
@@ -350,17 +395,17 @@ let push_rel_context_to_named_context env sigma typ =
let ids = List.map get_id (named_context env) in
let inst_vars = List.map mkVar ids in
if List.is_empty (Environ.rel_context env) then
- (named_context_val env, typ, inst_vars, empty_csubst, [])
+ (named_context_val env, typ, inst_vars, empty_csubst)
else
let avoid = List.fold_right Id.Set.add ids Id.Set.empty in
let inst_rels = List.rev (rel_list 0 (nb_rel env)) in
(* move the rel context to a named context and extend the named instance *)
(* with vars of the rel context *)
(* We do keep the instances corresponding to local definition (see above) *)
- let (subst, vsubst, _, env) =
+ let (subst, _, env) =
Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc)
- (rel_context env) ~init:(empty_csubst, [], avoid, named_context env) in
- (val_of_named_context env, subst2 subst vsubst typ, inst_rels@inst_vars, subst, vsubst)
+ (rel_context env) ~init:(empty_csubst, avoid, named_context env) in
+ (val_of_named_context env, csubst_subst subst typ, inst_rels@inst_vars, subst)
(*------------------------------------*
* Entry points to define new evars *
@@ -425,8 +470,8 @@ let new_evar_from_context sign evd ?src ?filter ?candidates ?store ?naming ?prin
(* [new_evar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
- let sign,typ',instance,subst,vsubst = push_rel_context_to_named_context env evd typ in
- let map c = subst2 subst vsubst c in
+ let sign,typ',instance,subst = push_rel_context_to_named_context env evd typ in
+ let map c = csubst_subst subst c in
let candidates = Option.map (fun l -> List.map map l) candidates in
let instance =
match filter with
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index 37f5968ad8..373875bd05 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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
@@ -222,14 +224,13 @@ val empty_csubst : csubst
val csubst_subst : csubst -> constr -> constr
type ext_named_context =
- csubst * (Id.t * constr) list *
- Id.Set.t * named_context
+ csubst * Id.Set.t * named_context
val push_rel_decl_to_named_context :
evar_map -> rel_declaration -> ext_named_context -> ext_named_context
val push_rel_context_to_named_context : Environ.env -> evar_map -> types ->
- named_context_val * types * constr list * csubst * (Id.t*constr) list
+ named_context_val * types * constr list * csubst
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
diff --git a/engine/evd.ml b/engine/evd.ml
index e33c851f6e..185cab1019 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Pp
@@ -251,21 +253,8 @@ let instantiate_evar_array info c args =
| [] -> c
| _ -> replace_vars inst c
-type evar_universe_context = UState.t
-type 'a in_evar_universe_context = 'a * evar_universe_context
-
-let empty_evar_universe_context = UState.empty
-let union_evar_universe_context = UState.union
-let evar_universe_context_set = UState.context_set
-let evar_universe_context_constraints = UState.constraints
-let evar_context_universe_context = UState.context
-let evar_universe_context_of = UState.of_context_set
-let evar_universe_context_subst = UState.subst
-let add_constraints_context = UState.add_constraints
-let add_universe_constraints_context = UState.add_universe_constraints
-let constrain_variables = UState.constrain_variables
-let evar_universe_context_of_binders = UState.of_binders
+type 'a in_evar_universe_context = 'a * UState.t
(*******************************************************************)
(* Metamaps *)
@@ -425,7 +414,7 @@ type evar_map = {
undf_evars : evar_info EvMap.t;
evar_names : EvNames.t;
(** Universes *)
- universes : evar_universe_context;
+ universes : UState.t;
(** Conversion problems *)
conv_pbs : evar_constraint list;
last_mods : Evar.Set.t;
@@ -556,10 +545,10 @@ let existential_type d (n, args) =
instantiate_evar_array info info.evar_concl args
let add_constraints d c =
- { d with universes = add_constraints_context d.universes c }
+ { d with universes = UState.add_constraints d.universes c }
let add_universe_constraints d c =
- { d with universes = add_universe_constraints_context d.universes c }
+ { d with universes = UState.add_universe_constraints d.universes c }
(*** /Lifting... ***)
@@ -584,7 +573,7 @@ let create_evar_defs sigma = { sigma with
let empty = {
defn_evars = EvMap.empty;
undf_evars = EvMap.empty;
- universes = empty_evar_universe_context;
+ universes = UState.empty;
conv_pbs = [];
last_mods = Evar.Set.empty;
metas = Metamap.empty;
@@ -607,14 +596,14 @@ let evars_reset_evd ?(with_conv_pbs=false) ?(with_univs=true) evd d =
let last_mods = if with_conv_pbs then evd.last_mods else d.last_mods in
let universes =
if not with_univs then evd.universes
- else union_evar_universe_context evd.universes d.universes
+ else UState.union evd.universes d.universes
in
{ evd with
metas = d.metas;
last_mods; conv_pbs; universes }
let merge_universe_context evd uctx' =
- { evd with universes = union_evar_universe_context evd.universes uctx' }
+ { evd with universes = UState.union evd.universes uctx' }
let set_universe_context evd uctx' =
{ evd with universes = uctx' }
@@ -796,16 +785,6 @@ let make_flexible_variable evd ~algebraic u =
{ evd with universes =
UState.make_flexible_variable evd.universes ~algebraic u }
-let make_evar_universe_context e l =
- let uctx = UState.make (Environ.universes e) in
- match l with
- | None -> uctx
- | Some us ->
- List.fold_left
- (fun uctx (loc,id) ->
- fst (UState.new_univ_variable ?loc univ_rigid (Some id) uctx))
- uctx us
-
(****************************************)
(* Operations on constants *)
(****************************************)
@@ -855,7 +834,7 @@ let normalize_universe evd =
let normalize_universe_instance evd l =
let vars = ref (UState.subst evd.universes) in
- let normalize = Univ.level_subst_of (Universes.normalize_univ_variable_opt_subst vars) in
+ let normalize = Universes.level_subst_of (Universes.normalize_univ_variable_opt_subst vars) in
Univ.Instance.subst_fn normalize l
let normalize_sort evars s =
@@ -908,10 +887,6 @@ let check_eq evd s s' =
let check_leq evd s s' =
UGraph.check_leq (UState.ugraph evd.universes) s s'
-let normalize_evar_universe_context_variables = UState.normalize_variables
-
-let abstract_undefined_variables = UState.abstract_undefined_variables
-
let fix_undefined_variables evd =
{ evd with universes = UState.fix_undefined_variables evd.universes }
@@ -920,16 +895,14 @@ let refresh_undefined_universes evd =
let evd' = cmap (subst_univs_level_constr subst) {evd with universes = uctx'} in
evd', subst
-let normalize_evar_universe_context = UState.normalize
-
-let nf_univ_variables evd =
- let subst, uctx' = normalize_evar_universe_context_variables evd.universes in
+let nf_univ_variables evd =
+ let subst, uctx' = UState.normalize_variables evd.universes in
let evd' = {evd with universes = uctx'} in
evd', subst
-let nf_constraints evd =
- let subst, uctx' = normalize_evar_universe_context_variables evd.universes in
- let uctx' = normalize_evar_universe_context uctx' in
+let minimize_universes evd =
+ let subst, uctx' = UState.normalize_variables evd.universes in
+ let uctx' = UState.minimize uctx' in
{evd with universes = uctx'}
let universe_of_name evd s = UState.universe_of_name evd.universes s
@@ -1074,7 +1047,7 @@ let clear_metas evd = {evd with metas = Metamap.empty}
let meta_merge ?(with_univs = true) evd1 evd2 =
let metas = Metamap.fold Metamap.add evd1.metas evd2.metas in
let universes =
- if with_univs then union_evar_universe_context evd2.universes evd1.universes
+ if with_univs then UState.union evd2.universes evd1.universes
else evd2.universes
in
{evd2 with universes; metas; }
@@ -1174,3 +1147,25 @@ module Monad =
(* Failure explanation *)
type unsolvability_explanation = SeveralInstancesFound of int
+
+(** Deprecated *)
+type evar_universe_context = UState.t
+let empty_evar_universe_context = UState.empty
+let union_evar_universe_context = UState.union
+let evar_universe_context_set = UState.context_set
+let evar_universe_context_constraints = UState.constraints
+let evar_context_universe_context = UState.context
+let evar_universe_context_of = UState.of_context_set
+let evar_universe_context_subst = UState.subst
+let add_constraints_context = UState.add_constraints
+let constrain_variables = UState.constrain_variables
+let evar_universe_context_of_binders = UState.of_binders
+let make_evar_universe_context e l =
+ let g = Environ.universes e in
+ match l with
+ | None -> UState.make g
+ | Some l -> UState.make_with_initial_binders g l
+let normalize_evar_universe_context_variables = UState.normalize_variables
+let abstract_undefined_variables = UState.abstract_undefined_variables
+let normalize_evar_universe_context = UState.minimize
+let nf_constraints = minimize_universes
diff --git a/engine/evd.mli b/engine/evd.mli
index b28ce2a62d..49c953f6d3 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Util
@@ -318,8 +320,8 @@ exception UniversesDiffer
val add_universe_constraints : evar_map -> Universes.Constraints.t -> evar_map
(** Add the given universe unification constraints to the evar map.
- @raises UniversesDiffer in case a first-order unification fails.
- @raises UniverseInconsistency
+ @raise UniversesDiffer in case a first-order unification fails.
+ @raise UniverseInconsistency .
*)
(** {5 Extra data}
@@ -491,22 +493,31 @@ val univ_flexible_alg : rigid
type 'a in_evar_universe_context = 'a * UState.t
val evar_universe_context_set : UState.t -> Univ.ContextSet.t
+[@@ocaml.deprecated "Alias of UState.context_set"]
val evar_universe_context_constraints : UState.t -> Univ.Constraint.t
+[@@ocaml.deprecated "Alias of UState.constraints"]
val evar_context_universe_context : UState.t -> Univ.UContext.t
[@@ocaml.deprecated "alias of UState.context"]
val evar_universe_context_of : Univ.ContextSet.t -> UState.t
+[@@ocaml.deprecated "Alias of UState.of_context_set"]
val empty_evar_universe_context : UState.t
+[@@ocaml.deprecated "Alias of UState.empty"]
val union_evar_universe_context : UState.t -> UState.t ->
UState.t
+[@@ocaml.deprecated "Alias of UState.union"]
val evar_universe_context_subst : UState.t -> Universes.universe_opt_subst
+[@@ocaml.deprecated "Alias of UState.subst"]
val constrain_variables : Univ.LSet.t -> UState.t -> UState.t
+[@@ocaml.deprecated "Alias of UState.constrain_variables"]
val evar_universe_context_of_binders :
Universes.universe_binders -> UState.t
+[@@ocaml.deprecated "Alias of UState.of_binders"]
-val make_evar_universe_context : env -> (Id.t located) list option -> UState.t
+val make_evar_universe_context : env -> Misctypes.lident list option -> UState.t
+[@@ocaml.deprecated "Use UState.make or UState.make_with_initial_binders"]
val restrict_universe_context : evar_map -> Univ.LSet.t -> evar_map
(** Raises Not_found if not a name for a universe in this map. *)
val universe_of_name : evar_map -> Id.t -> Univ.Level.t
@@ -514,13 +525,15 @@ val universe_of_name : evar_map -> Id.t -> Univ.Level.t
val universe_binders : evar_map -> Universes.universe_binders
val add_constraints_context : UState.t ->
Univ.Constraint.t -> UState.t
+[@@ocaml.deprecated "Alias of UState.add_constraints"]
val normalize_evar_universe_context_variables : UState.t ->
Univ.universe_subst in_evar_universe_context
+[@@ocaml.deprecated "Alias of UState.normalize_variables"]
-val normalize_evar_universe_context : UState.t ->
- UState.t
+val normalize_evar_universe_context : UState.t -> UState.t
+[@@ocaml.deprecated "Alias of UState.minimize"]
val new_univ_level_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Level.t
val new_univ_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Universe.t
@@ -579,12 +592,16 @@ val with_context_set : ?loc:Loc.t -> rigid -> evar_map -> 'a Univ.in_universe_co
val nf_univ_variables : evar_map -> evar_map * Univ.universe_subst
val abstract_undefined_variables : UState.t -> UState.t
+[@@ocaml.deprecated "Alias of UState.abstract_undefined_variables"]
val fix_undefined_variables : evar_map -> evar_map
val refresh_undefined_universes : evar_map -> evar_map * Univ.universe_level_subst
+(** Universe minimization *)
+val minimize_universes : evar_map -> evar_map
val nf_constraints : evar_map -> evar_map
+[@@ocaml.deprecated "Alias of Evd.minimize_universes"]
val update_sigma_env : evar_map -> env -> evar_map
diff --git a/engine/ftactic.ml b/engine/ftactic.ml
index 8e4c5f2206..e23a03c0c7 100644
--- a/engine/ftactic.ml
+++ b/engine/ftactic.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Proofview.Notations
diff --git a/engine/ftactic.mli b/engine/ftactic.mli
index c108c0c2ea..6c389b2d67 100644
--- a/engine/ftactic.mli
+++ b/engine/ftactic.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This module defines potentially focussing tactics. They are used by Ltac to
@@ -39,10 +41,10 @@ val run : 'a t -> ('a -> unit Proofview.tactic) -> unit Proofview.tactic
(** {5 Focussing} *)
-val nf_enter : ([ `NF ] Proofview.Goal.t -> 'a t) -> 'a t
+val nf_enter : (Proofview.Goal.t -> 'a t) -> 'a t
(** Enter a goal. The resulting tactic is focussed. *)
-val enter : ([ `LZ ] Proofview.Goal.t -> 'a t) -> 'a t
+val enter : (Proofview.Goal.t -> 'a t) -> 'a t
(** Enter a goal, without evar normalization. The resulting tactic is
focussed. *)
diff --git a/engine/logic_monad.ml b/engine/logic_monad.ml
index 9dc5d473b9..4afa817b27 100644
--- a/engine/logic_monad.ml
+++ b/engine/logic_monad.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file defines the low-level monadic operations used by the
@@ -107,7 +109,6 @@ struct
let print_debug s = make (fun _ -> Feedback.msg_info s)
let print_info s = make (fun _ -> Feedback.msg_info s)
let print_warning s = make (fun _ -> Feedback.msg_warning s)
- let print_error s = make (fun _ -> Feedback.msg_error s)
let print_notice s = make (fun _ -> Feedback.msg_notice s)
let run = fun x ->
diff --git a/engine/logic_monad.mli b/engine/logic_monad.mli
index 8c8f9fe935..545334ce9a 100644
--- a/engine/logic_monad.mli
+++ b/engine/logic_monad.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file implements the low-level monadic operations used by the
@@ -61,7 +63,6 @@ module NonLogical : sig
val print_warning : Pp.t -> unit t
val print_notice : Pp.t -> unit t
val print_info : Pp.t -> unit t
- val print_error : Pp.t -> unit t
(** [Pervasives.raise]. Except that exceptions are wrapped with
{!Exception}. *)
diff --git a/engine/namegen.ml b/engine/namegen.ml
index ff0b5a74e7..d66b77b573 100644
--- a/engine/namegen.ml
+++ b/engine/namegen.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(* Created from contents that was formerly in termops.ml and
@@ -190,9 +192,45 @@ let it_mkLambda_or_LetIn_name env sigma b hyps =
(**********************************************************************)
(* Fresh names *)
+(* Introduce a mode where auto-generated names are mangled
+ to test dependence of scripts on auto-generated names *)
+
+let mangle_names = ref false
+
+let _ = Goptions.(
+ declare_bool_option
+ { optdepr = false;
+ optname = "mangle auto-generated names";
+ optkey = ["Mangle";"Names"];
+ optread = (fun () -> !mangle_names);
+ optwrite = (:=) mangle_names; })
+
+let mangle_names_prefix = ref (Id.of_string "_0")
+let set_prefix x = mangle_names_prefix := forget_subscript x
+
+let set_mangle_names_mode x = begin
+ set_prefix x;
+ mangle_names := true
+ end
+
+let _ = Goptions.(
+ declare_string_option
+ { optdepr = false;
+ optname = "mangled names prefix";
+ optkey = ["Mangle";"Names";"Prefix"];
+ optread = (fun () -> Id.to_string !mangle_names_prefix);
+ optwrite = begin fun x ->
+ set_prefix
+ (try Id.of_string x
+ with CErrors.UserError _ -> CErrors.user_err Pp.(str ("Not a valid identifier: \"" ^ x ^ "\".")))
+ end })
+
+let mangle_id id = if !mangle_names then !mangle_names_prefix else id
+
(* Looks for next "good" name by lifting subscript *)
let next_ident_away_from id bad =
+ let id = mangle_id id in
let rec name_rec id = if bad id then name_rec (increment_subscript id) else id in
name_rec id
@@ -291,6 +329,7 @@ let next_global_ident_away id avoid =
looks for same name with lower available subscript *)
let next_ident_away id avoid =
+ let id = mangle_id id in
if Id.Set.mem id avoid then
next_ident_away_from (restart_subscript id) (fun id -> Id.Set.mem id avoid)
else id
@@ -421,23 +460,3 @@ let rename_bound_vars_as_displayed sigma avoid env c =
| _ -> c
in
rename avoid env c
-
-(**********************************************************************)
-(* "H"-based naming strategy introduced June 2014 for hypotheses in
- Prop produced by case/elim/destruct/induction, in place of the
- strategy that was using the first letter of the type, leading to
- inelegant "n:~A", "e:t=u", etc. when eliminating sumbool or similar
- types *)
-
-let h_based_elimination_names = ref false
-
-let use_h_based_elimination_names () = !h_based_elimination_names
-
-open Goptions
-
-let _ = declare_bool_option
- { optdepr = true; (* remove in 8.8 *)
- optname = "use of \"H\"-based proposition names in elimination tactics";
- optkey = ["Standard";"Proposition";"Elimination";"Names"];
- optread = (fun () -> !h_based_elimination_names);
- optwrite = (:=) h_based_elimination_names }
diff --git a/engine/namegen.mli b/engine/namegen.mli
index abeed9f62d..1b70ef68dd 100644
--- a/engine/namegen.mli
+++ b/engine/namegen.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file features facilities to generate fresh names. *)
@@ -114,7 +116,6 @@ val compute_displayed_name_in_gen :
(evar_map -> int -> 'a -> bool) ->
evar_map -> Id.Set.t -> Name.t -> 'a -> Name.t * Id.Set.t
-(**********************************************************************)
-(* Naming strategy for arguments in Prop when eliminating inductive types *)
-
-val use_h_based_elimination_names : unit -> bool
+val set_mangle_names_mode : Id.t -> unit
+(** Turn on mangled names mode and with the given prefix.
+ @raise UserError if the argument is invalid as an identifier. *)
diff --git a/engine/nameops.ml b/engine/nameops.ml
index 5105d7becc..53969cafa8 100644
--- a/engine/nameops.ml
+++ b/engine/nameops.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Util
diff --git a/engine/nameops.mli b/engine/nameops.mli
index 0fec8a925d..96842dfb99 100644
--- a/engine/nameops.mli
+++ b/engine/nameops.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 0a64351950..8a844bbf54 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
@@ -33,7 +35,7 @@ type entry = (EConstr.constr * EConstr.types) list
(* In this version: returns the list of focused goals together with
the [evar_map] context. *)
let proofview p =
- p.comb , p.solution
+ List.map drop_state p.comb , p.solution
let compact el ({ solution } as pv) =
let nf c = Evarutil.nf_evar solution c in
@@ -74,7 +76,7 @@ let dependent_init =
let (gl, _) = EConstr.destEvar sigma econstr in
let ret, { solution = sol; comb = comb } = aux (t sigma econstr) in
let entry = (econstr, typ) :: ret in
- entry, { solution = sol; comb = gl :: comb; shelf = [] }
+ entry, { solution = sol; comb = with_empty_state gl :: comb; shelf = [] }
in
fun t ->
let entry, v = aux t in
@@ -110,7 +112,7 @@ let partial_proof entry pv = CList.map (return_constr pv) (CList.map fst entry)
(* First component is a reverse list of the goals which come before
and second component is the list of the goals which go after (in
the expected order). *)
-type focus_context = Evar.t list * Evar.t list
+type focus_context = goal_with_state list * goal_with_state list
(** Returns a stylised view of a focus_context for use by, for
@@ -120,11 +122,12 @@ type focus_context = Evar.t list * Evar.t list
new nearly identical function everytime. Hence the generic name. *)
(* In this version: the goals in the context, as a "zipper" (the first
list is in reversed order). *)
-let focus_context f = f
+let focus_context (left,right) =
+ (List.map drop_state left, List.map drop_state right)
(** This (internal) function extracts a sublist between two indices,
and returns this sublist together with its context: if it returns
- [(a,(b,c))] then [a] is the sublist and (rev b)@a@c is the
+ [(a,(b,c))] then [a] is the sublist and [(rev b) @ a @ c] is the
original list. The focused list has lenght [j-i-1] and contains
the goals from number [i] to number [j] (both included) the first
goal of the list being numbered [1]. [focus_sublist i j l] raises
@@ -149,21 +152,35 @@ let unfocus_sublist (left,right) s =
proofview. It returns the focused proofview, and a context for
the focus stack. *)
let focus i j sp =
- let (new_comb, context) = focus_sublist i j sp.comb in
- ( { sp with comb = new_comb } , context )
+ let (new_comb, (left, right)) = focus_sublist i j sp.comb in
+ ( { sp with comb = new_comb } , (left, right) )
+
+let cleared_alias evd g =
+ let evk = drop_state g in
+ let state = get_state g in
+ Option.map (fun g -> goal_with_state g state) (Evarutil.advance evd evk)
(** [undefined defs l] is the list of goals in [l] which are still
unsolved (after advancing cleared goals). Note that order matters. *)
-let undefined defs l =
+let undefined_evars defs l =
List.fold_right (fun evk l ->
match Evarutil.advance defs evk with
| Some evk -> List.add_set Evar.equal evk l
| None -> l) l []
+let goal_with_state_equal x y = Evar.equal (drop_state x) (drop_state y)
+let undefined defs l =
+ List.fold_right (fun evk l ->
+ match cleared_alias defs evk with
+ | Some evk -> List.add_set goal_with_state_equal evk l
+ | None -> l) l []
(** Unfocuses a proofview with respect to a context. *)
-let unfocus c sp =
- { sp with comb = undefined sp.solution (unfocus_sublist c sp.comb) }
+let unfocus (left, right) sp =
+ { sp with comb = undefined sp.solution (unfocus_sublist (left, right) sp.comb) }
+let with_empty_state = Proofview_monad.with_empty_state
+let drop_state = Proofview_monad.drop_state
+let goal_with_state = Proofview_monad.goal_with_state
(** {6 The tactic monad} *)
@@ -406,7 +423,8 @@ let tclFOCUSID id t =
try
let ev = Evd.evar_key id initial.solution in
try
- let n = CList.index Evar.equal ev initial.comb in
+ let comb = CList.map drop_state initial.comb in
+ let n = CList.index Evar.equal ev comb in
(* goal is already under focus *)
let (focused,context) = focus n n initial in
Pv.set focused >>
@@ -415,7 +433,7 @@ let tclFOCUSID id t =
return result
with Not_found ->
(* otherwise, save current focus and work purely on the shelve *)
- Comb.set [ev] >>
+ Comb.set [with_empty_state ev] >>
t >>= fun result ->
Comb.set initial.comb >>
return result
@@ -445,7 +463,7 @@ let iter_goal i =
Comb.get >>= fun initial ->
Proof.List.fold_left begin fun (subgoals as cur) goal ->
Solution.get >>= fun step ->
- match Evarutil.advance step goal with
+ match cleared_alias step goal with
| None -> return cur
| Some goal ->
Comb.set [goal] >>
@@ -462,7 +480,7 @@ let map_goal i =
Comb.get >>= fun initial ->
Proof.List.fold_left begin fun (acc, subgoals as cur) goal ->
Solution.get >>= fun step ->
- match Evarutil.advance step goal with
+ match cleared_alias step goal with
| None -> return cur
| Some goal ->
Comb.set [goal] >>
@@ -488,7 +506,7 @@ let fold_left2_goal i s l =
in
Proof.List.fold_left2 err begin fun ((r,subgoals) as cur) goal a ->
Solution.get >>= fun step ->
- match Evarutil.advance step goal with
+ match cleared_alias step goal with
| None -> return cur
| Some goal ->
Comb.set [goal] >>
@@ -532,7 +550,7 @@ let tclDISPATCHGEN0 join tacs =
let open Proof in
Pv.get >>= function
| { comb=[goal] ; solution } ->
- begin match Evarutil.advance solution goal with
+ begin match cleared_alias solution goal with
| None -> tclUNIT (join [])
| Some _ -> Proof.map (fun res -> join [res]) tac
end
@@ -554,8 +572,8 @@ let tclDISPATCHL tacs = tclDISPATCHGEN CList.rev tacs
(** [extend_to_list startxs rx endxs l] builds a list
- [startxs@[rx,...,rx]@endxs] of the same length as [l]. Raises
- [SizeMismatch] if [startxs@endxs] is already longer than [l]. *)
+ [startxs @ [rx,...,rx] @ endxs] of the same length as [l]. Raises
+ [SizeMismatch] if [startxs @ endxs] is already longer than [l]. *)
let extend_to_list startxs rx endxs l =
(* spiwack: I use [l] essentially as a natural number *)
let rec duplicate acc = function
@@ -624,12 +642,12 @@ let shelve =
Comb.get >>= fun initial ->
Comb.set [] >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve")) >>
- Shelf.modify (fun gls -> gls @ initial)
+ Shelf.modify (fun gls -> gls @ CList.map drop_state initial)
let shelve_goals l =
let open Proof in
Comb.get >>= fun initial ->
- let comb = CList.filter (fun g -> not (CList.mem g l)) initial in
+ let comb = CList.filter (fun g -> not (CList.mem (drop_state g) l)) initial in
Comb.set comb >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_goals")) >>
Shelf.modify (fun gls -> gls @ l)
@@ -656,9 +674,27 @@ let free_evars sigma l =
in
List.map map l
+let free_evars_with_state sigma l =
+ let cache = Evarutil.create_undefined_evars_cache () in
+ let map ev =
+ (** Computes the set of evars appearing in the hypotheses, the conclusion or
+ the body of the evar_info [evi]. Note: since we want to use it on goals,
+ the body is actually supposed to be empty. *)
+ let ev = drop_state ev in
+ let evi = Evd.find sigma ev in
+ let fevs = lazy (Evarutil.filtered_undefined_evars_of_evar_info ~cache sigma evi) in
+ (ev, fevs)
+ in
+ List.map map l
+
+
(** [unifiable sigma g l] checks whether [g] appears in another
subgoal of [l]. The list [l] may contain [g], but it does not
affect the result. *)
+let unifiable_delayed_with_state sigma g l =
+ let g = drop_state g in
+ unifiable_delayed g l
+
let unifiable sigma g l =
let l = free_evars sigma l in
unifiable_delayed g l
@@ -668,8 +704,8 @@ let unifiable sigma g l =
whose definition other goals of [l] depend, and [n] are the
non-unifiable goals. *)
let partition_unifiable sigma l =
- let fevs = free_evars sigma l in
- CList.partition (fun g -> unifiable_delayed g fevs) l
+ let fevs = free_evars_with_state sigma l in
+ CList.partition (fun g -> unifiable_delayed_with_state sigma g fevs) l
(** Shelves the unifiable goals under focus, i.e. the goals which
appear in other goals under focus (the unfocused goals are not
@@ -680,7 +716,7 @@ let shelve_unifiable =
let (u,n) = partition_unifiable initial.solution initial.comb in
Comb.set n >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_unifiable")) >>
- Shelf.modify (fun gls -> gls @ u)
+ Shelf.modify (fun gls -> gls @ CList.map drop_state u)
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *)
@@ -691,13 +727,14 @@ let guard_no_unifiable =
match u with
| [] -> tclUNIT None
| gls ->
- let l = CList.map (fun g -> Evd.dependent_evar_ident g initial.solution) gls in
+ let l = CList.map (fun g -> Evd.dependent_evar_ident (drop_state g) initial.solution) gls in
let l = CList.map (fun id -> Names.Name id) l in
tclUNIT (Some l)
(** [unshelve l p] adds all the goals in [l] at the end of the focused
goals of p *)
let unshelve l p =
+ let l = List.map with_empty_state l in
(* advance the goals in case of clear *)
let l = undefined p.solution l in
{ p with comb = p.comb@l }
@@ -736,7 +773,7 @@ let with_shelf tac =
let pgoal = Evd.principal_future_goal solution in
let sigma = Evd.restore_future_goals sigma fgoals pgoal in
(* Ensure we mark and return only unsolved goals *)
- let gls' = undefined sigma (CList.rev_append gls' gls) in
+ let gls' = undefined_evars sigma (CList.rev_append gls' gls) in
let sigma = CList.fold_left (mark_in_evm ~goal:false) sigma gls' in
let npv = { npv with shelf; solution = sigma } in
Pv.set npv >> tclUNIT (gls', ans)
@@ -818,7 +855,7 @@ let give_up =
Comb.set [] >>
mark_as_unsafe >>
InfoL.leaf (Info.Tactic (fun () -> Pp.str"give_up")) >>
- Giveup.put initial
+ Giveup.put (CList.map drop_state initial)
@@ -859,8 +896,8 @@ module Progress = struct
(** Equality function on goals *)
let goal_equal evars1 gl1 evars2 gl2 =
- let evi1 = Evd.find evars1 gl1 in
- let evi2 = Evd.find evars2 gl2 in
+ let evi1 = Evd.find evars1 (drop_state gl1) in
+ let evi2 = Evd.find evars2 (drop_state gl2) in
eq_evar_info evars1 evars2 evi1 evi2
end
@@ -1023,14 +1060,19 @@ let catchable_exception = function
module Goal = struct
- type 'a t = {
+ type t = {
env : Environ.env;
sigma : Evd.evar_map;
concl : EConstr.constr ;
+ state : StateStore.t;
self : Evar.t ; (* for compatibility with old-style definitions *)
}
- let assume (gl : 'a t) = (gl :> [ `NF ] t)
+ let assume (gl : t) = (gl : t)
+
+ let print { sigma; self } = { Evd.it = self; sigma }
+
+ let state { state=state } = state
let env {env} = env
let sigma {sigma} = sigma
@@ -1038,16 +1080,19 @@ module Goal = struct
let concl {concl} = concl
let extra {sigma; self} = goal_extra sigma self
- let gmake_with info env sigma goal =
+ let gmake_with info env sigma goal state =
{ env = Environ.reset_with_named_context (Evd.evar_filtered_hyps info) env ;
sigma = sigma ;
concl = EConstr.of_constr (Evd.evar_concl info);
+ state = state ;
self = goal }
let nf_gmake env sigma goal =
+ let state = get_state goal in
+ let goal = drop_state goal in
let info = Evarutil.nf_evar_info sigma (Evd.find sigma goal) in
let sigma = Evd.add sigma goal info in
- gmake_with info env sigma goal , sigma
+ gmake_with info env sigma goal state , sigma
let nf_enter f =
InfoL.tag (Info.Dispatch) begin
@@ -1063,15 +1108,17 @@ module Goal = struct
end
end
- let normalize { self } =
+ let normalize { self; state } =
Env.get >>= fun env ->
tclEVARMAP >>= fun sigma ->
- let (gl,sigma) = nf_gmake env sigma self in
+ let (gl,sigma) = nf_gmake env sigma (goal_with_state self state) in
tclTHEN (Unsafe.tclEVARS sigma) (tclUNIT gl)
let gmake env sigma goal =
+ let state = get_state goal in
+ let goal = drop_state goal in
let info = Evd.find sigma goal in
- gmake_with info env sigma goal
+ gmake_with info env sigma goal state
let enter f =
let f gl = InfoL.tag (Info.DBranch) (f gl) in
@@ -1086,7 +1133,7 @@ module Goal = struct
end
end
- let enter_one f =
+ let enter_one ?(__LOC__=__LOC__) f =
let open Proof in
Comb.get >>= function
| [goal] -> begin
@@ -1097,13 +1144,14 @@ module Goal = struct
let (e, info) = CErrors.push e in
tclZERO ~info e
end
- | _ -> assert false (* unsatisfied not-exactly-one-goal precondition *)
+ | _ ->
+ CErrors.anomaly Pp.(str __LOC__ ++ str " enter_one")
let goals =
Pv.get >>= fun step ->
let sigma = step.solution in
let map goal =
- match Evarutil.advance sigma goal with
+ match cleared_alias sigma goal with
| None -> None (** ppedrot: Is this check really necessary? *)
| Some goal ->
let gl =
@@ -1156,25 +1204,29 @@ let tclCHECKINTERRUPT =
module V82 = struct
type tac = Evar.t Evd.sigma -> Evar.t list Evd.sigma
- let tactic tac =
+ let tactic ?(nf_evars=true) tac =
(* spiwack: we ignore the dependencies between goals here,
expectingly preserving the semantics of <= 8.2 tactics *)
(* spiwack: convenience notations, waiting for ocaml 3.12 *)
let open Proof in
Pv.get >>= fun ps ->
try
- let tac gl evd =
+ let tac g_w_s evd =
+ let g, w = drop_state g_w_s, get_state g_w_s in
let glsigma =
- tac { Evd.it = gl ; sigma = evd; } in
+ tac { Evd.it = g ; sigma = evd; } in
let sigma = glsigma.Evd.sigma in
- let g = glsigma.Evd.it in
+ let g = CList.map (fun g -> goal_with_state g w) glsigma.Evd.it in
( g, sigma )
in
(* Old style tactics expect the goals normalized with respect to evars. *)
- let (initgoals,initevd) =
- Evd.Monad.List.map (fun g s -> goal_nf_evar s g) ps.comb ps.solution
+ let (initgoals_w_state, initevd) =
+ Evd.Monad.List.map (fun g_w_s s ->
+ let g, w = drop_state g_w_s, get_state g_w_s in
+ let g, s = if nf_evars then goal_nf_evar s g else g, s in
+ goal_with_state g w, s) ps.comb ps.solution
in
- let (goalss,evd) = Evd.Monad.List.map tac initgoals initevd in
+ let (goalss,evd) = Evd.Monad.List.map tac initgoals_w_state initevd in
let sgs = CList.flatten goalss in
let sgs = undefined evd sgs in
InfoL.leaf (Info.Tactic (fun () -> Pp.str"<unknown>")) >>
@@ -1189,8 +1241,9 @@ module V82 = struct
let nf_evar_goals =
Pv.modify begin fun ps ->
let map g s = goal_nf_evar s g in
- let (goals,evd) = Evd.Monad.List.map map ps.comb ps.solution in
- { ps with solution = evd; comb = goals; }
+ let comb = CList.map drop_state ps.comb in
+ let (_goals,evd) = Evd.Monad.List.map map comb ps.solution in
+ { ps with solution = evd; }
end
let has_unresolved_evar pv =
@@ -1200,14 +1253,14 @@ module V82 = struct
let grab pv =
let undef = Evd.undefined_map pv.solution in
let goals = CList.rev_map fst (Evar.Map.bindings undef) in
- { pv with comb = goals }
+ { pv with comb = List.map with_empty_state goals }
(* Returns the open goals of the proofview together with the evar_map to
interpret them. *)
let goals { comb = comb ; solution = solution; } =
- { Evd.it = comb ; sigma = solution }
+ { Evd.it = List.map drop_state comb ; sigma = solution }
let top_goals initial { solution=solution; } =
let goals = CList.map (fun (t,_) -> fst (Constr.destEvar (EConstr.Unsafe.to_constr t))) initial in
@@ -1221,9 +1274,9 @@ module V82 = struct
let of_tactic t gls =
try
- let init = { shelf = []; solution = gls.Evd.sigma ; comb = [gls.Evd.it] } in
+ let init = { shelf = []; solution = gls.Evd.sigma ; comb = [with_empty_state gls.Evd.it] } in
let (_,final,_,_) = apply (goal_env gls.Evd.sigma gls.Evd.it) t init in
- { Evd.sigma = final.solution ; it = final.comb }
+ { Evd.sigma = final.solution ; it = CList.map drop_state final.comb }
with Logic_monad.TacticFailure e as src ->
let (_, info) = CErrors.push src in
iraise (e, info)
diff --git a/engine/proofview.mli b/engine/proofview.mli
index 59728a2fd1..4862791874 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This files defines the basic mechanism of proofs: the [proofview]
@@ -72,7 +74,15 @@ val return : proofview -> Evd.evar_map
val partial_proof : entry -> proofview -> constr list
val initial_goals : entry -> (constr * types) list
+(** goal <-> goal_with_state *)
+val with_empty_state :
+ Proofview_monad.goal -> Proofview_monad.goal_with_state
+val drop_state :
+ Proofview_monad.goal_with_state -> Proofview_monad.goal
+val goal_with_state :
+ Proofview_monad.goal -> Proofview_monad.StateStore.t ->
+ Proofview_monad.goal_with_state
(** {6 Focusing commands} *)
@@ -416,14 +426,14 @@ module Unsafe : sig
(** [tclNEWGOALS gls] adds the goals [gls] to the ones currently
being proved, appending them to the list of focused goals. If a
goal is already solved, it is not added. *)
- val tclNEWGOALS : Evar.t list -> unit tactic
+ val tclNEWGOALS : Proofview_monad.goal_with_state list -> unit tactic
(** [tclSETGOALS gls] sets goals [gls] as the goals being under focus. If a
goal is already solved, it is not set. *)
- val tclSETGOALS : Evar.t list -> unit tactic
+ val tclSETGOALS : Proofview_monad.goal_with_state list -> unit tactic
(** [tclGETGOALS] returns the list of goals under focus. *)
- val tclGETGOALS : Evar.t list tactic
+ val tclGETGOALS : Proofview_monad.goal_with_state list tactic
(** Sets the evar universe context. *)
val tclEVARUNIVCONTEXT : UState.t -> unit tactic
@@ -461,56 +471,51 @@ end
module Goal : sig
- (** Type of goals.
-
- The first parameter type is a phantom argument indicating whether the data
- contained in the goal has been normalized w.r.t. the current sigma. If it
- is the case, it is flagged [ `NF ]. You may still access the un-normalized
- data using {!assume} if you known you do not rely on the assumption of
- being normalized, at your own risk.
-
- *)
- type 'a t
+ (** Type of goals. *)
+ type t
(** Assume that you do not need the goal to be normalized. *)
- val assume : 'a t -> [ `NF ] t
+ val assume : t -> t
+ [@@ocaml.deprecated "Normalization is enforced by EConstr, [assume] is not needed anymore"]
(** Normalises the argument goal. *)
- val normalize : 'a t -> [ `NF ] t tactic
+ val normalize : t -> t tactic
(** [concl], [hyps], [env] and [sigma] given a goal [gl] return
respectively the conclusion of [gl], the hypotheses of [gl], the
environment of [gl] (i.e. the global environment and the
hypotheses) and the current evar map. *)
- val concl : 'a t -> constr
- val hyps : 'a t -> named_context
- val env : 'a t -> Environ.env
- val sigma : 'a t -> Evd.evar_map
- val extra : 'a t -> Evd.Store.t
+ val concl : t -> constr
+ val hyps : t -> named_context
+ val env : t -> Environ.env
+ val sigma : t -> Evd.evar_map
+ val extra : t -> Evd.Store.t
+ val state : t -> Proofview_monad.StateStore.t
(** [nf_enter t] applies the goal-dependent tactic [t] in each goal
independently, in the manner of {!tclINDEPENDENT} except that
the current goal is also given as an argument to [t]. The goal
is normalised with respect to evars. *)
- val nf_enter : ([ `NF ] t -> unit tactic) -> unit tactic
+ val nf_enter : (t -> unit tactic) -> unit tactic
(** Like {!nf_enter}, but does not normalize the goal beforehand. *)
- val enter : ([ `LZ ] t -> unit tactic) -> unit tactic
+ val enter : (t -> unit tactic) -> unit tactic
(** Like {!enter}, but assumes exactly one goal under focus, raising *)
(** a fatal error otherwise. *)
- val enter_one : ([ `LZ ] t -> 'a tactic) -> 'a tactic
+ val enter_one : ?__LOC__:string -> (t -> 'a tactic) -> 'a tactic
(** Recover the list of current goals under focus, without evar-normalization.
FIXME: encapsulate the level in an existential type. *)
- val goals : [ `LZ ] t tactic list tactic
+ val goals : t tactic list tactic
(** [unsolved g] is [true] if [g] is still unsolved in the current
proof state. *)
- val unsolved : 'a t -> bool tactic
+ val unsolved : t -> bool tactic
(** Compatibility: avoid if possible *)
- val goal : [ `NF ] t -> Evar.t
+ val goal : t -> Evar.t
+ val print : t -> Goal.goal Evd.sigma
end
@@ -547,7 +552,10 @@ val tclLIFT : 'a NonLogical.t -> 'a tactic
(*** Compatibility layer with <= 8.2 tactics ***)
module V82 : sig
type tac = Evar.t Evd.sigma -> Evar.t list Evd.sigma
- val tactic : tac -> unit tactic
+
+ (* [nf_evars=true] applies the evar (assignment) map to the goals
+ * (conclusion and context) before calling the tactic *)
+ val tactic : ?nf_evars:bool -> tac -> unit tactic
(* normalises the evars in the goals, and stores the result in
solution. *)
diff --git a/engine/proofview_monad.ml b/engine/proofview_monad.ml
index d0f4712258..52bcabf958 100644
--- a/engine/proofview_monad.ml
+++ b/engine/proofview_monad.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file defines the datatypes used as internal states by the
@@ -149,13 +151,25 @@ module Info = struct
CList.map_append (collapse_tree n) f
end
+module StateStore = Store.Make(struct end)
+
+(* let (set_state, get_state) = StateDyn.Easy.make_dyn "goal_state" *)
+
+type goal = Evar.t
+type goal_with_state = Evar.t * StateStore.t
+
+let drop_state = fst
+let get_state = snd
+let goal_with_state g s = (g, s)
+let with_empty_state g = (g, StateStore.empty)
+let map_goal_with_state f (g, s) = (f g, s)
(** Type of proof views: current [evar_map] together with the list of
focused goals. *)
type proofview = {
solution : Evd.evar_map;
- comb : Evar.t list;
- shelf : Evar.t list;
+ comb : goal_with_state list;
+ shelf : goal list;
}
(** {6 Instantiation of the logic monad} *)
@@ -169,7 +183,7 @@ module P = struct
type e = bool
(** Status (safe/unsafe) * shelved goals * given up *)
- type w = bool * Evar.t list
+ type w = bool * goal list
let wunit = true , []
let wprod (b1, g1) (b2, g2) = b1 && b2 , g1@g2
@@ -209,9 +223,9 @@ module Solution : State with type t := Evd.evar_map = struct
let modify f = Pv.modify (fun pv -> { pv with solution = f pv.solution })
end
-module Comb : State with type t = Evar.t list = struct
+module Comb : State with type t = goal_with_state list = struct
(* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *)
- type t = Evar.t list
+ type t = goal_with_state list
let get = Logical.map (fun {comb} -> comb) Pv.get
let set c = Pv.modify (fun pv -> { pv with comb = c })
let modify f = Pv.modify (fun pv -> { pv with comb = f pv.comb })
@@ -227,17 +241,17 @@ module Status : Writer with type t := bool = struct
let put s = Logical.put (s, [])
end
-module Shelf : State with type t = Evar.t list = struct
+module Shelf : State with type t = goal list = struct
(* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *)
- type t = Evar.t list
+ type t = goal list
let get = Logical.map (fun {shelf} -> shelf) Pv.get
let set c = Pv.modify (fun pv -> { pv with shelf = c })
let modify f = Pv.modify (fun pv -> { pv with shelf = f pv.shelf })
end
-module Giveup : Writer with type t = Evar.t list = struct
+module Giveup : Writer with type t = goal list = struct
(* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *)
- type t = Evar.t list
+ type t = goal list
let put gs = Logical.put (true, gs)
end
diff --git a/engine/proofview_monad.mli b/engine/proofview_monad.mli
index e7123218b1..9d75242175 100644
--- a/engine/proofview_monad.mli
+++ b/engine/proofview_monad.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file defines the datatypes used as internal states by the
@@ -67,12 +69,21 @@ module Info : sig
end
+module StateStore : Store.S
+type goal = Evar.t
+type goal_with_state
+val drop_state : goal_with_state -> goal
+val get_state : goal_with_state -> StateStore.t
+val goal_with_state : goal -> StateStore.t -> goal_with_state
+val with_empty_state : goal -> goal_with_state
+val map_goal_with_state : (goal -> goal) -> goal_with_state -> goal_with_state
+
(** Type of proof views: current [evar_map] together with the list of
focused goals. *)
type proofview = {
solution : Evd.evar_map;
- comb : Evar.t list;
- shelf : Evar.t list;
+ comb : goal_with_state list;
+ shelf : goal list;
}
(** {6 Instantiation of the logic monad} *)
@@ -81,7 +92,7 @@ module P : sig
type s = proofview * Environ.env
(** Status (safe/unsafe) * given up *)
- type w = bool * Evar.t list
+ type w = bool * goal list
val wunit : w
val wprod : w -> w -> w
@@ -118,7 +129,7 @@ module Pv : State with type t := proofview
module Solution : State with type t := Evd.evar_map
(** Lens to the list of focused goals. *)
-module Comb : State with type t = Evar.t list
+module Comb : State with type t = goal_with_state list
(** Lens to the global environment. *)
module Env : State with type t := Environ.env
@@ -128,11 +139,11 @@ module Status : Writer with type t := bool
(** Lens to the list of goals which have been shelved during the
execution of the tactic. *)
-module Shelf : State with type t = Evar.t list
+module Shelf : State with type t = goal list
(** Lens to the list of goals which were given up during the execution
of the tactic. *)
-module Giveup : Writer with type t = Evar.t list
+module Giveup : Writer with type t = goal list
(** Lens and utilies pertaining to the info trace *)
module InfoL : sig
diff --git a/engine/termops.ml b/engine/termops.ml
index a71bdff31e..35258762a7 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Pp
@@ -292,12 +294,11 @@ let reference_of_level evd l = UState.reference_of_level (Evd.evar_universe_cont
let pr_evar_universe_context ctx =
let open UState in
- let open Evd in
let prl = pr_uctx_level ctx in
if UState.is_empty ctx then mt ()
else
(str"UNIVERSES:"++brk(0,1)++
- h 0 (Univ.pr_universe_context_set prl (evar_universe_context_set ctx)) ++ fnl () ++
+ h 0 (Univ.pr_universe_context_set prl (UState.context_set ctx)) ++ fnl () ++
str"ALGEBRAIC UNIVERSES:"++brk(0,1)++
h 0 (Univ.LSet.pr prl (UState.algebraics ctx)) ++ fnl() ++
str"UNDEFINED UNIVERSES:"++brk(0,1)++
@@ -797,9 +798,9 @@ let fold_constr_with_binders sigma g f n acc c =
each binder traversal; it is not recursive and the order with which
subterms are processed is not specified *)
-let iter_constr_with_full_binders g f l c =
+let iter_constr_with_full_binders sigma g f l c =
let open RelDecl in
- match kind c with
+ match EConstr.kind sigma c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> ()
| Cast (c,_, t) -> f l c; f l t
@@ -1463,6 +1464,18 @@ let prod_applist sigma c l =
| _ -> anomaly (Pp.str "Not enough prod's.") in
app [] c l
+let prod_applist_assum sigma n c l =
+ let open EConstr in
+ let rec app n subst c l =
+ if Int.equal n 0 then
+ if l == [] then Vars.substl subst c
+ else anomaly (Pp.str "Not enough arguments.")
+ else match EConstr.kind sigma c, l with
+ | Prod(_,_,c), arg::l -> app (n-1) (arg::subst) c l
+ | LetIn(_,b,_,c), _ -> app (n-1) (Vars.substl subst b::subst) c l
+ | _ -> anomaly (Pp.str "Not enough prod/let's.") in
+ app n [] c l
+
(* Combinators on judgments *)
let on_judgment f j = { uj_val = f j.uj_val; uj_type = f j.uj_type }
diff --git a/engine/termops.mli b/engine/termops.mli
index c1600abe80..ef3cb91be6 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file defines various utilities for term manipulation that are not
@@ -76,9 +78,10 @@ val fold_constr_with_full_binders : Evd.evar_map ->
(Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> 'b -> constr -> 'b) ->
'a -> 'b -> constr -> 'b
-val iter_constr_with_full_binders :
- (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> Constr.constr -> unit) -> 'a ->
- Constr.constr -> unit
+val iter_constr_with_full_binders : Evd.evar_map ->
+ (rel_declaration -> 'a -> 'a) ->
+ ('a -> constr -> unit) -> 'a ->
+ constr -> unit
(**********************************************************************)
@@ -159,8 +162,18 @@ val eta_reduce_head : Evd.evar_map -> constr -> constr
(** Flattens application lists *)
val collapse_appl : Evd.evar_map -> constr -> constr
+(** [prod_applist] [forall (x1:B1;...;xn:Bn), B] [a1...an] @return [B[a1...an]] *)
val prod_applist : Evd.evar_map -> constr -> constr list -> constr
+(** In [prod_applist_assum n c args], [c] is supposed to have the
+ form [∀Γ.c] with [Γ] of length [m] and possibly with let-ins; it
+ returns [c] with the assumptions of [Γ] instantiated by [args] and
+ the local definitions of [Γ] expanded.
+ Note that [n] counts both let-ins and prods, while the length of [args]
+ only counts prods. In other words, varying [n] changes how many
+ trailing let-ins are expanded. *)
+val prod_applist_assum : Evd.evar_map -> int -> constr -> constr list -> constr
+
(** Remove recursively the casts around a term i.e.
[strip_outer_cast (Cast (Cast ... (Cast c, t) ... ))] is [c]. *)
val strip_outer_cast : Evd.evar_map -> constr -> constr
diff --git a/engine/uState.ml b/engine/uState.ml
index 6131f4c033..e57afd743a 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Pp
@@ -201,14 +203,18 @@ let process_universe_constraints ctx cstrs =
| None -> user_err Pp.(str "Algebraic universe on the right")
| Some r' ->
if Univ.Level.is_small r' then
- let levels = Univ.Universe.levels l in
- let fold l' local =
- let l = Univ.Universe.make l' in
- if Univ.Level.is_small l' || is_local l' then
- equalize_variables false l l' r r' local
- else raise (Univ.UniverseInconsistency (Univ.Le, l, r, None))
- in
- Univ.LSet.fold fold levels local
+ if not (Univ.Universe.is_levels l)
+ then
+ raise (Univ.UniverseInconsistency (Univ.Le, l, r, None))
+ else
+ let levels = Univ.Universe.levels l in
+ let fold l' local =
+ let l = Univ.Universe.make l' in
+ if Univ.Level.is_small l' || is_local l' then
+ equalize_variables false l l' r r' local
+ else raise (Univ.UniverseInconsistency (Univ.Le, l, r, None))
+ in
+ Univ.LSet.fold fold levels local
else
Univ.enforce_leq l r local
end
@@ -278,7 +284,7 @@ let pr_uctx_level uctx l =
Libnames.pr_reference (reference_of_level uctx l)
type universe_decl =
- (Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
+ (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
let error_unbound_universes left uctx =
let open Univ in
@@ -301,7 +307,7 @@ let universe_context ~names ~extensible uctx =
let levels = ContextSet.levels uctx.uctx_local in
let newinst, left =
List.fold_right
- (fun (loc,id) (newinst, acc) ->
+ (fun { CAst.loc; v = id } (newinst, acc) ->
let l =
try UNameMap.find id (fst uctx.uctx_names)
with Not_found -> assert false
@@ -321,7 +327,7 @@ let check_universe_context_set ~names ~extensible uctx =
if extensible then ()
else
let open Univ in
- let left = List.fold_left (fun left (loc,id) ->
+ let left = List.fold_left (fun left { CAst.loc; v = id } ->
let l =
try UNameMap.find id (fst uctx.uctx_names)
with Not_found -> assert false
@@ -470,6 +476,13 @@ let new_univ_variable ?loc rigid name
uctx_initial_universes = initial}
in uctx', u
+let make_with_initial_binders e us =
+ let uctx = make e in
+ List.fold_left
+ (fun uctx { CAst.loc; v = id } ->
+ fst (new_univ_variable ?loc univ_rigid (Some id) uctx))
+ uctx us
+
let add_global_univ uctx u =
let initial =
UGraph.add_universe u true uctx.uctx_initial_universes
@@ -516,7 +529,7 @@ let is_sort_variable uctx s =
| _ -> None
let subst_univs_context_with_def def usubst (ctx, cst) =
- (Univ.LSet.diff ctx def, Univ.subst_univs_constraints usubst cst)
+ (Univ.LSet.diff ctx def, Universes.subst_univs_constraints usubst cst)
let normalize_variables uctx =
let normalized_variables, undef, def, subst =
@@ -572,7 +585,7 @@ let refresh_undefined_univ_variables uctx =
uctx_initial_universes = initial } in
uctx', subst
-let normalize uctx =
+let minimize uctx =
let ((vars',algs'), us') =
Universes.normalize_context_set uctx.uctx_local uctx.uctx_univ_variables
uctx.uctx_univ_algebraic
@@ -600,3 +613,6 @@ let update_sigma_env uctx env =
uctx_universes = univs }
in
merge true univ_rigid eunivs eunivs.uctx_local
+
+(** Deprecated *)
+let normalize = minimize
diff --git a/engine/uState.mli b/engine/uState.mli
index 6657d6047d..9a2bc706be 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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) *)
(************************************************************************)
(** This file defines universe unification states which are part of evarmaps.
@@ -24,6 +26,8 @@ val empty : t
val make : UGraph.t -> t
+val make_with_initial_binders : UGraph.t -> Misctypes.lident list -> t
+
val is_empty : t -> bool
val union : t -> t -> t
@@ -129,10 +133,13 @@ val fix_undefined_variables : t -> t
val refresh_undefined_univ_variables : t -> t * Univ.universe_level_subst
+(** Universe minimization *)
+val minimize : t -> t
val normalize : t -> t
+[@@ocaml.deprecated "Alias of UState.minimize"]
type universe_decl =
- (Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
+ (Misctypes.lident list, Univ.Constraint.t) Misctypes.gen_universe_decl
(** [check_univ_decl ctx decl]
diff --git a/engine/universes.ml b/engine/universes.ml
index 30490ec56a..c744674053 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Sorts
@@ -92,14 +94,14 @@ let register_universe_binders ref ubinders =
if not (Id.Map.is_empty ubinders)
then Lib.add_anonymous_leaf (ubinder_obj (ref,ubinders))
-type univ_name_list = Name.t Loc.located list
+type univ_name_list = Misctypes.lname list
let universe_binders_with_opt_names ref levels = function
| None -> universe_binders_of_global ref
| Some udecl ->
if Int.equal(List.length levels) (List.length udecl)
then
- List.fold_left2 (fun acc (_,na) lvl -> match na with
+ List.fold_left2 (fun acc { CAst.v = na} lvl -> match na with
| Anonymous -> acc
| Name na -> Names.Id.Map.add na lvl acc)
empty_binders udecl levels
@@ -181,6 +183,30 @@ let enforce_eq_instances_univs strict x y c =
(fun x y -> Constraints.add (Universe.make x, d, Universe.make y))
ax ay c
+let enforce_univ_constraint (u,d,v) =
+ match d with
+ | Eq -> enforce_eq u v
+ | Le -> enforce_leq u v
+ | Lt -> enforce_leq (super u) v
+
+let subst_univs_level fn l =
+ try Some (fn l)
+ with Not_found -> None
+
+let subst_univs_constraint fn (u,d,v as c) cstrs =
+ let u' = subst_univs_level fn u in
+ let v' = subst_univs_level fn v in
+ match u', v' with
+ | None, None -> Constraint.add c cstrs
+ | Some u, None -> enforce_univ_constraint (u,d,Universe.make v) cstrs
+ | None, Some v -> enforce_univ_constraint (Universe.make u,d,v) cstrs
+ | Some u, Some v -> enforce_univ_constraint (u,d,v) cstrs
+
+let subst_univs_constraints subst csts =
+ Constraint.fold
+ (fun c cstrs -> subst_univs_constraint subst c cstrs)
+ csts Constraint.empty
+
let subst_univs_universe_constraint fn (u,d,v) =
let u' = subst_univs_universe fn u and v' = subst_univs_universe fn v in
if Universe.equal u' v' then None
@@ -519,13 +545,60 @@ let choose_canonical ctx flexible algs s =
let canon = LSet.choose algs in
canon, (global, rigid, LSet.remove canon flexible)
+let level_subst_of f =
+ fun l ->
+ try let u = f l in
+ match Universe.level u with
+ | None -> l
+ | Some l -> l
+ with Not_found -> l
+
+let subst_univs_fn_constr f c =
+ let changed = ref false in
+ let fu = Univ.subst_univs_universe f in
+ let fi = Univ.Instance.subst_fn (level_subst_of f) in
+ let rec aux t =
+ match kind t with
+ | Sort (Sorts.Type u) ->
+ let u' = fu u in
+ if u' == u then t else
+ (changed := true; mkSort (Sorts.sort_of_univ u'))
+ | Const (c, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkConstU (c, u'))
+ | Ind (i, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkIndU (i, u'))
+ | Construct (c, u) ->
+ let u' = fi u in
+ if u' == u then t
+ else (changed := true; mkConstructU (c, u'))
+ | _ -> map aux t
+ in
+ let c' = aux c in
+ if !changed then c' else c
+
+let subst_univs_constr subst c =
+ if Univ.is_empty_subst subst then c
+ else
+ let f = Univ.make_subst subst in
+ subst_univs_fn_constr f c
+
+let subst_univs_constr =
+ if Flags.profile then
+ let subst_univs_constr_key = CProfile.declare_profile "subst_univs_constr" in
+ CProfile.profile2 subst_univs_constr_key subst_univs_constr
+ else subst_univs_constr
+
let subst_univs_fn_puniverses lsubst (c, u as cu) =
let u' = Instance.subst_fn lsubst u in
if u' == u then cu else (c, u')
let nf_evars_and_universes_opt_subst f subst =
let subst = fun l -> match LMap.find l subst with None -> raise Not_found | Some l' -> l' in
- let lsubst = Univ.level_subst_of subst in
+ let lsubst = level_subst_of subst in
let rec aux c =
match kind c with
| Evar (evk, args) ->
@@ -605,7 +678,7 @@ let normalize_opt_subst ctx =
in !ectx
type universe_opt_subst = Universe.t option universe_map
-
+
let make_opt_subst s =
fun x ->
(match Univ.LMap.find x s with
@@ -614,8 +687,7 @@ let make_opt_subst s =
let subst_opt_univs_constr s =
let f = make_opt_subst s in
- Vars.subst_univs_fn_constr f
-
+ subst_univs_fn_constr f
let normalize_univ_variables ctx =
let ctx = normalize_opt_subst ctx in
@@ -1033,14 +1105,3 @@ let solve_constraints_system levels level_bounds level_min =
done;
done;
v
-
-
-(** Operations for universe_info_ind *)
-
-(** Given a universe context representing constraints of an inductive
- this function produces a UInfoInd.t that with the trivial subtyping relation. *)
-let univ_inf_ind_from_universe_context univcst =
- let freshunivs = Instance.of_array
- (Array.map (fun _ -> new_univ_level ())
- (Instance.to_array (UContext.instance univcst)))
- in CumulativityInfo.from_universe_context univcst freshunivs
diff --git a/engine/universes.mli b/engine/universes.mli
index 1a98d969b4..8e6b8f60c9 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Util
@@ -35,7 +37,7 @@ val empty_binders : universe_binders
val register_universe_binders : Globnames.global_reference -> universe_binders -> unit
val universe_binders_of_global : Globnames.global_reference -> universe_binders
-type univ_name_list = Name.t Loc.located list
+type univ_name_list = Misctypes.lname list
(** [universe_binders_with_opt_names ref u l]
@@ -154,6 +156,11 @@ val extend_context : 'a in_universe_context_set -> ContextSet.t ->
module UF : Unionfind.PartitionSig with type elt = Level.t
+val level_subst_of : universe_subst_fn -> universe_level_subst_fn
+val subst_univs_constraints : universe_subst_fn -> Constraint.t -> Constraint.t
+
+val subst_univs_constr : universe_subst -> constr -> constr
+
type universe_opt_subst = Universe.t option universe_map
val make_opt_subst : universe_opt_subst -> universe_subst_fn
@@ -216,9 +223,3 @@ val pr_universe_opt_subst : universe_opt_subst -> Pp.t
val solve_constraints_system : Universe.t option array -> Universe.t array -> Universe.t array ->
Universe.t array
-
-(** Operations for universe_info_ind *)
-
-(** Given a universe context representing constraints of an inductive
- this function produces a UInfoInd.t that with the trivial subtyping relation. *)
-val univ_inf_ind_from_universe_context : UContext.t -> CumulativityInfo.t
diff --git a/engine/univops.ml b/engine/univops.ml
index df25d87252..76dbaa250a 100644
--- a/engine/univops.ml
+++ b/engine/univops.ml
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Univ
diff --git a/engine/univops.mli b/engine/univops.mli
index 30fcc43681..d1585414c1 100644
--- a/engine/univops.mli
+++ b/engine/univops.mli
@@ -1,9 +1,11 @@
(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <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 *)
+(* // * 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 Constr