Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Z3 数据类型和量词模式/触发器_Z3 - Fatal编程技术网

Z3 数据类型和量词模式/触发器

Z3 数据类型和量词模式/触发器,z3,Z3,我观察到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 In

我观察到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不应该能够触发所有的
,因为它是由模式
(fun s1 i)
保护的,而Z3不应该(实际上不是)能够证明
s1=s2

相反,如果我将
Snap
声明为未解释的排序,那么最后的
检查sat
将产生
未知的
——这是我所期望的:

如果我假设
s1
s2
不同,即

(assert (not (= s1 s2)))
然后,在这两种情况下,最后的
检查sat
都会产生
unknown

为了方便起见,这里是rise4fun


Q:行为上的差异是一个bug,还是故意的?

这不是bug,因为z3没有对
sat
公式(或
sat
公式)说
unsat
。在存在量化公式的情况下,SMT解算器(通常)是不完整的。因此,当他们不确定
sat
中的输入公式是否正确时,他们有时会回答
unknown

例如:

a-当假设
s1
s2
不同时,使用匹配技术,z3不证明公式是正常的。事实上,没有任何形式的
(funs15)
基本术语与模式
(funs1i)
相匹配,这将允许从量化公式生成有用的实例
(>(bar 5)0)


b-如果你不认为
s1
s2
是不同的,你也无法得到证据。除了z3可能在内部假设当
Snap
是数据类型时
s1=s2
。只要没有与
s1=s2
相矛盾的内容,这是正确的。由于这一点以及匹配的模等式,基础项
(fun s2 5)
与模式
(fun s1 i)
匹配,并且生成了证明不可满足性所需的实例。

断言(而不是(=s1 s2))是必不可少的。使用基于模式的量词实例化,如果搜索的当前状态满足s1=s2,则模式匹配。在代数数据类型的情况下,Z3试图通过构造构造函数应用程序的最小模型来满足代数数据类型的公式。在Snap作为代数数据类型的情况下,s1和s2的最小模型都将其作为Snap.unit。此时,触发器被启用,因为术语E-match。换言之,对同余进行模化,变量I可以实例化为(funs1i)匹配(funs25),但设置I表示感谢。我理解为什么Z3报告
unknown
,但对于Z3报告
unsat
数据类型,我感到惊讶:要这样做,它必须触发公理,但给定触发器,它不应该被允许这样做-正是因为
s1=s2
未知。为什么Z3简单地假设s1=s2是合理的呢?这将不合理地删减一个证明分支(即
s1!=s2
),这显然是在
Snap
不是数据类型的情况下探索的。此外,如果Z3只是简单地添加了等式
s1=s2
,那么如果我添加了
(assert(not(=s1s2)))
,它应该报告
unsat
,而它没有。顺便说一句,我澄清了我的问题描述,既然你的回答让我得出结论,之前还不够清楚。如果你明确表示
(assert(not(=s1 s2))
,那么.z3不会假定
s1=s2
。在我的解释中,我已经说过,只有当没有任何东西与等式相矛盾时,z3才会假定
s1=s2
s1 s2
显然与等式相矛盾。只要没有任何矛盾,添加
s1=s2
是合理的,原因是:如果你找到某个公式的模型
F和s1=s2
,那么它也是
F
的模型。对于您的示例(据我所知),z3在假设
s1=s2
时,以及在实例化量化公式之前,会找到一个模型。但是,生成的实例(由于匹配模相等)与另一个与
s1=s2
无关的断言冲突。无需查找案例
s1s2
:输入公式为
unsat
。感谢您的解释。我仍然不明白为什么Z3——至少在我理解触发器的方式上——在
Snap
是数据类型的情况下报告
unsat
,但在
Snap
是未解释的排序时报告
unknown
——这是我在这两种情况下都希望得到的答案。当然,这可能本质上是一种影响内部启发式的“随机种子效应”,但也可能是数据类型和我不知道的未解释类型之间更系统的差异。
(assert (not (= s1 s2)))
(=> (forall I F(I))  (F(5)))