Skip to content

Commit 9a2b4ba

Browse files
committed
Output loop_transition_invariant-s to YAML witnesses
1 parent 7c2322a commit 9a2b4ba

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

src/analyses/apron/relationAnalysis.apron.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,11 @@ struct
317317
|> Seq.fold_left (fun acc x -> Invariant.(acc && of_exp x)) Invariant.none
318318
in
319319
Logs.debug "inv: %a" Invariant.pretty inv;
320-
()
320+
inv
321321

322322
let branch man e b =
323323
let st = man.local in
324324
let ask = Analyses.ask_of_man man in
325-
query_invariant_transition man;
326325
let res = assign_from_globals_wrapper ask man.global st e (fun rel' e' ->
327326
(* not an assign, but must remove g#in-s still *)
328327
RD.assert_inv ask rel' e' (not b) (no_overflow ask e)
@@ -704,6 +703,7 @@ struct
704703
let vf' x = vf (Obj.repr x) in
705704
Priv.iter_sys_vars man.global vq vf'
706705
| Queries.Invariant context -> query_invariant man context
706+
| Queries.InvariantTransition _context -> query_invariant_transition man
707707
| Queries.InvariantGlobal g ->
708708
let g: V.t = Obj.obj g in
709709
query_invariant_global man g

src/config/options.schema.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2824,7 +2824,8 @@
28242824
"type": "string",
28252825
"enum": [
28262826
"location_invariant",
2827-
"loop_invariant"
2827+
"loop_invariant",
2828+
"loop_transition_invariant"
28282829
]
28292830
},
28302831
"default": [

src/domains/queries.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ type _ t =
131131
| MustProtectedVars: mustprotectedvars -> VS.t t
132132
| MustProtectingLocks: mustprotectinglocks -> LockDomain.MustLockset.t t
133133
| Invariant: invariant_context -> Invariant.t t
134+
| InvariantTransition: invariant_context -> Invariant.t t
134135
| InvariantGlobal: Obj.t -> Invariant.t t (** Argument must be of corresponding [Spec.V.t]. *)
135136
| WarnGlobal: Obj.t -> Unit.t t (** Argument must be of corresponding [Spec.V.t]. *)
136137
| IterSysVars: VarQuery.t * Obj.t VarQuery.f -> Unit.t t (** [iter_vars] for [Constraints.FromSpec]. [Obj.t] represents [Spec.V.t]. *)
@@ -206,6 +207,7 @@ struct
206207
| MustProtectedVars _ -> (module VS)
207208
| MustProtectingLocks _ -> (module LockDomain.MustLockset)
208209
| Invariant _ -> (module Invariant)
210+
| InvariantTransition _ -> (module Invariant)
209211
| InvariantGlobal _ -> (module Invariant)
210212
| WarnGlobal _ -> (module Unit)
211213
| IterSysVars _ -> (module Unit)
@@ -280,6 +282,7 @@ struct
280282
| MustProtectedVars _ -> VS.top ()
281283
| MustProtectingLocks _ -> LockDomain.MustLockset.top ()
282284
| Invariant _ -> Invariant.top ()
285+
| InvariantTransition _ -> Invariant.top ()
283286
| InvariantGlobal _ -> Invariant.top ()
284287
| WarnGlobal _ -> Unit.top ()
285288
| IterSysVars _ -> Unit.top ()
@@ -366,6 +369,7 @@ struct
366369
| Any (MustProtectingLocks _) -> 61
367370
| Any (GhostVarAvailable _) -> 62
368371
| Any InvariantGlobalNodes -> 63
372+
| Any (InvariantTransition _) -> 64
369373

370374
let rec compare a b =
371375
let r = Stdlib.compare (order a) (order b) in
@@ -413,6 +417,7 @@ struct
413417
| Any (EvalJumpBuf e1), Any (EvalJumpBuf e2) -> CilType.Exp.compare e1 e2
414418
| Any (WarnGlobal vi1), Any (WarnGlobal vi2) -> Stdlib.compare (Hashtbl.hash vi1) (Hashtbl.hash vi2)
415419
| Any (Invariant i1), Any (Invariant i2) -> compare_invariant_context i1 i2
420+
| Any (InvariantTransition i1), Any (InvariantTransition i2) -> compare_invariant_context i1 i2
416421
| Any (InvariantGlobal vi1), Any (InvariantGlobal vi2) -> Stdlib.compare (Hashtbl.hash vi1) (Hashtbl.hash vi2)
417422
| Any (YamlEntryGlobal (vi1, task1)), Any (YamlEntryGlobal (vi2, task2)) -> Stdlib.compare (Hashtbl.hash vi1) (Hashtbl.hash vi2) (* TODO: compare task *)
418423
| Any (IterSysVars (vq1, vf1)), Any (IterSysVars (vq2, vf2)) -> VarQuery.compare vq1 vq2 (* not comparing fs *)
@@ -461,6 +466,7 @@ struct
461466
| Any (EvalJumpBuf e) -> CilType.Exp.hash e
462467
| Any (WarnGlobal vi) -> Hashtbl.hash vi
463468
| Any (Invariant i) -> hash_invariant_context i
469+
| Any (InvariantTransition i) -> hash_invariant_context i
464470
| Any (MutexType m) -> Mval.Unit.hash m
465471
| Any (InvariantGlobal vi) -> Hashtbl.hash vi
466472
| Any (YamlEntryGlobal (vi, task)) -> Hashtbl.hash vi (* TODO: hash task *)
@@ -522,6 +528,7 @@ struct
522528
| Any (MustProtectedVars m) -> Pretty.dprintf "MustProtectedVars _"
523529
| Any (MustProtectingLocks g) -> Pretty.dprintf "MustProtectingLocks _"
524530
| Any (Invariant i) -> Pretty.dprintf "Invariant _"
531+
| Any (InvariantTransition i) -> Pretty.dprintf "InvariantTransition _"
525532
| Any (WarnGlobal vi) -> Pretty.dprintf "WarnGlobal _"
526533
| Any (IterSysVars _) -> Pretty.dprintf "IterSysVars _"
527534
| Any (InvariantGlobal i) -> Pretty.dprintf "InvariantGlobal _"

src/witness/yamlWitness.ml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ struct
118118
};
119119
}
120120

