关于ACSL归纳谓词的Coq归纳推理?

时间:2015-09-08 09:58:51

标签: coq frama-c formal-verification why3

是否可以在ACSL中定义的归纳谓词上使用归纳法?

请考虑https://support.office.com/en-us/article/VLOOKUP-function-0bbc8083-26fe-4963-8ab8-93a18ad188a1中的以下示例:

struct List {
    int value;
    struct List* next;
};
/*@ inductive reachable{L}(struct List* root, struct List* to) {
  @   case empty{L}: \forall struct List* l; reachable(l, l);
  @   case non_empty{L}: \forall struct List *l1,*l2;
  @     \valid(l1) && reachable(l1->next, l2) ==> reachable(l1, l2);
  @ }
*/

我试图证明以下问题:

/*@ lemma next_null_reachable: \forall struct List* l;
  @   \valid(l) && reachable(l, \null) ==> reachable(l->next, \null);
*/

Alt-Ergo在这里失败,所以我采用手动Coq推理:

Goal
  forall (t : array Z),
  forall (t_1 : farray addr addr),
  forall (a : addr),
  ((valid_rw t a 2%Z)) ->
  ((P_reachable t t_1 a (null))) ->
  ((P_reachable t t_1 (t_1.[ (shiftfield_F_List_next a) ]) (null))).

但是当我Search P_reachable时,我发现只产生了两个公理:

Q_non_empty:
  forall (t : array int) (t_1 : farray addr addr) (a_1 a : addr),
  valid_rw t a_1 2 ->
  P_reachable t t_1 (t_1 .[ shiftfield_F_List_next a_1]) a ->
  P_reachable t t_1 a_1 a
Q_empty:
  forall (t : array int) (t_1 : farray addr addr) (a : addr),
  P_reachable t t_1 a a    

没有归纳原则。因此,我无法应用induction P_reachabledestruct P_reachable

我使用frama-c版本Sodium-20150201的WP插件。

要重现,您可以运行frama-c -wp -wp-rte -wp-prover coqide file.c,其中file.c包含Listreachable定义以及next_null_reachable引理。

2 个答案:

答案 0 :(得分:2)

从您的目标形式来看,我假设您正在使用WP插件。实际上,它没有提供一个引理,表明reachable是验证两个案例emptynon_empty的最小谓词,这意味着您无法使用归纳。

如果我没记错的话,添加这样一个公理会混淆一阶定理证明者(他们会反复构造reachableemptynon_empty的实例并用归纳原理破坏它们)。但是,WP的Coq输出可以很好地提供完整的翻译。

解决方法是提供一组适当的专用化学引物(不能通过WP证明)而不是归纳原理。参见例如this archive中的binary_search_proved.c

答案 1 :(得分:0)

我从未使用过Alt-Ergo,但似乎他们没有创造真正的归纳命题,而是将它们公理化。所以你不能induction但是你可以使用它们提供的基本块(Q_empty是你的默认构造函数而Q_non_empty是你的归纳构造函数)来执行证明。

我缺少一些基本定义来重播您的问题,但我会先申请Q_non_empty一次,这应该要求我证明valid_rw语句和子P_reachable语句。它们都应该根据你的背景进行证明。