Как доказать простые равенства недетерминированных значений в Frama-C + EVA?
Меня немного смущает поведение Frama-C версии 18.0 (Argon).
Учитывая следующую программу:
#include <assert.h>
#include <limits.h>
/*@ requires order: min <= max;
assigns \result \from min, max;
ensures result_bounded: min <= \result <= max ;
*/
extern int Frama_C_interval(int min, int max);
int main() {
int i,j;
i = Frama_C_interval(INT_MIN, INT_MAX);
j = i;
assert(j == i);
return 0;
}
Я ожидал бы, что утверждение будет доказано довольно легко с любой из абстрактных областей, которые отслеживают равенство. Тем не менее, ссылаясь
frama-c -eva -eva-равенство-домен -eva-полька-равенства foo.c
дает:
[eva] Warning: The Apron domains binding is experimental.
[kernel] Parsing stupid_test.c (with preprocessing)
[eva] Analyzing a complete application starting at main
[eva] Computing initial state
[eva] Initial state computed
[eva:initial-state] Values of globals at initialization
[eva] using specification for function Frama_C_interval
[eva] using specification for function __FC_assert
[eva:alarm] foo.c:20: Warning:
function __FC_assert: precondition 'nonnull_c' got status unknown.
[eva] done for function main
[eva] ====== VALUES COMPUTED ======
[eva:final-states] Values at end of function main:
i ∈ [--..--]
j ∈ [--..--]
__retres ∈ {0}
Я что-то пропустил?
2 ответа
Интересно. Ваш пример не обработан -eva -eva-equality-domain
, который был написан с другими целями. Таким образом, особый случай для x == y
когда x
а также y
Как известно, равных не было написано. Это было бы довольно легко добавить.
(Учитывая имя домена, это может показаться удивительным. Домен равенства больше ориентирован на более широкое распространение в обратном направлении, когда у нас есть неинтересные псевдонимы, например, временные ссылки, добавленные ядром.)
Что касается доменов, поступающих из Apron, это более удивительно. Я изменил ваш пример как таковой:
j = i;
int b = j - i;
int c = j == i;
Frama_C_dump_each_domain();
Бег frama-c -eva -eva-polka-equalities foo.c -value-msg-key d-apron
дает следующий результат:
[eva] c/eq.c:23:
Frama_C_dump_each_domain:
# Cvalue domain:
i ∈ [--..--]
j ∈ [--..--]
b ∈ {0}
c ∈ {0; 1}
__retres ∈ UNINITIALIZED
# Polka linear equalities domain:
[|-i_44+j_45=0; b_46=0|]
Как вы можете видеть, Фартук предположил связь между i
а также j
(суффикс - номер строки), упрощенный b
до 0, но не упростил c
1. Это удивительно для меня, но объясняет неточность, которую вы наблюдали. Он также не работает с доменом восьмиугольников.
Я не очень знаком с абстрактными преобразователями в реляционных областях, так что этого можно ожидать, но это, безусловно, озадачивает. Код для обработки реляционных операторов существует во Frama-C/Eva/Apron, но частично написан на дому (это не просто вызов примитива Apron). В частности, он вызывает оператор для вычитания и анализирует равенство результата с 0. Трудно понять, почему b
было бы точно, но не c
,
Обновление: в более поздних версиях Frama-C (я пробовал с Frama-C 25.0, но он, безусловно, будет работать и в некоторых более старых версиях), домен восьмиугольника может обрабатывать этот конкретный случай:-eva -eva-domains octagon
достаточно, в вашем конкретном коде, чтобы избежать тревоги.
Также обратите внимание, что восьмиугольный домен можно косвенно включить с помощью опции-eva-precision 5
(или выше).