diff options
| author | soubiran | 2008-02-01 12:18:37 +0000 |
|---|---|---|
| committer | soubiran | 2008-02-01 12:18:37 +0000 |
| commit | 7acb63cad5f92c2618f99ca2a812a465092a523f (patch) | |
| tree | b673bec4833d608f314c132ff85a0ffc5eab1e0f /kernel/modops.ml | |
| parent | 9b913feb3532c15aad771f914627a7a82743e625 (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.ml | 359 |
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 + |
