如何使用VST/coq编写switch语句的证明?

如何使用VST/coq编写switch语句的证明?,coq,coq-tactic,verifiable-c,Coq,Coq Tactic,Verifiable C,我有一个关于VST和switch语句使用的问题 当switch变量有匹配的情况时,我在编写一个证明单步执行switch语句时遇到困难。例如: 我可以为这样的事情写一个证明: int switchTest(int x){ switch (x){ case(0): return 0; default: return 1; } } int switchTest(){ int x = 5; switch (x){ case(0): retur

我有一个关于VST和switch语句使用的问题

当switch变量有匹配的情况时,我在编写一个证明单步执行switch语句时遇到困难。例如:

我可以为这样的事情写一个证明:

int switchTest(int x){
   switch (x){
      case(0): return 0;
      default: return 1;
   }
}
int switchTest(){
   int x = 5;
   switch (x){
      case(0): return 0;
      case(1): return 1;
      case(5): return 5;  //The matching case for x - causes my problem
      default: return 8;
   }
}
但是,我不能为这样的事情写证据:

int switchTest(int x){
   switch (x){
      case(0): return 0;
      default: return 1;
   }
}
int switchTest(){
   int x = 5;
   switch (x){
      case(0): return 0;
      case(1): return 1;
      case(5): return 5;  //The matching case for x - causes my problem
      default: return 8;
   }
}
每当“x”有匹配的情况时(就像我的第二个代码示例),在尝试为switch语句编写策略时,我就会遇到“No matching子句for match”错误

通常我可以写一些类似的东西:“forward_if”、“forward_if True”、“forward_if(PROP()LOCAL()SEP())”,它们适用于我的第一个代码示例,但不适用于我的第二个代码示例

总结:对于第二个代码示例,我的证明中的下一行应该是什么

Lemma body_switchTest: semax body Vprog Gprog f_switchTest switchTest_spec.
Proof.
start_function.
forward.
???

提前谢谢

这确实是VST Floyd战术中的一个漏洞。 导入VST.floyd.proofauto后,您可以在任意位置进行修补:

Ltac process_cases sign ::= 
match goal with
| |- semax _ _ (seq_of_labeled_statement 
     match select_switch_case ?N (LScons (Some ?X) ?C ?SL)
      with Some _ => _ | None => _ end) _ =>
       let y := constr:(adjust_for_sign sign X) in let y := eval compute in y in 
      rewrite (select_switch_case_signed y); 
           [ | reflexivity | clear; compute; split; congruence];
     let E := fresh "E" in let NE := fresh "NE" in 
     destruct (zeq N (Int.unsigned (Int.repr y))) as [E|NE];
      [ try ( rewrite if_true; [  | symmetry; apply E]);
        unfold seq_of_labeled_statement at 1;
        apply unsigned_eq_eq in E;
        match sign with
        | Signed => apply repr_inj_signed in E; [ | rep_lia | rep_lia]
        | Unsigned => apply repr_inj_unsigned in E; [ | rep_lia | rep_lia]
        end;
        try match type of E with ?a = _ => is_var a; subst a end;
        repeat apply -> semax_skip_seq
     | try (rewrite if_false by (contradict NE; symmetry; apply NE));
        process_cases sign
    ]
| |- semax _ _ (seq_of_labeled_statement 
     match select_switch_case ?N (LScons None ?C ?SL)
      with Some _ => _ | None => _ end) _ =>
      change (select_switch_case N (LScons None C SL))
       with (select_switch_case N SL);
        process_cases sign
| |- semax _ _ (seq_of_labeled_statement 
     match select_switch_case ?N LSnil
      with Some _ => _ | None => _ end) _ =>
      change (select_switch_case N LSnil)
           with (@None labeled_statements);
      cbv iota;
      unfold seq_of_labeled_statement at 1;
      repeat apply -> semax_skip_seq
end.

这将在2.7版中修复,您已经可以从github获取v2.7版,或者v2.7的opam包将在一个月内发布。