在CBMC中表达“恰好一次”的更好方法

时间:2015-03-09 14:01:51

标签: c model-checking sat cbmc

我正在努力想出一个更好的解决方案来陈述CBMC中的“一次性”属性(C有界模型检查器)。我的意思是一行中的一个元素位置应该具有值1(或者可以作为布尔值true检查的任何正数),其余的必须全为零。

  

对于M = 4

for(i=0;i<M;i++){
__CPROVER_assume( (update[i][0]) ?  
    ( !(update[i][1]) && !(update[i][2])  &&!(update[i][3]) ) :         
     ((update[i][1]) ?  (!(update[i][2])  && !(update[i][3]) ) :                  
     ((update[i][2]) ? !update[i][3] : update[i][3] )) )   ;
}`
  

对于大于此的M这是一个巨大的问题。让我们说M = 8我必须做类似的事情:

for(i=0;i<M;i++){
   __CPROVER_assume( (update[i][0]) ?  ( !(update[i][1]) && !(update[i][2])  && !(update[i][3]) && (update[i][4]) && !(update[i][5])  && !(update[i][6]) && !(update[i][7]) )  :
           ((update[i][1]) ?  (!(update[i][2])  && !(update[i][3]) && !(update[i][4]) && !(update[i][5])  && !(update[i][6]) && !(update[i][7]) ) :
             ((update[i][2]) ? ((!update[i][3]) && !(update[i][4]) && !(update[i][5])  && !(update[i][6]) && !(update[i][7]))  :
                   ((update[i][3]) ? (!(update[i][4]) && !(update[i][5])  && !(update[i][6]) && !(update[i][7]))  : 
                   ((update[i][4]) ? (!(update[i][5])  && !(update[i][6]) && !(update[i][7])) : 
                      ((update[i][5]) ? (!(update[i][6]) && !(update[i][7])) :  
                         ((update[i][6]) ? !(update[i][7]) : (update[i][7])))))))) ;
}

检查一次违规很容易,但说明它看起来很重要。我可能还有一个选择:将二维数组问题陈述为1维位向量问题,然后做一些智能xor。但我目前还不确定。

有没有人有更好的解决方案?

1 个答案:

答案 0 :(得分:3)

如何计算计算真值的数量,然后检查它们的数量:

for (i = 0; i < M; i++) {
    int n_true = 0;
    int j;

    for (j = 0; j < M; j++) {
        n_true += (update[i][j] ? 1 : 0);
    }

    __CPROVER_assume(n_true == 1);
}