【发布时间】:2014-08-02 23:20:49
【问题描述】:
我正在使用 Z3 for Java 来检查具有未解释函数的术语的可满足性,例如 (type(o)>1 或 type(p)2 and type(o)=1)运行solver.check() 需要6 ms。
FuncDecl typeFun = ctx.MkFuncDecl("type", ctx.IntSort(), ctx.IntSort());
Expr o = ctx.MkConst("o", ctx.IntSort());
//type(o)
IntExpr to = (IntExpr)typeFun.Apply(o);
//type(o)=1
BoolExpr subExpr1 = ctx.MkEq(to, ctx.MkInt("1"));
//type(o)>2
BoolExpr subExpr2 = ctx.MkGt(to, ctx.MkInt("2"));
//type(o)>2 and type(o)=1
BoolExpr expr = ctx.MkAnd(new BoolExpr[] { subExpr1, subExpr2 });
solver.Assert(expr);
//this step will take 6 ms.
solver.check();
鉴于我的项目中实际约束的大小比这个例子大得多(但每个术语都非常简单,例如 type(o1)=1, type(o2)>1 等)并且有数十亿个这样的例子约束需要解决:
1、check()的表现应该是这样的吗?
2. 如果 1 的答案是肯定的,是否有其他替代方法可以绕过性能问题?
提前致谢。
@ChristophWintersteiger: 我认为我系统中的很大一部分约束应该是 SAT。我正在为 Java 实现指针分析,并且我正在使用 Z3 以自下而上的方式解决虚拟调用的潜在目标。假设我有一个虚拟调用点 v.foo(),这个调用点可能会根据 v 的动态类型调用不同的方法。所以对于每个被调用者 foo(),我将引入一个约束 type(o) = T,其中 o 是点- 接收者 v 和 T 的集合是声明 foo 的类。约束意味着当 v.foo() 的一个动态指向集的类型为 T 时,v.foo() 可以在 T 中调用方法 foo()。我当前系统中的所有约束都是一些线性算术,只有一个未解释的函数“类型” (o)"。但是由于我是以自下而上的方式分析调用图,因此可以扩展与每个虚拟调用点相关的约束,直到分析到达根级别并且已经解决了接收器的所有指向目标。
【问题讨论】:
标签: java performance z3