[passes] ensure that apps don't mix with operators
This commit is contained in:
parent
025d25a146
commit
91ff654fc9
@ -46,6 +46,7 @@ let _ =
|
|||||||
let default_passes =
|
let default_passes =
|
||||||
["remove_if";
|
["remove_if";
|
||||||
"linearization_pre"; "linearization_tuples"; "linearization_app";
|
"linearization_pre"; "linearization_tuples"; "linearization_app";
|
||||||
|
"ensure_assign_val";
|
||||||
"equations_ordering"] in
|
"equations_ordering"] in
|
||||||
let sanity_passes = ["sanity_pass_assignment_unicity"; "check_typing"] in
|
let sanity_passes = ["sanity_pass_assignment_unicity"; "check_typing"] in
|
||||||
let usage_msg =
|
let usage_msg =
|
||||||
@ -87,6 +88,7 @@ let _ =
|
|||||||
("linearization_tuples", Passes.pass_linearization_tuples);
|
("linearization_tuples", Passes.pass_linearization_tuples);
|
||||||
("linearization_app", Passes.pass_linearization_app);
|
("linearization_app", Passes.pass_linearization_app);
|
||||||
("linearization_pre", Passes.pass_linearization_pre);
|
("linearization_pre", Passes.pass_linearization_pre);
|
||||||
|
("ensure_assign_val", Passes.pass_ensure_assignment_value);
|
||||||
("sanity_pass_assignment_unicity", Passes.sanity_pass_assignment_unicity);
|
("sanity_pass_assignment_unicity", Passes.sanity_pass_assignment_unicity);
|
||||||
("automata_translation", Passes.automata_translation_pass);
|
("automata_translation", Passes.automata_translation_pass);
|
||||||
("automata_validity", Passes.check_automata_validity);
|
("automata_validity", Passes.check_automata_validity);
|
||||||
|
@ -391,6 +391,79 @@ let pass_linearization_app verbose debug =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let pass_ensure_assignment_value verbose debug =
|
||||||
|
let varcount = ref 0 in
|
||||||
|
let rec aux_expr should_be_value vars expr =
|
||||||
|
match expr with
|
||||||
|
| EConst _ | EVar _ -> [], vars, expr
|
||||||
|
| EMonOp (t, op, e) ->
|
||||||
|
let eqs, vars, e = aux_expr true vars e in
|
||||||
|
eqs, vars, EMonOp (t, op, e)
|
||||||
|
| EBinOp (t, op, e, e') ->
|
||||||
|
let eqs, vars, e = aux_expr true vars e in
|
||||||
|
let eqs', vars, e' = aux_expr true vars e' in
|
||||||
|
eqs @ eqs', vars, EBinOp (t, op, e, e')
|
||||||
|
| ETriOp (t, op, e, e', e'') ->
|
||||||
|
let eqs, vars, e = aux_expr should_be_value vars e in
|
||||||
|
let eqs', vars, e' = aux_expr should_be_value vars e' in
|
||||||
|
let eqs'', vars, e'' = aux_expr should_be_value vars e'' in
|
||||||
|
eqs @ eqs' @ eqs'', vars, ETriOp (t, op, e, e', e'')
|
||||||
|
| EComp (t, op, e, e') ->
|
||||||
|
let eqs, vars, e = aux_expr true vars e in
|
||||||
|
let eqs', vars, e' = aux_expr true vars e' in
|
||||||
|
eqs @ eqs', vars, EComp (t, op, e, e')
|
||||||
|
| EWhen (t, e, e') ->
|
||||||
|
let eqs, vars, e = aux_expr should_be_value vars e in
|
||||||
|
let eqs', vars, e' = aux_expr should_be_value vars e' in
|
||||||
|
eqs @ eqs', vars, EWhen (t, e, e')
|
||||||
|
| EReset (t, e, e') ->
|
||||||
|
let eqs, vars, e = aux_expr should_be_value vars e in
|
||||||
|
let eqs', vars, e' = aux_expr should_be_value vars e' in
|
||||||
|
eqs @ eqs', vars, EReset (t, e, e')
|
||||||
|
| ETuple (t, l) ->
|
||||||
|
let eqs, vars, l =
|
||||||
|
List.fold_right
|
||||||
|
(fun e (eqs, vars, l) ->
|
||||||
|
let eqs', vars, e = aux_expr true vars e in
|
||||||
|
eqs' @ eqs, vars, e :: l)
|
||||||
|
l ([], vars, []) in
|
||||||
|
eqs, vars, ETuple (t, l)
|
||||||
|
| EApp (t, n, e) ->
|
||||||
|
let eqs, vars, e = aux_expr true vars e in
|
||||||
|
if should_be_value
|
||||||
|
then
|
||||||
|
let nvar = Format.sprintf "_assignval%d" !varcount in
|
||||||
|
incr varcount;
|
||||||
|
let nvar: t_var =
|
||||||
|
match t with
|
||||||
|
| [TBool] -> BVar nvar
|
||||||
|
| [TReal] -> RVar nvar
|
||||||
|
| [TInt] -> IVar nvar
|
||||||
|
| _ ->
|
||||||
|
failwith "An application occurring here should return a single element."
|
||||||
|
in
|
||||||
|
let neq_patt: t_varlist = (t, [nvar]) in
|
||||||
|
let neq_expr: t_expression = EApp (t, n, e) in
|
||||||
|
let vars = varlist_concat neq_patt vars in
|
||||||
|
(neq_patt, neq_expr) :: eqs, vars, EVar (t, nvar)
|
||||||
|
else
|
||||||
|
eqs, vars, EApp (t, n, e)
|
||||||
|
in
|
||||||
|
let aux_ensure_assign_val node =
|
||||||
|
let new_equations, vars =
|
||||||
|
List.fold_left
|
||||||
|
(fun (eqs, vars) eq ->
|
||||||
|
let eqs', vars, expr = aux_expr false vars (snd eq) in
|
||||||
|
(fst eq, expr) :: eqs' @ eqs, vars
|
||||||
|
)
|
||||||
|
([], node.n_local_vars) node.n_equations
|
||||||
|
in
|
||||||
|
Some { node with n_equations = new_equations; n_local_vars = vars }
|
||||||
|
in
|
||||||
|
node_pass aux_ensure_assign_val
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(** [sanity_pass_assignment_unicity] makes sure that there is at most one
|
(** [sanity_pass_assignment_unicity] makes sure that there is at most one
|
||||||
* equation defining each variable (and that no equation tries to redefine an
|
* equation defining each variable (and that no equation tries to redefine an
|
||||||
* input).
|
* input).
|
||||||
|
Loading…
Reference in New Issue
Block a user