summaryrefslogtreecommitdiff
path: root/pretyping/inductiveops.ml
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping/inductiveops.ml')
-rw-r--r--pretyping/inductiveops.ml145
1 files changed, 92 insertions, 53 deletions
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index c33a261b..57d966f1 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: inductiveops.ml,v 1.14.2.2 2004/12/29 12:15:00 herbelin Exp $ *)
+(* $Id: inductiveops.ml 8653 2006-03-22 09:41:17Z herbelin $ *)
open Util
open Names
@@ -18,6 +18,24 @@ open Declarations
open Environ
open Reductionops
+(* The following three functions are similar to the ones defined in
+ Inductive, but they expect an env *)
+
+let type_of_inductive env ind =
+ let specif = Inductive.lookup_mind_specif env ind in
+ Inductive.type_of_inductive specif
+
+(* Return type as quoted by the user *)
+let type_of_constructor env cstr =
+ let specif =
+ Inductive.lookup_mind_specif env (inductive_of_constructor cstr) in
+ Inductive.type_of_constructor cstr specif
+
+(* Return constructor types in normal form *)
+let arities_of_constructors env ind =
+ let specif = Inductive.lookup_mind_specif env ind in
+ Inductive.arities_of_constructors ind specif
+
(* [inductive_family] = [inductive_instance] applied to global parameters *)
type inductive_family = inductive * constr list
@@ -73,6 +91,7 @@ let mis_nf_constructor_type (ind,mib,mip) j =
substl (list_tabulate make_Ik ntypes) specif.(j-1)
(* Arity of constructors excluding parameters and local defs *)
+
let mis_constr_nargs indsp =
let (mib,mip) = Global.lookup_inductive indsp in
let recargs = dest_subterms mip.mind_recargs in
@@ -87,7 +106,21 @@ let mis_constr_nargs_env env (kn,i) =
let mis_constructor_nargs_env env ((kn,i),j) =
let mib = Environ.lookup_mind kn env in
let mip = mib.mind_packets.(i) in
- recarg_length mip.mind_recargs j + mip.mind_nparams
+ recarg_length mip.mind_recargs j + mib.mind_nparams
+
+let constructor_nrealargs env (ind,j) =
+ let (_,mip) = Inductive.lookup_mind_specif env ind in
+ recarg_length mip.mind_recargs j
+
+let constructor_nrealhyps env (ind,j) =
+ let (mib,mip) = Inductive.lookup_mind_specif env ind in
+ mip.mind_consnrealdecls.(j-1)
+
+(* Length of arity (w/o local defs) *)
+
+let inductive_nargs env ind =
+ let (mib,mip) = Inductive.lookup_mind_specif env ind in
+ mip.mind_nrealargs + rel_context_nhyps mib.mind_params_ctxt
(* Annotation for cases *)
let make_case_info env ind style pats_source =
@@ -97,7 +130,8 @@ let make_case_info env ind style pats_source =
style = style;
source = pats_source } in
{ ci_ind = ind;
- ci_npar = mip.mind_nparams;
+ ci_npar = mib.mind_nparams;
+ ci_cstr_nargs = mip.mind_consnrealdecls;
ci_pp_info = print_info }
let make_default_case_info env style ind =
@@ -122,6 +156,7 @@ let lift_constructor n cs = {
cs_args = lift_rel_context n cs.cs_args;
cs_concl_realargs = Array.map (liftn n (cs.cs_nargs+1)) cs.cs_concl_realargs
}
+(* Accept less parameters than in the signature *)
let instantiate_params t args sign =
let rec inst s t = function
@@ -133,17 +168,17 @@ let instantiate_params t args sign =
(match kind_of_term t with
| LetIn(_,_,_,t) -> inst ((substl s b)::s) t (ctxt,args)
| _ -> anomaly"instantiate_params: type, ctxt and args mismatch")
- | [], [] -> substl s t
+ | _, [] -> substl s t
| _ -> anomaly"instantiate_params: type, ctxt and args mismatch"
in inst [] t (List.rev sign,args)
let get_constructor (ind,mib,mip,params) j =
assert (j <= Array.length mip.mind_consnames);
let typi = mis_nf_constructor_type (ind,mib,mip) j in
- let typi = instantiate_params typi params mip.mind_params_ctxt in
+ let typi = instantiate_params typi params mib.mind_params_ctxt in
let (args,ccl) = decompose_prod_assum typi in
let (_,allargs) = decompose_app ccl in
- let vargs = list_skipn mip.mind_nparams allargs in
+ let vargs = list_skipn (List.length params) allargs in
{ cs_cstr = ith_constructor_of_inductive ind j;
cs_params = params;
cs_nargs = rel_context_length args;
@@ -175,8 +210,7 @@ let build_dependent_constructor cs =
let build_dependent_inductive env ((ind, params) as indf) =
let arsign,_ = get_arity env indf in
- let (mib,mip) = Inductive.lookup_mind_specif env ind in
- let nrealargs = mip.mind_nrealargs in
+ let nrealargs = List.length arsign in
applist
(mkInd ind,
(List.map (lift nrealargs) params)@(extended_rel_list 0 arsign))
@@ -189,7 +223,7 @@ let make_arity_signature env dep indf =
(* We need names everywhere *)
name_context env
((Anonymous,None,build_dependent_inductive env indf)::arsign)
- (* Costly: would be better to name one for all at definition time *)
+ (* Costly: would be better to name once for all at definition time *)
else
(* No need to enforce names *)
arsign
@@ -225,7 +259,7 @@ let find_rectype env sigma c =
match kind_of_term t with
| Ind ind ->
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- let (par,rargs) = list_chop mip.mind_nparams l in
+ let (par,rargs) = list_chop mib.mind_nparams l in
IndType((ind, par),rargs)
| _ -> raise Not_found
@@ -247,59 +281,60 @@ let find_coinductive env sigma c =
(***********************************************)
-(* find appropriate names for pattern variables. Useful in the
- Case tactic. *)
+(* find appropriate names for pattern variables. Useful in the Case
+ and Inversion (case_then_using et case_nodep_then_using) tactics. *)
-let is_dep_predicate env kelim pred nodep_ar =
- let rec srec env pval pt nodep_ar =
- let pt' = whd_betadeltaiota env Evd.empty pt in
+let is_predicate_explicitly_dep env pred nodep_ar =
+ let rec srec env pval nodep_ar =
let pv' = whd_betadeltaiota env Evd.empty pval in
- match kind_of_term pv', kind_of_term pt', kind_of_term nodep_ar with
- | Lambda (na,t,b), Prod (_,_,a), Prod (_,_,a') ->
- srec (push_rel_assum (na,t) env) b a a'
- | _, Prod (na,t,a), Prod (_,_,a') ->
- srec (push_rel_assum (na,t) env) (lift 1 pv') a a'
- | Lambda (_,_,b), Prod (_,_,_), _ -> (*dependent (mkRel 1) b*) true
- | _, Prod (_,_,_), _ -> true
- | _ -> false in
- srec env pred.uj_val pred.uj_type nodep_ar
-
-let is_dependent_elimination_predicate env pred indf =
- let (ind,params) = indf in
- let (_,mip) = Inductive.lookup_mind_specif env ind in
- let kelim = mip.mind_kelim in
- let arsign,s = get_arity env indf in
- let glob_t = it_mkProd_or_LetIn (mkSort s) arsign in
- is_dep_predicate env kelim pred glob_t
-
-let is_dep_arity env kelim predty nodep_ar =
- let rec srec pt nodep_ar =
- let pt' = whd_betadeltaiota env Evd.empty pt in
- match kind_of_term pt', kind_of_term nodep_ar with
- | Prod (_,a1,a2), Prod (_,a1',a2') -> srec a2 a2'
- | Prod (_,a1,a2), _ -> true
- | _ -> false in
- srec predty nodep_ar
-
-let is_dependent_elimination env predty indf =
- let (ind,params) = indf in
- let (_,mip) = Inductive.lookup_mind_specif env ind in
- let kelim = mip.mind_kelim in
+ match kind_of_term pv', kind_of_term nodep_ar with
+ | Lambda (na,t,b), Prod (_,_,a') ->
+ srec (push_rel_assum (na,t) env) b a'
+ | Lambda (na,_,_), _ ->
+
+ (* The following code has impact on the introduction names
+ given by the tactics "case" and "inversion": when the
+ elimination is not dependent, "case" uses Anonymous for
+ inductive types in Prop and names created by mkProd_name for
+ inductive types in Set/Type while "inversion" uses anonymous
+ for inductive types both in Prop and Set/Type !!
+
+ Previously, whether names were created or not relied on
+ whether the predicate created in Indrec.make_case_com had a
+ dependent arity or not. To avoid different predicates
+ printed the same in v8, all predicates built in indrec.ml
+ got a dependent arity (Aug 2004). The new way to decide
+ whether names have to be created or not is to use an
+ Anonymous or Named variable to enforce the expected
+ dependency status (of course, Anonymous implies non
+ dependent, but not conversely).
+
+ At the end, this is only to preserve the compatibility: a
+ check whether the predicate is actually dependent or not
+ would indeed be more natural! *)
+
+ na <> Anonymous
+
+ | _ -> anomaly "Non eta-expanded dep-expanded \"match\" predicate"
+ in
+ srec env pred nodep_ar
+
+let is_elim_predicate_explicitly_dependent env pred indf =
let arsign,s = get_arity env indf in
let glob_t = it_mkProd_or_LetIn (mkSort s) arsign in
- is_dep_arity env kelim predty glob_t
+ is_predicate_explicitly_dep env pred glob_t
let set_names env n brty =
let (ctxt,cl) = decompose_prod_n_assum n brty in
it_mkProd_or_LetIn_name env cl ctxt
let set_pattern_names env ind brv =
- let (_,mip) = Inductive.lookup_mind_specif env ind in
+ let (mib,mip) = Inductive.lookup_mind_specif env ind in
let arities =
Array.map
(fun c ->
rel_context_length (fst (decompose_prod_assum c)) -
- mip.mind_nparams)
+ mib.mind_nparams)
mip.mind_nf_lc in
array_map2 (set_names env) arities brv
@@ -308,8 +343,8 @@ let type_case_branches_with_names env indspec pj c =
let (ind,args) = indspec in
let (lbrty,conclty,_) = Inductive.type_case_branches env indspec pj c in
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- let params = list_firstn mip.mind_nparams args in
- if is_dependent_elimination_predicate env pj (ind,params) then
+ let params = list_firstn mib.mind_nparams args in
+ if is_elim_predicate_explicitly_dependent env pj.uj_val (ind,params) then
(set_pattern_names env ind lbrty, conclty)
else (lbrty, conclty)
@@ -342,11 +377,15 @@ let control_only_guard env =
Array.iter control_rec tys;
Array.iter control_rec bds;
| Case(_,p,c,b) -> control_rec p;control_rec c;Array.iter control_rec b
- | Evar (_,cl) -> Array.iter control_rec cl
+ | Evar (_,cl) -> Array.iter control_rec cl
| App (c,cl) -> control_rec c; Array.iter control_rec cl
- | Cast (c1,c2) -> control_rec c1; control_rec c2
+ | Cast (c1,_, c2) -> control_rec c1; control_rec c2
| Prod (_,c1,c2) -> control_rec c1; control_rec c2
| Lambda (_,c1,c2) -> control_rec c1; control_rec c2
| LetIn (_,c1,c2,c3) -> control_rec c1; control_rec c2; control_rec c3
in
control_rec
+
+let subst_inductive subst (kn,i as ind) =
+ let kn' = Mod_subst.subst_kn subst kn in
+ if kn == kn' then ind else (kn',i)