Ported transformations
A BIG Refactoring is needed
This commit is contained in:
parent
ca38c3ba44
commit
a0cc9917ac
6 changed files with 176 additions and 189 deletions
|
@ -150,19 +150,38 @@ type interface =
|
|||
and interface_desc =
|
||||
| Iopen of name | Itypedef of type_dec | Isignature of signature
|
||||
|
||||
(* Helper functions to create AST. *) (*TODO refactor en mk_*)
|
||||
|
||||
(* Helper functions to create AST. *)
|
||||
let mk_exp desc ty =
|
||||
{ e_desc = desc; e_ty = ty; e_loc = no_location; }
|
||||
|
||||
let mk_op op = { a_op = op; }
|
||||
|
||||
|
||||
let mk_op_desc ln params kind =
|
||||
{ op_name = ln; op_params = params; op_kind = kind }
|
||||
|
||||
let mk_type_dec name desc =
|
||||
{ t_name = name; t_desc = desc; t_loc = no_location; }
|
||||
|
||||
let mk_equation desc =
|
||||
{ eq_desc = desc; eq_statefull = true; eq_loc = no_location; }
|
||||
|
||||
let mk_equation ?(statefull = true) desc =
|
||||
{ eq_desc = desc; eq_statefull = statefull; eq_loc = no_location; }
|
||||
|
||||
let mk_var_dec ?(last = Var) name ty =
|
||||
{ v_name = name; v_type = ty;
|
||||
v_last = last; v_loc = Location.get_current_location () }
|
||||
|
||||
let mk_block defnames eqs =
|
||||
{ b_local = []; b_equs = eqs; b_defnames = defnames;
|
||||
b_statefull = true; b_loc = no_location }
|
||||
|
||||
let dfalse = mk_exp (Econst (Cconstr Initial.pfalse)) (Tid Initial.pbool)
|
||||
let dtrue = mk_exp (Econst (Cconstr Initial.ptrue)) (Tid Initial.pbool)
|
||||
|
||||
let mk_ifthenelse e1 e2 e3 =
|
||||
{ e3 with e_desc = Eapp(mk_op Eifthenelse, [e1; e2; e3]) }
|
||||
|
||||
let mk_simple_equation pat e =
|
||||
mk_equation ~statefull:false (Eeq(pat, e))
|
||||
|
||||
(*
|
||||
let cfalse = Cconstr Initial.pfalse
|
||||
|
||||
|
|
|
@ -10,26 +10,30 @@
|
|||
|
||||
(* $Id$ *)
|
||||
|
||||
open Location
|
||||
open Misc
|
||||
open Names
|
||||
open Ident
|
||||
open Heptagon
|
||||
open Global
|
||||
open Initial
|
||||
open Interference_graph
|
||||
open Types
|
||||
|
||||
let rename_states env g =
|
||||
let rename_one n =
|
||||
try
|
||||
let olds = List.hd n.g_content in
|
||||
let s = NamesEnv.find olds env in
|
||||
Hashtbl.remove g.g_hash olds;
|
||||
Hashtbl.add g.g_hash s n;
|
||||
n.g_content <- [s]
|
||||
with Not_found -> ()
|
||||
in
|
||||
List.iter rename_one g.g_nodes
|
||||
let mk_var_exp n ty =
|
||||
mk_exp (Evar n) ty
|
||||
|
||||
let mk_pair e1 e2 =
|
||||
mk_exp (Etuple [e1;e2]) (Tprod [e1.e_ty; e2.e_ty])
|
||||
|
||||
let mk_reset_equation eq_list e =
|
||||
mk_equation (Ereset (eq_list, e))
|
||||
|
||||
let mk_switch_equation e l =
|
||||
mk_equation (Eswitch (e, l))
|
||||
|
||||
let mk_exp_fby_false e =
|
||||
mk_exp (Eapp(mk_op (Epre (Some (Cconstr Initial.pfalse))), [e]))
|
||||
(Tid Initial.pbool)
|
||||
|
||||
let mk_exp_fby_state initial e =
|
||||
{ e with e_desc = Eapp(mk_op (Epre (Some (Cconstr initial))), [e]) }
|
||||
|
||||
(* the list of enumerated types introduced to represent states *)
|
||||
let state_type_dec_list = ref []
|
||||
|
@ -39,8 +43,8 @@ let intro_type states =
|
|||
let n = gen_symbol () in
|
||||
let state_type = "st" ^ n in
|
||||
state_type_dec_list :=
|
||||
(tmake state_type (Type_enum(list states))) :: !state_type_dec_list;
|
||||
Name(state_type)
|
||||
(mk_type_dec state_type (Type_enum (list states))) :: !state_type_dec_list;
|
||||
Name(state_type)
|
||||
|
||||
(* an automaton may be a Moore automaton, i.e., with only weak transitions; *)
|
||||
(* a Mealy one, i.e., with only strong transition or mixed *)
|
||||
|
@ -49,41 +53,41 @@ let moore_mealy state_handlers =
|
|||
(moore or (l1 <> []), mealy or (l2 <> [])) in
|
||||
List.fold_left handler (false, false) state_handlers
|
||||
|
||||
let rec translate_eq g (v, eq_list) eq =
|
||||
let rec translate_eq (v, eq_list) eq =
|
||||
match eq.eq_desc with
|
||||
Eautomaton(state_handlers) ->
|
||||
translate_automaton g v eq_list state_handlers
|
||||
translate_automaton v eq_list state_handlers
|
||||
| Eswitch(e, switch_handlers) ->
|
||||
v,
|
||||
{ eq with eq_desc =
|
||||
Eswitch(e, translate_switch_handlers g switch_handlers) }
|
||||
Eswitch(e, translate_switch_handlers switch_handlers) }
|
||||
:: eq_list
|
||||
| Epresent(present_handlers, block) ->
|
||||
v, { eq with eq_desc =
|
||||
Epresent(translate_present_handlers g present_handlers,
|
||||
translate_block g block) } :: eq_list
|
||||
Epresent(translate_present_handlers present_handlers,
|
||||
translate_block block) } :: eq_list
|
||||
| Ereset(r_eq_list, e) ->
|
||||
let v, r_eq_list = translate_eqs g v r_eq_list in
|
||||
let v, r_eq_list = translate_eqs v r_eq_list in
|
||||
v, { eq with eq_desc = Ereset(r_eq_list, e) } :: eq_list
|
||||
| Eeq _ -> v, eq :: eq_list
|
||||
|
||||
and translate_eqs g v eq_list = List.fold_left (translate_eq g) (v, []) eq_list
|
||||
and translate_eqs v eq_list = List.fold_left translate_eq (v, []) eq_list
|
||||
|
||||
and translate_block g ({ b_local = v; b_equs = eq_list } as b) =
|
||||
let v, eq_list = translate_eqs g v eq_list in
|
||||
and translate_block ({ b_local = v; b_equs = eq_list } as b) =
|
||||
let v, eq_list = translate_eqs v eq_list in
|
||||
{ b with b_local = v; b_equs = eq_list }
|
||||
|
||||
and translate_switch_handlers g handlers =
|
||||
and translate_switch_handlers handlers =
|
||||
let translate_switch_handler { w_name = n; w_block = b } =
|
||||
{ w_name = n; w_block = translate_block g b } in
|
||||
{ w_name = n; w_block = translate_block b } in
|
||||
List.map translate_switch_handler handlers
|
||||
|
||||
and translate_present_handlers g handlers =
|
||||
and translate_present_handlers handlers =
|
||||
let translate_present_handler { p_cond = e; p_block = b } =
|
||||
{ p_cond = e; p_block = translate_block g b } in
|
||||
{ p_cond = e; p_block = translate_block b } in
|
||||
List.map translate_present_handler handlers
|
||||
|
||||
and translate_automaton g v eq_list handlers =
|
||||
and translate_automaton v eq_list handlers =
|
||||
let has_until, has_unless = moore_mealy handlers in
|
||||
let states =
|
||||
let suffix = gen_symbol () in
|
||||
|
@ -92,7 +96,7 @@ and translate_automaton g v eq_list handlers =
|
|||
NamesEnv.empty handlers in
|
||||
|
||||
let statetype = intro_type states in
|
||||
let tstatetype = Tbase(Tid(statetype)) in
|
||||
let tstatetype = Tid statetype in
|
||||
let initial = Name(NamesEnv.find (List.hd handlers).s_state states) in
|
||||
|
||||
let statename = Ident.fresh "s" in
|
||||
|
@ -101,84 +105,80 @@ and translate_automaton g v eq_list handlers =
|
|||
let next_resetname = Ident.fresh "nr" in
|
||||
let pre_next_resetname = Ident.fresh "pnr" in
|
||||
|
||||
(* update the states graph with the suffixed names *)
|
||||
rename_states states g;
|
||||
|
||||
let name n = Name(NamesEnv.find n states) in
|
||||
let state n =
|
||||
emake (Econst(Cconstr(name n))) tstatetype in
|
||||
let statevar n = var n tstatetype in
|
||||
let boolvar n = var n tybool in
|
||||
let state n = mk_exp (Econst (Cconstr (name n))) tstatetype in
|
||||
let statevar n = mk_var_exp n tstatetype in
|
||||
let boolvar n = mk_var_exp n (Tid Initial.pbool) in
|
||||
|
||||
let escapes n s rcont =
|
||||
let escape { e_cond = e; e_reset = r; e_next_state = n } cont =
|
||||
ifthenelse e (pair (state n) (if r then dtrue else dfalse)) cont in
|
||||
List.fold_right escape s (pair (state n) rcont) in
|
||||
mk_ifthenelse e (mk_pair (state n) (if r then dtrue else dfalse)) cont in
|
||||
List.fold_right escape s (mk_pair (state n) rcont) in
|
||||
let strong { s_state = n; s_unless = su } =
|
||||
block
|
||||
mk_block
|
||||
(Env.add statename tstatetype
|
||||
(Env.add resetname tybool Env.empty))
|
||||
([reset(
|
||||
[eq (Etuplepat[Evarpat(statename);Evarpat(resetname)])
|
||||
(Env.add resetname (Tid Initial.pbool) Env.empty))
|
||||
([mk_reset_equation (
|
||||
[mk_simple_equation (Etuplepat[Evarpat(statename);Evarpat(resetname)])
|
||||
(escapes n su (boolvar pre_next_resetname))])
|
||||
(boolvar pre_next_resetname)]) in
|
||||
|
||||
let weak { s_state = n; s_block = b; s_until = su } =
|
||||
let b = translate_block g b in
|
||||
let b = translate_block b in
|
||||
{ b with b_equs =
|
||||
[reset ((eq (Etuplepat[Evarpat(next_statename);
|
||||
[mk_reset_equation ((mk_simple_equation (Etuplepat[Evarpat(next_statename);
|
||||
Evarpat(next_resetname)])
|
||||
(escapes n su dfalse)) :: b.b_equs)
|
||||
(boolvar resetname)];
|
||||
(* (or_op (boolvar pre_next_resetname) (boolvar resetname))]; *)
|
||||
b_defnames =
|
||||
Env.add next_statename tstatetype
|
||||
(Env.add next_resetname tybool
|
||||
(Env.add next_resetname (Tid Initial.pbool)
|
||||
b.b_defnames)
|
||||
} in
|
||||
let v =
|
||||
(param next_statename (Tid(statetype))) ::
|
||||
(param resetname tbool) ::
|
||||
(param next_resetname tbool) ::
|
||||
(param pre_next_resetname tbool) :: v in
|
||||
(mk_var_dec next_statename (Tid(statetype))) ::
|
||||
(mk_var_dec resetname (Tid Initial.pbool)) ::
|
||||
(mk_var_dec next_resetname (Tid Initial.pbool)) ::
|
||||
(mk_var_dec pre_next_resetname (Tid Initial.pbool)) :: v in
|
||||
(* we optimise the case of an only strong automaton *)
|
||||
(* or only weak automaton *)
|
||||
match has_until, has_unless with
|
||||
| true, false ->
|
||||
(* a Moore automaton with only weak transitions *)
|
||||
v, (switch (fby_state initial (statevar next_statename))
|
||||
v, (mk_switch_equation (mk_exp_fby_state initial (statevar next_statename))
|
||||
(List.map
|
||||
(fun ({ s_state = n } as case) ->
|
||||
{ w_name = name n; w_block = weak case })
|
||||
handlers)) ::
|
||||
(eq (Evarpat pre_next_resetname)
|
||||
(fby_false (boolvar (next_resetname)))) ::
|
||||
(eq (Evarpat resetname) (boolvar pre_next_resetname)) :: eq_list
|
||||
(mk_simple_equation (Evarpat pre_next_resetname)
|
||||
(mk_exp_fby_false (boolvar (next_resetname)))) ::
|
||||
(mk_simple_equation (Evarpat resetname) (boolvar pre_next_resetname)) :: eq_list
|
||||
| _ ->
|
||||
(* the general case; two switch to generate,
|
||||
statename variable used and defined *)
|
||||
(param statename (Tid(statetype))) :: v,
|
||||
(switch (fby_state initial (statevar next_statename))
|
||||
(mk_var_dec statename (Tid statetype)) :: v,
|
||||
(mk_switch_equation (mk_exp_fby_state initial (statevar next_statename))
|
||||
(List.map
|
||||
(fun ({ s_state = n } as case) ->
|
||||
{ w_name = name n; w_block = strong case })
|
||||
handlers)) ::
|
||||
(switch (statevar statename)
|
||||
(mk_switch_equation (statevar statename)
|
||||
(List.map
|
||||
(fun ({ s_state = n } as case) ->
|
||||
{ w_name = name n; w_block = weak case })
|
||||
handlers)) ::
|
||||
(eq (Evarpat pre_next_resetname)
|
||||
(fby_false (boolvar (next_resetname)))) ::
|
||||
(mk_simple_equation (Evarpat pre_next_resetname)
|
||||
(mk_exp_fby_false (boolvar (next_resetname)))) ::
|
||||
eq_list
|
||||
|
||||
let translate_contract g ({ c_local = v; c_eq = eq_list} as c) =
|
||||
let v, eq_list = translate_eqs g v eq_list in
|
||||
let translate_contract ({ c_local = v; c_eq = eq_list} as c) =
|
||||
let v, eq_list = translate_eqs v eq_list in
|
||||
{ c with c_local = v; c_eq = eq_list }
|
||||
|
||||
let node ({ n_local = v; n_equs = eq_list; n_contract = contract; n_states_graph = g } as n) =
|
||||
let v, eq_list = translate_eqs g v eq_list in
|
||||
let contract = optional (translate_contract g) contract in
|
||||
let node ({ n_local = v; n_equs = eq_list; n_contract = contract } as n) =
|
||||
let v, eq_list = translate_eqs v eq_list in
|
||||
let contract = optional translate_contract contract in
|
||||
{ n with n_local = v; n_equs = eq_list; n_contract = contract }
|
||||
|
||||
let program ({ p_types = pt_list; p_nodes = n_list } as p) =
|
||||
|
|
|
@ -8,25 +8,19 @@
|
|||
(**************************************************************************)
|
||||
(* complete partial definitions with [x = last(x)] *)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
open Location
|
||||
open Ident
|
||||
open Misc
|
||||
open Heptagon
|
||||
open Global
|
||||
open Ident
|
||||
|
||||
(* adds an equation [x = last(x)] for every partially defined variable *)
|
||||
(* in a control structure *)
|
||||
let complete_with_last defined_names local_defined_names eq_list =
|
||||
let last n ty =
|
||||
{ e_desc = Elast(n); e_ty = ty; e_linearity = Linearity.NotLinear;
|
||||
e_loc = no_location } in
|
||||
let last n ty = mk_exp (Elast n) ty in
|
||||
let equation n ty eq_list =
|
||||
{ eq_desc = Eeq(Evarpat(n), last n ty); eq_statefull = false;
|
||||
eq_loc = no_location } :: eq_list in
|
||||
(mk_equation (Eeq(Evarpat n, last n ty)))::eq_list
|
||||
in
|
||||
let d = Env.diff defined_names local_defined_names in
|
||||
Env.fold equation d eq_list
|
||||
Env.fold equation d eq_list
|
||||
|
||||
let rec translate_eq eq =
|
||||
match eq.eq_desc with
|
||||
|
|
|
@ -15,42 +15,11 @@
|
|||
x = (f every r) e'
|
||||
*)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
open Location
|
||||
open Misc
|
||||
open Ident
|
||||
open Heptagon
|
||||
open Global
|
||||
open Initial
|
||||
open Reset
|
||||
|
||||
let eq pat e =
|
||||
{ eq_desc = Eeq(pat, e); eq_statefull = false; eq_loc = no_location }
|
||||
let statefulleq = Heptagon.eq
|
||||
|
||||
(* add an equation *)
|
||||
let equation v acc_eq_list e =
|
||||
let n = Ident.fresh "r" in
|
||||
n,
|
||||
(bool_param n) :: v,
|
||||
{ eq_desc = Eeq(Evarpat(n), e); eq_statefull = true; eq_loc = e.e_loc } ::
|
||||
acc_eq_list
|
||||
|
||||
let orthen v acc_eq_list res e =
|
||||
match e.e_desc with
|
||||
Evar(n) -> v, acc_eq_list, Rorthen(res, n)
|
||||
| _ ->
|
||||
let n, v, acc_eq_list = equation v acc_eq_list e in
|
||||
v, acc_eq_list, Rorthen(res, n)
|
||||
|
||||
let add_locals m n locals =
|
||||
let rec loop locals i n =
|
||||
if i < n then
|
||||
loop ((bool_param m.(i)) :: locals) (i+1) n
|
||||
else locals in
|
||||
loop locals 0 n
|
||||
|
||||
(*
|
||||
let defnames m n d =
|
||||
let rec loop acc k = if k < n then loop (S.add m.(k) acc) (k+1) else acc in
|
||||
|
@ -60,7 +29,7 @@ let defnames m n d =
|
|||
let statefull eq_list = List.exists (fun eq -> eq.eq_statefull) eq_list
|
||||
|
||||
let is_var = function
|
||||
| { e_desc = Evar(_) } -> true
|
||||
| { e_desc = Evar _ } -> true
|
||||
| _ -> false
|
||||
|
||||
let rec translate_eq v acc_eq_list eq =
|
||||
|
@ -102,25 +71,27 @@ and translate v acc_eq_list e =
|
|||
| Etuple(e_list) ->
|
||||
let v, acc_eq_list,e_list = translate_list v acc_eq_list e_list in
|
||||
v,acc_eq_list,
|
||||
{ e with e_desc = Etuple(e_list) }
|
||||
| Eapp({ a_op = Eevery(f,params) } as op, re :: e_list)
|
||||
{ e with e_desc = Etuple e_list }
|
||||
| Eapp ({ a_op = Ecall(op_desc, Some re) } as op, e_list)
|
||||
when not (is_var re) ->
|
||||
let v, acc_eq_list,re = translate v acc_eq_list re in
|
||||
let n, v, acc_eq_list = equation v acc_eq_list re in
|
||||
let v, acc_eq_list, e_list = translate_list v acc_eq_list e_list in
|
||||
v,acc_eq_list,
|
||||
v,acc_eq_list,
|
||||
{ e with e_desc =
|
||||
Eapp({ op with a_op = Eevery(f,params) },
|
||||
{ re with e_desc = Evar(n) } :: e_list) }
|
||||
| Eapp({ a_op = Eiterator(it, f, params, Some re) } as op, e_list)
|
||||
when not (is_var re) ->
|
||||
Eapp({ op with a_op = Ecall(op_desc,
|
||||
Some { re with e_desc = Evar(n) }) },
|
||||
e_list) }
|
||||
| Eapp ({ a_op = Earray_op(Eiterator(it, op_desc, Some re)) } as op, e_list)
|
||||
when not (is_var re) ->
|
||||
let v, acc_eq_list,re = translate v acc_eq_list re in
|
||||
let n, v, acc_eq_list = equation v acc_eq_list re in
|
||||
let v, acc_eq_list, e_list = translate_list v acc_eq_list e_list in
|
||||
let re = { re with e_desc = Evar n } in
|
||||
v,acc_eq_list,
|
||||
let re = { re with e_desc = Evar n } in
|
||||
v,acc_eq_list,
|
||||
{ e with e_desc =
|
||||
Eapp({ op with a_op = Eiterator(it, f, params, Some re) },e_list) }
|
||||
Eapp({ op with a_op = Earray_op(Eiterator(it, op_desc, Some re)) },
|
||||
e_list) }
|
||||
| Eapp(f, e_list) ->
|
||||
let v, acc_eq_list, e_list = translate_list v acc_eq_list e_list in
|
||||
v, acc_eq_list,
|
||||
|
@ -142,7 +113,6 @@ and translate v acc_eq_list e =
|
|||
let v, acc_eq_list,e_list = translate_list v acc_eq_list e_list in
|
||||
v,acc_eq_list,
|
||||
{ e with e_desc = Earray(e_list) }
|
||||
| Ereset_mem _ -> v,acc_eq_list,e
|
||||
|
||||
and translate_list v acc_eq_list e_list =
|
||||
let v,acc_eq_list,acc_e =
|
||||
|
|
|
@ -8,13 +8,9 @@
|
|||
(**************************************************************************)
|
||||
(* removing accessed to shared variables (last x) *)
|
||||
|
||||
(* $Id$ *)
|
||||
|
||||
open Location
|
||||
open Misc
|
||||
open Ident
|
||||
open Heptagon
|
||||
open Global
|
||||
open Ident
|
||||
|
||||
(* introduce a fresh equation [last_x = pre(x)] for every *)
|
||||
(* variable declared with a last *)
|
||||
|
@ -23,15 +19,13 @@ let last (eq_list, env, v) { v_name = n; v_type = t; v_last = last } =
|
|||
| Var -> (eq_list, env, v)
|
||||
| Last(default) ->
|
||||
let lastn = Ident.fresh ("last" ^ (sourcename n)) in
|
||||
(eqmake (Eeq(Evarpat(lastn),
|
||||
emake
|
||||
(Eapp (eop (Epre(default)),
|
||||
[emake (Evar(n)) (Tbase(t))]))
|
||||
(Tbase(t)))))
|
||||
:: eq_list,
|
||||
let eq = mk_equation (Eeq (Evarpat lastn,
|
||||
mk_exp (Eapp (mk_op (Epre default),
|
||||
[mk_exp (Evar n) t])) t)) in
|
||||
eq:: eq_list,
|
||||
Env.add n lastn env,
|
||||
(param lastn t) :: v
|
||||
|
||||
(mk_var_dec lastn t) :: v
|
||||
|
||||
let extend_env env v = List.fold_left last ([], env, []) v
|
||||
|
||||
let rec translate_eq env eq =
|
||||
|
@ -71,7 +65,6 @@ and translate env e =
|
|||
Estruct(List.map (fun (f, e) -> (f, translate env e)) e_f_list) }
|
||||
| Earray(e_list) ->
|
||||
{ e with e_desc = Earray(List.map (translate env) e_list) }
|
||||
| Ereset_mem _ -> assert false
|
||||
|
||||
let translate_contract env contract =
|
||||
match contract with
|
||||
|
|
|
@ -10,12 +10,10 @@
|
|||
|
||||
(* $Id$ *)
|
||||
|
||||
open Location
|
||||
open Misc
|
||||
open Ident
|
||||
open Heptagon
|
||||
open Global
|
||||
open Initial
|
||||
open Types
|
||||
|
||||
(* We introduce an initialization variable for each block *)
|
||||
(* Using an asynchronous reset would allow to produce *)
|
||||
|
@ -43,14 +41,16 @@ open Initial
|
|||
e1 -> e2 is translated into if (true fby false) then e1 else e2
|
||||
*)
|
||||
|
||||
let mk_bool_var n =
|
||||
mk_exp (Evar n) (Tid Initial.pbool)
|
||||
let mk_bool_param n =
|
||||
mk_var_dec n (Tid Initial.pbool)
|
||||
|
||||
let or_op_call = mk_op ( Ecall(mk_op_desc Initial.por [] Eop, None) )
|
||||
|
||||
let pre_true e =
|
||||
{ e with e_desc = Eapp(eop (Epre(Some(Cconstr(ptrue)))), [e]) }
|
||||
{ e with e_desc = Eapp(mk_op (Epre (Some (Cconstr Initial.ptrue))), [e]) }
|
||||
let init e = pre_true { dfalse with e_loc = e.e_loc }
|
||||
let ifthenelse e1 e2 e3 =
|
||||
{ e3 with e_desc = Eapp(eop Eifthenelse, [e1; e2; e3]) }
|
||||
let eq pat e =
|
||||
{ eq_desc = Eeq(pat, e); eq_statefull = false; eq_loc = no_location }
|
||||
let statefulleq = Heptagon.eq
|
||||
|
||||
(* the boolean condition for a structural reset *)
|
||||
type reset =
|
||||
|
@ -68,31 +68,30 @@ let rec or_op res e =
|
|||
match res with
|
||||
| Rfalse -> e
|
||||
| Rorthen(res, n) ->
|
||||
or_op res { e with e_desc = Eapp(eop (Eop(por,[])), [bool_var n; e]) }
|
||||
or_op res { e with e_desc = Eapp(or_op_call, [mk_bool_var n; e]) }
|
||||
|
||||
let default e =
|
||||
match e.e_desc with
|
||||
| Econst c -> Some(c)
|
||||
| Econst c -> Some c
|
||||
| _ -> None
|
||||
|
||||
let exp_of_res res =
|
||||
match res with
|
||||
| Rfalse -> dfalse
|
||||
| Rorthen(res, n) -> or_op res (bool_var n)
|
||||
| Rorthen(res, n) -> or_op res (mk_bool_var n)
|
||||
|
||||
let ifres res e2 e3 =
|
||||
match res with
|
||||
| Rfalse -> ifthenelse (init e3) e2 e3
|
||||
| Rfalse -> mk_ifthenelse (init e3) e2 e3
|
||||
| _ -> (* a reset occurs *)
|
||||
ifthenelse (exp_of_res res) e2 e3
|
||||
mk_ifthenelse (exp_of_res res) e2 e3
|
||||
|
||||
(* add an equation *)
|
||||
let equation v acc_eq_list e =
|
||||
let n = Ident.fresh "r" in
|
||||
n,
|
||||
(bool_param n) :: v,
|
||||
{ eq_desc = Eeq(Evarpat(n), e); eq_statefull = true; eq_loc = e.e_loc } ::
|
||||
acc_eq_list
|
||||
(mk_bool_param n) :: v,
|
||||
(mk_equation (Eeq(Evarpat n, e))) ::acc_eq_list
|
||||
|
||||
let orthen v acc_eq_list res e =
|
||||
match e.e_desc with
|
||||
|
@ -104,7 +103,7 @@ let orthen v acc_eq_list res e =
|
|||
let add_locals m n locals =
|
||||
let rec loop locals i n =
|
||||
if i < n then
|
||||
loop ((bool_param m.(i)) :: locals) (i+1) n
|
||||
loop ((mk_bool_param m.(i)) :: locals) (i+1) n
|
||||
else locals in
|
||||
loop locals 0 n
|
||||
|
||||
|
@ -112,10 +111,10 @@ let add_local_equations i n m lm acc =
|
|||
(* [mi = false;...; m1 = l_m1;...; mn = l_mn] *)
|
||||
let rec loop acc k =
|
||||
if k < n then
|
||||
if k = i then loop ((eq (varpat(m.(k))) dfalse) :: acc) (k+1)
|
||||
if k = i then loop ((mk_simple_equation (Evarpat (m.(k))) dfalse) :: acc) (k+1)
|
||||
else
|
||||
loop
|
||||
((eq (varpat(m.(k))) (bool_var lm.(k))) :: acc) (k+1)
|
||||
((mk_simple_equation (Evarpat (m.(k))) (mk_bool_var lm.(k))) :: acc) (k+1)
|
||||
else acc
|
||||
in loop acc 0
|
||||
|
||||
|
@ -124,20 +123,20 @@ let add_global_equations n m lm res acc =
|
|||
l_mn = if res then true else true fby mn ] *)
|
||||
let rec loop acc k =
|
||||
if k < n then
|
||||
loop
|
||||
((statefulleq (varpat(lm.(k)))
|
||||
(match res with
|
||||
| Rfalse -> pre_true (bool_var m.(k))
|
||||
| _ -> ifres res dtrue (pre_true (bool_var m.(k)))
|
||||
)
|
||||
) :: acc) (k+1)
|
||||
let exp =
|
||||
(match res with
|
||||
| Rfalse -> pre_true (mk_bool_var m.(k))
|
||||
| _ -> ifres res dtrue (pre_true (mk_bool_var m.(k)))
|
||||
) in
|
||||
loop
|
||||
((mk_equation (Eeq (Evarpat (lm.(k)), exp))) :: acc) (k+1)
|
||||
else acc in
|
||||
loop acc 0
|
||||
|
||||
let defnames m n d =
|
||||
let rec loop acc k =
|
||||
if k < n
|
||||
then loop (Env.add m.(k) tybool acc) (k+1)
|
||||
then loop (Env.add m.(k) (Tid Initial.pbool) acc) (k+1)
|
||||
else acc in
|
||||
loop d 0
|
||||
|
||||
|
@ -207,37 +206,49 @@ and translate res e =
|
|||
match res, e1 with
|
||||
| Rfalse, { e_desc = Econst(c) } ->
|
||||
(* no reset *)
|
||||
{ e with e_desc =
|
||||
Eapp({ op with a_op = Epre(Some(c)) }, [e2]) }
|
||||
{ e with e_desc =
|
||||
Eapp({ op with a_op = Epre(Some c) }, [e2]) }
|
||||
| _ ->
|
||||
ifres res e1
|
||||
{ e with e_desc =
|
||||
Eapp({ op with a_op = Epre(default e1) }, [e2]) }
|
||||
Eapp({ op with a_op = Epre(default e1) }, [e2]) }
|
||||
end
|
||||
| Eapp({ a_op = Earrow }, [e1;e2]) ->
|
||||
let e1 = translate res e1 in
|
||||
let e2 = translate res e2 in
|
||||
ifres res e1 e2
|
||||
| Eapp({ a_op = Enode(f,params) } as op, e_list) ->
|
||||
let e_list = List.map (translate res) e_list in
|
||||
if true_reset res then
|
||||
{ e with e_desc = Eapp({ op with a_op = Eevery(f, params) },
|
||||
(exp_of_res res) :: e_list) }
|
||||
else
|
||||
{ e with e_desc = Eapp({ op with a_op = Enode(f,params) }, e_list ) }
|
||||
| Eapp( { a_op = Eiterator(it,f, params, _) } as op, e_list) ->
|
||||
let e_list = List.map (translate res) e_list in
|
||||
if true_reset res then
|
||||
let r = Some (exp_of_res res) in
|
||||
{ e with e_desc = Eapp({ op with a_op = Eiterator(it,f,params,r) },
|
||||
e_list) }
|
||||
else
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
| Eapp({ a_op = Eevery(f, params) } as op, re :: e_list) ->
|
||||
|
||||
(* add reset to the current reset exp. *)
|
||||
| Eapp({ a_op = Ecall(op_desc, Some re) } as op, e_list) ->
|
||||
let re = translate res re in
|
||||
let e_list = List.map (translate res) e_list in
|
||||
{ e with e_desc = Eapp({ op with a_op = Eevery(f, params)},
|
||||
(or_op res re) :: e_list) }
|
||||
let op = { op with a_op = Ecall(op_desc, Some (or_op res re))} in
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
(* create a new reset exp if necessary *)
|
||||
| Eapp({ a_op = Ecall(op_desc, None) } as op, e_list) ->
|
||||
let e_list = List.map (translate res) e_list in
|
||||
if true_reset res then
|
||||
let op = { op with a_op = Ecall(op_desc, Some (exp_of_res res)) } in
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
else
|
||||
{ e with e_desc = Eapp(op, e_list ) }
|
||||
(* add reset to the current reset exp. *)
|
||||
| Eapp( { a_op = Earray_op (Eiterator(it, op_desc, Some re)) } as op, e_list) ->
|
||||
let re = translate res re in
|
||||
let e_list = List.map (translate res) e_list in
|
||||
let r = Some (or_op res re) in
|
||||
let op = { op with a_op = Earray_op (Eiterator(it, op_desc, r)) } in
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
(* create a new reset exp if necessary *)
|
||||
| Eapp( { a_op = Earray_op (Eiterator(it, op_desc, None)) } as op, e_list) ->
|
||||
let e_list = List.map (translate res) e_list in
|
||||
if true_reset res then
|
||||
let r = Some (exp_of_res res) in
|
||||
let op = { op with a_op = Earray_op (Eiterator(it, op_desc, r)) } in
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
else
|
||||
{ e with e_desc = Eapp(op, e_list) }
|
||||
|
||||
| Eapp(op, e_list) ->
|
||||
{ e with e_desc = Eapp(op, List.map (translate res) e_list) }
|
||||
| Efield(e', field) ->
|
||||
|
|
Loading…
Reference in a new issue