将Z3与文本格式一起使用,我可以使用define-fun
来定义稍后重用的函数。例如:
(define-fun mydiv ((x Real) (y Real)) Real
(if (not (= y 0.0))
(/ x y)
0.0))
我想知道如何使用Z3 API创建define-fun
(我使用F#)而不是在任何地方重复函数体。我想用它来避免重复和调试公式更容易。我尝试使用Context.MkFuncDecl
,但它似乎只生成未解释的函数。
答案 0 :(得分:10)
define-fun
命令只是创建一个宏。请注意,SMT 2.0标准不允许递归定义。
在解析时,Z3将扩展my-div
的每次出现。
命令define-fun
可用于使输入文件更简单,更容易阅读,但在内部它并不能真正帮助Z3。
在当前的API中,不支持创建宏。 这不是一个真正的限制,因为我们可以定义一个C或F#函数来创建宏的实例。 但是,您似乎希望显示(并手动检查)使用Z3 API创建的公式。在这种情况下,宏不会帮助你。
一种替代方法是使用量词。您可以声明一个未解释的函数my-div
并断言普遍量化的公式:
(declare-fun mydiv (Real Real) Real)
(assert (forall ((x Real) (y Real))
(= (mydiv x y)
(if (not (= y 0.0))
(/ x y)
0.0))))
现在,您可以使用未解释的函数mydiv
创建公式。
这种量化公式可由Z3处理。实际上,有两种方法可以处理这种量词:
MACRO_FINDER=true
MBQI
(基于模型的量词实例化)。该模块也可以处理这种量词。但是,量词将根据需求进行扩展。当然,解决时间可能在很大程度上取决于您使用的方法。例如,如果您的公式不能满足mydiv
的“含义”,则方法2可能更好。