aboutsummaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/eConstr.ml71
-rw-r--r--engine/eConstr.mli27
-rw-r--r--engine/engine.mllib7
-rw-r--r--engine/evarutil.ml96
-rw-r--r--engine/evarutil.mli43
-rw-r--r--engine/evd.ml73
-rw-r--r--engine/evd.mli185
-rw-r--r--engine/geninterp.ml98
-rw-r--r--engine/geninterp.mli68
-rw-r--r--engine/logic_monad.ml2
-rw-r--r--engine/namegen.ml67
-rw-r--r--engine/namegen.mli29
-rw-r--r--engine/nameops.ml216
-rw-r--r--engine/nameops.mli138
-rw-r--r--engine/proofview.ml40
-rw-r--r--engine/proofview.mli29
-rw-r--r--engine/termops.ml111
-rw-r--r--engine/termops.mli21
-rw-r--r--engine/uState.ml260
-rw-r--r--engine/uState.mli65
-rw-r--r--engine/universes.ml219
-rw-r--r--engine/universes.mli137
-rw-r--r--engine/univops.ml111
-rw-r--r--engine/univops.mli16
24 files changed, 1397 insertions, 732 deletions
diff --git a/engine/eConstr.ml b/engine/eConstr.ml
index 7b879a8031..a65b3941ef 100644
--- a/engine/eConstr.ml
+++ b/engine/eConstr.ml
@@ -9,7 +9,7 @@
open CErrors
open Util
open Names
-open Term
+open Constr
open Context
open Evd
@@ -34,7 +34,7 @@ end
type t
val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
val kind_upto : Evd.evar_map -> constr -> (constr, types, Sorts.t, Univ.Instance.t) Constr.kind_of_term
-val kind_of_type : Evd.evar_map -> t -> (t, t) kind_of_type
+val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type
val whd_evar : Evd.evar_map -> t -> t
val of_kind : (t, t, ESorts.t, EInstance.t) Constr.kind_of_term -> t
val of_constr : Constr.t -> t
@@ -54,7 +54,7 @@ struct
type t = Sorts.t
let make s = s
let kind sigma = function
- | Type u -> sort_of_univ (Evd.normalize_universe sigma u)
+ | Sorts.Type u -> Sorts.sort_of_univ (Evd.normalize_universe sigma u)
| s -> s
let unsafe_to_sorts s = s
end
@@ -114,7 +114,7 @@ let rec to_constr sigma c = match Constr.kind c with
| Some c -> to_constr sigma c
| None -> Constr.map (fun c -> to_constr sigma c) c
end
-| Sort (Type u) ->
+| Sort (Sorts.Type u) ->
let u' = Evd.normalize_universe sigma u in
if u' == u then c else mkSort (Sorts.sort_of_univ u')
| Const (c', u) when not (Univ.Instance.is_empty u) ->
@@ -150,6 +150,8 @@ type rel_declaration = (constr, types) Context.Rel.Declaration.pt
type named_context = (constr, types) Context.Named.pt
type rel_context = (constr, types) Context.Rel.pt
+type 'a puniverses = 'a * EInstance.t
+
let in_punivs a = (a, EInstance.empty)
let mkProp = of_kind (Sort (ESorts.make Sorts.prop))
@@ -566,7 +568,6 @@ let compare_constr sigma cmp c1 c2 =
let cmp c1 c2 = cmp (of_constr c1) (of_constr c2) in
compare_gen kind (fun _ -> Univ.Instance.equal) Sorts.equal cmp (unsafe_to_constr c1) (unsafe_to_constr c2)
-(** TODO: factorize with universes.ml *)
let test_constr_universes sigma leq m n =
let open Universes in
let kind c = kind_upto sigma c in
@@ -574,14 +575,20 @@ let test_constr_universes sigma leq m n =
else
let cstrs = ref Constraints.empty in
let eq_universes strict l l' =
+ let l = EInstance.kind sigma (EInstance.make l) in
+ let l' = EInstance.kind sigma (EInstance.make l') in
cstrs := enforce_eq_instances_univs strict l l' !cstrs; true in
let eq_sorts s1 s2 =
+ let s1 = ESorts.kind sigma (ESorts.make s1) in
+ let s2 = ESorts.kind sigma (ESorts.make s2) in
if Sorts.equal s1 s2 then true
else (cstrs := Constraints.add
(Sorts.univ_of_sort s1,UEq,Sorts.univ_of_sort s2) !cstrs;
true)
in
let leq_sorts s1 s2 =
+ let s1 = ESorts.kind sigma (ESorts.make s1) in
+ let s2 = ESorts.kind sigma (ESorts.make s2) in
if Sorts.equal s1 s2 then true
else
(cstrs := Constraints.add
@@ -640,6 +647,37 @@ let eq_constr_universes_proj env sigma m n =
let res = eq_constr' (unsafe_to_constr m) (unsafe_to_constr n) in
if res then Some !cstrs else None
+let universes_of_constr env sigma c =
+ let open Univ in
+ let open Declarations in
+ let rec aux s c =
+ match kind sigma c with
+ | Const (c, u) ->
+ begin match (Environ.lookup_constant c env).const_universes with
+ | Polymorphic_const _ ->
+ LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s
+ | Monomorphic_const (univs, _) ->
+ LSet.union s univs
+ end
+ | Ind ((mind,_), u) | Construct (((mind,_),_), u) ->
+ begin match (Environ.lookup_mind mind env).mind_universes with
+ | Cumulative_ind _ | Polymorphic_ind _ ->
+ LSet.fold LSet.add (Instance.levels (EInstance.kind sigma u)) s
+ | Monomorphic_ind (univs,_) ->
+ LSet.union s univs
+ end
+ | Sort u ->
+ let sort = ESorts.kind sigma u in
+ if Sorts.is_small sort then s
+ else
+ let u = Sorts.univ_of_sort sort in
+ LSet.fold LSet.add (Universe.levels u) s
+ | Evar (k, args) ->
+ let concl = Evd.evar_concl (Evd.find sigma k) in
+ fold sigma aux (aux s (of_constr concl)) c
+ | _ -> fold sigma aux s c
+ in aux LSet.empty c
+
open Context
open Environ
@@ -732,6 +770,20 @@ let rec isArity sigma c =
| Sort _ -> true
| _ -> false
+type arity = rel_context * ESorts.t
+
+let destArity sigma =
+ let open Context.Rel.Declaration in
+ let rec prodec_rec l c =
+ match kind sigma c with
+ | Prod (x,t,c) -> prodec_rec (LocalAssum (x,t) :: l) c
+ | LetIn (x,b,t,c) -> prodec_rec (LocalDef (x,b,t) :: l) c
+ | Cast (c,_,_) -> prodec_rec l c
+ | Sort s -> l,s
+ | _ -> anomaly ~label:"destArity" (Pp.str "not an arity.")
+ in
+ prodec_rec []
+
let mkProd_or_LetIn decl c =
let open Context.Rel.Declaration in
match decl with
@@ -779,6 +831,15 @@ let lookup_rel i e = cast_rel_decl (sym unsafe_eq) (lookup_rel i e)
let lookup_named n e = cast_named_decl (sym unsafe_eq) (lookup_named n e)
let lookup_named_val n e = cast_named_decl (sym unsafe_eq) (lookup_named_val n e)
+let map_rel_context_in_env f env sign =
+ let rec aux env acc = function
+ | d::sign ->
+ aux (push_rel d env) (Context.Rel.Declaration.map_constr (f env) d :: acc) sign
+ | [] ->
+ acc
+ in
+ aux env [] (List.rev sign)
+
let fresh_global ?loc ?rigid ?names env sigma reference =
let (evd,t) = Evd.fresh_global ?loc ?rigid ?names env sigma reference in
evd, of_constr t
diff --git a/engine/eConstr.mli b/engine/eConstr.mli
index 4dbf6c18a3..30de748a19 100644
--- a/engine/eConstr.mli
+++ b/engine/eConstr.mli
@@ -56,6 +56,8 @@ sig
val is_empty : t -> bool
end
+type 'a puniverses = 'a * EInstance.t
+
(** {5 Destructors} *)
val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_term
@@ -93,14 +95,14 @@ val mkEvar : t pexistential -> t
val mkSort : Sorts.t -> t
val mkProp : t
val mkSet : t
-val mkType : Univ.universe -> t
+val mkType : Univ.Universe.t -> t
val mkCast : t * cast_kind * t -> t
val mkProd : Name.t * t * t -> t
val mkLambda : Name.t * t * t -> t
val mkLetIn : Name.t * t * t * t -> t
val mkApp : t * t array -> t
-val mkConst : constant -> t
-val mkConstU : constant * EInstance.t -> t
+val mkConst : Constant.t -> t
+val mkConstU : Constant.t * EInstance.t -> t
val mkProj : (projection * t) -> t
val mkInd : inductive -> t
val mkIndU : inductive * EInstance.t -> t
@@ -144,7 +146,11 @@ val isFix : Evd.evar_map -> t -> bool
val isCoFix : Evd.evar_map -> t -> bool
val isCase : Evd.evar_map -> t -> bool
val isProj : Evd.evar_map -> t -> bool
+
+type arity = rel_context * ESorts.t
+val destArity : Evd.evar_map -> types -> arity
val isArity : Evd.evar_map -> t -> bool
+
val isVarId : Evd.evar_map -> Id.t -> t -> bool
val isRelN : Evd.evar_map -> int -> t -> bool
@@ -157,7 +163,7 @@ val destProd : Evd.evar_map -> t -> Name.t * types * types
val destLambda : Evd.evar_map -> t -> Name.t * types * t
val destLetIn : Evd.evar_map -> t -> Name.t * t * types * t
val destApp : Evd.evar_map -> t -> t * t array
-val destConst : Evd.evar_map -> t -> constant * EInstance.t
+val destConst : Evd.evar_map -> t -> Constant.t * EInstance.t
val destEvar : Evd.evar_map -> t -> t pexistential
val destInd : Evd.evar_map -> t -> inductive * EInstance.t
val destConstruct : Evd.evar_map -> t -> constructor * EInstance.t
@@ -187,9 +193,9 @@ val whd_evar : Evd.evar_map -> constr -> constr
val eq_constr : Evd.evar_map -> t -> t -> bool
val eq_constr_nounivs : Evd.evar_map -> t -> t -> bool
-val eq_constr_universes : Evd.evar_map -> t -> t -> Universes.universe_constraints option
-val leq_constr_universes : Evd.evar_map -> t -> t -> Universes.universe_constraints option
-val eq_constr_universes_proj : Environ.env -> Evd.evar_map -> t -> t -> Universes.universe_constraints option
+val eq_constr_universes : Evd.evar_map -> t -> t -> Universes.Constraints.t option
+val leq_constr_universes : Evd.evar_map -> t -> t -> Universes.Constraints.t option
+val eq_constr_universes_proj : Environ.env -> Evd.evar_map -> t -> t -> Universes.Constraints.t option
val compare_constr : Evd.evar_map -> (t -> t -> bool) -> t -> t -> bool
(** {6 Iterators} *)
@@ -201,6 +207,10 @@ val iter_with_binders : Evd.evar_map -> ('a -> 'a) -> ('a -> t -> unit) -> 'a ->
val iter_with_full_binders : Evd.evar_map -> (rel_declaration -> 'a -> 'a) -> ('a -> t -> unit) -> 'a -> t -> unit
val fold : Evd.evar_map -> ('a -> t -> 'a) -> 'a -> t -> 'a
+(** Gather the universes transitively used in the term, including in the
+ type of evars appearing in it. *)
+val universes_of_constr : Environ.env -> Evd.evar_map -> t -> Univ.LSet.t
+
(** {6 Substitutions} *)
module Vars :
@@ -256,6 +266,9 @@ val lookup_rel : int -> env -> rel_declaration
val lookup_named : variable -> env -> named_declaration
val lookup_named_val : variable -> named_context_val -> named_declaration
+val map_rel_context_in_env :
+ (env -> constr -> constr) -> env -> rel_context -> rel_context
+
(* XXX Missing Sigma proxy *)
val fresh_global :
?loc:Loc.t -> ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
diff --git a/engine/engine.mllib b/engine/engine.mllib
index afc02d7f6d..a3614f6c4a 100644
--- a/engine/engine.mllib
+++ b/engine/engine.mllib
@@ -1,12 +1,13 @@
-Logic_monad
Universes
+Univops
UState
+Nameops
Evd
EConstr
Namegen
Termops
-Proofview_monad
Evarutil
+Logic_monad
+Proofview_monad
Proofview
Ftactic
-Geninterp
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 339c6a248e..374fdce722 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -10,11 +10,12 @@ open CErrors
open Util
open Names
open Term
-open Termops
-open Namegen
+open Constr
open Pre_env
open Environ
open Evd
+open Termops
+open Namegen
module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
@@ -53,15 +54,15 @@ let new_global evd x =
(* flush_and_check_evars fails if an existential is undefined *)
-exception Uninstantiated_evar of existential_key
+exception Uninstantiated_evar of Evar.t
let rec flush_and_check_evars sigma c =
- match kind_of_term c with
+ match kind c with
| Evar (evk,_ as ev) ->
(match existential_opt_value sigma ev with
| None -> raise (Uninstantiated_evar evk)
| Some c -> flush_and_check_evars sigma c)
- | _ -> map_constr (flush_and_check_evars sigma) c
+ | _ -> Constr.map (flush_and_check_evars sigma) c
let flush_and_check_evars sigma c =
flush_and_check_evars sigma (EConstr.Unsafe.to_constr c)
@@ -162,7 +163,7 @@ exception NoHeadEvar
let head_evar sigma c =
(** FIXME: this breaks if using evar-insensitive code *)
let c = EConstr.Unsafe.to_constr c in
- let rec hrec c = match kind_of_term c with
+ let rec hrec c = match kind c with
| Evar (evk,_) -> evk
| Case (_,_,c,_) -> hrec c
| App (c,_) -> hrec c
@@ -198,9 +199,10 @@ let whd_head_evar sigma c =
let meta_counter_summary_name = "meta counter"
(* Generator of metavariables *)
-let new_meta =
- let meta_ctr = Summary.ref 0 ~name:meta_counter_summary_name in
- fun () -> incr meta_ctr; !meta_ctr
+let meta_ctr, meta_counter_summary_tag =
+ Summary.ref_tag 0 ~name:meta_counter_summary_name
+
+let new_meta () = incr meta_ctr; !meta_ctr
let mk_new_meta () = EConstr.mkMeta(new_meta())
@@ -306,7 +308,7 @@ let push_rel_decl_to_named_context sigma decl (subst, vsubst, avoid, nc) =
in
let extract_if_neq id = function
| Anonymous -> None
- | Name id' when id_ord id id' = 0 -> None
+ | Name id' when Id.compare id id' = 0 -> None
| Name id' -> Some id'
in
let na = RelDecl.get_name decl in
@@ -478,8 +480,6 @@ type clear_dependency_error =
exception ClearDependencyError of Id.t * clear_dependency_error
-let cleared = Store.field ()
-
exception Depends of Id.t
let rec check_and_clear_in_constr env evdref err ids global c =
@@ -487,7 +487,7 @@ let rec check_and_clear_in_constr env evdref err ids global c =
(ie the hypotheses ids have been removed from the contexts of
evars). [global] should be true iff there is some variable of [ids] which
is a section variable *)
- match kind_of_term c with
+ match kind c with
| Var id' ->
if Id.Set.mem id' ids then raise (ClearDependencyError (id', err)) else c
@@ -552,16 +552,9 @@ let rec check_and_clear_in_constr env evdref err ids global c =
let evd = !evdref in
let (evd,_) = restrict_evar evd evk filter None in
evdref := evd;
- (* spiwack: hacking session to mark the old [evk] as having been "cleared" *)
- let evi = Evd.find !evdref evk in
- let extra = evi.evar_extra in
- let extra' = Store.set extra cleared true in
- let evi' = { evi with evar_extra = extra' } in
- evdref := Evd.add !evdref evk evi' ;
- (* spiwack: /hacking session *)
Evd.existential_value !evdref ev
- | _ -> map_constr (check_and_clear_in_constr env evdref err ids global) c
+ | _ -> Constr.map (check_and_clear_in_constr env evdref err ids global) c
let clear_hyps_in_evi_main env evdref hyps terms ids =
(* clear_hyps_in_evi erases hypotheses ids in hyps, checking if some
@@ -665,11 +658,9 @@ let rec advance sigma evk =
match evi.evar_body with
| Evar_empty -> Some evk
| Evar_defined v ->
- if Option.default false (Store.get evi.evar_extra cleared) then
- let (evk,_) = Term.destEvar v in
- advance sigma evk
- else
- None
+ match is_restricted_evar evi with
+ | Some evk -> advance sigma evk
+ | None -> None
(** The following functions return the set of undefined evars
contained in the object, the defined evars being traversed.
@@ -701,16 +692,65 @@ let undefined_evars_of_evar_info evd evi =
(undefined_evars_of_named_context evd
(named_context_of_val evi.evar_hyps)))
+type undefined_evars_cache = {
+ mutable cache : (EConstr.named_declaration * Evar.Set.t) ref Id.Map.t;
+}
+
+let create_undefined_evars_cache () = { cache = Id.Map.empty; }
+
+let cached_evar_of_hyp cache sigma decl accu = match cache with
+| None ->
+ let fold c acc =
+ let evs = undefined_evars_of_term sigma c in
+ Evar.Set.union evs acc
+ in
+ NamedDecl.fold_constr fold decl accu
+| Some cache ->
+ let id = NamedDecl.get_id decl in
+ let r =
+ try Id.Map.find id cache.cache
+ with Not_found ->
+ (** Dummy value *)
+ let r = ref (NamedDecl.LocalAssum (id, EConstr.mkProp), Evar.Set.empty) in
+ let () = cache.cache <- Id.Map.add id r cache.cache in
+ r
+ in
+ let (decl', evs) = !r in
+ let evs =
+ if NamedDecl.equal (==) decl decl' then snd !r
+ else
+ let fold c acc =
+ let evs = undefined_evars_of_term sigma c in
+ Evar.Set.union evs acc
+ in
+ let evs = NamedDecl.fold_constr fold decl Evar.Set.empty in
+ let () = r := (decl, evs) in
+ evs
+ in
+ Evar.Set.fold Evar.Set.add evs accu
+
+let filtered_undefined_evars_of_evar_info ?cache sigma evi =
+ let evars_of_named_context cache accu nc =
+ let fold decl accu = cached_evar_of_hyp cache sigma (EConstr.of_named_decl decl) accu in
+ Context.Named.fold_outside fold nc ~init:accu
+ in
+ let accu = match evi.evar_body with
+ | Evar_empty -> Evar.Set.empty
+ | Evar_defined b -> evars_of_term b
+ in
+ let accu = Evar.Set.union (undefined_evars_of_term sigma (EConstr.of_constr evi.evar_concl)) accu in
+ evars_of_named_context cache accu (evar_filtered_context evi)
+
(* spiwack: this is a more complete version of
{!Termops.occur_evar}. The latter does not look recursively into an
[evar_map]. If unification only need to check superficially, tactics
do not have this luxury, and need the more complete version. *)
let occur_evar_upto sigma n c =
let c = EConstr.Unsafe.to_constr c in
- let rec occur_rec c = match kind_of_term c with
+ let rec occur_rec c = match kind c with
| Evar (sp,_) when Evar.equal sp n -> raise Occur
| Evar e -> Option.iter occur_rec (existential_opt_value sigma e)
- | _ -> iter_constr occur_rec c
+ | _ -> Constr.iter occur_rec c
in
try occur_rec c; false with Occur -> true
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index 14173e774d..37f5968ad8 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -7,7 +7,7 @@
(************************************************************************)
open Names
-open Term
+open Constr
open Evd
open Environ
open EConstr
@@ -38,9 +38,9 @@ val new_pure_evar :
named_context_val -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * evar
+ ?principal:bool -> types -> evar_map * Evar.t
-val new_pure_evar_full : evar_map -> evar_info -> evar_map * evar
+val new_pure_evar_full : evar_map -> evar_info -> evar_map * Evar.t
(** the same with side-effects *)
val e_new_evar :
@@ -54,17 +54,17 @@ val e_new_evar :
val new_type_evar :
env -> evar_map -> ?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid ->
- evar_map * (constr * sorts)
+ evar_map * (constr * Sorts.t)
val e_new_type_evar : env -> evar_map ref ->
?src:Evar_kinds.t Loc.located -> ?filter:Filter.t ->
- ?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid -> constr * sorts
+ ?naming:Misctypes.intro_pattern_naming_expr -> ?principal:bool -> rigid -> constr * Sorts.t
val new_Type : ?rigid:rigid -> env -> evar_map -> evar_map * constr
val e_new_Type : ?rigid:rigid -> env -> evar_map ref -> constr
-val restrict_evar : evar_map -> existential_key -> Filter.t ->
- ?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * existential_key
+val restrict_evar : evar_map -> Evar.t -> Filter.t ->
+ ?src:Evar_kinds.t Loc.located -> constr list option -> evar_map * Evar.t
(** Polymorphic constants *)
@@ -96,7 +96,7 @@ val non_instantiated : evar_map -> evar_info Evar.Map.t
(** [head_evar c] returns the head evar of [c] if any *)
exception NoHeadEvar
-val head_evar : evar_map -> constr -> existential_key (** may raise NoHeadEvar *)
+val head_evar : evar_map -> constr -> Evar.t (** may raise NoHeadEvar *)
(* Expand head evar if any *)
val whd_head_evar : evar_map -> constr -> constr
@@ -116,13 +116,13 @@ val is_ground_env : evar_map -> env -> bool
associating to each dependent evar [None] if it has no (partial)
definition or [Some s] if [s] is the list of evars appearing in
its (partial) definition. *)
-val gather_dependent_evars : evar_map -> evar list -> (Evar.Set.t option) Evar.Map.t
+val gather_dependent_evars : evar_map -> Evar.t list -> (Evar.Set.t option) Evar.Map.t
(** [advance sigma g] returns [Some g'] if [g'] is undefined and is
the current avatar of [g] (for instance [g] was changed by [clear]
into [g']). It returns [None] if [g] has been (partially)
solved. *)
-val advance : evar_map -> evar -> evar option
+val advance : evar_map -> Evar.t -> Evar.t option
(** The following functions return the set of undefined evars
contained in the object, the defined evars being traversed.
@@ -133,6 +133,12 @@ val undefined_evars_of_term : evar_map -> constr -> Evar.Set.t
val undefined_evars_of_named_context : evar_map -> Context.Named.t -> Evar.Set.t
val undefined_evars_of_evar_info : evar_map -> evar_info -> Evar.Set.t
+type undefined_evars_cache
+
+val create_undefined_evars_cache : unit -> undefined_evars_cache
+
+val filtered_undefined_evars_of_evar_info : ?cache:undefined_evars_cache -> evar_map -> evar_info -> Evar.Set.t
+
(** [occur_evar_upto sigma k c] returns [true] if [k] appears in
[c]. It looks up recursively in [sigma] for the value of existential
variables. *)
@@ -177,7 +183,7 @@ val e_nf_evars_and_universes : evar_map ref -> (Constr.constr -> Constr.constr)
val nf_evar_map_universes : evar_map -> evar_map * (Constr.constr -> Constr.constr)
(** Replacing all evars, possibly raising [Uninstantiated_evar] *)
-exception Uninstantiated_evar of existential_key
+exception Uninstantiated_evar of Evar.t
val flush_and_check_evars : evar_map -> constr -> Constr.constr
(** {6 Term manipulation up to instantiation} *)
@@ -204,10 +210,6 @@ type clear_dependency_error =
exception ClearDependencyError of Id.t * clear_dependency_error
-(* spiwack: marks an evar that has been "defined" by clear.
- used by [Goal] and (indirectly) [Proofview] to handle the clear tactic gracefully*)
-val cleared : bool Store.field
-
val clear_hyps_in_evi : env -> evar_map ref -> named_context_val -> types ->
Id.Set.t -> named_context_val * types
@@ -227,7 +229,7 @@ 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 * (identifier*constr) list
+ named_context_val * types * constr list * csubst * (Id.t*constr) list
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
@@ -237,12 +239,13 @@ val evd_comb0 : (evar_map -> evar_map * 'a) -> evar_map ref -> 'a
val evd_comb1 : (evar_map -> 'b -> evar_map * 'a) -> evar_map ref -> 'b -> 'a
val evd_comb2 : (evar_map -> 'b -> 'c -> evar_map * 'a) -> evar_map ref -> 'b -> 'c -> 'a
-val subterm_source : existential_key -> Evar_kinds.t Loc.located ->
+val subterm_source : Evar.t -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
-val meta_counter_summary_name : string
-
-(** Deprecater *)
+val meta_counter_summary_tag : int Summary.Dyn.tag
+(** Deprecated *)
type type_constraint = types option
+[@@ocaml.deprecated "use the version in Evardefine"]
type val_constraint = constr option
+[@@ocaml.deprecated "use the version in Evardefine"]
diff --git a/engine/evd.ml b/engine/evd.ml
index cfc9aa6351..e33c851f6e 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -8,10 +8,11 @@
open Pp
open CErrors
+open Sorts
open Util
open Names
open Nameops
-open Term
+open Constr
open Vars
open Environ
@@ -124,10 +125,9 @@ end
(* The type of mappings for existential variables *)
-module Dummy = struct end
-module Store = Store.Make(Dummy)
+module Store = Store.Make ()
-type evar = Term.existential_key
+type evar = Evar.t
let string_of_existential evk = "?X" ^ string_of_int (Evar.repr evk)
@@ -281,9 +281,9 @@ type 'a freelisted = {
(* Collects all metavars appearing in a constr *)
let metavars_of c =
let rec collrec acc c =
- match kind_of_term c with
+ match kind c with
| Meta mv -> Int.Set.add mv acc
- | _ -> Term.fold_constr collrec acc c
+ | _ -> Constr.fold collrec acc c
in
collrec Int.Set.empty c
@@ -371,17 +371,17 @@ val key : Id.t -> t -> Evar.t
end =
struct
-type t = Id.t EvMap.t * existential_key Idmap.t
+type t = Id.t EvMap.t * Evar.t Id.Map.t
-let empty = (EvMap.empty, Idmap.empty)
+let empty = (EvMap.empty, Id.Map.empty)
let add_name_newly_undefined id evk evi (evtoid, idtoev as names) =
match id with
| None -> names
| Some id ->
- if Idmap.mem id idtoev then
- user_err (str "Already an existential evar of name " ++ pr_id id);
- (EvMap.add evk id evtoid, Idmap.add id evk idtoev)
+ if Id.Map.mem id idtoev then
+ user_err (str "Already an existential evar of name " ++ Id.print id);
+ (EvMap.add evk id evtoid, Id.Map.add id evk idtoev)
let add_name_undefined naming evk evi (evtoid,idtoev as evar_names) =
if EvMap.mem evk evtoid then
@@ -393,15 +393,15 @@ let remove_name_defined evk (evtoid, idtoev as names) =
let id = try Some (EvMap.find evk evtoid) with Not_found -> None in
match id with
| None -> names
- | Some id -> (EvMap.remove evk evtoid, Idmap.remove id idtoev)
+ | Some id -> (EvMap.remove evk evtoid, Id.Map.remove id idtoev)
let rename evk id (evtoid, idtoev) =
let id' = try Some (EvMap.find evk evtoid) with Not_found -> None in
match id' with
- | None -> (EvMap.add evk id evtoid, Idmap.add id evk idtoev)
+ | None -> (EvMap.add evk id evtoid, Id.Map.add id evk idtoev)
| Some id' ->
- if Idmap.mem id idtoev then anomaly (str "Evar name already in use.");
- (EvMap.update evk id evtoid (* overwrite old name *), Idmap.add id evk (Idmap.remove id' idtoev))
+ if Id.Map.mem id idtoev then anomaly (str "Evar name already in use.");
+ (EvMap.set evk id evtoid (* overwrite old name *), Id.Map.add id evk (Id.Map.remove id' idtoev))
let reassign_name_defined evk evk' (evtoid, idtoev as names) =
let id = try Some (EvMap.find evk evtoid) with Not_found -> None in
@@ -409,13 +409,13 @@ let reassign_name_defined evk evk' (evtoid, idtoev as names) =
| None -> names (** evk' must not be defined *)
| Some id ->
(EvMap.add evk' id (EvMap.remove evk evtoid),
- Idmap.add id evk' (Idmap.remove id idtoev))
+ Id.Map.add id evk' (Id.Map.remove id idtoev))
let ident evk (evtoid, _) =
try Some (EvMap.find evk evtoid) with Not_found -> None
let key id (_, idtoev) =
- Idmap.find id idtoev
+ Id.Map.find id idtoev
end
@@ -466,9 +466,8 @@ let add d e i = add_with_name d e i
let evar_counter_summary_name = "evar counter"
(* Generator of existential names *)
-let new_untyped_evar =
- let evar_ctr = Summary.ref 0 ~name:evar_counter_summary_name in
- fun () -> incr evar_ctr; Evar.unsafe_of_int !evar_ctr
+let evar_ctr, evar_counter_summary_tag = Summary.ref_tag 0 ~name:evar_counter_summary_name
+let new_untyped_evar () = incr evar_ctr; Evar.unsafe_of_int !evar_ctr
let new_evar evd ?name evi =
let evk = new_untyped_evar () in
@@ -630,7 +629,9 @@ let evar_source evk d = (find d evk).evar_source
let evar_ident evk evd = EvNames.ident evk evd.evar_names
let evar_key id evd = EvNames.key id evd.evar_names
-let define_aux def undef evk body =
+let restricted = Store.field ()
+
+let define_aux ?dorestrict def undef evk body =
let oldinfo =
try EvMap.find evk undef
with Not_found ->
@@ -640,7 +641,10 @@ let define_aux def undef evk body =
anomaly ~label:"Evd.define" (Pp.str "cannot define undeclared evar.")
in
let () = assert (oldinfo.evar_body == Evar_empty) in
- let newinfo = { oldinfo with evar_body = Evar_defined body } in
+ let evar_extra = match dorestrict with
+ | Some evk' -> Store.set oldinfo.evar_extra restricted evk'
+ | None -> oldinfo.evar_extra in
+ let newinfo = { oldinfo with evar_body = Evar_defined body; evar_extra } in
EvMap.add evk newinfo def, EvMap.remove evk undef
(* define the existential of section path sp as the constr body *)
@@ -653,6 +657,9 @@ let define evk body evd =
let evar_names = EvNames.remove_name_defined evk evd.evar_names in
{ evd with defn_evars; undf_evars; last_mods; evar_names }
+let is_restricted_evar evi =
+ Store.get evi.evar_extra restricted
+
let restrict evk filter ?candidates ?src evd =
let evk' = new_untyped_evar () in
let evar_info = EvMap.find evk evd.undf_evars in
@@ -667,7 +674,7 @@ let restrict evk filter ?candidates ?src evd =
let ctxt = Filter.filter_list filter (evar_context evar_info) in
let id_inst = Array.map_of_list (NamedDecl.get_id %> mkVar) ctxt in
let body = mkEvar(evk',id_inst) in
- let (defn_evars, undf_evars) = define_aux evd.defn_evars evd.undf_evars evk body in
+ let (defn_evars, undf_evars) = define_aux ~dorestrict:evk' evd.defn_evars evd.undf_evars evk body in
{ evd with undf_evars = EvMap.add evk' evar_info' undf_evars;
defn_evars; last_mods; evar_names }, evk'
@@ -699,10 +706,10 @@ let extract_all_conv_pbs evd =
extract_conv_pbs evd (fun _ -> true)
let loc_of_conv_pb evd (pbty,env,t1,t2) =
- match kind_of_term (fst (decompose_app t1)) with
+ match kind (fst (decompose_app t1)) with
| Evar (evk1,_) -> fst (evar_source evk1 evd)
| _ ->
- match kind_of_term (fst (decompose_app t2)) with
+ match kind (fst (decompose_app t2)) with
| Evar (evk2,_) -> fst (evar_source evk2 evd)
| _ -> None
@@ -713,9 +720,9 @@ let loc_of_conv_pb evd (pbty,env,t1,t2) =
let evars_of_term c =
let rec evrec acc c =
- match kind_of_term c with
+ match kind c with
| Evar (n, l) -> Evar.Set.add n (Array.fold_left evrec acc l)
- | _ -> Term.fold_constr evrec acc c
+ | _ -> Constr.fold evrec acc c
in
evrec Evar.Set.empty c
@@ -748,7 +755,12 @@ let evar_universe_context d = d.universes
let universe_context_set d = UState.context_set d.universes
-let universe_context ?names evd = UState.universe_context ?names evd.universes
+let to_universe_context evd = UState.context evd.universes
+
+let const_univ_entry ~poly evd = UState.const_univ_entry ~poly evd.universes
+let ind_univ_entry ~poly evd = UState.ind_univ_entry ~poly evd.universes
+
+let check_univ_decl ~poly evd decl = UState.check_univ_decl ~poly evd.universes decl
let restrict_universe_context evd vars =
{ evd with universes = UState.restrict evd.universes vars }
@@ -791,7 +803,7 @@ let make_evar_universe_context e l =
| Some us ->
List.fold_left
(fun uctx (loc,id) ->
- fst (UState.new_univ_variable ?loc univ_rigid (Some (Id.to_string id)) uctx))
+ fst (UState.new_univ_variable ?loc univ_rigid (Some id) uctx))
uctx us
(****************************************)
@@ -922,8 +934,7 @@ let nf_constraints evd =
let universe_of_name evd s = UState.universe_of_name evd.universes s
-let add_universe_name evd s l =
- { evd with universes = UState.add_universe_name evd.universes s l }
+let universe_binders evd = UState.universe_binders evd.universes
let universes evd = UState.ugraph evd.universes
diff --git a/engine/evd.mli b/engine/evd.mli
index 3f00a3b0b2..b28ce2a62d 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -9,7 +9,7 @@
open Util
open Loc
open Names
-open Term
+open Constr
open Environ
(** This file defines the pervasive unification state used everywhere in Coq
@@ -28,12 +28,13 @@ open Environ
(** {5 Existential variables and unification states} *)
-(** {6 Evars} *)
-
-type evar = existential_key
-(** Existential variables. TODO: Should be made opaque one day. *)
+type evar = Evar.t
+[@@ocaml.deprecated "use Evar.t"]
+(** Existential variables. *)
-val string_of_existential : evar -> string
+(** {6 Evars} *)
+val string_of_existential : Evar.t -> string
+[@@ocaml.deprecated "use Evar.print"]
(** {6 Evar filters} *)
@@ -125,6 +126,7 @@ val map_evar_info : (constr -> constr) -> evar_info -> evar_info
(** {6 Unification state} **)
type evar_universe_context = UState.t
+[@@ocaml.deprecated "Alias of UState.t"]
(** The universe context associated to an evar map *)
type evar_map
@@ -138,7 +140,7 @@ val from_env : env -> evar_map
(** The empty evar map with given universe context, taking its initial
universes from env. *)
-val from_ctx : evar_universe_context -> evar_map
+val from_ctx : UState.t -> evar_map
(** The empty evar map with given universe context *)
val is_empty : evar_map -> bool
@@ -149,44 +151,44 @@ val has_undefined : evar_map -> bool
there are uninstantiated evars in [sigma]. *)
val new_evar : evar_map ->
- ?name:Id.t -> evar_info -> evar_map * evar
+ ?name:Id.t -> evar_info -> evar_map * Evar.t
(** Creates a fresh evar mapping to the given information. *)
-val add : evar_map -> evar -> evar_info -> evar_map
+val add : evar_map -> Evar.t -> evar_info -> evar_map
(** [add sigma ev info] adds [ev] with evar info [info] in sigma.
Precondition: ev must not preexist in [sigma]. *)
-val find : evar_map -> evar -> evar_info
+val find : evar_map -> Evar.t -> evar_info
(** Recover the data associated to an evar. *)
-val find_undefined : evar_map -> evar -> evar_info
+val find_undefined : evar_map -> Evar.t -> evar_info
(** Same as {!find} but restricted to undefined evars. For efficiency
reasons. *)
-val remove : evar_map -> evar -> evar_map
+val remove : evar_map -> Evar.t -> evar_map
(** Remove an evar from an evar map. Use with caution. *)
-val mem : evar_map -> evar -> bool
+val mem : evar_map -> Evar.t -> bool
(** Whether an evar is present in an evarmap. *)
-val fold : (evar -> evar_info -> 'a -> 'a) -> evar_map -> 'a -> 'a
+val fold : (Evar.t -> evar_info -> 'a -> 'a) -> evar_map -> 'a -> 'a
(** Apply a function to all evars and their associated info in an evarmap. *)
-val fold_undefined : (evar -> evar_info -> 'a -> 'a) -> evar_map -> 'a -> 'a
+val fold_undefined : (Evar.t -> evar_info -> 'a -> 'a) -> evar_map -> 'a -> 'a
(** Same as {!fold}, but restricted to undefined evars. For efficiency
reasons. *)
-val raw_map : (evar -> evar_info -> evar_info) -> evar_map -> evar_map
+val raw_map : (Evar.t -> evar_info -> evar_info) -> evar_map -> evar_map
(** Apply the given function to all evars in the map. Beware: this function
expects the argument function to preserve the kind of [evar_body], i.e. it
must send [Evar_empty] to [Evar_empty] and [Evar_defined c] to some
[Evar_defined c']. *)
-val raw_map_undefined : (evar -> evar_info -> evar_info) -> evar_map -> evar_map
+val raw_map_undefined : (Evar.t -> evar_info -> evar_info) -> evar_map -> evar_map
(** Same as {!raw_map}, but restricted to undefined evars. For efficiency
reasons. *)
-val define : evar -> constr -> evar_map -> evar_map
+val define : Evar.t-> constr -> evar_map -> evar_map
(** Set the body of an evar to the given constr. It is expected that:
{ul
{- The evar is already present in the evarmap.}
@@ -197,16 +199,16 @@ val define : evar -> constr -> evar_map -> evar_map
val cmap : (constr -> constr) -> evar_map -> evar_map
(** Map the function on all terms in the evar map. *)
-val is_evar : evar_map -> evar -> bool
+val is_evar : evar_map -> Evar.t-> bool
(** Alias for {!mem}. *)
-val is_defined : evar_map -> evar -> bool
+val is_defined : evar_map -> Evar.t-> bool
(** Whether an evar is defined in an evarmap. *)
-val is_undefined : evar_map -> evar -> bool
+val is_undefined : evar_map -> Evar.t-> bool
(** Whether an evar is not defined in an evarmap. *)
-val add_constraints : evar_map -> Univ.constraints -> evar_map
+val add_constraints : evar_map -> Univ.Constraint.t -> evar_map
(** Add universe constraints in an evar map. *)
val undefined_map : evar_map -> evar_info Evar.Map.t
@@ -239,28 +241,31 @@ val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
(** {6 Misc} *)
-val restrict : evar -> Filter.t -> ?candidates:constr list ->
- ?src:Evar_kinds.t located -> evar_map -> evar_map * evar
+val restrict : Evar.t-> Filter.t -> ?candidates:constr list ->
+ ?src:Evar_kinds.t located -> evar_map -> evar_map * Evar.t
(** Restrict an undefined evar into a new evar by filtering context and
possibly limiting the instances to a set of candidates *)
-val downcast : evar -> types -> evar_map -> evar_map
+val is_restricted_evar : evar_info -> Evar.t option
+(** Tell if an evar comes from restriction of another evar, and if yes, which *)
+
+val downcast : Evar.t-> types -> evar_map -> evar_map
(** Change the type of an undefined evar to a new type assumed to be a
subtype of its current type; subtyping must be ensured by caller *)
-val evar_source : existential_key -> evar_map -> Evar_kinds.t located
+val evar_source : Evar.t -> evar_map -> Evar_kinds.t located
(** Convenience function. Wrapper around {!find} to recover the source of an
evar in a given evar map. *)
-val evar_ident : existential_key -> evar_map -> Id.t option
+val evar_ident : Evar.t -> evar_map -> Id.t option
-val rename : existential_key -> Id.t -> evar_map -> evar_map
+val rename : Evar.t -> Id.t -> evar_map -> evar_map
-val evar_key : Id.t -> evar_map -> existential_key
+val evar_key : Id.t -> evar_map -> Evar.t
val evar_source_of_meta : metavariable -> evar_map -> Evar_kinds.t located
-val dependent_evar_ident : existential_key -> evar_map -> Id.t
+val dependent_evar_ident : Evar.t -> evar_map -> Id.t
(** {5 Side-effects} *)
@@ -311,7 +316,7 @@ val whd_sort_variable : evar_map -> constr -> constr
exception UniversesDiffer
-val add_universe_constraints : evar_map -> Universes.universe_constraints -> evar_map
+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
@@ -483,86 +488,97 @@ val univ_rigid : rigid
val univ_flexible : rigid
val univ_flexible_alg : rigid
-type 'a in_evar_universe_context = 'a * evar_universe_context
+type 'a in_evar_universe_context = 'a * UState.t
-val evar_universe_context_set : evar_universe_context -> Univ.universe_context_set
-val evar_universe_context_constraints : evar_universe_context -> Univ.constraints
-val evar_context_universe_context : evar_universe_context -> Univ.universe_context
-val evar_universe_context_of : Univ.universe_context_set -> evar_universe_context
-val empty_evar_universe_context : evar_universe_context
-val union_evar_universe_context : evar_universe_context -> evar_universe_context ->
- evar_universe_context
-val evar_universe_context_subst : evar_universe_context -> Universes.universe_opt_subst
-val constrain_variables : Univ.LSet.t -> evar_universe_context -> Univ.constraints
+val evar_universe_context_set : UState.t -> Univ.ContextSet.t
+val evar_universe_context_constraints : UState.t -> Univ.Constraint.t
+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
+val empty_evar_universe_context : UState.t
+val union_evar_universe_context : UState.t -> UState.t ->
+ UState.t
+val evar_universe_context_subst : UState.t -> Universes.universe_opt_subst
+val constrain_variables : Univ.LSet.t -> UState.t -> UState.t
val evar_universe_context_of_binders :
- Universes.universe_binders -> evar_universe_context
-
-val make_evar_universe_context : env -> (Id.t located) list option -> evar_universe_context
-val restrict_universe_context : evar_map -> Univ.universe_set -> evar_map
+ Universes.universe_binders -> UState.t
+
+val make_evar_universe_context : env -> (Id.t located) list option -> UState.t
+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 -> string -> Univ.universe_level
-val add_universe_name : evar_map -> string -> Univ.universe_level -> evar_map
+val universe_of_name : evar_map -> Id.t -> Univ.Level.t
-val add_constraints_context : evar_universe_context ->
- Univ.constraints -> evar_universe_context
+val universe_binders : evar_map -> Universes.universe_binders
+val add_constraints_context : UState.t ->
+ Univ.Constraint.t -> UState.t
-val normalize_evar_universe_context_variables : evar_universe_context ->
+val normalize_evar_universe_context_variables : UState.t ->
Univ.universe_subst in_evar_universe_context
-val normalize_evar_universe_context : evar_universe_context ->
- evar_universe_context
+val normalize_evar_universe_context : UState.t ->
+ UState.t
-val new_univ_level_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Univ.universe_level
-val new_univ_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Univ.universe
-val new_sort_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * sorts
+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
+val new_sort_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Sorts.t
val add_global_univ : evar_map -> Univ.Level.t -> evar_map
val universe_rigidity : evar_map -> Univ.Level.t -> rigid
-val make_flexible_variable : evar_map -> algebraic:bool -> Univ.universe_level -> evar_map
+val make_flexible_variable : evar_map -> algebraic:bool -> Univ.Level.t -> evar_map
(** See [UState.make_flexible_variable] *)
-val is_sort_variable : evar_map -> sorts -> Univ.universe_level option
+val is_sort_variable : evar_map -> Sorts.t -> Univ.Level.t option
(** [is_sort_variable evm s] returns [Some u] or [None] if [s] is
not a local sort variable declared in [evm] *)
val is_flexible_level : evar_map -> Univ.Level.t -> bool
-(* val normalize_universe_level : evar_map -> Univ.universe_level -> Univ.universe_level *)
-val normalize_universe : evar_map -> Univ.universe -> Univ.universe
-val normalize_universe_instance : evar_map -> Univ.universe_instance -> Univ.universe_instance
+(* val normalize_universe_level : evar_map -> Univ.Level.t -> Univ.Level.t *)
+val normalize_universe : evar_map -> Univ.Universe.t -> Univ.Universe.t
+val normalize_universe_instance : evar_map -> Univ.Instance.t -> Univ.Instance.t
-val set_leq_sort : env -> evar_map -> sorts -> sorts -> evar_map
-val set_eq_sort : env -> evar_map -> sorts -> sorts -> evar_map
-val has_lub : evar_map -> Univ.universe -> Univ.universe -> evar_map
-val set_eq_level : evar_map -> Univ.universe_level -> Univ.universe_level -> evar_map
-val set_leq_level : evar_map -> Univ.universe_level -> Univ.universe_level -> evar_map
+val set_leq_sort : env -> evar_map -> Sorts.t -> Sorts.t -> evar_map
+val set_eq_sort : env -> evar_map -> Sorts.t -> Sorts.t -> evar_map
+val has_lub : evar_map -> Univ.Universe.t -> Univ.Universe.t -> evar_map
+val set_eq_level : evar_map -> Univ.Level.t -> Univ.Level.t -> evar_map
+val set_leq_level : evar_map -> Univ.Level.t -> Univ.Level.t -> evar_map
val set_eq_instances : ?flex:bool ->
- evar_map -> Univ.universe_instance -> Univ.universe_instance -> evar_map
+ evar_map -> Univ.Instance.t -> Univ.Instance.t -> evar_map
-val check_eq : evar_map -> Univ.universe -> Univ.universe -> bool
-val check_leq : evar_map -> Univ.universe -> Univ.universe -> bool
+val check_eq : evar_map -> Univ.Universe.t -> Univ.Universe.t -> bool
+val check_leq : evar_map -> Univ.Universe.t -> Univ.Universe.t -> bool
-val evar_universe_context : evar_map -> evar_universe_context
-val universe_context_set : evar_map -> Univ.universe_context_set
-val universe_context : ?names:(Id.t located) list -> evar_map ->
- (Id.t * Univ.Level.t) list * Univ.universe_context
+val evar_universe_context : evar_map -> UState.t
+val universe_context_set : evar_map -> Univ.ContextSet.t
val universe_subst : evar_map -> Universes.universe_opt_subst
val universes : evar_map -> UGraph.t
+(** [to_universe_context evm] extracts the local universes and
+ constraints of [evm] and orders the universes the same as
+ [Univ.ContextSet.to_context]. *)
+val to_universe_context : evar_map -> Univ.UContext.t
+
+val const_univ_entry : poly:bool -> evar_map -> Entries.constant_universes_entry
-val merge_universe_context : evar_map -> evar_universe_context -> evar_map
-val set_universe_context : evar_map -> evar_universe_context -> evar_map
+(** NB: [ind_univ_entry] cannot create cumulative entries. *)
+val ind_univ_entry : poly:bool -> evar_map -> Entries.inductive_universes
-val merge_context_set : ?loc:Loc.t -> ?sideff:bool -> rigid -> evar_map -> Univ.universe_context_set -> evar_map
+val check_univ_decl : poly:bool -> evar_map -> UState.universe_decl -> Entries.constant_universes_entry
+
+val merge_universe_context : evar_map -> UState.t -> evar_map
+val set_universe_context : evar_map -> UState.t -> evar_map
+
+val merge_context_set : ?loc:Loc.t -> ?sideff:bool -> rigid -> evar_map -> Univ.ContextSet.t -> evar_map
val merge_universe_subst : evar_map -> Universes.universe_opt_subst -> evar_map
val with_context_set : ?loc:Loc.t -> rigid -> evar_map -> 'a Univ.in_universe_context_set -> evar_map * 'a
val nf_univ_variables : evar_map -> evar_map * Univ.universe_subst
-val abstract_undefined_variables : evar_universe_context -> evar_universe_context
+val abstract_undefined_variables : UState.t -> UState.t
val fix_undefined_variables : evar_map -> evar_map
@@ -574,8 +590,8 @@ val update_sigma_env : evar_map -> env -> evar_map
(** Polymorphic universes *)
-val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:rigid -> env -> evar_map -> sorts_family -> evar_map * sorts
-val fresh_constant_instance : ?loc:Loc.t -> env -> evar_map -> constant -> evar_map * pconstant
+val fresh_sort_in_family : ?loc:Loc.t -> ?rigid:rigid -> env -> evar_map -> Sorts.family -> evar_map * Sorts.t
+val fresh_constant_instance : ?loc:Loc.t -> env -> evar_map -> Constant.t -> evar_map * pconstant
val fresh_inductive_instance : ?loc:Loc.t -> env -> evar_map -> inductive -> evar_map * pinductive
val fresh_constructor_instance : ?loc:Loc.t -> env -> evar_map -> constructor -> evar_map * pconstructor
@@ -593,11 +609,16 @@ type open_constr = evar_map * constr (* Special case when before is empty *)
type unsolvability_explanation = SeveralInstancesFound of int
(** Failure explanation. *)
+(** {5 Summary names} *)
+
+(* This stuff is internal and should not be used. Currently a hack in
+ the STM relies on it. *)
+val evar_counter_summary_tag : int Summary.Dyn.tag
+
(** {5 Deprecated functions} *)
+val create_evar_defs : evar_map -> evar_map
+(* XXX: This is supposed to be deprecated by used by ssrmatching, what
+ should the replacement be? *)
-val create_evar_defs : evar_map -> evar_map
(** Create an [evar_map] with empty meta map: *)
-(** {5 Summary names} *)
-
-val evar_counter_summary_name : string
diff --git a/engine/geninterp.ml b/engine/geninterp.ml
deleted file mode 100644
index e79e258fbc..0000000000
--- a/engine/geninterp.ml
+++ /dev/null
@@ -1,98 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-open Names
-open Genarg
-
-module TacStore = Store.Make(struct end)
-
-(** Dynamic toplevel values *)
-
-module ValT = Dyn.Make(struct end)
-
-module Val =
-struct
-
- type 'a typ = 'a ValT.tag
-
- type _ tag =
- | Base : 'a typ -> 'a tag
- | List : 'a tag -> 'a list tag
- | Opt : 'a tag -> 'a option tag
- | Pair : 'a tag * 'b tag -> ('a * 'b) tag
-
- type t = Dyn : 'a typ * 'a -> t
-
- let eq = ValT.eq
- let repr = ValT.repr
- let create = ValT.create
-
- let pr : type a. a typ -> Pp.t = fun t -> Pp.str (repr t)
-
- let typ_list = ValT.create "list"
- let typ_opt = ValT.create "option"
- let typ_pair = ValT.create "pair"
-
- let rec inject : type a. a tag -> a -> t = fun tag x -> match tag with
- | Base t -> Dyn (t, x)
- | List tag -> Dyn (typ_list, List.map (fun x -> inject tag x) x)
- | Opt tag -> Dyn (typ_opt, Option.map (fun x -> inject tag x) x)
- | Pair (tag1, tag2) ->
- Dyn (typ_pair, (inject tag1 (fst x), inject tag2 (snd x)))
-
-end
-
-module ValReprObj =
-struct
- type ('raw, 'glb, 'top) obj = 'top Val.tag
- let name = "valrepr"
- let default _ = None
-end
-
-module ValRepr = Register(ValReprObj)
-
-let rec val_tag : type a b c. (a, b, c) genarg_type -> c Val.tag = function
-| ListArg t -> Val.List (val_tag t)
-| OptArg t -> Val.Opt (val_tag t)
-| PairArg (t1, t2) -> Val.Pair (val_tag t1, val_tag t2)
-| ExtraArg s -> ValRepr.obj (ExtraArg s)
-
-let val_tag = function Topwit t -> val_tag t
-
-let register_val0 wit tag =
- let tag = match tag with
- | None ->
- let name = match wit with
- | ExtraArg s -> ArgT.repr s
- | _ -> assert false
- in
- Val.Base (Val.create name)
- | Some tag -> tag
- in
- ValRepr.register0 wit tag
-
-(** Interpretation functions *)
-
-type interp_sign = {
- lfun : Val.t Id.Map.t;
- extra : TacStore.t }
-
-type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
-
-module InterpObj =
-struct
- type ('raw, 'glb, 'top) obj = ('glb, Val.t) interp_fun
- let name = "interp"
- let default _ = None
-end
-
-module Interp = Register(InterpObj)
-
-let interp = Interp.obj
-
-let register_interp0 = Interp.register0
diff --git a/engine/geninterp.mli b/engine/geninterp.mli
deleted file mode 100644
index 492e372adb..0000000000
--- a/engine/geninterp.mli
+++ /dev/null
@@ -1,68 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(** Interpretation functions for generic arguments and interpreted Ltac
- values. *)
-
-open Names
-open Genarg
-
-(** {6 Dynamic toplevel values} *)
-
-module Val :
-sig
- type 'a typ
-
- val create : string -> 'a typ
-
- type _ tag =
- | Base : 'a typ -> 'a tag
- | List : 'a tag -> 'a list tag
- | Opt : 'a tag -> 'a option tag
- | Pair : 'a tag * 'b tag -> ('a * 'b) tag
-
- type t = Dyn : 'a typ * 'a -> t
-
- val eq : 'a typ -> 'b typ -> ('a, 'b) CSig.eq option
- val repr : 'a typ -> string
- val pr : 'a typ -> Pp.t
-
- val typ_list : t list typ
- val typ_opt : t option typ
- val typ_pair : (t * t) typ
-
- val inject : 'a tag -> 'a -> t
-
-end
-(** Dynamic types for toplevel values. While the generic types permit to relate
- objects at various levels of interpretation, toplevel values are wearing
- their own type regardless of where they came from. This allows to use the
- same runtime representation for several generic types. *)
-
-val val_tag : 'a typed_abstract_argument_type -> 'a Val.tag
-(** Retrieve the dynamic type associated to a toplevel genarg. *)
-
-val register_val0 : ('raw, 'glb, 'top) genarg_type -> 'top Val.tag option -> unit
-(** Register the representation of a generic argument. If no tag is given as
- argument, a new fresh tag with the same name as the argument is associated
- to the generic type. *)
-
-(** {6 Interpretation functions} *)
-
-module TacStore : Store.S
-
-type interp_sign = {
- lfun : Val.t Id.Map.t;
- extra : TacStore.t }
-
-type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
-
-val interp : ('raw, 'glb, 'top) genarg_type -> ('glb, Val.t) interp_fun
-
-val register_interp0 :
- ('raw, 'glb, 'top) genarg_type -> ('glb, Val.t) interp_fun -> unit
diff --git a/engine/logic_monad.ml b/engine/logic_monad.ml
index bf1b3e0e86..9dc5d473b9 100644
--- a/engine/logic_monad.ml
+++ b/engine/logic_monad.ml
@@ -95,7 +95,7 @@ struct
let print_char = fun c -> (); fun () -> print_char c
let timeout = fun n t -> (); fun () ->
- Control.timeout n t (Exception Timeout)
+ Control.timeout n t () (Exception Timeout)
let make f = (); fun () ->
try f ()
diff --git a/engine/namegen.ml b/engine/namegen.ml
index a75fe721f7..ff0b5a74e7 100644
--- a/engine/namegen.ml
+++ b/engine/namegen.ml
@@ -43,6 +43,8 @@ let default_non_dependent_ident = Id.of_string default_non_dependent_string
let default_dependent_ident = Id.of_string "x"
+let default_generated_non_letter_string = "x"
+
(**********************************************************************)
(* Globality of identifiers *)
@@ -59,9 +61,9 @@ let is_imported_ref = function
| VarRef _ -> false
| IndRef (kn,_)
| ConstructRef ((kn,_),_) ->
- let (mp,_,_) = repr_mind kn in is_imported_modpath mp
+ let (mp,_,_) = MutInd.repr3 kn in is_imported_modpath mp
| ConstRef kn ->
- let (mp,_,_) = repr_con kn in is_imported_modpath mp
+ let (mp,_,_) = Constant.repr3 kn in is_imported_modpath mp
let is_global id =
try
@@ -97,7 +99,7 @@ let head_name sigma c = (* Find the head constant of a constr if any *)
match EConstr.kind sigma c with
| Prod (_,_,c) | Lambda (_,_,c) | LetIn (_,_,_,c)
| Cast (c,_,_) | App (c,_) -> hdrec c
- | Proj (kn,_) -> Some (Label.to_id (con_label (Projection.constant kn)))
+ | Proj (kn,_) -> Some (Label.to_id (Constant.label (Projection.constant kn)))
| Const _ | Ind _ | Construct _ | Var _ as c ->
Some (basename_of_global (global_of_constr c))
| Fix ((_,i),(lna,_,_)) | CoFix (i,(lna,_,_)) ->
@@ -107,7 +109,17 @@ let head_name sigma c = (* Find the head constant of a constr if any *)
hdrec c
let lowercase_first_char id = (* First character of a constr *)
- Unicode.lowercase_first_char (Id.to_string id)
+ let s = Id.to_string id in
+ match Unicode.split_at_first_letter s with
+ | None ->
+ (* General case: nat -> n *)
+ Unicode.lowercase_first_char s
+ | Some (s,s') ->
+ if String.length s' = 0 then
+ (* No letter, e.g. __, or __'_, etc. *)
+ default_generated_non_letter_string
+ else
+ s ^ Unicode.lowercase_first_char s'
let sort_hdchar = function
| Prop(_) -> "P"
@@ -118,10 +130,10 @@ let hdchar env sigma c =
match EConstr.kind sigma c with
| Prod (_,_,c) | Lambda (_,_,c) | LetIn (_,_,_,c) -> hdrec (k+1) c
| Cast (c,_,_) | App (c,_) -> hdrec k c
- | Proj (kn,_) -> lowercase_first_char (Label.to_id (con_label (Projection.constant kn)))
- | Const (kn,_) -> lowercase_first_char (Label.to_id (con_label kn))
- | Ind (x,_) -> lowercase_first_char (basename_of_global (IndRef x))
- | Construct (x,_) -> lowercase_first_char (basename_of_global (ConstructRef x))
+ | Proj (kn,_) -> lowercase_first_char (Label.to_id (Constant.label (Projection.constant kn)))
+ | Const (kn,_) -> lowercase_first_char (Label.to_id (Constant.label kn))
+ | Ind (x,_) -> (try lowercase_first_char (basename_of_global (IndRef x)) with Not_found when !Flags.in_debugger -> "zz")
+ | Construct (x,_) -> (try lowercase_first_char (basename_of_global (ConstructRef x)) with Not_found when !Flags.in_debugger -> "zz")
| Var id -> lowercase_first_char id
| Sort s -> sort_hdchar (ESorts.kind sigma s)
| Rel n ->
@@ -239,7 +251,7 @@ let visible_ids sigma (nenv, c) =
let next_name_away_in_cases_pattern sigma env_t na avoid =
let id = match na with Name id -> id | Anonymous -> default_dependent_ident in
let visible = visible_ids sigma env_t in
- let bad id = Id.List.mem id avoid || is_constructor id
+ let bad id = Id.Set.mem id avoid || is_constructor id
|| Id.Set.mem id visible in
next_ident_away_from id bad
@@ -253,8 +265,8 @@ let next_name_away_in_cases_pattern sigma env_t na avoid =
name is taken by finding a free subscript starting from 0 *)
let next_ident_away_in_goal id avoid =
- let id = if Id.List.mem id avoid then restart_subscript id else id in
- let bad id = Id.List.mem id avoid || (is_global id && not (is_section_variable id)) in
+ let id = if Id.Set.mem id avoid then restart_subscript id else id in
+ let bad id = Id.Set.mem id avoid || (is_global id && not (is_section_variable id)) in
next_ident_away_from id bad
let next_name_away_in_goal na avoid =
@@ -271,16 +283,16 @@ let next_name_away_in_goal na avoid =
beyond the current subscript *)
let next_global_ident_away id avoid =
- let id = if Id.List.mem id avoid then restart_subscript id else id in
- let bad id = Id.List.mem id avoid || is_global id in
+ let id = if Id.Set.mem id avoid then restart_subscript id else id in
+ let bad id = Id.Set.mem id avoid || is_global id in
next_ident_away_from id bad
(* 4- Looks for next fresh name outside a list; if name already used,
looks for same name with lower available subscript *)
let next_ident_away id avoid =
- if Id.List.mem id avoid then
- next_ident_away_from (restart_subscript id) (fun id -> Id.List.mem id avoid)
+ if Id.Set.mem id avoid then
+ next_ident_away_from (restart_subscript id) (fun id -> Id.Set.mem id avoid)
else id
let next_name_away_with_default default na avoid =
@@ -302,7 +314,7 @@ let next_name_away = next_name_away_with_default default_non_dependent_string
let make_all_name_different env sigma =
(** FIXME: this is inefficient, but only used in printing *)
- let avoid = ref (Id.Set.elements (Context.Named.to_vars (named_context env))) in
+ let avoid = ref (ids_of_named_context_val (named_context_val env)) in
let sign = named_context_val env in
let rels = rel_context env in
let env0 = reset_with_named_context sign env in
@@ -310,7 +322,7 @@ let make_all_name_different env sigma =
(fun decl newenv ->
let na = named_hd newenv sigma (RelDecl.get_type decl) (RelDecl.get_name decl) in
let id = next_name_away na !avoid in
- avoid := id::!avoid;
+ avoid := Id.Set.add id !avoid;
push_rel (RelDecl.set_name (Name id) decl) newenv)
rels ~init:env0
@@ -321,7 +333,7 @@ let make_all_name_different env sigma =
let next_ident_away_for_default_printing sigma env_t id avoid =
let visible = visible_ids sigma env_t in
- let bad id = Id.List.mem id avoid || Id.Set.mem id visible in
+ let bad id = Id.Set.mem id avoid || Id.Set.mem id visible in
next_ident_away_from id bad
let next_name_away_for_default_printing sigma env_t na avoid =
@@ -364,14 +376,21 @@ let next_name_for_display sigma flags =
| RenamingElsewhereFor env_t -> next_name_away_for_default_printing sigma env_t
(* Remark: Anonymous var may be dependent in Evar's contexts *)
-let compute_displayed_name_in sigma flags avoid na c =
+let compute_displayed_name_in_gen_poly noccurn_fun sigma flags avoid na c =
match na with
- | Anonymous when noccurn sigma 1 c ->
+ | Anonymous when noccurn_fun sigma 1 c ->
(Anonymous,avoid)
| _ ->
let fresh_id = next_name_for_display sigma flags na avoid in
- let idopt = if noccurn sigma 1 c then Anonymous else Name fresh_id in
- (idopt, fresh_id::avoid)
+ let idopt = if noccurn_fun sigma 1 c then Anonymous else Name fresh_id in
+ (idopt, Id.Set.add fresh_id avoid)
+
+let compute_displayed_name_in = compute_displayed_name_in_gen_poly noccurn
+
+let compute_displayed_name_in_gen f sigma =
+ (* only flag which does not need a constr, maybe to be refined *)
+ let flag = RenamingForGoal in
+ compute_displayed_name_in_gen_poly f sigma flag
let compute_and_force_displayed_name_in sigma flags avoid na c =
match na with
@@ -379,11 +398,11 @@ let compute_and_force_displayed_name_in sigma flags avoid na c =
(Anonymous,avoid)
| _ ->
let fresh_id = next_name_for_display sigma flags na avoid in
- (Name fresh_id, fresh_id::avoid)
+ (Name fresh_id, Id.Set.add fresh_id avoid)
let compute_displayed_let_name_in sigma flags avoid na c =
let fresh_id = next_name_for_display sigma flags na avoid in
- (Name fresh_id, fresh_id::avoid)
+ (Name fresh_id, Id.Set.add fresh_id avoid)
let rename_bound_vars_as_displayed sigma avoid env c =
let rec rename avoid env c =
diff --git a/engine/namegen.mli b/engine/namegen.mli
index 14846a9184..abeed9f62d 100644
--- a/engine/namegen.mli
+++ b/engine/namegen.mli
@@ -9,7 +9,6 @@
(** This file features facilities to generate fresh names. *)
open Names
-open Term
open Environ
open Evd
open EConstr
@@ -27,7 +26,7 @@ val default_dependent_ident : Id.t (* "x" *)
Generating "intuitive" names from their type *)
val lowercase_first_char : Id.t -> string
-val sort_hdchar : sorts -> string
+val sort_hdchar : Sorts.t -> string
val hdchar : env -> evar_map -> types -> string
val id_of_name_using_hdchar : env -> evar_map -> types -> Name.t -> Id.t
val named_hd : env -> evar_map -> types -> Name.t -> Name.t
@@ -72,23 +71,22 @@ val next_ident_away_from : Id.t -> (Id.t -> bool) -> Id.t
the whole identifier except for the {i subscript}.
E.g. if we take [foo42], then [42] is the {i subscript}, and [foo] is the root. *)
-val next_ident_away : Id.t -> Id.t list -> Id.t
+val next_ident_away : Id.t -> Id.Set.t -> Id.t
(** Avoid clashing with a name already used in current module *)
-val next_ident_away_in_goal : Id.t -> Id.t list -> Id.t
+val next_ident_away_in_goal : Id.t -> Id.Set.t -> Id.t
(** Avoid clashing with a name already used in current module
but tolerate overwriting section variables, as in goals *)
-val next_global_ident_away : Id.t -> Id.t list -> Id.t
+val next_global_ident_away : Id.t -> Id.Set.t -> Id.t
(** Default is [default_non_dependent_ident] *)
-val next_name_away : Name.t -> Id.t list -> Id.t
+val next_name_away : Name.t -> Id.Set.t -> Id.t
-val next_name_away_with_default : string -> Name.t -> Id.t list ->
- Id.t
+val next_name_away_with_default : string -> Name.t -> Id.Set.t -> Id.t
val next_name_away_with_default_using_types : string -> Name.t ->
- Id.t list -> types -> Id.t
+ Id.Set.t -> types -> Id.t
val set_reserved_typed_name : (types -> Name.t) -> unit
@@ -103,13 +101,18 @@ type renaming_flags =
val make_all_name_different : env -> evar_map -> env
val compute_displayed_name_in :
- evar_map -> renaming_flags -> Id.t list -> Name.t -> constr -> Name.t * Id.t list
+ evar_map -> renaming_flags -> Id.Set.t -> Name.t -> constr -> Name.t * Id.Set.t
val compute_and_force_displayed_name_in :
- evar_map -> renaming_flags -> Id.t list -> Name.t -> constr -> Name.t * Id.t list
+ evar_map -> renaming_flags -> Id.Set.t -> Name.t -> constr -> Name.t * Id.Set.t
val compute_displayed_let_name_in :
- evar_map -> renaming_flags -> Id.t list -> Name.t -> constr -> Name.t * Id.t list
+ evar_map -> renaming_flags -> Id.Set.t -> Name.t -> 'a -> Name.t * Id.Set.t
val rename_bound_vars_as_displayed :
- evar_map -> Id.t list -> Name.t list -> types -> types
+ evar_map -> Id.Set.t -> Name.t list -> types -> types
+
+(* Generic function expecting a "not occurn" function *)
+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 *)
diff --git a/engine/nameops.ml b/engine/nameops.ml
new file mode 100644
index 0000000000..5105d7becc
--- /dev/null
+++ b/engine/nameops.ml
@@ -0,0 +1,216 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Util
+open Names
+
+(* Identifiers *)
+
+let pr_id id = Id.print id
+
+(* Utilities *)
+
+let code_of_0 = Char.code '0'
+let code_of_9 = Char.code '9'
+
+let cut_ident skip_quote s =
+ let s = Id.to_string s in
+ let slen = String.length s in
+ (* [n'] is the position of the first non nullary digit *)
+ let rec numpart n n' =
+ if Int.equal n 0 then
+ (* ident made of _ and digits only [and ' if skip_quote]: don't cut it *)
+ slen
+ else
+ let c = Char.code (String.get s (n-1)) in
+ if Int.equal c code_of_0 && not (Int.equal n slen) then
+ numpart (n-1) n'
+ else if code_of_0 <= c && c <= code_of_9 then
+ numpart (n-1) (n-1)
+ else if skip_quote && (Int.equal c (Char.code '\'') || Int.equal c (Char.code '_')) then
+ numpart (n-1) (n-1)
+ else
+ n'
+ in
+ numpart slen slen
+
+let repr_ident s =
+ let numstart = cut_ident false s in
+ let s = Id.to_string s in
+ let slen = String.length s in
+ if Int.equal numstart slen then
+ (s, None)
+ else
+ (String.sub s 0 numstart,
+ Some (int_of_string (String.sub s numstart (slen - numstart))))
+
+let make_ident sa = function
+ | Some n ->
+ let c = Char.code (String.get sa (String.length sa -1)) in
+ let s =
+ if c < code_of_0 || c > code_of_9 then sa ^ (string_of_int n)
+ else sa ^ "_" ^ (string_of_int n) in
+ Id.of_string s
+ | None -> Id.of_string sa
+
+let root_of_id id =
+ let suffixstart = cut_ident true id in
+ Id.of_string (String.sub (Id.to_string id) 0 suffixstart)
+
+(* Return the same identifier as the original one but whose {i subscript} is incremented.
+ If the original identifier does not have a suffix, [0] is appended to it.
+
+ Example mappings:
+
+ [bar] ↦ [bar0]
+ [bar0] ↦ [bar1]
+ [bar00] ↦ [bar01]
+ [bar1] ↦ [bar2]
+ [bar01] ↦ [bar01]
+ [bar9] ↦ [bar10]
+ [bar09] ↦ [bar10]
+ [bar99] ↦ [bar100]
+*)
+let increment_subscript id =
+ let id = Id.to_string id in
+ let len = String.length id in
+ let rec add carrypos =
+ let c = id.[carrypos] in
+ if is_digit c then
+ if Int.equal (Char.code c) (Char.code '9') then begin
+ assert (carrypos>0);
+ add (carrypos-1)
+ end
+ else begin
+ let newid = Bytes.of_string id in
+ Bytes.fill newid (carrypos+1) (len-1-carrypos) '0';
+ Bytes.set newid carrypos (Char.chr (Char.code c + 1));
+ newid
+ end
+ else begin
+ let newid = Bytes.of_string (id^"0") in
+ if carrypos < len-1 then begin
+ Bytes.fill newid (carrypos+1) (len-1-carrypos) '0';
+ Bytes.set newid (carrypos+1) '1'
+ end;
+ newid
+ end
+ in Id.of_bytes (add (len-1))
+
+let has_subscript id =
+ let id = Id.to_string id in
+ is_digit (id.[String.length id - 1])
+
+let forget_subscript id =
+ let numstart = cut_ident false id in
+ let newid = Bytes.make (numstart+1) '0' in
+ String.blit (Id.to_string id) 0 newid 0 numstart;
+ (Id.of_bytes newid)
+
+let add_suffix id s = Id.of_string (Id.to_string id ^ s)
+let add_prefix s id = Id.of_string (s ^ Id.to_string id)
+
+let atompart_of_id id = fst (repr_ident id)
+
+(* Names *)
+
+module type ExtName =
+sig
+
+ include module type of struct include Names.Name end
+
+ exception IsAnonymous
+
+ val fold_left : ('a -> Id.t -> 'a) -> 'a -> t -> 'a
+ val fold_right : (Id.t -> 'a -> 'a) -> t -> 'a -> 'a
+ val iter : (Id.t -> unit) -> t -> unit
+ val map : (Id.t -> Id.t) -> t -> t
+ val fold_left_map : ('a -> Id.t -> 'a * Id.t) -> 'a -> t -> 'a * t
+ val fold_right_map : (Id.t -> 'a -> Id.t * 'a) -> Name.t -> 'a -> Name.t * 'a
+ val get_id : t -> Id.t
+ val pick : t -> t -> t
+ val cons : t -> Id.t list -> Id.t list
+ val to_option : Name.t -> Id.t option
+
+end
+
+module Name : ExtName =
+struct
+
+ include Names.Name
+
+ exception IsAnonymous
+
+ let fold_left f a = function
+ | Name id -> f a id
+ | Anonymous -> a
+
+ let fold_right f na a =
+ match na with
+ | Name id -> f id a
+ | Anonymous -> a
+
+ let iter f na = fold_right (fun x () -> f x) na ()
+
+ let map f = function
+ | Name id -> Name (f id)
+ | Anonymous -> Anonymous
+
+ let fold_left_map f a = function
+ | Name id -> let (a, id) = f a id in (a, Name id)
+ | Anonymous -> a, Anonymous
+
+ let fold_right_map f na a = match na with
+ | Name id -> let (id, a) = f id a in (Name id, a)
+ | Anonymous -> Anonymous, a
+
+ let get_id = function
+ | Name id -> id
+ | Anonymous -> raise IsAnonymous
+
+ let pick na1 na2 =
+ match na1 with
+ | Name _ -> na1
+ | Anonymous -> na2
+
+ let cons na l =
+ match na with
+ | Anonymous -> l
+ | Name id -> id::l
+
+ let to_option = function
+ | Anonymous -> None
+ | Name id -> Some id
+
+end
+
+open Name
+
+(* Compatibility *)
+let out_name = get_id
+let name_fold = fold_right
+let name_iter = iter
+let name_app = map
+let name_fold_map = fold_left_map
+let name_cons = cons
+let name_max = pick
+let pr_name = print
+
+let pr_lab l = Label.print l
+
+(* Metavariables *)
+let pr_meta = Pp.int
+let string_of_meta = string_of_int
+
+(* Deprecated *)
+open Libnames
+let default_library = default_library
+let coq_string = coq_string
+let coq_root = coq_root
+let default_root_prefix = default_root_prefix
+
diff --git a/engine/nameops.mli b/engine/nameops.mli
new file mode 100644
index 0000000000..0fec8a925d
--- /dev/null
+++ b/engine/nameops.mli
@@ -0,0 +1,138 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+
+(** Identifiers and names *)
+
+val make_ident : string -> int option -> Id.t
+val repr_ident : Id.t -> string * int option
+
+val atompart_of_id : Id.t -> string (** remove trailing digits *)
+val root_of_id : Id.t -> Id.t (** remove trailing digits, ' and _ *)
+
+val add_suffix : Id.t -> string -> Id.t
+val add_prefix : string -> Id.t -> Id.t
+
+(** Below, by {i subscript} we mean a suffix composed solely from (decimal) digits. *)
+
+val has_subscript : Id.t -> bool
+
+val increment_subscript : Id.t -> Id.t
+(** Return the same identifier as the original one but whose {i subscript} is incremented.
+ If the original identifier does not have a suffix, [0] is appended to it.
+
+ Example mappings:
+
+ [bar] ↦ [bar0]
+
+ [bar0] ↦ [bar1]
+
+ [bar00] ↦ [bar01]
+
+ [bar1] ↦ [bar2]
+
+ [bar01] ↦ [bar01]
+
+ [bar9] ↦ [bar10]
+
+ [bar09] ↦ [bar10]
+
+ [bar99] ↦ [bar100]
+*)
+
+val forget_subscript : Id.t -> Id.t
+
+module Name : sig
+
+ include module type of struct include Names.Name end
+
+ exception IsAnonymous
+
+ val fold_left : ('a -> Id.t -> 'a) -> 'a -> Name.t -> 'a
+ (** [fold_left f na a] is [f id a] if [na] is [Name id], and [a] otherwise. *)
+
+ val fold_right : (Id.t -> 'a -> 'a) -> Name.t -> 'a -> 'a
+ (** [fold_right f a na] is [f a id] if [na] is [Name id], and [a] otherwise. *)
+
+ val iter : (Id.t -> unit) -> Name.t -> unit
+ (** [iter f na] does [f id] if [na] equals [Name id], nothing otherwise. *)
+
+ val map : (Id.t -> Id.t) -> Name.t -> t
+ (** [map f na] is [Anonymous] if [na] is [Anonymous] and [Name (f id)] if [na] is [Name id]. *)
+
+ val fold_left_map : ('a -> Id.t -> 'a * Id.t) -> 'a -> Name.t -> 'a * Name.t
+ (** [fold_left_map f a na] is [a',Name id'] when [na] is [Name id] and [f a id] is [(a',id')].
+ It is [a,Anonymous] otherwise. *)
+
+ val fold_right_map : (Id.t -> 'a -> Id.t * 'a) -> Name.t -> 'a -> Name.t * 'a
+ (** [fold_right_map f na a] is [Name id',a'] when [na] is [Name id] and [f id a] is [(id',a')].
+ It is [Anonymous,a] otherwise. *)
+
+ val get_id : Name.t -> Id.t
+ (** [get_id] associates [id] to [Name id]. @raise IsAnonymous otherwise. *)
+
+ val pick : Name.t -> Name.t -> Name.t
+ (** [pick na na'] returns [Anonymous] if both names are [Anonymous].
+ Pick one of [na] or [na'] otherwise. *)
+
+ val cons : Name.t -> Id.t list -> Id.t list
+ (** [cons na l] returns [id::l] if [na] is [Name id] and [l] otherwise. *)
+
+ val to_option : Name.t -> Id.t option
+ (** [to_option Anonymous] is [None] and [to_option (Name id)] is [Some id] *)
+
+end
+
+(** Metavariables *)
+val pr_meta : Constr.metavariable -> Pp.t
+val string_of_meta : Constr.metavariable -> string
+
+val out_name : Name.t -> Id.t
+[@@ocaml.deprecated "Same as [Name.get_id]"]
+
+val name_fold : (Id.t -> 'a -> 'a) -> Name.t -> 'a -> 'a
+[@@ocaml.deprecated "Same as [Name.fold_right]"]
+
+val name_iter : (Id.t -> unit) -> Name.t -> unit
+[@@ocaml.deprecated "Same as [Name.iter]"]
+
+val name_app : (Id.t -> Id.t) -> Name.t -> Name.t
+[@@ocaml.deprecated "Same as [Name.map]"]
+
+val name_fold_map : ('a -> Id.t -> 'a * Id.t) -> 'a -> Name.t -> 'a * Name.t
+[@@ocaml.deprecated "Same as [Name.fold_left_map]"]
+
+val name_max : Name.t -> Name.t -> Name.t
+[@@ocaml.deprecated "Same as [Name.pick]"]
+
+val name_cons : Name.t -> Id.t list -> Id.t list
+[@@ocaml.deprecated "Same as [Name.cons]"]
+
+val pr_name : Name.t -> Pp.t
+[@@ocaml.deprecated "Same as [Name.print]"]
+
+val pr_id : Id.t -> Pp.t
+[@@ocaml.deprecated "Same as [Names.Id.print]"]
+
+val pr_lab : Label.t -> Pp.t
+[@@ocaml.deprecated "Same as [Names.Label.print]"]
+
+(** Deprecated stuff to libnames *)
+val default_library : DirPath.t
+[@@ocaml.deprecated "Same as [Libnames.default_library]"]
+
+val coq_root : module_ident (** "Coq" *)
+[@@ocaml.deprecated "Same as [Libnames.coq_root]"]
+
+val coq_string : string (** "Coq" *)
+[@@ocaml.deprecated "Same as [Libnames.coq_string]"]
+
+val default_root_prefix : DirPath.t
+[@@ocaml.deprecated "Same as [Libnames.default_root_prefix]"]
+
diff --git a/engine/proofview.ml b/engine/proofview.ml
index eef2b83f44..0a64351950 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -153,8 +153,12 @@ let focus i j sp =
( { sp with comb = new_comb } , context )
(** [undefined defs l] is the list of goals in [l] which are still
- unsolved (after advancing cleared goals). *)
-let undefined defs l = CList.map_filter (Evarutil.advance defs) l
+ unsolved (after advancing cleared goals). Note that order matters. *)
+let undefined 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 []
(** Unfocuses a proofview with respect to a context. *)
let unfocus c sp =
@@ -630,32 +634,42 @@ let shelve_goals l =
InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_goals")) >>
Shelf.modify (fun gls -> gls @ l)
-(** [contained_in_info e evi] checks whether the evar [e] appears 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 contained_in_info sigma e evi =
- Evar.Set.mem e (Evd.evars_of_filtered_evar_info (Evarutil.nf_evar_info sigma evi))
-
(** [depends_on sigma src tgt] checks whether the goal [src] appears
as an existential variable in the definition of the goal [tgt] in
[sigma]. *)
let depends_on sigma src tgt =
let evi = Evd.find sigma tgt in
- contained_in_info sigma src evi
+ Evar.Set.mem src (Evd.evars_of_filtered_evar_info (Evarutil.nf_evar_info sigma evi))
+
+let unifiable_delayed g l =
+ CList.exists (fun (tgt, lazy evs) -> not (Evar.equal g tgt) && Evar.Set.mem g evs) l
+
+let free_evars 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 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 sigma g l =
- CList.exists (fun tgt -> not (Evar.equal g tgt) && depends_on sigma g tgt) l
+ let l = free_evars sigma l in
+ unifiable_delayed g l
(** [partition_unifiable sigma l] partitions [l] into a pair [(u,n)]
where [u] is composed of the unifiable goals, i.e. the goals on
whose definition other goals of [l] depend, and [n] are the
non-unifiable goals. *)
let partition_unifiable sigma l =
- CList.partition (fun g -> unifiable sigma g l) l
+ let fevs = free_evars sigma l in
+ CList.partition (fun g -> unifiable_delayed 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
@@ -1196,7 +1210,7 @@ module V82 = struct
{ Evd.it = comb ; sigma = solution }
let top_goals initial { solution=solution; } =
- let goals = CList.map (fun (t,_) -> fst (Term.destEvar (EConstr.Unsafe.to_constr t))) initial in
+ let goals = CList.map (fun (t,_) -> fst (Constr.destEvar (EConstr.Unsafe.to_constr t))) initial in
{ Evd.it = goals ; sigma=solution; }
let top_evars initial =
diff --git a/engine/proofview.mli b/engine/proofview.mli
index d92d0a7d53..59728a2fd1 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -25,7 +25,7 @@ type proofview
new nearly identical function everytime. Hence the generic name. *)
(* In this version: returns the list of focused goals together with
the [evar_map] context. *)
-val proofview : proofview -> Evd.evar list * Evd.evar_map
+val proofview : proofview -> Evar.t list * Evd.evar_map
(** {6 Starting and querying a proof view} *)
@@ -88,7 +88,7 @@ type focus_context
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). *)
-val focus_context : focus_context -> Evd.evar list * Evd.evar list
+val focus_context : focus_context -> Evar.t list * Evar.t list
(** [focus i j] focuses a proofview on the goals from index [i] to
index [j] (inclusive, goals are indexed from [1]). I.e. goals
@@ -148,7 +148,7 @@ type +'a tactic
{!Logic_monad.TacticFailure}*)
val apply : Environ.env -> 'a tactic -> proofview -> 'a
* proofview
- * (bool*Evd.evar list*Evd.evar list)
+ * (bool*Evar.t list*Evar.t list)
* Proofview_monad.Info.tree
(** {7 Monadic primitives} *)
@@ -304,12 +304,12 @@ val shelve : unit tactic
(** Shelves the given list of goals, which might include some that are
under focus and some that aren't. All the goals are placed on the
shelf for later use (or being solved by side-effects). *)
-val shelve_goals : Evd.evar list -> unit tactic
+val shelve_goals : Evar.t list -> unit tactic
(** [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. Used by [shelve_unifiable]. *)
-val unifiable : Evd.evar_map -> Evd.evar -> Evd.evar list -> bool
+val unifiable : Evd.evar_map -> Evar.t -> Evar.t list -> bool
(** Shelves the unifiable goals under focus, i.e. the goals which
appear in other goals under focus (the unfocused goals are not
@@ -322,15 +322,15 @@ val guard_no_unifiable : Names.Name.t list option tactic
(** [unshelve l p] adds all the goals in [l] at the end of the focused
goals of p *)
-val unshelve : Evd.evar list -> proofview -> proofview
+val unshelve : Evar.t list -> proofview -> proofview
(** [depends_on g1 g2 sigma] checks if g1 occurs in the type/ctx of g2 *)
-val depends_on : Evd.evar_map -> Evd.evar -> Evd.evar -> bool
+val depends_on : Evd.evar_map -> Evar.t -> Evar.t -> bool
(** [with_shelf tac] executes [tac] and returns its result together with
the set of goals shelved by [tac]. The current shelf is unchanged
and the returned list contains only unsolved goals. *)
-val with_shelf : 'a tactic -> (Evd.evar list * 'a) tactic
+val with_shelf : 'a tactic -> (Evar.t list * 'a) tactic
(** If [n] is positive, [cycle n] puts the [n] first goal last. If [n]
is negative, then it puts the [n] last goals first.*)
@@ -416,17 +416,17 @@ 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 : Evd.evar list -> unit tactic
+ val tclNEWGOALS : Evar.t 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 : Evd.evar list -> unit tactic
+ val tclSETGOALS : Evar.t list -> unit tactic
(** [tclGETGOALS] returns the list of goals under focus. *)
- val tclGETGOALS : Evd.evar list tactic
+ val tclGETGOALS : Evar.t list tactic
(** Sets the evar universe context. *)
- val tclEVARUNIVCONTEXT : Evd.evar_universe_context -> unit tactic
+ val tclEVARUNIVCONTEXT : UState.t -> unit tactic
(** Clears the future goals store in the proof view. *)
val reset_future_goals : proofview -> proofview
@@ -563,11 +563,12 @@ module V82 : sig
(* Returns the open goals of the proofview together with the evar_map to
interpret them. *)
val goals : proofview -> Evar.t list Evd.sigma
+ [@@ocaml.deprecated "Use [Proofview.proofview]"]
val top_goals : entry -> proofview -> Evar.t list Evd.sigma
-
+
(* returns the existential variable used to start the proof *)
- val top_evars : entry -> Evd.evar list
+ val top_evars : entry -> Evar.t list
(* Caution: this function loses quite a bit of information. It
should be avoided as much as possible. It should work as
diff --git a/engine/termops.ml b/engine/termops.ml
index 2bd0c06d6d..a71bdff31e 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -12,6 +12,7 @@ open Util
open Names
open Nameops
open Term
+open Constr
open Vars
open Environ
@@ -31,7 +32,7 @@ let pr_sort_family = function
| InProp -> (str "Prop")
| InType -> (str "Type")
-let pr_con sp = str(string_of_con sp)
+let pr_con sp = str(Constant.to_string sp)
let pr_fix pr_constr ((t,i),(lna,tl,bl)) =
let fixl = Array.mapi (fun i na -> (na,t.(i),tl.(i),bl.(i))) lna in
@@ -46,16 +47,16 @@ let pr_puniverses p u =
if Univ.Instance.is_empty u then p
else p ++ str"(*" ++ Univ.Instance.pr Universes.pr_with_global_universes u ++ str"*)"
-let rec pr_constr c = match kind_of_term c with
+let rec pr_constr c = match kind c with
| Rel n -> str "#"++int n
| Meta n -> str "Meta(" ++ int n ++ str ")"
- | Var id -> pr_id id
+ | Var id -> Id.print id
| Sort s -> print_sort s
| Cast (c,_, t) -> hov 1
(str"(" ++ pr_constr c ++ cut() ++
str":" ++ pr_constr t ++ str")")
| Prod (Name(id),t,c) -> hov 1
- (str"forall " ++ pr_id id ++ str":" ++ pr_constr t ++ str"," ++
+ (str"forall " ++ Id.print id ++ str":" ++ pr_constr t ++ str"," ++
spc() ++ pr_constr c)
| Prod (Anonymous,t,c) -> hov 0
(str"(" ++ pr_constr t ++ str " ->" ++ spc() ++
@@ -74,9 +75,9 @@ let rec pr_constr c = match kind_of_term c with
(str"Evar#" ++ int (Evar.repr e) ++ str"{" ++
prlist_with_sep spc pr_constr (Array.to_list l) ++str"}")
| Const (c,u) -> str"Cst(" ++ pr_puniverses (pr_con c) u ++ str")"
- | Ind ((sp,i),u) -> str"Ind(" ++ pr_puniverses (pr_mind sp ++ str"," ++ int i) u ++ str")"
+ | Ind ((sp,i),u) -> str"Ind(" ++ pr_puniverses (MutInd.print sp ++ str"," ++ int i) u ++ str")"
| Construct (((sp,i),j),u) ->
- str"Constr(" ++ pr_puniverses (pr_mind sp ++ str"," ++ int i ++ str"," ++ int j) u ++ str")"
+ str"Constr(" ++ pr_puniverses (MutInd.print sp ++ str"," ++ int i ++ str"," ++ int j) u ++ str")"
| Proj (p,c) -> str"Proj(" ++ pr_con (Projection.constant p) ++ str"," ++ bool (Projection.unfolded p) ++ pr_constr c ++ str")"
| Case (ci,p,c,bl) -> v 0
(hv 0 (str"<"++pr_constr p++str">"++ cut() ++ str"Case " ++
@@ -129,9 +130,9 @@ let pr_existential_key sigma evk =
let open Evd in
match evar_ident evk sigma with
| None ->
- str "?" ++ pr_id (pr_evar_suggested_name evk sigma)
+ str "?" ++ Id.print (pr_evar_suggested_name evk sigma)
| Some id ->
- str "?" ++ pr_id id
+ str "?" ++ Id.print id
let pr_instance_status (sc,typ) =
let open Evd in
@@ -157,7 +158,7 @@ let pr_meta_map evd =
let open Evd in
let print_constr = print_kconstr in
let pr_name = function
- Name id -> str"[" ++ pr_id id ++ str"]"
+ Name id -> str"[" ++ Id.print id ++ str"]"
| _ -> mt() in
let pr_meta_binding = function
| (mv,Cltyp (na,b)) ->
@@ -177,23 +178,23 @@ let pr_decl (decl,ok) =
let open NamedDecl in
let print_constr = print_kconstr in
match decl with
- | LocalAssum (id,_) -> if ok then pr_id id else (str "{" ++ pr_id id ++ str "}")
- | LocalDef (id,c,_) -> str (if ok then "(" else "{") ++ pr_id id ++ str ":=" ++
+ | LocalAssum (id,_) -> if ok then Id.print id else (str "{" ++ Id.print id ++ str "}")
+ | LocalDef (id,c,_) -> str (if ok then "(" else "{") ++ Id.print id ++ str ":=" ++
print_constr c ++ str (if ok then ")" else "}")
let pr_evar_source = function
- | Evar_kinds.NamedHole id -> pr_id id
+ | Evar_kinds.NamedHole id -> Id.print id
| Evar_kinds.QuestionMark _ -> str "underscore"
| Evar_kinds.CasesType false -> str "pattern-matching return predicate"
| Evar_kinds.CasesType true ->
str "subterm of pattern-matching return predicate"
- | Evar_kinds.BinderType (Name id) -> str "type of " ++ Nameops.pr_id id
+ | Evar_kinds.BinderType (Name id) -> str "type of " ++ Id.print id
| Evar_kinds.BinderType Anonymous -> str "type of anonymous binder"
| Evar_kinds.ImplicitArg (c,(n,ido),b) ->
let open Globnames in
let print_constr = print_kconstr in
let id = Option.get ido in
- str "parameter " ++ pr_id id ++ spc () ++ str "of" ++
+ str "parameter " ++ Id.print id ++ spc () ++ str "of" ++
spc () ++ print_constr (printable_constr_of_global c)
| Evar_kinds.InternalHole -> str "internal placeholder"
| Evar_kinds.TomatchTypeParameter (ind,n) ->
@@ -202,10 +203,9 @@ let pr_evar_source = function
| Evar_kinds.GoalEvar -> str "goal evar"
| Evar_kinds.ImpossibleCase -> str "type of impossible pattern-matching clause"
| Evar_kinds.MatchingVar _ -> str "matching variable"
- | Evar_kinds.VarInstance id -> str "instance of " ++ pr_id id
+ | Evar_kinds.VarInstance id -> str "instance of " ++ Id.print id
| Evar_kinds.SubEvar evk ->
- let open Evd in
- str "subterm of " ++ str (string_of_existential evk)
+ str "subterm of " ++ Evar.print evk
let pr_evar_info evi =
let open Evd in
@@ -288,6 +288,7 @@ let has_no_evar sigma =
with Exit -> false
let pr_evd_level evd = UState.pr_uctx_level (Evd.evar_universe_context evd)
+let reference_of_level evd l = UState.reference_of_level (Evd.evar_universe_context evd) l
let pr_evar_universe_context ctx =
let open UState in
@@ -327,11 +328,11 @@ let pr_evar_constraints sigma pbs =
Namegen.make_all_name_different env sigma
in
print_env_short env ++ spc () ++ str "|-" ++ spc () ++
- print_constr_env env sigma (EConstr.of_constr t1) ++ spc () ++
+ protect (print_constr_env env sigma) (EConstr.of_constr t1) ++ spc () ++
str (match pbty with
| Reduction.CONV -> "=="
| Reduction.CUMUL -> "<=") ++
- spc () ++ print_constr_env env Evd.empty (EConstr.of_constr t2)
+ spc () ++ protect (print_constr_env env Evd.empty) (EConstr.of_constr t2)
in
prlist_with_sep fnl pr_evconstr pbs
@@ -355,40 +356,40 @@ let pr_evar_map_gen with_univs pr_evars sigma =
let pr_evar_list sigma l =
let open Evd in
let pr (ev, evi) =
- h 0 (str (string_of_existential ev) ++
+ h 0 (Evar.print ev ++
str "==" ++ pr_evar_info evi ++
(if evi.evar_body == Evar_empty
- then str " {" ++ pr_existential_key sigma ev ++ str "}"
+ then str " {" ++ pr_existential_key sigma ev ++ str "}"
else mt ()))
in
h 0 (prlist_with_sep fnl pr l)
-let pr_evar_by_depth depth sigma = match depth with
-| None ->
- (* Print all evars *)
- let to_list d =
- let open Evd in
- (* Workaround for change in Map.fold behavior in ocaml 3.08.4 *)
- let l = ref [] in
- let fold_def evk evi () = match evi.evar_body with
+let to_list d =
+ let open Evd in
+ (* Workaround for change in Map.fold behavior in ocaml 3.08.4 *)
+ let l = ref [] in
+ let fold_def evk evi () = match evi.evar_body with
| Evar_defined _ -> l := (evk, evi) :: !l
| Evar_empty -> ()
- in
- let fold_undef evk evi () = match evi.evar_body with
+ in
+ let fold_undef evk evi () = match evi.evar_body with
| Evar_empty -> l := (evk, evi) :: !l
| Evar_defined _ -> ()
- in
- Evd.fold fold_def d ();
- Evd.fold fold_undef d ();
- !l
in
- str"EVARS:"++brk(0,1)++pr_evar_list sigma (to_list sigma)++fnl()
-| Some n ->
+ Evd.fold fold_def d ();
+ Evd.fold fold_undef d ();
+ !l
+
+let pr_evar_by_depth depth sigma = match depth with
+| None ->
(* Print all evars *)
+ str"EVARS:" ++ brk(0,1) ++ pr_evar_list sigma (to_list sigma) ++ fnl()
+| Some n ->
+ (* Print closure of undefined evars *)
str"UNDEFINED EVARS:"++
(if Int.equal n 0 then mt() else str" (+level "++int n++str" closure):")++
brk(0,1)++
- pr_evar_list sigma (evar_dependency_closure n sigma)++fnl()
+ pr_evar_list sigma (evar_dependency_closure n sigma) ++ fnl()
let pr_evar_by_filter filter sigma =
let open Evd in
@@ -434,7 +435,7 @@ let pr_var_decl env decl =
(str" := " ++ pb ++ cut () ) in
let pt = print_constr_env env Evd.empty (EConstr.of_constr (get_type decl)) in
let ptyp = (str" : " ++ pt) in
- (pr_id (get_id decl) ++ hov 0 (pbody ++ ptyp))
+ (Id.print (get_id decl) ++ hov 0 (pbody ++ ptyp))
let pr_rel_decl env decl =
let open RelDecl in
@@ -448,7 +449,7 @@ let pr_rel_decl env decl =
let ptyp = print_constr_env env Evd.empty (EConstr.of_constr (get_type decl)) in
match get_name decl with
| Anonymous -> hov 0 (str"<>" ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
- | Name id -> hov 0 (pr_id id ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
+ | Name id -> hov 0 (Id.print id ++ spc () ++ pbody ++ str":" ++ spc () ++ ptyp)
let print_named_context env =
hv 0 (fold_named_context
@@ -798,7 +799,7 @@ let fold_constr_with_binders sigma g f n acc c =
let iter_constr_with_full_binders g f l c =
let open RelDecl in
- match kind_of_term c with
+ match kind c with
| (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
| Construct _) -> ()
| Cast (c,_, t) -> f l c; f l t
@@ -983,9 +984,9 @@ let isMetaOf sigma mv c =
match EConstr.kind sigma c with Meta mv' -> Int.equal mv mv' | _ -> false
let rec subst_meta bl c =
- match kind_of_term c with
+ match kind c with
| Meta i -> (try Int.List.assoc i bl with Not_found -> c)
- | _ -> map_constr (subst_meta bl) c
+ | _ -> Constr.map (subst_meta bl) c
let rec strip_outer_cast sigma c = match EConstr.kind sigma c with
| Cast (c,_,_) -> strip_outer_cast sigma c
@@ -1071,9 +1072,9 @@ let replace_term_gen sigma eq_fun c by_c in_t =
let replace_term sigma c byc t = replace_term_gen sigma EConstr.eq_constr c byc t
let vars_of_env env =
- let s =
- Context.Named.fold_outside (fun decl s -> Id.Set.add (NamedDecl.get_id decl) s)
- (named_context env) ~init:Id.Set.empty in
+ let s = Environ.ids_of_named_context_val (Environ.named_context_val env) in
+ if List.is_empty (Environ.rel_context env) then s
+ else
Context.Rel.fold_outside
(fun decl s -> match RelDecl.get_name decl with Name id -> Id.Set.add id s | _ -> s)
(rel_context env) ~init:s
@@ -1165,6 +1166,24 @@ let rec is_Prop sigma c = match EConstr.kind sigma c with
| Cast (c,_,_) -> is_Prop sigma c
| _ -> false
+let rec is_Set sigma c = match EConstr.kind sigma c with
+ | Sort u ->
+ begin match EConstr.ESorts.kind sigma u with
+ | Prop Pos -> true
+ | _ -> false
+ end
+ | Cast (c,_,_) -> is_Set sigma c
+ | _ -> false
+
+let rec is_Type sigma c = match EConstr.kind sigma c with
+ | Sort u ->
+ begin match EConstr.ESorts.kind sigma u with
+ | Type _ -> true
+ | _ -> false
+ end
+ | Cast (c,_,_) -> is_Type sigma c
+ | _ -> false
+
(* eq_constr extended with universe erasure *)
let compare_constr_univ sigma f cv_pb t1 t2 =
let open EConstr in
diff --git a/engine/termops.mli b/engine/termops.mli
index 2624afd30d..c1600abe80 100644
--- a/engine/termops.mli
+++ b/engine/termops.mli
@@ -10,13 +10,13 @@
needed in the kernel. *)
open Names
-open Term
+open Constr
open Environ
open EConstr
(** printers *)
-val print_sort : sorts -> Pp.t
-val pr_sort_family : sorts_family -> Pp.t
+val print_sort : Sorts.t -> Pp.t
+val pr_sort_family : Sorts.family -> Pp.t
val pr_fix : ('a -> Pp.t) -> ('a, 'a) pfixpoint -> Pp.t
(** about contexts *)
@@ -91,7 +91,7 @@ exception Occur
val occur_meta : Evd.evar_map -> constr -> bool
val occur_existential : Evd.evar_map -> constr -> bool
val occur_meta_or_existential : Evd.evar_map -> constr -> bool
-val occur_evar : Evd.evar_map -> existential_key -> constr -> bool
+val occur_evar : Evd.evar_map -> Evar.t -> constr -> bool
val occur_var : env -> Evd.evar_map -> Id.t -> constr -> bool
val occur_var_in_decl :
env -> Evd.evar_map ->
@@ -113,6 +113,7 @@ val collect_metas : Evd.evar_map -> constr -> int list
val collect_vars : Evd.evar_map -> constr -> Id.Set.t (** for visible vars only *)
val vars_of_global_reference : env -> Globnames.global_reference -> Id.Set.t
val occur_term : Evd.evar_map -> constr -> constr -> bool (** Synonymous of dependent *)
+[@@ocaml.deprecated "alias of Termops.dependent"]
(* Substitution of metavariables *)
type meta_value_map = (metavariable * Constr.constr) list
@@ -147,7 +148,7 @@ val subst_term : Evd.evar_map -> constr -> constr -> constr
val replace_term : Evd.evar_map -> constr -> constr -> constr -> constr
(** Alternative term equalities *)
-val base_sort_cmp : Reduction.conv_pb -> sorts -> sorts -> bool
+val base_sort_cmp : Reduction.conv_pb -> Sorts.t -> Sorts.t -> bool
val compare_constr_univ : Evd.evar_map -> (Reduction.conv_pb -> constr -> constr -> bool) ->
Reduction.conv_pb -> constr -> constr -> bool
val constr_cmp : Evd.evar_map -> Reduction.conv_pb -> constr -> constr -> bool
@@ -267,6 +268,10 @@ val isGlobalRef : Evd.evar_map -> constr -> bool
val is_template_polymorphic : env -> Evd.evar_map -> constr -> bool
val is_Prop : Evd.evar_map -> constr -> bool
+val is_Set : Evd.evar_map -> constr -> bool
+val is_Type : Evd.evar_map -> constr -> bool
+
+val reference_of_level : Evd.evar_map -> Univ.Level.t -> Libnames.reference
(** Combinators on judgments *)
@@ -278,9 +283,9 @@ val on_judgment_type : ('t -> 't) -> ('c, 't) punsafe_judgment -> ('c, 't) puns
open Evd
-val pr_existential_key : evar_map -> evar -> Pp.t
+val pr_existential_key : evar_map -> Evar.t -> Pp.t
-val pr_evar_suggested_name : existential_key -> evar_map -> Id.t
+val pr_evar_suggested_name : Evar.t -> evar_map -> Id.t
val pr_evar_info : evar_info -> Pp.t
val pr_evar_constraints : evar_map -> evar_constraint list -> Pp.t
@@ -288,7 +293,7 @@ val pr_evar_map : ?with_univs:bool -> int option -> evar_map -> Pp.t
val pr_evar_map_filter : ?with_univs:bool -> (Evar.t -> evar_info -> bool) ->
evar_map -> Pp.t
val pr_metaset : Metaset.t -> Pp.t
-val pr_evar_universe_context : evar_universe_context -> Pp.t
+val pr_evar_universe_context : UState.t -> Pp.t
val pr_evd_level : evar_map -> Univ.Level.t -> Pp.t
(** debug printer: do not use to display terms to the casual user... *)
diff --git a/engine/uState.ml b/engine/uState.ml
index 63bd247d56..6131f4c033 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -11,32 +11,21 @@ open CErrors
open Util
open Names
-module StringOrd = struct type t = string let compare = String.compare end
-module UNameMap = struct
+module UNameMap = Names.Id.Map
- include Map.Make(StringOrd)
-
- let union s t =
- if s == t then s
- else
- merge (fun k l r ->
- match l, r with
- | Some _, _ -> l
- | _, _ -> r) s t
-end
-
type uinfo = {
- uname : string option;
+ uname : Id.t option;
uloc : Loc.t option;
}
(* 2nd part used to check consistency on the fly. *)
type t =
- { uctx_names : Univ.Level.t UNameMap.t * uinfo Univ.LMap.t;
- uctx_local : Univ.universe_context_set; (** The local context of variables *)
+ { uctx_names : Universes.universe_binders * uinfo Univ.LMap.t;
+ uctx_local : Univ.ContextSet.t; (** The local context of variables *)
+ uctx_seff_univs : Univ.LSet.t; (** Local universes used through private constants *)
uctx_univ_variables : Universes.universe_opt_subst;
(** The local universes that are unification variables *)
- uctx_univ_algebraic : Univ.universe_set;
+ uctx_univ_algebraic : Univ.LSet.t;
(** The subset of unification variables that can be instantiated with
algebraic universes as they appear in inferred types only. *)
uctx_universes : UGraph.t; (** The current graph extended with the local constraints *)
@@ -46,6 +35,7 @@ type t =
let empty =
{ uctx_names = UNameMap.empty, Univ.LMap.empty;
uctx_local = Univ.ContextSet.empty;
+ uctx_seff_univs = Univ.LSet.empty;
uctx_univ_variables = Univ.LMap.empty;
uctx_univ_algebraic = Univ.LSet.empty;
uctx_universes = UGraph.initial_universes;
@@ -59,12 +49,21 @@ let is_empty ctx =
Univ.ContextSet.is_empty ctx.uctx_local &&
Univ.LMap.is_empty ctx.uctx_univ_variables
+let uname_union s t =
+ if s == t then s
+ else
+ UNameMap.merge (fun k l r ->
+ match l, r with
+ | Some _, _ -> l
+ | _, _ -> r) s t
+
let union ctx ctx' =
if ctx == ctx' then ctx
else if is_empty ctx' then ctx
else
let local = Univ.ContextSet.union ctx.uctx_local ctx'.uctx_local in
- let names = UNameMap.union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
+ let seff = Univ.LSet.union ctx.uctx_seff_univs ctx'.uctx_seff_univs in
+ let names = uname_union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
let newus = Univ.LSet.diff (Univ.ContextSet.levels ctx'.uctx_local)
(Univ.ContextSet.levels ctx.uctx_local) in
let newus = Univ.LSet.diff newus (Univ.LMap.domain ctx.uctx_univ_variables) in
@@ -74,6 +73,7 @@ let union ctx ctx' =
let names_rev = Univ.LMap.union (snd ctx.uctx_names) (snd ctx'.uctx_names) in
{ uctx_names = (names, names_rev);
uctx_local = local;
+ uctx_seff_univs = seff;
uctx_univ_variables =
Univ.LMap.subst_union ctx.uctx_univ_variables ctx'.uctx_univ_variables;
uctx_univ_algebraic =
@@ -91,25 +91,31 @@ let constraints ctx = snd ctx.uctx_local
let context ctx = Univ.ContextSet.to_context ctx.uctx_local
+let const_univ_entry ~poly uctx =
+ let open Entries in
+ if poly then Polymorphic_const_entry (context uctx)
+ else Monomorphic_const_entry (context_set uctx)
+
+(* does not support cumulativity since you need more info *)
+let ind_univ_entry ~poly uctx =
+ let open Entries in
+ if poly then Polymorphic_ind_entry (context uctx)
+ else Monomorphic_ind_entry (context_set uctx)
+
let of_context_set ctx = { empty with uctx_local = ctx }
let subst ctx = ctx.uctx_univ_variables
let ugraph ctx = ctx.uctx_universes
-let algebraics ctx = ctx.uctx_univ_algebraic
+let initial_graph ctx = ctx.uctx_initial_universes
-let constrain_variables diff ctx =
- Univ.LSet.fold
- (fun l cstrs ->
- try
- match Univ.LMap.find l ctx.uctx_univ_variables with
- | Some u -> Univ.Constraint.add (l, Univ.Eq, Option.get (Univ.Universe.level u)) cstrs
- | None -> cstrs
- with Not_found | Option.IsNone -> cstrs)
- diff Univ.Constraint.empty
+let algebraics ctx = ctx.uctx_univ_algebraic
let add_uctx_names ?loc s l (names, names_rev) =
+ if UNameMap.mem s names
+ then user_err ?loc ~hdr:"add_uctx_names"
+ Pp.(str "Universe " ++ Names.Id.print s ++ str" already bound.");
(UNameMap.add s l names, Univ.LMap.add l { uname = Some s; uloc = loc } names_rev)
let add_uctx_loc l loc (names, names_rev) =
@@ -119,13 +125,17 @@ let add_uctx_loc l loc (names, names_rev) =
let of_binders b =
let ctx = empty in
- let names =
- List.fold_left (fun acc (id, l) -> add_uctx_names (Id.to_string id) l acc)
- ctx.uctx_names b
- in { ctx with uctx_names = names }
+ let rmap =
+ UNameMap.fold (fun id l rmap ->
+ Univ.LMap.add l { uname = Some id; uloc = None } rmap)
+ b Univ.LMap.empty
+ in
+ { ctx with uctx_names = b, rmap }
+
+let universe_binders ctx = fst ctx.uctx_names
let instantiate_variable l b v =
- try v := Univ.LMap.update l (Some b) !v
+ try v := Univ.LMap.set l (Some b) !v
with Not_found -> assert false
exception UniversesDiffer
@@ -230,8 +240,8 @@ let add_constraints ctx cstrs =
uctx_univ_variables = vars;
uctx_universes = UGraph.merge_constraints local' ctx.uctx_universes }
-(* let addconstrkey = Profile.declare_profile "add_constraints_context";; *)
-(* let add_constraints_context = Profile.profile2 addconstrkey add_constraints_context;; *)
+(* let addconstrkey = CProfile.declare_profile "add_constraints_context";; *)
+(* let add_constraints_context = CProfile.profile2 addconstrkey add_constraints_context;; *)
let add_universe_constraints ctx cstrs =
let univs, local = ctx.uctx_local in
@@ -240,53 +250,140 @@ let add_universe_constraints ctx cstrs =
uctx_univ_variables = vars;
uctx_universes = UGraph.merge_constraints local' ctx.uctx_universes }
-let pr_uctx_level uctx =
+let constrain_variables diff ctx =
+ let univs, local = ctx.uctx_local in
+ let univs, vars, local =
+ Univ.LSet.fold
+ (fun l (univs, vars, cstrs) ->
+ try
+ match Univ.LMap.find l vars with
+ | Some u ->
+ (Univ.LSet.add l univs,
+ Univ.LMap.remove l vars,
+ Univ.Constraint.add (l, Univ.Eq, Option.get (Univ.Universe.level u)) cstrs)
+ | None -> (univs, vars, cstrs)
+ with Not_found | Option.IsNone -> (univs, vars, cstrs))
+ diff (univs, ctx.uctx_univ_variables, local)
+ in
+ { ctx with uctx_local = (univs, local); uctx_univ_variables = vars }
+
+let reference_of_level uctx =
let map, map_rev = uctx.uctx_names in
fun l ->
- try str (Option.get (Univ.LMap.find l map_rev).uname)
+ try Libnames.Ident (Loc.tag @@ Option.get (Univ.LMap.find l map_rev).uname)
with Not_found | Option.IsNone ->
- Universes.pr_with_global_universes l
-
-let universe_context ?names ctx =
- match names with
- | None -> [], Univ.ContextSet.to_context ctx.uctx_local
- | Some pl ->
- let levels = Univ.ContextSet.levels ctx.uctx_local in
- let newinst, map, left =
- List.fold_right
- (fun (loc,id) (newinst, map, acc) ->
- let l =
- try UNameMap.find (Id.to_string id) (fst ctx.uctx_names)
- with Not_found ->
- user_err ?loc ~hdr:"universe_context"
- (str"Universe " ++ Nameops.pr_id id ++ str" is not bound anymore.")
- in (l :: newinst, (id, l) :: map, Univ.LSet.remove l acc))
- pl ([], [], levels)
- in
- if not (Univ.LSet.is_empty left) then
- let n = Univ.LSet.cardinal left in
- let loc =
- try
- let info =
- Univ.LMap.find (Univ.LSet.choose left) (snd ctx.uctx_names) in
- info.uloc
- with Not_found -> None
- in
- user_err ?loc ~hdr:"universe_context"
- ((str(CString.plural n "Universe") ++ spc () ++
- Univ.LSet.pr (pr_uctx_level ctx) left ++
- spc () ++ str (CString.conjugate_verb_to_be n) ++
- str" unbound."))
- else
- let inst = Univ.Instance.of_array (Array.of_list newinst) in
- let ctx = Univ.UContext.make (inst,
- Univ.ContextSet.constraints ctx.uctx_local)
- in map, ctx
+ Universes.reference_of_level l
+
+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
+
+let error_unbound_universes left uctx =
+ let open Univ in
+ let n = LSet.cardinal left in
+ let loc =
+ try
+ let info =
+ LMap.find (LSet.choose left) (snd uctx.uctx_names) in
+ info.uloc
+ with Not_found -> None
+ in
+ user_err ?loc ~hdr:"universe_context"
+ ((str(CString.plural n "Universe") ++ spc () ++
+ LSet.pr (pr_uctx_level uctx) left ++
+ spc () ++ str (CString.conjugate_verb_to_be n) ++
+ str" unbound."))
+
+let universe_context ~names ~extensible uctx =
+ let open Univ in
+ let levels = ContextSet.levels uctx.uctx_local in
+ let newinst, left =
+ List.fold_right
+ (fun (loc,id) (newinst, acc) ->
+ let l =
+ try UNameMap.find id (fst uctx.uctx_names)
+ with Not_found -> assert false
+ in (l :: newinst, LSet.remove l acc))
+ names ([], levels)
+ in
+ if not extensible && not (LSet.is_empty left)
+ then error_unbound_universes left uctx
+ else
+ let left = ContextSet.sort_levels (Array.of_list (LSet.elements left)) in
+ let inst = Array.append (Array.of_list newinst) left in
+ let inst = Instance.of_array inst in
+ let ctx = UContext.make (inst, ContextSet.constraints uctx.uctx_local) in
+ ctx
+
+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 l =
+ try UNameMap.find id (fst uctx.uctx_names)
+ with Not_found -> assert false
+ in LSet.remove l left)
+ (ContextSet.levels uctx.uctx_local) names
+ in
+ if not (LSet.is_empty left)
+ then error_unbound_universes left uctx
+
+let check_implication uctx cstrs cstrs' =
+ let gr = initial_graph uctx in
+ let grext = UGraph.merge_constraints cstrs gr in
+ if UGraph.check_constraints cstrs' grext then ()
+ else CErrors.user_err ~hdr:"check_univ_decl"
+ (str "Universe constraints are not implied by the ones declared.")
+
+let check_mono_univ_decl uctx decl =
+ let open Misctypes in
+ let () =
+ let names = decl.univdecl_instance in
+ let extensible = decl.univdecl_extensible_instance in
+ check_universe_context_set ~names ~extensible uctx
+ in
+ if not decl.univdecl_extensible_constraints then
+ check_implication uctx
+ decl.univdecl_constraints
+ (Univ.ContextSet.constraints uctx.uctx_local);
+ uctx.uctx_local
+
+let check_univ_decl ~poly uctx decl =
+ let open Misctypes in
+ let ctx =
+ let names = decl.univdecl_instance in
+ let extensible = decl.univdecl_extensible_instance in
+ if poly
+ then Entries.Polymorphic_const_entry (universe_context ~names ~extensible uctx)
+ else
+ let () = check_universe_context_set ~names ~extensible uctx in
+ Entries.Monomorphic_const_entry uctx.uctx_local
+ in
+ if not decl.univdecl_extensible_constraints then
+ check_implication uctx
+ decl.univdecl_constraints
+ (Univ.ContextSet.constraints uctx.uctx_local);
+ ctx
let restrict ctx vars =
+ let vars = Univ.LSet.union vars ctx.uctx_seff_univs in
+ let vars = Names.Id.Map.fold (fun na l vars -> Univ.LSet.add l vars)
+ (fst ctx.uctx_names) vars
+ in
let uctx' = Univops.restrict_universe_context ctx.uctx_local vars in
{ ctx with uctx_local = uctx' }
+let demote_seff_univs entry uctx =
+ let open Entries in
+ match entry.const_entry_universes with
+ | Polymorphic_const_entry _ -> uctx
+ | Monomorphic_const_entry (univs, _) ->
+ let seff = Univ.LSet.union uctx.uctx_seff_univs univs in
+ { uctx with uctx_seff_univs = seff }
+
type rigid =
| UnivRigid
| UnivFlexible of bool (** Is substitution by an algebraic ok? *)
@@ -348,7 +445,7 @@ let emit_side_effects eff u =
let new_univ_variable ?loc rigid name
({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
- let u = Universes.new_univ_level (Global.current_dirpath ()) in
+ let u = Universes.new_univ_level () in
let ctx' = Univ.ContextSet.add_universe u ctx in
let uctx', pred =
match rigid with
@@ -405,6 +502,9 @@ let make_flexible_variable ctx ~algebraic u =
{ctx with uctx_univ_variables = uvars';
uctx_univ_algebraic = avars'}
+let make_flexible_nonalgebraic ctx =
+ {ctx with uctx_univ_algebraic = Univ.LSet.empty}
+
let is_sort_variable uctx s =
match s with
| Sorts.Type u ->
@@ -465,7 +565,8 @@ let refresh_undefined_univ_variables uctx =
let initial = declare uctx.uctx_initial_universes in
let univs = declare UGraph.initial_universes in
let uctx' = {uctx_names = uctx.uctx_names;
- uctx_local = ctx';
+ uctx_local = ctx';
+ uctx_seff_univs = uctx.uctx_seff_univs;
uctx_univ_variables = vars; uctx_univ_algebraic = alg;
uctx_universes = univs;
uctx_initial_universes = initial } in
@@ -482,7 +583,8 @@ let normalize uctx =
Universes.refresh_constraints uctx.uctx_initial_universes us'
in
{ uctx_names = uctx.uctx_names;
- uctx_local = us';
+ uctx_local = us';
+ uctx_seff_univs = uctx.uctx_seff_univs; (* not sure about this *)
uctx_univ_variables = vars';
uctx_univ_algebraic = algs';
uctx_universes = universes;
@@ -491,10 +593,6 @@ let normalize uctx =
let universe_of_name uctx s =
UNameMap.find s (fst uctx.uctx_names)
-let add_universe_name uctx s l =
- let names' = add_uctx_names s l uctx.uctx_names in
- { uctx with uctx_names = names' }
-
let update_sigma_env uctx env =
let univs = Environ.universes env in
let eunivs =
diff --git a/engine/uState.mli b/engine/uState.mli
index d198fbfbe9..6657d6047d 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -28,13 +28,15 @@ val is_empty : t -> bool
val union : t -> t -> t
-val of_context_set : Univ.universe_context_set -> t
+val of_context_set : Univ.ContextSet.t -> t
val of_binders : Universes.universe_binders -> t
+val universe_binders : t -> Universes.universe_binders
+
(** {5 Projections} *)
-val context_set : t -> Univ.universe_context_set
+val context_set : t -> Univ.ContextSet.t
(** The local context of the state, i.e. a set of bound variables together
with their associated constraints. *)
@@ -44,39 +46,48 @@ val subst : t -> Universes.universe_opt_subst
val ugraph : t -> UGraph.t
(** The current graph extended with the local constraints *)
+val initial_graph : t -> UGraph.t
+(** The initial graph with just the declarations of new universes. *)
+
val algebraics : t -> Univ.LSet.t
(** The subset of unification variables that can be instantiated with algebraic
universes as they appear in inferred types only. *)
-val constraints : t -> Univ.constraints
+val constraints : t -> Univ.Constraint.t
(** Shorthand for {!context_set} composed with {!ContextSet.constraints}. *)
-val context : t -> Univ.universe_context
+val context : t -> Univ.UContext.t
(** Shorthand for {!context_set} with {!Context_set.to_context}. *)
+val const_univ_entry : poly:bool -> t -> Entries.constant_universes_entry
+(** Pick from {!context} or {!context_set} based on [poly]. *)
+
+val ind_univ_entry : poly:bool -> t -> Entries.inductive_universes
+(** Pick from {!context} or {!context_set} based on [poly].
+ Cannot create cumulative entries. *)
+
(** {5 Constraints handling} *)
-val add_constraints : t -> Univ.constraints -> t
+val add_constraints : t -> Univ.Constraint.t -> t
(**
@raise UniversesDiffer when universes differ
*)
-val add_universe_constraints : t -> Universes.universe_constraints -> t
+val add_universe_constraints : t -> Universes.Constraints.t -> t
(**
@raise UniversesDiffer when universes differ
*)
(** {5 Names} *)
-val add_universe_name : t -> string -> Univ.Level.t -> t
-(** Associate a human-readable name to a local variable. *)
-
-val universe_of_name : t -> string -> Univ.Level.t
+val universe_of_name : t -> Id.t -> Univ.Level.t
(** Retrieve the universe associated to the name. *)
(** {5 Unification} *)
-val restrict : t -> Univ.universe_set -> t
+val restrict : t -> Univ.LSet.t -> t
+
+val demote_seff_univs : Safe_typing.private_constants Entries.definition_entry -> t -> t
type rigid =
| UnivRigid
@@ -86,11 +97,11 @@ val univ_rigid : rigid
val univ_flexible : rigid
val univ_flexible_alg : rigid
-val merge : ?loc:Loc.t -> bool -> rigid -> t -> Univ.universe_context_set -> t
+val merge : ?loc:Loc.t -> bool -> rigid -> t -> Univ.ContextSet.t -> t
val merge_subst : t -> Universes.universe_opt_subst -> t
val emit_side_effects : Safe_typing.private_constants -> t -> t
-val new_univ_variable : ?loc:Loc.t -> rigid -> string option -> t -> t * Univ.Level.t
+val new_univ_variable : ?loc:Loc.t -> rigid -> Id.t option -> t -> t * Univ.Level.t
val add_global_univ : t -> Univ.Level.t -> t
(** [make_flexible_variable g algebraic l]
@@ -101,11 +112,16 @@ val add_global_univ : t -> Univ.Level.t -> t
universe. Otherwise the variable is just made flexible. *)
val make_flexible_variable : t -> algebraic:bool -> Univ.Level.t -> t
+(** Turn all undefined flexible algebraic variables into simply flexible
+ ones. Can be used in case the variables might appear in universe instances
+ (typically for polymorphic program obligations). *)
+val make_flexible_nonalgebraic : t -> t
+
val is_sort_variable : t -> Sorts.t -> Univ.Level.t option
val normalize_variables : t -> Univ.universe_subst * t
-val constrain_variables : Univ.LSet.t -> t -> Univ.constraints
+val constrain_variables : Univ.LSet.t -> t -> t
val abstract_undefined_variables : t -> t
@@ -115,12 +131,29 @@ val refresh_undefined_univ_variables : t -> t * Univ.universe_level_subst
val normalize : t -> t
-(** {5 TODO: Document me} *)
+type universe_decl =
+ (Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
+
+(** [check_univ_decl ctx decl]
+
+ If non extensible in [decl], check that the local universes (resp.
+ universe constraints) in [ctx] are implied by [decl].
+
+ Return a [Entries.constant_universes_entry] containing the local
+ universes of [ctx] and their constraints.
-val universe_context : ?names:(Id.t Loc.located) list -> t -> (Id.t * Univ.Level.t) list * Univ.universe_context
+ When polymorphic, the universes corresponding to
+ [decl.univdecl_instance] come first in the order defined by that
+ list. *)
+val check_univ_decl : poly:bool -> t -> universe_decl -> Entries.constant_universes_entry
+
+val check_mono_univ_decl : t -> universe_decl -> Univ.ContextSet.t
+
+(** {5 TODO: Document me} *)
val update_sigma_env : t -> Environ.env -> t
(** {5 Pretty-printing} *)
val pr_uctx_level : t -> Univ.Level.t -> Pp.t
+val reference_of_level : t -> Univ.Level.t -> Libnames.reference
diff --git a/engine/universes.ml b/engine/universes.ml
index 719af43edf..30490ec56a 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -6,32 +6,107 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Sorts
open Util
open Pp
open Names
-open Term
+open Constr
open Environ
open Univ
open Globnames
-
-let pr_with_global_universes l =
- try Nameops.pr_id (LMap.find l (snd (Global.global_universe_names ())))
- with Not_found -> Level.pr l
+open Nametab
+
+let reference_of_level l =
+ match Level.name l with
+ | Some (d, n as na) ->
+ let qid =
+ try Nametab.shortest_qualid_of_universe na
+ with Not_found ->
+ let name = Id.of_string_soft (string_of_int n) in
+ Libnames.make_qualid d name
+ in Libnames.Qualid (Loc.tag @@ qid)
+ | None -> Libnames.Ident (Loc.tag @@ Id.of_string_soft (Level.to_string l))
+
+let pr_with_global_universes l = Libnames.pr_reference (reference_of_level l)
+
+(** Global universe information outside the kernel, to handle
+ polymorphic universe names in sections that have to be discharged. *)
+
+let universe_map = (Summary.ref UnivIdMap.empty ~name:"global universe info" : bool Nametab.UnivIdMap.t ref)
+
+let add_global_universe u p =
+ match Level.name u with
+ | Some n -> universe_map := Nametab.UnivIdMap.add n p !universe_map
+ | None -> ()
+
+let is_polymorphic l =
+ match Level.name l with
+ | Some n ->
+ (try Nametab.UnivIdMap.find n !universe_map
+ with Not_found -> false)
+ | None -> false
(** Local universe names of polymorphic references *)
-type universe_binders = (Id.t * Univ.universe_level) list
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+let empty_binders = Id.Map.empty
let universe_binders_table = Summary.ref Refmap.empty ~name:"universe binders"
-let universe_binders_of_global ref =
+let universe_binders_of_global ref : universe_binders =
try
let l = Refmap.find ref !universe_binders_table in l
- with Not_found -> []
+ with Not_found -> Names.Id.Map.empty
-let register_universe_binders ref l =
+let cache_ubinder (_,(ref,l)) =
universe_binders_table := Refmap.add ref l !universe_binders_table
-
+
+let subst_ubinder (subst,(ref,l as orig)) =
+ let ref' = fst (Globnames.subst_global subst ref) in
+ if ref == ref' then orig else ref', l
+
+let discharge_ubinder (_,(ref,l)) =
+ Some (Lib.discharge_global ref, l)
+
+let ubinder_obj : Globnames.global_reference * universe_binders -> Libobject.obj =
+ let open Libobject in
+ declare_object { (default_object "universe binder") with
+ cache_function = cache_ubinder;
+ load_function = (fun _ x -> cache_ubinder x);
+ classify_function = (fun x -> Substitute x);
+ subst_function = subst_ubinder;
+ discharge_function = discharge_ubinder;
+ rebuild_function = (fun x -> x); }
+
+let register_universe_binders ref ubinders =
+ let open Names in
+ (* Add the polymorphic (section) universes *)
+ let ubinders = UnivIdMap.fold (fun lvl poly ubinders ->
+ let qid = Nametab.shortest_qualid_of_universe lvl in
+ let level = Level.make (fst lvl) (snd lvl) in
+ if poly then Id.Map.add (snd (Libnames.repr_qualid qid)) level ubinders
+ else ubinders)
+ !universe_map ubinders
+ in
+ 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
+
+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
+ | Anonymous -> acc
+ | Name na -> Names.Id.Map.add na lvl acc)
+ empty_binders udecl levels
+ else
+ CErrors.user_err ~hdr:"universe_binders_with_opt_names"
+ Pp.(str "Universe instance should have length " ++ int (List.length levels))
+
(* To disallow minimization to Set *)
let set_minimization = ref true
@@ -39,7 +114,7 @@ let is_set_minimization () = !set_minimization
type universe_constraint_type = ULe | UEq | ULub
-type universe_constraint = universe * universe_constraint_type * universe
+type universe_constraint = Universe.t * universe_constraint_type * Universe.t
module Constraints = struct
module S = Set.Make(
@@ -131,47 +206,6 @@ let to_constraints g s =
"to_constraints: non-trivial algebraic constraint between universes")
in Constraints.fold tr s Constraint.empty
-let test_constr_univs_infer leq univs fold m n accu =
- if m == n then Some accu
- else
- let cstrs = ref accu in
- let eq_universes strict l l' = UGraph.check_eq_instances univs l l' in
- let eq_sorts s1 s2 =
- if Sorts.equal s1 s2 then true
- else
- let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- match fold (Constraints.singleton (u1, UEq, u2)) !cstrs with
- | None -> false
- | Some accu -> cstrs := accu; true
- in
- let leq_sorts s1 s2 =
- if Sorts.equal s1 s2 then true
- else
- let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- match fold (Constraints.singleton (u1, ULe, u2)) !cstrs with
- | None -> false
- | Some accu -> cstrs := accu; true
- in
- let rec eq_constr' m n =
- m == n || Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
- in
- let res =
- if leq then
- let rec compare_leq m n =
- Constr.compare_head_gen_leq eq_universes leq_sorts
- eq_constr' leq_constr' m n
- and leq_constr' m n = m == n || compare_leq m n in
- compare_leq m n
- else Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
- in
- if res then Some !cstrs else None
-
-let eq_constr_univs_infer univs fold m n accu =
- test_constr_univs_infer false univs fold m n accu
-
-let leq_constr_univs_infer univs fold m n accu =
- test_constr_univs_infer true univs fold m n accu
-
(** Variant of [eq_constr_univs_infer] taking kind-of-term functions,
to expose subterms of [m] and [n], arguments. *)
let eq_constr_univs_infer_with kind1 kind2 univs fold m n accu =
@@ -197,48 +231,12 @@ let eq_constr_univs_infer_with kind1 kind2 univs fold m n accu =
let res = Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' m n in
if res then Some !cstrs else None
-let test_constr_universes leq m n =
- if m == n then Some Constraints.empty
- else
- let cstrs = ref Constraints.empty in
- let eq_universes strict l l' =
- cstrs := enforce_eq_instances_univs strict l l' !cstrs; true in
- let eq_sorts s1 s2 =
- if Sorts.equal s1 s2 then true
- else (cstrs := Constraints.add
- (Sorts.univ_of_sort s1,UEq,Sorts.univ_of_sort s2) !cstrs;
- true)
- in
- let leq_sorts s1 s2 =
- if Sorts.equal s1 s2 then true
- else
- (cstrs := Constraints.add
- (Sorts.univ_of_sort s1,ULe,Sorts.univ_of_sort s2) !cstrs;
- true)
- in
- let rec eq_constr' m n =
- m == n || Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
- in
- let res =
- if leq then
- let rec compare_leq m n =
- Constr.compare_head_gen_leq eq_universes leq_sorts eq_constr' leq_constr' m n
- and leq_constr' m n = m == n || compare_leq m n in
- compare_leq m n
- else
- Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
- in
- if res then Some !cstrs else None
-
-let eq_constr_universes m n = test_constr_universes false m n
-let leq_constr_universes m n = test_constr_universes true m n
-
let compare_head_gen_proj env equ eqs eqc' m n =
- match kind_of_term m, kind_of_term n with
+ match kind m, kind n with
| Proj (p, c), App (f, args)
| App (f, args), Proj (p, c) ->
- (match kind_of_term f with
- | Const (p', u) when eq_constant (Projection.constant p) p' ->
+ (match kind f with
+ | Const (p', u) when Constant.equal (Projection.constant p) p' ->
let pb = Environ.lookup_projection p env in
let npars = pb.Declarations.proj_npars in
if Array.length args == npars + 1 then
@@ -267,14 +265,17 @@ let eq_constr_universes_proj env m n =
res, !cstrs
(* Generator of levels *)
-let new_univ_level, set_remote_new_univ_level =
+type universe_id = DirPath.t * int
+
+let new_univ_id, set_remote_new_univ_id =
RemoteCounter.new_counter ~name:"Universes" 0 ~incr:((+) 1)
- ~build:(fun n -> Univ.Level.make (Global.current_dirpath ()) n)
+ ~build:(fun n -> Global.current_dirpath (), n)
-let new_univ_level _ = new_univ_level ()
- (* Univ.Level.make db (new_univ_level ()) *)
+let new_univ_level () =
+ let dp, id = new_univ_id () in
+ Univ.Level.make dp id
-let fresh_level () = new_univ_level (Global.current_dirpath ())
+let fresh_level () = new_univ_level ()
(* TODO: remove *)
let new_univ dp = Univ.Universe.make (new_univ_level dp)
@@ -282,7 +283,7 @@ let new_Type dp = mkType (new_univ dp)
let new_Type_sort dp = Type (new_univ dp)
let fresh_universe_instance ctx =
- let init _ = new_univ_level (Global.current_dirpath ()) in
+ let init _ = new_univ_level () in
Instance.of_array (Array.init (AUContext.size ctx) init)
let fresh_instance_from_context ctx =
@@ -293,7 +294,7 @@ let fresh_instance_from_context ctx =
let fresh_instance ctx =
let ctx' = ref LSet.empty in
let init _ =
- let u = new_univ_level (Global.current_dirpath ()) in
+ let u = new_univ_level () in
ctx' := LSet.add u !ctx'; u
in
let inst = Instance.of_array (Array.init (AUContext.size ctx) init)
@@ -405,7 +406,7 @@ let fresh_global_or_constr_instance env = function
| IsGlobal gr -> fresh_global_instance env gr
let global_of_constr c =
- match kind_of_term c with
+ match kind c with
| Const (c, u) -> ConstRef c, u
| Ind (i, u) -> IndRef i, u
| Construct (c, u) -> ConstructRef c, u
@@ -467,8 +468,8 @@ let type_of_reference env r =
let type_of_global t = type_of_reference (Global.env ()) t
let fresh_sort_in_family env = function
- | InProp -> prop_sort, ContextSet.empty
- | InSet -> set_sort, ContextSet.empty
+ | InProp -> Sorts.prop, ContextSet.empty
+ | InSet -> Sorts.set, ContextSet.empty
| InType ->
let u = fresh_level () in
Type (Univ.Universe.make u), ContextSet.singleton u
@@ -490,7 +491,7 @@ module LevelUnionFind = Unionfind.Make (Univ.LSet) (Univ.LMap)
let add_list_map u t map =
try
let l = LMap.find u map in
- LMap.update u (t :: l) map
+ LMap.set u (t :: l) map
with Not_found ->
LMap.add u [t] map
@@ -526,7 +527,7 @@ 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 rec aux c =
- match kind_of_term c with
+ match kind c with
| Evar (evk, args) ->
let args = Array.map aux args in
(match try f (evk, args) with Not_found -> None with
@@ -544,7 +545,7 @@ let nf_evars_and_universes_opt_subst f subst =
| Sort (Type u) ->
let u' = Univ.subst_univs_universe subst u in
if u' == u then c else mkSort (sort_of_univ u')
- | _ -> map_constr aux c
+ | _ -> Constr.map aux c
in aux
let fresh_universe_context_set_instance ctx =
@@ -583,7 +584,7 @@ let normalize_univ_variable_subst subst =
let find l = Univ.LMap.find l !subst in
let update l b =
assert (match Universe.level b with Some l' -> not (Level.equal l l') | None -> true);
- try subst := Univ.LMap.update l b !subst; b with Not_found -> assert false in
+ try subst := Univ.LMap.set l b !subst; b with Not_found -> assert false in
normalize_univ_variable ~find ~update
let normalize_universe_opt_subst subst =
@@ -603,7 +604,7 @@ let normalize_opt_subst ctx =
else try ignore(normalize u) with Not_found -> assert(false)) ctx
in !ectx
-type universe_opt_subst = universe option universe_map
+type universe_opt_subst = Universe.t option universe_map
let make_opt_subst s =
fun x ->
@@ -865,7 +866,7 @@ let normalize_context_set ctx us algs =
(* We first put constraints in a normal-form: all self-loops are collapsed
to equalities. *)
let g = Univ.LSet.fold (fun v g -> UGraph.add_universe v false g)
- ctx UGraph.empty_universes
+ ctx UGraph.initial_universes
in
let g =
Univ.Constraint.fold
@@ -945,8 +946,8 @@ let normalize_context_set ctx us algs =
let us = normalize_opt_subst us in
(us, algs), (ctx', Constraint.union noneqs eqs)
-(* let normalize_conkey = Profile.declare_profile "normalize_context_set" *)
-(* let normalize_context_set a b c = Profile.profile3 normalize_conkey normalize_context_set a b c *)
+(* let normalize_conkey = CProfile.declare_profile "normalize_context_set" *)
+(* let normalize_context_set a b c = CProfile.profile3 normalize_conkey normalize_context_set a b c *)
let is_trivial_leq (l,d,r) =
Univ.Level.is_prop l && (d == Univ.Le || (d == Univ.Lt && Univ.Level.is_set r))
diff --git a/engine/universes.mli b/engine/universes.mli
index fe40f82385..1a98d969b4 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -8,7 +8,7 @@
open Util
open Names
-open Term
+open Constr
open Environ
open Univ
@@ -18,29 +18,52 @@ val is_set_minimization : unit -> bool
(** Universes *)
val pr_with_global_universes : Level.t -> Pp.t
+val reference_of_level : Level.t -> Libnames.reference
+
+(** Global universe information outside the kernel, to handle
+ polymorphic universes in sections that have to be discharged. *)
+val add_global_universe : Level.t -> Decl_kinds.polymorphic -> unit
+
+val is_polymorphic : Level.t -> bool
(** Local universe name <-> level mapping *)
-type universe_binders = (Id.t * Univ.universe_level) list
-
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+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
+
+(** [universe_binders_with_opt_names ref u l]
+
+ If [l] is [Some univs] return the universe binders naming the levels of [u] by [univs] (skipping Anonymous).
+ May error if the lengths mismatch.
+
+ Otherwise return [universe_binders_of_global ref]. *)
+val universe_binders_with_opt_names : Globnames.global_reference ->
+ Univ.Level.t list -> univ_name_list option -> universe_binders
+
(** The global universe counter *)
-val set_remote_new_univ_level : universe_level RemoteCounter.installer
+type universe_id = DirPath.t * int
+
+val set_remote_new_univ_id : universe_id RemoteCounter.installer
(** Side-effecting functions creating new universe levels. *)
-val new_univ_level : Names.dir_path -> universe_level
-val new_univ : Names.dir_path -> universe
-val new_Type : Names.dir_path -> types
-val new_Type_sort : Names.dir_path -> sorts
+val new_univ_id : unit -> universe_id
+val new_univ_level : unit -> Level.t
+val new_univ : unit -> Universe.t
+val new_Type : unit -> types
+val new_Type_sort : unit -> Sorts.t
-val new_global_univ : unit -> universe in_universe_context_set
-val new_sort_in_family : sorts_family -> sorts
+val new_global_univ : unit -> Universe.t in_universe_context_set
+val new_sort_in_family : Sorts.family -> Sorts.t
(** {6 Constraints for type inference}
-
+
When doing conversion of universes, not only do we have =/<= constraints but
also Lub constraints which correspond to unification of two levels which might
not be necessary if unfolding is performed.
@@ -48,29 +71,26 @@ val new_sort_in_family : sorts_family -> sorts
type universe_constraint_type = ULe | UEq | ULub
-type universe_constraint = universe * universe_constraint_type * universe
+type universe_constraint = Universe.t * universe_constraint_type * Universe.t
module Constraints : sig
include Set.S with type elt = universe_constraint
-
+
val pr : t -> Pp.t
end
type universe_constraints = Constraints.t
-type 'a constraint_accumulator = universe_constraints -> 'a -> 'a option
-type 'a universe_constrained = 'a * universe_constraints
-type 'a universe_constraint_function = 'a -> 'a -> universe_constraints -> universe_constraints
+[@@ocaml.deprecated "Use Constraints.t"]
-val subst_univs_universe_constraints : universe_subst_fn ->
- universe_constraints -> universe_constraints
+type 'a constraint_accumulator = Constraints.t -> 'a -> 'a option
+type 'a universe_constrained = 'a * Constraints.t
+type 'a universe_constraint_function = 'a -> 'a -> Constraints.t -> Constraints.t
-val enforce_eq_instances_univs : bool -> universe_instance universe_constraint_function
+val subst_univs_universe_constraints : universe_subst_fn ->
+ Constraints.t -> Constraints.t
-val to_constraints : UGraph.t -> universe_constraints -> constraints
+val enforce_eq_instances_univs : bool -> Instance.t universe_constraint_function
-(** [eq_constr_univs_infer u a b] is [true, c] if [a] equals [b] modulo alpha, casts,
- application grouping, the universe constraints in [u] and additional constraints [c]. *)
-val eq_constr_univs_infer : UGraph.t -> 'a constraint_accumulator ->
- constr -> constr -> 'a -> 'a option
+val to_constraints : UGraph.t -> Constraints.t -> Constraint.t
(** [eq_constr_univs_infer_With kind1 kind2 univs m n] is a variant of
{!eq_constr_univs_infer} taking kind-of-term functions, to expose
@@ -80,20 +100,6 @@ val eq_constr_univs_infer_with :
(constr -> (constr, types, Sorts.t, Univ.Instance.t) kind_of_term) ->
UGraph.t -> 'a constraint_accumulator -> constr -> constr -> 'a -> 'a option
-(** [leq_constr_univs u a b] is [true, c] if [a] is convertible to [b]
- modulo alpha, casts, application grouping, the universe constraints
- in [u] and additional constraints [c]. *)
-val leq_constr_univs_infer : UGraph.t -> 'a constraint_accumulator ->
- constr -> constr -> 'a -> 'a option
-
-(** [eq_constr_universes a b] [true, c] if [a] equals [b] modulo alpha, casts,
- application grouping and the universe constraints in [c]. *)
-val eq_constr_universes : constr -> constr -> universe_constraints option
-
-(** [leq_constr_universes a b] [true, c] if [a] is convertible to [b] modulo
- alpha, casts, application grouping and the universe constraints in [c]. *)
-val leq_constr_universes : constr -> constr -> universe_constraints option
-
(** [eq_constr_universes a b] [true, c] if [a] equals [b] modulo alpha, casts,
application grouping and the universe constraints in [c]. *)
val eq_constr_universes_proj : env -> constr -> constr -> bool universe_constrained
@@ -101,15 +107,15 @@ val eq_constr_universes_proj : env -> constr -> constr -> bool universe_constrai
(** Build a fresh instance for a given context, its associated substitution and
the instantiated constraints. *)
-val fresh_instance_from_context : abstract_universe_context ->
- universe_instance constrained
+val fresh_instance_from_context : AUContext.t ->
+ Instance.t constrained
-val fresh_instance_from : abstract_universe_context -> universe_instance option ->
- universe_instance in_universe_context_set
+val fresh_instance_from : AUContext.t -> Instance.t option ->
+ Instance.t in_universe_context_set
-val fresh_sort_in_family : env -> sorts_family ->
- sorts in_universe_context_set
-val fresh_constant_instance : env -> constant ->
+val fresh_sort_in_family : env -> Sorts.family ->
+ Sorts.t in_universe_context_set
+val fresh_constant_instance : env -> Constant.t ->
pconstant in_universe_context_set
val fresh_inductive_instance : env -> inductive ->
pinductive in_universe_context_set
@@ -124,15 +130,15 @@ val fresh_global_or_constr_instance : env -> Globnames.global_reference_or_const
(** Get fresh variables for the universe context.
Useful to make tactics that manipulate constrs in universe contexts polymorphic. *)
-val fresh_universe_context_set_instance : universe_context_set ->
- universe_level_subst * universe_context_set
+val fresh_universe_context_set_instance : ContextSet.t ->
+ universe_level_subst * ContextSet.t
(** Raises [Not_found] if not a global reference. *)
val global_of_constr : constr -> Globnames.global_reference puniverses
val constr_of_global_univ : Globnames.global_reference puniverses -> constr
-val extend_context : 'a in_universe_context_set -> universe_context_set ->
+val extend_context : 'a in_universe_context_set -> ContextSet.t ->
'a in_universe_context_set
(** Simplification and pruning of constraints:
@@ -146,38 +152,38 @@ val extend_context : 'a in_universe_context_set -> universe_context_set ->
(a global one if there is one) and transitively saturate
the constraints w.r.t to the equalities. *)
-module UF : Unionfind.PartitionSig with type elt = universe_level
+module UF : Unionfind.PartitionSig with type elt = Level.t
-type universe_opt_subst = universe option universe_map
+type universe_opt_subst = Universe.t option universe_map
val make_opt_subst : universe_opt_subst -> universe_subst_fn
val subst_opt_univs_constr : universe_opt_subst -> constr -> constr
-val normalize_context_set : universe_context_set ->
+val normalize_context_set : ContextSet.t ->
universe_opt_subst (* The defined and undefined variables *) ->
- universe_set (* univ variables that can be substituted by algebraics *) ->
- (universe_opt_subst * universe_set) in_universe_context_set
+ LSet.t (* univ variables that can be substituted by algebraics *) ->
+ (universe_opt_subst * LSet.t) in_universe_context_set
val normalize_univ_variables : universe_opt_subst ->
- universe_opt_subst * universe_set * universe_set * universe_subst
+ universe_opt_subst * LSet.t * LSet.t * universe_subst
val normalize_univ_variable :
- find:(universe_level -> universe) ->
- update:(universe_level -> universe -> universe) ->
- universe_level -> universe
+ find:(Level.t -> Universe.t) ->
+ update:(Level.t -> Universe.t -> Universe.t) ->
+ Level.t -> Universe.t
val normalize_univ_variable_opt_subst : universe_opt_subst ref ->
- (universe_level -> universe)
+ (Level.t -> Universe.t)
val normalize_univ_variable_subst : universe_subst ref ->
- (universe_level -> universe)
+ (Level.t -> Universe.t)
val normalize_universe_opt_subst : universe_opt_subst ref ->
- (universe -> universe)
+ (Universe.t -> Universe.t)
val normalize_universe_subst : universe_subst ref ->
- (universe -> universe)
+ (Universe.t -> Universe.t)
(** Create a fresh global in the global environment, without side effects.
BEWARE: this raises an ANOMALY on polymorphic constants/inductives:
@@ -188,6 +194,7 @@ val constr_of_global : Globnames.global_reference -> constr
(** ** DEPRECATED ** synonym of [constr_of_global] *)
val constr_of_reference : Globnames.global_reference -> constr
+[@@ocaml.deprecated "synonym of [constr_of_global]"]
(** Returns the type of the global reference, by creating a fresh instance of polymorphic
references and computing their instantiated universe context. (side-effect on the
@@ -199,7 +206,7 @@ val type_of_global : Globnames.global_reference -> types in_universe_context_set
val nf_evars_and_universes_opt_subst : (existential -> constr option) ->
universe_opt_subst -> constr -> constr
-val refresh_constraints : UGraph.t -> universe_context_set -> universe_context_set * UGraph.t
+val refresh_constraints : UGraph.t -> ContextSet.t -> ContextSet.t * UGraph.t
(** Pretty-printing *)
@@ -207,11 +214,11 @@ val pr_universe_opt_subst : universe_opt_subst -> Pp.t
(** {6 Support for template polymorphism } *)
-val solve_constraints_system : universe option array -> universe array -> universe array ->
- universe array
+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 : universe_context -> cumulativity_info
+val univ_inf_ind_from_universe_context : UContext.t -> CumulativityInfo.t
diff --git a/engine/univops.ml b/engine/univops.ml
new file mode 100644
index 0000000000..df25d87252
--- /dev/null
+++ b/engine/univops.ml
@@ -0,0 +1,111 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Univ
+open Constr
+
+let universes_of_constr env c =
+ let open Declarations in
+ let rec aux s c =
+ match kind c with
+ | Const (c, u) ->
+ begin match (Environ.lookup_constant c env).const_universes with
+ | Polymorphic_const _ ->
+ LSet.fold LSet.add (Instance.levels u) s
+ | Monomorphic_const (univs, _) ->
+ LSet.union s univs
+ end
+ | Ind ((mind,_), u) | Construct (((mind,_),_), u) ->
+ begin match (Environ.lookup_mind mind env).mind_universes with
+ | Cumulative_ind _ | Polymorphic_ind _ ->
+ LSet.fold LSet.add (Instance.levels u) s
+ | Monomorphic_ind (univs,_) ->
+ LSet.union s univs
+ end
+ | Sort u when not (Sorts.is_small u) ->
+ let u = Sorts.univ_of_sort u in
+ LSet.fold LSet.add (Universe.levels u) s
+ | _ -> Constr.fold aux s c
+ in aux LSet.empty c
+
+type graphnode = {
+ mutable up : constraint_type LMap.t;
+ mutable visited : bool
+}
+
+let merge_types d d0 =
+ match d, d0 with
+ | _, Lt | Lt, _ -> Lt
+ | Le, _ | _, Le -> Le
+ | Eq, Eq -> Eq
+
+let merge_up d b up =
+ let find = try Some (LMap.find b up) with Not_found -> None in
+ match find with
+ | Some d0 ->
+ let d = merge_types d d0 in
+ if d == d0 then up else LMap.add b d up
+ | None -> LMap.add b d up
+
+let add_up a d b graph =
+ let node, graph =
+ try LMap.find a graph, graph
+ with Not_found ->
+ let node = { up = LMap.empty; visited = false } in
+ node, LMap.add a node graph
+ in
+ node.up <- merge_up d b node.up;
+ graph
+
+(* for each node transitive close until you find a non removable, discard the rest *)
+let transitive_close removable graph =
+ let rec do_node a node =
+ if not node.visited
+ then
+ let keepup =
+ LMap.fold (fun b d keepup ->
+ if not (LSet.mem b removable)
+ then merge_up d b keepup
+ else
+ begin
+ match LMap.find b graph with
+ | bnode ->
+ do_node b bnode;
+ LMap.fold (fun k d' keepup ->
+ merge_up (merge_types d d') k keepup)
+ bnode.up keepup
+ | exception Not_found -> keepup
+ end
+ )
+ node.up LMap.empty
+ in
+ node.up <- keepup;
+ node.visited <- true
+ in
+ LMap.iter do_node graph
+
+let restrict_universe_context (univs,csts) keep =
+ let removable = LSet.diff univs keep in
+ let (csts, rem) =
+ Constraint.fold (fun (a,d,b as cst) (csts, rem) ->
+ if LSet.mem a removable || LSet.mem b removable
+ then (csts, add_up a d b rem)
+ else (Constraint.add cst csts, rem))
+ csts (Constraint.empty, LMap.empty)
+ in
+ transitive_close removable rem;
+ let csts =
+ LMap.fold (fun a node csts ->
+ if LSet.mem a removable
+ then csts
+ else
+ LMap.fold (fun b d csts -> Constraint.add (a,d,b) csts)
+ node.up csts)
+ rem csts
+ in
+ (LSet.inter univs keep, csts)
diff --git a/engine/univops.mli b/engine/univops.mli
new file mode 100644
index 0000000000..30fcc43681
--- /dev/null
+++ b/engine/univops.mli
@@ -0,0 +1,16 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Constr
+open Univ
+
+(** The universes of monomorphic constants appear. *)
+val universes_of_constr : Environ.env -> constr -> LSet.t
+
+(** Shrink a universe context to a restricted set of variables *)
+val restrict_universe_context : ContextSet.t -> LSet.t -> ContextSet.t