let combinePredecessors
      (s: stmt)
      ~old:{under_outputs = old_outputs;
            over_inputs = old_inputs}
      new_ =
    let {under_outputs = new_outputs;
         over_inputs = new_inputs} = computeFirstPredecessor s new_
    in
    let result_inputs = Zone.join old_inputs new_inputs in
    (* over-approximation :
       I+ = I_old+ \/+ (I_new+  \/+ (D+(exp) /+ Onew-)
    *)

    let result_outputs = Zone.meet old_outputs new_outputs in
    (* under-approximation :
       O- = O_old- /\- O_new-
    *)

    if Zone.is_included result_inputs old_inputs
      (* test for an over-approximation *)
      && Zone.is_included old_outputs result_outputs
      (* test for an under-approximation *)
    then None
    else Some {under_outputs = result_outputs; over_inputs = result_inputs}