From 91ff654fc9cdab2dbb031a43befdba403101bbc7 Mon Sep 17 00:00:00 2001 From: Arnaud DABY-SEESARAM Date: Mon, 19 Dec 2022 23:21:11 +0100 Subject: [PATCH] [passes] ensure that apps don't mix with operators --- src/main.ml | 2 ++ src/passes.ml | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/main.ml b/src/main.ml index da6fed1..b9c677e 100644 --- a/src/main.ml +++ b/src/main.ml @@ -46,6 +46,7 @@ let _ = let default_passes = ["remove_if"; "linearization_pre"; "linearization_tuples"; "linearization_app"; + "ensure_assign_val"; "equations_ordering"] in let sanity_passes = ["sanity_pass_assignment_unicity"; "check_typing"] in let usage_msg = @@ -87,6 +88,7 @@ let _ = ("linearization_tuples", Passes.pass_linearization_tuples); ("linearization_app", Passes.pass_linearization_app); ("linearization_pre", Passes.pass_linearization_pre); + ("ensure_assign_val", Passes.pass_ensure_assignment_value); ("sanity_pass_assignment_unicity", Passes.sanity_pass_assignment_unicity); ("automata_translation", Passes.automata_translation_pass); ("automata_validity", Passes.check_automata_validity); diff --git a/src/passes.ml b/src/passes.ml index c409846..ac498da 100644 --- a/src/passes.ml +++ b/src/passes.ml @@ -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 * equation defining each variable (and that no equation tries to redefine an * input).