Почему WP не может вывести «еще» близко?
Я пытаюсь написать спецификацию для функции, которая принимает 2 указателя на int и присваивает меньшее значение первому указателю, а другое — второму.
Вот код и спецификация:
/*@
requires \valid(a) && \valid(b);
assigns *a, *b;
ensures *a > *b ==> *a == \old(*b) && *b == \old(*a);
ensures *a <= *b ==> *a == \old(*a) && *b == \old(*b);
*/
void order(int * a, int *b) {
if (*a > *b) {
int tmp = *a;
*a = *b;
*b = *a;
}
}
И вот вывод
frama-c -wp so.c
:
[kernel] Parsing so.c (with preprocessing)
[wp] Warning: Missing RTE guards
[wp] 4 goals scheduled
[wp] [Alt-Ergo] Goal typed_order_post_2 : Unknown (Qed:4ms) (366ms)
[wp] Proved goals: 3 / 4
Qed: 2 (0.40ms-2ms-5ms)
Alt-Ergo: 1 (30ms) (16) (unknown: 1)
WP не может доказать второе пост-условие, можете ли вы объяснить мне, почему?
1 ответ
Оказывается, решение моего вопроса находится в учебнике Алена Бланшара, $3.3.1.1. ( здесь )
В пост-условиях мне не хватает примитивов вокруг
*a
а также
*b
. Итак, условия должны гласить:
ensures \old(*a) < \old(*b) ==> *a == \old(*b) && *b == \old(*a) ;
ensures \old(*a) >= \old(*b) ==> *a == \old(*a) && *b == \old(*b) ;
Без
\old
, левые части импликаций относятся к значениям после выполнения функции.