heptagon/compiler/main/hept2mls.ml
Gwenal Delaval 2956002f85 Correction and simplification of the sigali pass
Added a "Contracts" pass, after inlining, taking care of the
contracts of the nodes called in the body of a node. This pass
"inlines" the code and assume/guarantee parts of these subcontracts.

The "Sigali" pass both generates the sigali ("z3z") code and add the call to
the controller (which is a node generated further by the sigali tool).
Therefore this pass has been included into the mls compiler, and removed
from the targets (a "z3z" dummy target has been kept for backward compatibility
reasons).
2012-06-06 15:59:08 +02:00

259 lines
9.6 KiB
OCaml

(**************************************************************************)
(* *)
(* Heptagon *)
(* *)
(* Author : Marc Pouzet *)
(* Organization : Demons, LRI, University of Paris-Sud, Orsay *)
(* *)
(**************************************************************************)
(* removing switch statements and translation into Minils *)
open Location
open Misc
open Names
open Idents
open Static
open Types
open Clocks
open Format
open Minils
open Mls_utils
open Signature
module Error =
struct
type error =
| Ereset_not_var
| Eunsupported_language_construct
| Enormalization
let message loc kind =
begin match kind with
| Ereset_not_var ->
eprintf "%aOnly variables can be used for resets.@."
print_location loc
| Eunsupported_language_construct ->
eprintf "%aThis construct is not supported by MiniLS.@."
print_location loc
| Enormalization ->
eprintf "%aThis construct should have been normalized.@."
print_location loc
end;
raise Errors.Error
end
let fresh = Idents.gen_fresh "hept2mls"
(function Heptagon.Enode f -> (shortname f)
| _ -> "n")
let translate_var { Heptagon.v_ident = n; Heptagon.v_type = ty; Heptagon.v_linearity = linearity;
Heptagon.v_loc = loc; Heptagon.v_clock = ck } =
mk_var_dec ~loc:loc n ty linearity ck
let translate_reset = function
| Some { Heptagon.e_desc = Heptagon.Evar n } -> Some n
| Some re -> Error.message re.Heptagon.e_loc Error.Ereset_not_var
| None -> None
let translate_iterator_type = function
| Heptagon.Imap -> Imap
| Heptagon.Imapi -> Imapi
| Heptagon.Ifold -> Ifold
| Heptagon.Ifoldi -> Ifoldi
| Heptagon.Imapfold -> Imapfold
let rec translate_op = function
| Heptagon.Eifthenelse -> Eifthenelse
| Heptagon.Efun f -> Efun f
| Heptagon.Enode f -> Enode f
| Heptagon.Efield -> assert false
| Heptagon.Efield_update -> Efield_update
| Heptagon.Earray_fill -> Earray_fill
| Heptagon.Eselect -> Eselect
| Heptagon.Eselect_dyn -> Eselect_dyn
| Heptagon.Eupdate -> Eupdate
| Heptagon.Eselect_slice -> Eselect_slice
| Heptagon.Eselect_trunc -> Eselect_trunc
| Heptagon.Econcat -> Econcat
| Heptagon.Earray -> Earray
| Heptagon.Etuple -> Misc.internal_error "hept2mls Etuple"
| Heptagon.Earrow -> assert false
| Heptagon.Ereinit -> assert false
let translate_app app =
mk_app ~params:app.Heptagon.a_params
~unsafe:app.Heptagon.a_unsafe
~id:(Some (fresh app.Heptagon.a_op))
(translate_op app.Heptagon.a_op)
let mk_extvalue e w =
let clock = match e.Heptagon.e_ct_annot with
| None -> fresh_clock ()
| Some ct -> assert_1 (unprod ct)
in
mk_extvalue ~loc:e.Heptagon.e_loc ~linearity:e.Heptagon.e_linearity
~ty:e.Heptagon.e_ty ~clock:clock w
let rec translate_extvalue e =
match e.Heptagon.e_desc with
| Heptagon.Econst c -> mk_extvalue e (Wconst c)
| Heptagon.Evar x -> mk_extvalue e (Wvar x)
| Heptagon.Ewhen (e', c, x) ->
mk_extvalue e (Wwhen (translate_extvalue e', c, x))
| Heptagon.Eapp({ Heptagon.a_op = Heptagon.Efield;
Heptagon.a_params = params }, e_list, _) ->
let e = assert_1 e_list in
let f = assert_1 params in
let fn = match f.se_desc with Sfield fn -> fn | _ -> assert false in
mk_extvalue e (Wfield (translate_extvalue e, fn))
| Heptagon.Eapp({ Heptagon.a_op = Heptagon.Ereinit }, e_list, _) ->
let e1, e2 = assert_2 e_list in
mk_extvalue e (Wreinit (translate_extvalue e1, translate_extvalue e2))
| _ -> Error.message e.Heptagon.e_loc Error.Enormalization
let rec translate ({ Heptagon.e_desc = desc; Heptagon.e_ty = ty;
Heptagon.e_level_ck = b_ck; Heptagon.e_linearity = linearity;
Heptagon.e_ct_annot = a_ct; Heptagon.e_loc = loc; } as e) =
let desc = match desc with
| Heptagon.Econst _
| Heptagon.Evar _
| Heptagon.Eapp({ Heptagon.a_op = Heptagon.Efield | Heptagon.Ereinit }, _, _) ->
let w = translate_extvalue e in
Eextvalue w
| Heptagon.Ewhen (e,c,x) -> Ewhen (translate e, c, x)
| Heptagon.Epre(None, e) ->
Efby(None, translate_extvalue e)
| Heptagon.Epre(Some c, e) ->
Efby(Some c, translate_extvalue e)
| Heptagon.Efby ({ Heptagon.e_desc = Heptagon.Econst c }, e) ->
Efby(Some c, translate_extvalue e)
| Heptagon.Estruct f_e_list ->
let f_e_list = List.map
(fun (f, e) -> (f, translate_extvalue e)) f_e_list in
Estruct f_e_list
| Heptagon.Eapp({ Heptagon.a_op = Heptagon.Earrow }, _, _) ->
Error.message loc Error.Eunsupported_language_construct
| Heptagon.Eapp(app, e_list, reset) ->
Eapp (translate_app app, List.map translate_extvalue e_list, translate_reset reset)
| Heptagon.Eiterator(it, app, n, pe_list, e_list, reset) ->
Eiterator (translate_iterator_type it,
translate_app app, n,
List.map translate_extvalue pe_list,
List.map translate_extvalue e_list,
translate_reset reset)
| Heptagon.Efby _ | Heptagon.Esplit _
| Heptagon.Elast _ ->
Error.message loc Error.Eunsupported_language_construct
| Heptagon.Emerge (x, c_e_list) ->
Emerge (x, List.map (fun (c,e)-> c, translate_extvalue e) c_e_list)
in
match a_ct with
| None -> mk_exp b_ck ty ~loc:loc ~linearity:linearity desc
| Some ct -> mk_exp b_ck ty ~ct:ct ~loc:loc ~linearity:linearity desc
let rec translate_pat = function
| Heptagon.Evarpat(n) -> Evarpat n
| Heptagon.Etuplepat(l) -> Etuplepat (List.map translate_pat l)
let rec translate_eq { Heptagon.eq_desc = desc; Heptagon.eq_loc = loc } =
match desc with
| Heptagon.Eeq(p, e) ->
begin match e.Heptagon.e_desc with
| Heptagon.Eapp({ Heptagon.a_unsafe = unsafe },_,_)
| Heptagon.Eiterator(_,{ Heptagon.a_unsafe = unsafe},_,_,_,_) ->
mk_equation ~loc:loc unsafe (translate_pat p) (translate e)
| _ -> mk_equation ~loc:loc false (translate_pat p) (translate e)
end
| Heptagon.Eblock _ | Heptagon.Eswitch _
| Heptagon.Epresent _ | Heptagon.Eautomaton _ | Heptagon.Ereset _ ->
Error.message loc Error.Eunsupported_language_construct
let translate_contract contract =
match contract with
| None -> None
| Some { Heptagon.c_block = { Heptagon.b_local = v;
Heptagon.b_equs = eq_list };
Heptagon.c_assume = e_a;
Heptagon.c_enforce = e_g;
Heptagon.c_assume_loc = e_a_loc;
Heptagon.c_enforce_loc = e_g_loc;
Heptagon.c_controllables = l_c } ->
Some { c_local = List.map translate_var v;
c_eq = List.map translate_eq eq_list;
c_assume = translate_extvalue e_a;
c_enforce = translate_extvalue e_g;
c_assume_loc = translate_extvalue e_a_loc;
c_enforce_loc = translate_extvalue e_g_loc;
c_controllables = List.map translate_var l_c }
let node n =
enter_node n.Heptagon.n_name;
{ n_name = n.Heptagon.n_name;
n_stateful = n.Heptagon.n_stateful;
n_unsafe = n.Heptagon.n_unsafe;
n_input = List.map translate_var n.Heptagon.n_input;
n_output = List.map translate_var n.Heptagon.n_output;
n_contract = translate_contract n.Heptagon.n_contract;
n_controller_call = ([],[]);
n_local = List.map translate_var n.Heptagon.n_block.Heptagon.b_local;
n_equs = List.map translate_eq n.Heptagon.n_block.Heptagon.b_equs;
n_loc = n.Heptagon.n_loc ;
n_params = n.Heptagon.n_params;
n_param_constraints = n.Heptagon.n_param_constraints;
n_mem_alloc = [] }
let typedec
{Heptagon.t_name = n; Heptagon.t_desc = tdesc; Heptagon.t_loc = loc} =
let onetype = function
| Heptagon.Type_abs -> Type_abs
| Heptagon.Type_alias ln -> Type_alias ln
| Heptagon.Type_enum tag_list -> Type_enum tag_list
| Heptagon.Type_struct field_ty_list -> Type_struct field_ty_list
in
{ t_name = n; t_desc = onetype tdesc; t_loc = loc }
let const_dec cd =
{ Minils.c_name = cd.Heptagon.c_name;
Minils.c_value = cd.Heptagon.c_value;
Minils.c_type = cd.Heptagon.c_type;
Minils.c_loc = cd.Heptagon.c_loc; }
let program_desc pd = match pd with
| Heptagon.Ptype td -> Ptype (typedec td)
| Heptagon.Pnode nd -> Pnode (node nd)
| Heptagon.Pconst cd -> Pconst (const_dec cd)
let program
{ Heptagon.p_modname = modname;
Heptagon.p_opened = modules;
Heptagon.p_desc = desc_list } =
{ p_modname = modname;
p_format_version = minils_format_version;
p_opened = modules;
p_desc = List.map program_desc desc_list }
let signature s =
{ sig_name = s.Heptagon.sig_name;
sig_inputs = s.Heptagon.sig_inputs;
sig_stateful = s.Heptagon.sig_stateful;
sig_outputs = s.Heptagon.sig_outputs;
sig_params = s.Heptagon.sig_params;
sig_param_constraints = s.Heptagon.sig_param_constraints;
sig_external = s.Heptagon.sig_external;
sig_loc = s.Heptagon.sig_loc }
let interface i =
let interface_decl id = match id with
| Heptagon.Itypedef td -> Itypedef (typedec td)
| Heptagon.Iconstdef cd -> Iconstdef (const_dec cd)
| Heptagon.Isignature s -> Isignature (signature s)
in
{ i_modname = i.Heptagon.i_modname;
i_opened = i.Heptagon.i_opened;
i_desc = List.map interface_decl i.Heptagon.i_desc }