首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取CBMC中的所有排列?

如何获取CBMC中的所有排列?
EN

Stack Overflow用户
提问于 2020-04-15 17:06:14
回答 1查看 78关注 0票数 0

我正在尝试获取CBMC中数组的所有排列。对于小的情况,例如1,2,3,我想我可以写

代码语言:javascript
复制
i1 = nondet()
i2 = nondet()
i3 = nondet()
assume (i > 0 && i < 4); ...
assume (i1 != i2 && i2 != i3 && i1 != i3);
// do stuffs with i1,i2,i3

但是对于较大的元素,代码将非常混乱。所以我的问题是,有没有更好的/通用的方式来表达这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-07 20:02:47

基于Craig提出的使用数组的建议,您可以循环遍历您想要置换的值,并不确定地选择一个尚未被占用的位置。例如,像这样的循环(其中,对于所有值,序列都使用-1进行了预初始化)。

代码语言:javascript
复制
for(int i = 1; i <= count; ++i) {
  int nondet;
  assume(nondet >= 0 && nondet < count);
  // ensure we don't pick a spot already picked
  assume(sequence[nondet] == -1); 
  sequence[nondet] = i;
}

所以一个完整的程序看起来就像这样:

代码语言:javascript
复制
#include <assert.h>
#include <memory.h>

int sum(int *array, int count) {
    int total = 0;
    for(int i = 0; i < count; ++i) {
        total += array[i];
    }
    return total;
}

int main(){

    int count = 5; // 1, ..., 6
    int *sequence = malloc(sizeof(int) * count);

    // this isn't working - not sure why, but constant propagator should
    // unroll the loop anyway
    // memset(sequence, -1, count);
    for(int i = 0; i < count; ++i) {
        sequence[i] = -1;
    }

    assert(sum(sequence, count) == -1 * count);

    for(int i = 1; i <= count; ++i) {
      int nondet;
      __CPROVER_assume(nondet >= 0);
      __CPROVER_assume(nondet < count);
      __CPROVER_assume(sequence[nondet] == -1); // ensure we don't pick a spot already picked
      sequence[nondet] = i;
    }

    int total = (count * (count + 1)) / 2;
    // verify this is a permuation
    assert(sum(sequence, count) == total);
}

然而,对于大于6的值,这是相当慢的(尽管我没有将它与您的方法进行比较-它不会卡住解开,它会卡住求解)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61225031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档