aboutsummaryrefslogtreecommitdiff
path: root/checker/safe_typing.ml
diff options
context:
space:
mode:
authorbarras2008-04-21 16:54:38 +0000
committerbarras2008-04-21 16:54:38 +0000
commitd09af1d5ca8bb610cec40918b23be67ba6f9673f (patch)
treea0ffa9b6df25e44b7ce51aa6017781f9bac2f84a /checker/safe_typing.ml
parent2407beea26ae531431db3123ecba6a08acd4e3e2 (diff)
added the .vo checker (with independent Makefile)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10826 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'checker/safe_typing.ml')
-rw-r--r--checker/safe_typing.ml248
1 files changed, 248 insertions, 0 deletions
diff --git a/checker/safe_typing.ml b/checker/safe_typing.ml
new file mode 100644
index 0000000000..c6388499a7
--- /dev/null
+++ b/checker/safe_typing.ml
@@ -0,0 +1,248 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* $Id: safe_typing.ml 10275 2007-10-30 11:01:24Z barras $ *)
+
+open Pp
+open Util
+open Names
+open Declarations
+open Environ
+open Mod_checking
+
+(*
+let type_modpath env mp =
+ strengthen env (lookup_module mp env).mod_type mp
+
+let rec check_spec_body env mp lab = function
+ | SPBconst cb ->
+ let kn = mp, empty_dirpath, lab in
+ check_constant_declaration env kn cb
+ | SPBmind mib ->
+ let kn = mp, empty_dirpath, lab in
+ Indtypes.check_inductive env kn mib
+ | SPBmodule msb ->
+ check_mod_spec env msb;
+ Modops.add_module (MPdot(mp,lab)) (module_body_of_type msb.msb_modtype)
+ (add_modtype_constraints env msb.msb_modtype)
+ | SPBmodtype mty ->
+ let kn = mp, empty_dirpath, lab in
+ check_modtype env mty;
+ add_modtype kn mty (add_modtype_constraints env mty)
+
+and check_mod_spec env msb =
+ let env' = add_constraints msb.msb_constraints env in
+ check_modtype env' msb.msb_modtype;
+
+(* Subtyping.check_equal env' msb.msb_modtype (MTBident *)
+ (* TODO: check equiv *)
+ env'
+
+(* !!!: modtype needs mp (the name it will be given) because
+ submodule should be added without reference to self *)
+and check_modtype env = function
+ | MTBident kn ->
+ (try let _ = lookup_modtype kn env in ()
+ with Not_found -> failwith ("unbound module type "(*^string_of_kn kn*)))
+ | MTBfunsig (mbid,marg,mbody) ->
+ check_modtype env marg;
+ let env' =
+ add_module (MPbound mbid) (module_body_of_type marg)
+ (add_modtype_constraints env marg) in
+ check_modtype env' mbody
+ | MTBsig (msid,sign) ->
+ let _ =
+ List.fold_left (fun env (lab,mb) ->
+ check_spec_body env (MPself msid) lab mb) env sign in
+ ()
+
+
+let elem_spec_of_body (lab,e) =
+ lab,
+ match e with
+ SEBconst cb -> SPBconst cb
+ | SEBmind mind -> SPBmind mind
+ | SEBmodule msb -> SPBmodule (module_spec_of_body msb)
+ | SEBmodtype mtb -> SPBmodtype mtb
+
+let rec check_module env mb =
+ let env' = add_module_constraints env mb in
+ (* mod_type *)
+ check_modtype env' mb.mod_type;
+ (* mod_expr *)
+ let msig =
+ match mb.mod_expr with
+ Some mex ->
+ let msig = infer_mod_expr env' mex in
+ Subtyping.check_subtypes env' msig mb.mod_type;
+ msig
+ | None -> mb.mod_type in
+ (* mod_user_type *)
+ (match mb.mod_user_type with
+ Some usig -> Subtyping.check_subtypes env' msig usig
+ | None -> ());
+ (* mod_equiv *)
+ (match mb.mod_equiv with
+ Some mid ->
+ if mb.mod_expr <> Some(MEBident mid) then
+ failwith "incorrect module alias"
+ | None -> ());
+
+and infer_mod_expr env = function
+ MEBident mp -> type_modpath env mp
+ | MEBstruct(msid,msb) ->
+ let mp = MPself msid in
+ let _ =
+ List.fold_left (fun env (lab,mb) ->
+ struct_elem_body env mp lab mb) env msb in
+ MTBsig(msid,List.map elem_spec_of_body msb)
+ | MEBfunctor (arg_id, arg, body) ->
+ check_modtype env arg;
+ let env' = add_module (MPbound arg_id) (module_body_of_type arg) env in
+ let body_ty = infer_mod_expr env' body in
+ MTBfunsig (arg_id, arg, body_ty)
+ | MEBapply (fexpr,MEBident mp,_) ->
+ let ftb = infer_mod_expr env fexpr in
+ let ftb = scrape_modtype env ftb in
+ let farg_id, farg_b, fbody_b = destr_functor ftb in
+ let mtb = type_modpath env mp in
+ Subtyping.check_subtypes env mtb farg_b;
+ subst_modtype (map_mbid farg_id mp) fbody_b
+ | MEBapply _ ->
+ failwith "functor argument must be a module variable"
+
+and struct_elem_body env mp lab = function
+ | SEBconst cb ->
+ let kn = mp, empty_dirpath, lab in
+ check_constant_declaration env kn cb
+ | SEBmind mib ->
+ let kn = mp, empty_dirpath, lab in
+ Indtypes.check_inductive env kn mib
+ | SEBmodule msb ->
+ check_module env msb;
+(*msgnl(str"MODULE OK: "++prkn(make_kn mp empty_dirpath lab)++fnl());*)
+ Modops.add_module (MPdot(mp,lab)) msb
+ (add_module_constraints env msb)
+ | SEBmodtype mty ->
+ check_modtype env mty;
+ add_modtype (mp, empty_dirpath, lab) mty
+ (add_modtype_constraints env mty)
+*)
+
+(************************************************************************)
+(*
+ * Global environment
+ *)
+
+let genv = ref empty_env
+let reset () = genv := empty_env
+let get_env () = !genv
+
+let set_engagement c =
+ genv := set_engagement c !genv
+
+(* full_add_module adds module with universes and constraints *)
+let full_add_module dp mb digest =
+ let env = !genv in
+ let mp = MPfile dp in
+ let env = add_module_constraints env mb in
+ let env = Modops.add_module mp mb env in
+ genv := add_digest env dp digest
+
+(* Check that the engagement expected by a library matches the initial one *)
+let check_engagement env c =
+ match engagement env, c with
+ | Some ImpredicativeSet, Some ImpredicativeSet -> ()
+ | _, None -> ()
+ | _, Some ImpredicativeSet ->
+ error "Needs option -impredicative-set"
+
+(* Libraries = Compiled modules *)
+
+let report_clash f caller dir =
+ let msg =
+ str "compiled library " ++ str(string_of_dirpath caller) ++
+ spc() ++ str "makes inconsistent assumptions over library" ++ spc() ++
+ str(string_of_dirpath dir) ++ fnl() in
+ f msg
+
+
+let check_imports f caller env needed =
+ let check (dp,stamp) =
+ try
+ let actual_stamp = lookup_digest env dp in
+ if stamp <> actual_stamp then report_clash f caller dp
+ with Not_found ->
+ error ("Reference to unknown module " ^ (string_of_dirpath dp))
+ in
+ List.iter check needed
+
+
+
+(* Remove the body of opaque constants in modules *)
+(* also remove mod_expr ? *)
+let rec lighten_module mb =
+ { mb with
+ mod_expr = Option.map lighten_modexpr mb.mod_expr;
+ mod_type = Option.map lighten_modexpr mb.mod_type }
+
+and lighten_struct struc =
+ let lighten_body (l,body) = (l,match body with
+ | SFBconst ({const_opaque=true} as x) -> SFBconst {x with const_body=None}
+ | (SFBconst _ | SFBmind _ | SFBalias _) as x -> x
+ | SFBmodule m -> SFBmodule (lighten_module m)
+ | SFBmodtype m -> SFBmodtype
+ ({m with
+ typ_expr = lighten_modexpr m.typ_expr}))
+ in
+ List.map lighten_body struc
+
+and lighten_modexpr = function
+ | SEBfunctor (mbid,mty,mexpr) ->
+ SEBfunctor (mbid,
+ ({mty with
+ typ_expr = lighten_modexpr mty.typ_expr}),
+ lighten_modexpr mexpr)
+ | SEBident mp as x -> x
+ | SEBstruct (msid, struc) ->
+ SEBstruct (msid, lighten_struct struc)
+ | SEBapply (mexpr,marg,u) ->
+ SEBapply (lighten_modexpr mexpr,lighten_modexpr marg,u)
+ | SEBwith (seb,wdcl) ->
+ SEBwith (lighten_modexpr seb,wdcl)
+
+let lighten_library (dp,mb,depends,s) = (dp,lighten_module mb,depends,s)
+
+
+type compiled_library =
+ dir_path *
+ module_body *
+ (dir_path * Digest.t) list *
+ engagement option
+
+(* When the module is checked, digests do not need to match, but a
+ warning is issued in case of mismatch *)
+let import (dp,mb,depends,engmt as vo) digest =
+Validate.val_vo (Obj.repr vo);
+prerr_endline "*** vo validated ***";
+ let env = !genv in
+ check_imports msg_warning dp env depends;
+ check_engagement env engmt;
+ check_module env mb;
+ (* We drop proofs once checked *)
+(* let mb = lighten_module mb in*)
+ full_add_module dp mb digest
+
+(* When the module is admitted, digests *must* match *)
+let unsafe_import (dp,mb,depends,engmt) digest =
+ let env = !genv in
+ check_imports (errorlabstrm"unsafe_import") dp env depends;
+ check_engagement env engmt;
+ (* We drop proofs once checked *)
+(* let mb = lighten_module mb in*)
+ full_add_module dp mb digest