Giter Site home page Giter Site logo

Comments (5)

robin-aws avatar robin-aws commented on August 17, 2024

It looks like Dafny no longer allows quantifying over such possibly-heap types: trying this on the latest commit yields an error on the second line:

a quantifier involved in a predicate definition is not allowed to depend on the set of allocated references; Dafny's heuristics can't figure out a bound for the values of 'x' (perhaps declare its type, 'T', as 'T(!new)')

Removing this line and the assert statement referencing it inside M3 does still allow the last assert to successfully verify, however.

from dafny.

RustanLeino avatar RustanLeino commented on August 17, 2024

Here are some further, related test cases:

class Basic {
  var data: int
}

class Cell {
  const x: int
  var y: int
  constructor (x: int, y: int)
    decreases if x == y == 0 then 0 else 1
  {
    this.x, this.y := x, y;
    if !(x == y == 0) {
      var anotherCell := new Cell(0, 0);
    }
  }
}

method P0()
  requires forall c: Basic :: c.data == 8
{
  var o := new Basic;
  o.data := 8;
  assert forall c: Basic :: c.data == 8;  // fine
}

method P1()
  requires forall c: Basic :: c.data == 8
{
  var o := new Basic;
  assert forall c: Basic :: c.data == 8;  // BOGUS: this should not verify -- may not hold for o
}

method Q()
  requires forall c: Basic :: c.data == 8
{
  var o := new object;
  assert forall c: Basic :: c.data == 8;  // BOGUS: this ought not verify (well, it could, but only if o is known not to be a Basic)
}

method M0()
  requires forall c: Cell :: c.x == 8
{
  var o := new Cell(7, 8);
  assert forall c: Cell :: c.x == 8;  // BOGUS: this should not verify -- does not hold for o (or for anotherCell)
}

method M1()
  requires forall c: Cell :: c.x == 8
{
  var o := new Cell(8, 8);
  assert forall c: Cell :: c.x == 8;  // BOGUS: this should not verify -- does not hold for anotherCell
}

method N0()
  requires forall c: Cell :: c.y == 8
{
  var o := new Cell(8, 7);
  assert forall c: Cell :: c.y == 8;  // error: does not hold for o (or for anotherCell)
}

method N1()
  requires forall c: Cell :: c.y == 8
{
  var o := new Cell(8, 8);
  assert forall c: Cell :: c.y == 8;  // error: does not hold for anotherCell
}

from dafny.

jtristan avatar jtristan commented on August 17, 2024

A note, mostly for myself: when we fix this, we need to make sure that the following still checks out:

method P1'()
  requires forall c: Basic :: c.data == 8
{
  var o := new Basic;
  assert forall c: Basic :: c != o ==> c.data == 8;  
}

from dafny.

MikaelMayer avatar MikaelMayer commented on August 17, 2024

I just had a look at the examples for quantifying, and I found a way to prove false, which summarizes well the challenge.

class Cell {
  const x: int
  constructor (x: int) ensures this.x == x {
    this.x := x;
  }
}

method M0()
  requires forall c: Cell :: c.x == 8
{
  var o := new Cell(7);
  assert false;
}

Looking at the generated boogie code, I see that the precondition is encoded as:

requires (forall c#1: ref :: 
    { _module.Cell.x(c#1) } 
    $Is(c#1, Tclass._module.Cell()) ==> _module.Cell.x(c#1) == LitInt(8));

This is wrong, because it does not depend on the heap at all.
The axiom should say that it's not true for all references, it's true for all the references that have already been allocated.

requires (forall c#1: ref  :: 
    { _module.Cell.x(c#1) } 
    $Is(c#1, Tclass._module.Cell()) && read($Heap, c#1, alloc) ==> _module.Cell.x(c#1) == LitInt(8));

Of @RustanLeino 's example, as of today, only P1, Q, M0, and M1 are problematic, the others are correctly handled.
However, fixing the axiom above would exactly fix P1, Q, M0 and M1.
And even if N0 and N1 could be proved, the fix above would still prevent them to verify.

from dafny.

MikaelMayer avatar MikaelMayer commented on August 17, 2024

One problem with the fix above is that, even if we replace 7 with 8, we still cannot prove anymore forall c: Cell :: c.x == 8 after the constructor. This is because we only know that what was allocated before is still allocated afterwards, but we don't know what new references were allocated in the heap.

Fortunately, we can fix that as usual by encoding it in the pre and post condition of the constructor (since, the constructor might allocate new references, it has to check locally that the predicate holds), but there is one caveat.)

class Cell {
  const x: int
  constructor (x: int)
    requires forall c: Cell :: c.x == 8
    decreases if x == 0 then 0 else 1
    ensures this.x == x
    ensures forall c: Cell :: c.x == 8 // Error, cannot prove this, unless we require x == 8 !
    {
      this.x := x;
      if !(x == 0) {
        var anotherCell := new Cell(0); // And if we require x =8, this fails. Yay!
      }
  }
}

method M0()
  requires forall c: Cell :: c.x == 8
{
  var o := new Cell(8);
  assert forall c: Cell :: c.x == 8;
}

from dafny.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.