let crosscond_to_exp cross func status =
(* TODO : Consider particular cases of result during return and parameters during call *)
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.Call) then
(Bool3.True, true_exp)
else
(Bool3.False,false_exp)
| PReturn (s) ->
if(s=func) && (status=Promelaast.Return) then
(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)
(* | PGt (c1,c2) -> (Undefined,BinOp(Gt,convert_arith c1,convert_arith c2,Cil.intType))
| PGe (c1,c2) -> (Undefined,BinOp(Ge,convert_arith c1,convert_arith c2,Cil.intType))
| PLt (c1,c2) -> (Undefined,BinOp(Lt,convert_arith c1,convert_arith c2,Cil.intType))
| PLe (c1,c2) -> (Undefined,BinOp(Le,convert_arith c1,convert_arith c2,Cil.intType))
| PEq (c1,c2) -> (Undefined,BinOp(Eq,convert_arith c1,convert_arith c2,Cil.intType))
| PNeq (c1,c2) -> (Undefined,BinOp(Ne,convert_arith c1,convert_arith c2,Cil.intType))
| PBoolVar (s) -> (Undefined,Lval(Cil.var(get_varinfo s))) *)
in
try
(*let (_,res) = *)
convert cross (*in
res*)
with
| _ ->
Ltl_to_acsl_option.fatal "Ltl_to_acsl plugin internal error. Status : Not_found exception during exp conversion.\n"