aboutsummaryrefslogtreecommitdiffhomepage
path: root/kernel/environ.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/environ.ml')
-rw-r--r--kernel/environ.ml144
1 files changed, 116 insertions, 28 deletions
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 41b664309..3563a1340 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -23,10 +23,13 @@ type compilation_unit_name = dir_path * checksum
type global = Constant | Inductive
+type key = (bool*int) option ref
+type constant_key = constant_body * key
+
type engagement = ImpredicativeSet
type globals = {
- env_constants : constant_body KNmap.t;
+ env_constants : constant_key KNmap.t;
env_inductives : mutual_inductive_body KNmap.t;
env_modules : module_body MPmap.t;
env_modtypes : module_type_body KNmap.t }
@@ -36,10 +39,20 @@ type stratification = {
env_engagement : engagement option
}
-type env = {
- env_globals : globals;
- env_named_context : named_context;
- env_rel_context : rel_context;
+type 'a val_kind =
+ | VKvalue of values
+ | VKaxiom of 'a
+ | VKdef of constr * env
+
+and 'a lazy_val = 'a val_kind ref
+
+and env = {
+ env_globals : globals;
+ env_named_context : named_context;
+ env_named_val : (identifier * (identifier lazy_val)) list;
+ env_rel_context : rel_context;
+ env_rel_val : inv_rel_key lazy_val list;
+ env_nb_rel : int;
env_stratification : stratification }
let empty_env = {
@@ -49,11 +62,16 @@ let empty_env = {
env_modules = MPmap.empty;
env_modtypes = KNmap.empty };
env_named_context = empty_named_context;
+ env_named_val = [];
env_rel_context = empty_rel_context;
+ env_rel_val = [];
+ env_nb_rel = 0;
env_stratification = {
env_universes = initial_universes;
env_engagement = None } }
+
+
let engagement env = env.env_stratification.env_engagement
let universes env = env.env_stratification.env_universes
let named_context env = env.env_named_context
@@ -63,6 +81,9 @@ let empty_context env =
env.env_rel_context = empty_rel_context
&& env.env_named_context = empty_named_context
+exception NotEvaluated
+exception AllReadyEvaluated
+
(* Rel context *)
let lookup_rel n env =
Sign.lookup_rel n env.env_rel_context
@@ -75,68 +96,135 @@ let evaluable_rel n env =
with Not_found ->
false
+let nb_rel env = env.env_nb_rel
+
let push_rel d env =
+ let _,body,_ = d in
+ let rval =
+ match body with
+ | None -> ref (VKaxiom env.env_nb_rel)
+ | Some c -> ref (VKdef(c,env))
+ in
{ env with
- env_rel_context = add_rel_decl d env.env_rel_context }
+ env_rel_context = add_rel_decl d env.env_rel_context;
+ env_rel_val = rval :: env.env_rel_val;
+ env_nb_rel = env.env_nb_rel + 1 }
+
let push_rel_context ctxt x = Sign.fold_rel_context push_rel ctxt ~init:x
+
let push_rec_types (lna,typarray,_) env =
let ctxt =
array_map2_i
(fun i na t -> (na, None, type_app (lift i) t)) lna typarray in
Array.fold_left (fun e assum -> push_rel assum e) env ctxt
-
+
let reset_rel_context env =
{ env with
- env_rel_context = empty_rel_context }
+ env_rel_context = empty_rel_context;
+ env_rel_val = [];
+ env_nb_rel = 0 }
let fold_rel_context f env ~init =
snd (Sign.fold_rel_context
(fun d (env,e) -> (push_rel d env, f env d e))
(rel_context env) ~init:(reset_rel_context env,init))
-
-
+
+(* Abstract machine rel values *)
+type relval = int lazy_val
+
+let kind_of_rel r = !r
+
+let set_relval r v =
+ match !r with
+ | VKvalue _ -> raise AllReadyEvaluated
+ | _ -> r := VKvalue v
+
+let lookup_relval n env =
+ try List.nth env.env_rel_val (n - 1)
+ with _ -> raise Not_found
+
(* Named context *)
let lookup_named id env =
Sign.lookup_named id env.env_named_context
+
-(* A local const is evaluable if it is defined and not opaque *)
+
+(* A local const is evaluable if it is defined *)
let evaluable_named id env =
try
match lookup_named id env with
- (_,Some _,_) -> true
- | _ -> false
+ (_,Some _,_) -> true
+ | _ -> false
with Not_found ->
false
-
-let push_named d env =
- { env with
- env_named_context = Sign.add_named_decl d env.env_named_context }
+
+let push_named d env =
+ let id,body,_ = d in
+ let rval =
+ match body with
+ | None -> ref (VKaxiom id)
+ | Some c -> ref (VKdef(c,env))
+ in
+ { env with
+ env_named_context = Sign.add_named_decl d env.env_named_context;
+ env_named_val = (id,rval):: env.env_named_val }
let reset_context env =
{ env with
- env_named_context = empty_named_context;
- env_rel_context = empty_rel_context }
+ env_named_context = empty_named_context;
+ env_named_val = [];
+ env_rel_context = empty_rel_context;
+ env_rel_val = [];
+ env_nb_rel = 0 }
let reset_with_named_context ctxt env =
- { env with
- env_named_context = ctxt;
- env_rel_context = empty_rel_context }
-
+ Sign.fold_named_context push_named ctxt ~init:(reset_context env)
+
let fold_named_context f env ~init =
snd (Sign.fold_named_context
(fun d (env,e) -> (push_named d env, f env d e))
(named_context env) ~init:(reset_context env,init))
-
+
let fold_named_context_reverse f ~init env =
Sign.fold_named_context_reverse f ~init:init (named_context env)
-
+
+(* Abstract machine values of local vars referred by names *)
+type namedval = identifier lazy_val
+
+let kind_of_named r = !r
+
+let set_namedval r v =
+ match !r with
+ | VKvalue _ -> raise AllReadyEvaluated
+ | _ -> r := VKvalue v
+
+let lookup_namedval id env =
+ snd (List.find (fun (id',_) -> id = id') env.env_named_val)
+
(* Global constants *)
-let lookup_constant kn env =
+
+let notevaluated = None
+
+let constant_key_pos (cb,r) =
+ match !r with
+ | None -> raise NotEvaluated
+ | Some key -> key
+
+let constant_key_body = fst
+
+let set_pos_constant (cb,r) bpos =
+ if !r = notevaluated then r := Some bpos
+ else raise AllReadyEvaluated
+
+let lookup_constant_key kn env =
KNmap.find kn env.env_globals.env_constants
-let add_constant kn cb env =
- let new_constants = KNmap.add kn cb env.env_globals.env_constants in
+let lookup_constant kn env = constant_key_body (lookup_constant_key kn env)
+
+let add_constant kn cs env =
+ let new_constants =
+ KNmap.add kn (cs,ref notevaluated) env.env_globals.env_constants in
let new_globals =
{ env.env_globals with
env_constants = new_constants } in