3

I am writing a partition method in Dafny as part of a quicksort implementation, and I want to specify that this method only modifies part of the backing array.

Here is the header for my method:

method partitionSegment (a : array<int>, first : int, len : int) returns (p : int)
  modifies a
...

The idea is that the first and len parameters specify a segment of array a (elements a[first] ... a[first+len-1]); partitionSegment partitions this array, returning the index of the pivot, which will be between first and first+len-1.

In my modifies clause I would like to indicate that only a[first] ... a[first+len-1] can be modified, rather than all of a. However, when I try using a set comprehension such as:

method partitionSegment (a : array<int>, first : int, len : int) returns (p : int)
modifies (set x | first <= x < first+len :: a[x])

the type checker balks, saying this is a set of integers rather than a set of memory locations. (So a[x] is being interpreted as the value stored at a[x], and not the memory location a[x].)

Is there any way I can do this in dafny: specify part of an array in a modifies annotation?

1 Answers1

3

The best way to do this is to keep the modifies clause as modifies a and then add a postcondition that uses old to guarantee that only the intended parts of a change.

Something like this:

ensures forall i | 0 <= i < a.Length :: 
    !(first <= i < first + len) ==> a[i] == old(a[i])

In other words, this says that all indices outside the intended range are equal to their values from before the method executed.

In general, you should think of Dafny's modifies clauses as being relatively coarse-grained. They typically constrain which objects can be modified, not which parts of those objects. If you want to specify that some fields of an object don't change, then you can do that with a postcondition like foo.f == old(foo.f).

James Wilcox
  • 5,307
  • 16
  • 25
  • 1
    Thanks, this is helpful. I was hoping to avoid adding a postcondition, but now that I know I need to I can "move on" to other parts of the coding. – Rance Cleaveland Mar 31 '18 at 17:15