语句 1 是一个宏。Z3 将用表达式替换每次出现max_integ
的ite
。它在解析期间执行此操作。在第二个语句中,默认情况下,Z3 不会消除max_integ
,并且为了能够返回sat
它必须为未解释的符号构建一个解释,该解释max_integ
将满足所有x
和的量词y
。Z3 有一个名为 的选项:macro-finder
,它将检测本质上是编码宏的量词,并消除它们。这是一个示例(也可在此处在线获得):
(set-option :macro-finder true)
(declare-fun max_integ ((Int)(Int)) Int)
(assert (forall ((x Int) (y Int)) (= (max_integ x y) (if (< x y) y x))))
(check-sat)
(get-model)
话虽如此,我们可以通过编写一个给定 Z3 表达式返回新 Z3 表达式的函数,轻松地在编程 API 中模拟宏。这里是一个使用 Python API 的示例(也可以在此处在线获得):
def max(a, b):
# The function If builds a Z3 if-then-else expression
return If(a >= b, a, b)
x, y = Ints('x y')
solve(x == max(x, y), y == max(x, y), x > 0)
另一种选择是使用 C API Z3_substitute_vars
:. 这个想法是一个包含自由变量的表达式。自由变量是使用 API 创建的Z3_mk_bound
。每个变量代表一个参数。然后,我们用Z3_substitute_vars
其他表达式替换变量。