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:None init_state assumes in
let update_status st =
List.iter
(fun (k, post) -> if k = kind then
let ip =
Property.IPPredicate(Property.PKEnsures (b,kind),kf,kinstr,post)
in
Status.join ip st)
b.b_post_cond
in
match activated with
| True ->
(let res = eval_predicate ~result 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 state slevel vc
| Unknown ->
update_status status_maybe;
reduce_by_disjunction ~result state slevel vc)
| Unknown ->
(let res = eval_predicate ~result 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