Microsoft Z3:将表达式转换为特定变量

Microsoft Z3:将表达式转换为特定变量,z3,solver,smt,Z3,Solver,Smt,我正在使用微软的Z3对动态观测进行一些简单的分析。作为这项工作的一部分,如果我能将一些公式从使用一组变量转换为另一组目标变量,那将是很有帮助的 我对Z3很陌生,但我知道它有一些内部简化规则和其他转换公式的方法。。。基本上,我想知道是否可以进行一些转换,如: (declare-const local Real) (declare-const x Real) (declare-const y Real) (declare-const midstep Real) (declare-const loca

我正在使用微软的Z3对动态观测进行一些简单的分析。作为这项工作的一部分,如果我能将一些公式从使用一组变量转换为另一组目标变量,那将是很有帮助的

我对Z3很陌生,但我知道它有一些内部简化规则和其他转换公式的方法。。。基本上,我想知道是否可以进行一些转换,如:

(declare-const local Real)
(declare-const x Real)
(declare-const y Real)
(declare-const midstep Real)
(declare-const local_1 Real)
(declare-const foo_ret Real)

(assert (= local (/ x y)))
(assert (= midstep local))
(assert (= local_1 (+ midstep 1.0)))

(assert (= foo_ret local_1) :name toTransform)

; this is what I'd love to do - give Z3 a formula and a target set of variables
(special-simplify (= foo_ret local_1) (foo_ret x y))
; and have Z3 do the appropriate substitutions, etc to spit back 
; a "simplified" version in terms of foo_ret, x, and y, e.g.: 
;    (= foo_ret (+ (/ x y) 1.0))
我知道这并不是Z3的主要目标,但我知道它已经具备了一些简化/解决问题的能力。。。从帮助文本判断,我得到的印象是,有很多方法可以设计目标状态和实现目标的策略,但我无法根据Z3的
(help)
命令找到如何实现目标的信息(除非我遗漏了什么…)


我并不是真的想做任何复杂的事情-只是简单地替换/消除不在目标集中的符号。。。我想知道是否有什么方法可以诱使工具这么做?

z34.0支持战术。它们可用于预处理公式和应用多个变换。本教程包含有关此新功能的详细信息。命令
(帮助战术)
将显示Z3中可用的所有战术

也就是说,现有的策略没有一个能完全满足你的需求。我认为最接近的是量词消除策略/命令。在您的示例中,我们可以使用量词消除过程来消除
local
local_1
midesp
。当然,这个过程可能非常昂贵,而且它所做的远不止是替换变量。这里有一个例子。我使用命令
elim量词
而不是策略
qe
。 此外,正如您所观察到的,结果不一定是我们称之为“简化”的格式。我们通过量词消除程序提供的唯一保证是: 如果成功,则结果公式与输入公式等效。 我们可以用Z3证明
elim量词产生的结果确实等价于公式
(=foo_ret(+(/x y)1.0))


Z34.0支持战术。它们可用于预处理公式和应用多个变换。本教程包含有关此新功能的详细信息。命令
(帮助战术)
将显示Z3中可用的所有战术

也就是说,现有的策略没有一个能完全满足你的需求。我认为最接近的是量词消除策略/命令。在您的示例中,我们可以使用量词消除过程来消除
local
local_1
midesp
。当然,这个过程可能非常昂贵,而且它所做的远不止是替换变量。这里有一个例子。我使用命令
elim量词
而不是策略
qe
。 此外,正如您所观察到的,结果不一定是我们称之为“简化”的格式。我们通过量词消除程序提供的唯一保证是: 如果成功,则结果公式与输入公式等效。 我们可以用Z3证明
elim量词产生的结果确实等价于公式
(=foo_ret(+(/x y)1.0))

(declare-const x Real)
(declare-const y Real)
(declare-const foo_ret Real)

(set-option :pp-max-depth 100)

(elim-quantifiers 
  (exists ((local Real) (midstep Real) (local_1 Real))
    (and (= local (/ x y))
         (= midstep local)
         (= local_1 (+ midstep 1.0))
         (= foo_ret local_1))))