summaryrefslogtreecommitdiff
path: root/toplevel/discharge.ml
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel/discharge.ml')
-rw-r--r--toplevel/discharge.ml364
1 files changed, 61 insertions, 303 deletions
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index 281ff1b6..6c543079 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -6,325 +6,83 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: discharge.ml,v 1.81.2.2 2005/11/29 21:40:53 letouzey Exp $ *)
+(* $Id: discharge.ml 7493 2005-11-02 22:12:16Z mohring $ *)
-open Pp
-open Util
open Names
-open Nameops
+open Util
open Sign
open Term
-open Declarations
open Entries
-open Inductive
-open Instantiate
-open Reduction
+open Declarations
open Cooking
-open Typeops
-open Libnames
-open Libobject
-open Lib
-open Nametab
-open Declare
-open Impargs
-open Classops
-open Class
-open Recordops
-open Library
-open Indtypes
-open Nametab
-open Decl_kinds
-let recalc_sp dir sp =
- let (_,spid) = repr_path sp in Libnames.make_path dir spid
+(********************************)
+(* Discharging mutual inductive *)
-let recalc_kn dir kn =
- let (mp,_,l) = Names.repr_kn kn in
- Names.make_kn mp dir l
+let detype_param = function
+ | (Name id,None,p) -> id, Entries.LocalAssum p
+ | (Name id,Some p,_) -> id, Entries.LocalDef p
+ | (Anonymous,_,_) -> anomaly"Unnamed inductive local variable"
-let rec find_var id = function
- | [] -> false
- | (x,b,_)::l -> if x = id then b=None else find_var id l
+(* Replace
-let build_abstract_list sec_sp hyps ids_to_discard =
- let l1,l2 =
- List.split
- (List.fold_left
- (fun vars id ->
- if find_var id hyps then (mkVar id, Libnames.make_path sec_sp id)::vars
- else vars)
- [] ids_to_discard) in
- Array.of_list l1, l2
+ Var(y1)..Var(yq):C1..Cq |- Ij:Bj
+ Var(y1)..Var(yq):C1..Cq; I1..Ip:B1..Bp |- ci : Ti
-(* Discharge of inductives is done here (while discharge of constants
- is done by the kernel for efficiency). *)
+ by
-let abstract_inductive sec_sp ids_to_abs hyps inds =
- let abstract_one_assum id t inds =
- let ntyp = List.length inds in
- let new_refs =
- list_tabulate (fun k -> applist(mkRel (k+2),[mkRel 1])) ntyp in
- let inds' =
- List.map
- (function (np,tname,arity,cnames,lc) ->
- let arity' = mkNamedProd id t arity in
- let lc' =
- List.map (fun b -> mkNamedProd id t (substl new_refs b)) lc
- in
- (np,tname,arity',cnames,lc'))
- inds
- in
- inds' in
- let abstract_one_def id c inds =
- List.map
- (function (np,tname,arity,cnames,lc) ->
- let arity' = replace_vars [id, c] arity in
- let lc' = List.map (replace_vars [id, c]) lc in
- (np,tname,arity',cnames,lc'))
- inds in
- let abstract_once ((hyps,inds,vars) as sofar) id =
- match hyps with
- | (hyp,None,t as d)::rest when id = hyp ->
- let inds' = abstract_one_assum hyp t inds in
- (rest, inds', (mkVar id, Libnames.make_path sec_sp id)::vars)
- | (hyp,Some b,t as d)::rest when id = hyp ->
- let inds' = abstract_one_def hyp b inds in
- (rest, inds', vars)
- | _ -> sofar in
- let (_,inds',vars) =
- List.fold_left abstract_once (hyps,inds,[]) ids_to_abs in
- let inds'' =
- List.map
- (fun (nparams,a,arity,c,lc) ->
- let nparams' = nparams + (List.length vars) in
- let params, 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
- (function
- | (Name id,None,p) -> id, Entries.LocalAssum p
- | (Name id,Some p,_) -> id, Entries.LocalDef p
- | (Anonymous,_,_) -> anomaly"Unnamed inductive local variable")
- params in
- { mind_entry_params = params';
- mind_entry_typename = a;
- mind_entry_arity = short_arity;
- mind_entry_consnames = c;
- mind_entry_lc = shortlc })
- inds' in
- let l1,l2 = List.split vars in
- (inds'', Array.of_list l1, l2)
+ |- Ij: (y1..yq:C1..Cq)Bj
+ I1..Ip:(B1 y1..yq)..(Bp y1..yq) |- ci : (y1..yq:C1..Cq)Ti[Ij:=(Ij y1..yq)]
+*)
-let process_inductive sec_sp osecsp nsecsp oldenv (ids_to_discard,modlist) mib =
- assert (Array.length mib.mind_packets > 0);
- let record = mib.mind_record in
- let finite = mib.mind_finite in
+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 (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
+ (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 (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
+ { 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_type modlist mip.mind_user_arity in
- let lc = Array.map (expmod_type modlist) mip.mind_user_lc in
- (nparams,
- mip.mind_typename,
+ let arity = expmod_constr modlist mip.mind_user_arity in
+ let lc = Array.map (expmod_constr modlist) mip.mind_user_lc in
+ (mip.mind_typename,
arity,
Array.to_list mip.mind_consnames,
Array.to_list lc))
- mib.mind_packets
- in
- let hyps = mib.mind_hyps in
- let hyps' =
- Sign.fold_named_context
- (fun (x,b,t) sgn ->
- Sign.add_named_decl
- (x, option_app (expmod_constr modlist) b,expmod_constr modlist t)
- sgn)
- mib.mind_hyps ~init:empty_named_context in
- let (inds',abs_vars,discharged_hyps ) =
- abstract_inductive sec_sp ids_to_discard hyps' inds in
- let lmodif_one_mind i =
- let nbc = Array.length mib.mind_packets.(i).mind_consnames in
- (((osecsp,i), DO_ABSTRACT ((nsecsp,i),abs_vars)),
- list_tabulate
- (function j ->
- let j' = j + 1 in
- (((osecsp,i),j'), DO_ABSTRACT (((nsecsp,i),j'),abs_vars)))
- nbc)
- in
- let indmodifs,cstrmodifs =
- List.split (list_tabulate lmodif_one_mind mib.mind_ntypes) in
- ({ mind_entry_record = record;
- mind_entry_finite = finite;
- mind_entry_inds = inds' },
- indmodifs,
- List.flatten cstrmodifs,
- discharged_hyps)
-
-(* Discharge messages. *)
-
-let constant_message id =
- Options.if_verbose ppnl (pr_id id ++ str " is discharged.")
-
-let inductive_message inds =
- Options.if_verbose
- ppnl
- (hov 0
- (match inds with
- | [] -> assert false
- | [ind] ->
- (pr_id ind.mind_entry_typename ++ str " is discharged.")
- | l ->
- (prlist_with_sep pr_coma
- (fun ind -> pr_id ind.mind_entry_typename) l ++
- spc () ++ str "are discharged.")))
-
-(* Discharge operations for the various objects of the environment. *)
-
-type opacity = bool
-
-type discharge_operation =
- | Variable of identifier * section_variable_entry * local_kind *
- implicits_flags * Dischargedhypsmap.discharged_hyps
- | Constant of identifier * recipe * global_kind * constant *
- implicits_flags * Dischargedhypsmap.discharged_hyps
- | Inductive of mutual_inductive_entry * implicits_flags *
- Dischargedhypsmap.discharged_hyps
- | Class of cl_typ * cl_info_typ
- | Struc of inductive * (unit -> struc_typ)
- | Objdef of constant
- | Coercion of coercion_entry
- | Require of library_reference
- | Constraints of Univ.constraints
-
-(* Main function to traverse the library segment and compute the various
- discharge operations. *)
-
-let process_object oldenv olddir full_olddir newdir
-(* {dir -> newdir} {sec_sp -> full_olddir, olddir} *)
- (ops,ids_to_discard,(constl,indl,cstrl as work_alist)) ((sp,kn),lobj) =
- let tag = object_tag lobj in
- match tag with
- | "VARIABLE" ->
- let ((id,c,t),cst) = get_variable_with_constraints (basename sp) in
- (* VARIABLE means local (entry Variable/Hypothesis/Local and are *)
- (* always discharged *)
- (Constraints cst :: ops, id :: ids_to_discard, work_alist)
-
- | "CONSTANT" ->
- (* CONSTANT means never discharge (though visibility may vary) *)
- let kind = constant_kind sp in
- let kn = Nametab.locate_constant (qualid_of_sp sp) in
- let lab = label kn in
- let cb = Environ.lookup_constant kn oldenv in
- let imp = is_implicit_constant kn in
- let newkn = recalc_kn newdir kn in
- let abs_vars,discharged_hyps0 =
- build_abstract_list full_olddir cb.const_hyps ids_to_discard in
- (* let's add the new discharged hypothesis to those already discharged*)
- let discharged_hyps =
- discharged_hyps0 @ Dischargedhypsmap.get_discharged_hyps sp in
- let mods = [ (kn, DO_ABSTRACT(newkn,abs_vars)) ]
- in
- let r = { d_from = cb;
- d_modlist = work_alist;
- d_abstract = ids_to_discard } in
- let op = Constant (id_of_label lab,r,kind,newkn,imp,discharged_hyps) in
- (op :: ops, ids_to_discard, (mods@constl, indl, cstrl))
-
- | "INDUCTIVE" ->
- let kn = Nametab.locate_mind (qualid_of_sp sp) in
- let mib = Environ.lookup_mind kn oldenv in
- let newkn = recalc_kn newdir kn in
- let imp = is_implicit_inductive_definition kn in
-(* let imp = is_implicit_args (* CHANGE *) in*)
- let (mie,indmods,cstrmods,discharged_hyps0) =
- process_inductive full_olddir kn newkn oldenv (ids_to_discard,work_alist) mib in
- (* let's add the new discharged hypothesis to those already discharged*)
- let discharged_hyps =
- discharged_hyps0 @ Dischargedhypsmap.get_discharged_hyps sp in
- ((Inductive(mie,imp,discharged_hyps)) :: ops, ids_to_discard,
- (constl,indmods@indl,cstrmods@cstrl))
-
- | "CLASS" ->
- let ((cl,clinfo) as x) = outClass lobj in
- if clinfo.cl_strength = Local then
- (ops,ids_to_discard,work_alist)
- else
- let (y1,y2) = process_class olddir ids_to_discard x in
- ((Class (y1,y2))::ops, ids_to_discard, work_alist)
-
- | "COERCION" ->
- let (_,coeinfo,_,_ as x) = outCoercion lobj in
- if coercion_strength coeinfo = Local then
- (ops,ids_to_discard,work_alist)
- else
- let y = process_coercion olddir ids_to_discard x in
- ((Coercion y)::ops, ids_to_discard, work_alist)
-
- | "STRUCTURE" ->
- let ((kn,i),info) = outStruc lobj in
- let newkn = recalc_kn newdir kn in
- let strobj () =
- let mib = Environ.lookup_mind newkn (Global.env ()) in
- { s_CONST = info.s_CONST;
- s_PARAM = mib.mind_packets.(0).mind_nparams;
- s_PROJ = List.map (option_app (fun kn -> recalc_kn newdir kn)) info.s_PROJ } in
- ((Struc ((newkn,i),strobj))::ops, ids_to_discard, work_alist)
-
- | "OBJDEF1" ->
- let kn = outObjDef1 lobj in
- let new_kn = recalc_kn newdir kn in
- ((Objdef new_kn)::ops, ids_to_discard, work_alist)
-
- | "REQUIRE" ->
- let c = out_require lobj in
- ((Require c)::ops, ids_to_discard, work_alist)
-
- | _ -> (ops,ids_to_discard,work_alist)
-
-let process_item oldenv olddir full_olddir newdir acc = function
- | (sp,Leaf lobj) ->
- process_object oldenv olddir full_olddir newdir acc (sp,lobj)
- | (_,_) -> acc
-
-let process_operation = function
- | Variable (id,expmod_a,stre,imp,discharged_hyps) ->
- (* Warning:parentheses needed to get a side-effect from with_implicits *)
- with_implicits imp (redeclare_variable id discharged_hyps)
- (Lib.cwd(),expmod_a,stre)
- | Constant (id,r,stre,kn,imp,discharged_hyps) ->
- with_implicits imp (redeclare_constant id discharged_hyps) (r,stre);
- constant_message id
- | Inductive (mie,imp,discharged_hyps) ->
- let _ = with_implicits imp (redeclare_inductive discharged_hyps) mie in
- inductive_message mie.mind_entry_inds
- | Class (y1,y2) ->
- Lib.add_anonymous_leaf (inClass (y1,y2))
- | Struc (newsp,strobj) ->
- Lib.add_anonymous_leaf (inStruc (newsp,strobj ()))
- | Objdef newsp ->
- begin try Recordobj.objdef_declare (ConstRef newsp) with _ -> () end
- | Coercion y -> add_new_coercion y
- | Require y -> reload_library y
- | Constraints y -> Global.add_constraints y
-
-let catch_not_found f x =
- try f x
- with Not_found ->
- error ("Something is missing; perhaps a reference to a"^
- " module required inside the section")
-
-let close_section _ s =
- let oldenv = Global.env() in
- let prefix,decls,fs = close_section false s in
- let full_olddir, (_,olddir) = prefix in
- let newdir = fst (split_dirpath olddir) in
- let (ops,ids,_) =
- List.fold_left
- (process_item oldenv olddir full_olddir newdir) ([],[],([],[],[])) decls
- in
- let ids = last_section_hyps olddir in
- Summary.section_unfreeze_summaries fs;
- catch_not_found (List.iter process_operation) (List.rev ops);
- Nametab.push_dir (Until 1) full_olddir (DirClosedSection full_olddir)
+ mib.mind_packets in
+ let sechyps' = map_named_context (expmod_constr modlist) sechyps 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' }