aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2001-02-14 15:41:55 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2001-02-14 15:41:55 +0000
commite7d592ada2d681876d2bcf0a45d4267b3746064f (patch)
treee0b7eb1e67b1871b7cb356c33f66182f6dde86c3
parent045c85f66a65c6aaedeed578d352c6de27d5e6a4 (diff)
Mise en place d'un système optionnel de discharge immédiat; prise en compte des défs locales dans les arguments des inductifs; nettoyage divers
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@1381 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--kernel/cooking.ml3
-rw-r--r--kernel/declarations.ml7
-rw-r--r--kernel/declarations.mli7
-rw-r--r--kernel/environ.ml16
-rw-r--r--kernel/environ.mli1
-rw-r--r--kernel/indtypes.ml85
-rw-r--r--kernel/indtypes.mli5
-rw-r--r--kernel/inductive.ml89
-rw-r--r--kernel/inductive.mli42
-rw-r--r--kernel/instantiate.ml17
-rw-r--r--kernel/instantiate.mli4
-rw-r--r--kernel/names.ml4
-rw-r--r--kernel/names.mli3
-rw-r--r--kernel/reduction.mli3
-rw-r--r--kernel/safe_typing.ml56
-rw-r--r--kernel/safe_typing.mli11
-rw-r--r--kernel/sign.ml40
-rw-r--r--kernel/sign.mli14
-rw-r--r--kernel/term.ml18
-rw-r--r--kernel/term.mli6
-rw-r--r--kernel/typeops.ml13
-rw-r--r--library/declare.ml171
-rw-r--r--library/declare.mli5
-rw-r--r--library/global.ml12
-rw-r--r--library/global.mli10
-rwxr-xr-xlibrary/nametab.ml35
-rwxr-xr-xlibrary/nametab.mli4
-rw-r--r--toplevel/class.ml9
-rw-r--r--toplevel/command.ml3
-rw-r--r--toplevel/discharge.ml27
-rw-r--r--toplevel/record.ml16
-rw-r--r--toplevel/record.mli3
32 files changed, 510 insertions, 229 deletions
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index cfbd760d8..f0be35882 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -145,5 +145,6 @@ let cook_constant env r =
let cb = lookup_constant r.d_from env in
let typ = expmod_type env r.d_modlist cb.const_type in
let body = option_app (expmod_constr env r.d_modlist) cb.const_body in
- let hyps = map_named_context (expmod_constr env r.d_modlist) cb.const_hyps in
+ let hyps = List.map (fun (sp,c,t) -> (basename sp,c,t)) cb.const_hyps in
+ let hyps = map_named_context (expmod_constr env r.d_modlist) hyps in
abstract_constant r.d_abstract hyps (body,typ)
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index 8be72eb94..9de1866cc 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -12,7 +12,7 @@ type constant_body = {
const_kind : path_kind;
const_body : constr option;
const_type : types;
- const_hyps : named_context;
+ const_hyps : section_context;
const_constraints : constraints;
mutable const_opaque : bool }
@@ -52,12 +52,13 @@ type one_inductive_body = {
mind_kelim : sorts list;
mind_listrec : (recarg list) array;
mind_finite : bool;
- mind_nparams : int }
+ mind_nparams : int;
+ mind_params_ctxt : rel_context }
type mutual_inductive_body = {
mind_kind : path_kind;
mind_ntypes : int;
- mind_hyps : named_context;
+ mind_hyps : section_context;
mind_packets : one_inductive_body array;
mind_constraints : constraints;
mind_singl : constr option }
diff --git a/kernel/declarations.mli b/kernel/declarations.mli
index aca660567..531a616ba 100644
--- a/kernel/declarations.mli
+++ b/kernel/declarations.mli
@@ -17,7 +17,7 @@ type constant_body = {
const_kind : path_kind;
const_body : constr option;
const_type : types;
- const_hyps : named_context; (* New: younger hyp at top *)
+ const_hyps : section_context; (* New: younger hyp at top *)
const_constraints : constraints;
mutable const_opaque : bool }
@@ -61,12 +61,13 @@ type one_inductive_body = {
mind_kelim : sorts list;
mind_listrec : (recarg list) array;
mind_finite : bool;
- mind_nparams : int }
+ mind_nparams : int;
+ mind_params_ctxt : rel_context }
type mutual_inductive_body = {
mind_kind : path_kind;
mind_ntypes : int;
- mind_hyps : named_context;
+ mind_hyps : section_context;
mind_packets : one_inductive_body array;
mind_constraints : constraints;
mind_singl : constr option }
diff --git a/kernel/environ.ml b/kernel/environ.ml
index cb4b1e003..6bec01ecd 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -283,16 +283,28 @@ let name_assumption env (na,c,t) =
let mkProd_or_LetIn_name env b d = mkProd_or_LetIn (name_assumption env d) b
let mkLambda_or_LetIn_name env b d = mkLambda_or_LetIn (name_assumption env d)b
-let it_mkProd_or_LetIn_name env = List.fold_left (mkProd_or_LetIn_name env)
-let it_mkLambda_or_LetIn_name env = List.fold_left (mkLambda_or_LetIn_name env)
+let name_context env hyps =
+ snd
+ (List.fold_left
+ (fun (env,hyps) d ->
+ let d' = name_assumption env d in (push_rel d' env, d' :: hyps))
+ (env,[]) (List.rev hyps))
let it_mkProd_wo_LetIn = List.fold_left (fun c d -> mkProd_wo_LetIn d c)
let it_mkProd_or_LetIn = List.fold_left (fun c d -> mkProd_or_LetIn d c)
let it_mkLambda_or_LetIn = List.fold_left (fun c d -> mkLambda_or_LetIn d c)
+let it_mkProd_or_LetIn_name env b hyps =
+ it_mkProd_or_LetIn b (name_context env hyps)
+
+let it_mkLambda_or_LetIn_name env b hyps =
+ it_mkLambda_or_LetIn b (name_context env hyps)
+
let it_mkNamedProd_or_LetIn = it_named_context_quantifier mkNamedProd_or_LetIn
let it_mkNamedLambda_or_LetIn = it_named_context_quantifier mkNamedLambda_or_LetIn
+let it_mkNamedProd_wo_LetIn = it_named_context_quantifier mkNamedProd_wo_LetIn
+
let make_all_name_different env =
let avoid = ref (ids_of_named_context (named_context env)) in
process_rel_context
diff --git a/kernel/environ.mli b/kernel/environ.mli
index 65a2bb671..eba1e0979 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -140,6 +140,7 @@ val it_mkProd_or_LetIn : constr -> rel_context -> constr
val it_mkNamedLambda_or_LetIn : constr -> named_context -> constr
val it_mkNamedProd_or_LetIn : constr -> named_context -> constr
+val it_mkNamedProd_wo_LetIn : constr -> named_context -> constr
(* [lambda_create env (t,c)] builds [[x:t]c] where [x] is a name built
from [t]; [prod_create env (t,c)] builds [(x:t)c] where [x] is a
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 2307a405f..228e2bafa 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -132,16 +132,20 @@ let failwith_non_pos_vect n ntypes v =
done;
anomaly "failwith_non_pos_vect: some k in [n;n+ntypes-1] should occur in v"
-let check_correct_par env nparams ntypes n l largs =
+let check_correct_par env hyps nparams ntypes n l largs =
let largs = Array.of_list largs in
if Array.length largs < nparams then
raise (IllFormedInd (LocalNotEnoughArgs l));
let (lpar,largs') = array_chop nparams largs in
- for k = 0 to nparams - 1 do
- match kind_of_term (whd_betadeltaiotaeta env Evd.empty lpar.(k)) with
- | IsRel w when (n-k-1 = w) -> ()
- | _ -> raise (IllFormedInd (LocalNonPar (k+1,l)))
- done;
+ let nhyps = List.length hyps in
+ let rec check k index = function
+ | [] -> ()
+ | (_,Some _,_)::hyps -> check k (index+1) hyps
+ | _::hyps ->
+ match kind_of_term (whd_betadeltaiotaeta env Evd.empty lpar.(k)) with
+ | IsRel w when w = index -> check (k-1) (index+1) hyps
+ | _ -> raise (IllFormedInd (LocalNonPar (k+1,l)))
+ in check (nparams-1) (n-nhyps) hyps;
if not (array_for_all (noccur_between n ntypes) largs') then
failwith_non_pos_vect n ntypes largs'
@@ -156,7 +160,8 @@ let abstract_mind_lc env ntyps npars lc =
in
Array.map (compose (nf_beta env Evd.empty) (substl make_abs)) lc
-let listrec_mconstr env ntypes nparams i indlc =
+let listrec_mconstr env ntypes hyps nparams i indlc =
+ let nhyps = List.length hyps in
(* check the inductive types occur positively in [c] *)
let rec check_pos env n c =
let x,largs = whd_betadeltaiota_stack env Evd.empty c in
@@ -168,10 +173,10 @@ let listrec_mconstr env ntypes nparams i indlc =
check_pos (push_rel_assum (na, b) env) (n+1) d
| IsRel k ->
if k >= n && k<n+ntypes then begin
- check_correct_par env nparams ntypes n (k-n+1) largs;
+ check_correct_par env hyps nparams ntypes n (k-n+1) largs;
Mrec(n+ntypes-k-1)
end else if List.for_all (noccur_between n ntypes) largs then
- if (n-nparams) <= k & k <= (n-1)
+ if (n-nhyps) <= k & k <= (n-1)
then Param(n-1-k)
else Norec
else
@@ -200,7 +205,7 @@ let listrec_mconstr env ntypes nparams i indlc =
let auxlcvect = abstract_mind_lc env auxntyp auxnpar auxlc in
let newidx = n + auxntyp in
(* Extends the environment with a variable corresponding to the inductive def *)
- let env' = push_rel_assum (Anonymous,mis_user_arity mispeci) env in
+ let env' = push_rel_assum (Anonymous,mis_arity mispeci) env in
let _ =
(* fails if the inductive type occurs non positively *)
(* when substituted *)
@@ -270,7 +275,7 @@ let listrec_mconstr env ntypes nparams i indlc =
| hd ->
if check_head then
if hd = IsRel (n+ntypes-i) then
- check_correct_par env nparams ntypes n (ntypes-i+1) largs
+ check_correct_par env hyps nparams ntypes n (ntypes-i+1) largs
else
raise (IllFormedInd LocalNotConstructor)
else
@@ -282,12 +287,12 @@ let listrec_mconstr env ntypes nparams i indlc =
Array.map
(fun c ->
let c = body_of_type c in
- let sign, rawc = mind_extract_params nparams c in
+ let sign, rawc = mind_extract_params nhyps c in
let env' = push_rels sign env in
try
- check_construct env' true (1+nparams) rawc
+ check_construct env' true (1+nhyps) rawc
with IllFormedInd err ->
- explain_ind_err (ntypes-i+1) env nparams c err)
+ explain_ind_err (ntypes-i+1) env nhyps c err)
indlc
let is_recursive listind =
@@ -299,10 +304,38 @@ let is_recursive listind =
in
array_exists one_is_rec
-let cci_inductive env env_ar kind finite inds cst =
+let abstract_inductive ntypes hyps (par,np,id,arity,cnames,issmall,isunit,lc) =
+ let args = instance_from_named_context (List.rev hyps) in
+ let nhyps = List.length hyps in
+ let nparams = List.length args in (* nparams = nhyps - nb(letin) *)
+ let new_refs =
+ list_tabulate (fun k -> applist(mkRel (k+nhyps+1),args)) ntypes in
+ let abs_constructor b = it_mkNamedProd_or_LetIn (substl new_refs b) hyps in
+ let lc' = Array.map abs_constructor lc in
+ let arity' = it_mkNamedProd_or_LetIn arity hyps in
+ let par' = push_named_to_rel_context hyps par in
+ (par',np+nparams,id,arity',cnames,issmall,isunit,lc')
+
+let cci_inductive locals env env_ar kind finite inds cst =
let ntypes = List.length inds in
- let one_packet i (nparams,id,ar,cnames,issmall,isunit,lc) =
- let recargs = listrec_mconstr env_ar ntypes nparams i lc in
+ let ids =
+ List.fold_left
+ (fun acc (_,_,_,ar,_,_,_,lc) ->
+ Idset.union (global_vars_set (body_of_type ar))
+ (Array.fold_left
+ (fun acc c -> Idset.union (global_vars_set (body_of_type c)) acc)
+ acc
+ lc))
+ Idset.empty inds
+ in
+ let hyps = keep_hyps ids (named_context env) in
+ let inds' =
+ if Options.immediate_discharge then
+ List.map (abstract_inductive ntypes hyps) inds
+ else
+ inds in
+ let one_packet i (params,nparams,id,ar,cnames,issmall,isunit,lc) =
+ let recargs = listrec_mconstr env_ar ntypes params nparams i lc in
let isunit = isunit && ntypes = 1 && (not (is_recursive [0] recargs)) in
let (ar_sign,ar_sort) = splay_arity env Evd.empty (body_of_type ar) in
@@ -327,22 +360,14 @@ let cci_inductive env env_ar kind finite inds cst =
mind_kelim = kelim;
mind_listrec = recargs;
mind_finite = finite;
- mind_nparams = nparams }
- in
- let ids =
- List.fold_left
- (fun acc (_,_,ar,_,_,_,lc) ->
- Idset.union (global_vars_set (body_of_type ar))
- (Array.fold_left
- (fun acc c -> Idset.union (global_vars_set (body_of_type c)) acc)
- acc
- lc))
- Idset.empty inds
+ mind_nparams = nparams;
+ mind_params_ctxt = params }
in
- let packets = Array.of_list (list_map_i one_packet 1 inds) in
+ let sp_hyps = List.map (fun (id,b,t) -> (List.assoc id locals,b,t)) hyps in
+ let packets = Array.of_list (list_map_i one_packet 1 inds') in
{ mind_kind = kind;
mind_ntypes = ntypes;
- mind_hyps = keep_hyps ids (named_context env);
+ mind_hyps = sp_hyps;
mind_packets = packets;
mind_constraints = cst;
mind_singl = None }
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index be97f5249..d0e3a4cb0 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -42,8 +42,9 @@ val mind_check_wellformed : env -> mutual_inductive_entry -> unit
(* [cci_inductive] checks positivity and builds an inductive body *)
val cci_inductive :
- env -> env -> path_kind -> bool ->
- (int * identifier * types * identifier list * bool * bool * types array)
+ (identifier * variable_path) list -> env -> env -> path_kind -> bool ->
+ (Sign.rel_context * int * identifier * types *
+ identifier list * bool * bool * types array)
list ->
constraints ->
mutual_inductive_body
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 493cb15f5..b444baa8d 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -37,13 +37,16 @@ let mis_typename mis = mis.mis_mip.mind_typename
let mis_typepath mis =
make_path (dirpath mis.mis_sp) mis.mis_mip.mind_typename CCI
let mis_consnames mis = mis.mis_mip.mind_consnames
+let mis_conspaths mis =
+ let dir = dirpath mis.mis_sp in
+ Array.map (fun id -> make_path dir id CCI) mis.mis_mip.mind_consnames
let mis_inductive mis = ((mis.mis_sp,mis.mis_tyi),mis.mis_args)
let mis_finite mis = mis.mis_mip.mind_finite
let mis_typed_nf_lc mis =
let sign = mis.mis_mib.mind_hyps in
let args = Array.to_list mis.mis_args in
- Array.map (fun t -> Instantiate.instantiate_type sign t args)
+ Array.map (fun t -> (* Instantiate.instantiate_type sign*) t (*args*))
mis.mis_mip.mind_nf_lc
let mis_nf_lc mis = Array.map body_of_type (mis_typed_nf_lc mis)
@@ -51,25 +54,14 @@ let mis_nf_lc mis = Array.map body_of_type (mis_typed_nf_lc mis)
let mis_user_lc mis =
let sign = mis.mis_mib.mind_hyps in
let args = Array.to_list mis.mis_args in
- Array.map (fun t -> Instantiate.instantiate_type sign t args)
+ Array.map (fun t -> (*Instantiate.instantiate_type sign*) t (*args*))
(mind_user_lc mis.mis_mip)
(* gives the vector of constructors and of
types of constructors of an inductive definition
correctly instanciated *)
-let mis_type_mconstructs mispec =
- let specif = Array.map body_of_type (mis_user_lc mispec)
- and ntypes = mis_ntypes mispec
- and nconstr = mis_nconstr mispec in
- let make_Ik k = mkMutInd ((mispec.mis_sp,ntypes-k-1),mispec.mis_args)
- and make_Ck k = mkMutConstruct
- (((mispec.mis_sp,mispec.mis_tyi),k+1),
- mispec.mis_args) in
- (Array.init nconstr make_Ck,
- Array.map (substl (list_tabulate make_Ik ntypes)) specif)
-
-let mis_type_nf_mconstruct i mispec =
+let mis_nf_constructor_type i mispec =
let specif = mis_nf_lc mispec
and ntypes = mis_ntypes mispec
and nconstr = mis_nconstr mispec in
@@ -77,15 +69,15 @@ let mis_type_nf_mconstruct i mispec =
if i > nconstr then error "Not enough constructors in the type";
substl (list_tabulate make_Ik ntypes) specif.(i-1)
-let mis_type_mconstruct i mispec =
+let mis_constructor_type i mispec =
let specif = mis_user_lc mispec
and ntypes = mis_ntypes mispec
and nconstr = mis_nconstr mispec in
let make_Ik k = mkMutInd ((mispec.mis_sp,ntypes-k-1),mispec.mis_args) in
if i > nconstr then error "Not enough constructors in the type";
- type_app (substl (list_tabulate make_Ik ntypes)) specif.(i-1)
+ substl (list_tabulate make_Ik ntypes) specif.(i-1)
-let mis_user_arity mis =
+let mis_arity mis =
let hyps = mis.mis_mib.mind_hyps
and largs = Array.to_list mis.mis_args in
Instantiate.instantiate_type hyps (mind_user_arity mis.mis_mip) largs
@@ -95,11 +87,13 @@ let mis_nf_arity mis =
and largs = Array.to_list mis.mis_args in
Instantiate.instantiate_type hyps mis.mis_mip.mind_nf_arity largs
-let mis_params_ctxt mispec =
+let mis_params_ctxt mis = mis.mis_mip.mind_params_ctxt
+(*
let paramsign,_ =
- decompose_prod_n_assum mispec.mis_mip.mind_nparams
- (body_of_type (mis_nf_arity mispec))
+ decompose_prod_n_assum mis.mis_mip.mind_nparams
+ (body_of_type (mis_nf_arity mis))
in paramsign
+*)
let mis_sort mispec = mispec.mis_mip.mind_sort
@@ -239,10 +233,33 @@ let lift_constructor n cs = {
cs_concl_realargs = Array.map (liftn n (cs.cs_nargs+1)) cs.cs_concl_realargs
}
-let get_constructor (IndFamily (mispec,params)) j =
+let instantiate_params t args sign =
+ let rec inst s t = function
+ | ((_,None,_)::ctxt,a::args) ->
+ (match kind_of_term t with
+ | IsProd(_,_,t) -> inst (a::s) t (ctxt,args)
+ | _ -> anomaly"instantiate_params: type, ctxt and args mismatch")
+ | ((_,(Some b),_)::ctxt,args) ->
+ (match kind_of_term t with
+ | IsLetIn(_,_,_,t) -> inst ((substl s b)::s) t (ctxt,args)
+ | _ -> anomaly"instantiate_params: type, ctxt and args mismatch")
+ | [], [] -> substl s t
+ | _ -> anomaly"instantiate_params: type, ctxt and args mismatch"
+ in inst [] t (List.rev sign,args)
+
+let get_constructor_type (IndFamily (mispec,params)) j =
assert (j <= mis_nconstr mispec);
- let typi = mis_type_nf_mconstruct j mispec in
- let (args,ccl) = decompose_prod_assum (prod_applist typi params) in
+ let typi = mis_constructor_type j mispec in
+ instantiate_params typi params (mis_params_ctxt mispec)
+
+let get_constructors_types (IndFamily (mispec,params) as indf) =
+ Array.init (mis_nconstr mispec) (fun j -> get_constructor_type indf (j+1))
+
+let get_constructor (IndFamily (mispec,params) as indf) j =
+ assert (j <= mis_nconstr mispec);
+ let typi = mis_nf_constructor_type j mispec in
+ let typi = instantiate_params typi params (mis_params_ctxt mispec) in
+ let (args,ccl) = decompose_prod_assum typi in
let (_,allargs) = whd_stack ccl in
let (_,vargs) = list_chop (mis_nparams mispec) allargs in
{ cs_cstr = ith_constructor_of_inductive (mis_inductive mispec) j;
@@ -254,8 +271,14 @@ let get_constructor (IndFamily (mispec,params)) j =
let get_constructors (IndFamily (mispec,params) as indf) =
Array.init (mis_nconstr mispec) (fun j -> get_constructor indf (j+1))
+let get_arity_type (IndFamily (mispec,params)) =
+ let arity = body_of_type (mis_arity mispec) in
+(* instantiate_params arity params (mis_params_ctxt mispec) *)
+ prod_applist arity params
+
let get_arity (IndFamily (mispec,params)) =
let arity = body_of_type (mis_nf_arity mispec) in
+(* instantiate_params arity params (mis_params_ctxt mispec) *)
destArity (prod_applist arity params)
(* Functions to build standard types related to inductive *)
@@ -299,3 +322,23 @@ let build_branch_type env dep p cs =
cs.cs_args
else
it_mkProd_or_LetIn base cs.cs_args
+
+(* [Rel (n+m);...;Rel(n+1)] *)
+
+let rel_vect n m = Array.init m (fun i -> mkRel(n+m-i))
+
+let rel_list n m =
+ let rec reln l p =
+ if p>m then l else reln (mkRel(n+p)::l) (p+1)
+ in
+ reln [] 1
+
+let extended_rel_list n hyps =
+ let rec reln l p = function
+ | (_,None,_) :: hyps -> reln (mkRel (n+p) :: l) (p+1) hyps
+ | (_,Some _,_) :: hyps -> reln l (p+1) hyps
+ | [] -> l
+ in
+ reln [] 1 hyps
+
+let extended_rel_vect n hyps = Array.of_list (extended_rel_list n hyps)
diff --git a/kernel/inductive.mli b/kernel/inductive.mli
index 47d98e608..e7504bf16 100644
--- a/kernel/inductive.mli
+++ b/kernel/inductive.mli
@@ -42,17 +42,16 @@ val mis_typepath : inductive_instance -> section_path
val mis_is_recursive_subset : int list -> inductive_instance -> bool
val mis_is_recursive : inductive_instance -> bool
val mis_consnames : inductive_instance -> identifier array
+val mis_conspaths : inductive_instance -> section_path array
val mis_inductive : inductive_instance -> inductive
-val mis_nf_arity : inductive_instance -> types
-val mis_user_arity : inductive_instance -> types
+val mis_arity : inductive_instance -> types
val mis_params_ctxt : inductive_instance -> rel_context
val mis_sort : inductive_instance -> sorts
-val mis_type_mconstruct : int -> inductive_instance -> types
+val mis_constructor_type : int -> inductive_instance -> types
val mis_finite : inductive_instance -> bool
(* The ccl of constructor is pre-normalised in the following functions *)
val mis_nf_lc : inductive_instance -> constr array
-val mis_type_mconstructs : inductive_instance -> constr array * constr array
(*s [inductive_family] = [inductive_instance] applied to global parameters *)
type inductive_family = IndFamily of inductive_instance * constr list
@@ -117,6 +116,16 @@ val build_dependent_constructor : constructor_summary -> constr
the constructor argument of a dependent predicate in a cases branch *)
val build_dependent_inductive : inductive_family -> constr
+(*s [rel_list n m] and [rel_vect n m] compute [[Rel (n+m);...;Rel(n+1)]] *)
+(* (this is iota operator in C. Paulin habilitation thesis) *)
+val rel_vect : int -> int -> constr array
+val rel_list : int -> int -> constr list
+
+(*s [extended_rel_vect n hyps] and [extended_rel_list n hyps]
+ generalizes [rel_vect] when local definitions may occur in parameters *)
+val extended_rel_vect : int -> rel_context -> constr array
+val extended_rel_list : int -> rel_context -> constr list
+
(* if the arity for some inductive family [indf] associated to [(I
params)] is [(x1:A1)...(xn:An)sort'] then [make_arity env sigma dep
indf k] builds [(x1:A1)...(xn:An)sort] which is the arity of an
@@ -157,6 +166,14 @@ val lookup_mind_specif : inductive -> env -> inductive_instance
val find_rectype : env -> 'a evar_map -> constr -> inductive_type
+(* [get_constructors_types indf] returns the array of the types of
+ constructors of the inductive\_family [indf], i.e. the types are
+ instantiated by the parameters of the family (the type may be not
+ in canonical form -- e.g. cf sets library) *)
+
+val get_constructors_types : inductive_family -> types array
+val get_constructor_type : inductive_family -> int -> types
+
(* [get_constructors indf] build an array of [constructor_summary]
from some inductive type already analysed as an [inductive_family];
global parameters are already instanciated in the constructor
@@ -165,17 +182,24 @@ val find_rectype : env -> 'a evar_map -> constr -> inductive_type
are not renamed when [Anonymous] *)
val get_constructors : inductive_family -> constructor_summary array
-
val get_constructor : inductive_family -> int -> constructor_summary
-(* [get_arity indf] returns the product and the sort of the arity of
- the inductive family described by [indf]; global parameters are
- already instanciated; the products signature is relative to the
+(* [get_arity_type indf] returns the type of the arity of the
+ inductive family described by [indf]; global parameters are already
+ instanciated (but the type may be not in canonical form -- e.g. cf
+ sets library); the products signature is relative to the
environment definition of [indf]; the names of the products of the
- constructors types are not renamed when [Anonymous] *)
+ constructors types are not renamed when [Anonymous]; [get_arity
+ indf] does the same but normalises and decomposes it as an arity *)
+val get_arity_type : inductive_family -> types
val get_arity : inductive_family -> arity
+(* [get_arity_type indf] returns the type of the arity of the inductive
+ family described by [indf]; global parameters are already instanciated *)
+
+
+
(* Examples: assume
\begin{verbatim}
diff --git a/kernel/instantiate.ml b/kernel/instantiate.ml
index c9e39c9f5..27754ae84 100644
--- a/kernel/instantiate.ml
+++ b/kernel/instantiate.ml
@@ -17,13 +17,22 @@ let is_id_inst inst =
in
List.for_all is_id inst
-let instantiate_constr sign c args =
+let instantiate sign c args =
let inst = instantiate_named_context sign args in
if is_id_inst inst then
c
else
replace_vars inst c
+let instantiate_evar = instantiate
+
+let instantiate_constr sign c args =
+ if Options.immediate_discharge then
+ c
+ else
+ let sign = List.map (fun (sp,b,t) -> (basename sp,b,t)) sign in
+ instantiate sign c args
+
let instantiate_type sign tty args =
type_app (fun c -> instantiate_constr sign c args) tty
@@ -33,7 +42,7 @@ let instantiate_type sign tty args =
let constant_type env sigma (sp,args) =
let cb = lookup_constant sp env in
(* TODO: check args *)
- instantiate_type cb.const_hyps cb.const_type (Array.to_list args)
+(* instantiate_type cb.const_hyps *) cb.const_type (*(Array.to_list args)*)
type const_evaluation_result = NoBody | Opaque
@@ -60,7 +69,7 @@ let existential_type sigma (n,args) =
let info = Evd.map sigma n in
let hyps = info.evar_hyps in
(* TODO: check args [this comment was in Typeops] *)
- instantiate_constr hyps info.evar_concl (Array.to_list args)
+ instantiate_evar hyps info.evar_concl (Array.to_list args)
exception NotInstantiatedEvar
@@ -69,7 +78,7 @@ let existential_value sigma (n,args) =
let hyps = info.evar_hyps in
match evar_body info with
| Evar_defined c ->
- instantiate_constr hyps c (Array.to_list args)
+ instantiate_evar hyps c (Array.to_list args)
| Evar_empty ->
raise NotInstantiatedEvar
diff --git a/kernel/instantiate.mli b/kernel/instantiate.mli
index a80dcc435..1414196f3 100644
--- a/kernel/instantiate.mli
+++ b/kernel/instantiate.mli
@@ -12,9 +12,9 @@ open Environ
(* Instantiation of constants and inductives on their real arguments. *)
val instantiate_constr :
- named_context -> constr -> constr list -> constr
+ section_context -> constr -> constr list -> constr
val instantiate_type :
- named_context -> types -> constr list -> types
+ section_context -> types -> constr list -> types
(*s [constant_value env c] raises [NotEvaluableConst Opaque] if
[c] is opaque and [NotEvaluableConst NoBody] if it has no
diff --git a/kernel/names.ml b/kernel/names.ml
index 8b1cb71a1..fc3453611 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -235,6 +235,10 @@ let next_name_away name l =
| Name str -> next_ident_away str l
| Anonymous -> id_of_string "_"
+let out_name = function
+ | Name id -> id
+ | Anonymous -> anomaly "out_name: expects a defined name"
+
(* Kinds *)
type path_kind = CCI | FW | OBJ
diff --git a/kernel/names.mli b/kernel/names.mli
index bd3d0e590..edcadf634 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -41,6 +41,9 @@ val next_name_away : name -> identifier list -> identifier
val next_name_away_with_default :
string -> name -> identifier list -> identifier
+(* [out_name na] raises an anomaly if [na] is [Anonymous] *)
+val out_name : name -> identifier
+
(*s [path_kind] is currently degenerated, [FW] is not used *)
type path_kind = CCI | FW | OBJ
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 600cdd823..794c49354 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -59,16 +59,19 @@ val nf_betadeltaiota : 'a reduction_function
val whd_beta : local_reduction_function
val whd_betaiota : local_reduction_function
val whd_betadeltaiota : 'a contextual_reduction_function
+val whd_betadeltaiota_nolet : 'a contextual_reduction_function
val whd_betaetalet : local_reduction_function
val whd_beta_stack : local_stack_reduction_function
val whd_betaiota_stack : local_stack_reduction_function
val whd_betadeltaiota_stack : 'a contextual_stack_reduction_function
+val whd_betadeltaiota_nolet_stack : 'a contextual_stack_reduction_function
val whd_betaetalet_stack : local_stack_reduction_function
val whd_beta_state : local_state_reduction_function
val whd_betaiota_state : local_state_reduction_function
val whd_betadeltaiota_state : 'a contextual_state_reduction_function
+val whd_betadeltaiota_nolet_state : 'a contextual_state_reduction_function
val whd_betaetalet_state : local_state_reduction_function
(*s Head normal forms *)
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 925ca9bf0..72e9bfd1a 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -297,36 +297,49 @@ let safe_infer_declaration env = function
let (j,cst) = safe_infer env t in
None, assumption_of_judgment env Evd.empty j, cst
-let add_global_declaration sp env (body,typ,cst) =
+type local_names = (identifier * variable_path) list
+
+let add_global_declaration sp env locals (body,typ,cst) =
let env' = add_constraints cst env in
let ids = match body with
| None -> global_vars_set typ
| Some b -> Idset.union (global_vars_set b) (global_vars_set typ) in
+ let hyps = keep_hyps ids (named_context env) in
+ let body, typ =
+ if Options.immediate_discharge then
+ option_app (fun c -> it_mkNamedLambda_or_LetIn c hyps) body,
+ it_mkNamedProd_or_LetIn typ hyps
+ else
+ body,typ in
+ let sp_hyps = List.map (fun (id,b,t) -> (List.assoc id locals, b, t)) hyps in
let cb = {
const_kind = kind_of_path sp;
const_body = body;
const_type = typ;
- const_hyps = keep_hyps ids (named_context env);
+ const_hyps = sp_hyps;
const_constraints = cst;
const_opaque = false }
in
Environ.add_constant sp cb env'
-let add_parameter sp t env =
- add_global_declaration sp env (safe_infer_declaration env (Assum t))
+let add_parameter sp t locals env =
+ add_global_declaration sp env locals (safe_infer_declaration env (Assum t))
-let add_constant_with_value sp body typ env =
+let add_constant_with_value sp body typ locals env =
let body' =
match typ with
| None -> body
| Some ty -> mkCast (body, ty) in
- add_global_declaration sp env (safe_infer_declaration env (Def body'))
+ add_global_declaration sp env locals (safe_infer_declaration env (Def body'))
+
+let add_constant sp ce locals env =
+ add_constant_with_value sp ce.const_entry_body ce.const_entry_type locals env
-let add_discharged_constant sp r env =
+let add_discharged_constant sp r locals env =
let (body,typ) = Cooking.cook_constant env r in
match body with
| None ->
- add_parameter sp typ env
+ add_parameter sp typ [] (* Bricolage avant poubelle *) env
| Some c ->
(* let c = hcons1_constr c in *)
let (jtyp,cst) = safe_infer env typ in
@@ -335,17 +348,19 @@ let add_discharged_constant sp r env =
Idset.union (global_vars_set c)
(global_vars_set (body_of_type jtyp.uj_val))
in
- let cb = { const_kind = kind_of_path sp;
- const_body = Some c;
- const_type = assumption_of_judgment env' Evd.empty jtyp;
- const_hyps = keep_hyps ids (named_context env);
- const_constraints = cst;
- const_opaque = false }
+ let hyps = keep_hyps ids (named_context env) in
+ let sp_hyps =
+ List.map (fun (id,b,t) -> (List.assoc id locals,b,t)) hyps in
+ let cb =
+ { const_kind = kind_of_path sp;
+ const_body = Some c;
+ const_type = assumption_of_judgment env' Evd.empty jtyp;
+ const_hyps = sp_hyps;
+ const_constraints = cst;
+ const_opaque = false }
in
- add_constant sp cb env'
+ Environ.add_constant sp cb env'
-let add_constant sp ce env =
- add_constant_with_value sp ce.const_entry_body ce.const_entry_type env
(* Insertion of inductive types. *)
@@ -427,7 +442,7 @@ let infer_constructor_packet env_ar params short_arity arsort vc =
let issmall,isunit = small_unit constrsinfos (env_ar_par,short_arity) in
(issmall,isunit,vc', cst)
-let add_mind sp mie env =
+let add_mind sp mie locals env =
mind_check_wellformed env mie;
(* We first type params and arity of each inductive definition *)
@@ -466,7 +481,8 @@ let add_mind sp mie env =
in
let nparams = ind.mind_entry_nparams in
let consnames = ind.mind_entry_consnames in
- let ind' = (nparams,id,full_arity,consnames,issmall,isunit,lc') in
+ let ind' = (params,nparams,id,full_arity,consnames,issmall,isunit,lc')
+ in
(ind'::inds, Constraint.union cst cst'))
mie.mind_entry_inds
params_arity_list
@@ -474,7 +490,7 @@ let add_mind sp mie env =
(* Finally, we build the inductive packet and push it to env *)
let kind = kind_of_path sp in
- let mib = cci_inductive env env_arities kind mie.mind_entry_finite inds cst
+ let mib = cci_inductive locals env env_arities kind mie.mind_entry_finite inds cst
in
add_mind sp mib (add_constraints cst env)
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index 7f50c7104..474da34b8 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -31,15 +31,18 @@ val push_named_assum :
val push_named_def :
identifier * constr -> safe_environment -> safe_environment
+type local_names = (identifier * variable_path) list
+
val add_parameter :
- section_path -> constr -> safe_environment -> safe_environment
+ section_path -> constr -> local_names -> safe_environment -> safe_environment
val add_constant :
- section_path -> constant_entry -> safe_environment -> safe_environment
+ section_path -> constant_entry -> local_names ->
+ safe_environment -> safe_environment
val add_discharged_constant :
- section_path -> Cooking.recipe -> safe_environment -> safe_environment
+ section_path -> Cooking.recipe -> local_names -> safe_environment -> safe_environment
val add_mind :
- section_path -> mutual_inductive_entry -> safe_environment
+ section_path -> mutual_inductive_entry -> local_names -> safe_environment
-> safe_environment
val add_constraints : constraints -> safe_environment -> safe_environment
diff --git a/kernel/sign.ml b/kernel/sign.ml
index efdc08a3f..fc3e15f5e 100644
--- a/kernel/sign.ml
+++ b/kernel/sign.ml
@@ -50,8 +50,24 @@ let fold_named_context_reverse = List.fold_left
let fold_named_context_both_sides = list_fold_right_and_left
let it_named_context_quantifier f = List.fold_left (fun c d -> f d c)
+(*s Signatures of ordered section variables *)
+
+type section_declaration = variable_path * constr option * constr
+type section_context = section_declaration list
+let rec instance_from_section_context = function
+ | (sp,None,_) :: sign ->
+ mkVar (basename sp) :: instance_from_section_context sign
+ | _ :: sign -> instance_from_section_context sign
+ | [] -> []
+let instance_from_section_context x =
+ if Options.immediate_discharge then [] else instance_from_section_context x
+
+(*s Signatures of ordered optionally named variables, intended to be
+ accessed by de Bruijn indices *)
+
type rel_declaration = name * constr option * types
type rel_context = rel_declaration list
+type rev_rel_context = rel_declaration list
let add_rel_decl = add
let add_rel_assum = add_decl
@@ -87,6 +103,14 @@ let lift_rel_context n sign =
| [] -> []
in
liftrec (rel_context_length sign) sign
+let lift_rev_rel_context n sign =
+ let rec liftrec k = function
+ | (na,c,t)::sign ->
+ (na,option_app (liftn n k) c,type_app (liftn n k) t)
+ ::(liftrec (k+1) sign)
+ | [] -> []
+ in
+ liftrec 1 sign
let concat_rel_context = (@)
let ids_of_rel_context sign =
List.fold_right
@@ -98,6 +122,22 @@ let assums_of_rel_context sign =
(fun (na,c,t) l -> match c with Some _ -> l | None -> (na,body_of_type t)::l)
sign []
let map_rel_context = map
+let push_named_to_rel_context hyps ctxt =
+ let rec push = function
+ | (id,b,t) :: l ->
+ let s, hyps = push l in
+ let d = (Name id, option_app (subst_vars s) b, subst_vars s t) in
+ id::s, d::hyps
+ | [] -> [],[] in
+ let s, hyps = push hyps in
+ let rec subst = function
+ | (na,b,t) :: l ->
+ let n, ctxt = subst l in
+ let d = (na, option_app (substn_vars n s) b, substn_vars n s t) in
+ (n+1), d::ctxt
+ | [] -> 1, hyps in
+ snd (subst ctxt)
+let reverse_rel_context = List.rev
let instantiate_sign sign args =
let rec instrec = function
diff --git a/kernel/sign.mli b/kernel/sign.mli
index 5c93bccbf..ede431eb4 100644
--- a/kernel/sign.mli
+++ b/kernel/sign.mli
@@ -36,11 +36,22 @@ val instantiate_sign :
val keep_hyps : Idset.t -> named_context -> named_context
val instance_from_named_context : named_context -> constr list
+(*s Signatures of ordered section variables *)
+
+type section_declaration = variable_path * constr option * constr
+type section_context = section_declaration list
+
+val instance_from_section_context : section_context -> constr list
+
(*s Signatures of ordered optionally named variables, intended to be
accessed by de Bruijn indices *)
+(* In [rel_context], more recent declaration is on top *)
type rel_context = rel_declaration list
+(* In [rev_rel_context], older declaration is on top *)
+type rev_rel_context = rel_declaration list
+
val add_rel_decl : (name * constr option * types) -> rel_context -> rel_context
val add_rel_assum : (name * types) -> rel_context -> rel_context
val add_rel_def : (name * constr * types) -> rel_context -> rel_context
@@ -50,10 +61,13 @@ val lookup_rel_id : identifier -> rel_context -> int * types
val empty_rel_context : rel_context
val rel_context_length : rel_context -> int
val lift_rel_context : int -> rel_context -> rel_context
+val lift_rev_rel_context : int -> rev_rel_context -> rev_rel_context
val concat_rel_context : newer:rel_context -> older:rel_context -> rel_context
val ids_of_rel_context : rel_context -> identifier list
val assums_of_rel_context : rel_context -> (name * constr) list
val map_rel_context : (constr -> constr) -> rel_context -> rel_context
+val push_named_to_rel_context : named_context -> rel_context -> rel_context
+val reverse_rel_context : rel_context -> rev_rel_context
(*s This is used to translate names into de Bruijn indices and
vice-versa without to care about typing information *)
diff --git a/kernel/term.ml b/kernel/term.ml
index 7503aa03a..f942fe178 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -977,11 +977,13 @@ let replace_vars var_alist =
let subst_var str = replace_vars [(str, mkRel 1)]
(* (subst_vars [id1;...;idn] t) substitute (VAR idj) by (Rel j) in t *)
-let subst_vars vars =
+let substn_vars p vars =
let _,subst =
- List.fold_left (fun (n,l) var -> ((n+1),(var,mkRel n)::l)) (1,[]) vars
+ List.fold_left (fun (n,l) var -> ((n+1),(var,mkRel n)::l)) (p,[]) vars
in replace_vars (List.rev subst)
+let subst_vars = substn_vars 1
+
(*********************)
(* Term constructors *)
(*********************)
@@ -1242,7 +1244,7 @@ let destArity =
| IsLetIn (x,b,t,c) -> prodec_rec ((x,Some b,t)::l) c
| IsCast (c,_) -> prodec_rec l c
| IsSort s -> l,s
- | _ -> anomaly "decompose_arity: not an arity"
+ | _ -> anomaly "destArity: not an arity"
in
prodec_rec []
@@ -1387,16 +1389,6 @@ let global_vars_set constr =
in
filtrec Idset.empty constr
-(* [Rel (n+m);...;Rel(n+1)] *)
-
-let rel_vect n m = Array.init m (fun i -> mkRel(n+m-i))
-
-let rel_list n m =
- let rec reln l p =
- if p>m then l else reln (mkRel(n+p)::l) (p+1)
- in
- reln [] 1
-
(* Rem: end of import from old module Generic *)
(* Various occurs checks *)
diff --git a/kernel/term.mli b/kernel/term.mli
index 08b1e5e86..858ba2465 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -474,9 +474,9 @@ val subst_var : identifier -> constr -> constr
if two names are identical, the one of least indice is keeped *)
val subst_vars : identifier list -> constr -> constr
-(* [rel_list n m] and [rel_vect n m] compute [[Rel (n+m);...;Rel(n+1)]] *)
-val rel_vect : int -> int -> constr array
-val rel_list : int -> int -> constr list
+(* [substn_vars n [id1;...;idn] t] substitute [VAR idj] by [Rel j+n-1] in [t]
+ if two names are identical, the one of least indice is keeped *)
+val substn_vars : int -> identifier list -> constr -> constr
(*s Compact representation of implicit lifts. \\
[ELSHFT(l,n)] == lift of [n], then apply [lift l].
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index ae1bb46cf..fa3db0b86 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -78,21 +78,16 @@ let type_of_constant = Instantiate.constant_type
(* Inductive types. *)
-let instantiate_arity = mis_user_arity
-
let type_of_inductive env sigma i =
(* TODO: check args *)
- instantiate_arity (lookup_mind_specif i env)
+ mis_arity (lookup_mind_specif i env)
(* Constructors. *)
-let type_mconstruct env sigma i mind =
- mis_type_mconstruct i (lookup_mind_specif mind env)
-
let type_of_constructor env sigma cstr =
- type_mconstruct env sigma
- (index_of_constructor cstr)
- (inductive_of_constructor cstr)
+ mis_constructor_type
+ (index_of_constructor cstr)
+ (lookup_mind_specif (inductive_of_constructor cstr) env)
let type_of_existential env sigma ev =
Instantiate.existential_type sigma ev
diff --git a/library/declare.ml b/library/declare.ml
index 82966022b..57e58256e 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -48,12 +48,17 @@ type sticky = bool
type variable_declaration = section_variable_entry * strength * sticky
-let vartab = ref (Spmap.empty : (identifier * variable_declaration) Spmap.t)
+let vartab =
+ ref ((Spmap.empty, []) :
+ (identifier * variable_declaration) Spmap.t * section_path list)
+
+let current_section_context () =
+ List.map (fun sp -> (basename sp, sp)) (snd !vartab)
let _ = Summary.declare_summary "VARIABLE"
{ Summary.freeze_function = (fun () -> !vartab);
Summary.unfreeze_function = (fun ft -> vartab := ft);
- Summary.init_function = (fun () -> vartab := Spmap.empty);
+ Summary.init_function = (fun () -> vartab := (Spmap.empty, []));
Summary.survive_section = false }
let cache_variable (sp,(id,(d,_,_) as vd)) =
@@ -65,7 +70,7 @@ let cache_variable (sp,(id,(d,_,_) as vd)) =
| SectionLocalDef c -> Global.push_named_def (id,c)
end;
Nametab.push_local sp (VarRef sp);
- vartab := Spmap.add sp vd !vartab
+ vartab := let (m,l) = !vartab in (Spmap.add sp vd m, sp::l)
let (in_variable, out_variable) =
let od = {
@@ -87,7 +92,7 @@ let cache_parameter (sp,c) =
if Nametab.exists_cci sp then
errorlabstrm "cache_parameter"
[< pr_id (basename sp); 'sTR " already exists" >];
- Global.add_parameter sp c;
+ Global.add_parameter sp c (current_section_context ());
Nametab.push sp (ConstRef sp)
let load_parameter _ = ()
@@ -132,9 +137,10 @@ let cache_constant (sp,(cdt,stre,op)) =
if Nametab.exists_cci sp then
errorlabstrm "cache_constant"
[< pr_id (basename sp); 'sTR " already exists" >] ;
+ let sc = current_section_context() in
begin match cdt with
- | ConstantEntry ce -> Global.add_constant sp ce
- | ConstantRecipe r -> Global.add_discharged_constant sp r
+ | ConstantEntry ce -> Global.add_constant sp ce sc
+ | ConstantRecipe r -> Global.add_discharged_constant sp r sc
end;
Nametab.push sp (ConstRef sp);
if op then Global.set_opaque sp;
@@ -197,7 +203,7 @@ let check_exists_inductive (sp,_) =
let cache_inductive (sp,mie) =
let names = inductive_names sp mie in
List.iter check_exists_inductive names;
- Global.add_mind sp mie;
+ Global.add_mind sp mie (current_section_context ());
List.iter (fun (sp, ref) -> Nametab.push sp ref) names
let load_inductive _ = ()
@@ -236,12 +242,12 @@ let constant_or_parameter_strength sp =
try constant_strength sp with Not_found -> NeverDischarge
let get_variable sp =
- let (id,(_,str,sticky)) = Spmap.find sp !vartab in
+ let (id,(_,str,sticky)) = Spmap.find sp (fst !vartab) in
let (c,ty) = Global.lookup_named id in
((id,c,ty),str,sticky)
let variable_strength sp =
- let _,(_,str,_) = Spmap.find sp !vartab in str
+ let _,(_,str,_) = Spmap.find sp (fst !vartab) in str
(* Global references. *)
@@ -267,11 +273,11 @@ let mind_oper_of_id sp id mib =
mip.mind_consnames)
mib.mind_packets
-let context_of_global_reference env = function
- | VarRef sp -> [] (* Hum !, pas correct *)
- | ConstRef sp -> (Environ.lookup_constant sp env).const_hyps
- | IndRef (sp,_) -> (Environ.lookup_mind sp env).mind_hyps
- | ConstructRef ((sp,_),_) -> (Environ.lookup_mind sp env).mind_hyps
+let context_of_global_reference = function
+ | VarRef sp -> []
+ | ConstRef sp -> (Global.lookup_constant sp).const_hyps
+ | IndRef (sp,_) -> (Global.lookup_mind sp).mind_hyps
+ | ConstructRef ((sp,_),_) -> (Global.lookup_mind sp).mind_hyps
(*
let global_sp_operator env sp id =
@@ -282,87 +288,102 @@ let global_sp_operator env sp id =
mind_oper_of_id sp id mib, mib.mind_hyps
*)
-let occur_decl env (id,c,t) hyps =
- try
- let (c',t') = Sign.lookup_id id hyps in
- let matching_bodies = match c,c' with
- | None, _ -> true
- | Some c, None -> false
- | Some c, Some c' -> is_conv env Evd.empty c c' in
- let matching_types =
- is_conv env Evd.empty (body_of_type t) (body_of_type t') in
- matching_types & matching_bodies
- with Not_found -> false
-
-(*
-let find_common_hyps_then_abstract c env hyps' hyps =
- snd (fold_named_context_both_sides
- (fun
- (env,c) (id,_,_ as d) hyps ->
- if occur_decl env d hyps' then
- (Environ.push_named_decl d env,c)
- else
- let hyps'' = List.rev (d :: hyps) in
- (env, Environ.it_mkNamedLambda_or_LetIn c hyps''))
- hyps
- (env,c))
-*)
+let rec occur_section_variable sp = function
+ | (_,sp')::_ when sp = sp' -> true
+ | _::l -> occur_section_variable sp l
+ | [] -> false
let rec quantify_extra_hyps c = function
- | (id,None,t)::hyps -> mkNamedLambda id t (quantify_extra_hyps c hyps)
+ | (sp,None,t)::hyps ->
+ mkNamedLambda (basename sp) t (quantify_extra_hyps c hyps)
(* Buggé car id n'apparaît pas dans les instances des constantes dans c *)
(* et id n'est donc pas substitué dans ces constantes *)
- | (id,Some b,t)::hyps -> mkNamedLetIn id b t (quantify_extra_hyps c hyps)
+ | (sp,Some b,t)::hyps ->
+ mkNamedLetIn (basename sp) b t (quantify_extra_hyps c hyps)
| [] -> c
-let rec find_common_hyps_then_abstract c env hyps' = function
- | (id,_,_ as d) :: hyps when occur_decl env d hyps' ->
- find_common_hyps_then_abstract c (Environ.push_named_decl d env) hyps' hyps
- | hyps -> quantify_extra_hyps c hyps
+let find_common_hyps_then_abstract c hyps' hyps =
+ let rec find = function
+ | (sp,_,_) :: hyps when occur_section_variable sp hyps' -> find hyps
+ | hyps -> quantify_extra_hyps c hyps in
+ find (List.rev hyps)
-let find_common_hyps_then_abstract c env hyps' hyps =
- find_common_hyps_then_abstract c env hyps' (List.rev hyps)
-
-let current_section_context () =
- let current = Spmap.fold (fun _ (id,_) hyps -> id::hyps) !vartab [] in
- List.fold_right
- (fun (id,_,_ as d) hyps -> if List.mem id current then d::hyps else hyps)
- (Global.named_context ()) []
+let section_variable_paths () = snd !vartab
let find_section_variable id =
let l =
Spmap.fold
(fun sp (id',_) hyps -> if id=id' then sp::hyps else hyps)
- !vartab [] in
+ (fst !vartab) [] in
match l with
| [] -> raise Not_found
| [sp] -> sp
| _ -> error "Arghh, you blasted me with several variables of same name"
+let last_section_hyps dir =
+ List.fold_right
+ (fun sp hyps -> if dirpath sp = dir then basename sp :: hyps else hyps)
+ (snd !vartab) []
+
+let rec find_var id = function
+ | [] -> raise Not_found
+ | sp::l -> if basename sp = id then sp else find_var id l
+
+let implicit_section_args ref =
+ if Options.immediate_discharge then
+ let hyps = context_of_global_reference ref in
+ let hyps0 = section_variable_paths () in
+ let rec keep acc = function
+ | (sp,None,_)::hyps ->
+ let acc = if List.mem sp hyps0 then sp::acc else acc in
+ keep acc hyps
+ | (_,Some _,_)::hyps -> keep acc hyps
+ | [] -> acc
+ in keep [] hyps
+ else []
+
+let section_hyps ref =
+ let hyps = context_of_global_reference ref in
+ let hyps0 = section_variable_paths () in
+ let rec keep acc = function
+ | (sp,b,_ as d)::hyps ->
+ let acc = if List.mem sp hyps0 then (sp,b=None)::acc else acc in
+ keep acc hyps
+ | [] -> acc
+ in keep [] hyps
+
let extract_instance ref args =
- let hyps = context_of_global_reference (Global.env ()) ref in
+ if Options.immediate_discharge then args
+ else
+ let hyps = context_of_global_reference ref in
let hyps0 = current_section_context () in
let na = Array.length args in
let rec peel n acc = function
- | (_,None,_ as d)::hyps ->
- if List.mem d hyps0 then peel (n-1) acc hyps
+ | (sp,None,_ as d)::hyps ->
+ if List.mem_assoc (basename sp) hyps0 then peel (n-1) acc hyps
else peel (n-1) (args.(n)::acc) hyps
| (_,Some _,_)::hyps -> peel n acc hyps
| [] -> Array.of_list acc
in peel (na-1) [] hyps
-let constr_of_reference _ env ref =
- let hyps = context_of_global_reference env ref in
+let constr_of_reference _ _ ref =
+if Options.immediate_discharge then
+ match ref with
+ | VarRef sp -> mkVar (basename sp)
+ | ConstRef sp -> mkConst (sp,[||])
+ | ConstructRef sp -> mkMutConstruct (sp,[||])
+ | IndRef sp -> mkMutInd (sp,[||])
+else
+ let hyps = context_of_global_reference ref in
let hyps0 = current_section_context () in
- let env0 = Environ.reset_context env in
- let args = instance_from_named_context hyps in
+ let args = instance_from_section_context hyps in
let body = match ref with
| VarRef sp -> mkVar (basename sp)
| ConstRef sp -> mkConst (sp,Array.of_list args)
| ConstructRef sp -> mkMutConstruct (sp,Array.of_list args)
| IndRef sp -> mkMutInd (sp,Array.of_list args)
in
- find_common_hyps_then_abstract body env0 hyps0 hyps
+ find_common_hyps_then_abstract body hyps0 hyps
let construct_absolute_reference env sp =
constr_of_reference Evd.empty env (Nametab.absolute_reference sp)
@@ -384,6 +405,10 @@ let global_qualified_reference qid =
let global_absolute_reference sp =
construct_absolute_reference (Global.env()) sp
+let global_reference_in_absolute_module dir id =
+ constr_of_reference Evd.empty (Global.env())
+ (Nametab.locate_in_absolute_module dir id)
+
let global_reference kind id =
construct_reference (Global.env()) kind id
@@ -414,6 +439,21 @@ let path_of_inductive_path (sp,tyi) =
let (pa,_,k) = repr_path sp in
Names.make_path pa (mip.mind_typename) k
+(* Util *)
+let instantiate_inductive_section_params t ind =
+ if Options.immediate_discharge then
+ let sign = section_hyps (IndRef ind) in
+ let rec inst s ctxt t =
+ let k = kind_of_term t in
+ match (ctxt,k) with
+ | (sp,true)::ctxt, IsLambda(_,_,t) ->
+ inst ((mkVar (basename sp))::s) ctxt t
+ | (sp,false)::ctxt, IsLetIn(_,_,_,t) ->
+ inst ((mkVar (basename sp))::s) ctxt t
+ | [], _ -> substl s t
+ | _ -> anomaly"instantiate_params: term and ctxt mismatch"
+ in inst [] sign t
+ else t
(* Eliminations. *)
let eliminations = [ (prop,"_ind") ; (spec,"_rec") ; (types,"_rect") ]
@@ -426,6 +466,9 @@ let elimination_suffix = function
let declare_one_elimination mispec =
let mindstr = string_of_id (mis_typename mispec) in
let declare na c =
+ (* Hack to get const_hyps right in the declaration *)
+ let c = instantiate_inductive_section_params c (fst (mis_inductive mispec))
+ in
let _ = declare_constant (id_of_string na)
(ConstantEntry { const_entry_body = c; const_entry_type = None },
NeverDischarge,false) in
@@ -444,10 +487,12 @@ let declare_one_elimination mispec =
let declare_eliminations sp =
let mib = Global.lookup_mind sp in
+(*
let ids = ids_of_named_context mib.mind_hyps in
if not (list_subset ids (ids_of_named_context (Global.named_context ()))) then error ("Declarations of elimination scheme outside the section "^
"of the inductive definition is not implemented");
- let ctxt = instance_from_named_context mib.mind_hyps in
+*)
+ let ctxt = instance_from_section_context mib.mind_hyps in
for i = 0 to Array.length mib.mind_packets - 1 do
if mind_type_finite mib i then
let mispec = Global.lookup_mind_specif ((sp,i), Array.of_list ctxt) in
diff --git a/library/declare.mli b/library/declare.mli
index 894cebd0d..07dc96914 100644
--- a/library/declare.mli
+++ b/library/declare.mli
@@ -72,6 +72,7 @@ val out_variable : Libobject.obj -> identifier * variable_declaration
val get_variable : variable_path -> named_declaration * strength * sticky
val variable_strength : variable_path -> strength
val find_section_variable : identifier -> variable_path
+val last_section_hyps : dir_path -> identifier list
(*s [global_reference k id] returns the object corresponding to
the name [id] in the global environment. It may be a constant,
@@ -81,6 +82,9 @@ val find_section_variable : identifier -> variable_path
[construct_reference] is a version which looks for variables in a
given environment instead of looking in the current global environment. *)
+val context_of_global_reference : global_reference -> section_context
+val instantiate_inductive_section_params : constr -> inductive_path -> constr
+val implicit_section_args : global_reference -> section_path list
val extract_instance : global_reference -> constr array -> constr array
val constr_of_reference :
@@ -88,6 +92,7 @@ val constr_of_reference :
val global_qualified_reference : qualid -> constr
val global_absolute_reference : section_path -> constr
+val global_reference_in_absolute_module : dir_path -> identifier -> constr
val construct_qualified_reference : Environ.env -> qualid -> constr
val construct_absolute_reference : Environ.env -> section_path -> constr
diff --git a/library/global.ml b/library/global.ml
index e5f0d07fd..c07452988 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -35,11 +35,11 @@ let named_context () = named_context !global_env
let push_named_def idc = global_env := push_named_def idc !global_env
let push_named_assum idc = global_env := push_named_assum idc !global_env
-let add_parameter sp c = global_env := add_parameter sp c !global_env
-let add_constant sp ce = global_env := add_constant sp ce !global_env
-let add_discharged_constant sp r =
- global_env := add_discharged_constant sp r !global_env
-let add_mind sp mie = global_env := add_mind sp mie !global_env
+let add_parameter sp c l = global_env := add_parameter sp c l !global_env
+let add_constant sp ce l = global_env := add_constant sp ce l !global_env
+let add_discharged_constant sp r l =
+ global_env := add_discharged_constant sp r l !global_env
+let add_mind sp mie l = global_env := add_mind sp mie l !global_env
let add_constraints c = global_env := add_constraints c !global_env
let pop_named_decls ids = global_env := pop_named_decls ids !global_env
@@ -87,8 +87,6 @@ let mind_is_recursive =
let mind_nconstr = Util.compose Inductive.mis_nconstr lookup_mind_specif
let mind_nparams = Util.compose Inductive.mis_nparams lookup_mind_specif
-let mind_nf_arity x =
- body_of_type (Inductive.mis_user_arity (lookup_mind_specif x))
let mind_nf_lc = Util.compose Inductive.mis_nf_lc lookup_mind_specif
diff --git a/library/global.mli b/library/global.mli
index 0ad3e3713..74a7197d4 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -26,10 +26,11 @@ val named_context : unit -> named_context
val push_named_assum : identifier * constr -> unit
val push_named_def : identifier * constr -> unit
-val add_parameter : section_path -> constr -> unit
-val add_constant : section_path -> constant_entry -> unit
-val add_discharged_constant : section_path -> Cooking.recipe -> unit
-val add_mind : section_path -> mutual_inductive_entry -> unit
+val add_parameter : section_path -> constr -> local_names -> unit
+val add_constant : section_path -> constant_entry -> local_names -> unit
+val add_discharged_constant : section_path -> Cooking.recipe ->
+ local_names -> unit
+val add_mind : section_path -> mutual_inductive_entry -> local_names -> unit
val add_constraints : constraints -> unit
val pop_named_decls : identifier list -> unit
@@ -61,6 +62,5 @@ val env_of_context : named_context -> env
val mind_is_recursive : inductive -> bool
val mind_nconstr : inductive -> int
val mind_nparams : inductive -> int
-val mind_nf_arity : inductive -> constr
val mind_nf_lc : inductive -> constr array
diff --git a/library/nametab.ml b/library/nametab.ml
index b62f4d867..c8e10a1ed 100755
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -148,15 +148,34 @@ let constant_sp_of_id id =
| ConstRef sp -> sp
| _ -> raise Not_found
-let check_absoluteness sp =
- match dirpath sp with
+let check_absoluteness dir =
+ match dir with
| a::_ when List.mem a !roots -> ()
- | _ -> anomaly ("Not an absolute path: "^(string_of_path sp))
+ | _ -> anomaly ("Not an absolute dirpath: "^(string_of_dirpath dir))
let absolute_reference sp =
- check_absoluteness sp;
+ check_absoluteness (dirpath sp);
locate (qualid_of_sp sp)
+exception Found of global_reference
+let locate_in_module dir id =
+ let rec exists_in id (Closed (ccitab,_,modtab)) =
+ try raise (Found (Stringmap.find id ccitab))
+ with Not_found ->
+ Stringmap.iter (fun _ (sp,mc) -> exists_in id mc) modtab
+ in
+ let rec search (Closed (ccitab,_,modtab) as mc) = function
+ | modid :: dir' -> search (snd (Stringmap.find modid modtab)) dir'
+ | [] ->
+ try exists_in id mc; raise Not_found
+ with Found ref -> ref
+ in
+ search !persistent_nametab dir
+
+let locate_in_absolute_module dir id =
+ check_absoluteness dir;
+ locate_in_module dir (string_of_id id)
+
(* These are entry points to make the contents of a module/section visible *)
(* in the current env (does not affect the absolute name space `coq_root') *)
let open_module_contents qid =
@@ -165,7 +184,13 @@ let open_module_contents qid =
(* Stringmap.iter (fun _ -> Libobject.open_object) objtab;*)
Stringmap.iter push_mod_current modtab
-let open_section_contents = open_module_contents
+let conditional_push ref = push_cci_current ref (* TODO *)
+
+let open_section_contents qid =
+ let _, (Closed (ccitab,objtab,modtab)) = locate_module qid in
+ Stringmap.iter push_cci_current ccitab;
+(* Stringmap.iter (fun _ -> Libobject.open_object) objtab;*)
+ Stringmap.iter push_mod_current modtab
let rec rec_open_module_contents qid =
let _, (Closed (ccitab,objtab,modtab)) = locate_module qid in
diff --git a/library/nametab.mli b/library/nametab.mli
index 64cba70c2..08aea7ccc 100755
--- a/library/nametab.mli
+++ b/library/nametab.mli
@@ -59,3 +59,7 @@ val push_library_root : string -> unit
especially, constructor/inductive names are turned into internal
references inside a block of mutual inductive *)
val absolute_reference : section_path -> global_reference
+
+(* [locate_in_absolute_module dir id] finds [id] in module [dir] or in
+ one of its section/subsection *)
+val locate_in_absolute_module : dir_path -> identifier -> global_reference
diff --git a/toplevel/class.ml b/toplevel/class.ml
index e0ae40af6..4d8e5ba2c 100644
--- a/toplevel/class.ml
+++ b/toplevel/class.ml
@@ -8,6 +8,7 @@ open Term
open Inductive
open Declarations
open Environ
+open Inductive
open Lib
open Classops
open Declare
@@ -260,18 +261,16 @@ let build_id_coercion idf_opt source =
| Some c -> c
| None -> error_not_transparent source in
let lams,t = Sign.decompose_lam_assum c in
- let llams = List.length lams in
- let lams = List.rev lams in
let val_f =
it_mkLambda_or_LetIn
(mkLambda (Name (id_of_string "x"),
- applistc vs (rel_list 0 llams),
+ applistc vs (extended_rel_list 0 lams),
mkRel 1))
lams
in
let typ_f =
it_mkProd_wo_LetIn
- (mkProd (Anonymous, applistc vs (rel_list 0 llams), lift 1 t))
+ (mkProd (Anonymous, applistc vs (extended_rel_list 0 lams), lift 1 t))
lams
in
(* juste pour verification *)
@@ -387,7 +386,7 @@ let count_extra_abstractions hyps ids_to_discard =
List.fold_left
(fun (hyps,n as sofar) id ->
match hyps with
- | (hyp,None,_)::rest when id = hyp ->(rest, n+1)
+ | (hyp,None,_)::rest when id = basename hyp ->(rest, n+1)
| _ -> sofar)
(hyps,0) ids_to_discard
in n
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 49dd7b887..5a029a0e6 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -440,8 +440,11 @@ let save opacity id ({const_entry_body = pft; const_entry_type = tpo} as const)
strength =
begin match strength with
| DischargeAt disch_sp when Lib.is_section_p disch_sp ->
+ (*
let c = constr_of_constr_entry const in
let _ = declare_variable id (SectionLocalDef c,strength,opacity) in ()
+ *)
+ let _ = declare_constant id (ConstantEntry const,strength,opacity)in ()
| NeverDischarge | DischargeAt _ ->
let _ = declare_constant id (ConstantEntry const,strength,opacity)in ()
| NotDeclare -> apply_tac_not_declare id pft tpo
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index a3c9586a4..42f05a01d 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -23,13 +23,15 @@ open Recordops
let recalc_sp dir sp =
let (_,spid,k) = repr_path sp in Names.make_path dir spid k
+let rec find_var id = function
+ | [] -> raise Not_found
+ | (sp,b,_)::l -> if basename sp = id then b=None else find_var id l
+
let build_abstract_list hyps ids_to_discard =
map_succeed
(fun id ->
try
- match lookup_id_value id hyps with
- | None -> ABSTRACT
- | Some c -> failwith "caugth"
+ if find_var id hyps then ABSTRACT else failwith "caugth"
with Not_found -> failwith "caugth")
ids_to_discard
@@ -110,7 +112,8 @@ let process_inductive osecsp nsecsp oldenv (ids_to_discard,modlist) mib =
Array.to_list lc))
mib.mind_packets
in
- let hyps' = map_named_context (expmod_constr oldenv modlist) mib.mind_hyps in
+ let hyps = List.map (fun (sp,c,t) -> (basename sp,c,t)) mib.mind_hyps in
+ let hyps' = map_named_context (expmod_constr oldenv modlist) hyps in
let (inds',modl) = abstract_inductive ids_to_discard hyps' inds in
let lmodif_one_mind i =
let nbc = Array.length (mind_nth_type_packet mib i).mind_consnames in
@@ -355,15 +358,21 @@ let close_section _ s =
let newdir = dirpath sec_sp in
let olddir = wd_of_sp sec_sp in
let (ops,ids,_) =
- List.fold_left
- (process_item oldenv newdir olddir) ([],[],([],[],[])) decls
- in
+ if Options.immediate_discharge then ([],[],([],[],[]))
+ else
+ List.fold_left
+ (process_item oldenv newdir olddir) ([],[],([],[],[])) decls
+ in
+ let ids = last_section_hyps olddir in
Global.pop_named_decls ids;
Summary.unfreeze_lost_summaries fs;
let mc = segment_contents decls in
- add_anonymous_leaf (in_end_section (sec_sp,mc));
- List.iter process_operation (List.rev ops)
+ add_anonymous_leaf (in_end_section (sec_sp,mc));
+ if Options.immediate_discharge then ()
+ else
+ List.iter process_operation (List.rev ops)
let save_module_to s f =
Library.save_module_to segment_contents s f
+
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 91d65a5f9..f24051fd1 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -77,8 +77,13 @@ let warning_or_error coe err =
pPNL (hOV 0 [< 'sTR"Warning: "; st >])
(* We build projections *)
-let declare_projections structref coers paramdecls fields =
- let r = constr_of_reference Evd.empty (Global.env()) structref in
+let declare_projections indsp coers fields =
+ let mispec = Global.lookup_mind_specif (indsp,[||]) in
+ let paramdecls = Inductive.mis_params_ctxt mispec in
+ let paramdecls =
+ List.map (fun (na,b,t) -> match na with Name id -> (id,b,t) | _ -> assert false)
+ paramdecls in
+ let r = constr_of_reference Evd.empty (Global.env()) (IndRef indsp) in
let paramargs = List.rev (List.map (fun (id,_,_) -> mkVar id) paramdecls) in
let rp = applist (r, paramargs) in
let x = Environ.named_hd (Global.env()) r Anonymous in
@@ -107,6 +112,7 @@ let declare_projections structref coers paramdecls fields =
it_mkNamedLambda_or_LetIn (mkLambda (x, rp, body)) paramdecls in
let name =
try
+ let proj = instantiate_inductive_section_params proj indsp in
let cie = { const_entry_body = proj; const_entry_type = None} in
let sp =
declare_constant fi (ConstantEntry cie,NeverDischarge,false)
@@ -122,7 +128,7 @@ let declare_projections structref coers paramdecls fields =
let constr_fi =
constr_of_reference Evd.empty (Global.env()) refi in
if coe then begin
- let cl = Class.class_of_ref structref in
+ let cl = Class.class_of_ref (IndRef indsp) in
Class.try_add_new_coercion_with_source
refi NeverDischarge cl
end;
@@ -163,13 +169,13 @@ let definition_structure (is_coe,idstruc,ps,cfs,idbuild,s) =
mind_entry_typename = idstruc;
mind_entry_arity = mkSort s;
mind_entry_consnames = [idbuild];
- mind_entry_lc = [type_constructor] } in
+ mind_entry_lc = [type_constructor] } in
let mie =
{ mind_entry_finite = true;
mind_entry_inds = [mie_ind] } in
let sp = declare_mutual_with_eliminations mie in
let rsp = (sp,0) in (* This is ind path of idstruc *)
- let sp_projs = declare_projections (IndRef rsp) coers params fields in
+ let sp_projs = declare_projections rsp coers fields in
let build = ConstructRef (rsp,1) in (* This is construct path of idbuild *)
if is_coe then Class.try_add_new_coercion build NeverDischarge;
Recordops.add_new_struc (rsp,idbuild,nparams,List.rev sp_projs)
diff --git a/toplevel/record.mli b/toplevel/record.mli
index ac2c6836e..b678cc3e5 100644
--- a/toplevel/record.mli
+++ b/toplevel/record.mli
@@ -12,8 +12,7 @@ open Sign
[coers]; it returns the absolute names of projections *)
val declare_projections :
- global_reference -> bool list ->
- named_context -> named_context -> constant_path option list
+ inductive_path -> bool list -> named_context -> constant_path option list
val definition_structure :
bool * identifier * (identifier * Coqast.t) list *