Skip to content
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

Fix multiple apply of magic wands with quantified expressions #805

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e951a1f
Remove MissingOutput flag from test case conditionals2.vpr
manud99 May 2, 2024
2f700d3
Add test suite that I used while developing magic wand snap functions.
manud99 May 13, 2024
6374709
Add UnexpectedOutput annotations for Carbon.
manud99 May 13, 2024
e0c11ac
Add unsound example illustrating issue viperproject/silicon#307.
manud99 May 13, 2024
e963e8f
Merge branch 'master' into magic-wand-maps
JonasAlaif May 14, 2024
ca79834
Merge branch 'magic-wand-maps' into magic-wand-fixes
JonasAlaif May 16, 2024
fe2e291
[WIP] Use MWSF for quantified magic wands.
manud99 May 19, 2024
e040eb8
Find even more unsound test cases.
manud99 Jun 2, 2024
129284b
Record which snapshot maps were created during packaging.
manud99 Jun 9, 2024
3d6fc1a
Simplify assume10QPwand.vpr test case.
manud99 Jun 11, 2024
9dba1b4
triggerFoldPackage.vpr still fails when using z3 version 4.13.0
manud99 Jun 11, 2024
a7d509f
Add tests to prevent unsoundness in QPPredicates.
manud99 Jun 12, 2024
710d56e
Add simplified versions of the QPWands.vpr test file.
manud99 Jun 12, 2024
4f7bf26
Merge branch 'refs/heads/master' into quantified-magic-wand-maps
manud99 Jun 12, 2024
482e7f2
Add annotations for the failing QPWands tests.
manud99 Jun 15, 2024
7a0b345
Merge branch 'master' into quantified-magic-wand-maps
manud99 Jun 15, 2024
c295837
Update test 13 and 15.
manud99 Jun 25, 2024
7eaf86a
Add test case 16.
manud99 Jun 27, 2024
709b763
Merge branch 'master' into quantified-magic-wand-maps
manud99 Jun 27, 2024
547cbdd
Rename test files.
manud99 Jun 28, 2024
2f8d64b
Update annotations on quantified magic wand tests.
manud99 Jun 30, 2024
6047989
Merge branch 'master' into quantified-magic-wand-maps
manud99 Jun 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ method m1(xs: Set[Ref], y: Ref, zs: Seq[Ref]) {
assume z in zs
assume !(z in xs)
package acc(z.f) --* acc(y.f)

//:: MissingOutput(assert.failed:assertion.false, /Silicon/issue/000/)
//:: ExpectedOutput(assert.failed:assertion.false)
assert z != y
}
Expand Down
25 changes: 25 additions & 0 deletions src/test/resources/all/impure_assume/assume10QPwand-light.vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/


field f: Int

predicate p(x: Ref)

method m(xs: Set[Ref], q: Perm, xs1: Set[Ref]) {

inhale none < q
inhale forall x: Ref :: (x in xs) ==> acc(x.f) --* acc(p(x))

assume (forall x1: Ref :: {acc(x1.f, q) --* acc(p(x1), q)} (x1 in xs1) ==> acc(x1.f, q) --* acc(p(x1), q))

var a: Ref

assume a in xs1

//:: UnexpectedOutput(assert.failed:wand.not.found, /carbon/issue/257/)
assert acc(a.f, q) --* acc(p(a), q)

//:: ExpectedOutput(assert.failed:assertion.false)
assert q == write ==> false // MS: Can we expect this to hold?
}
35 changes: 35 additions & 0 deletions src/test/resources/wands/mwsf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Test Suite for Magic Wand Snap Functions

This folder contains Viper test files that I used when working on MagicWandSnapFunctions for the Silicon project.

## Overview

