aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mohring <mohring@85f007b7-540e-0410-9357-904b9bb8a0f7>2005-11-02 22:12:16 +0000
committerGravatar mohring <mohring@85f007b7-540e-0410-9357-904b9bb8a0f7>2005-11-02 22:12:16 +0000
commit2f5c0f8880cd4ccc27cef4980768d35c9ebd26ea (patch)
treefb1f33855c930c0f5c46a67529e6df6e24652c9f
parent30ef31fd8e01d39fb7ce909167dcc1e4a29d7f80 (diff)
Types inductifs parametriques
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@7493 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--contrib/cc/cctac.ml2
-rw-r--r--contrib/extraction/extraction.ml6
-rw-r--r--contrib/first-order/formula.ml4
-rw-r--r--contrib/interface/showproof.ml2
-rw-r--r--contrib/xml/xmlcommand.ml13
-rw-r--r--ide/coq.ml6
-rw-r--r--interp/constrextern.ml2
-rw-r--r--interp/constrintern.ml4
-rw-r--r--kernel/cbytegen.ml10
-rw-r--r--kernel/declarations.ml12
-rw-r--r--kernel/declarations.mli5
-rw-r--r--kernel/entries.ml2
-rw-r--r--kernel/entries.mli3
-rw-r--r--kernel/indtypes.ml142
-rw-r--r--kernel/inductive.ml32
-rw-r--r--kernel/subtyping.ml4
-rw-r--r--kernel/vconv.ml4
-rw-r--r--lib/rtree.mli3
-rw-r--r--library/declare.ml8
-rw-r--r--library/library.ml3
-rw-r--r--parsing/prettyp.ml2
-rw-r--r--pretyping/detyping.ml4
-rw-r--r--pretyping/indrec.ml116
-rw-r--r--pretyping/indrec.mli3
-rw-r--r--pretyping/inductiveops.ml21
-rw-r--r--pretyping/pretyping.ml4
-rwxr-xr-xpretyping/recordops.ml2
-rw-r--r--tactics/eqdecide.ml42
-rw-r--r--tactics/equality.ml4
-rw-r--r--tactics/hipattern.ml8
-rw-r--r--tactics/tacticals.ml2
-rw-r--r--toplevel/command.ml9
-rw-r--r--toplevel/command.mli2
-rw-r--r--toplevel/discharge.ml34
-rw-r--r--toplevel/himsg.ml2
-rw-r--r--toplevel/record.ml8
36 files changed, 296 insertions, 194 deletions
diff --git a/contrib/cc/cctac.ml b/contrib/cc/cctac.ml
index d685051e9..71545d966 100644
--- a/contrib/cc/cctac.ml
+++ b/contrib/cc/cctac.ml
@@ -58,7 +58,7 @@ let rec decompose_term env t=
let targs=Array.map (decompose_term env) args in
Array.fold_left (fun s t->Appli (s,t)) tf targs
| Construct c->
- let (_,oib)=Global.lookup_inductive (fst c) in
+ let (oib,_)=Global.lookup_inductive (fst c) in
let nargs=mis_constructor_nargs_env env c in
Constructor {ci_constr=c;
ci_arity=nargs;
diff --git a/contrib/extraction/extraction.ml b/contrib/extraction/extraction.ml
index 0eb35e95b..55ad52ee2 100644
--- a/contrib/extraction/extraction.ml
+++ b/contrib/extraction/extraction.ml
@@ -295,8 +295,8 @@ and extract_ind env kn = (* kn is supposed to be in long form *)
(* Everything concerning parameters. *)
(* We do that first, since they are common to all the [mib]. *)
let mip0 = mib.mind_packets.(0) in
- let npar = mip0.mind_nparams in
- let epar = push_rel_context mip0.mind_params_ctxt env in
+ let npar = mib.mind_nparams in
+ let epar = push_rel_context mib.mind_params_ctxt env in
(* First pass: we store inductive signatures together with *)
(* their type var list. *)
let packets =
@@ -358,7 +358,7 @@ and extract_ind env kn = (* kn is supposed to be in long form *)
| _ -> []
in
let field_names =
- list_skipn mip0.mind_nparams (names_prod mip0.mind_user_lc.(0)) in
+ list_skipn mib.mind_nparams (names_prod mip0.mind_user_lc.(0)) in
assert (List.length field_names = List.length typ);
let projs = ref Cset.empty in
let mp,d,_ = repr_kn kn in
diff --git a/contrib/first-order/formula.ml b/contrib/first-order/formula.ml
index 9dbda969a..4e256981f 100644
--- a/contrib/first-order/formula.ml
+++ b/contrib/first-order/formula.ml
@@ -47,7 +47,7 @@ let rec nb_prod_after n c=
let construct_nhyps ind gls =
let env=pf_env gls in
- let nparams = (snd (Global.lookup_inductive ind)).mind_nparams in
+ let nparams = (fst (Global.lookup_inductive ind)).mind_nparams in
let constr_types = Inductiveops.arities_of_constructors (pf_env gls) ind in
let hyp = nb_prod_after nparams in
Array.map hyp constr_types
@@ -99,7 +99,7 @@ let rec kind_of_formula gl term =
let has_realargs=(n>0) in
let is_trivial=
let is_constant c =
- nb_prod c = mip.mind_nparams in
+ nb_prod c = mib.mind_nparams in
array_exists is_constant mip.mind_nf_lc in
if Inductiveops.mis_is_recursive (ind,mib,mip) ||
(has_realargs && not is_trivial)
diff --git a/contrib/interface/showproof.ml b/contrib/interface/showproof.ml
index 5b265ec86..2560b0b82 100644
--- a/contrib/interface/showproof.ml
+++ b/contrib/interface/showproof.ml
@@ -1556,7 +1556,7 @@ and mind_ind_info_hyp_constr indf c =
let env = Global.env() in
let (ind,_) = dest_ind_family indf in
let (mib,mip) = lookup_mind_specif env ind in
- let p = mip.mind_nparams in
+ let p = mib.mind_nparams in
let a = arity_of_constr_of_mind env indf c in
let lp=ref (get_constructors env indf).(c).cs_args in
let lr=ref [] in
diff --git a/contrib/xml/xmlcommand.ml b/contrib/xml/xmlcommand.ml
index df059677b..e8f149402 100644
--- a/contrib/xml/xmlcommand.ml
+++ b/contrib/xml/xmlcommand.ml
@@ -38,6 +38,8 @@ let print_if_verbose s = if !verbose then print_string s;;
(* Next exception is used only inside print_coq_object and tag_of_string_tag *)
exception Uninteresting;;
+(* NOT USED anymore, we back to the V6 point of view with global parameters
+
(* Internally, for Coq V7, params of inductive types are associated *)
(* not to the whole block of mutual inductive (as it was in V6) but to *)
(* each member of the block; but externally, all params are required *)
@@ -60,6 +62,8 @@ let extract_nparams pack =
done;
nparams0
+*)
+
(* could_have_namesakes sp = true iff o is an object that could be cooked and *)
(* than that could exists in cooked form with the same name in a super *)
(* section of the actual section *)
@@ -392,11 +396,11 @@ let mk_constant_obj id bo ty variables hyps =
ty,params)
;;
-let mk_inductive_obj sp packs variables hyps finite =
+let mk_inductive_obj sp packs variables nparams hyps finite =
let module D = Declarations in
let hyps = string_list_of_named_context_list hyps in
let params = filter_params variables hyps in
- let nparams = extract_nparams packs in
+(* let nparams = extract_nparams packs in *)
let tys =
let tyno = ref (Array.length packs) in
Array.fold_right
@@ -524,10 +528,11 @@ let print internal glob_ref kind xml_library_root =
G.lookup_constant kn in
Cic2acic.Constant kn,mk_constant_obj id val0 typ variables hyps
| Ln.IndRef (kn,_) ->
- let {D.mind_packets=packs ;
+ let {D.mind_nparams=nparams;
+ D.mind_packets=packs ;
D.mind_hyps=hyps;
D.mind_finite=finite} = G.lookup_mind kn in
- Cic2acic.Inductive kn,mk_inductive_obj kn packs variables hyps finite
+ Cic2acic.Inductive kn,mk_inductive_obj kn packs variables nparams hyps finite
| Ln.ConstructRef _ ->
Util.anomaly ("print: this should not happen")
in
diff --git a/ide/coq.ml b/ide/coq.ml
index 0a72c97bc..eeb31e1ae 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -432,10 +432,8 @@ let make_cases s =
let glob_ref = Nametab.locate qualified_name in
match glob_ref with
| Libnames.IndRef i ->
- let _,
- {
- Declarations.mind_nparams = np ;
- Declarations.mind_consnames = carr ;
+ let {Declarations.mind_nparams = np},
+ {Declarations.mind_consnames = carr ;
Declarations.mind_nf_lc = tarr }
= Global.lookup_inductive i
in
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index a5b022058..8faec21df 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -1254,7 +1254,7 @@ let rec match_cases_pattern metas sigma a1 a2 = match (a1,a2) with
| a, AHole _ when not(Options.do_translate()) -> sigma
| PatCstr (loc,(ind,_ as r1),args1,Anonymous), _ ->
let nparams =
- (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ (fst (Global.lookup_inductive ind)).Declarations.mind_nparams in
let l2 =
match a2 with
| ARef (ConstructRef r2) when r1 = r2 -> []
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index b2b657c5f..498c483dc 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -462,7 +462,7 @@ let subst_cases_pattern loc (ids,asubst as aliases) intern subst scopes a =
| ARef (ConstructRef c) ->
(ids,[asubst, PatCstr (loc,c, [], alias_of aliases)])
| AApp (ARef (ConstructRef (ind,_ as c)),args) ->
- let nparams = (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let nparams = (fst (Global.lookup_inductive ind)).Declarations.mind_nparams in
let _,args = list_chop nparams args in
let idslpll = List.map (aux ([],[]) subst) args in
let ids',pll = product_of_cases_patterns ids idslpll in
@@ -500,7 +500,7 @@ let rec patt_of_rawterm loc cstr =
| RApp (_,RApp(_,h,l1),l2) -> patt_of_rawterm loc (RApp(loc,h,l1@l2))
| RApp (_,RRef(_,(ConstructRef c as x)),pl) ->
if !dump then add_glob loc x;
- let (_,mib) = Inductive.lookup_mind_specif (Global.env()) (fst c) in
+ let (mib,_) = Inductive.lookup_mind_specif (Global.env()) (fst c) in
let npar = mib.Declarations.mind_nparams in
let (params,args) =
if List.length pl <= npar then (pl,[]) else
diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml
index 7877fbccb..cc59558e1 100644
--- a/kernel/cbytegen.ml
+++ b/kernel/cbytegen.ml
@@ -196,8 +196,9 @@ let rec str_const c =
begin
match kind_of_term f with
| Construct((kn,j),i) ->
- let oib = (lookup_mind kn !global_env).mind_packets.(j) in
- let num,arity = oib.mind_reloc_tbl.(i-1) in
+ let oib = lookup_mind kn !global_env in
+ let oip = oib.mind_packets.(j) in
+ let num,arity = oip.mind_reloc_tbl.(i-1) in
let nparams = oib.mind_nparams in
if nparams + arity = Array.length args then
if arity = 0 then Bstrconst(Const_b0 num)
@@ -216,8 +217,9 @@ let rec str_const c =
end
| Ind ind -> Bstrconst (Const_ind ind)
| Construct ((kn,j),i) ->
- let oib = (lookup_mind kn !global_env).mind_packets.(j) in
- let num,arity = oib.mind_reloc_tbl.(i-1) in
+ let oib = lookup_mind kn !global_env in
+ let oip = oib.mind_packets.(j) in
+ let num,arity = oip.mind_reloc_tbl.(i-1) in
let nparams = oib.mind_nparams in
if nparams + arity = 0 then Bstrconst(Const_b0 num)
else Bconstruct_app(num,nparams,arity,[||])
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index 72f37e226..9ce925207 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -80,8 +80,6 @@ let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p
type one_inductive_body = {
mind_typename : identifier;
- mind_nparams : int;
- mind_params_ctxt : rel_context;
mind_nrealargs : int;
mind_nf_arity : types;
mind_user_arity : types;
@@ -101,6 +99,9 @@ type mutual_inductive_body = {
mind_finite : bool;
mind_ntypes : int;
mind_hyps : section_context;
+ mind_nparams : int;
+ mind_nparams_rec : int;
+ mind_params_ctxt : rel_context;
mind_packets : one_inductive_body array;
mind_constraints : constraints;
mind_equiv : kernel_name option
@@ -128,9 +129,6 @@ let subst_mind_packet sub mbp =
mind_sort = mbp.mind_sort;
mind_nrealargs = mbp.mind_nrealargs;
mind_kelim = mbp.mind_kelim;
- mind_nparams = mbp.mind_nparams;
- mind_params_ctxt =
- map_rel_context (subst_mps sub) mbp.mind_params_ctxt;
mind_recargs = subst_wf_paths sub mbp.mind_recargs (*wf_paths*);
mind_nb_constant = mbp.mind_nb_constant;
mind_nb_args = mbp.mind_nb_args;
@@ -142,6 +140,10 @@ let subst_mind sub mib =
mind_finite = mib.mind_finite ;
mind_ntypes = mib.mind_ntypes ;
mind_hyps = (assert (mib.mind_hyps=[]); []) ;
+ mind_nparams = mib.mind_nparams;
+ mind_nparams_rec = mib.mind_nparams_rec;
+ mind_params_ctxt =
+ map_rel_context (subst_mps sub) mib.mind_params_ctxt;
mind_packets = array_smartmap (subst_mind_packet sub) mib.mind_packets ;
mind_constraints = mib.mind_constraints ;
mind_equiv = option_app (subst_kn sub) mib.mind_equiv }
diff --git a/kernel/declarations.mli b/kernel/declarations.mli
index 3c99b67ac..62a1cc07c 100644
--- a/kernel/declarations.mli
+++ b/kernel/declarations.mli
@@ -67,8 +67,6 @@ val subst_wf_paths : substitution -> wf_paths -> wf_paths
type one_inductive_body = {
mind_typename : identifier;
- mind_nparams : int;
- mind_params_ctxt : rel_context;
mind_nrealargs : int;
mind_nf_arity : types;
mind_user_arity : types;
@@ -90,6 +88,9 @@ type mutual_inductive_body = {
mind_finite : bool;
mind_ntypes : int;
mind_hyps : section_context;
+ mind_nparams : int;
+ mind_nparams_rec : int;
+ mind_params_ctxt : rel_context;
mind_packets : one_inductive_body array;
mind_constraints : constraints;
mind_equiv : kernel_name option;
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 6ea4bfc59..c31d8f74a 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -42,7 +42,6 @@ then, in $i^{th}$ block, [mind_entry_params] is [[xn:Xn;...;x1:X1]];
*)
type one_inductive_entry = {
- mind_entry_params : (identifier * local_entry) list;
mind_entry_typename : identifier;
mind_entry_arity : constr;
mind_entry_consnames : identifier list;
@@ -51,6 +50,7 @@ type one_inductive_entry = {
type mutual_inductive_entry = {
mind_entry_record : bool;
mind_entry_finite : bool;
+ mind_entry_params : (identifier * local_entry) list;
mind_entry_inds : one_inductive_entry list }
diff --git a/kernel/entries.mli b/kernel/entries.mli
index 71c756e26..6f4f343bb 100644
--- a/kernel/entries.mli
+++ b/kernel/entries.mli
@@ -42,7 +42,6 @@ then, in $i^{th}$ block, [mind_entry_params] is [[xn:Xn;...;x1:X1]];
*)
type one_inductive_entry = {
- mind_entry_params : (identifier * local_entry) list;
mind_entry_typename : identifier;
mind_entry_arity : constr;
mind_entry_consnames : identifier list;
@@ -51,9 +50,9 @@ type one_inductive_entry = {
type mutual_inductive_entry = {
mind_entry_record : bool;
mind_entry_finite : bool;
+ mind_entry_params : (identifier * local_entry) list;
mind_entry_inds : one_inductive_entry list }
-
(*s Constants (Definition/Axiom) *)
type definition_entry = {
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 6fac5c391..25464a3ce 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -187,16 +187,15 @@ let typecheck_inductive env mie =
(* Check unicity of names *)
mind_check_names mie;
mind_check_arities env mie;
- (* We first type params and arity of each inductive definition *)
+ (* Params are typed-checked here *)
+ let params = mie.mind_entry_params in
+ let env_params, params, cstp = infer_local_decls env params in
+ (* We first type arity of each inductive definition *)
(* This allows to build the environment of arities and to share *)
(* the set of constraints *)
let cst, arities, rev_params_arity_list =
List.fold_left
(fun (cst,arities,l) ind ->
- (* Params are typed-checked here *)
- let params = ind.mind_entry_params in
- let env_params, params, cst1 =
- infer_local_decls env params in
(* Arities (without params) are typed-checked here *)
let arity, cst2 =
infer_type env_params ind.mind_entry_arity in
@@ -206,10 +205,10 @@ let typecheck_inductive env mie =
upper universe will be generated *)
let id = ind.mind_entry_typename in
let full_arity = it_mkProd_or_LetIn arity.utj_val params in
- Constraint.union cst (Constraint.union cst1 cst2),
+ Constraint.union cst cst2,
Sign.add_rel_decl (Name id, None, full_arity) arities,
(params, id, full_arity, arity.utj_val)::l)
- (Constraint.empty,empty_rel_context,[])
+ (cstp,empty_rel_context,[])
mie.mind_entry_inds in
let env_arities = push_rel_context arities env in
@@ -225,13 +224,13 @@ let typecheck_inductive env mie =
let (issmall,isunit,lc',cst') =
infer_constructor_packet env_arities params arsort lc in
let consnames = ind.mind_entry_consnames in
- let ind' = (params,id,full_arity,consnames,issmall,isunit,lc')
+ let ind' = (id,full_arity,consnames,issmall,isunit,lc')
in
(ind'::inds, Constraint.union cst cst'))
mie.mind_entry_inds
params_arity_list
([],cst) in
- (env_arities, Array.of_list inds, cst)
+ (env_arities, params, Array.of_list inds, cst)
(************************************************************************)
(************************************************************************)
@@ -294,6 +293,26 @@ let check_correct_par (env,n,ntypes,_) hyps l largs =
if not (array_for_all (noccur_between n ntypes) largs') then
failwith_non_pos_vect n ntypes largs'
+(* Computes the maximum number of recursive parameters :
+ the first parameters which are constant in recursive arguments
+ n is the current depth, nmr is the maximum number of possible
+ recursive parameters *)
+
+let compute_rec_par (env,n,_,_) hyps nmr largs =
+if nmr = 0 then 0 else
+(* start from 0, hyps will be in reverse order *)
+ let (lpar,_) = list_chop nmr largs in
+ let rec find k index =
+ function
+ ([],_) -> nmr
+ | (_,[]) -> assert false (* |hyps|>=nmr *)
+ | (lp,(_,Some _,_)::hyps) -> find k (index-1) (lp,hyps)
+ | (p::lp,_::hyps) ->
+ ( match kind_of_term (whd_betadeltaiota env p) with
+ | Rel w when w = index -> find (k+1) (index-1) (lp,hyps)
+ | _ -> k)
+ in find 0 (n-1) (lpar,List.rev hyps)
+
(* This removes global parameters of the inductive types in lc (for
nested inductive types only ) *)
let abstract_mind_lc env ntyps npars lc =
@@ -327,13 +346,16 @@ let ienv_push_inductive (env, n, ntypes, ra_env) (mi,lpar) =
(* New index of the inductive types *)
let newidx = n + auxntyp in
(env', newidx, ntypes, ra_env')
+
+let array_min nmr a = if nmr = 0 then 0 else
+ Array.fold_left (fun k (nmri,_) -> min k nmri) nmr a
(* The recursive function that checks positivity and builds the list
of recursive arguments *)
let check_positivity_one (env, _,ntypes,_ as ienv) hyps i indlc =
let nparams = rel_context_length hyps in
(* check the inductive types occur positively in [c] *)
- let rec check_pos (env, n, ntypes, ra_env as ienv) c =
+ let rec check_pos (env, n, ntypes, ra_env as ienv) nmr c =
let x,largs = decompose_app (whd_betadeltaiota env c) in
match kind_of_term x with
| Prod (na,b,d) ->
@@ -341,33 +363,34 @@ let check_positivity_one (env, _,ntypes,_ as ienv) hyps i indlc =
let b = whd_betadeltaiota env b in
if not (noccur_between n ntypes b) then
raise (IllFormedInd (LocalNonPos n));
- check_pos (ienv_push_var ienv (na, b, mk_norec)) d
+ check_pos (ienv_push_var ienv (na, b, mk_norec)) nmr d
| Rel k ->
- let (ra,rarg) =
- try List.nth ra_env (k-1)
- with Failure _ | Invalid_argument _ -> (Norec,mk_norec) in
- (match ra with
- Mrec _ -> check_correct_par ienv hyps (k-n+1) largs
- | _ ->
- if not (List.for_all (noccur_between n ntypes) largs)
- then raise (IllFormedInd (LocalNonPos n)));
- rarg
+ (try let (ra,rarg) = List.nth ra_env (k-1) in
+ let nmr1 =
+ (match ra with
+ Mrec _ -> compute_rec_par ienv hyps nmr largs
+ | _ -> nmr)
+ in
+ if not (List.for_all (noccur_between n ntypes) largs)
+ then raise (IllFormedInd (LocalNonPos n))
+ else (nmr1,rarg)
+ with Failure _ | Invalid_argument _ -> (nmr,mk_norec))
| Ind ind_kn ->
(* If the inductive type being defined appears in a
parameter, then we have an imbricated type *)
- if List.for_all (noccur_between n ntypes) largs then mk_norec
- else check_positive_imbr ienv (ind_kn, largs)
+ if List.for_all (noccur_between n ntypes) largs then (nmr,mk_norec)
+ else check_positive_imbr ienv nmr (ind_kn, largs)
| err ->
if noccur_between n ntypes x &&
List.for_all (noccur_between n ntypes) largs
- then mk_norec
+ then (nmr,mk_norec)
else raise (IllFormedInd (LocalNonPos n))
(* accesses to the environment are not factorised, but does it worth
it? *)
- and check_positive_imbr (env,n,ntypes,ra_env as ienv) (mi, largs) =
+ and check_positive_imbr (env,n,ntypes,ra_env as ienv) nmr (mi, largs) =
let (mib,mip) = lookup_mind_specif env mi in
- let auxnpar = mip.mind_nparams in
+ let auxnpar = mib.mind_nparams_rec in
let (lpar,auxlargs) =
try list_chop auxnpar largs
with Failure _ -> raise (IllFormedInd (LocalNonPos n)) in
@@ -385,31 +408,34 @@ let check_positivity_one (env, _,ntypes,_ as ienv) hyps i indlc =
let (env',_,_,_ as ienv') = ienv_push_inductive ienv (mi,lpar) in
(* Parameters expressed in env' *)
let lpar' = List.map (lift auxntyp) lpar in
- let irecargs =
+ let irecargs_nmr =
(* fails if the inductive type occurs non positively *)
(* when substituted *)
Array.map
(function c ->
let c' = hnf_prod_applist env' c lpar' in
- check_constructors ienv' false c')
+ check_constructors ienv' false nmr c')
auxlcvect
+ in
+ let irecargs = Array.map snd irecargs_nmr
+ and nmr' = array_min nmr irecargs_nmr
in
- (Rtree.mk_rec [|mk_paths (Imbr mi) irecargs|]).(0)
+ (nmr,(Rtree.mk_rec [|mk_paths (Imbr mi) irecargs|]).(0))
(* check the inductive types occur positively in the products of C, if
check_head=true, also check the head corresponds to a constructor of
the ith type *)
- and check_constructors ienv check_head c =
- let rec check_constr_rec (env,n,ntypes,ra_env as ienv) lrec c =
+ and check_constructors ienv check_head nmr c =
+ let rec check_constr_rec (env,n,ntypes,ra_env as ienv) nmr lrec c =
let x,largs = decompose_app (whd_betadeltaiota env c) in
match kind_of_term x with
| Prod (na,b,d) ->
assert (largs = []);
- let recarg = check_pos ienv b in
+ let nmr',recarg = check_pos ienv nmr b in
let ienv' = ienv_push_var ienv (na,b,mk_norec) in
- check_constr_rec ienv' (recarg::lrec) d
+ check_constr_rec ienv' nmr' (recarg::lrec) d
| hd ->
if check_head then
@@ -420,32 +446,40 @@ let check_positivity_one (env, _,ntypes,_ as ienv) hyps i indlc =
else
if not (List.for_all (noccur_between n ntypes) largs)
then raise (IllFormedInd (LocalNonPos n));
- List.rev lrec
- in check_constr_rec ienv [] c
+ (nmr,List.rev lrec)
+ in check_constr_rec ienv nmr [] c
in
- mk_paths (Mrec i)
- (Array.map
+ let irecargs_nmr =
+ Array.map
(fun c ->
let c = body_of_type c in
let sign, rawc = mind_extract_params nparams c in
let env' = push_rel_context sign env in
try
- check_constructors ienv true rawc
+ check_constructors ienv true nparams rawc
with IllFormedInd err ->
explain_ind_err (ntypes-i) env nparams c err)
- indlc)
+ indlc
+ in
+ let irecargs = Array.map snd irecargs_nmr
+ and nmr' = array_min nparams irecargs_nmr
+ in (nmr', mk_paths (Mrec i) irecargs)
-let check_positivity env_ar inds =
+let check_positivity env_ar params inds =
let ntypes = Array.length inds in
let lra_ind =
List.rev (list_tabulate (fun j -> (Mrec j, Rtree.mk_param j)) ntypes) in
- let check_one i (params,_,_,_,_,_,lc) =
- let nparams = rel_context_length params in
+ let nparams = rel_context_length params in
+ let check_one i (_,_,_,_,_,lc) =
let ra_env =
list_tabulate (fun _ -> (Norec,mk_norec)) nparams @ lra_ind in
let ienv = (env_ar, 1+nparams, ntypes, ra_env) in
- check_positivity_one ienv params i lc in
- Rtree.mk_rec (Array.mapi check_one inds)
+ check_positivity_one ienv params i lc
+ in
+ let irecargs_nmr = Array.mapi check_one inds in
+ let irecargs = Array.map snd irecargs_nmr
+ and nmr' = array_min nparams irecargs_nmr
+ in (nmr',Rtree.mk_rec irecargs)
(************************************************************************)
@@ -476,12 +510,12 @@ let allowed_sorts env issmall isunit = function
if isunit then all_sorts
else logical_sorts
-let build_inductive env env_ar record finite inds recargs cst =
+let build_inductive env env_ar params record finite inds nmr recargs cst =
let ntypes = Array.length inds in
(* Compute the set of used section variables *)
let ids =
Array.fold_left
- (fun acc (_,_,ar,_,_,_,lc) ->
+ (fun acc (_,ar,_,_,_,lc) ->
Idset.union (Environ.global_vars_set env (body_of_type ar))
(Array.fold_left
(fun acc c ->
@@ -490,10 +524,10 @@ let build_inductive env env_ar record finite inds recargs cst =
lc))
Idset.empty inds in
let hyps = keep_hyps env ids in
+ let nparamargs = rel_context_nhyps params in
(* Check one inductive *)
- let build_one_packet (params,id,ar,cnames,issmall,isunit,lc) recarg =
+ let build_one_packet (id,ar,cnames,issmall,isunit,lc) recarg =
(* Arity in normal form *)
- let nparamargs = rel_context_nhyps params in
let (ar_sign,ar_sort) = dest_arity env ar in
let nf_ar =
if isArity (body_of_type ar) then ar
@@ -521,8 +555,6 @@ let build_inductive env env_ar record finite inds recargs cst =
let rtbl = Array.init (List.length cnames) transf in
(* Build the inductive packet *)
{ mind_typename = id;
- mind_nparams = nparamargs;
- mind_params_ctxt = params;
mind_user_arity = ar;
mind_nf_arity = nf_ar;
mind_nrealargs = rel_context_nhyps ar_sign - nparamargs;
@@ -542,6 +574,9 @@ let build_inductive env env_ar record finite inds recargs cst =
mind_ntypes = ntypes;
mind_finite = finite;
mind_hyps = hyps;
+ mind_nparams = nparamargs;
+ mind_nparams_rec = nmr;
+ mind_params_ctxt = params;
mind_packets = packets;
mind_constraints = cst;
mind_equiv = None;
@@ -552,10 +587,11 @@ let build_inductive env env_ar record finite inds recargs cst =
let check_inductive env mie =
(* First type-check the inductive definition *)
- let (env_arities, inds, cst) = typecheck_inductive env mie in
+ let (env_ar, params, inds, cst) = typecheck_inductive env mie in
(* Then check positivity conditions *)
- let recargs = check_positivity env_arities inds in
+ let (nmr,recargs) = check_positivity env_ar params inds in
(* Build the inductive packets *)
- build_inductive env env_arities mie.mind_entry_record mie.mind_entry_finite
- inds recargs cst
+ build_inductive env env_ar params mie.mind_entry_record mie.mind_entry_finite
+ inds nmr recargs cst
+
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index e3b152aae..bf64dfda0 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -80,13 +80,13 @@ let instantiate_params t args sign =
if rem_args <> [] then fail();
type_app (substl subs) ty
-let full_inductive_instantiate mip params t =
- instantiate_params t params mip.mind_params_ctxt
+let full_inductive_instantiate mib params t =
+ instantiate_params t params mib.mind_params_ctxt
-let full_constructor_instantiate (((mind,_),mib,mip),params) =
+let full_constructor_instantiate (((mind,_),mib,_),params) =
let inst_ind = constructor_instantiate mind mib in
(fun t ->
- instantiate_params (inst_ind t) params mip.mind_params_ctxt)
+ instantiate_params (inst_ind t) params mib.mind_params_ctxt)
(************************************************************************)
(************************************************************************)
@@ -148,12 +148,12 @@ let local_rels ctxt =
rels
(* Get type of inductive, with parameters instantiated *)
-let get_arity mip params =
+let get_arity mib mip params =
let arity = mip.mind_nf_arity in
- destArity (full_inductive_instantiate mip params arity)
+ destArity (full_inductive_instantiate mib params arity)
-let build_dependent_inductive ind mip params =
- let arsign,_ = get_arity mip params in
+let build_dependent_inductive ind mib mip params =
+ let arsign,_ = get_arity mib mip params in
let nrealargs = mip.mind_nrealargs in
applist
(mkInd ind, (List.map (lift nrealargs) params)@(local_rels arsign))
@@ -162,9 +162,9 @@ let build_dependent_inductive ind mip params =
(* This exception is local *)
exception LocalArity of (constr * constr * arity_error) option
-let is_correct_arity env c pj ind mip params =
+let is_correct_arity env c pj ind mib mip params =
let kelim = mip.mind_kelim in
- let arsign,s = get_arity mip params in
+ let arsign,s = get_arity mib mip params in
let nodep_ar = it_mkProd_or_LetIn (mkSort s) arsign in
let rec srec env pt t u =
let pt' = whd_betadeltaiota env pt in
@@ -180,7 +180,7 @@ let is_correct_arity env c pj ind mip params =
let ksort = match kind_of_term k with
| Sort s -> family_of_sort s
| _ -> raise (LocalArity None) in
- let dep_ind = build_dependent_inductive ind mip params in
+ let dep_ind = build_dependent_inductive ind mib mip params in
let univ =
try conv env a1 dep_ind
with NotConvertible -> raise (LocalArity None) in
@@ -224,7 +224,7 @@ let build_branches_type ind mib mip params dep p =
let (args,ccl) = decompose_prod_assum typi in
let nargs = rel_context_length args in
let (_,allargs) = decompose_app ccl in
- let (lparams,vargs) = list_chop mip.mind_nparams allargs in
+ let (lparams,vargs) = list_chop mib.mind_nparams allargs in
let cargs =
if dep then
let cstr = ith_constructor_of_inductive ind (i+1) in
@@ -244,10 +244,10 @@ let build_case_type dep p c realargs =
let type_case_branches env (ind,largs) pj c =
let (mib,mip) = lookup_mind_specif env ind in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let (params,realargs) = list_chop nparams largs in
let p = pj.uj_val in
- let (dep,univ) = is_correct_arity env c pj ind mip params in
+ let (dep,univ) = is_correct_arity env c pj ind mib mip params in
let lc = build_branches_type ind mib mip params dep p in
let ty = build_case_type dep p c realargs in
(lc, ty, univ)
@@ -270,7 +270,7 @@ let check_case_info env indsp ci =
let (mib,mip) = lookup_mind_specif env indsp in
if
(indsp <> ci.ci_ind) or
- (mip.mind_nparams <> ci.ci_npar)
+ (mib.mind_nparams <> ci.ci_npar)
then raise (TypeError(env,WrongCaseInfo(indsp,ci)))
(************************************************************************)
@@ -770,7 +770,7 @@ let check_one_cofix env nbfix def deftype =
let lra =vlra.(i-1) in
let mI = inductive_of_constructor cstr_kn in
let (mib,mip) = lookup_mind_specif env mI in
- let realargs = list_skipn mip.mind_nparams args in
+ let realargs = list_skipn mib.mind_nparams args in
let rec process_args_of_constr = function
| (t::lr), (rar::lrar) ->
if rar = mk_norec then
diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml
index 033eeec79..f87dc90e4 100644
--- a/kernel/subtyping.ml
+++ b/kernel/subtyping.ml
@@ -114,8 +114,8 @@ let check_inductive cst env msid1 l info1 mib2 spec2 =
&& Array.length mib2.mind_packets >= 1);
(* TODO: we should allow renaming of parameters at least ! *)
- check (fun mib -> mib.mind_packets.(0).mind_nparams);
- check (fun mib -> mib.mind_packets.(0).mind_params_ctxt);
+ check (fun mib -> mib.mind_nparams);
+ check (fun mib -> mib.mind_params_ctxt);
begin
match mib2.mind_equiv with
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 5ef84adc7..cdc9fa0f7 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -318,7 +318,7 @@ let find_rectype typ =
let construct_of_constr_block env tag typ =
let (mind,_ as ind),allargs = find_rectype (whd_betadeltaiota env typ) in
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let rtbl = mip.mind_reloc_tbl in
let i = invert_tag false tag rtbl in
let params = Array.sub allargs 0 nparams in
@@ -429,7 +429,7 @@ and nf_stk env c t stk =
| Zswitch sw :: stk ->
let (mind,_ as ind),allargs = find_rectype (whd_betadeltaiota env t) in
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let params,realargs = Util.array_chop nparams allargs in
(* calcul du predicat du case,
[dep] indique si c'est un case dependant *)
diff --git a/lib/rtree.mli b/lib/rtree.mli
index 80523d588..554af8163 100644
--- a/lib/rtree.mli
+++ b/lib/rtree.mli
@@ -9,7 +9,8 @@
(*i $Id$ i*)
(* Type of regular tree with nodes labelled by values of type 'a *)
-type 'a t
+
+type 'a t
(* Building trees *)
(* build a recursive call *)
diff --git a/library/declare.ml b/library/declare.ml
index 6bace2654..1b48acf04 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -43,9 +43,9 @@ let string_of_strength = function
| Global -> "(global)"
(* XML output hooks *)
-let xml_declare_variable = ref (fun sp -> ())
-let xml_declare_constant = ref (fun sp -> ())
-let xml_declare_inductive = ref (fun sp -> ())
+let xml_declare_variable = ref (fun (sp:object_name) -> ())
+let xml_declare_constant = ref (fun (sp:bool * constant)-> ())
+let xml_declare_inductive = ref (fun (sp:bool * object_name) -> ())
let if_xml f x = if !Options.xml_export then f x else ()
@@ -291,7 +291,6 @@ let discharge_inductive ((sp,kn),(dhyps,imps,mie)) =
Discharge.process_inductive sechyps repl mie)
let dummy_one_inductive_entry mie = {
- mind_entry_params = [];
mind_entry_typename = mie.mind_entry_typename;
mind_entry_arity = mkProp;
mind_entry_consnames = mie.mind_entry_consnames;
@@ -300,6 +299,7 @@ let dummy_one_inductive_entry mie = {
(* Hack to reduce the size of .vo: we keep only what load/open needs *)
let dummy_inductive_entry (_,imps,m) = ([],imps,{
+ mind_entry_params = [];
mind_entry_record = false;
mind_entry_finite = true;
mind_entry_inds = List.map dummy_one_inductive_entry m.mind_entry_inds })
diff --git a/library/library.ml b/library/library.ml
index ce4fa533c..456658760 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -308,7 +308,8 @@ let (in_import, out_import) =
(*s Loading from disk to cache (preparation phase) *)
let vo_magic_number7 = 07992 (* V8.0 final old syntax *)
-let vo_magic_number8 = 08002 (* V8.0 final new syntax *)
+(* let vo_magic_number8 = 08002 (* V8.0 final new syntax *) *)
+let vo_magic_number8 = 08003 (* V8.0 final new syntax + new params in ind *)
let (raw_extern_library7, raw_intern_library7) =
System.raw_extern_intern vo_magic_number7 ".vo"
diff --git a/parsing/prettyp.ml b/parsing/prettyp.ml
index ac5c7430f..97139ec15 100644
--- a/parsing/prettyp.ml
+++ b/parsing/prettyp.ml
@@ -285,7 +285,7 @@ let print_constructors envpar names types =
let build_inductive sp tyi =
let (mib,mip) = Global.lookup_inductive (sp,tyi) in
- let params = mip.mind_params_ctxt in
+ let params = mib.mind_params_ctxt in
let args = extended_rel_list 0 params in
let env = Global.env() in
let arity = hnf_prod_applist env mip.mind_user_arity args in
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 536317613..8b6e476c7 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -219,7 +219,7 @@ let detype_case computable detype detype_eqn testdep
let (mib,mip) = Inductive.lookup_mind_specif tenv indsp in
let get_consnarg j =
let typi = mis_nf_constructor_type (indsp,mib,mip) (j+1) in
- let _,t = decompose_prod_n_assum (List.length mip.mind_params_ctxt) typi in
+ let _,t = decompose_prod_n_assum (List.length mib.mind_params_ctxt) typi in
List.rev (fst (decompose_prod_assum t)) in
let consnargs = Array.init (Array.length mip.mind_consnames) get_consnarg in
let consnargsl = Array.map List.length consnargs in
@@ -253,7 +253,7 @@ let detype_case computable detype detype_eqn testdep
let aliastyp =
if List.for_all ((=) Anonymous) nl then None
else
- let pars = list_tabulate (fun _ -> Anonymous) mip.mind_nparams
+ let pars = list_tabulate (fun _ -> Anonymous) mib.mind_nparams
in Some (dummy_loc,indsp,pars@nl) in
n, aliastyp, Some typ, Some p
in
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index e6d674a5e..e58609195 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -41,7 +41,7 @@ let mkLambda_string s t c = mkLambda (Name (id_of_string s), t, c)
lifter les paramètres globaux *)
let mis_make_case_com depopt env sigma (ind,mib,mip) kind =
- let lnamespar = mip.mind_params_ctxt in
+ let lnamespar = mib.mind_params_ctxt in
let dep = match depopt with
| None -> mip.mind_sort <> (Prop Null)
| Some d -> d
@@ -191,7 +191,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
let c = it_mkProd_or_LetIn base cs.cs_args in
process_constr env 0 c recargs nhyps []
-let make_rec_branch_arg env sigma (nparams,fvect,decF) f cstr recargs =
+let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
let process_pos env fk =
let rec prec env i hyps p =
let p',largs = whd_betadeltaiota_nolet_stack env sigma p in
@@ -203,7 +203,7 @@ let make_rec_branch_arg env sigma (nparams,fvect,decF) f cstr recargs =
let d = (n,Some b,t) in
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::hyps) c)
| Ind _ ->
- let realargs = list_skipn nparams largs
+ let realargs = list_skipn nparrec largs
and arg = appvect (mkRel (i+1),extended_rel_vect 0 hyps) in
applist(lift i fk,realargs@[arg])
| _ -> assert false
@@ -245,9 +245,12 @@ let make_rec_branch_arg env sigma (nparams,fvect,decF) f cstr recargs =
process_constr env 0 f (List.rev cstr.cs_args, recargs)
(* Main function *)
-let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
- let nparams = mip.mind_nparams in
- let lnamespar = mip.mind_params_ctxt in
+let mis_make_indrec env sigma listdepkind mib =
+ let nparams = mib.mind_nparams in
+ let nparrec = mib. mind_nparams_rec in
+ let lnamespar = mib.mind_params_ctxt in
+ let lnonparrec,lnamesparrec =
+ list_chop (nparams-nparrec) mib.mind_params_ctxt in
let nrec = List.length listdepkind in
let depPvec =
Array.create mib.mind_ntypes (None : (bool * constr) option) in
@@ -262,6 +265,11 @@ let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
assign nrec listdepkind in
let recargsvec =
Array.map (fun mip -> mip.mind_recargs) mib.mind_packets in
+ (* recarg information for non recursive parameters *)
+ let rec recargparn l n =
+ if n = 0 then l else recargparn (mk_norec::l) (n-1)
+ in
+ let recargpar = recargparn [] (nparams-nparrec) in
let make_one_rec p =
let makefix nbconstruct =
let rec mrec i ln ltyp ldef = function
@@ -272,59 +280,86 @@ let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
(* arity in the context of the fixpoint, i.e.
P1..P_nrec f1..f_nbconstruct *)
- let args = extended_rel_list (nrec+nbconstruct) lnamespar in
+ let args = extended_rel_list (nrec+nbconstruct) lnamesparrec in
let indf = make_ind_family(indi,args) in
let arsign,_ = get_arity env indf in
let depind = build_dependent_inductive env indf in
let deparsign = (Anonymous,None,depind)::arsign in
-
+
+ let nonrecpar = nparams-nparrec in
let nar = mipi.mind_nrealargs in
let ndepar = nar + 1 in
- let dect = ndepar+nrec+nbconstruct in
+ let dect = nonrecpar+ndepar+nrec+nbconstruct in
- let branches =
(* constructors in context of the Cases expr, i.e.
- P1..P_nrec f1..f_nbconstruct F_1..F_nrec a_1..a_nar x:I *)
- let args' = extended_rel_list (dect+nrec) lnamespar in
- let indf' = make_ind_family(indi,args') in
+ P1..P_nrec f1..f_nbconstruct F_1..F_nrec a_1..a_nar x:I *)
+ let args' = extended_rel_list (dect+nrec) lnamesparrec in
+ let args'' = extended_rel_list ndepar lnonparrec in
+ let indf' = make_ind_family(indi,args'@args'') in
+
+ let branches =
let constrs = get_constructors env indf' in
- let vecfi = rel_vect (dect-i-nctyi) nctyi in
+ let fi = rel_vect (dect-i-nctyi) nctyi in
+ let vecfi = Array.map
+ (fun f -> appvect (f,rel_vect ndepar nonrecpar))
+ fi
+ in
array_map3
- (make_rec_branch_arg env sigma (nparams,depPvec,ndepar))
- vecfi constrs (dest_subterms recargsvec.(tyi)) in
+ (make_rec_branch_arg env sigma
+ (nparrec,depPvec,ndepar+nonrecpar))
+ vecfi constrs (dest_subterms recargsvec.(tyi))
+ in
let j = (match depPvec.(tyi) with
| Some (_,c) when isRel c -> destRel c
- | _ -> assert false) in
+ | _ -> assert false)
+ in
+
+ (* Predicate in the context of the case *)
+
+ let depind' = build_dependent_inductive env indf' in
+ let arsign',_ = get_arity env indf' in
+ let deparsign' = (Anonymous,None,depind')::arsign' in
+
let pargs =
- if dep then extended_rel_vect 0 deparsign
- else extended_rel_vect 1 arsign in
- let concl = appvect (mkRel (nbconstruct+ndepar+j),pargs) in
+ let nrpar = extended_rel_list (2*ndepar) lnonparrec
+ and nrar = if dep then extended_rel_list 0 deparsign'
+ else extended_rel_list 1 arsign'
+ in nrpar@nrar
+
+ in
(* body of i-th component of the mutual fixpoint *)
let deftyi =
let ci = make_default_case_info env RegularStyle indi in
- let p =
+ let concl = applist (mkRel (dect+j+ndepar),pargs) in
+ let pred =
it_mkLambda_or_LetIn_name env
((if dep then mkLambda_name env else mkLambda)
- (Anonymous,depind,concl))
- arsign
+ (Anonymous,depind',concl))
+ arsign'
in
it_mkLambda_or_LetIn_name env
- (mkCase (ci, lift (nrec+ndepar) p,
+ (mkCase (ci, pred,
mkRel 1,
branches))
(lift_rel_context nrec deparsign)
in
(* type of i-th component of the mutual fixpoint *)
+
let typtyi =
- it_mkProd_or_LetIn_name env
+ let concl =
+ let pargs = if dep then extended_rel_vect 0 deparsign
+ else extended_rel_vect 1 arsign
+ in appvect (mkRel (nbconstruct+ndepar+nonrecpar+j),pargs)
+ in it_mkProd_or_LetIn_name env
concl
deparsign
in
- mrec (i+nctyi) (nar::ln) (typtyi::ltyp) (deftyi::ldef) rest
+ mrec (i+nctyi) (nar+nonrecpar::ln) (typtyi::ltyp)
+ (deftyi::ldef) rest
| [] ->
let fixn = Array.of_list (List.rev ln) in
let fixtyi = Array.of_list (List.rev ltyp) in
@@ -343,7 +378,8 @@ let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
make_branch env (i+j) rest
else
let recarg = (dest_subterms recargsvec.(tyi)).(j) in
- let vargs = extended_rel_list (nrec+i+j) lnamespar in
+ let recarg = recargpar@recarg in
+ let vargs = extended_rel_list (nrec+i+j) lnamesparrec in
let indf = (indi, vargs) in
let cs = get_constructor (indi,mibi,mipi,vargs) (j+1) in
let p_0 =
@@ -358,7 +394,7 @@ let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
in
let rec put_arity env i = function
| (indi,_,_,dep,kinds)::rest ->
- let indf = make_ind_family (indi,extended_rel_list i lnamespar) in
+ let indf = make_ind_family (indi,extended_rel_list i lnamesparrec) in
let typP = make_arity env dep indf (new_sort_in_family kinds) in
mkLambda_string "P" typP
(put_arity (push_rel (Anonymous,None,typP) env) (i+1) rest)
@@ -366,12 +402,14 @@ let mis_make_indrec env sigma listdepkind (ind,mib,mip) =
make_branch env 0 listdepkind
in
let (indi,mibi,mipi,dep,kind) = List.nth listdepkind p in
- let env' = push_rel_context lnamespar env in
+
if mis_is_recursive_subset
(List.map (fun (indi,_,_,_,_) -> snd indi) listdepkind)
mipi.mind_recargs
then
- it_mkLambda_or_LetIn_name env (put_arity env' 0 listdepkind) lnamespar
+ let env' = push_rel_context lnamesparrec env in
+ it_mkLambda_or_LetIn_name env (put_arity env' 0 listdepkind)
+ lnamesparrec
else
mis_make_case_com (Some dep) env sigma (indi,mibi,mipi) kind
in
@@ -437,16 +475,22 @@ let instanciate_type_indrec_scheme sort npars term =
(**********************************************************************)
(* Interface to build complex Scheme *)
+(* Check inductive types only occurs once
+(otherwise we obtain a meaning less scheme) *)
let check_arities listdepkind =
- List.iter
- (function (indi,mibi,mipi,dep,kind) ->
+ let _ = List.fold_left
+ (fun ln ((_,ni),mibi,mipi,dep,kind) ->
let id = mipi.mind_typename in
let kelim = mipi.mind_kelim in
if not (List.exists ((=) kind) kelim) then
raise
- (InductiveError (BadInduction (dep, id, new_sort_in_family kind))))
- listdepkind
+ (InductiveError (BadInduction (dep, id, new_sort_in_family kind)))
+ else if List.mem ni ln then raise
+ (InductiveError NotMutualInScheme)
+ else ni::ln)
+ [] listdepkind
+ in true
let build_mutual_indrec env sigma = function
| (mind,mib,mip,dep,s)::lrecspec ->
@@ -464,14 +508,14 @@ let build_mutual_indrec env sigma = function
lrecspec)
in
let _ = check_arities listdepkind in
- mis_make_indrec env sigma listdepkind (mind,mib,mip)
+ mis_make_indrec env sigma listdepkind mib
| _ -> anomaly "build_indrec expects a non empty list of inductive types"
let build_indrec env sigma ind =
let (mib,mip) = lookup_mind_specif env ind in
let kind = family_of_sort mip.mind_sort in
let dep = kind <> InProp in
- List.hd (mis_make_indrec env sigma [(ind,mib,mip,dep,kind)] (ind,mib,mip))
+ List.hd (mis_make_indrec env sigma [(ind,mib,mip,dep,kind)] mib)
(**********************************************************************)
(* To handle old Case/Match syntax in Pretyping *)
diff --git a/pretyping/indrec.mli b/pretyping/indrec.mli
index d96908a7b..2306201b2 100644
--- a/pretyping/indrec.mli
+++ b/pretyping/indrec.mli
@@ -54,3 +54,6 @@ val make_rec_branch_arg :
val lookup_eliminator : inductive -> sorts_family -> constr
val elimination_suffix : sorts_family -> string
val make_elimination_ident : identifier -> sorts_family -> identifier
+
+
+
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index a0b2cb80f..c540a4a1f 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -105,7 +105,7 @@ 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
(* Annotation for cases *)
let make_case_info env ind style pats_source =
@@ -115,7 +115,7 @@ 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_pp_info = print_info }
let make_default_case_info env style ind =
@@ -140,6 +140,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
@@ -151,17 +152,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;
@@ -194,7 +195,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))
@@ -243,7 +244,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
@@ -313,12 +314,12 @@ let set_names env n brty =
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
@@ -327,7 +328,7 @@ 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
+ 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)
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index b5d6318dc..497739692 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -101,7 +101,7 @@ let transform_rec loc env sigma (pj,c,lf) indt =
(* build now the fixpoint *)
let lnames,_ = get_arity env indf in
let nar = List.length lnames in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let constrs = get_constructors env (lift_inductive_family (nar+2) indf) in
let branches =
array_map3
@@ -893,7 +893,7 @@ let rec pretype tycon env isevars lvar = function
let (mib,mip) = Inductive.lookup_mind_specif (Global.env()) ind in
let get_consnarg j =
let typi = mis_nf_constructor_type (ind,mib,mip) (j+1) in
- let _,t = decompose_prod_n_assum mip.mind_nparams typi in
+ let _,t = decompose_prod_n_assum mib.mind_nparams typi in
List.rev (fst (decompose_prod_assum t)) in
let consnargs = Array.init (Array.length mip.mind_consnames) get_consnarg in
let consnargsl = Array.map List.length consnargs in
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index 4157b383c..b3180b06b 100755
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -42,7 +42,7 @@ let projection_table = ref Cmap.empty
let option_fold_right f p e = match p with Some a -> f a e | None -> e
let load_structure i (_,(ind,id,kl,projs)) =
- let n = (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let n = (fst (Global.lookup_inductive ind)).Declarations.mind_nparams in
let struc =
{ s_CONST = id; s_PARAM = n; s_PROJ = projs; s_PROJKIND = kl } in
structure_table := Indmap.add ind struc !structure_table;
diff --git a/tactics/eqdecide.ml4 b/tactics/eqdecide.ml4
index 770f2d6b7..9d19d37e8 100644
--- a/tactics/eqdecide.ml4
+++ b/tactics/eqdecide.ml4
@@ -127,7 +127,7 @@ let solveLeftBranch rectype g =
try
let (lhs,rhs) = match_eqdec_partial (pf_concl g) in
let (mib,mip) = Global.lookup_inductive rectype in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let getargs l = list_skipn nparams (snd (decompose_app l)) in
let rargs = getargs rhs
and largs = getargs lhs in
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 0ef96e5fe..4797146a3 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -393,7 +393,7 @@ let rec build_discriminator sigma env dirn c sort = function
let (ind,_) = dest_ind_family indf in
let (mib,mip) = lookup_mind_specif env ind in
let _,arsort = get_arity env indf in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let (cnum_nlams,cnum_env,kont) = descend_then sigma env c cnum in
let newc = mkRel(cnum_nlams-(argnum-nparams)) in
let subval = build_discriminator sigma cnum_env dirn newc sort l in
@@ -673,7 +673,7 @@ let rec build_injrec sigma env dflt c = function
let cty = type_of env sigma c in
let (ity,_) = find_mrectype env sigma cty in
let (mib,mip) = lookup_mind_specif env ity in
- let nparams = mip.mind_nparams in
+ let nparams = mib.mind_nparams in
let (cnum_nlams,cnum_env,kont) = descend_then sigma env c cnum in
let newc = mkRel(cnum_nlams-(argnum-nparams)) in
let (subval,tuplety,dfltval) =
diff --git a/tactics/hipattern.ml b/tactics/hipattern.ml
index dfdacbb99..c3735b2c8 100644
--- a/tactics/hipattern.ml
+++ b/tactics/hipattern.ml
@@ -120,7 +120,7 @@ let match_with_unit_type t =
let constr_types = mip.mind_nf_lc in
let nconstr = Array.length mip.mind_consnames in
let zero_args c =
- nb_prod c = mip.mind_nparams in
+ nb_prod c = mib.mind_nparams in
if nconstr = 1 && array_for_all zero_args constr_types then
Some hdapp
else
@@ -213,11 +213,11 @@ let match_with_nodep_ind t =
| Ind ind ->
let (mib,mip) = Global.lookup_inductive ind in
if Array.length (mib.mind_packets)>1 then None else
- let nodep_constr = has_nodep_prod_after mip.mind_nparams in
+ let nodep_constr = has_nodep_prod_after mib.mind_nparams in
if array_for_all nodep_constr mip.mind_nf_lc then
let params=
if mip.mind_nrealargs=0 then args else
- fst (list_chop mip.mind_nparams args) in
+ fst (list_chop mib.mind_nparams args) in
Some (hdapp,params,mip.mind_nrealargs)
else
None
@@ -233,7 +233,7 @@ let match_with_sigma_type t=
if (Array.length (mib.mind_packets)=1) &&
(mip.mind_nrealargs=0) &&
(Array.length mip.mind_consnames=1) &&
- has_nodep_prod_after (mip.mind_nparams+1) mip.mind_nf_lc.(0) then
+ has_nodep_prod_after (mib.mind_nparams+1) mip.mind_nf_lc.(0) then
(*allowing only 1 existential*)
Some (hdapp,args)
else
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index e30bb7e63..29fd46f3e 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -288,7 +288,7 @@ let compute_construtor_signatures isrec (_,k as ity) =
| _ -> anomaly "compute_construtor_signatures"
in
let (mib,mip) = Global.lookup_inductive ity in
- let n = mip.mind_nparams in
+ let n = mib.mind_nparams in
let lc =
Array.map (fun c -> snd (decompose_prod_n_assum n c)) mip.mind_nf_lc in
let lrecargs = dest_subterms mip.mind_recargs in
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 42e18fadc..2da3e2cf5 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -220,7 +220,7 @@ let declare_one_elimination ind =
let env = Global.env () in
let sigma = Evd.empty in
let elim_scheme = Indrec.build_indrec env sigma ind in
- let npars = mip.mind_nparams in
+ let npars = mib.mind_nparams_rec in
let make_elim s = Indrec.instanciate_indrec_scheme s npars elim_scheme in
let kelim = mip.mind_kelim in
(* in case the inductive has a type elimination, generates only one
@@ -373,15 +373,15 @@ let interp_mutual lparams lnamearconstrs finite =
in
(* Build the inductive entry *)
- { mind_entry_params = params';
- mind_entry_typename = name;
+ { mind_entry_typename = name;
mind_entry_arity = ar;
mind_entry_consnames = constrnames;
mind_entry_lc = constrs })
(List.rev arityl) lnamearconstrs
in
States.unfreeze fs;
- notations, { mind_entry_record = false;
+ notations, { mind_entry_params = params';
+ mind_entry_record = false;
mind_entry_finite = finite;
mind_entry_inds = mispecvec }
with e -> States.unfreeze fs; raise e
@@ -397,6 +397,7 @@ let declare_mutual_with_eliminations isrecord mie =
(* Very syntactical equality *)
let eq_la d1 d2 = match d1,d2 with
| LocalRawAssum (nal,ast), LocalRawAssum (nal',ast') ->
+ (List.length nal = List.length nal') &&
List.for_all2 (fun (_,na) (_,na') -> na = na') nal nal'
& (try let _ = Constrextern.check_same_type ast ast' in true with _ -> false)
| LocalRawDef ((_,id),ast), LocalRawDef ((_,id'),ast') ->
diff --git a/toplevel/command.mli b/toplevel/command.mli
index d6eb9cfc5..be815ffd6 100644
--- a/toplevel/command.mli
+++ b/toplevel/command.mli
@@ -84,3 +84,5 @@ val admit : unit -> unit
and the current global env *)
val get_current_context : unit -> Evd.evar_map * Environ.env
+
+
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index 8c71c0513..f10a461d6 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -35,48 +35,54 @@ let detype_param = function
I1..Ip:(B1 y1..yq)..(Bp y1..yq) |- ci : (y1..yq:C1..Cq)Ti[Ij:=(Ij y1..yq)]
*)
-let abstract_inductive hyps inds =
+let abstract_inductive hyps nparams inds =
let ntyp = List.length inds in
let nhyp = named_context_length hyps in
let args = instance_from_named_context (List.rev hyps) in
let subs = list_tabulate (fun k -> lift nhyp (mkApp(mkRel (k+1),args))) ntyp in
let inds' =
List.map
- (function (np,tname,arity,cnames,lc) ->
+ (function (tname,arity,cnames,lc) ->
let lc' = List.map (substl subs) lc in
let lc'' = List.map (fun b -> Termops.it_mkNamedProd_wo_LetIn b hyps) lc' in
let arity' = Termops.it_mkNamedProd_wo_LetIn arity hyps in
- (np,tname,arity',cnames,lc''))
+ (tname,arity',cnames,lc''))
inds in
+ let nparams' = nparams + Array.length args in
+(* To be sure to be the same as before, should probably be moved to process_inductive *)
+ let params' = let (_,arity,_,_) = List.hd inds' in
+ let (params,_) = decompose_prod_n_assum nparams' arity in
+ List.map detype_param params
+ in
+ let ind'' =
List.map
- (fun (nparams,a,arity,c,lc) ->
- let nparams' = nparams + Array.length args in
- let params, short_arity = decompose_prod_n_assum nparams' arity in
+ (fun (a,arity,c,lc) ->
+ let _, short_arity = decompose_prod_n_assum nparams' arity in
let shortlc =
- List.map (fun c -> snd (decompose_prod_n_assum nparams' c))lc in
- let params' = List.map detype_param params in
- { mind_entry_params = params';
- mind_entry_typename = a;
+ List.map (fun c -> snd (decompose_prod_n_assum nparams' c)) lc in
+ { mind_entry_typename = a;
mind_entry_arity = short_arity;
mind_entry_consnames = c;
mind_entry_lc = shortlc })
inds'
+ in (params',ind'')
+
let process_inductive sechyps modlist mib =
+ let nparams = mib.mind_nparams in
let inds =
array_map_to_list
(fun mip ->
- let nparams = mip.mind_nparams in
let arity = expmod_constr modlist mip.mind_user_arity in
let lc = Array.map (expmod_constr modlist) mip.mind_user_lc in
- (nparams,
- mip.mind_typename,
+ (mip.mind_typename,
arity,
Array.to_list mip.mind_consnames,
Array.to_list lc))
mib.mind_packets in
let sechyps' = map_named_context (expmod_constr modlist) sechyps in
- let inds' = abstract_inductive sechyps' inds in
+ let (params',inds') = abstract_inductive sechyps' nparams inds in
{ mind_entry_record = mib.mind_record;
mind_entry_finite = mib.mind_finite;
+ mind_entry_params = params';
mind_entry_inds = inds' }
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index ad41844ce..8b72d5b01 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -586,7 +586,7 @@ let error_bad_induction dep indid kind =
str "is not allowed"
let error_not_mutual_in_scheme () =
- str "Induction schemes is concerned only with mutually inductive types"
+ str "Induction schemes are concerned only with distinct mutually inductive types"
let explain_inductive_error = function
(* These are errors related to inductive constructions *)
diff --git a/toplevel/record.ml b/toplevel/record.ml
index f6d8b6000..6b412ea68 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -146,7 +146,7 @@ let subst_projection fid l c =
let declare_projections indsp coers fields =
let env = Global.env() in
let (mib,mip) = Global.lookup_inductive indsp in
- let paramdecls = mip.mind_params_ctxt in
+ let paramdecls = mib.mind_params_ctxt in
let r = mkInd indsp in
let rp = applist (r, extended_rel_list 0 paramdecls) in
let paramargs = extended_rel_list 1 paramdecls in (*def in [[params;x:rp]]*)
@@ -223,13 +223,13 @@ let definition_structure ((is_coe,(_,idstruc)),ps,cfs,idbuild,s) =
let ind = applist (mkRel (1+List.length params+List.length fields), args) in
let type_constructor = it_mkProd_or_LetIn ind fields in
let mie_ind =
- { mind_entry_params = List.map degenerate_decl params;
- mind_entry_typename = idstruc;
+ { mind_entry_typename = idstruc;
mind_entry_arity = mkSort s;
mind_entry_consnames = [idbuild];
mind_entry_lc = [type_constructor] } in
let mie =
- { mind_entry_record = true;
+ { mind_entry_params = List.map degenerate_decl params;
+ mind_entry_record = true;
mind_entry_finite = true;
mind_entry_inds = [mie_ind] } in
let sp = declare_mutual_with_eliminations true mie in