Z3中宏与量词的区别

Z3中宏与量词的区别,z3,Z3,我想知道以下两种说法的区别是什么- 声明1 (define-fun max_integ ((x Int) (y Int)) Int (ite (< x y) y x)) (定义最大整数((x Int)(y Int))Int (ite(

我想知道以下两种说法的区别是什么-

声明1

(define-fun max_integ ((x Int) (y Int)) Int 
  (ite (< x y) y x))
(定义最大整数((x Int)(y Int))Int
(ite(
声明2

(declare-fun max_integ ((Int)(Int)) Int)
(assert (forall ((x Int) (y Int)) (= (max_integ x y) (if (< x y) y x))))
(声明最大整数((Int)(Int))Int)
(断言(对于所有((x Int)(y Int))(=(max_integ x y)(如果(
我注意到,当我使用语句1时,我的z3约束会在0.03秒内给出一个结果。而当我使用Statement2时,它不会在2分钟内完成,我会终止解算器。 我还想知道如何使用C-API实现它


谢谢

语句1是一个宏。Z3将用
ite
表达式替换每次出现的
max_integ
。它在解析时执行此操作。在第二条语句中,默认情况下,Z3不会消除
max_integ
,为了能够返回
sat
,它必须为未解释的符号
max_integ
建立一个解释,该解释将满足所有
x
y
的量词。 Z3有一个名为
:macro finder
的选项,它将检测基本上是对宏进行编码的量词,并消除它们。以下是一个示例(也可在线获取):


另一种选择是使用C API:
Z3\u substitute\u vars
。其思想是构造一个包含自由变量的表达式。自由变量是使用API
Z3_mk_-bound
创建的。每个变量代表一个参数。然后,我们使用
Z3\u substitute\u vars
将变量替换为其他表达式。

是否可以使用
Z3\u substitute\u vars
为同一量词包含一个小示例?文件
examples/c/test\u capi.c
有一个示例:function
substitute\u vars\u example()
。以下是指向此文件的链接:
(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) 
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)