| Name | Description | Expected Result |
|----------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|-----------------|
| [basic-bool.vpr](./basic-bool.vpr) | Boolean Magic Wand with trivial LHS | ✓ |
| [basic-int.vpr](./basic-int.vpr) | Integer Magic Wand with trivial LHS | ✓ |
| [basic-lhs-eq-rhs.vpr](./basic-lhs-equal-to-rhs.vpr) | Integer Magic Wand with LHS = RHS | ✓ |
| [basic-lhs-lt-rhs.vpr](./basic-lhs-smaller-than-rhs.vpr) | Integer Magic Wand with LHS < RHS | ✓ |
| [basic-lhs-gt-rhs.vpr](./basic-lhs-larger-than-rhs.vpr) | Integer Magic Wand with LHS > RHS | ✓ |
| [applying-twice-bool.vpr](./applying-twice-bool.vpr) | Applying the magic wand multiple times. Original version leaks information into the outer state | × |
| [assign-applying-bool.vpr](./assign-applying-bool.vpr) | Assigning result of applying expression to the same field using booleans | × |
| [assign-applying-int.vpr](./assign-applying-int.vpr) | Assigning result of applying expression to the same field using integers | × |
| [inhaling-magic-wand.vpr](./inhaling-magic-wand.vpr) | Inhaling a magic wand | ✓ |
| [predicates-in-magic-wands.vpr](./predicates-in-magic-wands.vpr) | Magic wand with predicates | ✓ |
| [example-list.vpr](./example-list.vpr) | Iterate over a List | ✓ |
| [applying-twice-quantified-wand.vpr](./applying-twice-quantified-wand.vpr) | Applying a quantified magic wand multiple times. | ✓ |
| [applying-twice-quantified-lhs.vpr](./applying-twice-quantified-lhs.vpr) | Applying a magic wand multiple times with a quantified expression on the LHS. | ✓ |
| [applying-twice-qp-fields.vpr](./applying-twice-qp-fields.vpr) | Test from QPFields.vpr adapted to test some unsound behavior. | ✓ |
| [applying-twice-qp-predicates.vpr](./applying-twice-qp-predicates.vpr) | Test from QPPredicates.vpr adapted to test some unsound behavior. | ✓ |
| [quantified-magic-wands.vpr](./quantified-magic-wands.vpr) | Tests with quantified magic wands. | ✓ |
| [two-fields.vpr](./two-fields.vpr) | Magic wand with quantifier over two fields. | ✓ |

