-
Notifications
You must be signed in to change notification settings - Fork 41
Open
Labels
Milestone
Description
Description
When using a ghost variable in a loop, KeY assumes it will always have the initial value (value before the loop is executed).
Reproducible
always
Steps to reproduce
File SetGhost.java:
import java.util.List;
public class SetGhost {
/*@ public normal_behavior
@ requires \invariant_for(l);
@ ensures \result == l.seq.length;
@*/
static int counter(List l) {
int listSize = l.size();
int counter = 0;
//@ ghost int iter;
//@ set iter = 0;
/*@ loop_invariant
@ i >= 0 && i <= listSize && listSize == l.size()
@ && i == counter
@ && iter == counter
@ ;
@ decreases listSize - i;
@ assignable counter,iter;
@*/
for (int i = 0; i < listSize; i++) {
counter++;
//@ set iter = iter + 1;
//@ assert iter == 1;
assert counter == 1;
}
//@ assert iter == counter;
return counter;
}
}- Load
SetGhost.java - Run automode
Expected behavior: the proof does not close, both assertions fail to prove
Actual behavior: proof closes
Reproducer using `\seq` instead of int
In this case, the assertion's validity can be proven, but the loop invariant fails to prove (since KeY thinks values == [l.get(i)] with unknown i).
import java.util.List;
public class SetGhostSeq {
/*@ public normal_behavior
@ requires \invariant_for(l);
@ ensures \result == l.seq.length;
@*/
static int counter(List l) {
int listSize = l.size();
int counter = 0;
//@ ghost \seq values;
//@ set values = \seq_empty;
/*@ loop_invariant
@ i >= 0 && i <= listSize && listSize == l.size()
@ && values == l.seq[0 .. values.length]
@ && i == counter
@ && \invariant_for(l)
@ ;
@ decreases listSize - i;
@ assignable counter,values;
@*/
for (int i = 0; i < listSize; i++) {
// System.out.println("" + counter);
counter++;
Object x = l.get(i);
//@ set values = \seq_concat(values, \seq_singleton(x));
//@ assert values.length == 1;
}
return counter;
}
}Additional information
- Commit: 9d0379c (latest
main)