Z3在python中的开发是相对友好的,可以直接引用相关的python库 - z3-solver。 然而,其运行效率是十分低的,如果运行十分复杂的项目,所需的时间将会非常长 (最近的我一个科研项目中使用了基于python的z3,即使问题规模很小,依然需要数分钟,乃至十数个小时的求解时间,“月本_诚”同学也提到了该问题 - z3 C++学习笔记_c++ z3-CSDN博客)。
补充:当我以c++实现之前以python编程的版本后,我发现,对于我的项目而言,z3的求解过程并没有得到优化。
具体如下:
![](https://img-blog.csdnimg.cn/img_convert/c00b1c38012c786acb5fdd6ade12c316.png)
上图为python版本的输出,生成constraint的时间为22s,求解时间为104s。
![](https://img-blog.csdnimg.cn/img_convert/a236df39ef142ba8beca543e692d340a.png)
上图为c++版本的输出,生成constraint的时间为0.2s,求解时间为149s。
对比可以发现,在生成constraints时,c++版本相比python具有显著的优势,大约快了100倍,然而在求解时间上没有任何优势,甚至花费了更多的时间。速度变慢的原因可能有以下两点:1)python作为一个更流行(较多的教程是以python给出的)的z3上层调用接口,得到了一些优化;2)目前我实现的c++版本在我实现的过程中我做的优化较少,这里的优化较少可能是生成constraints以及使用了并非最合适的数据结构,而python版本因为并不需要指定数据结构等的类型,因而可以被其求解器自行优化到合适的数据结构,因而效率更高。
总结:在进行模型的验证时,建议首先按python框架进行实现,python的版本,可以在网络上搜索更多的资料,配置简单,不用担心数据结构问题,对于数组等数据结构的支持更方便等。如果确有需要,可以尝试转为c++版本,具体能得到多少的性能增益,我无法给出答案。
正如“月本_诚”所言,中文互联网上基本没有关于z3 C++的相关教程,甚至在国外的平台上也十分少见。本文章会分享一下,在Mac OS系统中关于z3 C++的配置过程,在Linux系统中应也可以按照相同方式进行配置。Windows平台的配置,目前还存在bug,可以成功编译,不会报错,但当运行程序时,会直接退出,且暂时无法debug。
配置的基本环境
-
IDE:JetBrains CLion
-
Operating system: Mac OS 13.1/Linux
配置过程
-
编译z3 project
在这里我没有使用官方的Relsases版本,而是选择了自己编译,编译过程按照官方的教程非常简单,直接。
z3 project的GitHub地址为:GitHub - Z3Prover/z3: The Z3 Theorem Prover,下载源码。下载之后解压的名称一般为z3-master。
接下来,按照主页readme中的"Building Z3 using make and GCC/Clang"部分进行编译,大致需要以下几个命令:
python scripts/mk_make.py
cd build
make
sudo make install
上述第一个命令在下载后的z3-master根目录下执行。
在执行第三个命令"make"时,为了加速,可以使用"make -j4",其中j后面的数字可以根据电脑的配置调整,该数字应指的是同时编译的线程数,一般数字越大,编译速度越快,如不确定,可以先设置一个数字,然后打开资源管理器查看处理器的资源占用情况确定。
执行上述第四个命令时,若不指定目录,在Mac OS系统下应为 /usr/local/bin,成功执行上述命令后,可以在/usr/local/bin目录下找到z3的可执行文件,也可以尝试在终端中输入"z3 -h"。
![](https://img-blog.csdnimg.cn/img_convert/da0d4560fcba8330c5a36e72ee3beb9a.png)
-
在CLion中创建project
我使用的IDE为CLion,成功配置需要做的工作主要有以下几点:1)创建一个clion的project;2)添加库和头文件;3)设置CMake需要使用的CMakeLists.txt;4)编译并执行。
2.1 创建CLion的project
该创建过程比较简答,如下图,需要注意的是,c++版本需选择c++ 17 (该选项后续也可以在CMakeLists.txt中进行修改)。
![](https://img-blog.csdnimg.cn/img_convert/115edfd66522ff5f9a5c8a1c32fc0058.png)
2.2 添加库和头文件
库和头文件可以从前面编译好的文件夹中获取。
2.2.1 获取库文件
库文件的路径为:z3-master下的build文件夹,需要复制libz3.dylib与z3两个文件。
![](https://img-blog.csdnimg.cn/img_convert/b8f1ea43281191a5f989cb0d06c83fd5.png)
2.2.2 获取头文件
头文件路径为:z3-master/src/api,此处需要复值整个文件夹。
![](https://img-blog.csdnimg.cn/img_convert/cb121b44b354ec1826aa5265b40e89b4.png)
2.2.3 将库文件和头文件添加到CLion project中
在当前的project中,我创建了文件夹z3用于存放库文件和头文件,其中库文件在bin文件夹中,头文件在src文件夹中,图片右边显示的是所需的CMakeLists.txt文件。
![](https://img-blog.csdnimg.cn/img_convert/28f8031530f9cad2e645818104db37c9.png)
2.3 设置所需的CMakeLists.txt文件
CLion中我们使用CMake来帮助我们对project进行配置(也就是生成Makefile文件),可以使用下述命令进行配置:
cmake_minimum_required(VERSION 3.23)
project(SMT_CPP)
set(CMAKE_CXX_STANDARD 17)
link_directories(z3/bin)
add_executable(SMT_CPP main.cpp)
target_include_directories(SMT_CPP PUBLIC z3/src/api/c++)
target_include_directories(SMT_CPP PUBLIC z3/src/api)
target_link_libraries(SMT_CPP PUBLIC z3)
其中,SMT_CPP为项目名,可以被替换,link_directories(),target_include_directories()中的路径可以根据实际创建的库文件和头文件路径进行修改。因为这里需要使用c++相关的头文件,因此头文件的路径包含了两部分,z3/src/api和z3/src/api/c++。
Note: 这里的target_include_directories()与target_link_libraries()必须出现在add_executable()语句的后面,不然会报错,大致意思是提示该库不是为本项目创建。
2.4 编译并执行
这里使用一个非常简单的代码进行验证:
#include <z3++.h>
#include <iostream>
int main() {
z3::context c;
z3::solver s(c);
std::cout << "Hello world!" << std::endl;
return 0;
}
如果正常输出"Hello world!"即为编译成功。
-
关于Windows平台
在Windows平台的测试中,最终可以成功编译,但程序会直接退出,如下所示:
![](https://img-blog.csdnimg.cn/img_convert/0a295bc350682f29b33c68aaff3f6022.png)
相比于上述Mac OS平台的配置,缺少了的是make install 这一步骤,但目前并未在其官方找到如何在Windows平台上进行make install的方法,又或许并不上make install导致的,毕竟现在可以成功编译。
若您读到这里,有任何相关的想法,欢迎交流,共同解决问题。