let interp_annot state stmt ca record =
let aux text behav p =
let in_behavior =
match behav with
| [] -> True
| behavs ->
let ab = AnalysisParam.active_behaviors in
let all_active = Extlib.filter_map'
(ActiveBehaviors.behavior_from_name ab)
(ActiveBehaviors.is_active ab)
behavs
in
if all_active = [] then False
else
if List.exists (ActiveBehaviors.only_active ab) all_active
then True
else Unknown
in
if in_behavior = False
then state
else
let result = fold_join_predicate State_set.fold
(fun here ->
let env = env_annot ~pre:!!fused_initial_state ~here in
eval_predicate ~result:None env p)
state
in
let ip = Property.ip_of_code_annot (current_kf()) stmt ca in
let change_status st =
if record then List.iter (fun p -> emit_status p st) ip
in
let message, result =
(match result, in_behavior with
| Unknown, _ | False, Unknown ->
if State_set.is_empty state then begin
change_status Property_status.False_if_reachable;
"invalid (stopping propagation)", State_set.empty
end else begin
change_status Property_status.Dont_know;
"unknown", state
end
| True, _ ->
change_status Property_status.True;
"valid", state
| False, True ->
change_status Property_status.False_if_reachable;
"invalid (stopping propagation)", State_set.empty
| _, False -> assert false)
in
if record then
Value_parameters.result ~once:true ~current:true
"%s got status %s.%t" text message pp_callstack;
if in_behavior = True then
let env = env_annot ~pre:!!fused_initial_state
~here:(State_set.join result) in
reduce_by_disjunction ~result:None ~env
result
slevel
p
else
result
in
match ca.annot_content with
| AAssert (behav,p) -> aux "Assertion" behav p
| AInvariant (behav, true, p) -> aux "Loop invariant" behav p
| APragma _
| AInvariant (_, false, _)
| AVariant _ | AAssigns _
| AStmtSpec _ -> state