上次我问过如何在Z3 Java API中定义一个函数。原因是没有命令在Java API中定义函数。答案是用函数的参数值替换输入值(Z3 Java API defining a function)。
示例(我需要的):
1。没有API(普通smt文件)
(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(define-fun max2 ((x Int) (y Int)) Int (ite (<= x y) y x))
(assert (< (max2 a b) c))
(assert (>= (max2 a b) c))
(check-sat)
我现在做的是这样的事情:
2。使用Java API
Context ctx = new Context();
ArithExpr a = (ArithExpr) ctx.mkConst(ctx.mkSymbol("a"), ctx.getIntSort());
ArithExpr b = (ArithExpr) ctx.mkConst(ctx.mkSymbol("b"), ctx.getIntSort());
ArithExpr c = (ArithExpr) ctx.mkConst(ctx.mkSymbol("c"), ctx.getIntSort());
ArithExpr max2 = (ArithExpr) ctx.mkITE(ctx.mkLe(a, b), b, a);
BoolExpr one = (BoolExpr) ctx.mkLt(max2, c);
BoolExpr two = (BoolExpr) ctx.mkGe(max2, c);
我想知道,如果这有所不同?
我假设smt文件(1)中的max2-function是正确的,不必再次重新求解。但是如果我按照上面的java代码(2)来做,求解器必须解决max2函数的表达式 ctx.mkITE(ctx.mkLe(a,b),b,a)每一次。或者我完全错了,忽略max2-function的表达式是不可能的?
有没有人有想法?
答案 0 :(得分:3)
define-fun构造的行为类似于宏,因此所有出现的max2都将替换为函数定义。或者,我们可以使用量词和宏查找器(参见例如Equivalent of define-fun in Z3 API),或者我们可以自己替换所有出现的函数。
一般来说,不可能“忽略”任何东西,而Z3不会试图在另一个函数之前“解决”一个函数;它只知道一个问题,其中相同的子表达式可以出现多次(并且它具有散列值,因此它知道相同的子表达式)。如果你知道在不知道函数语义的情况下解决问题是可能的,那么你可以用一个新变量替换它来表示某些特定参数的返回值,这样就可以解决问题。更快。