let check_preconditions kf kinstr ~slevel header active_behaviors
init_state spec =
let env = env_pre_f (State_set.join init_state) in
let incorporate_behavior states b =
if b.b_requires = [] then states
else
let header = header ^ ActiveBehaviors.header b in
let update_status st vc =
let ip = Property.ip_of_requires kf kinstr b vc in
emit_status ip st
in
match ActiveBehaviors.active active_behaviors b with
| True ->
List.fold_left (fun state ({ip_content=pr;ip_loc=loc} as pre) ->
let source = fst loc in
if State_set.is_empty state then
(Value_parameters.result ~once:true ~source
"%s: no state in which to evaluate precondition, status not computed.%t"
header pp_callstack;
state)
else
let pr = Ast_info.predicate loc pr in
let res = fold_join_predicate State_set.fold
(fun state ->
eval_predicate ~result:None (env_pre_f state) pr)
state
in
Value_parameters.result ~once:true ~source
"%s: precondition got status %a.%t"
header pretty_predicate_value res pp_callstack;
match res with
| False ->
update_status Property_status.False_if_reachable pre;
State_set.empty
| True ->
update_status Property_status.True pre;
reduce_by_disjunction ~result:None ~env state slevel pr
| Unknown ->
update_status Property_status.Dont_know pre;
reduce_by_disjunction ~result:None ~env state slevel pr
) states b.b_requires
| Unknown ->
List.fold_left
(fun state ({ip_content=pr;ip_loc=loc} as pre) ->
let source = fst loc in
if State_set.is_empty state then
(Value_parameters.result ~once:true ~source
"%s: no state in which to evaluate precondition, status not computed.%t"
header pp_callstack;
state)
else
let pr = Ast_info.predicate loc pr in
let res = fold_join_predicate State_set.fold
(fun state ->
eval_predicate ~result:None (env_pre_f state) pr)
state
in
Value_parameters.result ~once:true ~source:(fst loc)
"%s: precondition got status %a.%t"
header pretty_predicate_value res pp_callstack;
match res with
| Unknown | False ->
update_status Property_status.Dont_know pre;
Value_parameters.result ~once:true ~source
"%s: precondition got status %a, but it is unknown if the behavior is active.%t"
header pretty_predicate_value res pp_callstack;
state
| True ->
update_status Property_status.True pre;
Value_parameters.result ~once:true ~source
"%s: precondition got status %a.%t"
header pretty_predicate_value res pp_callstack;
state
) states b.b_requires
| False ->
(match b.b_requires with
| [] -> ()
| {ip_loc=(source,_)}::_ ->
Value_parameters.result ~once:true ~source
"%s: assumption got status invalid; precondition not evaluated.%t"
header pp_callstack);
states
in
List.fold_left
incorporate_behavior
init_state spec.spec_behavior