let crosscond_to_pred cross op_logic_var status_logic_var  =
  let rec convert : Promelaast.condition -> Bool3.bool3 * Cil_types.predicate = function
    (* Lazy evaluation of logic operators if the result can be statically computed *)
    | POr  (c1, c2) -> (*BinOp(LOr,convert c1,convert c2,Cil.intType)*)
        begin
          let (c1_val,c1_pred) = convert c1 in
          match c1_val with
            | Bool3.True      -> (c1_val,c1_pred)
            | Bool3.False     -> convert c2
            | Undefined ->
                let (c2_val,c2_pred) = convert c2 in
                match c2_val with
                  | Bool3.True      -> (c2_val,c2_pred)
                  | Bool3.False     -> (c1_val,c1_pred)
                  | Undefined -> (Undefined,Por(unamed c1_pred, unamed c2_pred))
        end

    | PAnd (c1, c2) -> (*BinOp(LAnd,convert c1,convert c2,Cil.intType)*)
        begin
          let (c1_val,c1_pred) = convert c1 in
          match c1_val with
            | Bool3.True      -> convert c2
            | Bool3.False     -> (c1_val,c1_pred)
            | Undefined ->
                let (c2_val,c2_pred) = convert c2 in
                match c2_val with
                  | Bool3.True      -> (c1_val,c1_pred)
                  | Bool3.False     -> (c2_val,c2_pred)
                  | Undefined -> (Undefined,Pand(unamed c1_pred, unamed c2_pred))
        end

    | PNot (c1)     -> (*UnOp(LNot,convert c1,Cil.intType)*)
        begin
          let (c1_val,c1_pred) = convert c1 in
          match c1_val with
            | Bool3.True      -> (Bool3.False,Pfalse)
            | Bool3.False     -> (Bool3.True,Ptrue)
            | Undefined -> (c1_val,Pnot(unamed c1_pred))
        end

    (* Call and return are statically defined *)
    | PFuncParam (_, s, _) (* This introduce an over-approximation in invariant (we do not consider param value) *)
    | PCall (s) ->
        (Undefined,
         Pand(
           unamed(
             Prel(Req,
                  mk_dummy_term (TLval(TVar(op_logic_var),TNoOffset)) Cil.intType,
                  mk_dummy_term (TConst(func_to_cenum  s)) Cil.intType
                 )
           ),
           unamed (
             Prel(Req,
                  mk_dummy_term (TLval(TVar(status_logic_var),TNoOffset)) Cil.intType,
                  mk_dummy_term (TConst(op_status_to_cenum Promelaast.Call)) Cil.intType
                 )
           )
         )
        )

    | PFuncReturn (_, s) (* This introduce an over-approximation in invariant (we do not consider returned value) *)
    | PReturn (s) ->
        (Undefined,
         Pand(
           unamed(
             Prel(Req,
                  mk_dummy_term (TLval(TVar(op_logic_var),TNoOffset)) Cil.intType,
                  mk_dummy_term (TConst(func_to_cenum s)) Cil.intType
                 )
           ),
           unamed (
             Prel(Req,
                  mk_dummy_term (TLval(TVar(status_logic_var),TNoOffset)) Cil.intType,
                  mk_dummy_term (TConst(op_status_to_cenum Promelaast.Return)) Cil.intType
                 )
           )
         )
        )



    | PCallOrReturn (s) ->
        (Undefined,
         Prel(Req,
              mk_dummy_term (TLval(TVar(op_logic_var),TNoOffset)) Cil.intType,
              mk_dummy_term (TConst(func_to_cenum s)) Cil.intType
             )
        )




    (* Other expressions are left unchanged *)
    | PTrue -> (Bool3.TruePtrue)
    | PFalse -> (Bool3.FalsePfalse)

    | PIndexedExp(s) -> (Undefined,get_pred_from_tmpident s)
  in
  try
    let (_,res) = convert cross in
    res
  with
    | _ ->
        Aorai_option.fatal "Aorai plugin internal error. Status : Not_found exception during term conversion.\n"