let check_preconditions kf kinstr ~slevel header state spec =
let incorporate_behavior state b =
let header =
if Cil.is_default_behavior b then header
else header ^ ", behavior " ^ b.b_name
in
if b.b_requires = [] then state
else
let assumes =
(Logic_const.pands
(List.map Logic_const.pred_of_id_pred b.b_assumes))
in
let vc =
(Logic_const.pands
(List.map Logic_const.pred_of_id_pred b.b_requires))
in
let activated = eval_predicate ~result:None state assumes in
let update_status st =
List.iter
(fun pre ->
let ip =
Property.IPPredicate(Property.PKRequires b,kf,kinstr,pre)
in
Status.join ip st)
b.b_requires
in
match activated with
| True ->
(let res = eval_predicate ~result:None state vc in
Value_parameters.result ~once:true ~current:true
"%s: precondition 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:None state slevel vc
| Unknown ->
update_status status_maybe;
reduce_by_disjunction ~result:None state slevel vc)
| Unknown ->
(let res = eval_predicate ~result:None state vc in
Value_parameters.result ~once:true ~current:true
"%s: precondition 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: precondition 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: precondition got status valid" header;
state)
| False ->
Value_parameters.result ~once:true ~current:true
"%s: assumption got status invalid; precondition not evaluated"
header;
state
in
List.fold_left
incorporate_behavior
state spec.spec_behavior