let crosscond_to_pred ?event cross op_logic_var status_logic_var =
let inv = match event with None -> true | Some _ -> false in
let check_current_event f status pred =
let (curr_f, curr_status) = Extlib.the event in
if Kernel_function.equal curr_f f && curr_status = status then pred
else (Bool3.False, pfalse)
in
let rec convert =
function
| TOr (c1, c2) ->
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,Logic_const.por(c1_pred, c2_pred))
end
| TAnd (c1, c2) ->
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,Logic_const.pand(c1_pred, c2_pred))
end
| TNot (c1) ->
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,Logic_const.pnot(c1_pred))
end
| TCall (kf,b) when inv ->
let s = Kernel_function.get_name kf in
let res =
[ prel(Req,
Logic_const.tvar op_logic_var,
Logic_const.term (TConst(func_to_cenum s))
(Ctype (func_enum_type()))
);
prel(Req,
Logic_const.tvar status_logic_var,
Logic_const.term
(TConst(op_status_to_cenum Promelaast.Call))
(Ctype (status_enum_type()))
)]
in
let res =
match b with
None -> res
| Some b ->
List.rev_append
(List.rev_map
Logic_utils.named_of_identified_predicate b.b_assumes)
res
in
(Undefined, Logic_const.pands res)
| TReturn kf when inv ->
let s = Kernel_function.get_name kf in
(Undefined,
Logic_const.pand(
prel(Req,
Logic_const.term
(TLval(TVar(op_logic_var),TNoOffset))
(Ctype Cil.intType),
Logic_const.term
(TConst(func_to_cenum s))
(Ctype Cil.intType)
),
prel(Req,
Logic_const.term
(TLval(TVar(status_logic_var),TNoOffset))
(Ctype Cil.intType),
Logic_const.term
(TConst(op_status_to_cenum Promelaast.Return))
(Ctype Cil.intType)
)
)
)
| TCall (f,b) ->
let pred = match b with
None -> Bool3.True, ptrue
| Some b ->
(Bool3.Undefined,
Logic_const.pands
(List.map Logic_utils.named_of_identified_predicate b.b_assumes))
in
check_current_event f Promelaast.Call pred
| TReturn f ->
check_current_event f Promelaast.Return (Bool3.True, ptrue)
| TTrue -> (Bool3.True, ptrue)
| TFalse -> (Bool3.False, pfalse)
| TRel(rel,t1,t2) ->
(Bool3.Undefined, Logic_const.prel (rel,t1,t2))
in
snd (convert cross)