Z3,C++ API, 如何将 bool 排序转换为 int 排序

Z3,C++ API, How to convert bool sort to int sort

我在 C++ 中使用 Z3,并且我有一些布尔排序表达式。

我要做的是统计真值表达式的个数。

一个很简单的方法就是把这些expr转换成int-sort然后相加。

但是我不知道如何将 bool 转换为 int。

谢谢!


解决方案:

如 cpp 示例文件所示(function ite_example2()):

expr b = c.bool_const("x");
expr x = c.int_val(1);
expr y = c.int_val(0);
expr conj = ite(b,x,y);
#include <iostream>
using namespace std;

int main() {
    int a = 6;
    a += (int)true;
    cout << a << "\n";
}

我使用 Z3 已经有很长时间了,但我认为你应该能够定义一个函数来有效地投影 true=>1 和 false=>0(或其他方式)。

假设您正在执行 脚本,它看起来类似于

(declare-fun boolToIntDirect (Bool) Int)
(assert (= (boolToIntDirect false) 0))
(assert (= (boolToIntDirect true) 1))

(declare-fun boolToIntNegated (Bool) Int)
(assert (= (boolToIntNegated false) 1))
(assert (= (boolToIntNegated true) 0))

然后,如果您使用该函数构造表达式,它将进行转换,并且还会报告任何问题,例如获取非布尔参数。

伪布尔函数

对于计算布尔值,断言有多少是真的等(互斥条件),伪布尔函数是你的朋友:

https://github.com/Z3Prover/z3/blob/master/src/api/c%2B%2B/z3%2B%2B.h#L949-L953

这些函数允许您声明允许您创建基数条件的约束,这是我怀疑您首先要尝试做的。与任何其他间接编码相比,这些函数为 z3 生成更好的代码来解决。这是基于 python 接口的讨论:K-out-of-N constraint in Z3Py

直接计数

当然你也可以直接计数,但如果你需要的话,你应该更喜欢上面的功能。如果你真的想得到一个整数,你必须使用:

  • int_val:创建一个数字表达式
  • ite:如果-那么-其他
  • sum: 创建总和

本质上创建表达式(伪代码):

 z = int_val(0);
 o = int_val(1);
 sum(ite(b1, o, z), ite(b2, o, z), ...)

但是如果可能的话,你真的应该坚持使用伪布尔值。

Z3 中有 built-in 个函数用于计算“k among N”和其他变体。

它们通常应该是首选,因为它们采用专门的策略提供更好的性能。

((_ at-most k) x y z)

这意味着最多 k 个布尔值 x、y、z... 为真。

有关更多详细信息,请参阅此其他问题,以及 Nikolaj Bjorner 对变体的 SMT 语法答案的评论。

K-out-of-N constraint in Z3Py