aboutsummaryrefslogtreecommitdiff
path: root/kernel/modops.ml
diff options
context:
space:
mode:
authorsoubiran2008-02-01 12:18:37 +0000
committersoubiran2008-02-01 12:18:37 +0000
commit7acb63cad5f92c2618f99ca2a812a465092a523f (patch)
treeb673bec4833d608f314c132ff85a0ffc5eab1e0f /kernel/modops.ml
parent9b913feb3532c15aad771f914627a7a82743e625 (diff)
Beaoucoup de changements dans la representation interne des modules.
kernel: -declaration.ml unification des representations pour les modules et modules types. (type struct_expr_body) -mod_typing.ml le typage des modules est separe de l'evaluation des modules -modops.ml nouvelle fonction qui pour toutes expressions de structure calcule sa forme evaluee.(eval_struct) -safe_typing.ml ajout du support du nouvel operateur Include.(add_include). library: -declaremods.ml nouveaux objets Include et Module-alias et gestion de la resolution de noms pour les alias via la nametab. parsing: -g_vernac.ml4: nouvelles regles pour le support des Includes et pour l'application des signatures fonctorielles. extraction: Adaptation a la nouvelle representation des modules et support de l'operateur with. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10497 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'kernel/modops.ml')
-rw-r--r--kernel/modops.ml359
1 files changed, 233 insertions, 126 deletions
diff --git a/kernel/modops.ml b/kernel/modops.ml
index 135a377471..c5b8e15b50 100644
--- a/kernel/modops.ml
+++ b/kernel/modops.ml
@@ -83,43 +83,36 @@ let error_local_context lo =
let error_no_such_label_sub l l1 l2 =
- error (l1^" is not a subtype of "^l2^".\nThe field "^(string_of_label l)^" is missing (or invisible) in "^l1^".")
+ error (l1^" is not a subtype of "^l2^".\nThe field "^(string_of_label l)^" is missing in "^l1^".")
-let rec scrape_modtype env = function
- | MTBident kn -> scrape_modtype env (lookup_modtype kn env)
- | mtb -> mtb
+
+
+let rec list_split_assoc k rev_before = function
+ | [] -> raise Not_found
+ | (k',b)::after when k=k' -> rev_before,b,after
+ | h::tail -> list_split_assoc k (h::rev_before) tail
+
+let path_of_seb = function
+ | SEBident mb -> mb
+ | _ -> anomaly "Modops: evaluation failed."
+
+
+let destr_functor env mtb =
+ match mtb with
+ | SEBfunctor (arg_id,arg_t,body_t) ->
+ (arg_id,arg_t,body_t)
+ | _ -> error_not_a_functor mtb
(* the constraints are not important here *)
-let module_body_of_spec msb =
- { mod_type = msb.msb_modtype;
- mod_equiv = msb.msb_equiv;
- mod_expr = None;
- mod_user_type = None;
- mod_constraints = Constraint.empty;
- mod_retroknowledge = []}
let module_body_of_type mtb =
- { mod_type = mtb;
+ { mod_type = Some mtb;
mod_equiv = None;
mod_expr = None;
- mod_user_type = None;
mod_constraints = Constraint.empty;
mod_retroknowledge = []}
-(* the constraints are not important here *)
-let module_spec_of_body mb =
- { msb_modtype = mb.mod_type;
- msb_equiv = mb.mod_equiv;
- msb_constraints = Constraint.empty}
-
-
-
-let destr_functor = function
- | MTBfunsig (arg_id,arg_t,body_t) -> (arg_id,arg_t,body_t)
- | mtb -> error_not_a_functor mtb
-
-
let rec check_modpath_equiv env mp1 mp2 =
if mp1=mp2 then () else
let mb1 = lookup_module mp1 env in
@@ -131,47 +124,62 @@ let rec check_modpath_equiv env mp1 mp2 =
| Some mp2' -> check_modpath_equiv env mp2' mp1)
| Some mp1' -> check_modpath_equiv env mp2 mp1'
+let subst_with_body sub = function
+ | With_module_body(id,mp,cst) ->
+ With_module_body(id,subst_mp sub mp,cst)
+ | With_definition_body(id,cb) ->
+ With_definition_body( id,subst_const_body sub cb)
-let rec subst_modtype sub = function
- (* This is the case in which I am substituting a whole module.
- For instance "Module M(X). Module N := X. End M". When I apply
- M to M' I must substitute M' for X in "Module N := X". *)
- | MTBident ln -> MTBident (subst_kn sub ln)
- | MTBfunsig (arg_id, arg_b, body_b) ->
- MTBfunsig (arg_id,
- subst_modtype sub arg_b,
- subst_modtype sub body_b)
- | MTBsig (sid1, msb) ->
- MTBsig (sid1, subst_signature sub msb)
-
-and subst_signature sub sign =
+let rec subst_modtype sub mtb =
+ subst_struct_expr sub mtb
+
+and subst_structure sub sign =
let subst_body = function
- SPBconst cb ->
- SPBconst (subst_const_body sub cb)
- | SPBmind mib ->
- SPBmind (subst_mind sub mib)
- | SPBmodule mb ->
- SPBmodule (subst_module sub mb)
- | SPBmodtype mtb ->
- SPBmodtype (subst_modtype sub mtb)
+ SFBconst cb ->
+ SFBconst (subst_const_body sub cb)
+ | SFBmind mib ->
+ SFBmind (subst_mind sub mib)
+ | SFBmodule mb ->
+ SFBmodule (subst_module sub mb)
+ | SFBmodtype mtb ->
+ SFBmodtype (subst_modtype sub mtb)
in
List.map (fun (l,b) -> (l,subst_body b)) sign
and subst_module sub mb =
- let mtb' = subst_modtype sub mb.msb_modtype in
+ let mtb' = Option.smartmap (subst_modtype sub) mb.mod_type in
(* This is similar to the previous case. In this case we have
a module M in a signature that is knows to be equivalent to a module M'
(because the signature is "K with Module M := M'") and we are substituting
M' with some M''. *)
- let mpo' = Option.smartmap (subst_mp sub) mb.msb_equiv in
- if mtb'==mb.msb_modtype && mpo'==mb.msb_equiv then mb else
- { msb_modtype=mtb';
- msb_equiv=mpo';
- msb_constraints=mb.msb_constraints}
+ let me' = Option.smartmap (subst_struct_expr sub) mb.mod_expr in
+ let mpo' = Option.smartmap (subst_mp sub) mb.mod_equiv in
+ if mtb'==mb.mod_type && mpo'==mb.mod_equiv && mb.mod_expr == me'
+ then mb else
+ { mod_expr = me';
+ mod_type=mtb';
+ mod_equiv=mpo';
+ mod_constraints=mb.mod_constraints;
+ mod_retroknowledge=mb.mod_retroknowledge}
+
+
+and subst_struct_expr sub = function
+ | SEBident mp -> SEBident (subst_mp sub mp)
+ | SEBfunctor (msid, mtb, meb') ->
+ SEBfunctor(msid,subst_modtype sub mtb,subst_struct_expr sub meb')
+ | SEBstruct (msid,str)->
+ SEBstruct(msid, subst_structure sub str)
+ | SEBapply (meb1,meb2,cst)->
+ SEBapply(subst_struct_expr sub meb1,
+ subst_struct_expr sub meb2,
+ cst)
+ | SEBwith (meb,wdb)->
+ SEBwith(subst_struct_expr sub meb,
+ subst_with_body sub wdb)
+
let subst_signature_msid msid mp =
- subst_signature (map_msid msid mp)
-
+ subst_structure (map_msid msid mp)
(* spiwack: here comes the function which takes care of importing
the retroknowledge declared in the library *)
@@ -198,43 +206,150 @@ let add_retroknowledge msid mp =
imports 10 000 retroknowledge registration.*)
List.fold_right subst_and_perform lclrk env
-(* we assume that the substitution of "mp" into "msid" is already done
-(or unnecessary) *)
-let rec add_signature mp sign env =
+
+
+let strengthen_const env mp l cb =
+ match cb.const_opaque, cb.const_body with
+ | false, Some _ -> cb
+ | true, Some _
+ | _, None ->
+ let const = mkConst (make_con mp empty_dirpath l) in
+ let const_subs = Some (Declarations.from_val const) in
+ {cb with
+ const_body = const_subs;
+ const_opaque = false;
+ const_body_code = Cemitcodes.from_val
+ (compile_constant_body env const_subs false false)
+ }
+
+let strengthen_mind env mp l mib = match mib.mind_equiv with
+ | Some _ -> mib
+ | None -> {mib with mind_equiv = Some (make_kn mp empty_dirpath l)}
+
+
+let rec eval_struct env = function
+ | SEBident mp ->
+ begin
+ match (lookup_modtype mp env) with
+ mtb,None -> eval_struct env mtb
+ | mtb,Some mp -> strengthen_mtb env mp (eval_struct env mtb)
+ end
+ | SEBapply (seb1,seb2,_) ->
+ let svb1 = eval_struct env seb1 in
+ let farg_id, farg_b, fbody_b = destr_functor env svb1 in
+ let mp = path_of_seb seb2 in
+ let resolve = resolver_of_environment farg_id farg_b mp env in
+ eval_struct env (subst_modtype
+ (map_mbid farg_id mp (Some resolve)) fbody_b)
+ | SEBwith (mtb,wdb) -> merge_with env mtb wdb
+ | mtb -> mtb
+
+and type_of_mb env mb =
+ match mb.mod_type,mb.mod_expr with
+ None,Some b -> eval_struct env b
+ | Some t, _ -> eval_struct env t
+ | _,_ -> anomaly
+ "Modops: empty type and empty expr"
+
+and merge_with env mtb with_decl =
+ let msid,sig_b = match (eval_struct env mtb) with
+ | SEBstruct(msid,sig_b) -> msid,sig_b
+ | _ -> error_signature_expected mtb
+ in
+ let id,idl = match with_decl with
+ | With_definition_body (id::idl,_) | With_module_body (id::idl,_,_) -> id,idl
+ | With_definition_body ([],_) | With_module_body ([],_,_) -> assert false
+ in
+ let l = label_of_id id in
+ try
+ let rev_before,spec,after = list_split_assoc l [] sig_b in
+ let before = List.rev rev_before in
+ let new_spec = match with_decl with
+ | With_definition_body ([],_)
+ | With_module_body ([],_,_) -> assert false
+ | With_definition_body ([id],c) ->
+ SFBconst c
+ | With_module_body ([id], mp,cst) ->
+ let old = match spec with
+ SFBmodule msb -> msb
+ | _ -> error_not_a_module (string_of_label l)
+ in
+ let mtb' = eval_struct env (SEBident mp) in
+ let msb =
+ {mod_expr = Some (SEBident mp);
+ mod_type = Some mtb';
+ mod_equiv = Some mp;
+ mod_constraints = cst;
+ mod_retroknowledge = old.mod_retroknowledge }
+ in
+ (SFBmodule msb)
+ | With_definition_body (_::_,_)
+ | With_module_body (_::_,_,_) ->
+ let old = match spec with
+ SFBmodule msb -> msb
+ | _ -> error_not_a_module (string_of_label l)
+ in
+ let new_with_decl = match with_decl with
+ With_definition_body (_,c) -> With_definition_body (idl,c)
+ | With_module_body (_,c,cst) -> With_module_body (idl,c,cst) in
+ let modtype =
+ merge_with env (type_of_mb env old) new_with_decl in
+ let msb =
+ { mod_expr = None;
+ mod_type = Some modtype;
+ mod_equiv = None;
+ mod_constraints = old.mod_constraints;
+ mod_retroknowledge = old.mod_retroknowledge}
+ in
+ (SFBmodule msb)
+ in
+ SEBstruct(msid, before@(l,new_spec)::after)
+ with
+ Not_found -> error_no_such_label l
+
+and add_signature mp sign env =
let add_one env (l,elem) =
let kn = make_kn mp empty_dirpath l in
let con = make_con mp empty_dirpath l in
match elem with
- | SPBconst cb -> Environ.add_constant con cb env
- | SPBmind mib -> Environ.add_mind kn mib env
- | SPBmodule mb ->
- add_module (MPdot (mp,l)) (module_body_of_spec mb) env
+ | SFBconst cb -> Environ.add_constant con cb env
+ | SFBmind mib -> Environ.add_mind kn mib env
+ | SFBmodule mb ->
+ add_module (MPdot (mp,l)) mb env
(* adds components as well *)
- | SPBmodtype mtb -> Environ.add_modtype kn mtb env
+ | SFBmodtype mtb -> Environ.add_modtype (MPdot(mp,l))
+ (mtb,None) env
in
List.fold_left add_one env sign
-
and add_module mp mb env =
let env = Environ.shallow_add_module mp mb env in
- match scrape_modtype env mb.mod_type with
- | MTBident _ -> anomaly "scrape_modtype does not work!"
- | MTBsig (msid,sign) ->
+ let env = match mb.mod_type,mb.mod_expr with
+ | Some mt, _ ->
+ Environ.add_modtype mp (mt,Some mp) env
+ | None, Some me ->
+ Environ.add_modtype mp (me,Some mp) env
+ | _,_ -> anomaly "Modops:Empty expr and type" in
+ let mod_typ = type_of_mb env mb in
+ match mod_typ with
+ | SEBstruct (msid,sign) ->
add_retroknowledge msid mp (mb.mod_retroknowledge)
(add_signature mp (subst_signature_msid msid mp sign) env)
- | MTBfunsig _ -> env
+ | SEBfunctor _ -> env
+ | _ -> anomaly "Modops:the evaluation of the structure failed "
+
-let rec constants_of_specification env mp sign =
+and constants_of_specification env mp sign =
let aux (env,res) (l,elem) =
match elem with
- | SPBconst cb -> env,((make_con mp empty_dirpath l),cb)::res
- | SPBmind _ -> env,res
- | SPBmodule mb ->
- let new_env = add_module (MPdot (mp,l)) (module_body_of_spec mb) env in
+ | SFBconst cb -> env,((make_con mp empty_dirpath l),cb)::res
+ | SFBmind _ -> env,res
+ | SFBmodule mb ->
+ let new_env = add_module (MPdot (mp,l)) mb env in
new_env,(constants_of_modtype env (MPdot (mp,l))
- (module_body_of_spec mb).mod_type) @ res
- | SPBmodtype mtb ->
+ (type_of_mb env mb)) @ res
+ | SFBmodtype mtb ->
(* module type dans un module type.
Il faut au moins mettre mtb dans l'environnement (avec le bon
kn pour pouvoir continuer aller deplier les modules utilisant ce
@@ -250,21 +365,22 @@ let rec constants_of_specification env mp sign =
si on ne rajoute pas T2 dans l'environement de typage
on va exploser au moment du Declare Module
*)
- let new_env = Environ.add_modtype (make_kn mp empty_dirpath l) mtb env in
+ let new_env = Environ.add_modtype (MPdot(mp,l)) (mtb,None) env in
new_env, constants_of_modtype env (MPdot(mp,l)) mtb @ res
in
snd (List.fold_left aux (env,[]) sign)
and constants_of_modtype env mp modtype =
- match scrape_modtype env modtype with
- MTBident _ -> anomaly "scrape_modtype does not work!"
- | MTBsig (msid,sign) ->
- constants_of_specification env mp
- (subst_signature_msid msid mp sign)
- | MTBfunsig _ -> []
-
-(* returns a resolver for kn that maps mbid to mp *)
-let resolver_of_environment mbid modtype mp env =
+ match (eval_struct env modtype) with
+ SEBstruct (msid,sign) ->
+ constants_of_specification env mp
+ (subst_signature_msid msid mp sign)
+ | SEBfunctor _ -> []
+ | _ -> anomaly "Modops:the evaluation of the structure failed "
+
+(* returns a resolver for kn that maps mbid to mp. We only keep
+ constants that have the inline flag *)
+and resolver_of_environment mbid modtype mp env =
let constants = constants_of_modtype env (MPbound mbid) modtype in
let rec make_resolve = function
| [] -> []
@@ -284,65 +400,56 @@ let resolver_of_environment mbid modtype mp env =
let resolve = make_resolve constants in
Mod_subst.make_resolver resolve
-let strengthen_const env mp l cb =
- match cb.const_opaque, cb.const_body with
- | false, Some _ -> cb
- | true, Some _
- | _, None ->
- let const = mkConst (make_con mp empty_dirpath l) in
- let const_subs = Some (Declarations.from_val const) in
- {cb with
- const_body = const_subs;
- const_opaque = false;
- const_body_code = Cemitcodes.from_val
- (compile_constant_body env const_subs false false)
- }
-
-let strengthen_mind env mp l mib = match mib.mind_equiv with
- | Some _ -> mib
- | None -> {mib with mind_equiv = Some (make_kn mp empty_dirpath l)}
-let rec strengthen_mtb env mp mtb = match scrape_modtype env mtb with
- | MTBident _ -> anomaly "scrape_modtype does not work!"
- | MTBfunsig _ -> mtb
- | MTBsig (msid,sign) -> MTBsig (msid,strengthen_sig env msid sign mp)
-
-and strengthen_mod env mp msb =
- { msb_modtype = strengthen_mtb env mp msb.msb_modtype;
- msb_equiv = begin match msb.msb_equiv with
- | Some _ -> msb.msb_equiv
- | None -> Some mp
- end ;
- msb_constraints = msb.msb_constraints; }
-
+and strengthen_mtb env mp mtb =
+ let mtb1 = eval_struct env mtb in
+ match mtb1 with
+ | SEBfunctor _ -> mtb1
+ | SEBstruct (msid,sign) ->
+ SEBstruct (msid,strengthen_sig env msid sign mp)
+ | _ -> anomaly "Modops:the evaluation of the structure failed "
+
+and strengthen_mod env mp mb =
+ let mod_typ = type_of_mb env mb in
+ { mod_expr = mb.mod_expr;
+ mod_type = Some (strengthen_mtb env mp mod_typ);
+ mod_equiv = begin match mb.mod_equiv with
+ | Some _ -> mb.mod_equiv
+ | None -> Some mp
+ end ;
+ mod_constraints = mb.mod_constraints;
+ mod_retroknowledge = mb.mod_retroknowledge}
+
and strengthen_sig env msid sign mp = match sign with
| [] -> []
- | (l,SPBconst cb) :: rest ->
- let item' = l,SPBconst (strengthen_const env mp l cb) in
+ | (l,SFBconst cb) :: rest ->
+ let item' = l,SFBconst (strengthen_const env mp l cb) in
let rest' = strengthen_sig env msid rest mp in
item'::rest'
- | (l,SPBmind mib) :: rest ->
- let item' = l,SPBmind (strengthen_mind env mp l mib) in
+ | (l,SFBmind mib) :: rest ->
+ let item' = l,SFBmind (strengthen_mind env mp l mib) in
let rest' = strengthen_sig env msid rest mp in
item'::rest'
- | (l,SPBmodule mb) :: rest ->
+ | (l,SFBmodule mb) :: rest ->
let mp' = MPdot (mp,l) in
- let item' = l,SPBmodule (strengthen_mod env mp' mb) in
+ let item' = l,SFBmodule (strengthen_mod env mp' mb) in
let env' = add_module
(MPdot (MPself msid,l))
- (module_body_of_spec mb)
- env
+ mb
+ env
in
let rest' = strengthen_sig env' msid rest mp in
item'::rest'
- | (l,SPBmodtype mty as item) :: rest ->
+ | (l,SFBmodtype mty as item) :: rest ->
let env' = add_modtype
- (make_kn (MPself msid) empty_dirpath l)
- mty
+ (MPdot((MPself msid),l))
+ (mty,None)
env
in
let rest' = strengthen_sig env' msid rest mp in
item::rest'
+
let strengthen env mtb mp = strengthen_mtb env mp mtb
+