我正在尝试使用Z3的JAVA API来构建以下公式
(assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
(=> (and (= (domain x_0)
(domain x_1))
(forall ((y Int))
(= (alpha x_0 y)
(alpha x_1 y))))))
(= x_0 x_1)))))
通过以下代码
Sort[] types1 = new Sort[2]; // for x_0 and x_1
Expr[] xs1 = new Expr[2];
for (int j = 0; j < 2; j++) {
types1[j] = this.getZ3Sort("fcn_sort_2");
xs1[j] = ctx.mkConst(ctx.mkSymbol("x_" + Integer.toString(j)), types1[j]);
}
Sort[] types2 = new Sort[1]; // for y
Expr[] xs2 = new Expr[1];
types2[0] = ctx.mkIntSort();
xs2[0] = ctx.mkConst(ctx.mkSymbol("y"), types2[0]);
FuncDecl alpha_fcn = this.getFuncSymbol("alpha");
Expr[] arg0 = new Expr[] { xs1[0], xs2[0] };
Expr[] arg1 = new Expr[] { xs1[1], xs2[0] };
BoolExpr
// (= (alpha x_0 y) (alpha x_1 y))
body2 = ctx.mkEq(ctx.mkApp(alpha_fcn, arg0), ctx.mkApp(alpha_fcn, arg1)),
// forall ((y Int)) ...
bf2 = ctx.mkForall(xs2, body2, 1, null, null, null, null);
FuncDecl domain_fcn = this.getFuncSymbol("domain");
BoolExpr
// (= x_0 x_1)
eqX = ctx.mkEq(xs1[0], xs1[1]),
// (= (domain x_0) (domain x_1))
eqDo = ctx.mkEq(ctx.mkApp(domain_fcn, new Expr[] {xs1[0]}), ctx.mkApp(domain_fcn, new Expr[] {xs1[1]})),
// (and ...)
andNode = ctx.mkAnd(eqDo, bf2),
// (=> ...)
body1 = ctx.mkImplies(andNode, eqX),
// (forall ((x_0 ...) (x_1 ...))
bf1 = ctx.mkForall(xs1, body1, 1, null, null, null, null);
其中getFuncSymbol是我自己的函数,用于获取之前声明的FuncDecl。
不幸的是,我使用“let”和“a!1”
得到了错误的结果(assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
(let ((a!1 (and (= (domain_fcn_sort_2 x_0) (domain_fcn_sort_2 x_1))
(forall ((y Int))
(= (alpha_fcn_sort_2 x_0 y) (alpha_fcn_sort_2 x_1 y))))))
(=> a!1 (= x_0 x_1)))))
我发现有些不对劲,“让((a!1”)发生在
行 body1 = ctx.mkImplies(andNode, eqX)
我错过了什么吗?谢谢
答案 0 :(得分:0)
let-expressions在漂亮打印期间引入,试图使输出更简洁。在这里,它只是意味着只要输出中出现名称a!1
,就可以将其替换为(and ...)
。从语义上讲,这没有什么区别。