For an array in Dafny whats the difference between old(a[0]) and old(a)[0] - dafny

For an array in Dafny, what's the difference between old(a[0]) and old(a)[0]?
A method modifies an array 'a' by adding 1 to the first element. At the conclusion of the method, what is the value of old(a[0]) and old(a)[0]?

Good question! Yes, they are different.
When an expression is evaluated inside an old, all of its heap dereferences refer to the heap at the beginning of the method. Anything that is not a heap dereference is not affected at all by old.
In your example a[0] is a heap dereference, so old(a[0]) gets the 0-th value of the array "pointed to" by a in the old heap.
However, a by itself is not a heap dereference, it's just a parameter to the local function whose value never changes. So old(a) == a. One way to think about this is that a stores the "address" of the array, and that address doesn't change over the lifetime of the method.
Now that we know old(a) == a, it follows that old(a)[0] == a[0]. In other words, the old has no effect in your second example.
Here is a small example to demonstrate:
method M(a: array<int>)
requires a.Length >= 2
requires a[0] == 1
modifies a
ensures a[1] == old(a[0]) // so far so good
ensures old(a) == a // perhaps surprising: Dafny proves this!
ensures a[1] == old(a)[0] // but this is not necessarily true,
// because old(a)[0] actually means the same thing as a[0]
{
a[1] := 1;
}

Related

Dafny loop invariant fails even though invariant assertions work. Is this a small bug?

Hi for teaching I am setting up a mass of simple dafny questions. Mostly going fine, but... Either I have missed some detail about loop invariants in Dafny or this is a weakness/bug?
method whS(a:int) returns ()
{ var i:int := 0;
while (i<a )
decreases a-i
invariant i<= a
{ assert i<= a;
i:=i+1;
assert i<= a;
}
}
The method fails to verify with error "invariant might not hold on entry" Yet with the invariant commented out the method verifies even with the assertions.
A good way to remember the answer to the question "when must the loop invariant be true?" in Dafny is "whenever the loop condition would be evaluated".
So the loop invariant needs to be true before the first iteration of the loop, even if the body would never execute, because the loop condition will be evaluated to determine whether to enter the loop at all. The invariant also needs to be true after the last iteration, because again, the loop condition will be evaluated to determine whether to execute another iteration.
In your example, if the argument a to the method is negative, then the loop invariant is false before the first time the loop condition is evaluated. An example of an invariant that would work for this loop would be something like a >= 0 ==> i <= a.
many thanks James
I can see that I misunderstood how dafny implemented loop invariants. Wrapping the while in an if statement now verifies and gives me the semantics that I thought while on its own had.
method whS(a:int) returns ()
{ var i:int := 0;
if (i<a) {
while (i<a )
decreases a-i
invariant i<= a
{ i:=i+1;
}
}
}
Thanks again james . I will avoid this mistake when I give my lecture on Tuesday.

Comparing Julia variable to `nothing` using !== or !=

