Commit bfc3c223 authored by Jean-Christophe Filliâtre's avatar Jean-Christophe Filliâtre

merge of the branch 'modules'

parents f4a70768 8e5ef36a
...@@ -10,6 +10,7 @@ why.conf ...@@ -10,6 +10,7 @@ why.conf
*.cmo *.cmo
*.cmi *.cmi
*.cmxs *.cmxs
*.annot
\#*\# \#*\#
# / # /
......
...@@ -283,8 +283,8 @@ install_no_local:: ...@@ -283,8 +283,8 @@ install_no_local::
PGMGENERATED = src/programs/pgm_parser.mli src/programs/pgm_parser.ml \ PGMGENERATED = src/programs/pgm_parser.mli src/programs/pgm_parser.ml \
src/programs/pgm_lexer.ml src/programs/pgm_lexer.ml
PGM_FILES = pgm_ttree pgm_ptree pgm_parser pgm_lexer pgm_effect \ PGM_FILES = pgm_ttree pgm_ptree pgm_parser pgm_lexer \
pgm_env pgm_typing pgm_wp pgm_main pgm_types pgm_module pgm_wp pgm_env pgm_typing pgm_main
PGMMODULES = $(addprefix src/programs/, $(PGM_FILES)) PGMMODULES = $(addprefix src/programs/, $(PGM_FILES))
...@@ -729,9 +729,12 @@ test: bin/why.byte plugins.byte $(TOOLS) ...@@ -729,9 +729,12 @@ test: bin/why.byte plugins.byte $(TOOLS)
@for i in output_coq/*.v; do printf "coq $$i\\n" && coqc $$i ; done @for i in output_coq/*.v; do printf "coq $$i\\n" && coqc $$i ; done
testl: bin/whyml.byte testl: bin/whyml.byte
ocamlrun -bt bin/whyml.byte --debug-all tests/test-pgm-jcf.mlw ocamlrun -bt bin/whyml.byte tests/test-pgm-jcf.mlw
ocamlrun -bt bin/whyml.byte -P alt-ergo tests/test-pgm-jcf.mlw ocamlrun -bt bin/whyml.byte -P alt-ergo tests/test-pgm-jcf.mlw
testl-debug: bin/whyml.byte
ocamlrun -bt bin/whyml.byte --debug-all tests/test-pgm-jcf.mlw
testl-ide: bin/whyide.opt testl-ide: bin/whyide.opt
bin/whyide.opt tests/test-pgm-jcf.mlw bin/whyide.opt tests/test-pgm-jcf.mlw
......
whybench.opt
whybench.byte
...@@ -84,7 +84,7 @@ let alt_ergo : Whyconf.config_prover = ...@@ -84,7 +84,7 @@ let alt_ergo : Whyconf.config_prover =
exit 0 exit 0
(* builds the environment from the [loadpath] *) (* builds the environment from the [loadpath] *)
let env : Env.env = Env.create_env (Lexer.retrieve (Whyconf.loadpath main)) let env : Env.env = Lexer.create_env (Whyconf.loadpath main)
(* loading the Alt-Ergo driver *) (* loading the Alt-Ergo driver *)
let alt_ergo_driver : Driver.driver = Driver.load_driver env alt_ergo.Whyconf.driver let alt_ergo_driver : Driver.driver = Driver.load_driver env alt_ergo.Whyconf.driver
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
;; Note: comment font-lock is guaranteed by suitable syntax entries ;; Note: comment font-lock is guaranteed by suitable syntax entries
;; '("(\\*\\([^*)]\\([^*]\\|\\*[^)]\\)*\\)?\\*)" . font-lock-comment-face) ;; '("(\\*\\([^*)]\\([^*]\\|\\*[^)]\\)*\\)?\\*)" . font-lock-comment-face)
'("{\\([^}]*\\)}" . font-lock-type-face) '("{\\([^}]*\\)}" . font-lock-type-face)
`(,(why-regexp-opt '("use" "clone" "namespace" "import" "export" "inductive" "external" "logic" "parameter" "exception" "axiom" "lemma" "goal" "type")) . font-lock-builtin-face) `(,(why-regexp-opt '("use" "clone" "namespace" "import" "export" "inductive" "external" "logic" "parameter" "exception" "axiom" "lemma" "goal" "type" "mutable" "model")) . font-lock-builtin-face)
`(,(why-regexp-opt '("and" "any" "match" "let" "rec" "in" "if" "then" "else" "begin" "end" "while" "invariant" "variant" "for" "to" "downto" "do" "done" "label" "assert" "absurd" "assume" "check" "ghost" "try" "with" "theory" "uses")) . font-lock-keyword-face) `(,(why-regexp-opt '("and" "any" "match" "let" "rec" "in" "if" "then" "else" "begin" "end" "while" "invariant" "variant" "for" "to" "downto" "do" "done" "label" "assert" "absurd" "assume" "check" "ghost" "try" "with" "theory" "uses" "module")) . font-lock-keyword-face)
; `(,(why-regexp-opt '("unit" "bool" "int" "float" "prop" "array")) . font-lock-type-face) ; `(,(why-regexp-opt '("unit" "bool" "int" "float" "prop" "array")) . font-lock-type-face)
) )
"Minimal highlighting for Why mode") "Minimal highlighting for Why mode")
......
bench.annot
whybench.annot
...@@ -51,7 +51,7 @@ let read_tools absf wc map (name,section) = ...@@ -51,7 +51,7 @@ let read_tools absf wc map (name,section) =
let timelimit = get_int ~default:(timelimit wc_main) section "timelimit" in let timelimit = get_int ~default:(timelimit wc_main) section "timelimit" in
let memlimit = get_int ~default:(memlimit wc_main) section "memlimit" in let memlimit = get_int ~default:(memlimit wc_main) section "memlimit" in
(* env *) (* env *)
let env = Env.create_env (Lexer.retrieve loadpath) in let env = Lexer.create_env loadpath in
(* transformations *) (* transformations *)
let transforms = get_stringl ~default:[] section "transform" in let transforms = get_stringl ~default:[] section "transform" in
let lookup acc t = Trans.compose (Trans.lookup_transform t env) acc in let lookup acc t = Trans.compose (Trans.lookup_transform t env) acc in
......
...@@ -303,7 +303,7 @@ let () = ...@@ -303,7 +303,7 @@ let () =
in in
opt_task := List.fold_left add_meta !opt_task !opt_metas; opt_task := List.fold_left add_meta !opt_task !opt_metas;
let env = Env.create_env (Lexer.retrieve !opt_loadpath) in let env = Lexer.create_env !opt_loadpath in
let map_prover s = let map_prover s =
let prover = try Mstr.find s (get_provers config) with let prover = try Mstr.find s (get_provers config) with
| Not_found -> eprintf "Prover %s not found.@." s; exit 1 | Not_found -> eprintf "Prover %s not found.@." s; exit 1
......
...@@ -46,7 +46,7 @@ let cprovers = Whyconf.get_provers config ...@@ -46,7 +46,7 @@ let cprovers = Whyconf.get_provers config
let timelimit = timelimit main let timelimit = timelimit main
let env = Env.create_env (Lexer.retrieve (loadpath main)) let env = Lexer.create_env (loadpath main)
let provers = Hashtbl.create 17 let provers = Hashtbl.create 17
......
...@@ -22,7 +22,10 @@ open Theory ...@@ -22,7 +22,10 @@ open Theory
(** Environment *) (** Environment *)
type retrieve_channel = string list -> string * in_channel
type env = { type env = {
env_ret_chan : retrieve_channel;
env_retrieve : retrieve_theory; env_retrieve : retrieve_theory;
env_memo : (string list, theory Mnm.t) Hashtbl.t; env_memo : (string list, theory Mnm.t) Hashtbl.t;
env_tag : Hashweak.tag; env_tag : Hashweak.tag;
...@@ -35,7 +38,8 @@ let create_memo () = ...@@ -35,7 +38,8 @@ let create_memo () =
Hashtbl.add ht [] Mnm.empty; Hashtbl.add ht [] Mnm.empty;
ht ht
let create_env = let c = ref (-1) in fun retrieve -> { let create_env = let c = ref (-1) in fun ret_chan retrieve -> {
env_ret_chan = ret_chan;
env_retrieve = retrieve; env_retrieve = retrieve;
env_memo = create_memo (); env_memo = create_memo ();
env_tag = (incr c; Hashweak.create_tag !c) } env_tag = (incr c; Hashweak.create_tag !c) }
...@@ -70,6 +74,8 @@ let find_theory env sl s = ...@@ -70,6 +74,8 @@ let find_theory env sl s =
else try Mnm.find s (find_library env sl) else try Mnm.find s (find_library env sl)
with Not_found -> raise (TheoryNotFound (sl, s)) with Not_found -> raise (TheoryNotFound (sl, s))
let find_channel env = env.env_ret_chan
let env_tag env = env.env_tag let env_tag env = env.env_tag
module Wenv = Hashweak.Make(struct type t = env let tag = env_tag end) module Wenv = Hashweak.Make(struct type t = env let tag = env_tag end)
......
...@@ -27,9 +27,13 @@ val env_tag : env -> Hashweak.tag ...@@ -27,9 +27,13 @@ val env_tag : env -> Hashweak.tag
module Wenv : Hashweak.S with type key = env module Wenv : Hashweak.S with type key = env
type retrieve_theory = env -> string list -> theory Mnm.t type retrieve_channel = string list -> string * in_channel
(** retrieves a channel from a given path; a filename is also returned,
for printing purposes only *)
val create_env : retrieve_theory -> env type retrieve_theory = env -> string list -> theory Mnm.t
val create_env : retrieve_channel -> retrieve_theory -> env
exception TheoryNotFound of string list * string exception TheoryNotFound of string list * string
...@@ -37,6 +41,8 @@ val find_theory : env -> string list -> string -> theory ...@@ -37,6 +41,8 @@ val find_theory : env -> string list -> string -> theory
(** [find_theory e p n] finds the theory named [p.n] in environment [e] (** [find_theory e p n] finds the theory named [p.n] in environment [e]
@raise TheoryNotFound if theory not present in env [e] *) @raise TheoryNotFound if theory not present in env [e] *)
val find_channel : env -> string list -> string * in_channel
(** Parsers *) (** Parsers *)
type read_channel = env -> string -> in_channel -> theory Mnm.t type read_channel = env -> string -> in_channel -> theory Mnm.t
......
...@@ -111,10 +111,10 @@ let load_config config = ...@@ -111,10 +111,10 @@ let load_config config =
let provers = get_provers config in let provers = get_provers config in
*) *)
(* (*
let env = Env.create_env (Lexer.retrieve main.loadpath) in let env = Lexer.create_env main.loadpath in
*) *)
(* temporary sets env to empty *) (* temporary sets env to empty *)
let env = Env.create_env (Lexer.retrieve []) in let env = Lexer.create_env [] in
{ window_height = ide.ide_window_height; { window_height = ide.ide_window_height;
window_width = ide.ide_window_width; window_width = ide.ide_window_width;
tree_width = ide.ide_tree_width; tree_width = ide.ide_tree_width;
......
...@@ -166,7 +166,7 @@ let source_text fname = ...@@ -166,7 +166,7 @@ let source_text fname =
let gconfig = let gconfig =
let c = Gconfig.config in let c = Gconfig.config in
let loadpath = (Whyconf.loadpath (get_main ())) @ List.rev !includes in let loadpath = (Whyconf.loadpath (get_main ())) @ List.rev !includes in
c.env <- Env.create_env (Lexer.retrieve loadpath); c.env <- Lexer.create_env loadpath;
let provers = Whyconf.get_provers c.Gconfig.config in let provers = Whyconf.get_provers c.Gconfig.config in
c.provers <- c.provers <-
Util.Mstr.fold (Gconfig.get_prover_data c.env) provers Util.Mstr.empty; Util.Mstr.fold (Gconfig.get_prover_data c.env) provers Util.Mstr.empty;
......
...@@ -444,7 +444,7 @@ let do_input env drv = function ...@@ -444,7 +444,7 @@ let do_input env drv = function
let () = let () =
try try
let env = Env.create_env (Lexer.retrieve !opt_loadpath) in let env = Lexer.create_env !opt_loadpath in
let drv = Util.option_map (load_driver env) !opt_driver in let drv = Util.option_map (load_driver env) !opt_driver in
Queue.iter (do_input env drv) opt_queue Queue.iter (do_input env drv) opt_queue
with e when not (Debug.test_flag Debug.stack_trace) -> with e when not (Debug.test_flag Debug.stack_trace) ->
......
...@@ -50,6 +50,8 @@ and type_var = { ...@@ -50,6 +50,8 @@ and type_var = {
type_var_loc : loc option; type_var_loc : loc option;
} }
let tvsymbol_of_type_var tv = tv.tvsymbol
let rec print_dty fmt = function let rec print_dty fmt = function
| Tyvar { type_val = Some t } -> | Tyvar { type_val = Some t } ->
print_dty fmt t print_dty fmt t
...@@ -58,10 +60,9 @@ let rec print_dty fmt = function ...@@ -58,10 +60,9 @@ let rec print_dty fmt = function
| Tyapp (s, []) -> | Tyapp (s, []) ->
fprintf fmt "%s" s.ts_name.id_string fprintf fmt "%s" s.ts_name.id_string
| Tyapp (s, [t]) -> | Tyapp (s, [t]) ->
fprintf fmt "%a %s" print_dty t s.ts_name.id_string fprintf fmt "%s %a" s.ts_name.id_string print_dty t
| Tyapp (s, l) -> | Tyapp (s, l) ->
fprintf fmt "(%a) %s" fprintf fmt "%s %a" s.ts_name.id_string (print_list comma print_dty) l
(print_list comma print_dty) l s.ts_name.id_string
let create_ty_decl_var = let create_ty_decl_var =
let t = ref 0 in let t = ref 0 in
......
...@@ -95,3 +95,6 @@ val specialize_term : loc:Ptree.loc -> type_var Htv.t -> term -> dterm ...@@ -95,3 +95,6 @@ val specialize_term : loc:Ptree.loc -> type_var Htv.t -> term -> dterm
val specialize_fmla : loc:Ptree.loc -> type_var Htv.t -> fmla -> dfmla val specialize_fmla : loc:Ptree.loc -> type_var Htv.t -> fmla -> dfmla
(** exported for programs *)
val tvsymbol_of_type_var : type_var -> tvsymbol
...@@ -21,7 +21,7 @@ open Theory ...@@ -21,7 +21,7 @@ open Theory
(** parsing entry points *) (** parsing entry points *)
val retrieve : string list -> Env.retrieve_theory val create_env : string list -> Env.env
(** creates a new typing environment for a given loadpath *) (** creates a new typing environment for a given loadpath *)
val parse_list0_decl : val parse_list0_decl :
......
...@@ -271,21 +271,32 @@ and string = parse ...@@ -271,21 +271,32 @@ and string = parse
Loc.set_file file lb; Loc.set_file file lb;
parse_logic_file env lb parse_logic_file env lb
let retrieve lp env sl = (* searches file [f] in loadpath [lp] *)
let f = List.fold_left Filename.concat "" sl ^ ".why" in let locate_file lp f =
let fl = List.map (fun dir -> Filename.concat dir f) lp in let fl = List.map (fun dir -> Filename.concat dir f) lp in
let file = match List.filter Sys.file_exists fl with match List.filter Sys.file_exists fl with
| [] -> raise Not_found | [] -> raise Not_found
| [file] -> file | [file] -> file
| file1 :: file2 :: _ -> raise (AmbiguousPath (file1, file2)) | file1 :: file2 :: _ -> raise (AmbiguousPath (file1, file2))
let create_env lp =
let ret_chan sl =
let f = List.fold_left Filename.concat "" sl in
let file = locate_file lp f in
file, open_in file
in
let retrieve env sl =
let f = List.fold_left Filename.concat "" sl ^ ".why" in
let file = locate_file lp f in
let c = open_in file in
try
let tl = read_channel env file c in
close_in c;
tl
with
| e -> close_in c; raise e
in in
let c = open_in file in Env.create_env ret_chan retrieve
try
let tl = read_channel env file c in
close_in c;
tl
with
| e -> close_in c; raise e
let () = Env.register_format "why" ["why"] read_channel let () = Env.register_format "why" ["why"] read_channel
} }
......
...@@ -146,6 +146,9 @@ let mem_var x denv = Mstr.mem x denv.dvars ...@@ -146,6 +146,9 @@ let mem_var x denv = Mstr.mem x denv.dvars
let find_var x denv = Mstr.find x denv.dvars let find_var x denv = Mstr.find x denv.dvars
let add_var x ty denv = { denv with dvars = Mstr.add x ty denv.dvars } let add_var x ty denv = { denv with dvars = Mstr.add x ty denv.dvars }
let print_denv fmt denv =
Mstr.iter (fun x ty -> fprintf fmt "%s:%a,@ " x print_dty ty) denv.dvars
(* parsed types -> intermediate types *) (* parsed types -> intermediate types *)
let rec qloc = function let rec qloc = function
......
...@@ -71,6 +71,10 @@ val dfmla : ?localize:bool -> denv -> Ptree.lexpr -> Denv.dfmla ...@@ -71,6 +71,10 @@ val dfmla : ?localize:bool -> denv -> Ptree.lexpr -> Denv.dfmla
val dpat : denv -> Ptree.pattern -> denv * Denv.dpattern val dpat : denv -> Ptree.pattern -> denv * Denv.dpattern
val dpat_list : denv -> Denv.dty -> Ptree.pattern -> denv * Denv.dpattern val dpat_list : denv -> Denv.dty -> Ptree.pattern -> denv * Denv.dpattern
val print_denv : Format.formatter -> denv -> unit
val split_qualid : Ptree.qualid -> string list * string
val string_list_of_qualid : string list -> Ptree.qualid -> string list
val qloc : Ptree.qualid -> Loc.position val qloc : Ptree.qualid -> Loc.position
val ts_tuple : int -> Ty.tysymbol val ts_tuple : int -> Ty.tysymbol
......
o refs -> mutable types
o loadpath: how to retrieve program files? (cannot use "env")
o what about pervasives old, at, label, exn, unit = (), lt_nat
This diff is collapsed.
...@@ -18,104 +18,18 @@ ...@@ -18,104 +18,18 @@
(**************************************************************************) (**************************************************************************)
open Why open Why
open Util open Pgm_module
open Ident
open Ty
open Theory
open Term
open Decl
(* types *) type t
type effect = Pgm_effect.t val get_env : t -> Env.env
type reference = Pgm_effect.reference
type pre = Term.fmla type retrieve_module = t -> string -> in_channel -> Pgm_module.t Mnm.t
type post_fmla = Term.vsymbol (* result *) * Term.fmla val create : Env.env -> retrieve_module -> t
type exn_post_fmla = Term.vsymbol (* result *) option * Term.fmla
type post = post_fmla * (Term.lsymbol * exn_post_fmla) list exception ModuleNotFound of string list * string
type type_v = private val find_module : t -> string list -> string -> Pgm_module.t
| Tpure of Ty.ty (** [find_module e p n] finds the module named [p.n] in environment [e]
| Tarrow of binder list * type_c @raise ModuleNotFound if module not present in env [e] *)
and type_c =
{ c_result_type : type_v;
c_effect : effect;
c_pre : pre;
c_post : post; }
and binder = Term.vsymbol * type_v
val tpure : Ty.ty -> type_v
val tarrow : binder list -> type_c -> type_v
(* environments *)
type env = private {
uc : theory_uc;
globals : (lsymbol * type_v) Mstr.t;
exceptions : lsymbol Mstr.t;
(* predefined symbols *)
ts_arrow: tysymbol;
ts_bool : tysymbol;
ts_label: tysymbol;
ts_ref : tysymbol;
ts_exn : tysymbol;
ts_unit : tysymbol;
ls_at : lsymbol;
ls_bang : lsymbol;
ls_old : lsymbol;
ls_True : lsymbol;
ls_False: lsymbol;
ls_andb : lsymbol;
ls_orb : lsymbol;
ls_notb : lsymbol;
ls_unit : lsymbol;
ls_lt : lsymbol;
ls_gt : lsymbol;
ls_le : lsymbol;
ls_ge : lsymbol;
ls_add : lsymbol;
}
val empty_env : theory_uc -> env
val add_global : preid -> type_v -> env -> lsymbol * env
val add_decl : decl -> env -> env
val logic_lexpr : Loc.position * string -> Ptree.lexpr
val logic_decls : Loc.position * string -> Env.env -> env -> env
val add_exception : preid -> ty option -> env -> lsymbol * env
val t_True : env -> term
val type_v_unit : env -> type_v
val purify : env -> type_v -> ty
val apply_type_v : env -> type_v -> vsymbol -> type_c
val apply_type_v_ref : env -> type_v -> reference -> type_c
val occur_type_v : reference -> type_v -> bool
val v_result : ty -> vsymbol
val exn_v_result : Why.Term.lsymbol -> Why.Term.vsymbol option
val post_map : (fmla -> fmla) -> post -> post
val subst1 : vsymbol -> term -> term Mvs.t
val eq_type_v : type_v -> type_v -> bool
(* pretty-printers *)
val print_type_v : Format.formatter -> type_v -> unit
val print_type_c : Format.formatter -> type_c -> unit
val print_post : Format.formatter -> post -> unit
...@@ -29,7 +29,7 @@ open Theory ...@@ -29,7 +29,7 @@ open Theory
open Pgm_ttree open Pgm_ttree
open Pgm_typing open Pgm_typing
module E = Pgm_effect module E = Pgm_types.E
module State : sig module State : sig
type t type t
......
...@@ -50,17 +50,23 @@ ...@@ -50,17 +50,23 @@
"done", DONE; "done", DONE;
"downto", DOWNTO; "downto", DOWNTO;
"else", ELSE; "else", ELSE;
"export", EXPORT;
"end", END; "end", END;
"exception", EXCEPTION; "exception", EXCEPTION;
"for", FOR; "for", FOR;
"fun", FUN; "fun", FUN;
"ghost", GHOST; "ghost", GHOST;
"if", IF; "if", IF;
"import", IMPORT;
"in", IN; "in", IN;
"invariant", INVARIANT; "invariant", INVARIANT;
"label", LABEL; "label", LABEL;
"let", LET; "let", LET;
"match", MATCH; "match", MATCH;
"model", MODEL;
"module", MODULE;
"mutable", MUTABLE;
"namespace", NAMESPACE;
"not", NOT; "not", NOT;
"of", OF; "of", OF;
"parameter", PARAMETER; "parameter", PARAMETER;
...@@ -72,6 +78,7 @@ ...@@ -72,6 +78,7 @@
"to", TO; "to", TO;
"try", TRY; "try", TRY;
"type", TYPE; "type", TYPE;
"use", USE;
"variant", VARIANT; "variant", VARIANT;
"while", WHILE; "while", WHILE;
"with", WITH; "with", WITH;
......
...@@ -21,36 +21,47 @@ ...@@ -21,36 +21,47 @@
open Format open Format
open Why open Why
open Pgm_env open Util
open Ident
open Ptree
open Pgm_ptree
open Pgm_module
let type_and_wp ?(type_only=false) env gl dl = let add_module ?(type_only=false) env penv lmod m =
let decl gl d = if type_only then gl else Pgm_wp.decl gl d in let wp = not type_only in
let add gl d = let id = m.mod_name in
let gl, dl = Pgm_typing.decl env gl d in let uc = create_module (Ident.id_user id.id id.id_loc) in
List.fold_left decl gl dl let uc = List.fold_left (Pgm_typing.decl ~wp env penv lmod) uc m.mod_decl in
in let m = close_module uc in
List.fold_left add gl dl Mnm.add id.id m lmod
let read_channel env file c = let retrieve penv file c =
let lb = Lexing.from_channel c in let lb = Lexing.from_channel c in
Loc.set_file file lb; Loc.set_file file lb;
let dl = Pgm_lexer.parse_file lb in let ml = Pgm_lexer.parse_file lb in
if Debug.test_flag Typing.debug_parse_only then if Debug.test_flag Typing.debug_parse_only then
Theory.Mnm.empty Mnm.empty
else begin else
let type_only = Debug.test_flag Typing.debug_type_only in let type_only = Debug.test_flag Typing.debug_type_only in
let uc = Theory.create_theory (Ident.id_fresh "Pgm") in let env = Pgm_env.get_env penv in
let th = Env.find_theory env ["programs"] "Prelude" in List.fold_left (add_module ~type_only env penv) Mnm.empty ml
let uc = Theory.use_export uc th in
let gl = empty_env uc in let pgm_env_of_env =
let gl = type_and_wp ~type_only env gl dl in let h = Env.Wenv.create 17 in
if type_only then fun env ->
Theory.Mnm.empty try
else begin Env.Wenv.find h env
let th = Theory.close_theory gl.uc in with Not_found ->
Theory.Mnm.add "Pgm" th Theory.Mnm.empty let penv = Pgm_env.create env retrieve in
end Env.Wenv.set h env penv;
end penv
let read_channel env file c =
let penv = pgm_env_of_env env in