aboutsummaryrefslogtreecommitdiffhomepage
path: root/kernel/reduction.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/reduction.ml')
-rw-r--r--kernel/reduction.ml727
1 files changed, 89 insertions, 638 deletions
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 734187a9c..10ce90291 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -8,445 +8,64 @@
(* $Id$ *)
-open Pp
open Util
open Names
open Term
open Univ
-open Evd
open Declarations
open Environ
-open Instantiate
open Closure
open Esubst
-exception Elimconst
-
-(* The type of (machine) states (= lambda-bar-calculus' cuts) *)
-type state = constr * constr stack
-
-type 'a contextual_reduction_function = env -> 'a evar_map -> constr -> constr
-type 'a reduction_function = 'a contextual_reduction_function
-type local_reduction_function = constr -> constr
-
-type 'a contextual_stack_reduction_function =
- env -> 'a evar_map -> constr -> constr * constr list
-type 'a stack_reduction_function = 'a contextual_stack_reduction_function
-type local_stack_reduction_function = constr -> constr * constr list
-
-type 'a contextual_state_reduction_function =
- env -> 'a evar_map -> state -> state
-type 'a state_reduction_function = 'a contextual_state_reduction_function
-type local_state_reduction_function = state -> state
-
-(*************************************)
-(*** Reduction Functions Operators ***)
-(*************************************)
-
-let rec whd_state (x, stack as s) =
- match kind_of_term x with
- | IsApp (f,cl) -> whd_state (f, append_stack cl stack)
- | IsCast (c,_) -> whd_state (c, stack)
- | _ -> s
+(****************************************************************************)
+(* Reduction Functions *)
+(****************************************************************************)
-let appterm_of_stack (f,s) = (f,list_of_stack s)
+let nf_betaiota t =
+ norm_val (create_clos_infos betaiota empty_env) (inject t)
-let whd_stack x = appterm_of_stack (whd_state (x, empty_stack))
-let whd_castapp_stack = whd_stack
+let hnf_stack env x =
+ decompose_app
+ (norm_val (create_clos_infos hnf_flags env) (inject x))
-let stack_reduction_of_reduction red_fun env sigma s =
- let t = red_fun env sigma (app_stack s) in
- whd_stack t
+let whd_betadeltaiota env t =
+ whd_val (create_clos_infos betadeltaiota env) (inject t)
-let strong whdfun env sigma t =
- let rec strongrec env t =
- map_constr_with_full_binders push_rel strongrec env (whdfun env sigma t) in
- strongrec env t
+let whd_betadeltaiota_nolet env t =
+ whd_val (create_clos_infos betadeltaiotanolet env) (inject t)
-let local_strong whdfun =
- let rec strongrec t = map_constr strongrec (whdfun t) in
- strongrec
+(* Beta *)
-let rec strong_prodspine redfun c =
- let x = redfun c in
- match kind_of_term x with
- | IsProd (na,a,b) -> mkProd (na,a,strong_prodspine redfun b)
- | _ -> x
+let beta_appvect c v =
+ let rec stacklam env t stack =
+ match (decomp_stack stack,kind_of_term t) with
+ | Some (h,stacktl), Lambda (_,_,c) -> stacklam (h::env) c stacktl
+ | _ -> app_stack (substl env t, stack) in
+ stacklam [] c (append_stack v empty_stack)
-(****************************************************************************)
-(* Reduction Functions *)
-(****************************************************************************)
+(* pseudo-reduction rule:
+ * [hnf_prod_app env s (Prod(_,B)) N --> B[N]
+ * with an HNF on the first argument to produce a product.
+ * if this does not work, then we use the string S as part of our
+ * error message. *)
-(* lazy reduction functions. The infos must be created for each term *)
-let clos_norm_flags flgs env sigma t =
- norm_val (create_clos_infos flgs env sigma) (inject t)
-
-let nf_beta = clos_norm_flags beta empty_env Evd.empty
-let nf_betaiota = clos_norm_flags betaiota empty_env Evd.empty
-let nf_betadeltaiota env sigma = clos_norm_flags betadeltaiota env sigma
-
-(* lazy weak head reduction functions *)
-let whd_flags flgs env sigma t =
- whd_val (create_clos_infos flgs env sigma) (inject t)
-
-(*************************************)
-(*** Reduction using substitutions ***)
-(*************************************)
-
-(* This signature is very similar to Closure.RedFlagsSig except there
- is eta but no per-constant unfolding *)
-
-module type RedFlagsSig = sig
- type flags
- type flag
- val fbeta : flag
- val fevar : flag
- val fdelta : flag
- val feta : flag
- val fiota : flag
- val fzeta : flag
- val mkflags : flag list -> flags
- val red_beta : flags -> bool
- val red_delta : flags -> bool
- val red_evar : flags -> bool
- val red_eta : flags -> bool
- val red_iota : flags -> bool
- val red_zeta : flags -> bool
-end
-
-(* Naive Implementation
-module RedFlags = (struct
- type flag = BETA | DELTA | EVAR | IOTA | ZETA | ETA
- type flags = flag list
- let fbeta = BETA
- let fdelta = DELTA
- let fevar = EVAR
- let fiota = IOTA
- let fzeta = ZETA
- let feta = ETA
- let mkflags l = l
- let red_beta = List.mem BETA
- let red_delta = List.mem DELTA
- let red_evar = List.mem EVAR
- let red_eta = List.mem ETA
- let red_iota = List.mem IOTA
- let red_zeta = List.mem ZETA
-end : RedFlagsSig)
-*)
+let hnf_prod_app env t n =
+ match kind_of_term (whd_betadeltaiota env t) with
+ | Prod (_,_,b) -> subst1 n b
+ | _ -> anomaly "hnf_prod_app: Need a product"
-(* Compact Implementation *)
-module RedFlags = (struct
- type flag = int
- type flags = int
- let fbeta = 1
- let fdelta = 2
- let fevar = 4
- let feta = 8
- let fiota = 16
- let fzeta = 32
- let mkflags = List.fold_left (lor) 0
- let red_beta f = f land fbeta <> 0
- let red_delta f = f land fdelta <> 0
- let red_evar f = f land fevar <> 0
- let red_eta f = f land feta <> 0
- let red_iota f = f land fiota <> 0
- let red_zeta f = f land fzeta <> 0
-end : RedFlagsSig)
-
-open RedFlags
-
-(* Local *)
-let beta = mkflags [fbeta]
-let betaevar = mkflags [fevar; fbeta]
-let betaiota = mkflags [fiota; fbeta]
-let betaiotazeta = mkflags [fiota; fbeta;fzeta]
-
-(* Contextual *)
-let delta = mkflags [fdelta;fevar]
-let betadelta = mkflags [fbeta;fdelta;fzeta;fevar]
-let betadeltaeta = mkflags [fbeta;fdelta;fzeta;fevar;feta]
-let betadeltaiota = mkflags [fbeta;fdelta;fzeta;fevar;fiota]
-let betadeltaiota_nolet = mkflags [fbeta;fdelta;fevar;fiota]
-let betadeltaiotaeta = mkflags [fbeta;fdelta;fzeta;fevar;fiota;feta]
-let betaiotaevar = mkflags [fbeta;fiota;fevar]
-let betaetalet = mkflags [fbeta;feta;fzeta]
-
-(* Beta Reduction tools *)
-
-let rec stacklam recfun env t stack =
- match (decomp_stack stack,kind_of_term t) with
- | Some (h,stacktl), IsLambda (_,_,c) -> stacklam recfun (h::env) c stacktl
- | _ -> recfun (substl env t, stack)
-
-let beta_applist (c,l) =
- stacklam app_stack [] c (append_stack (Array.of_list l) empty_stack)
-
-(* Iota reduction tools *)
-
-type 'a miota_args = {
- mP : constr; (* the result type *)
- mconstr : constr; (* the constructor *)
- mci : case_info; (* special info to re-build pattern *)
- mcargs : 'a list; (* the constructor's arguments *)
- mlf : 'a array } (* the branch code vector *)
-
-let reducible_mind_case c = match kind_of_term c with
- | IsMutConstruct _ | IsCoFix _ -> true
- | _ -> false
-
-let contract_cofix (bodynum,(types,names,bodies as typedbodies)) =
- let nbodies = Array.length bodies in
- let make_Fi j = mkCoFix (nbodies-j-1,typedbodies) in
- substl (list_tabulate make_Fi nbodies) bodies.(bodynum)
-
-let reduce_mind_case mia =
- match kind_of_term mia.mconstr with
- | IsMutConstruct (ind_sp,i as cstr_sp) ->
-(* let ncargs = (fst mia.mci).(i-1) in*)
- let real_cargs = snd (list_chop (fst mia.mci) mia.mcargs) in
- applist (mia.mlf.(i-1),real_cargs)
- | IsCoFix cofix ->
- let cofix_def = contract_cofix cofix in
- mkMutCase (mia.mci, mia.mP, applist(cofix_def,mia.mcargs), mia.mlf)
- | _ -> assert false
-
-(* contracts fix==FIX[nl;i](A1...Ak;[F1...Fk]{B1....Bk}) to produce
- Bi[Fj --> FIX[nl;j](A1...Ak;[F1...Fk]{B1...Bk})] *)
-
-let contract_fix ((recindices,bodynum),(types,names,bodies as typedbodies)) =
- let nbodies = Array.length recindices in
- let make_Fi j = mkFix ((recindices,nbodies-j-1),typedbodies) in
- substl (list_tabulate make_Fi nbodies) bodies.(bodynum)
-
-let fix_recarg ((recindices,bodynum),_) stack =
- assert (0 <= bodynum & bodynum < Array.length recindices);
- let recargnum = Array.get recindices bodynum in
- try
- Some (recargnum, stack_nth stack recargnum)
- with Not_found ->
- None
-
-type fix_reduction_result = NotReducible | Reduced of state
-
-let reduce_fix whdfun fix stack =
- match fix_recarg fix stack with
- | None -> NotReducible
- | Some (recargnum,recarg) ->
- let (recarg'hd,_ as recarg') = whdfun (recarg, empty_stack) in
- let stack' = stack_assign stack recargnum (app_stack recarg') in
- (match kind_of_term recarg'hd with
- | IsMutConstruct _ -> Reduced (contract_fix fix, stack')
- | _ -> NotReducible)
-
-(* Generic reduction function *)
-
-(* Y avait un commentaire pour whd_betadeltaiota :
-
- NB : Cette fonction alloue peu c'est l'appel
- ``let (c,cargs) = whfun (recarg, empty_stack)''
- -------------------
- qui coute cher *)
-
-let rec whd_state_gen flags env sigma =
- let rec whrec (x, stack as s) =
- match kind_of_term x with
- | IsRel n when red_delta flags ->
- (match lookup_rel_value n env with
- | Some body -> whrec (lift n body, stack)
- | None -> s)
- | IsVar id when red_delta flags ->
- (match lookup_named_value id env with
- | Some body -> whrec (body, stack)
- | None -> s)
- | IsEvar ev when red_evar flags ->
- (match existential_opt_value sigma ev with
- | Some body -> whrec (body, stack)
- | None -> s)
- | IsConst const when red_delta flags ->
- (match constant_opt_value env const with
- | Some body -> whrec (body, stack)
- | None -> s)
- | IsLetIn (_,b,_,c) when red_zeta flags -> stacklam whrec [b] c stack
- | IsCast (c,_) -> whrec (c, stack)
- | IsApp (f,cl) -> whrec (f, append_stack cl stack)
- | IsLambda (na,t,c) ->
- (match decomp_stack stack with
- | Some (a,m) when red_beta flags -> stacklam whrec [a] c m
- | None when red_eta flags ->
- let env' = push_rel_assum (na,t) env in
- let whrec' = whd_state_gen flags env' sigma in
- (match kind_of_term (app_stack (whrec' (c, empty_stack))) with
- | IsApp (f,cl) ->
- let napp = Array.length cl in
- if napp > 0 then
- let x', l' = whrec' (array_last cl, empty_stack) in
- match kind_of_term x', decomp_stack l' with
- | IsRel 1, None ->
- let lc = Array.sub cl 0 (napp-1) in
- let u = if napp=1 then f else appvect (f,lc) in
- if noccurn 1 u then (pop u,empty_stack) else s
- | _ -> s
- else s
- | _ -> s)
- | _ -> s)
-
- | IsMutCase (ci,p,d,lf) when red_iota flags ->
- let (c,cargs) = whrec (d, empty_stack) in
- if reducible_mind_case c then
- whrec (reduce_mind_case
- {mP=p; mconstr=c; mcargs=list_of_stack cargs;
- mci=ci; mlf=lf}, stack)
- else
- (mkMutCase (ci, p, app_stack (c,cargs), lf), stack)
-
- | IsFix fix when red_iota flags ->
- (match reduce_fix whrec fix stack with
- | Reduced s' -> whrec s'
- | NotReducible -> s)
-
- | x -> s
- in
- whrec
-
-let local_whd_state_gen flags =
- let rec whrec (x, stack as s) =
- match kind_of_term x with
- | IsLetIn (_,b,_,c) when red_zeta flags -> stacklam whrec [b] c stack
- | IsCast (c,_) -> whrec (c, stack)
- | IsApp (f,cl) -> whrec (f, append_stack cl stack)
- | IsLambda (_,_,c) ->
- (match decomp_stack stack with
- | Some (a,m) when red_beta flags -> stacklam whrec [a] c m
- | None when red_eta flags ->
- (match kind_of_term (app_stack (whrec (c, empty_stack))) with
- | IsApp (f,cl) ->
- let napp = Array.length cl in
- if napp > 0 then
- let x', l' = whrec (array_last cl, empty_stack) in
- match kind_of_term x', decomp_stack l' with
- | IsRel 1, None ->
- let lc = Array.sub cl 0 (napp-1) in
- let u = if napp=1 then f else appvect (f,lc) in
- if noccurn 1 u then (pop u,empty_stack) else s
- | _ -> s
- else s
- | _ -> s)
- | _ -> s)
-
- | IsMutCase (ci,p,d,lf) when red_iota flags ->
- let (c,cargs) = whrec (d, empty_stack) in
- if reducible_mind_case c then
- whrec (reduce_mind_case
- {mP=p; mconstr=c; mcargs=list_of_stack cargs;
- mci=ci; mlf=lf}, stack)
- else
- (mkMutCase (ci, p, app_stack (c,cargs), lf), stack)
-
- | IsFix fix when red_iota flags ->
- (match reduce_fix whrec fix stack with
- | Reduced s' -> whrec s'
- | NotReducible -> s)
-
- | x -> s
- in
- whrec
-
-(* 1. Beta Reduction Functions *)
-
-let whd_beta_state = local_whd_state_gen beta
-let whd_beta_stack x = appterm_of_stack (whd_beta_state (x, empty_stack))
-let whd_beta x = app_stack (whd_beta_state (x,empty_stack))
-
-(* Nouveau ! *)
-let whd_betaetalet_state = local_whd_state_gen betaetalet
-let whd_betaetalet_stack x =
- appterm_of_stack (whd_betaetalet_state (x, empty_stack))
-let whd_betaetalet x = app_stack (whd_betaetalet_state (x,empty_stack))
-
-(* 2. Delta Reduction Functions *)
-
-let whd_delta_state e = whd_state_gen delta e
-let whd_delta_stack env sigma x =
- appterm_of_stack (whd_delta_state env sigma (x, empty_stack))
-let whd_delta env sigma c =
- app_stack (whd_delta_state env sigma (c, empty_stack))
-
-let whd_betadelta_state e = whd_state_gen betadelta e
-let whd_betadelta_stack env sigma x =
- appterm_of_stack (whd_betadelta_state env sigma (x, empty_stack))
-let whd_betadelta env sigma c =
- app_stack (whd_betadelta_state env sigma (c, empty_stack))
-
-let whd_betaevar_state e = whd_state_gen betaevar e
-let whd_betaevar_stack env sigma c =
- appterm_of_stack (whd_betaevar_state env sigma (c, empty_stack))
-let whd_betaevar env sigma c =
- app_stack (whd_betaevar_state env sigma (c, empty_stack))
-
-
-let whd_betadeltaeta_state e = whd_state_gen betadeltaeta e
-let whd_betadeltaeta_stack env sigma x =
- appterm_of_stack (whd_betadeltaeta_state env sigma (x, empty_stack))
-let whd_betadeltaeta env sigma x =
- app_stack (whd_betadeltaeta_state env sigma (x, empty_stack))
-
-(* 3. Iota reduction Functions *)
-
-let whd_betaiota_state = local_whd_state_gen betaiota
-let whd_betaiota_stack x =
- appterm_of_stack (whd_betaiota_state (x, empty_stack))
-let whd_betaiota x =
- app_stack (whd_betaiota_state (x, empty_stack))
-
-let whd_betaiotazeta_state = local_whd_state_gen betaiotazeta
-let whd_betaiotazeta_stack x =
- appterm_of_stack (whd_betaiotazeta_state (x, empty_stack))
-let whd_betaiotazeta x =
- app_stack (whd_betaiotazeta_state (x, empty_stack))
-
-let whd_betaiotaevar_state e = whd_state_gen betaiotaevar e
-let whd_betaiotaevar_stack env sigma x =
- appterm_of_stack (whd_betaiotaevar_state env sigma (x, empty_stack))
-let whd_betaiotaevar env sigma x =
- app_stack (whd_betaiotaevar_state env sigma (x, empty_stack))
-
-let whd_betadeltaiota_state e = whd_state_gen betadeltaiota e
-let whd_betadeltaiota_stack env sigma x =
- appterm_of_stack (whd_betadeltaiota_state env sigma (x, empty_stack))
-let whd_betadeltaiota env sigma x =
- app_stack (whd_betadeltaiota_state env sigma (x, empty_stack))
-
-let whd_betadeltaiotaeta_state e = whd_state_gen betadeltaiotaeta e
-let whd_betadeltaiotaeta_stack env sigma x =
- appterm_of_stack (whd_betadeltaiotaeta_state env sigma (x, empty_stack))
-let whd_betadeltaiotaeta env sigma x =
- app_stack (whd_betadeltaiotaeta_state env sigma (x, empty_stack))
-
-let whd_betadeltaiota_nolet_state e = whd_state_gen betadeltaiota_nolet e
-let whd_betadeltaiota_nolet_stack env sigma x =
- appterm_of_stack (whd_betadeltaiota_nolet_state env sigma (x, empty_stack))
-let whd_betadeltaiota_nolet env sigma x =
- app_stack (whd_betadeltaiota_nolet_state env sigma (x, empty_stack))
+let hnf_prod_applist env t nl =
+ List.fold_left (hnf_prod_app env) t nl
(********************************************************************)
(* Conversion *)
(********************************************************************)
-(*
-let fkey = Profile.declare_profile "fhnf";;
-let fhnf info v = Profile.profile2 fkey fhnf info v;;
-
-let fakey = Profile.declare_profile "fhnf_apply";;
-let fhnf_apply info k h a = Profile.profile4 fakey fhnf_apply info k h a;;
-*)
-
-type 'a conversion_function =
- env -> 'a evar_map -> constr -> constr -> constraints
(* Conversion utility functions *)
-
-type conversion_test = constraints -> constraints
+type 'a conversion_function = env -> 'a -> 'a -> constraints
exception NotConvertible
+exception NotConvertibleVect of int
(* Convertibility of sorts *)
@@ -454,12 +73,6 @@ type conv_pb =
| CONV
| CUMUL
-let pb_is_equal pb = pb = CONV
-
-let pb_equal = function
- | CUMUL -> CONV
- | CONV -> CONV
-
let sort_cmp pb s0 s1 cuniv =
match (s0,s1) with
| (Prop c1, Prop c2) -> if c1 = c2 then cuniv else raise NotConvertible
@@ -473,13 +86,6 @@ let sort_cmp pb s0 s1 cuniv =
| CUMUL -> enforce_geq u2 u1 cuniv)
| (_, _) -> raise NotConvertible
-let base_sort_cmp pb s0 s1 =
- match (s0,s1) with
- | (Prop c1, Prop c2) -> c1 = c2
- | (Prop c1, Type u) -> pb = CUMUL
- | (Type u1, Type u2) -> true
- | (_, _) -> false
-
(* Conversion between [lft1]term1 and [lft2]term2 *)
let rec ccnv cv_pb infos lft1 lft2 term1 term2 cuniv =
eqappr cv_pb infos (lft1, fhnf infos term1) (lft2, fhnf infos term2) cuniv
@@ -494,15 +100,20 @@ and eqappr cv_pb infos appr1 appr2 cuniv =
(* case of leaves *)
| (FAtom a1, FAtom a2) ->
(match kind_of_term a1, kind_of_term a2 with
- | (IsSort s1, IsSort s2) ->
+ | (Sort s1, Sort s2) ->
if stack_args_size v1 = 0 && stack_args_size v2 = 0
then sort_cmp cv_pb s1 s2 cuniv
else raise NotConvertible
- | (IsMeta n, IsMeta m) ->
+ | (Meta n, Meta m) ->
if n=m
then convert_stacks infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
| _ -> raise NotConvertible)
+ | (FEvar (ev1,args1), FEvar (ev2,args2)) ->
+ if ev1=ev2 then
+ let u1 = convert_vect infos el1 el2 args1 args2 cuniv in
+ convert_stacks infos lft1 lft2 v1 v2 u1
+ else raise NotConvertible
(* 2 index known to be bound to no constant *)
| (FRel n, FRel m) ->
@@ -575,13 +186,14 @@ and eqappr cv_pb infos appr1 appr2 cuniv =
convert_stacks infos lft1 lft2 v1 v2 u3
| (FInd op1, FInd op2) ->
- if op1 = op2
- then convert_stacks infos lft1 lft2 v1 v2 cuniv
+ if op1 = op2 then
+ convert_stacks infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
| (FConstruct op1, FConstruct op2) ->
if op1 = op2
- then convert_stacks infos lft1 lft2 v1 v2 cuniv
+ then
+ convert_stacks infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
| (FFix (op1,(_,tys1,cl1),_,_), FFix(op2,(_,tys2,cl2),_,_)) ->
@@ -631,241 +243,80 @@ and convert_vect infos lft1 lft2 v1 v2 cuniv =
-let fconv cv_pb env sigma t1 t2 =
+let fconv cv_pb env t1 t2 =
if eq_constr t1 t2 then
Constraint.empty
else
- let infos = create_clos_infos hnf_flags env sigma in
+ let infos = create_clos_infos hnf_flags env in
ccnv cv_pb infos ELID ELID (inject t1) (inject t2)
Constraint.empty
let conv env = fconv CONV env
-let conv_leq env = fconv CUMUL env
-
-(*
-let convleqkey = Profile.declare_profile "conv_leq";;
-let conv_leq env sigma t1 t2 =
- Profile.profile4 convleqkey conv_leq env sigma t1 t2;;
-
-let convkey = Profile.declare_profile "conv";;
-let conv env sigma t1 t2 =
- Profile.profile4 convleqkey conv env sigma t1 t2;;
-*)
-
-let conv_forall2 f env sigma v1 v2 =
- array_fold_left2
- (fun c x y -> let c' = f env sigma x y in Constraint.union c c')
- Constraint.empty
- v1 v2
+let conv_leq env = fconv CUMUL env
-let conv_forall2_i f env sigma v1 v2 =
+let conv_leq_vecti env v1 v2 =
array_fold_left2_i
- (fun i c x y -> let c' = f i env sigma x y in Constraint.union c c')
+ (fun i c t1 t2 ->
+ let c' =
+ try conv_leq env t1 t2
+ with NotConvertible -> raise (NotConvertibleVect i) in
+ Constraint.union c c')
Constraint.empty
- v1 v2
+ v1
+ v2
-let test_conversion f env sigma x y =
- try let _ = f env sigma x y in true with NotConvertible -> false
+(*
+let convleqkey = Profile.declare_profile "Kernel_reduction.conv_leq";;
+let conv_leq env t1 t2 =
+ Profile.profile4 convleqkey conv_leq env t1 t2;;
-let is_conv env sigma = test_conversion conv env sigma
-let is_conv_leq env sigma = test_conversion conv_leq env sigma
-let is_fconv = function | CONV -> is_conv | CUMUL -> is_conv_leq
+let convkey = Profile.declare_profile "Kernel_reduction.conv";;
+let conv env t1 t2 =
+ Profile.profile4 convleqkey conv env t1 t2;;
+*)
(********************************************************************)
(* Special-Purpose Reduction *)
(********************************************************************)
-let whd_meta metamap c = match kind_of_term c with
- | IsMeta p -> (try List.assoc p metamap with Not_found -> c)
- | _ -> c
-
-(* Try to replace all metas. Does not replace metas in the metas' values
- * Differs from (strong whd_meta). *)
-let plain_instance s c =
- let rec irec u = match kind_of_term u with
- | IsMeta p -> (try List.assoc p s with Not_found -> u)
- | IsCast (m,_) when isMeta m ->
- (try List.assoc (destMeta m) s with Not_found -> u)
- | _ -> map_constr irec u
- in
- if s = [] then c else irec c
-
-(* Pourquoi ne fait-on pas nf_betaiota si s=[] ? *)
-let instance s c =
- if s = [] then c else local_strong whd_betaiota (plain_instance s c)
-
+(* Dealing with arities *)
-(* pseudo-reduction rule:
- * [hnf_prod_app env s (Prod(_,B)) N --> B[N]
- * with an HNF on the first argument to produce a product.
- * if this does not work, then we use the string S as part of our
- * error message. *)
-
-let hnf_prod_app env sigma t n =
- match kind_of_term (whd_betadeltaiota env sigma t) with
- | IsProd (_,_,b) -> subst1 n b
- | _ -> anomaly "hnf_prod_app: Need a product"
-
-let hnf_prod_appvect env sigma t nl =
- Array.fold_left (hnf_prod_app env sigma) t nl
-
-let hnf_prod_applist env sigma t nl =
- List.fold_left (hnf_prod_app env sigma) t nl
-
-let hnf_lam_app env sigma t n =
- match kind_of_term (whd_betadeltaiota env sigma t) with
- | IsLambda (_,_,b) -> subst1 n b
- | _ -> anomaly "hnf_lam_app: Need an abstraction"
-
-let hnf_lam_appvect env sigma t nl =
- Array.fold_left (hnf_lam_app env sigma) t nl
-
-let hnf_lam_applist env sigma t nl =
- List.fold_left (hnf_lam_app env sigma) t nl
-
-let splay_prod env sigma =
+let dest_prod env =
let rec decrec env m c =
- let t = whd_betadeltaiota env sigma c in
+ let t = whd_betadeltaiota env c in
match kind_of_term t with
- | IsProd (n,a,c0) ->
- decrec (push_rel_assum (n,a) env)
- ((n,a)::m) c0
+ | Prod (n,a,c0) ->
+ let d = (n,None,a) in
+ decrec (push_rel d env) (Sign.add_rel_decl d 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
- | IsProd (x,t,c) ->
- prodec_rec (push_rel_assum (x,t) env)
- (Sign.add_rel_assum (x, t) l) c
- | IsLetIn (x,b,t,c) ->
- prodec_rec (push_rel_def (x,b, t) env)
- (Sign.add_rel_def (x,b, t) l) c
- | IsCast (c,_) -> prodec_rec env l c
- | _ -> l,t
+(* The same but preserving lets *)
+let dest_prod_assum env =
+ let rec prodec_rec env l ty =
+ let rty = whd_betadeltaiota_nolet env ty in
+ match kind_of_term rty with
+ | Prod (x,t,c) ->
+ let d = (x,None,t) in
+ prodec_rec (push_rel d env) (Sign.add_rel_decl d l) c
+ | LetIn (x,b,t,c) ->
+ let d = (x,Some b,t) in
+ prodec_rec (push_rel d env) (Sign.add_rel_decl d l) c
+ | Cast (c,_) -> prodec_rec env l c
+ | _ -> l,rty
in
prodec_rec env Sign.empty_rel_context
-let splay_arity env sigma c =
- let l, c = splay_prod env sigma c in
+let dest_arity env c =
+ let l, c = dest_prod env c in
match kind_of_term c with
- | IsSort s -> l,s
+ | Sort s -> l,s
| _ -> error "not an arity"
-let sort_of_arity env c = snd (splay_arity env Evd.empty c)
-
-let decomp_n_prod env sigma n =
- let rec decrec env m ln c = if m = 0 then (ln,c) else
- match kind_of_term (whd_betadeltaiota env sigma c) with
- | IsProd (n,a,c0) ->
- decrec (push_rel_assum (n,a) env)
- (m-1) (Sign.add_rel_assum (n,a) ln) c0
- | _ -> error "decomp_n_prod: Not enough products"
- in
- decrec env n Sign.empty_rel_context
-
-(* One step of approximation *)
-
-let rec apprec env sigma s =
- let (t, stack as s) = whd_betaiota_state s in
- match kind_of_term t with
- | IsMutCase (ci,p,d,lf) ->
- let (cr,crargs) = whd_betadeltaiota_stack env sigma d in
- let rslt = mkMutCase (ci, p, applist (cr,crargs), lf) in
- if reducible_mind_case cr then
- apprec env sigma (rslt, stack)
- else
- s
- | IsFix fix ->
- (match reduce_fix (whd_betadeltaiota_state env sigma) fix stack with
- | Reduced s -> apprec env sigma s
- | NotReducible -> s)
- | _ -> s
-
-let hnf env sigma c = apprec env sigma (c, empty_stack)
-
-(* A reduction function like whd_betaiota but which keeps casts
- * and does not reduce redexes containing existential variables.
- * Used in Correctness.
- * Added by JCF, 29/1/98. *)
-
-let whd_programs_stack env sigma =
- let rec whrec (x, stack as s) =
- match kind_of_term x with
- | IsApp (f,cl) ->
- let n = Array.length cl - 1 in
- let c = cl.(n) in
- if occur_existential c then
- s
- else
- whrec (mkApp (f, Array.sub cl 0 n), append_stack [|c|] stack)
- | IsLetIn (_,b,_,c) ->
- if occur_existential b then
- s
- else
- stacklam whrec [b] c stack
- | IsLambda (_,_,c) ->
- (match decomp_stack stack with
- | None -> s
- | Some (a,m) -> stacklam whrec [a] c m)
- | IsMutCase (ci,p,d,lf) ->
- if occur_existential d then
- s
- else
- let (c,cargs) = whrec (d, empty_stack) in
- if reducible_mind_case c then
- whrec (reduce_mind_case
- {mP=p; mconstr=c; mcargs=list_of_stack cargs;
- mci=ci; mlf=lf}, stack)
- else
- (mkMutCase (ci, p, app_stack(c,cargs), lf), stack)
- | IsFix fix ->
- (match reduce_fix whrec fix stack with
- | Reduced s' -> whrec s'
- | NotReducible -> s)
- | _ -> s
- in
- whrec
-
-let whd_programs env sigma x =
- app_stack (whd_programs_stack env sigma (x, empty_stack))
+let is_arity env c =
+ try
+ let _ = dest_arity env c in
+ true
+ with UserError _ -> false
-exception IsType
-
-let find_conclusion env sigma =
- let rec decrec env c =
- let t = whd_betadeltaiota env sigma c in
- match kind_of_term t with
- | IsProd (x,t,c0) -> decrec (push_rel_assum (x,t) env) c0
- | IsLambda (x,t,c0) -> decrec (push_rel_assum (x,t) env) c0
- | t -> t
- in
- decrec env
-
-let is_arity env sigma c =
- match find_conclusion env sigma c with
- | IsSort _ -> true
- | _ -> false
-
-let info_arity env sigma c =
- match find_conclusion env sigma c with
- | IsSort (Prop Null) -> false
- | IsSort (Prop Pos) -> true
- | _ -> raise IsType
-
-let is_info_arity env sigma c =
- try (info_arity env sigma c) with IsType -> true
-
-let is_type_arity env sigma c =
- match find_conclusion env sigma c with
- | IsSort (Type _) -> true
- | _ -> false
-
-let is_info_type env sigma t =
- let s = t.utj_type in
- (s = Prop Pos) ||
- (s <> Prop Null &&
- try info_arity env sigma t.utj_val with IsType -> true)