-
Notifications
You must be signed in to change notification settings - Fork 88
Implement delayed widening #1483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 10 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
5f2249f
Implement delayed widening
786ed5d
Use delayed widening option in control.ml
c635621
Merge branch 'master' into pr/RonaldJudin/1483
sim642 b4863a5
Move widening delay lifter up to avoid crash with witness lifter
sim642 e3a4186
Extract widening delay to separate module
sim642 0ec39cf
Reorganize analysis lifters
sim642 db3e88d
Refactor WideningDelay domain
sim642 2557f7d
Clean up WideningDelay lifter
sim642 766019e
Add widening delay example
sim642 d8d665b
Implement global widening delay
sim642 f34fc14
Add comment about widening delay transfer functions
sim642 1a8021d
Split 82-widen/02-mihaila-widen-fig7-delay into two tests
sim642 2eca6d6
Explain 82-widen/03-mihaila-widen-slide-delay
sim642 92ee72f
Merge branch 'master' into delay-widening
sim642 c2ba32a
Make ana.widen.delay.* option description more precise
sim642 bf8f4e9
Merge branch 'master' into delay-widening
sim642 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| (** Standard widening delay with counters. | ||
|
|
||
| Abstract elements are paired with an integer counter, indicating how many times it has been widened. | ||
| Lifted abstract elements are only widened if the counter exceeds a predefined limit. *) | ||
|
|
||
| open Batteries | ||
| open Lattice | ||
| open Analyses | ||
|
|
||
| module LocalChainParams: Printable.ChainParams = | ||
| struct | ||
| let n () = GobConfig.get_int "ana.widen.delay.local" | ||
| let names = string_of_int | ||
| end | ||
|
|
||
| module GlobalChainParams: Printable.ChainParams = | ||
| struct | ||
| let n () = GobConfig.get_int "ana.widen.delay.global" | ||
| let names = string_of_int | ||
| end | ||
|
|
||
| module Dom (Base: S) (ChainParams: Printable.ChainParams) = | ||
| struct | ||
| module Chain = Printable.Chain (ChainParams) | ||
| include Printable.Prod (Base) (Chain) | ||
|
|
||
| let bot () = (Base.bot (), 0) | ||
| let is_bot (b, _) = Base.is_bot b | ||
| let top () = (Base.top (), ChainParams.n ()) | ||
| let is_top (b, _) = Base.is_top b | ||
|
|
||
| let leq (b1, _) (b2, _) = Base.leq b1 b2 | ||
|
|
||
| (** All operations keep maximal counter. *) | ||
| let join (b1, i1) (b2, i2) = (Base.join b1 b2, max i1 i2) | ||
| let meet (b1, i1) (b2, i2) = (Base.meet b1 b2, max i1 i2) | ||
| let widen (b1, i1) (b2, i2) = | ||
| let i' = max i1 i2 in | ||
| if i' < ChainParams.n () then | ||
| (Base.join b1 b2, i' + 1) | ||
| else | ||
| (Base.widen b1 b2, i') (* Don't increase beyond n, otherwise TD3 will not reach fixpoint w.r.t. equal. *) | ||
| let narrow (b1, i1) (b2, i2) = (Base.narrow b1 b2, max i1 i2) | ||
|
|
||
| let pretty_diff () ((b1, _), (b2, _)) = | ||
| Base.pretty_diff () (b1, b2) (* Counters cannot violate leq. *) | ||
| end | ||
|
|
||
|
|
||
| module DLifter (S: Spec): Spec = | ||
| struct | ||
| module D = | ||
| struct | ||
| include Dom (S.D) (LocalChainParams) | ||
|
|
||
| let printXml f (b, i) = | ||
| BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" S.D.printXml b Chain.printXml i | ||
| end | ||
| module G = S.G | ||
| module C = S.C | ||
| module V = S.V | ||
| module P = | ||
| struct | ||
| include S.P | ||
| let of_elt (x, _) = of_elt x | ||
| end | ||
|
|
||
| let name () = S.name () ^ " with widening delay" | ||
|
|
||
| type marshal = S.marshal | ||
| let init = S.init | ||
| let finalize = S.finalize | ||
|
|
||
| let startstate v = (S.startstate v, 0) | ||
| let exitstate v = (S.exitstate v, 0) | ||
| let morphstate v (d, l) = (S.morphstate v d, l) | ||
|
|
||
| let conv (ctx: (D.t, G.t, C.t, V.t) ctx): (S.D.t, S.G.t, S.C.t, S.V.t) ctx = | ||
| { ctx with local = fst ctx.local | ||
| ; split = (fun d es -> ctx.split (d, 0) es) | ||
| } | ||
|
|
||
| let context ctx fd (d, _) = S.context (conv ctx) fd d | ||
| let startcontext () = S.startcontext () | ||
|
|
||
| let lift_fun ctx f g h = | ||
| f @@ h (g (conv ctx)) | ||
|
|
||
| let lift d = (d, 0) | ||
|
|
||
| let sync ctx reason = lift_fun ctx lift S.sync ((|>) reason) | ||
| let query ctx (type a) (q: a Queries.t): a Queries.result = S.query (conv ctx) q | ||
| let assign ctx lv e = lift_fun ctx lift S.assign ((|>) e % (|>) lv) | ||
| let vdecl ctx v = lift_fun ctx lift S.vdecl ((|>) v) | ||
| let branch ctx e tv = lift_fun ctx lift S.branch ((|>) tv % (|>) e) | ||
| let body ctx f = lift_fun ctx lift S.body ((|>) f) | ||
| let return ctx r f = lift_fun ctx lift S.return ((|>) f % (|>) r) | ||
| let asm ctx = lift_fun ctx lift S.asm identity | ||
| let skip ctx = lift_fun ctx lift S.skip identity | ||
| let special ctx r f args = lift_fun ctx lift S.special ((|>) args % (|>) f % (|>) r) | ||
|
|
||
| let enter ctx r f args = | ||
| let liftmap = List.map (Tuple2.mapn lift) in | ||
| lift_fun ctx liftmap S.enter ((|>) args % (|>) f % (|>) r) | ||
| let combine_env ctx r fe f args fc es f_ask = lift_fun ctx lift S.combine_env (fun p -> p r fe f args fc (fst es) f_ask) | ||
| let combine_assign ctx r fe f args fc es f_ask = lift_fun ctx lift S.combine_assign (fun p -> p r fe f args fc (fst es) f_ask) | ||
|
|
||
| let threadenter ctx ~multiple lval f args = lift_fun ctx (List.map lift) (S.threadenter ~multiple) ((|>) args % (|>) f % (|>) lval) | ||
| let threadspawn ctx ~multiple lval f args fctx = lift_fun ctx lift (S.threadspawn ~multiple) ((|>) (conv fctx) % (|>) args % (|>) f % (|>) lval) | ||
|
|
||
| let paths_as_set ctx = | ||
| let liftmap = List.map (fun x -> (x, snd ctx.local)) in | ||
| lift_fun ctx liftmap S.paths_as_set Fun.id | ||
|
|
||
| let event ctx e octx = | ||
| lift_fun ctx lift S.event ((|>) (conv octx) % (|>) e) | ||
| end | ||
|
|
||
| module GLifter (S: Spec): Spec = | ||
| struct | ||
| module D = S.D | ||
| module G = | ||
| struct | ||
| include Dom (S.G) (GlobalChainParams) | ||
|
|
||
| let printXml f (b, i) = | ||
| BatPrintf.fprintf f "%a<analysis name=\"widen-delay\">%a</analysis>" S.G.printXml b Chain.printXml i | ||
| end | ||
| module C = S.C | ||
| module V = S.V | ||
| module P = S.P | ||
|
|
||
| let name () = S.name () ^ " with widening delay" | ||
|
|
||
| type marshal = S.marshal | ||
| let init = S.init | ||
| let finalize = S.finalize | ||
|
|
||
| let startstate v = S.startstate v | ||
| let exitstate v = S.exitstate v | ||
| let morphstate v d = S.morphstate v d | ||
|
|
||
| let conv (ctx: (D.t, G.t, C.t, V.t) ctx): (S.D.t, S.G.t, S.C.t, S.V.t) ctx = | ||
| { ctx with global = (fun v -> fst (ctx.global v)) | ||
| ; sideg = (fun v g -> ctx.sideg v (g, 0)) | ||
| } | ||
|
|
||
| let context ctx fd d = S.context (conv ctx) fd d | ||
| let startcontext () = S.startcontext () | ||
|
|
||
| let lift_fun ctx f g h = | ||
| f @@ h (g (conv ctx)) | ||
|
|
||
| let lift d = d | ||
|
|
||
| let sync ctx reason = lift_fun ctx lift S.sync ((|>) reason) | ||
| let query ctx (type a) (q: a Queries.t): a Queries.result = S.query (conv ctx) q | ||
| let assign ctx lv e = lift_fun ctx lift S.assign ((|>) e % (|>) lv) | ||
| let vdecl ctx v = lift_fun ctx lift S.vdecl ((|>) v) | ||
| let branch ctx e tv = lift_fun ctx lift S.branch ((|>) tv % (|>) e) | ||
| let body ctx f = lift_fun ctx lift S.body ((|>) f) | ||
| let return ctx r f = lift_fun ctx lift S.return ((|>) f % (|>) r) | ||
| let asm ctx = lift_fun ctx lift S.asm identity | ||
| let skip ctx = lift_fun ctx lift S.skip identity | ||
| let special ctx r f args = lift_fun ctx lift S.special ((|>) args % (|>) f % (|>) r) | ||
|
|
||
| let enter ctx r f args = | ||
| let liftmap = List.map (Tuple2.mapn lift) in | ||
| lift_fun ctx liftmap S.enter ((|>) args % (|>) f % (|>) r) | ||
| let combine_env ctx r fe f args fc es f_ask = lift_fun ctx lift S.combine_env (fun p -> p r fe f args fc es f_ask) | ||
| let combine_assign ctx r fe f args fc es f_ask = lift_fun ctx lift S.combine_assign (fun p -> p r fe f args fc es f_ask) | ||
|
|
||
| let threadenter ctx ~multiple lval f args = lift_fun ctx (List.map lift) (S.threadenter ~multiple) ((|>) args % (|>) f % (|>) lval) | ||
| let threadspawn ctx ~multiple lval f args fctx = lift_fun ctx lift (S.threadspawn ~multiple) ((|>) (conv fctx) % (|>) args % (|>) f % (|>) lval) | ||
|
|
||
| let paths_as_set ctx = | ||
| lift_fun ctx Fun.id S.paths_as_set Fun.id | ||
|
|
||
| let event ctx e octx = | ||
| lift_fun ctx lift S.event ((|>) (conv octx) % (|>) e) | ||
| end |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // PARAM: --disable ana.int.def_exc --enable ana.int.interval --enable ana.sv-comp.functions --set ana.widen.delay.local 1 | ||
| #include <goblint.h> | ||
| extern _Bool __VERIFIER_nondet_bool(); | ||
| int main() { | ||
| int v = 0; | ||
| while (__VERIFIER_nondet_bool() == 0) { | ||
| __goblint_check(0 <= v); | ||
| __goblint_check(v <= 1); | ||
| if (v == 0) | ||
| v = 1; | ||
| // ... | ||
| } | ||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // PARAM: --disable ana.int.def_exc --enable ana.int.interval --enable ana.sv-comp.functions --set ana.widen.delay.local 3 | ||
| // From "Widening as Abstract Domain", Fig. 7: https://doi.org/10.1007/978-3-642-38088-4_12 | ||
| // They claim delay 2 (https://bytebucket.org/mihaila/bindead/wiki/resources/widening-talk.pdf), we need 3 for some reason. Why? | ||
| #include <goblint.h> | ||
| extern _Bool __VERIFIER_nondet_bool(); | ||
|
|
||
| int main() { | ||
| int x = 0; | ||
| int y = 0; | ||
| while (x < 100) { | ||
| __goblint_check(0 <= y); | ||
| __goblint_check(y <= 1); | ||
| if (__VERIFIER_nondet_bool()) | ||
| y = 1; | ||
| x = x + 4; | ||
| } | ||
| __goblint_check(0 <= y); | ||
| __goblint_check(y <= 1); | ||
| return 0; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // PARAM: --set ana.path_sens[+] threadflag --set ana.base.privatization mutex-meet-tid --enable ana.int.interval --set ana.widen.delay.local 100 --set ana.widen.delay.global 100 | ||
| // Fig 5a from Miné 2014 | ||
| #include <pthread.h> | ||
| #include <stdio.h> | ||
| #include <goblint.h> | ||
|
|
||
| int x; | ||
| pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
|
|
||
| void *t_fun(void *arg) { | ||
| int top; | ||
| while(top) { | ||
| pthread_mutex_lock(&mutex); | ||
| if(x<100) { | ||
| x++; | ||
| } | ||
| pthread_mutex_unlock(&mutex); | ||
| } | ||
| return NULL; | ||
| } | ||
|
|
||
|
|
||
| int main(void) { | ||
| int top, top2; | ||
|
|
||
|
|
||
| pthread_t id; | ||
| pthread_t id2; | ||
| pthread_create(&id, NULL, t_fun, NULL); | ||
| pthread_create(&id2, NULL, t_fun, NULL); | ||
| pthread_mutex_lock(&mutex); | ||
| __goblint_check(x <= 100); | ||
| pthread_mutex_unlock(&mutex); | ||
| return 0; | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.