Last active
June 2, 2023 15:12
-
-
Save samuelgruetter/83c57a7146b9c7e0fb31ea1fe1fd6bf7 to your computer and use it in GitHub Desktop.
`modifies` clauses in Dafny
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
class A { | |
var n: nat | |
ghost var Repr: set<object> | |
predicate Valid() | |
reads this, Repr | |
{ | |
this in Repr && | |
n % 2 == 0 | |
} | |
constructor() | |
ensures Valid() | |
ensures fresh(Repr - {this}) | |
{ | |
this.n := 0; | |
this.Repr := {this}; | |
} | |
method update() | |
requires Valid() | |
modifies this | |
ensures Valid() | |
ensures Repr == old(Repr) | |
// more general: ensures fresh(Repr - old(Repr)) | |
{ | |
this.n := this.n + 2; | |
} | |
} | |
class B { | |
var a1: A | |
var a2: A | |
ghost var Repr: set<object> | |
predicate Valid() | |
reads this, Repr | |
{ | |
this in Repr && a1 in Repr && a2 in Repr && a1.Repr <= Repr && a2.Repr <= Repr && | |
this !in a1.Repr && this !in a2.Repr && | |
//a1.Repr !! a2.Repr && // <-- needed? | |
a1.Valid() && a2.Valid() | |
} | |
constructor(a1: A, a2: A) | |
requires a1.Valid() && a2.Valid() | |
ensures Valid() | |
ensures fresh(Repr - {this} - a1.Repr - a2.Repr) | |
{ | |
this.a1 := a1; | |
this.a2 := a2; | |
this.Repr := {this} + a1.Repr + a2.Repr; | |
} | |
method update() | |
requires Valid() | |
modifies Repr | |
ensures Valid() | |
ensures Repr == old(Repr) | |
// more general: ensures fresh(Repr - old(Repr)) | |
{ | |
this.a1.update(); | |
this.a2.update(); | |
} | |
} | |
class C { | |
var bs: seq<B> | |
ghost var Repr: set<object> | |
predicate Valid() | |
reads this, Repr | |
{ | |
this in Repr && | |
(forall i :: 0 <= i < |bs| ==> | |
bs[i] in Repr && bs[i].Repr <= Repr && this !in bs[i].Repr && bs[i].Valid()) && | |
(forall i, j :: 0 <= i < j < |bs| ==> | |
bs[i] in Repr && bs[j] in Repr && | |
bs[i].Repr !! bs[j].Repr) | |
} | |
method update() | |
requires Valid() | |
modifies Repr | |
ensures Valid() | |
ensures Repr == old(Repr) | |
// more general: ensures fresh(Repr - old(Repr)) | |
{ | |
var i := 0; | |
while (i < |bs|) | |
invariant Valid() | |
invariant 0 <= i <= |bs| | |
invariant Repr == old(Repr) // <-- without this, bs[i].update() might violate context's modifes clause | |
decreases |bs| - i | |
{ | |
bs[i].update(); | |
i := i + 1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment