我观察到Z3的量词触发行为(我试过4.4.0和4.4.2.3f02beb8203b)的差异,我无法解释。请考虑以下程序:
(set-option :auto_config false)
(set-option :smt.mbqi false)
(declare-datatypes () ((Snap
(Snap.unit)
(Snap.combine (Snap.first Snap) (Snap.second Snap))
)))
(declare-fun fun (Snap Int) Bool)
(declare-fun bar (Int) Int)
(declare-const s1 Snap)
(declare-const s2 Snap)
(assert (forall ((i Int)) (!
(> (bar i) 0)
:pattern ((fun s1 i))
)))
(assert (fun s2 5))
(assert (not (> (bar 5) 0)))
(check-sat) ; unsat
据我理解,unsat
意外:Z3不应该触发forall
,因为它受到模式{{1}的保护}和Z3不应该(实际上不是)证明(fun s1 i)
。
相反,如果我声明s1 = s2
是未解释的排序,那么最终的Snap
会产生check-sat
- 这就是我期望的:< / p>
unknown
如果我假设(set-option :auto_config false)
(set-option :smt.mbqi false)
(declare-sort Snap 0)
...
(check-sat) ; unknown
和s1
不同,即
s2
然后最终的(assert (not (= s1 s2)))
在两种情况下都会产生check-sat
。
为方便起见,这里是the example on rise4fun。
问:行为的差异是错误还是打算?
答案 0 :(得分:2)
断言(不是(= s1 s2))是必不可少的。使用基于模式的量化器实例化,如果搜索的当前状态满足s1 = s2,则模式匹配。在代数数据类型的情况下,Z3通过根据构造函数应用程序构建最小模型来尝试满足具有代数数据类型的公式。在Snap作为代数数据类型的情况下,s1的最小模型,s2将它们都作为Snap.unit。此时,触发器已启用,因为术语是E-match。换句话说,以同形为模,我可以实例化变量I(fun s1 I)匹配(fun s2 5),但设置I&lt; - 5.启用触发器后,量化器被实例化并且公理< / p>
(=> (forall I F(I)) (F(5)))
添加(其中F是量词下的公式)。
这使得能够推断矛盾并推断出不满意。
当Snap未被解释时,Z3会尝试构建一个模型,其中术语s1和s2不同。由于没有什么可以迫使这些术语相等,所以它们仍然是不同的
答案 1 :(得分:0)
这不是一个错误,因为z3没有对unsat
公式说sat
(对sat
公式说unsat
。在存在量化公式的情况下,SMT求解器(通常)不完整。因此,当他们不确定unknown
中的输入公式时,他们有时会回答sat
。
对于你的例子:
a - 通过匹配技术,当你假设s1
和s2
不同时,z3不能证明公式是正常的。事实上,ground term
形式(fun s1 5)
matches
(fun s1 i)
模式(> (bar 5) 0)
,并且允许从您的s1
生成有用的实例s2
量化公式;
b - 当您不认为s1 = s2
和Snap
不同时,您也无法获得证明。除了当s1 = s2
是数据类型时,z3可能在内部假设为(fun s2 5)
。只要没有任何内容与(fun s1 i)
相矛盾,这是正确的。由于这一点并且匹配模数相等,基础项cut
与模式cut -d: -f1 filename
匹配,并且生成了证明不可满足性的所需实例。