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

Def assignment update #3311

Merged

Conversation

keyboardDrummer
Copy link
Member

@keyboardDrummer keyboardDrummer commented Jan 3, 2023

Changes

@RustanLeino should havocing a variable of a non-empty type even be allowed?

Testing

  • Havoc assignment to a field count as an assignment
  • Havoc to a local variable counts as an assignment
  • Arrays created with new CLI UI and without --enforce-determinism, don't need to initialise their values or be empty.

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

var x:G, y:G, z:G := a, *, a;
if h < 10 {
k := x; // fine
} else if h < 20 {
k := y; // error: y has not yet been assigned
k := y;
} else {
z := *;
return z; // this is fine, since z was assigned before the havoc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does 'z was assigned before the havoc' matter? It doesn't for 'y', right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment can go

@keyboardDrummer keyboardDrummer merged commit d621db4 into dafny-lang:master Jan 3, 2023
@RustanLeino
Copy link
Collaborator

@RustanLeino should havocing a variable of a non-empty type even be allowed?

(I'm assuming you meant "possibly empty", not "non-empty".)

Since we allow x :| true; where the type of x is possible empty, it makes sense to also allow x := *;.

@keyboardDrummer
Copy link
Member Author

@RustanLeino should havocing a variable of a non-empty type even be allowed?

(I'm assuming you meant "possibly empty", not "non-empty".)

Since we allow x :| true; where the type of x is possible empty, it makes sense to also allow x := *;.

I see :-)

@kjx
Copy link

kjx commented Jan 31, 2023

Don't you effectively define x := *; as x :| true;.

In fact: given you have x :| true; why do you need x := *; as well?

keyboardDrummer added a commit that referenced this pull request Feb 27, 2023
Fixes #3640

This PR fixes some issues with definite assignment and determinacy.

Recently, we changed the default rules for definite assignment in Dafny
(PR #3052). The main change was
to insist that all local variables and out-parameters be definitely
assigned before they are used. This was followed up by PR
#3311, which started considering
`:= *` assignments as fulfilling definite-assignment requirements. PR
#3311 also fixed a point where #3052 had gone too far; with PR #3311, it
is now again possible to allocate an array of an auto-init type without
having to explicitly assign the array elements.

There was one more point where PR #3052 had gone too far (reported in
#3640), and the present PR fixes that point. The issue regards fields of
a class. The present PR once again allows fields to be auto-initialized
(provided their types allow that).

This PR also makes `/definiteAssignment:4` available in the legacy CLI.
(Previously, it had been added internally, but not exposed in the legacy
CLI.)

Finally, this PR reports an error in the `--enforce-determinism` mode
for any class without a `constructor`. This was a latent omission in the
previous checking. Together with once again allowing auto-initialization
of fields, this change puts

``` dafny
class Cell { // constructor-less class not allowed with --enforce-determinism
  var data: int
}
method NondeterministicReturn() returns (r: int) {
  var c := new Cell;
  return c.data;
}
```

on the same footing as

``` dafny
class Cell {
  var data: int
  constructor () { // with --enforce-determinism, this constructor must initialize .data    
  }
}
method NondeterministicReturn() returns (r: int) {
  var c := new Cell();
  return c.data;
}
```

I argue this PR fixes the new definite-assignment mode in an important
way and therefore should be included in Dafny 4.0.

The documentation (see, e.g.,
#3584) may need to be updated.

<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>

---------

Co-authored-by: Remy Willems <rwillems@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants