创建一个固定大小的数组并初始化它

时间:2012-06-17 02:47:00

标签: z3

我将创建一个固定大小的数组,并用一些值初始化它。

例如,以下C ++代码:

a[0] = 10;
a[1] = 23;
a[2] = 27;
a[3] = 12;
a[4] = 19;
a[5] = 31;
a[6] = 41;
a[7] = 7;

Z3中是否有一些实用程序可以对其进行建模?

2 个答案:

答案 0 :(得分:13)

Z3支持数组理论,但通常用于编码无界数组或非常大的数组。大,我的意思是公式中的数组访问次数(即选择)远小于数组的实际大小。我们应该问自己:“我们真的需要数组来建模/解决问题X吗?”。对于像示例中的固定大小数组,我们可以为每个数组位置使用不同的变量。示例:a0a[0]a1a[1]等。当然,如果我们不使用理论,则编码数组访问权限,例如a[i]必须编码为一个大的if-then-else术语,例如

(ite (= i 0) a0 (ite (= i 1) a1 ...))

如果数组大小已知且很小,那么这通常是编码问题的最有效方法。

另一方面,如果您决定使用数组理论,则可以将问题中的初始化编码为:

(declare-const a (Array Int Int))
(assert (= (select a 0) 10))
...
(assert (= (select a 7) 7))

以下是以SMT 2.0格式编码的整个示例:

http://rise4fun.com/Z3/iwo

请注意,要对此阵列进行更新编码。例如,C语句a[3] = 5,我们必须在此赋值后创建一个表示数组的新数组变量。最紧凑的方式使用store表达式:

(declare-const a1 (Array Int Int))
(assert (= a1 (store a 3 5)))

以下是更新的完整示例。

http://rise4fun.com/Z3/Kpln

您也可以考虑使用Python / C ++ / .Net API。它们允许我们以更紧凑的方式编码像你这样的例子。这个想法是实现编码常用模式的函数,例如数组初始化。这是Python中的数组初始化示例:

http://rise4fun.com/Z3Py/AAD

答案 1 :(得分:0)

我同意莱昂纳多(Leonardo)的answer,尤其是数组被设计为对大输入范围建模。确实没有定义固定大小数组的方法(除非您使用有限的输入排序,例如BitVecSort(3))。

自从删除Z3Py(Python)示例以来,我想添加自己的解决方案。 此函数指定从起始地址开始的一系列数组条目。 (断言存储在{​​{1}}对象中。)

Solver

请注意,def assert_array(solver, array, address, data): for (offset, value) in enumerate(data): solver.add(array[address + offset] == value) 是SMT 2.0中array[idx]的Z3Py等效项。问题中的数组可以像这样建模:

(select array idx)