aboutsummaryrefslogtreecommitdiffhomepage
path: root/kernel/closure.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/closure.ml')
-rw-r--r--kernel/closure.ml200
1 files changed, 81 insertions, 119 deletions
diff --git a/kernel/closure.ml b/kernel/closure.ml
index 283b60e28..4bb9c941f 100644
--- a/kernel/closure.ml
+++ b/kernel/closure.ml
@@ -13,9 +13,7 @@ open Pp
open Term
open Names
open Environ
-open Instantiate
open Univ
-open Evd
open Esubst
@@ -67,7 +65,6 @@ module type RedFlagsSig = sig
type reds
type red_kind
val fBETA : red_kind
- val fEVAR : red_kind
val fDELTA : red_kind
val fIOTA : red_kind
val fZETA : red_kind
@@ -96,11 +93,10 @@ module RedFlags = (struct
r_evar : bool;
r_iota : bool }
- type red_kind = BETA | DELTA | EVAR | IOTA | ZETA
+ type red_kind = BETA | DELTA | IOTA | ZETA
| CONST of constant | VAR of identifier
let fBETA = BETA
let fDELTA = DELTA
- let fEVAR = EVAR
let fIOTA = IOTA
let fZETA = ZETA
let fCONST sp = CONST sp
@@ -120,7 +116,6 @@ module RedFlags = (struct
let (l1,l2) = red.r_const in
{ red with r_const = l1, Sppred.add sp l2 }
| IOTA -> { red with r_iota = true }
- | EVAR -> { red with r_evar = true }
| ZETA -> { red with r_zeta = true }
| VAR id ->
let (l1,l2) = red.r_const in
@@ -133,7 +128,6 @@ module RedFlags = (struct
let (l1,l2) = red.r_const in
{ red with r_const = l1, Sppred.remove sp l2 }
| IOTA -> { red with r_iota = false }
- | EVAR -> { red with r_evar = false }
| ZETA -> { red with r_zeta = false }
| VAR id ->
let (l1,l2) = red.r_const in
@@ -155,7 +149,6 @@ module RedFlags = (struct
let c = Idpred.mem id l in
incr_cnt c delta
| ZETA -> incr_cnt red.r_zeta zeta
- | EVAR -> incr_cnt red.r_zeta evar
| IOTA -> incr_cnt red.r_iota iota
| DELTA -> (* Used for Rel/Var defined in context *)
incr_cnt red.r_delta delta
@@ -174,7 +167,8 @@ end : RedFlagsSig)
open RedFlags
-let betadeltaiota_red = mkflags [fBETA;fDELTA;fZETA;fEVAR;fIOTA]
+let betadeltaiota_red = mkflags [fBETA;fDELTA;fZETA;fIOTA]
+let betadeltaiotanolet_red = mkflags [fBETA;fDELTA;fIOTA]
let betaiota_red = mkflags [fBETA;fIOTA]
let beta_red = mkflags [fBETA]
let betaiotazeta_red = mkflags [fBETA;fIOTA;fZETA]
@@ -248,7 +242,7 @@ let unfold_red sp =
a LetIn expression is Letin reduction *)
type red_kind =
- BETA | DELTA | ZETA | EVAR | IOTA
+ BETA | DELTA | ZETA | IOTA
| CONST of constant_path list | CONSTBUT of constant_path list
| VAR of identifier | VARBUT of identifier
@@ -270,7 +264,6 @@ let rec red_add red = function
{ red with r_const = true, list_union cl l1, l2;
r_zeta = true; r_evar = true })
| IOTA -> { red with r_iota = true }
- | EVAR -> { red with r_evar = true }
| ZETA -> { red with r_zeta = true }
| VAR id ->
(match red.r_const with
@@ -331,6 +324,7 @@ let no_flag = (UNIFORM,no_red)
let beta = (UNIFORM,beta_red)
let betaiota = (UNIFORM,betaiota_red)
let betadeltaiota = (UNIFORM,betadeltaiota_red)
+let betadeltaiotanolet = (UNIFORM,betadeltaiotanolet_red)
let hnf_flags = (SIMPL,betaiotazeta_red)
let unfold_flags sp = (UNIFORM, unfold_red sp)
@@ -362,7 +356,6 @@ let red_under (md,r) rk =
* mapped to constr. 'a infos implements a cache for constants and
* abstractions, storing a representation (of type 'a) of the body of
* this constant or abstraction.
- * * i_evc is the set of constraints for existential variables
* * i_tab is the cache table of the results
* * i_repr is the function to get the representation from the current
* state of the cache and the body of the constant. The result
@@ -379,20 +372,19 @@ let red_under (md,r) rk =
* instantiations (cbv or lazy) are.
*)
-type 'a table_key =
- | ConstBinding of constant
- | EvarBinding of existential
- | VarBinding of identifier
- | FarRelBinding of int
+type table_key =
+ | ConstKey of constant
+ | VarKey of identifier
+ | FarRelKey of int
+ (* FarRel: index in the rel_context part of _initial_ environment *)
-type ('a, 'b) infos = {
+type 'a infos = {
i_flags : flags;
- i_repr : ('a, 'b) infos -> constr -> 'a;
+ i_repr : 'a infos -> constr -> 'a;
i_env : env;
- i_evc : 'b evar_map;
i_rels : int * (int * constr) list;
i_vars : (identifier * constr) list;
- i_tab : ('a table_key, 'a) Hashtbl.t }
+ i_tab : (table_key, 'a) Hashtbl.t }
let info_flags info = info.i_flags
@@ -403,18 +395,16 @@ let ref_value_cache info ref =
try
let body =
match ref with
- | FarRelBinding n ->
+ | FarRelKey n ->
let (s,l) = info.i_rels in lift n (List.assoc (s-n) l)
- | VarBinding id -> List.assoc id info.i_vars
- | EvarBinding evc -> existential_value info.i_evc evc
- | ConstBinding cst -> constant_value info.i_env cst
+ | VarKey id -> List.assoc id info.i_vars
+ | ConstKey cst -> constant_value info.i_env cst
in
let v = info.i_repr info body in
Hashtbl.add info.i_tab ref v;
Some v
with
| Not_found (* List.assoc *)
- | NotInstantiatedEvar (* Evar *)
| NotEvaluableConst _ (* Const *)
-> None
@@ -438,11 +428,10 @@ let defined_rels flags env =
env (0,[])
(* else (0,[])*)
-let create mk_cl flgs env sigma =
+let create mk_cl flgs env =
{ i_flags = flgs;
i_repr = mk_cl;
i_env = env;
- i_evc = sigma;
i_rels = defined_rels flgs env;
i_vars = defined_vars flgs env;
i_tab = Hashtbl.create 17 }
@@ -549,7 +538,7 @@ let rec stack_nth s p = match s with
(* Lazy reduction: the one used in kernel operations *)
(* type of shared terms. fconstr and frterm are mutually recursive.
- * Clone of the Generic.term structure, but completely mutable, and
+ * Clone of the constr structure, but completely mutable, and
* annotated with booleans (true when we noticed that the term is
* normal and neutral) FLIFT is a delayed shift; allows sharing
* between 2 lifted copies of a given term FCLOS is a delayed
@@ -565,7 +554,7 @@ and fterm =
| FRel of int
| FAtom of constr
| FCast of fconstr * fconstr
- | FFlex of freference
+ | FFlex of table_key
| FInd of inductive
| FConstruct of constructor
| FApp of fconstr * fconstr array
@@ -577,17 +566,11 @@ and fterm =
| FLambda of name * fconstr * fconstr * constr * fconstr subs
| FProd of name * fconstr * fconstr * constr * fconstr subs
| FLetIn of name * fconstr * fconstr * fconstr * constr * fconstr subs
+ | FEvar of existential_key * fconstr array
| FLIFT of int * fconstr
| FCLOS of constr * fconstr subs
| FLOCKED
-and freference =
- (* only vars as args of FConst ... exploited for caching *)
- | FConst of constant
- | FEvar of existential_key * fconstr array
- | FVar of identifier
- | FFarRel of int (* index in the rel_context part of _initial_ environment *)
-
let fterm_of v = v.term
let set_whnf v = if v.norm = Red then v.norm <- Whnf
let set_cstr v = if v.norm = Red then v.norm <- Cstr
@@ -646,19 +629,22 @@ let clos_rel e i =
| Inl(n,mt) -> lift_fconstr n mt
| Inr(k,None) -> {norm=Red; term= FRel k}
| Inr(k,Some p) ->
- lift_fconstr (k-p) {norm=Norm;term=FFlex(FFarRel p)}
+ lift_fconstr (k-p) {norm=Norm;term=FFlex(FarRelKey p)}
(* Optimization: do not enclose variables in a closure.
Makes variable access much faster *)
-let mk_clos e t =
+let rec mk_clos e t =
match kind_of_term t with
- | IsRel i -> clos_rel e i
- | IsVar x -> { norm = Red; term = FFlex (FVar x) }
- | IsMeta _ | IsSort _ -> { norm = Norm; term = FAtom t }
- | (IsMutInd _|IsMutConstruct _|IsFix _|IsCoFix _
- |IsLambda _|IsProd _) ->
+ | Rel i -> clos_rel e i
+ | Var x -> { norm = Red; term = FFlex (VarKey x) }
+ | Meta _ | Sort _ -> { norm = Norm; term = FAtom t }
+ | Ind sp -> { norm = Norm; term = FInd sp }
+ | Construct sp -> { norm = Cstr; term = FConstruct sp }
+ | Evar (ev,args) ->
+ { norm = Cstr; term = FEvar (ev,Array.map (mk_clos e) args) }
+ | (Fix _|CoFix _|Lambda _|Prod _) ->
{norm = Cstr; term = FCLOS(t,e)}
- | (IsApp _|IsMutCase _|IsCast _|IsConst _|IsEvar _|IsLetIn _) ->
+ | (App _|Case _|Cast _|Const _|LetIn _) ->
{norm = Red; term = FCLOS(t,e)}
let mk_clos_vect env v = Array.map (mk_clos env) v
@@ -669,55 +655,46 @@ let mk_clos_vect env v = Array.map (mk_clos env) v
Could be used insted of mk_clos. *)
let mk_clos_deep clos_fun env t =
match kind_of_term t with
- | IsRel i -> clos_rel env i
- | (IsVar _|IsMeta _ | IsSort _) -> mk_clos env t
- | IsCast (a,b) ->
+ | (Rel _|Ind _|Construct _|Var _|Meta _ | Sort _|Evar _) ->
+ mk_clos env t
+ | Cast (a,b) ->
{ norm = Red;
term = FCast (clos_fun env a, clos_fun env b)}
- | IsApp (f,v) ->
+ | App (f,v) ->
{ norm = Red;
term = FApp (clos_fun env f, Array.map (clos_fun env) v) }
- | IsMutInd sp ->
- { norm = Norm; term = FInd sp }
- | IsMutConstruct sp ->
- { norm = Norm; term = FConstruct sp }
- | IsConst sp ->
+ | Const sp ->
{ norm = Red;
- term = FFlex (FConst sp) }
- | IsEvar (n,v) ->
- { norm = Red;
- term = FFlex (FEvar (n, Array.map (clos_fun env) v)) }
-
- | IsMutCase (ci,p,c,v) ->
+ term = FFlex (ConstKey sp) }
+ | Case (ci,p,c,v) ->
{ norm = Red;
term = FCases (ci, clos_fun env p, clos_fun env c,
Array.map (clos_fun env) v) }
- | IsFix (op,(lna,tys,bds)) ->
+ | Fix (op,(lna,tys,bds)) ->
let env' = subs_liftn (Array.length bds) env in
{ norm = Cstr;
term = FFix
(op,(lna, Array.map (clos_fun env) tys,
Array.map (clos_fun env') bds),
bds, env) }
- | IsCoFix (op,(lna,tys,bds)) ->
+ | CoFix (op,(lna,tys,bds)) ->
let env' = subs_liftn (Array.length bds) env in
{ norm = Cstr;
term = FCoFix
(op,(lna, Array.map (clos_fun env) tys,
Array.map (clos_fun env') bds),
bds, env) }
-
- | IsLambda (n,t,c) ->
+ | Lambda (n,t,c) ->
{ norm = Cstr;
term = FLambda (n, clos_fun env t,
clos_fun (subs_lift env) c,
c, env) }
- | IsProd (n,t,c) ->
+ | Prod (n,t,c) ->
{ norm = Cstr;
term = FProd (n, clos_fun env t,
clos_fun (subs_lift env) c,
c, env) }
- | IsLetIn (n,b,t,c) ->
+ | LetIn (n,b,t,c) ->
{ norm = Red;
term = FLetIn (n, clos_fun env b, clos_fun env t,
clos_fun (subs_lift env) c,
@@ -727,24 +704,22 @@ let mk_clos_deep clos_fun env t =
let rec to_constr constr_fun lfts v =
match v.term with
| FRel i -> mkRel (reloc_rel i lfts)
- | FFlex (FFarRel p) -> mkRel (reloc_rel p lfts)
- | FFlex (FVar x) -> mkVar x
+ | FFlex (FarRelKey p) -> mkRel (reloc_rel p lfts)
+ | FFlex (VarKey x) -> mkVar x
| FAtom c ->
(match kind_of_term c with
- | IsSort s -> mkSort s
- | IsMeta m -> mkMeta m
+ | Sort s -> mkSort s
+ | Meta m -> mkMeta m
| _ -> assert false)
| FCast (a,b) ->
mkCast (constr_fun lfts a, constr_fun lfts b)
- | FFlex (FConst op) -> mkConst op
- | FFlex (FEvar (n,args)) ->
- mkEvar (n, Array.map (constr_fun lfts) args)
- | FInd op -> mkMutInd op
- | FConstruct op -> mkMutConstruct op
+ | FFlex (ConstKey op) -> mkConst op
+ | FInd op -> mkInd op
+ | FConstruct op -> mkConstruct op
| FCases (ci,p,c,ve) ->
- mkMutCase (ci, constr_fun lfts p,
- constr_fun lfts c,
- Array.map (constr_fun lfts) ve)
+ mkCase (ci, constr_fun lfts p,
+ constr_fun lfts c,
+ Array.map (constr_fun lfts) ve)
| FFix (op,(lna,tys,bds),_,_) ->
let lfts' = el_liftn (Array.length bds) lfts in
mkFix (op, (lna, Array.map (constr_fun lfts) tys,
@@ -766,6 +741,7 @@ let rec to_constr constr_fun lfts v =
mkLetIn (n, constr_fun lfts b,
constr_fun lfts t,
constr_fun (el_lift lfts) c)
+ | FEvar (ev,args) -> mkEvar(ev,Array.map (constr_fun lfts) args)
| FLIFT (k,a) -> to_constr constr_fun (el_shft k lfts) a
| FCLOS (t,env) ->
let fr = mk_clos_deep mk_clos env t in
@@ -952,23 +928,23 @@ let rec knh m stk =
| (None, stk') -> (m,stk'))
| FCast(t,_) -> knh t stk
(* cases where knh stops *)
- | (FFlex _|FLetIn _) -> (m, stk)
- | (FRel _|FAtom _) -> (set_norm m; (m, stk))
- | (FLambda _|FConstruct _|FCoFix _|FInd _|FProd _) ->
+ | (FFlex _|FLetIn _|FInd _|FConstruct _|FEvar _) -> (m, stk)
+ | (FRel _|FAtom _|FInd _) -> (set_norm m; (m, stk))
+ | (FLambda _|FCoFix _|FProd _) ->
(set_whnf m; (m, stk))
(* The same for pure terms *)
and knht e t stk =
match kind_of_term t with
- | IsApp(a,b) ->
+ | App(a,b) ->
knht e a (append_stack (mk_clos_vect e b) stk)
- | IsMutCase(ci,p,t,br) ->
+ | Case(ci,p,t,br) ->
knht e t (Zcase(ci, mk_clos e p, mk_clos_vect e br)::stk)
- | IsFix _ -> knh (mk_clos_deep mk_clos e t) stk
- | IsCast(a,b) -> knht e a stk
- | IsRel n -> knh (clos_rel e n) stk
- | (IsLambda _|IsProd _|IsMutConstruct _|IsCoFix _|IsMutInd _|
- IsLetIn _|IsConst _|IsVar _|IsEvar _|IsMeta _|IsSort _) ->
+ | Fix _ -> knh (mk_clos_deep mk_clos e t) stk
+ | Cast(a,b) -> knht e a stk
+ | Rel n -> knh (clos_rel e n) stk
+ | (Lambda _|Prod _|Construct _|CoFix _|Ind _|
+ LetIn _|Const _|Var _|Evar _|Meta _|Sort _) ->
(mk_clos_deep mk_clos e t, stk)
@@ -981,30 +957,23 @@ let rec knr info m stk =
(match get_arg m stk with
(Some(depth,arg),s) -> knit info (subs_shift_cons(depth,e,arg)) f s
| (None,s) -> (m,s))
- | FFlex(FConst sp) when can_red info stk (fCONST sp) ->
- (match ref_value_cache info (ConstBinding sp) with
+ | FFlex(ConstKey sp) when can_red info stk (fCONST sp) ->
+ (match ref_value_cache info (ConstKey sp) with
Some v -> kni info v stk
| None -> (set_norm m; (m,stk)))
- | FFlex(FEvar (n,args)) when can_red info stk fEVAR ->
-(* In the case of evars, if it is not defined, then we do not set the
- flag to Norm, because it may be instantiated later on *)
- let evar = (n, Array.map term_of_fconstr args) in
- (match ref_value_cache info (EvarBinding evar) with
- Some v -> kni info v stk
- | None -> (m,stk))
- | FFlex(FVar id) when can_red info stk (fVAR id) ->
- (match ref_value_cache info (VarBinding id) with
+ | FFlex(VarKey id) when can_red info stk (fVAR id) ->
+ (match ref_value_cache info (VarKey id) with
Some v -> kni info v stk
| None -> (set_norm m; (m,stk)))
- | FFlex(FFarRel k) when can_red info stk fDELTA ->
- (match ref_value_cache info (FarRelBinding k) with
+ | FFlex(FarRelKey k) when can_red info stk fDELTA ->
+ (match ref_value_cache info (FarRelKey k) with
Some v -> kni info v stk
| None -> (set_norm m; (m,stk)))
| FConstruct(ind,c) when can_red info stk fIOTA ->
(match strip_update_shift_app m stk with
- (depth, args, Zcase(((*cn*) npar,_),_,br)::s) ->
- assert (npar>=0);
- let rargs = drop_parameters depth npar args in
+ (depth, args, Zcase(ci,_,br)::s) ->
+ assert (ci.ci_npar>=0);
+ let rargs = drop_parameters depth ci.ci_npar args in
kni info br.(c-1) (rargs@s)
| (_, cargs, Zfix(fx,par)::s) ->
let rarg = fapp_stack(m,cargs) in
@@ -1014,7 +983,7 @@ let rec knr info m stk =
| (_,args,s) -> (m,args@s))
| FCoFix _ when can_red info stk fIOTA ->
(match strip_update_shift_app m stk with
- (_, args, ((Zcase((cn,_),_,br)::_) as stk')) ->
+ (_, args, ((Zcase _::_) as stk')) ->
let efx = contract_fix_vect m.term in
kni info efx (args@stk')
| (_,args,s) -> (m,args@s))
@@ -1060,8 +1029,7 @@ and down_then_up info m stk =
| FCoFix(n,(na,ftys,fbds),bds,e) ->
FCoFix(n,(na, Array.map (kl info) ftys,
Array.map (kl info) fbds),bds,e)
- | FFlex(FEvar(i,args)) ->
- FFlex(FEvar(i, Array.map (kl info) args))
+ | FEvar(i,args) -> FEvar(i, Array.map (kl info) args)
| t -> t in
{norm=Norm;term=nt} in
(* Precondition: m.norm = Norm *)
@@ -1081,18 +1049,12 @@ let norm_val info v =
let inject = mk_clos (ESID 0)
(* cache of constants: the body is computed only when needed. *)
-type 'a clos_infos = (fconstr, 'a) infos
-
-let create_clos_infos flgs env sigma =
- create (fun _ -> inject) flgs env sigma
-
-let unfold_reference info = function
- | FConst op -> ref_value_cache info (ConstBinding op)
- | FEvar (n,v) ->
- let evar = (n, Array.map (norm_val info) v) in
- ref_value_cache info (EvarBinding evar)
- | FVar id -> ref_value_cache info (VarBinding id)
- | FFarRel p -> ref_value_cache info (FarRelBinding p)
+type clos_infos = fconstr infos
+
+let create_clos_infos flgs env =
+ create (fun _ -> inject) flgs env
+
+let unfold_reference = ref_value_cache
(* Head normal form. *)