我正在编写一个静态分析工具,需要对oracle执行一些查询来解决线性整数算术问题。对于我的第一个版本,我在OCaml中实现了Presburger算法的决策程序(为了好玩和利润)。在大型程序上,我的决策程序成为瓶颈,所以我决定转到Z3。
我的第一个结果令人失望,所以我认为我在使用Z3 API做错了。我观察到,在简单的程序中,Z3的分析速度比我天真的自制实现慢100多倍。经过一些微不足道的基准测试后,我认为罪魁祸首是:
let unsat ps =
let open Z3.Solver in
let solver = mk_solver ctx None in
add solver [ps];
check solver [] <> SATISFIABLE
我使用此功能数百次(大型程序上有数千次)。以ps
编码的问题的格式为(not (implies (and X X X X X) Y))
,其中连词通常少于10个合取,X
和Y
是简单的线性不等式。这些问题很容易解决,所以我认为我的性能问题更多地与脚手架代码有关。
我的问题是,如何降低每个unsat
函数调用的成本?