let crosscond_to_exp cross func status sid  =
  let false_exp = Cil.zero in
  let true_exp = Cil.one in
  let rec convert : Promelaast.condition -> Bool3.bool3 * Cil_types.exp = 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_exp) = convert c1 in
          match c1_val with
            | Bool3.True      -> (c1_val,c1_exp)
            | Bool3.False     -> convert c2
            | Undefined ->
                let (c2_val,c2_exp) = convert c2 in
                match c2_val with
                  | Bool3.True      -> (c2_val,c2_exp)
                  | Bool3.False     -> (c1_val,c1_exp)
                  | Undefined -> (Undefined,
                                  new_exp
                                    (BinOp(LOr,c1_exp,c2_exp,Cil.intType)))
        end

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

    | PNot (c1)     -> (*UnOp(LNot,convert c1,Cil.intType)*)
        begin
          let (c1_val,c1_exp) = convert c1 in
          match c1_val with
            | Bool3.True      -> (Bool3.False,false_exp)
            | Bool3.False     -> (Bool3.True,true_exp)
            | Undefined -> (c1_val,new_exp (UnOp(LNot,c1_exp,Cil.intType)))
        end

    (* Call and return are statically defined *)
    | PCall (s) ->
        if(s=func) && (status=Promelaast.Callthen
          (Bool3.True, true_exp)
        else
          (Bool3.False,false_exp)


    | PReturn (s) ->
        if(s=func) && (status=Promelaast.Returnthen
          (Bool3.True,true_exp)
            (*           snd (convert(PAnd(
                   PEq(PVar(s),PVar(curOp)),
                   PEq(PVar(callStatus),PVar(curOpStatus))
                   ))))*)

        else
          (Bool3.False,false_exp)



    | PCallOrReturn (s) ->
        if(s=func) then
          (Bool3.True,true_exp)
            (*           snd (convert(PEq(PVar(s),PVar(curOp)))))*)
        else
          (Bool3.False,false_exp)




    (* Other expressions are left unchanged *)
    | PTrue -> (Bool3.True, true_exp)
    | PFalse -> (Bool3.False, false_exp)

    | PIndexedExp(s) -> (Undefined,get_exp_from_tmpident s)
    | PFuncReturn (s, f) -> 
        (Undefined,
         Cil_manipulation.exp_substitution  
           (get_exp_from_tmpident s) 
           ["\\return"
           [get_concrete_value_of_return f]
        )

    | PFuncParam (s,f,varlist) -> 
        (Undefined
         Cil_manipulation.exp_substitution 
           (get_exp_from_tmpident s) 
           (varlist) 
           (get_concrete_value_of_call f sid varlist) 
        )
        


  in
  try
    convert cross 
  with
    | _ ->
        Aorai_option.fatal "Aorai plugin internal error. Status : Not_found exception during exp conversion.\n"