let check_postconditions ~result ~slevel header init_state state kind behaviors =
let incorporate_behavior state b =
if b.b_post_cond = [] then state
else
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 Status.join_predicate post 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 behavior %s: postcondition got status %s"
header b.b_name
(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 behavior %s: postcondition got status %s"
header b.b_name
(string_of_status res);
match res with
Unknown | False ->
update_status status_maybe;
Value_parameters.result ~once:true ~current:true
"%s behavior %s: postcondition got status %s, but it is unknown if the behavior is active"
header b.b_name (string_of_status res);
state
| True ->
update_status status_true;
Value_parameters.result ~once:true ~current:true
"%s behavior %s: postcondition got status valid"
header b.b_name;
state)
| False ->
Value_parameters.result ~once:true ~current:true
"%s behavior %s: assumption got status invalid; post-condition not evaluated"
header b.b_name;
state
in
List.fold_left
incorporate_behavior
state behaviors