Other interesting test cases in the [Silver repository](https://github.com/viperproject/silver/tree/master/src/test/resources) during the development of `MagicWandSnapFunctions` were:
* [wands/examples_paper/conditionals.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/examples_paper/conditionals.vpr)
* [wands/new_syntax/QPFields.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/new_syntax/QPFields.vpr)
* [wands/new_syntax/QPPredicates.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/new_syntax/QPPredicates.vpr)
* [wands/new_syntax/QPWands.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/new_syntax/QPWands.vpr)
* [wands/new_syntax/SnapshotsNestedMagicWands.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/new_syntax/SnapshotsNestedMagicWands.vpr)
* [wands/regression/conditionals2.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/regression/conditionals2.vpr)
* [wands/regression/issue024.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/regression/issue024.vpr)
* [wands/regression/issue029.vpr](https://github.com/viperproject/silver/tree/master/src/test/resources/wands/regression/issue029.vpr)
16 changes: 16 additions & 0 deletions src/test/resources/wands/mwsf/applying-twice-bool.vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
field b: Bool

method test06(x: Ref) {
inhale acc(x.b)

package acc(x.b) --* true

x.b := true
assert applying (acc(x.b) --* true) in true

x.b := false
assert applying (acc(x.b) --* true) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}
49 changes: 49 additions & 0 deletions src/test/resources/wands/mwsf/applying-twice-qp-fields.vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
field f: Int

// based on test7 in QPFields.vpr
method test14a(x: Ref)
requires forall y: Ref :: true ==> acc(y.f)
{
package (forall y: Ref :: true ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))

x.f := 0
assert applying ((forall y: Ref :: true ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))) in true
x.f := 1
assert applying ((forall y: Ref :: true ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

// based on test9 in QPFields.vpr
method test14b(x: Ref)
requires forall y: Ref :: true ==> acc(y.f)
{
package (forall y: Ref :: true ==> acc(y.f)) --* acc(x.f)

x.f := 0
assert applying ((forall y: Ref :: true ==> acc(y.f)) --* acc(x.f)) in true
x.f := 1
assert applying ((forall y: Ref :: true ==> acc(y.f)) --* acc(x.f)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

// based on test11 in QPFields.vpr
method test14c(x: Ref, z: Ref)
requires acc(x.f) && z != x
{
package (forall y: Ref :: y != x ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))
inhale forall y: Ref :: y != x ==> acc(y.f)

assert acc(z.f)

z.f := 0
assert applying ((forall y: Ref :: y != x ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))) in true
z.f := 1
assert applying ((forall y: Ref :: y != x ==> acc(y.f)) --* (forall y: Ref :: true ==> acc(y.f))) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}
73 changes: 73 additions & 0 deletions src/test/resources/wands/mwsf/applying-twice-qp-predicates.vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
field f: Int

predicate Cell(x: Ref) {
acc(x.f)
}

function get(x: Ref): Int
requires acc(Cell(x), 1/2)
{
unfolding acc(Cell(x), 1/2) in x.f
}

// based on test7 in QPPredicates.vpr
method test14d(x: Ref)
requires forall y: Ref :: true ==> Cell(y)
{
package (forall y: Ref :: true ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))

unfold Cell(x)
x.f := 0
fold Cell(x)
assert applying ((forall y: Ref :: true ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))) in true

unfold Cell(x)
x.f := 1
fold Cell(x)
assert applying ((forall y: Ref :: true ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

// based on test9 in QPPredicates.vpr
method test14e(x: Ref)
requires forall y: Ref :: true ==> Cell(y)
{
package (forall y: Ref :: true ==> Cell(y)) --* Cell(x)

unfold Cell(x)
x.f := 0
fold Cell(x)
assert applying ((forall y: Ref :: true ==> Cell(y)) --* Cell(x)) in true

unfold Cell(x)
x.f := 1
fold Cell(x)
assert applying ((forall y: Ref :: true ==> Cell(y)) --* Cell(x)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

// based on test11 in QPPredicates.vpr
method test14f(x: Ref, z: Ref)
requires Cell(x)
requires x != z
{
package (forall y: Ref :: y != x ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))
inhale forall y: Ref :: y != x ==> Cell(y)

unfold Cell(z)
z.f := 0
fold Cell(z)
assert applying ((forall y: Ref :: y != x ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))) in true

unfold Cell(z)
z.f := 1
fold Cell(z)
assert applying ((forall y: Ref :: y != x ==> Cell(y)) --* (forall y: Ref :: true ==> Cell(y))) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}
85 changes: 85 additions & 0 deletions src/test/resources/wands/mwsf/applying-twice-quantified-lhs.vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
field f: Int

method test13a(xs: Seq[Ref])
requires forall x: Ref :: x in xs ==> acc(x.f)
requires |xs| >= 1
{
xs[0].f := 0
var some: Ref := xs[0]

package (forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)

some.f := 1
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)) in true

some.f := 2
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

method test13b(xs: Seq[Ref])
requires forall x: Ref :: x in xs ==> acc(x.f)
requires |xs| >= 1
{
xs[0].f := 0
var some: Ref := xs[0]

package (forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)

some.f := 1
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)) in true

some.f := 2
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) --* acc(some.f)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false

var completed: Seq[Ref] := Seq(some)
assert forall z: Ref :: z in completed ==> (forall x: Ref :: x in xs ==> acc(x.f)) --* acc(z.f)
}

method test13c(xs: Seq[Ref], y: Ref)
requires forall x: Ref :: x in xs ==> acc(x.f)
requires |xs| >= 1
requires acc(y.f)
{
xs[0].f := 0
var some: Ref := xs[0]

package (forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)

some.f := 1
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)) in true

some.f := 2
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false
}

method test13d(xs: Seq[Ref], y: Ref)
requires forall x: Ref :: x in xs ==> acc(x.f)
requires |xs| >= 1
requires acc(y.f)
{
xs[0].f := 0
var some: Ref := xs[0]

package (forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)

some.f := 1
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)) in true

some.f := 2
assert applying ((forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(some.f) && acc(y.f)) in true

//:: ExpectedOutput(assert.failed:assertion.false)
assert false

var completed: Seq[Ref] := Seq(some)
assert forall z: Ref :: z in completed ==> (forall x: Ref :: x in xs ==> acc(x.f)) && acc(y.f) --* acc(z.f) && acc(y.f)
}
Loading
Loading