diff --git a/include/arrow_spec.h b/include/arrow_spec.h
index 66c5dd29140d370c7bee6ced4a503ca5ba2ee234..99acd13829296f240bcc73d864872e611371aca2 100644
--- a/include/arrow_spec.h
+++ b/include/arrow_spec.h
@@ -37,8 +37,8 @@ extern void _arrow_dealloc (struct _arrow_mem *);
  */
 
 /*@ predicate _arrow_transition(struct _arrow_mem_ghost mem_in,
-                                struct _arrow_mem_ghost mem_out,
-                                _Bool out) =
+                                _Bool out,
+                                struct _arrow_mem_ghost mem_out) =
       out == mem_in._reg._first
       && (mem_in._reg._first ? (mem_out._reg._first == 0)
                              : (mem_out._reg._first == mem_in._reg._first));
diff --git a/src/backends/C/c_backend_spec.ml b/src/backends/C/c_backend_spec.ml
index fe72e4c3752bb4b87a414ed39239c9ab972ae89a..2c355abeabde974b647160635e2a92f8d9dddc74 100644
--- a/src/backends/C/c_backend_spec.ml
+++ b/src/backends/C/c_backend_spec.ml
@@ -258,40 +258,32 @@ let pp_memory_pack_aux' ?i fmt =
 
 let pp_memory_pack' fmt = pp_memory_pack pp_print_string pp_print_string fmt
 
-let pp_transition_aux ?i m pp_mem_in pp_mem_out pp_input pp_output fmt
-    (name, inputs, locals, outputs, mem_in, mem_out) =
+let pp_transition_aux ?i m pp_mem_in pp_mem_out pp_var fmt
+    (name, vars, mem_in, mem_out) =
   let stateless = fst (get_stateless_status m) in
-  fprintf fmt "%s_transition%a(@[<hov>%t%a%a%t%a@])" name
+  fprintf fmt "%s_transition%a(@[<hov>%t%a%t@])" name
     (pp_print_option pp_print_int)
     i
     (fun fmt -> if not stateless then pp_mem_in fmt mem_in)
     (pp_comma_list
        ~pp_prologue:(fun fmt () -> if not stateless then pp_print_comma fmt ())
-       pp_input)
-    inputs
-    (pp_print_option (fun fmt _ ->
-         pp_comma_list ~pp_prologue:pp_print_comma pp_input fmt locals))
-    i
+       pp_var)
+    vars
     (fun fmt -> if not stateless then fprintf fmt ",@ %a" pp_mem_out mem_out)
-    (pp_comma_list ~pp_prologue:pp_print_comma pp_output)
-    outputs
 
-let pp_transition m pp_mem_in pp_mem_out pp_input pp_output fmt
-    (t, mem_in, mem_out) =
-  pp_transition_aux ?i:t.tindex m pp_mem_in pp_mem_out pp_input pp_output fmt
-    (t.tname.node_id, t.tinputs, t.tlocals, t.toutputs, mem_in, mem_out)
+let pp_transition m pp_mem_in pp_mem_out pp_var fmt (t, mem_in, mem_out) =
+  pp_transition_aux ?i:t.tindex m pp_mem_in pp_mem_out pp_var fmt
+    (t.tname.node_id, t.tvars, mem_in, mem_out)
 
 let pp_transition_aux' ?i m =
-  pp_transition_aux ?i m pp_print_string pp_print_string pp_var_decl pp_var_decl
+  pp_transition_aux ?i m pp_print_string pp_print_string pp_var_decl
 
 let pp_transition_aux'' ?i m =
-  pp_transition_aux ?i m pp_print_string pp_print_string pp_var_decl pp_ptr_decl
+  pp_transition_aux ?i m pp_print_string pp_print_string (fun fmt v ->
+      (if is_output m v then pp_ptr_decl else pp_var_decl) fmt v)
 
 let pp_transition' m =
-  pp_transition m pp_print_string pp_print_string pp_var_decl pp_var_decl
-
-let pp_transition'' m =
-  pp_transition m pp_print_string pp_print_string pp_var_decl pp_ptr_decl
+  pp_transition m pp_print_string pp_print_string pp_var_decl
 
 let pp_reset_cleared pp_mem_in pp_mem_out fmt (name, mem_in, mem_out) =
   fprintf fmt "%s_reset_cleared(@[<hov>%a,@ %a@])" name pp_mem_in mem_in
@@ -329,15 +321,15 @@ module PrintSpec = struct
 
   let pp_expr :
       type a.
-      ?output:bool ->
+      ?test_output:bool ->
       machine_t ->
       ident ->
       formatter ->
       (value_t, a) expression_t ->
       unit =
-   fun ?(output = false) m mem fmt -> function
+   fun ?(test_output = false) m mem fmt -> function
     | Val v ->
-      pp_c_val m mem (pp_c_var_read ~test_output:output m) fmt v
+      pp_c_val m mem (pp_c_var_read ~test_output m) fmt v
     | Tag t ->
       pp_print_string fmt t
     | Var v ->
@@ -346,7 +338,7 @@ module PrintSpec = struct
       pp_reg mem fmt r
 
   let pp_predicate mode m mem_in mem_in' mem_out mem_out' fmt p =
-    let output, mem_update =
+    let test_output, mem_update =
       match mode with
       | InstrMode _ ->
         true, false
@@ -355,12 +347,12 @@ module PrintSpec = struct
       | _ ->
         false, false
     in
-    let pp_expr :
-        type a. ?output:bool -> formatter -> (value_t, a) expression_t -> unit =
-     fun ?output fmt e -> pp_expr ?output m mem_out fmt e
+    let pp_expr : type a. bool -> formatter -> (value_t, a) expression_t -> unit
+        =
+     fun test_output fmt e -> pp_expr ~test_output m mem_out fmt e
     in
     match p with
-    | Transition (f, inst, i, inputs, locals, outputs, r, mems, insts) ->
+    | Transition (f, inst, i, vars, r, mems, insts) ->
       let pp_mem_in, pp_mem_out =
         match inst with
         | None ->
@@ -373,8 +365,8 @@ module PrintSpec = struct
               else pp_access' fmt (mem_in, inst)),
             fun fmt mem_out -> pp_access' fmt (mem_out, inst) )
       in
-      pp_transition_aux ?i m pp_mem_in pp_mem_out pp_expr (pp_expr ~output) fmt
-        (f, inputs, locals, outputs, mem_in', mem_out')
+      pp_transition_aux ?i m pp_mem_in pp_mem_out (pp_expr test_output) fmt
+        (f, vars, mem_in', mem_out')
     | Reset (_f, inst, r) ->
       pp_ite
         (pp_c_val m mem_in (pp_c_var_read m))
@@ -555,7 +547,7 @@ let pp_transition_def m fmt t =
        (pp_transition m
           (pp_machine_decl' ~ghost:true)
           (pp_machine_decl' ~ghost:true)
-          (pp_local m) (pp_local m))
+          (pp_local m))
        (PrintSpec.pp_spec TransitionMode m))
     fmt
     ((t, (name, mem_in), (name, mem_out)), t.tformula)
@@ -593,8 +585,7 @@ let pp_transition_footprint_lemma m fmt t =
   let instances = List.map (fun (i, f) -> f, i) (IMap.bindings insts) in
   let tr ?mems ?insts () =
     Spec_common.mk_transition ?mems ?insts ?i:t.tindex name
-      (vdecls_to_vals t.tinputs) (vdecls_to_vals t.tlocals)
-      (vdecls_to_vals t.toutputs)
+      (vdecls_to_vals t.tvars)
   in
   if not (mems_empty && insts_empty) then
     pp_acsl
@@ -610,10 +601,8 @@ let pp_transition_footprint_lemma m fmt t =
       ( t,
         ( (m.mname.node_id, [ mem_in; mem_out ]),
           ( instances,
-            ( memories,
-              Forall
-                ( t.tinputs @ t.tlocals @ t.toutputs,
-                  Imply (tr (), tr ~mems ~insts ()) ) ) ) ) )
+            (memories, Forall (t.tvars, Imply (tr (), tr ~mems ~insts ()))) ) )
+      )
 
 let pp_transition_footprint_lemmas fmt m =
   pp_print_list ~pp_epilogue:pp_print_cut ~pp_open_box:pp_open_vbox0
@@ -824,7 +813,7 @@ module SrcMod = struct
             (pp_requires pp_separated')
             outputs (pp_assigns pp_ptr_decl) outputs
             (pp_ensures (pp_transition_aux'' m))
-            (name, inputs, [], outputs, "", "")
+            (name, inputs @ outputs, "", "")
         else
           fprintf fmt
             "%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a@,%a"
@@ -839,9 +828,9 @@ module SrcMod = struct
             (pp_ensures (pp_memory_pack_aux pp_ptr pp_print_string))
             (name, mem, self)
             (pp_ensures
-               (pp_transition_aux m (pp_old pp_ptr) pp_ptr pp_var_decl
-                  pp_ptr_decl))
-            (name, inputs, [], outputs, mem, mem)
+               (pp_transition_aux m (pp_old pp_ptr) pp_ptr (fun fmt v ->
+                    (if is_output m v then pp_ptr_decl else pp_var_decl) fmt v)))
+            (name, inputs @ outputs, mem, mem)
             (pp_assigns pp_ptr_decl) outputs
             (pp_assigns (pp_reg self))
             m.mmemory
diff --git a/src/machine_code.ml b/src/machine_code.ml
index cf324c94324ed58f21966f27b0a5411cd07b0400..d550720eb5a1711f1636072981bdd8f04d9d9307 100644
--- a/src/machine_code.ml
+++ b/src/machine_code.ml
@@ -186,11 +186,7 @@ type machine_ctx = {
   (* Transition spec *)
   t :
     (var_decl list
-    (* inputs *)
-    * var_decl list
-    (* locals *)
-    * var_decl list
-    (* outputs *)
+    (* vars *)
     * ISet.t (* memory footprint *)
     * ident IMap.t
     (* memory instances footprint *)
@@ -247,18 +243,15 @@ let translate_eq env ctx nd inputs locals outputs i eq =
   let outputs_i = Lustre_live.inter_live_i_with id i outputs in
   let pred_mp ctx a = And [ mk_memory_pack ~i:(i - 1) id; a ] :: ctx.mp in
   let pred_t ctx a =
-    ( inputs,
-      locals_i,
-      outputs_i,
+    ( inputs @ locals_i @ outputs_i,
       ctx.m,
       IMap.map (fun (td, _) -> node_name td) ctx.j,
       Exists
         ( Lustre_live.existential_vars id i eq (locals @ outputs),
           And
             [
-              mk_transition ~i:(i - 1) id (vdecls_to_vals inputs)
-                (vdecls_to_vals locals_pi)
-                (vdecls_to_vals outputs_pi);
+              mk_transition ~i:(i - 1) id
+                (vdecls_to_vals (inputs @ locals_pi @ outputs_pi));
               a;
             ] ) )
     :: ctx.t
@@ -274,8 +267,8 @@ let translate_eq env ctx nd inputs locals outputs i eq =
             (if fst (get_stateless_status_node nd) then []
             else [ mk_memory_pack ~i id ])
             @ [
-                mk_transition ~i id (vdecls_to_vals inputs)
-                  (vdecls_to_vals locals_i) (vdecls_to_vals outputs_i);
+                mk_transition ~i id
+                  (vdecls_to_vals (inputs @ locals_i @ outputs_i));
               ];
         }
         :: ctx.s;
@@ -304,7 +297,7 @@ let translate_eq env ctx nd inputs locals outputs i eq =
       ctl
         (MStep ([ var_x ], inst, [ c1; c2 ]))
         (mk_memory_pack ~inst (node_name td))
-        (mk_transition ~inst (node_name td) [] [] [ vdecl_to_val var_x ])
+        (mk_transition ~inst (node_name td) [ vdecl_to_val var_x ])
         { ctx with j = IMap.add inst (td, []) ctx.j }
     in
     { ctx with si = mkinstr (MSetReset inst) :: ctx.si }
@@ -332,7 +325,7 @@ let translate_eq env ctx nd inputs locals outputs i eq =
     }
   | p, Expr_appl (f, arg, r)
     when not (Basic_library.is_expr_internal_fun eq.eq_rhs) ->
-    let var_p = List.map (fun v -> env.get_var v) p in
+    let var_p = List.map env.get_var p in
     let el = expr_list_of_expr arg in
     let vl = List.map translate_expr el in
     let node_f = node_from_name f in
@@ -351,7 +344,7 @@ let translate_eq env ctx nd inputs locals outputs i eq =
       ctl ~ck:call_ck
         (MStep (var_p, inst, vl))
         (mk_memory_pack ~inst (node_name node_f))
-        (mk_transition ?r ~inst (node_name node_f) vl [] (vdecls_to_vals var_p))
+        (mk_transition ?r ~inst (node_name node_f) (vl @ vdecls_to_vals var_p))
         {
           ctx with
           j = IMap.add inst call_f ctx.j;
@@ -472,9 +465,7 @@ let transition_0 nd =
   {
     tname = nd;
     tindex = Some 0;
-    tinputs = nd.node_inputs;
-    tlocals = [];
-    toutputs = [];
+    tvars = nd.node_inputs;
     tformula = True;
     tmem_footprint = ISet.empty;
     tinst_footprint = IMap.empty;
@@ -483,16 +474,12 @@ let transition_0 nd =
 let transition_toplevel nd i =
   let tr =
     mk_transition nd.node_id ~i
-      (vdecls_to_vals nd.node_inputs)
-      []
-      (vdecls_to_vals nd.node_outputs)
+      (vdecls_to_vals (nd.node_inputs @ nd.node_outputs))
   in
   {
     tname = nd;
     tindex = None;
-    tinputs = nd.node_inputs;
-    tlocals = [];
-    toutputs = nd.node_outputs;
+    tvars = nd.node_inputs @ nd.node_outputs;
     tformula =
       (if fst (get_stateless_status_node nd) then tr
       else ExistsMem (nd.node_id, Predicate (ResetCleared nd.node_id), tr));
@@ -564,13 +551,11 @@ let translate_decl nd sch =
     transition_0 nd
     ::
     List.mapi
-      (fun i (tinputs, tlocals, toutputs, tmem_footprint, tinst_footprint, f) ->
+      (fun i (tvars, tmem_footprint, tinst_footprint, f) ->
         {
           tname = nd;
           tindex = Some (i + 1);
-          tinputs;
-          tlocals;
-          toutputs;
+          tvars;
           tformula = red f;
           tmem_footprint;
           tinst_footprint;
@@ -583,9 +568,7 @@ let translate_decl nd sch =
       ~instr_spec:
         ((if fst (get_stateless_status_node nd) then []
          else [ mk_memory_pack ~i:0 nd.node_id ])
-        @ [
-            mk_transition ~i:0 nd.node_id (vdecls_to_vals nd.node_inputs) [] [];
-          ])
+        @ [ mk_transition ~i:0 nd.node_id (vdecls_to_vals nd.node_inputs) ])
       MClearReset
   in
   {
diff --git a/src/machine_code_common.ml b/src/machine_code_common.ml
index af44a8ec969ca118fe20bc97a9a8a3b95678c72c..d8361c0228183a1298f247e475ce76b31fa81379 100644
--- a/src/machine_code_common.ml
+++ b/src/machine_code_common.ml
@@ -58,7 +58,7 @@ module PrintSpec = struct
      fun fmt e -> pp_expr m fmt e
     in
     match p with
-    | Transition (f, inst, i, inputs, locals, outputs, _r, _mems, _insts) ->
+    | Transition (f, inst, i, vars, _r, _mems, _insts) ->
       fprintf fmt "Transition_%a<%a>%a%a" pp_print_string f
         (pp_print_option
            ~none:(fun fmt () -> pp_print_string fmt "SELF")
@@ -67,7 +67,7 @@ module PrintSpec = struct
         (pp_print_option pp_print_int)
         i
         (pp_print_parenthesized pp_expr)
-        (inputs @ locals @ outputs)
+        vars
     | Reset (f, inst, r) ->
       fprintf fmt "Reset_%a<%a> on %a" pp_print_string f pp_print_string inst
         (pp_val m) r
@@ -239,8 +239,7 @@ let pp_transition m fmt t =
     (pp_print_option pp_print_int)
     t.tindex
     (pp_print_parenthesized pp_vdecl)
-    (t.tinputs @ t.tlocals @ t.toutputs)
-    (PrintSpec.pp_spec m) t.tformula
+    t.tvars (PrintSpec.pp_spec m) t.tformula
 
 let pp_transitions m fmt =
   if !Options.spec <> "no" then
diff --git a/src/optimize_machine.ml b/src/optimize_machine.ml
index 5de389e9035e9e36d09f3214d838ef5df17dff38..2f9d14acf6d03bf4f57da5655669354b45bb2682 100644
--- a/src/optimize_machine.ml
+++ b/src/optimize_machine.ml
@@ -11,6 +11,7 @@
 
 open Utils
 open Lustre_types
+open Spec_types
 open Machine_code_types
 open Corelang
 open Causality
@@ -597,36 +598,75 @@ let rec value_replace_var fvar value =
   | Power (v, n) ->
     { value with value_desc = Power (value_replace_var fvar v, n) }
 
-let rec instr_replace_var fvar instr cont =
-  match get_instr_desc instr with
-  | MLocalAssign (i, v) ->
-    instr_cons
-      (update_instr_desc instr
-         (MLocalAssign (fvar i, value_replace_var fvar v)))
-      cont
-  | MStateAssign (i, v) ->
-    instr_cons
-      (update_instr_desc instr (MStateAssign (i, value_replace_var fvar v)))
-      cont
-  | MSetReset _
-  | MNoReset _
-  | MClearReset
-  | MResetAssign _
-  | MSpec _
-  | MComment _ ->
-    instr_cons instr cont
-  | MStep (il, i, vl) ->
-    instr_cons
-      (update_instr_desc instr
-         (MStep (List.map fvar il, i, List.map (value_replace_var fvar) vl)))
-      cont
-  | MBranch (g, hl) ->
-    instr_cons
-      (update_instr_desc instr
-         (MBranch
-            ( value_replace_var fvar g,
-              List.map (fun (h, il) -> h, instrs_replace_var fvar il []) hl )))
-      cont
+let expr_spec_replace :
+    type a.
+    (var_decl -> var_decl) ->
+    (value_t, a) expression_t ->
+    (value_t, a) expression_t =
+ fun fvar -> function
+  | Val v ->
+    Val (value_replace_var fvar v)
+  | Var v ->
+    Var (fvar v)
+  | e ->
+    e
+
+let predicate_spec_replace fvar = function
+  | Transition (f, inst, i, vars, r, mems, insts) ->
+    Transition
+      (f, inst, i, List.map (expr_spec_replace fvar) vars, r, mems, insts)
+  | p ->
+    p
+
+let rec instr_spec_replace fvar =
+  let aux instr = instr_spec_replace fvar instr in
+  function
+  | Equal (e1, e2) ->
+    Equal (expr_spec_replace fvar e1, expr_spec_replace fvar e2)
+  | And f ->
+    And (List.map aux f)
+  | Or f ->
+    Or (List.map aux f)
+  | Imply (a, b) ->
+    Imply (aux a, aux b)
+  | Exists (xs, a) ->
+    let fvar v = if List.mem v xs then v else fvar v in
+    Exists (xs, instr_spec_replace fvar a)
+  | Forall (xs, a) ->
+    let fvar v = if List.mem v xs then v else fvar v in
+    Forall (xs, instr_spec_replace fvar a)
+  | Ternary (e, a, b) ->
+    Ternary (expr_spec_replace fvar e, aux a, aux b)
+  | Predicate p ->
+    Predicate (predicate_spec_replace fvar p)
+  | ExistsMem (f, a, b) ->
+    ExistsMem (f, aux a, aux b)
+  | f ->
+    f
+
+let rec instr_replace_var fvar instr =
+  let instr_desc =
+    match instr.instr_desc with
+    | MLocalAssign (i, v) ->
+      MLocalAssign (fvar i, value_replace_var fvar v)
+    | MStateAssign (i, v) ->
+      MStateAssign (i, value_replace_var fvar v)
+    | MStep (il, i, vl) ->
+      MStep (List.map fvar il, i, List.map (value_replace_var fvar) vl)
+    | MBranch (g, hl) ->
+      MBranch
+        ( value_replace_var fvar g,
+          List.map (fun (h, il) -> h, instrs_replace_var fvar il []) hl )
+    | MSetReset _
+    | MNoReset _
+    | MClearReset
+    | MResetAssign _
+    | MSpec _
+    | MComment _ ->
+      instr.instr_desc
+  in
+  let instr_spec = List.map (instr_spec_replace fvar) instr.instr_spec in
+  instr_cons { instr with instr_desc; instr_spec }
 
 and instrs_replace_var fvar instrs cont =
   List.fold_right (instr_replace_var fvar) instrs cont
@@ -657,15 +697,13 @@ let step_replace_var fvar step =
 let machine_replace_variables fvar m =
   { m with mstep = step_replace_var fvar m.mstep }
 
-let machine_reuse_variables m reuse =
+let machine_reuse_variables reuse m =
   let fvar v = try Hashtbl.find reuse v.var_id with Not_found -> v in
   machine_replace_variables fvar m
 
-let machines_reuse_variables prog reuse_tables =
-  List.map
-    (fun m ->
-      machine_reuse_variables m (Utils.IMap.find m.mname.node_id reuse_tables))
-    prog
+let machines_reuse_variables reuse_tables =
+  List.map (fun m ->
+      machine_reuse_variables (Utils.IMap.find m.mname.node_id reuse_tables) m)
 
 let rec instr_assign res instr =
   match get_instr_desc instr with
@@ -723,19 +761,18 @@ and instrs_reduce branches instrs cont =
     i1 :: instrs_reduce branches (i2 :: q) cont
 
 let rec instrs_fusion instrs =
-  match instrs, List.map get_instr_desc instrs with
-  | [], [] | [ _ ], [ _ ] ->
+  match instrs with
+  | [] | [ _ ] ->
     instrs
-  | i1 :: _ :: q, _ :: MBranch ({ value_desc = Var v; _ }, hl) :: _
-    when instr_constant_assign v i1 ->
-    instr_reduce
-      (List.map (fun (h, b) -> h, instrs_fusion b) hl)
-      i1 (instrs_fusion q)
-  | i1 :: i2 :: q, _ ->
-    i1 :: instrs_fusion (i2 :: q)
-  | _ ->
-    assert false
-(* Other cases should not happen since both lists are of same size *)
+  | i1 :: i2 :: q -> (
+    match i2.instr_desc with
+    | MBranch ({ value_desc = Var v; _ }, hl) when instr_constant_assign v i1 ->
+      instr_reduce
+        (List.map (fun (h, b) -> h, instrs_fusion b) hl)
+        { i1 with instr_spec = i1.instr_spec @ i2.instr_spec }
+        (instrs_fusion q)
+    | _ ->
+      i1 :: instrs_fusion (i2 :: q))
 
 let step_fusion step =
   { step with step_instrs = instrs_fusion step.step_instrs }
@@ -897,7 +934,7 @@ let optimize params prog node_schs machine_code =
         Scheduling.remove_prog_inlined_locals removed_table node_schs
       in
       let reuse_tables = Scheduling.compute_prog_reuse_table node_schs in
-      machines_fusion (machines_reuse_variables machine_code reuse_tables))
+      machines_fusion (machines_reuse_variables reuse_tables machine_code))
     else machine_code
   in
 
diff --git a/src/spec_common.ml b/src/spec_common.ml
index 6f3c9373bb641f05fedaea2dcbfd9298bbc3e6da..eeee85194ed451777c94b5cb33ef63cfa3a80cf1 100644
--- a/src/spec_common.ml
+++ b/src/spec_common.ml
@@ -79,17 +79,15 @@ let vals vs = List.map (fun v -> Val v) vs
 
 let mk_pred_call pred = Predicate pred
 
-let mk_transition ?(mems = ISet.empty) ?(insts = IMap.empty) ?r ?i ?inst id
-    inputs locals outputs =
+let mk_transition ?(mems = ISet.empty) ?(insts = IMap.empty) ?r ?i ?inst id vars
+    =
   let tr =
     mk_pred_call
       (Transition
          ( id,
            inst,
            i,
-           vals inputs,
-           vals locals,
-           vals outputs,
+           vals vars,
            (match r with Some _ -> true | None -> false),
            mems,
            insts ))
diff --git a/src/spec_types.ml b/src/spec_types.ml
index c1201c3a138b98171a008ae892c320d86ebddac8..fc3dfeed01acb0544f1647a2a75caa4a72d10415 100644
--- a/src/spec_types.ml
+++ b/src/spec_types.ml
@@ -22,8 +22,6 @@ let type_of_l_value : type a. (a, left_v) expression_t -> Types.type_expr =
   | Memory (StateVar v) ->
     v.var_type
 
-type ('a, 'b) expressions_t = ('a, 'b) expression_t list
-
 type 'a predicate_t =
   | Transition :
       ident (* node name *)
@@ -31,12 +29,8 @@ type 'a predicate_t =
       (* instance *)
       * int option
       (* transition index *)
-      * ('a, 'b) expressions_t
-      (* inputs *)
-      * ('a, 'b) expressions_t
-      (* locals *)
-      * ('a, 'b) expressions_t
-      (* outputs *)
+      * ('a, 'b) expression_t list
+      (* variables *)
       * bool (* reset *)
       * Utils.ISet.t (* memory footprint *)
       * ident Utils.IMap.t
@@ -78,9 +72,7 @@ type 'a memory_pack_t = {
 type 'a transition_t = {
   tname : node_desc;
   tindex : int option;
-  tinputs : var_decl list;
-  tlocals : var_decl list;
-  toutputs : var_decl list;
+  tvars : var_decl list;
   tformula : 'a formula_t;
   tmem_footprint : Utils.ISet.t;
   tinst_footprint : ident Utils.IMap.t;