Пример Frama-C acsl max из руководства не работает
Я считаю, что мне не хватает чего-то очевидного, но я много пытался, и мне не удалось найти источник проблемы.
Я слежу за руководством по acsl от Frama-C. Вот вводный пример того, как проверить правильность нахождения максимального значения в массиве:
/*@ requires n > 0;
requires \valid(p+ (0 .. n-1));
ensures \forall int i; 0 <= i <= n-1 ==> \result >= p[i];
ensures \exists int e; 0 <= e <= n-1 && \result == p[e];
*/
int max_seq(int* p, int n) {
int res = *p;
for(int i = 0; i < n; i++) {
if (res < *p) { res = *p; }
p++;
}
return res;
}
Однако бег frama-c -wp -wp-prover alt-ergo samenum.c -then -report
Я получил:
[wp] Warning: Missing RTE guards
[wp] samenum.c:8: Warning: Missing assigns clause (assigns 'everything' instead)
[wp] 2 goals scheduled
[wp] [Alt-Ergo] Goal typed_max_seq_ensures_2 : Timeout (Qed:1ms) (10s)
[wp] [Alt-Ergo] Goal typed_max_seq_ensures : Timeout (Qed:2ms) (10s)
[wp] Proved goals: 0 / 2
Alt-Ergo: 0 (interrupted: 2)
[report] Computing properties status...
--------------------------------------------------------------------------------
--- Properties of Function 'max_seq'
--------------------------------------------------------------------------------
[ - ] Post-condition (file samenum.c, line 3)
tried with Wp.typed.
[ - ] Post-condition (file samenum.c, line 4)
tried with Wp.typed.
[ - ] Default behavior
tried with Frama-C kernel.
Похоже, что время ожидания alt-ergo истекает перед доказательством собственности. Чего стоит, я пробовал с большим тайм-аутом, но он все равно не работает.
Я использую:
- frama-c: 19,1
- почему3: 1.2.0
- альт-эрго: 2.3.2
Я запускаю это в Ubuntu 18.04 и перед запуском команды, которую я запускаю: why3 config --detect
чтобы убедиться, что why3 знает об alt-ergo.
Есть идеи? Может ли кто-нибудь проверить, что этот пример не работает? Любая помощь будет принята с благодарностью!
2 ответа
Это мини-руководство было написано довольно давно и не актуально. Новая версия сайта должна появиться в ближайшие месяцы. По сути, этот контракт, а также инвариант цикла, на который указывает @iguerNL, должны были проверяться с помощью плагина Jessie, а не плагина WP Frama-C. Среди различий между этими двумя плагинами Джесси не нуждалсяassigns
предложения для циклов и функций, в то время как они нужны WP.
Таким образом, полный аннотированный max_seq
функция может быть такой:
/*@ requires n > 0;
requires \valid(p+ (0..n−1));
assigns \nothing;
ensures \forall int i; 0 <= i <= n−1 ==> \result >= p[i];
ensures \exists int e; 0 <= e <= n−1 && \result == p[e];
*/
int max_seq(int* p, int n) {
int res = *p;
//@ ghost int e = 0;
/*@ loop invariant \forall integer j; 0 <= j < i ==> res >= \at(p[j],Pre);
loop invariant \valid(\at(p,Pre)+e) && \at(p,Pre)[e] == res;
loop invariant 0<=i<=n;
loop invariant p==\at(p,Pre)+i;
loop invariant 0<=e<n;
loop assigns i, res, p, e;
loop variant n-i;
*/
for(int i = 0; i < n; i++) {
if (res < *p) {
res = *p;
//@ ghost e = i;
}
p++;
}
return res;
}
где мы указываем, что функции ничего не назначают в памяти и что цикл назначает различные локальные переменные i
, res
, p
а также e
(таким образом оставляя n
без изменений).
Обратите внимание, что доступны более свежие учебные пособия, чтобы узнать об использовании Frama-C с плагином WP. В будущей версии сайта Frama-C упоминается:
Вы, наверное, забыли добавить инварианты для цикла for. См. Раздел "10.2 Инварианты цикла" в предоставленном вами руководстве ( https://frama-c.com/acsl_tutorial_index.html)