我目前正在尝试使用Z3作为有限的引擎(使用Alloy(关系逻辑/语言)编写的规范)。我使用UFBV作为目标语言。
我使用Z3选项(set-option :pull-nested-quantifiers true)
检测到问题。
对于两个语义相同的SMT规格Spec1和Spec2,Z3超时(200秒)用于证明Spec1,但证明了Spec2。
Spec1和Spec2之间唯一不同的是它们具有不同的函数标识符(因为我使用java哈希名称)。这可能与错误有关吗?
我想分享和讨论的第二个观察是UFBV背景下的“iff
”运算符。如果设置了(set-logic UFBV)
,则不支持此运算符。我的解决方案是使用“=”,但如果操作数包含深度嵌套的量词并且设置了“pull-nested-quantifiers
”,则这不能很好地工作。另一种解决方案是使用双重含义。
现在的问题是:
对于UFBV中的模型“iff
”还有其他更好的解决方案,因为我认为,使用双重含义通常会松散可用的语义信息以进行改进/简化。
http://i12www.ira.uka.de/~elghazi/tmp/
你可以找到: spec1 和 spec2 两个(我认为)语义相同的SMT规范, spec3 一个SMT规范使用“= “模拟”iff
“,z3超时。
答案 0 :(得分:4)
UFBV
逻辑的默认策略对您的问题无效。实际上,默认策略在不到1秒的时间内解决了所有这些策略。要强制Z3使用默认策略,您只需在脚本中注释以下行。
; (set-logic UFBV)
; (set-option :pull-nested-quantifiers true)
; (set-option :macro-finder true)
如果警告信息困扰您,您可以添加:
(set-option :print-warning false)
话虽如此,我会尝试解决你提出的问题。 标识符名称是否会影响Z3的行为?是的,他们这样做。 从版本3.0开始,我们开始在Z3表达式上使用总订单来执行操作,例如:对associative-commutative运算符的参数进行排序。 此总订单基于标识符名称。 具有讽刺意味的是,这种修改是出于用户反馈。在以前的版本中,我们使用内部ID执行操作,例如排序,并在许多不同的启发式中断开联系。但是,这些ID基于Z3创建/删除表达式的顺序,该顺序基于用户声明符号的顺序。因此,Z3 2.x行为会受到诸如删除未使用的声明等微不足道的修改的影响。
关于iff
,它不是SMT-LIB 2.0标准的一部分。在SMT-LIB 2.0中,=
用于公式和术语。为了确保Z3完全符合SMT-LIB 2.0标准,每当用户指定SMT-LIB支持的逻辑(或很快被支持,如UFBV)时,Z3仅“加载”其中定义的符号。当没有指定逻辑时,Z3假设用户正在使用包含Z3中所有支持的理论的“Z3逻辑”,以及许多额外的aliases
,例如:iff
用于布尔=
,if
ite
等等。