diff options
author | Samuel Mimram <smimram@debian.org> | 2006-04-28 14:59:16 +0000 |
---|---|---|
committer | Samuel Mimram <smimram@debian.org> | 2006-04-28 14:59:16 +0000 |
commit | 3ef7797ef6fc605dfafb32523261fe1b023aeecb (patch) | |
tree | ad89c6bb57ceee608fcba2bb3435b74e0f57919e /pretyping/reductionops.ml | |
parent | 018ee3b0c2be79eb81b1f65c3f3fa142d24129c8 (diff) |
Imported Upstream version 8.0pl3+8.1alphaupstream/8.0pl3+8.1alpha
Diffstat (limited to 'pretyping/reductionops.ml')
-rw-r--r-- | pretyping/reductionops.ml | 214 |
1 files changed, 184 insertions, 30 deletions
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml index a030dcf2..b590f743 100644 --- a/pretyping/reductionops.ml +++ b/pretyping/reductionops.ml @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(* $Id: reductionops.ml,v 1.6.2.2 2004/07/16 19:30:46 herbelin Exp $ *) +(* $Id: reductionops.ml 8708 2006-04-14 08:13:02Z jforest $ *) open Pp open Util @@ -17,7 +17,6 @@ open Univ open Evd open Declarations open Environ -open Instantiate open Closure open Esubst open Reduction @@ -48,7 +47,7 @@ type local_state_reduction_function = state -> state let rec whd_state (x, stack as s) = match kind_of_term x with | App (f,cl) -> whd_state (f, append_stack cl stack) - | Cast (c,_) -> whd_state (c, stack) + | Cast (c,_,_) -> whd_state (c, stack) | _ -> s let appterm_of_stack (f,s) = (f,list_of_stack s) @@ -189,7 +188,7 @@ let contract_cofix (bodynum,(types,names,bodies as typedbodies)) = let reduce_mind_case mia = match kind_of_term mia.mconstr with - | Construct (ind_sp,i as cstr_sp) -> + | Construct (ind_sp,i) -> (* let ncargs = (fst mia.mci).(i-1) in*) let real_cargs = list_skipn mia.mci.ci_npar mia.mcargs in applist (mia.mlf.(i-1),real_cargs) @@ -255,7 +254,7 @@ let rec whd_state_gen flags env sigma = | Some body -> whrec (body, stack) | None -> s) | LetIn (_,b,_,c) when red_zeta flags -> stacklam whrec [b] c stack - | Cast (c,_) -> whrec (c, stack) + | Cast (c,_,_) -> whrec (c, stack) | App (f,cl) -> whrec (f, append_stack cl stack) | Lambda (na,t,c) -> (match decomp_stack stack with @@ -300,7 +299,7 @@ let local_whd_state_gen flags = let rec whrec (x, stack as s) = match kind_of_term x with | LetIn (_,b,_,c) when red_zeta flags -> stacklam whrec [b] c stack - | Cast (c,_) -> whrec (c, stack) + | Cast (c,_,_) -> whrec (c, stack) | App (f,cl) -> whrec (f, append_stack cl stack) | Lambda (_,_,c) -> (match decomp_stack stack with @@ -339,6 +338,7 @@ let local_whd_state_gen flags = in whrec + (* 1. Beta Reduction Functions *) let whd_beta_state = local_whd_state_gen beta @@ -427,12 +427,14 @@ let whd_betadeltaiota_nolet env sigma x = (* Replacing defined evars for error messages *) let rec whd_evar sigma c = match kind_of_term c with - | Evar (ev,args) when Evd.in_dom sigma ev & Evd.is_defined sigma ev -> - whd_evar sigma (Instantiate.existential_value sigma (ev,args)) + | Evar (ev,args) + when Evd.in_dom sigma ev & Evd.is_defined sigma ev -> + whd_evar sigma (Evd.existential_value sigma (ev,args)) + | Sort s when is_sort_variable sigma s -> whd_sort_variable sigma c | _ -> collapse_appl c -let nf_evar sigma = - local_strong (whd_evar sigma) +let nf_evar evd = + local_strong (whd_evar evd) (* lazy reduction functions. The infos must be created for each term *) let clos_norm_flags flgs env sigma t = @@ -443,6 +445,120 @@ let nf_betaiota = clos_norm_flags Closure.betaiota empty_env Evd.empty let nf_betadeltaiota env sigma = clos_norm_flags Closure.betadeltaiota env sigma + +(* Attention reduire un beta-redexe avec un argument qui n'est pas + une variable, peut changer enormement le temps de conversion lors + du type checking : + (fun x => x + x) M +*) +let nf_betaiotaevar_preserving_vm_cast env sigma t = + let push decl (env,subst) = + (Environ.push_rel decl env, Esubst.subs_lift subst) in + let cons decl v (env, subst) = (push_rel decl env, Esubst.subs_cons (v,subst)) in + + let app_stack t (f, stack) = + let t' = app_stack (f,stack) in + match kind_of_term t, kind_of_term t' with + | App(f,args), App(f',args') when f == f' && array_for_all2 (==) args args' -> t + | _ -> t' + in + let rec whrec (env, subst as es) (t, stack as s) = + match kind_of_term t with + | Rel i -> + let t' = + match Esubst.expand_rel i subst with + | Inl (k,e) -> lift k e + | Inr (k,None) -> mkRel k + | Inr (k, Some p) -> lift (k-p) (mkRel p) (*??????? == mkRel k ! Julien *) + (* Est correct ??? *) + in + if t = t' then s else t', stack + | Meta _ | Var _ | Sort _ | Const _ | Ind _ | Construct _ -> s + | Evar (e,al) -> + let al' = Array.map (norm es) al in + begin match existential_opt_value sigma (e,al') with + | Some body -> whrec (env,Esubst.ESID 0) (body, stack) (**** ????? ****) + | None -> + if array_for_all2 (==) al al' then s else (mkEvar (e, al'), stack) + end + | Cast (c,VMcast,t) -> + let c' = norm es c in + let t' = norm es t in + if c == c' && t == t' then s + else (mkCast(c',VMcast,t'),stack) + | Cast (c,DEFAULTcast,_) -> + whrec es (c, stack) + + | Prod (na,t,c) -> + let t' = norm es t in + let c' = norm (push (na, None, t') es) c in + if t==t' && c==c' then s else (mkProd (na, t', c'), stack) + + | Lambda (na,t,c) -> + begin match decomp_stack stack with + | Some (a,m) -> + begin match kind_of_term a with + | Rel i when not (evaluable_rel i env) -> + whrec (cons (na,None,t) a es) (c, m) + | Var id when not (evaluable_named id env)-> + whrec (cons (na,None,t) a es) (c, m) + | _ -> + let t' = norm es t in + let c' = norm (push (na, None, t') es) c in + if t == t' && c == c' then s + else mkLambda (na, t', c'), stack + end + | _ -> + let t' = norm es t in + let c' = norm (push (na, None, t') es) c in + if t == t' && c == c' then s + else mkLambda(na,t',c'),stack + + end + | LetIn (na,b,t,c) -> + let b' = norm es b in + let t' = norm es t in + let c' = norm (push (na, Some b', t') es) c in + if b==b' && t==t' && c==c' then s + else mkLetIn (na, b', t', c'), stack + + | App (f,cl) -> + let cl' = Array.map (norm es) cl in + whrec es (f, append_stack cl' stack) + + | Case (ci,p,d,lf) -> + let (c,cargs) = whrec es (d, empty_stack) in + if reducible_mind_case c then + whrec es (reduce_mind_case + {mP=p; mconstr=c; mcargs=list_of_stack cargs; + mci=ci; mlf=lf}, stack) + else + let p' = norm es p in + let d' = app_stack d (c,cargs) in + let lf' = Array.map (norm es) lf in + if p==p' && d==d' && array_for_all2 (==) lf lf' then s + else (mkCase (ci, p', d', lf'), stack) + | Fix (ln,(lna,tl,bl)) -> + let tl' = Array.map (norm es) tl in + let es' = + array_fold_left2 (fun es na t -> push (na,None,t) es) es lna tl' in + let bl' = Array.map (norm es') bl in + if array_for_all2 (==) tl tl' && array_for_all2 (==) bl bl' + then s + else (mkFix (ln,(lna,tl',bl')), stack) + | CoFix(ln,(lna,tl,bl)) -> + let tl' = Array.map (norm es) tl in + let es' = + array_fold_left2 (fun es na t -> push (na,None,t) es) es lna tl in + let bl' = Array.map (norm es') bl in + if array_for_all2 (==) tl tl' && array_for_all2 (==) bl bl' + then s + else (mkCoFix (ln,(lna,tl',bl')), stack) + + and norm es t = app_stack t (whrec es (t,empty_stack)) in + norm (env, Esubst.ESID 0) t + + (* lazy weak head reduction functions *) let whd_flags flgs env sigma t = whd_val (create_clos_infos flgs env) (inject (nf_evar sigma t)) @@ -462,10 +578,6 @@ let fhnf_apply info k h a = Profile.profile4 fakey fhnf_apply info k h a;; type conversion_test = constraints -> constraints -type conv_pb = - | CONV - | CUMUL - let pb_is_equal pb = pb = CONV let pb_equal = function @@ -515,22 +627,22 @@ let plain_instance s c = let rec irec u = match kind_of_term u with | Meta p -> (try List.assoc p s with Not_found -> u) | App (f,l) when isCast f -> - let (f,t) = destCast f in + let (f,_,t) = destCast f in let l' = Array.map irec l in (match kind_of_term f with - | Meta p -> - (* Don't flatten application nodes: this is used to extract a - proof-term from a proof-tree and we want to keep the structure - of the proof-tree *) - (try let g = List.assoc p s in - match kind_of_term g with - | App _ -> - let h = id_of_string "H" in - mkLetIn (Name h,g,t,mkApp(mkRel 1,Array.map (lift 1) l')) - | _ -> mkApp (g,l') - with Not_found -> mkApp (f,l')) - | _ -> mkApp (irec f,l')) - | Cast (m,_) when isMeta m -> + | Meta p -> + (* Don't flatten application nodes: this is used to extract a + proof-term from a proof-tree and we want to keep the structure + of the proof-tree *) + (try let g = List.assoc p s in + match kind_of_term g with + | App _ -> + let h = id_of_string "H" in + mkLetIn (Name h,g,t,mkApp(mkRel 1,Array.map (lift 1) l')) + | _ -> mkApp (g,l') + with Not_found -> mkApp (f,l')) + | _ -> mkApp (irec f,l')) + | Cast (m,_,_) when isMeta m -> (try List.assoc (destMeta m) s with Not_found -> u) | _ -> map_constr irec u in @@ -580,17 +692,28 @@ let splay_prod env sigma = in decrec env [] +let splay_lambda env sigma = + let rec decrec env m c = + let t = whd_betadeltaiota env sigma c in + match kind_of_term t with + | Lambda (n,a,c0) -> + decrec (push_rel (n,None,a) env) + ((n,a)::m) c0 + | _ -> m,t + in + decrec env [] + let splay_prod_assum env sigma = let rec prodec_rec env l c = let t = whd_betadeltaiota_nolet env sigma c in - match kind_of_term c with + match kind_of_term t with | Prod (x,t,c) -> prodec_rec (push_rel (x,None,t) env) (Sign.add_rel_decl (x, None, t) l) c | LetIn (x,b,t,c) -> prodec_rec (push_rel (x, Some b, t) env) (Sign.add_rel_decl (x, Some b, t) l) c - | Cast (c,_) -> prodec_rec env l c + | Cast (c,_,_) -> prodec_rec env l c | _ -> l,t in prodec_rec env Sign.empty_rel_context @@ -613,6 +736,13 @@ let decomp_n_prod env sigma n = in decrec env n Sign.empty_rel_context +exception NotASort + +let decomp_sort env sigma t = + match kind_of_term (whd_betadeltaiota env sigma t) with + | Sort s -> s + | _ -> raise NotASort + (* One step of approximation *) let rec apprec env sigma s = @@ -715,3 +845,27 @@ let is_info_type env sigma t = (s = Prop Pos) || (s <> Prop Null && try info_arity env sigma t.utj_val with IsType -> true) + +(*************************************) +(* Metas *) + +let meta_value evd mv = + let rec valrec mv = + try + let b = meta_fvalue evd mv in + instance + (List.map (fun mv' -> (mv',valrec mv')) (Metaset.elements b.freemetas)) + b.rebus + with Anomaly _ | Not_found -> + mkMeta mv + in + valrec mv + +let meta_instance env b = + let c_sigma = + List.map + (fun mv -> (mv,meta_value env mv)) (Metaset.elements b.freemetas) + in + instance c_sigma b.rebus + +let nf_meta env c = meta_instance env (mk_freelisted c) |