JML удалить предупреждение после вызова функции
Мне дали задание, в котором я должен удалить все предупреждения, созданные JML.
Если я вызываю метод внутри конструктора, my и больше не проверяются, несмотря на добавление того же ограничения для вызываемой функции.
Меня просят использовать только
requires
,
ensures
,
invariant
а также
loop_invariant
.
Вот код:
/*@ non_null @*/ int[] elements;
int n;
//@ invariant n >= 0;
//@ requires input != null;
//@ requires input.length >= 0;
//@ ensures elements != null;
Class(int[] input) {
n = input.length;
elements = new int[n];
arraycopy(input, 0, elements, 0, n);
//@ assert n >= 0;
}
//@ requires srcOff >= 0;
//@ requires destOff >= 0;
//@ requires length >= 0;
//@ requires dest.length >= destOff + length;
//@ requires src.length >= srcOff + length;
//@ ensures dest.length == \old(dest.length);
//@ ensures length == \old(length) ==> length >= 0;
//@ ensures dest != null;
private static void arraycopy(/*@ non_null @*/ int[] src,
int srcOff,
/*@ non_null @*/ int[] dest,
int destOff,
int length) {
//@ loop_invariant destOff+i >= 0;
//@ loop_invariant srcOff+i >= 0;
//@ loop_invariant length >= 0;
for(int i=0 ; i<length; i=i+1) {
dest[destOff+i] = src[srcOff+i];
}
}
И произведенный вывод:
Class.java:25: warning: The prover cannot establish an assertion (NullField) in method Class
/*@ non_null @*/ int[] elements;
^
Class.java:32: warning: The prover cannot establish an assertion (InvariantExit: MultiSet.java:27: ) in method Class
Class(int[] input) {
^
Class.java:27: warning: Associated declaration: Class.java:32:
//@ invariant n >= 0;
^
3 warnings
Одно из решений состоит в том, чтобы сделать функцию
arraycopy
нестатический, но я не могу понять, почему.
1 ответ
Доказывающая сторона не может установить, изменяются ли переменные класса, поскольку функция имеет видимость более
n
а также . Таким образом, ему нужна аннотация, например
//@ ensures n == \old(n)
//@ ensures elements == \old(elements)
Это проблема по двум причинам:
- В Java статический метод не может получить доступ к значению нестатической переменной, следовательно, следующие спецификации не могут быть подтверждены JML (показывая ограничение инструмента).
// ...
//@ ensures n == \old(n)
//@ ensures elements == \old(elements)
private static void arraycopy( /* ... */ ) {
- Секунда
ensures
может вызвать некоторые проблемы с предоставлениемelements
в качествеsrc
аргумент за .
Чтобы избежать модификации сигнатуры функции, вам необходимо добавить
assume
спецификация после каждого
arraycopy
вызов функции.