aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cClosure.ml7
-rw-r--r--kernel/constr.ml28
-rw-r--r--kernel/constr.mli9
-rw-r--r--kernel/nativecode.ml43
-rw-r--r--kernel/nativelambda.ml8
-rw-r--r--kernel/uGraph.ml54
-rw-r--r--kernel/uGraph.mli10
7 files changed, 136 insertions, 23 deletions
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index 4da5f0f383..1d8861cbc0 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -1051,7 +1051,12 @@ let norm_val info tab v =
let inject c = mk_clos (subs_id 0) c
-let whd_stack infos tab m stk =
+let whd_stack infos tab m stk = match m.norm with
+| Whnf | Norm ->
+ (** No need to perform [kni] nor to unlock updates because
+ every head subterm of [m] is [Whnf] or [Norm] *)
+ knh infos m stk
+| Red | Cstr ->
let k = kni infos tab m stk in
let () = if !share then ignore (fapp_stack k) in (* to unlock Zupdates! *)
k
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 8f83d6baac..c11b9ebf46 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -479,6 +479,34 @@ let iter_with_binders g f n c = match kind c with
Array.Fun1.iter f n tl;
Array.Fun1.iter f (iterate g (Array.length tl) n) bl
+(* [fold_constr_with_binders g f n acc c] folds [f n] on the immediate
+ subterms of [c] starting from [acc] and proceeding from left to
+ right according to the usual representation of the constructions as
+ [fold_constr] but it carries an extra data [n] (typically a lift
+ index) which is processed by [g] (which typically add 1 to [n]) at
+ each binder traversal; it is not recursive *)
+
+let fold_constr_with_binders g f n acc c =
+ match kind c with
+ | (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _
+ | Construct _) -> acc
+ | Cast (c,_, t) -> f n (f n acc c) t
+ | Prod (na,t,c) -> f (g n) (f n acc t) c
+ | Lambda (na,t,c) -> f (g n) (f n acc t) c
+ | LetIn (na,b,t,c) -> f (g n) (f n (f n acc b) t) c
+ | App (c,l) -> Array.fold_left (f n) (f n acc c) l
+ | Proj (p,c) -> f n acc c
+ | Evar (_,l) -> Array.fold_left (f n) acc l
+ | Case (_,p,c,bl) -> Array.fold_left (f n) (f n (f n acc p) c) bl
+ | Fix (_,(lna,tl,bl)) ->
+ let n' = CArray.fold_left2 (fun c n t -> g c) n lna tl in
+ let fd = Array.map2 (fun t b -> (t,b)) tl bl in
+ Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
+ | CoFix (_,(lna,tl,bl)) ->
+ let n' = CArray.fold_left2 (fun c n t -> g c) n lna tl in
+ let fd = Array.map2 (fun t b -> (t,b)) tl bl in
+ Array.fold_left (fun acc (t,b) -> f n' (f n acc t) b) acc fd
+
(* [map f c] maps [f] on the immediate subterms of [c]; it is
not recursive and the order with which subterms are processed is
not specified *)
diff --git a/kernel/constr.mli b/kernel/constr.mli
index b35ea66536..742a13919a 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -402,6 +402,15 @@ val iter : (constr -> unit) -> constr -> unit
val iter_with_binders :
('a -> 'a) -> ('a -> constr -> unit) -> 'a -> constr -> unit
+(** [iter_with_binders g f n c] iters [f n] on the immediate
+ subterms of [c]; it carries an extra data [n] (typically a lift
+ index) which is processed by [g] (which typically add 1 to [n]) at
+ each binder traversal; it is not recursive and the order with which
+ subterms are processed is not specified *)
+
+val fold_constr_with_binders :
+ ('a -> 'a) -> ('a -> 'b -> constr -> 'b) -> 'a -> 'b -> constr -> 'b
+
type constr_compare_fn = int -> constr -> constr -> bool
(** [compare_head f c1 c2] compare [c1] and [c2] using [f] to compare
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 036cd4847e..5174eeea8e 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -2017,21 +2017,22 @@ let compile_mind_deps env prefix ~interactive
(* This function compiles all necessary dependencies of t, and generates code in
reverse order, as well as linking information updates *)
-let rec compile_deps env sigma prefix ~interactive init t =
+let compile_deps env sigma prefix ~interactive init t =
+ let rec aux env lvl init t =
match kind t with
| Ind ((mind,_),u) -> compile_mind_deps env prefix ~interactive init mind
| Const c ->
- let c,u = get_alias env c in
- let cb,(nameref,_) = lookup_constant_key c env in
- let (_, (_, const_updates)) = init in
- if is_code_loaded ~interactive nameref
- || (Cmap_env.mem c const_updates)
- then init
- else
+ let c,u = get_alias env c in
+ let cb,(nameref,_) = lookup_constant_key c env in
+ let (_, (_, const_updates)) = init in
+ if is_code_loaded ~interactive nameref
+ || (Cmap_env.mem c const_updates)
+ then init
+ else
let comp_stack, (mind_updates, const_updates) =
match cb.const_proj, cb.const_body with
| false, Def t ->
- compile_deps env sigma prefix ~interactive init (Mod_subst.force_constr t)
+ aux env lvl init (Mod_subst.force_constr t)
| true, _ ->
let pb = lookup_projection (Projection.make c false) env in
let mind = pb.proj_ind in
@@ -2047,12 +2048,30 @@ let rec compile_deps env sigma prefix ~interactive init t =
| Construct (((mind,_),_),u) -> compile_mind_deps env prefix ~interactive init mind
| Proj (p,c) ->
let term = mkApp (mkConst (Projection.constant p), [|c|]) in
- compile_deps env sigma prefix ~interactive init term
+ aux env lvl init term
| Case (ci, p, c, ac) ->
let mind = fst ci.ci_ind in
let init = compile_mind_deps env prefix ~interactive init mind in
- Constr.fold (compile_deps env sigma prefix ~interactive) init t
- | _ -> Constr.fold (compile_deps env sigma prefix ~interactive) init t
+ fold_constr_with_binders succ (aux env) lvl init t
+ | Var id ->
+ let open Context.Named.Declaration in
+ begin match lookup_named id env with
+ | LocalDef (_,t,_) ->
+ aux env lvl init t
+ | _ -> init
+ end
+ | Rel n when n > lvl ->
+ let open Context.Rel.Declaration in
+ let decl = lookup_rel n env in
+ let env = env_of_rel n env in
+ begin match decl with
+ | LocalDef (_,t,_) ->
+ aux env lvl init t
+ | LocalAssum _ -> init
+ end
+ | _ -> fold_constr_with_binders succ (aux env) lvl init t
+ in
+ aux env 0 init t
let compile_constant_field env prefix con acc cb =
let (gl, _) =
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index 8b61ed0c5a..6db75c89ae 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -296,15 +296,17 @@ let is_value lc =
match lc with
| Lval _ -> true
| Lmakeblock(_,_,_,args) when Array.is_empty args -> true
+ | Luint (UintVal _) -> true
| _ -> false
-
+
let get_value lc =
match lc with
| Lval v -> v
- | Lmakeblock(_,_,tag,args) when Array.is_empty args ->
+ | Lmakeblock(_,_,tag,args) when Array.is_empty args ->
Nativevalues.mk_int tag
+ | Luint (UintVal i) -> Nativevalues.mk_uint i
| _ -> raise Not_found
-
+
let make_args start _end =
Array.init (start - _end + 1) (fun i -> Lrel (Anonymous, start - i))
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index e6b27077ba..4a9467de52 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -503,7 +503,7 @@ let insert_edge strict ucan vcan g =
let () = cleanup_universes g in
raise e
-let add_universe vlev strict g =
+let add_universe_gen vlev g =
try
let _arcv = UMap.find vlev g.entries in
raise AlreadyDeclared
@@ -520,8 +520,14 @@ let add_universe vlev strict g =
}
in
let entries = UMap.add vlev (Canonical v) g.entries in
- let g = { entries; index = g.index - 1; n_nodes = g.n_nodes + 1; n_edges = g.n_edges } in
- insert_edge strict (get_set_arc g) v g
+ { entries; index = g.index - 1; n_nodes = g.n_nodes + 1; n_edges = g.n_edges }, v
+
+let add_universe vlev strict g =
+ let g, v = add_universe_gen vlev g in
+ insert_edge strict (get_set_arc g) v g
+
+let add_universe_unconstrained vlev g =
+ fst (add_universe_gen vlev g)
exception Found_explanation of explanation
@@ -696,6 +702,9 @@ let enforce_univ_lt u v g =
error_inconsistency Lt u v (get_explanation false v u g)
let empty_universes =
+ { entries = UMap.empty; index = 0; n_nodes = 0; n_edges = 0 }
+
+let initial_universes =
let set_arc = Canonical {
univ = Level.set;
ltle = LMap.empty;
@@ -718,9 +727,6 @@ let empty_universes =
let empty = { entries; index = (-2); n_nodes = 2; n_edges = 0 } in
enforce_univ_lt Level.prop Level.set empty
-(* Prop = Set is forbidden here. *)
-let initial_universes = empty_universes
-
let is_initial_universes g = UMap.equal (==) g.entries initial_universes.entries
let enforce_constraint cst g =
@@ -780,6 +786,42 @@ let constraints_of_universes g =
let csts = UMap.fold constraints_of g.entries Constraint.empty in
csts, UF.partition uf
+(* domain g.entries = kept + removed *)
+let constraints_for ~kept g =
+ (* rmap: partial map from canonical universes to kept universes *)
+ let rmap, csts = LSet.fold (fun u (rmap,csts) ->
+ let arcu = repr g u in
+ if LSet.mem arcu.univ kept then
+ LMap.add arcu.univ arcu.univ rmap, enforce_eq_level u arcu.univ csts
+ else
+ match LMap.find arcu.univ rmap with
+ | v -> rmap, enforce_eq_level u v csts
+ | exception Not_found -> LMap.add arcu.univ u rmap, csts)
+ kept (LMap.empty,Constraint.empty)
+ in
+ let rec add_from u csts todo = match todo with
+ | [] -> csts
+ | (v,strict)::todo ->
+ let v = repr g v in
+ (match LMap.find v.univ rmap with
+ | v ->
+ let d = if strict then Lt else Le in
+ let csts = Constraint.add (u,d,v) csts in
+ add_from u csts todo
+ | exception Not_found ->
+ (* v is not equal to any kept universe *)
+ let todo = LMap.fold (fun v' strict' todo ->
+ (v',strict || strict') :: todo)
+ v.ltle todo
+ in
+ add_from u csts todo)
+ in
+ LSet.fold (fun u csts ->
+ let arc = repr g u in
+ LMap.fold (fun v strict csts -> add_from u csts [v,strict])
+ arc.ltle csts)
+ kept csts
+
(** [sort_universes g] builds a totally ordered universe graph. The
output graph should imply the input graph (and the implication
will be strict most of the time), but is not necessarily minimal.
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
index cca2eb472b..e6dd629e45 100644
--- a/kernel/uGraph.mli
+++ b/kernel/uGraph.mli
@@ -49,13 +49,15 @@ exception AlreadyDeclared
val add_universe : Level.t -> bool -> t -> t
+(** Add a universe without (Prop,Set) <= u *)
+val add_universe_unconstrained : Level.t -> t -> t
+
(** {6 Pretty-printing of universes. } *)
val pr_universes : (Level.t -> Pp.t) -> t -> Pp.t
(** The empty graph of universes *)
val empty_universes : t
-[@@ocaml.deprecated "Use UGraph.initial_universes"]
val sort_universes : t -> t
@@ -64,6 +66,12 @@ val sort_universes : t -> t
of the universes into equivalence classes. *)
val constraints_of_universes : t -> Constraint.t * LSet.t list
+(** [constraints_for ~kept g] returns the constraints about the
+ universes [kept] in [g] up to transitivity.
+
+ eg if [g] is [a <= b <= c] then [constraints_for ~kept:{a, c} g] is [a <= c]. *)
+val constraints_for : kept:LSet.t -> t -> Constraint.t
+
val check_subtype : AUContext.t check_function
(** [check_subtype univ ctx1 ctx2] checks whether [ctx2] is an instance of
[ctx1]. *)