Comprehensive backend-independent counterexamples - #883
Conversation
| // Counterexample in the presence of magic wands. A wand acc(x.f, 1/2) --* | ||
| // acc(x.f, 1/1) is applied, combining the held half permission with the wand to | ||
| // obtain full permission to x.f. The counterexample at the subsequent failing | ||
| // assertion reports that full permission, i.e. the effect of applying the wand. |
There was a problem hiding this comment.
Is this really testing anything counterexample-related to magic wands? It seems this just does the usual permission accounting and then provides a counterexample related to the permisison on L18.
| method map_eq(s: Map[Int, Int], t: Map[Int, Int]) | ||
| requires s == t | ||
| { | ||
| //:: ExpectedCounterexample(assert.failed:assertion.false, (s == t)) |
There was a problem hiding this comment.
For this, sets.vpr, and multisets.vpr, would this not work equally "well" for any domain? I would expect maps.vpr to have something specific to maps, not just general equality. sequences.vpr seems better, for example.
| var x: Int | ||
| assume x == 5 | ||
| var y: Int := foo(x) | ||
| //:: ExpectedCounterexample(assert.failed:assertion.false, (x == 5, y == 42)) |
There was a problem hiding this comment.
Can we also report (and test for) values of functions unrelated to local variables? For example foo(3) == 42 here?
| method foo(a: Ref, b: Ref) | ||
| requires StructA(a) | ||
| requires StructB(b) | ||
| //:: ExpectedCounterexample(postcondition.violated:assertion.false, (a.x == 3)) |
There was a problem hiding this comment.
Can we also report (and test for) values of fields in folded predicates?
| import viper.silver.ast.{AbstractLocalVar, Exp, Type, Resource} | ||
|
|
||
| /** | ||
| * Classes used to build counterexamples. Two layers are distinguished: |
There was a problem hiding this comment.
But the frontend accepts five different values for the counterexample kind. Are the other three not processed here?
This PR introduces a shared, backend-independent counterexample format in Silver, produced by both Silicon and Carbon. A counterexample is built in two layers:
RawCounterexample): the information collected from the backend model in a simple form, with heap resources still identified by backend-internal (SMT) identifiers.ResolvedCounterexample): the human-readable form; heap resources are bound to their AST nodes (fields, predicates, magic wands) and values are ordinary Viper AST expressions.Values are represented as normal Viper AST expressions (
ast.Exp). The two new AST nodesRefLit(a concrete reference) andBackendValueLit(an otherwise opaque backend value) cover things that have no ordinary Viper syntax.Select the layer on the command line:
--counterexample resolved(orraw). Silicon additionally requires--exhaleMode 1.Example:
The resolved counterexample shown to the user:
Seq(10, #undefined),Set(1, 2, 3),Multiset(7, 7, 8),Map(1 := 100));#undefinedmarks an entry the model does not pin down.Other resource kinds render analogously; a magic wand appears as the wand itself, e.g. Magic Wand Entry:
acc(x.f, 1/2) --* acc(x.f, 1/1) (Perm: 1/1), and (domain) function values are listed under a separate section, e.g.The same format is emitted by both Silicon and Carbon, so the two agree modulo backend-internal reference names (
$Ref!val!0vsT@U!val!0).This is the result of @rvandoren's practical work project, with a bunch of additions from me.