121+
let loop_transition_invariant' ~location ~(invariant): InvariantSet.InvariantKind.t =
122+
Invariant {
123+
invariant_type = LoopTransitionInvariant {
124+
location;
125+
value = invariant;
126+
format = "ext_c_expression";
127+
labels = None;
128+
};
129+
}
130+
121131
let invariant_set ~task ~(invariants): Entry.t = {
122132
entry_type = InvariantSet {
123133
content = invariants;
@@ -572,6 +582,40 @@ struct
572582
invariants
573583
in
574584

585+
(* Generate loop transition invariants *)
586+
let invariants =
587+
if entry_type_enabled YamlWitnessType.InvariantSet.entry_type && invariant_type_enabled YamlWitnessType.InvariantSet.LoopTransitionInvariant.invariant_type then (
588+
LH.fold (fun loc ns acc ->
589+
if WitnessInvariant.emit_loop_head then ( (* TODO: remove double condition? *)
590+
let inv = List.fold_left (fun acc n ->
591+
let local = try NH.find (Lazy.force nh) n with Not_found -> Spec.D.bot () in
592+
Invariant.(acc || R.ask_local_node n ~local (InvariantTransition Invariant.default_context)) [@coverage off] (* bisect_ppx cannot handle redefined (||) *)
593+
) (Invariant.bot ()) ns
594+
in
595+
match inv with
596+
| `Lifted inv ->
597+
let fundec = Node.find_fundec (List.hd ns) in (* TODO: fix location hack *)
598+
let location_function = fundec.svar.vname in
599+
let location = Entry.location ~location:loc ~location_function in
600+
(* let invs = WitnessUtil.InvariantExp.process_exp inv in *)
601+
let invs = [inv] in (* TODO: not processing because original_name replacement removes \at names *)
602+
List.fold_left (fun acc inv ->
603+
let invariant = CilType.Exp.show inv in
604+
let invariant = Entry.loop_transition_invariant' ~location ~invariant in
605+
incr cnt_loop_invariant; (* TODO: separate counter? *)
606+
invariant :: acc
607+
) acc invs
608+
| `Bot | `Top -> (* TODO: 0 for bot (dead code)? *)
609+
acc
610+
)
611+
else
612+
acc
613+
) (Lazy.force loop_nodes) invariants
614+
)
615+
else
616+
invariants
617+
in
618+
575619
(* Generate flow-insensitive invariants as location invariants *)
576620
let invariants =
577621
if entry_type_enabled YamlWitnessType.FlowInsensitiveInvariant.entry_type && GobConfig.get_string "witness.invariant.flow_insensitive-as" = "invariant_set-location_invariant" then (

0 commit comments

Comments
 (0)