如何获得 CBMC 中的所有排列?
How to get all permutations in CBMC?
我正在尝试获取 CBMC 中数组的所有排列。
对于小情况,例如 [1,2,3],我想我可以写
i1 = nondet()
i2 = nondet()
i3 = nondet()
assume (i > 0 && i < 4); ...
assume (i1 != i2 && i2 != i3 && i1 != i3);
// do stuffs with i1,i2,i3
但是如果元素比较大,代码会很乱。
所以我的问题是,有没有 better/general 的表达方式?
根据 Craig 关于使用数组的建议,您可以循环遍历要排列的值,并最终确定 select 尚未占用的位置。例如,像这样的循环(其中序列的所有值都预初始化为 -1)。
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;
}
所以一个完整的程序看起来像这样:
#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 的值,这非常慢(尽管我没有将它与您的方法进行比较——它不会卡在展开中,而是卡在求解中)。
我正在尝试获取 CBMC 中数组的所有排列。 对于小情况,例如 [1,2,3],我想我可以写
i1 = nondet()
i2 = nondet()
i3 = nondet()
assume (i > 0 && i < 4); ...
assume (i1 != i2 && i2 != i3 && i1 != i3);
// do stuffs with i1,i2,i3
但是如果元素比较大,代码会很乱。 所以我的问题是,有没有 better/general 的表达方式?
根据 Craig 关于使用数组的建议,您可以循环遍历要排列的值,并最终确定 select 尚未占用的位置。例如,像这样的循环(其中序列的所有值都预初始化为 -1)。
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;
}
所以一个完整的程序看起来像这样:
#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 的值,这非常慢(尽管我没有将它与您的方法进行比较——它不会卡在展开中,而是卡在求解中)。