2015-07-20 8 views
2

Предположим, мы имеем следующий C аннотированный код:Доказывающий выходы SMT «неизвестно», несмотря на сильные доказанными утверждения

#define L 3 
int a[L] = {0}; 
/*@ requires \valid(a+(0..(L - 1))); 
    ensures \forall int j; 0 <= j < L ==> (a[j] == j); */ 
int main() { 
     int i = 0; 
     /*@ loop assigns i, a[0..(i-1)]; 
      loop invariant inv1: 0 <= i <= L; 
      loop invariant inv2: 
         \forall int k; 0 <= k < i ==> a[k] == k; 
     */ 
     while (i < L) { 
      a[i] = i; 
      i++; 
     } 
     /*@ assert final_progress: 
       \forall int k; 0 < k < L ==> a[k] == a[k-1] + 1; 
      assert final_c: 
       a[2] == a[1] - 1; */ 
     return 0; 
} 

Почему Alt-Ergo/Z3 дает «неизвестно» или тайм-ауты для final_c утверждения, несмотря на то, что final_progress заявление было доказано? Мне бы очень хотелось увидеть «Недействительно» для таких явно (с точки зрения пользователя) недопустимых утверждений.

$ frama-c -wp -wp-rte -wp-prover z3 test2.c 
.. 
[wp] [z3] Goal typed_main_assert_final_c : Unknown (455ms) 

$ frama-c -wp -wp-rte -wp-prover alt-ergo test2.c 
.. 
[wp] [Alt-Ergo] Goal typed_main_assert_final_c : Timeout 

ответ

1

В БК плагин не поддерживает маркировки свойства (предварительные условия, постусловия, пользовательские утверждения) недействительными. Как указано в разделе 2.2 WP plugin manual статус является одним из:

  1. never tried icon — Нет доказательств попытки.
  2. unknown icon — Недвижимость не подтверждена.

    Этот статус означает, что доказательства не удалось найти. Возможно, это связано с тем, что свойство действительно недействительно.

  3. valid under hypothesis icon — Недвижимость действительна, но имеет зависимости.

    Вы увидите, что этот статус применяется к свойству, если плагин WP способен доказать свойство, предполагающее, что одно или несколько свойств полностью действительны.

  4. surely valid icon — Собственность и все ее зависимости полностью действительны.

Хотя WP плагин не поддерживает маркировки свойства как недействительный, вы можете использовать трюк отстаивания \false в конце функции:

#define L 3 
int a[L] = {0}; 
/*@ requires \valid(a+(0..(L - 1))); 
    ensures \forall int j; 0 <= j < L ==> (a[j] == j); */ 
int main() 
{ 
    int i = 0; 
    /*@ loop assigns i, a[0..(i-1)]; 
     loop invariant inv1: 0 <= i <= L; 
     loop invariant inv2: \forall int k; 0 <= k < i ==> a[k] == k; 
    */ 
    while (i < L) { 
     a[i] = i; 
     i++; 
    } 
    //@ assert final_progress: \forall int k; 0 < k < L ==> a[k] == a[k-1] + 1; 
    //@ assert final_c: a[2] == a[1] - 1; 
    //@ assert false: \false; 
    return 0; 
} 

Запуск WP плагин этого кода приводит :

 
... 
[wp] [Alt-Ergo] Goal typed_main_assert_false : Valid (114ms) (97) 
... 

Если WP плагин отмечает assert \false правомочно (в графическом интерфейсе будет отображаться как действительные, но-имеет-зависимость), то вы знаете, что есть недопустимый Prope RTY.

+0

Я отмечаю этот вопрос как решенный, но все же я не понимаю почему так. После того, как SMT-решатель сможет получить sat/unsat/unknown. Возможно, это потому, что решатель должен пройти все возможные количественные значения, чтобы претендовать на что-то как «недействительное», но я сомневаюсь, что это практично. – Evgeniy

+0

@Evgeniy: Вы правы, что это возможно. Это просто, что плагин WP не поддерживает свойства маркировки как недействительные. Например, плагин Value Analysis поддерживает свойства маркировки как недопустимые. –

+0

@ Evgeniy: На самом деле, похоже, в руководстве имеется опция '-wp-unsat-model '. Тем не менее, я получаю сообщение об ошибке при попытке использовать этот параметр с помощью Frama-C Sodium: '[kernel] user error: option \' -wp-unsat-model 'неизвестно. ' –