In some Julia code when can see conditional expression such as
if val !== nothing
dosomething()
end
where val is a variable of type Union{Int,Nothing}
What is the difference between conditons val !== nothing and val != nothing?
First of all, it is generally advisable to use isnothing to compare if something is nothing. This particular function is efficient, as it is soley based on types (#edit isnothing(nothing)):
isnothing(::Any) = false
isnothing(::Nothing) = true
(Note that nothing is the only instance of the type Nothing.)
In regards to your question, the difference between === and == (and equally !== and !=) is that the former checks whether two things are identical whereas the latter checks for equality. To illustrate this difference, consider the following example:
julia> 1 == 1.0 # equal
true
julia> 1 === 1.0 # but not identical
false
Note that the former one is an integer whereas the latter one is a floating point number.
What does it mean for two things to be identical? We can consult the documentation of the comparison operators (?===):
help?> ===
search: === == !==
===(x,y) -> Bool
≡(x,y) -> Bool
Determine whether x and y are identical, in the sense that no program could distinguish them. First the types
of x and y are compared. If those are identical, mutable objects are compared by address in memory and
immutable objects (such as numbers) are compared by contents at the bit level. This function is sometimes
called "egal". It always returns a Bool value.
Sometimes, comparing with === is faster than comparing with == because the latter might involve a type conversion.

Modifying method parameters

Is it possible to annotate Dafny method parameters as mutable, without them being objects?
My goal is to be able to verify
method testMethod(a:int, b:int) returns (res :int) {
res :=0;
a := (a - b);
assert a < (a-b);
}
Ignoring the fact this is obviously an absurd assertion, Dafny complains about the LHS not being a mutable variable, while I'd like to avoid introducing temporary variables.
All in-parameters in Dafny are immutable (including in-parameters of reference types, though with an appropriate modifies clause a method can make modifications in the heap by dereferencing such a parameter). So, you need to use a local variable to store the expression a - b in your example. For example:
method testMethod(a:int, b:int) returns (res:int) {
res := 0;
var myLocalA := a - b;
assert myLocalA < myLocalA - b;
}
If you are bothered by having to introduce a new name for the local variable, Dafny actually allows you to give a local variable the same name as an in-parameter. If you find that to be in your style, you can write:
method testMethod(a:int, b:int) returns (res:int) {
res := 0;
var a := a - b;
assert a < a - b;
}
Note that the right-hand side of the assignment to the local variable a mentions the in-parameter a (because the local variable a is not quite yet in scope at that time).
If you do this a lot, you can also start your method off with a statement
var a := a;
This looks ridiculous and may be confusing until you realize what's going on, namely that this statement introduces a local variable a and assigns its initial value the value of the in-parameter a.
The reason for not automatically allowing in-parameters to be used as local variables (which is allowed by many other languages, including C and Java) is that, in my experience, some people then get confused about the meaning of in-parameters in postconditions. An in-parameter mentioned in a postcondition refers to the value of the in-parameter passed in by the caller, and this is made clear by making in-parameters immutable inside the method body.
Rustan

Sorted post-condition doesn't hold

What I want to do in the method is simply to overwrite the previous array and fill it with number that are sorted, however dafny says that the post-condition does not hold and I can't for the life of me figure out why.
I'm guessing I need to add some invariant to the loop but since they are checked before entering the loop I don't know how to put a valid invariant.
method sort2(a : array<int>)
modifies a;
requires a != null && a.Length >= 2;
ensures sorted2(a[..]);
{
var i := a.Length - 1;
while (i >= 0)
decreases i
{
a[i] := i;
i := i - 1;
}
}
predicate sorted2(s: seq<int>)
{
forall i :: 1 <= i < |s| ==> s[i] >= s[i-1]
}
My previous attempt was just to reinitialize a but dafny apparently doesn't allow that inside methods.
You do need a loop invariant in order to prove this program correct.
See Section 6 of the Dafny Tutorial for a general introduction to loop invariants and how to come up with them.
In this case, a good loop invariant will be something like sorted(a[i+1..]), which says that the part of the array after index i is sorted. That way, when the loop terminates and i is zero, you'll know that the whole array is sorted.
You will also need one or two more loop invariants describing bounds on i and the elements of the array itself.

Might Lua's length operator return a negative index?

The, well, special specification of Lua's length operator made me wonder whether Lua would be "allowed" to return a negative value in a situation like
#{[-5]=1,[-1]=3}
It says:
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil;
n=-5 and n=-1 would meet this criterion in my example, right?
moreover, if t[1] is nil, n can be zero.
Right, it can be zero, but it's not guaranteed, right?
For a regular array, with non-nil values from 1 to a given n, its length is exactly that n, the index of its last value.
This isn't the case here, so it doesn't apply.
If the array has "holes" (that is, nil values between other non-nil values), then #t can be any of the indices that directly precedes a nil value (that is, it may consider any such nil value as the end of the array).
This is the case here, so again, n=-5 and n=-1 would be valid return values, right?
Can I be entirely certain that Lua always returns 0 for the example table, or any other table containing only negative indices? If (hypothetically) I'd be writing a Lua interpreter and would return either of those values, would I be conforming with the specifications?
Edit
Obviously, the way Lua is implemented, it does not return negative values. I felt the length operator is somewhat underdocumented and I see that Lua 5.2's documentation has changed. It now says:
Unless a __len metamethod is given, the length of a table t is only defined if the table is a sequence, that is, the set of its positive numeric keys is equal to {1..n} for some integer n. In that case, n is its length. Note that a table like
{10, 20, nil, 40}
is not a sequence, because it has the key 4 but does not have the key 3.
So, it now talks about positive numeric keys, that's much clearer. I'm left wiser but not totally happy with the documentation. When it says the "length is only defined if the table is a sequence", it should also state that even if the table is not a sequence a value is returned, but the behavior is undefined. Also, this table looks pretty much like a sequence:
a = setmetatable(
{0},
{
__index = function(t,k)
return k < 10 and k or nil
end
}
)
i = 1
while a[i] do
print(a[i])
i = i+1
end
--[[ prints:
0
2
3
4
5
6
7
8
9
]]
print(#a)
-- prints: 1
However, this is becoming nitpicking as it's pretty clear that it wouldn't make sense to take into account what mess __index might make. And Stackoverflow is certainly not the place to complain about documentation that could be more precise.
As you have noted, the specification of the length operator has changed between 5.1 and 5.2.
Can I be entirely certain that Lua always returns 0 for the example table, or any other table containing only negative indices?
You can for the current reference implementation, which ensures that for ilen defined
function ilen (xs)
local i=0
while xs[i+1] do i=i+1 end
return i
end
we always have #xs >= ilen(xs) - see the definition of luaH_getn in the ltable.c source. But the specification now deliberately does not promise this behaviour: a conformant implementation can return nil or raise an exception for attempts to find the length of tables that are not sequences.
From the text in reference link. The answer is NO.
I think your confusing the fact that if a NIL is found then the length of the table is deemed to be position the NIL was found -1.
Therefore if t(1) is NIL then 1 - 1 = 0 so the table length is 0.
If the length of a table was 5 then the next position or t(6) IS or WOULD BE NIL
The length of a table t is defined to be any integer index n such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil, n can be zero.

Resources