Z3解算器的低效率问题
作为静态时间编译器分析的一部分,我使用(的JavaAPI)Z3Solver来检查(in)方程组是否可满足。一切似乎都正常工作。但是,解算器太慢。对于下面发布的系统,Z3需要大约109秒才能宣布系统不可满足。 我以前没有任何使用Z3的经验。为了帮助解算器具有合理的效率,是否有任何拇指规则可以遵循 前缀形式的(in)方程组如下所示: (注意:ITE表示if-then-else,并接受三个操作数。)Z3解算器的低效率问题,z3,solver,smt,Z3,Solver,Smt,作为静态时间编译器分析的一部分,我使用(的JavaAPI)Z3Solver来检查(in)方程组是否可满足。一切似乎都正常工作。但是,解算器太慢。对于下面发布的系统,Z3需要大约109秒才能宣布系统不可满足。 我以前没有任何使用Z3的经验。为了帮助解算器具有合理的效率,是否有任何拇指规则可以遵循 前缀形式的(in)方程组如下所示: (注意:ITE表示if-then-else,并接受三个操作数。) [,-,+,+,0,*,tid2,+,/,-,100,0,numTh,%,-,100,0,numTh,
[<,i_imopVarPre1,ITE,>,-,+,+,0,*,tid2,+,/,-,100,0,numTh,%,-,100,0,numTh,+,/,-,100,0,numTh,%,-,100,0,numTh,100,100,100,100,+,+,0,*,tid2,+,/,-,100,100,0,numTh,%,,,-,100,0,numTh,+,,/,100,100,0,numTh,%
[>=,i_imopVarPre1,+,0,*,tid2,+,/,-100,0,numTh,%,-100,0,numTh]
[<,i_imopVarPre0,ITE,>,-,+,+,+,0,*,tid1,+,/,-,100,0,numTh,%,-,100,numTh,+,/,-,100,0,numTh,%,-,100,0,numTh,100,0,0,0,0,0,tid1,+,/,-,100,0,numTh,%,,-,100,0,numTh,+,/,100,100,0,numTh,%,%,100,100,100,numTh,%,100,100,100,100,numTh]
[>=,i_imopVarPre0,+,0,*,tid1,+,/,-100,0,numTh,%,-100,0,numTh]
[=,i_imopVarPre0,i_imopVarPre1]
[>,numTh,0]
[>=,tid2,0]
[<,tid2,numTh]
[>=,tid1,0]
[<,tid1,numTh]
[!=,tid2,tid1]
我已经声明所有变量都是Int排序的。
将这些表达式添加到Z3后,当我在解算器中打印断言时,我得到以下输出:
(let ((a!1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh))))
(let ((a!2 (> (- (+ 0 (* tid2 a!1) a!1) 100) 0)))
(< i_imopVarPre1 (ite a!2 100 (+ 0 (* tid2 a!1) a!1)))))
(let ((a!1 (* tid2 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh)))))
(>= i_imopVarPre1 (+ 0 a!1)))
(let ((a!1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh))))
(let ((a!2 (> (- (+ 0 (* tid1 a!1) a!1) 100) 0)))
(< i_imopVarPre0 (ite a!2 100 (+ 0 (* tid1 a!1) a!1)))))
(let ((a!1 (* tid1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh)))))
(>= i_imopVarPre0 (+ 0 a!1)))
(= i_imopVarPre0 i_imopVarPre1)
(> numTh 0)
(>= tid2 0)
(< tid2 numTh)
(>= tid1 0)
(< tid1 numTh)
(not (= tid2 tid1))
(let((a!1(+(div(-1000)numTh)(mod(-1000)numTh)))
(让((a!2(>(+0(*tid2a!1)a!1)100)0)))
(=i_imopVarPre1(+0a!1)))
(let((a!1(+(div(-1000)numTh)(mod(-1000)numTh)))
(让((a!2(>(+0(*tid1a!1)a!1)100)0)))
(=i_imopVarPre0(+0a!1)))
(=i_imopVarPre0 i_imopVarPre1)
(>numTh 0)
(>=tid2 0)
(=TID10)
(
另外,请在此处查找调用check()
方法后获得的统计信息:
对于上述系统,Z3是否预计需要约100秒?如果没有,我是否遗漏了什么
此外,有没有办法重用Z3查询,因为其中许多查询可能是同构的?由于标识符名称可能不同,我觉得记忆/搜索本身的任务可能成本高昂。如果不能够复制,就很难对此发表评论。StackOverflow是最好的,当你可以发布人们可以自己创建的东西时。我注意到您有
div
/mod
术语,这将很难解决。您使用的是Int
还是位向量?你可能会使用一种定制的战术,但如果不知道更多细节,就不可能说出来。如果可能的话,请发布一些人们可以自己运行的东西。(一个完整的SMTLib文件,我们可以直接提供给z3将是最好的。)非常感谢关于div/mod的观点。在通过使分析稍微不精确来减少div/mod操作符的数量之后,我能够将求解时间减少到17秒。给定系统的另一个问题是变量numTh没有上界。当我使用上限为“11”时,时间减少到0.3秒。(使用numTh,在发布后几天内,我应该能够用tarball编辑帖子,使用tarball可以复制场景以更好地诊断问题。在此之前,感谢您的帮助。:)
(let ((a!1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh))))
(let ((a!2 (> (- (+ 0 (* tid2 a!1) a!1) 100) 0)))
(< i_imopVarPre1 (ite a!2 100 (+ 0 (* tid2 a!1) a!1)))))
(let ((a!1 (* tid2 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh)))))
(>= i_imopVarPre1 (+ 0 a!1)))
(let ((a!1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh))))
(let ((a!2 (> (- (+ 0 (* tid1 a!1) a!1) 100) 0)))
(< i_imopVarPre0 (ite a!2 100 (+ 0 (* tid1 a!1) a!1)))))
(let ((a!1 (* tid1 (+ (div (- 100 0) numTh) (mod (- 100 0) numTh)))))
(>= i_imopVarPre0 (+ 0 a!1)))
(= i_imopVarPre0 i_imopVarPre1)
(> numTh 0)
(>= tid2 0)
(< tid2 numTh)
(>= tid1 0)
(< tid1 numTh)
(not (= tid2 tid1))