let check_postconditions kf kinstr ~result ~slevel header init_state state kind behaviors =
let incorporate_behavior state b =
if b.b_post_cond = [] then state
else
let header =
if Cil.is_default_behavior b then header
else header ^ ", behavior " ^ b.b_name
in
let vc = Ast_info.behavior_postcondition b kind in
let assumes =
(Logic_const.pands
(List.map Logic_const.pred_of_id_pred b.b_assumes))
in
let activated = eval_predicate ~result ~old:None init_state assumes in
let update_status st =
let ip = Property.ip_ensures_of_behavior kf kinstr b in
List.iter (swap Status.join st) ip
in
let old = init_state in
match activated with
| True ->
(let res = eval_predicate ~result ~old state vc in
Value_parameters.result ~once:true ~current:true
"%s: postcondition got status %s" header (string_of_status res);
match res with
| False -> update_status status_false; State_set.empty
| True ->
update_status status_true;
reduce_by_disjunction ~result ~old state slevel vc
| Unknown ->
update_status status_maybe;
reduce_by_disjunction ~result ~old state slevel vc)
| Unknown ->
(let res = eval_predicate ~result ~old state vc in
Value_parameters.result ~once:true ~current:true
"%s: postcondition got status %s" header (string_of_status res);
match res with
Unknown | False ->
update_status status_maybe;
Value_parameters.result ~once:true ~current:true
"%s: postcondition got status %s, but it is unknown if the behavior is active"
header (string_of_status res);
state
| True ->
update_status status_true;
Value_parameters.result ~once:true ~current:true
"%s: postcondition got status valid" header;
state)
| False ->
Value_parameters.result ~once:true ~current:true
"%s: assumption got status invalid; post-condition not evaluated"
header;
state
in
List.fold_left incorporate_behavior state behaviors