简体   繁体   English

为什么 smtlib/z3/cvc4 允许多次声明同一个常量?

[英]Why does smtlib/z3/cvc4 allow to declare the same constant more than once?

I have a question about declare-const in smtlib.我对 smtlib 中的declare-const有疑问。

For example,例如,

In z3/cvc4, the following program doesn't report an error:在z3/cvc4中,以下程序不报错:

C:\Users\Chansey>z3 -in
(declare-const x Int)
(declare-const x Bool)

In the smt-lib-reference, it says that在 smt-lib-reference 中,它说

(declare-fun f (s1... sn) s)... The command reports an error if a function symbol with name f is already present in the current signature. (declare-fun f (s1... sn) s)... 如果名称为 f 的 function 符号已经存在于当前签名中,该命令将报告错误。

So the sort s is included in the entire signature of the x , is that right?所以 sort s包含在x的整个签名中,对吗?

But why is it so?但为什么会这样呢? What is the motivation behind it?其背后的动机是什么?

In my understanding, the x is variable identifier and in general (eg in some general programming languages) we are not allowed to declare the same variable with different types.在我的理解中, x是变量标识符,通常(例如在某些通用编程语言中)我们不允许用不同类型声明相同的变量。 So I think the above code is best to report an error.所以我觉得上面的代码最好报错。

I once thought that perhaps z3/smtlib can support redefinition?, but not...我曾经想过也许z3/smtlib可以支持重定义?,但不...

C:\Users\Chansey>z3 -in
(declare-const x Int)
(declare-const x Bool)
(assert (= x true))
(error "line 3 column 11: ambiguous constant reference, more than one constant with the same sort, use a qualified expre
ssion (as <symbol> <sort>) to disambiguate x")

So the above code is definitely wrong, why not report the error earlier?那么上面的代码肯定是错误的,为什么不早点报错呢?

PS.附言。 If I use the same sort, then it will report an error (that great, I hope the Bool case can also report the error):如果我用同样的sort,那么就会报错(那太好了,希望Bool case也能报错):

C:\Users\Chansey>z3 -in
(declare-fun x () Int)
(declare-fun x () Int)
(error "line 2 column 21: invalid declaration, constant 'x' (with the given signature) already declared")

Thanks.谢谢。

In SMTLib, a symbol is identified not just by its name, but also by its sort.在 SMTLib 中,符号不仅通过其名称来标识,还通过其类别来标识。 And it's perfectly fine to use the same name, so long as you have a different sort, as you observed.使用相同的名称完全没问题,只要您有不同的类型,正如您观察到的那样。 Here's an example:这是一个例子:

(set-logic ALL)
(set-option :produce-models true)
(declare-fun x () Int)
(declare-fun x () Bool)

(assert (= (as x Int) 4))
(assert (= (as x Bool) true))
(check-sat)
(get-model)
(get-value ((as x Int)))
(get-value ((as x Bool)))

This prints:这打印:

sat
(
  (define-fun x () Bool
    true)
  (define-fun x () Int
    4)
)
(((as x Int) 4))
(((as x Bool) true))

Note how we use the as construct to disambiguate between the two x 's.请注意我们如何使用as结构来消除两个x之间的歧义。 This is explained in Section 3.6.4 of http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2021-05-12.pdf这在 http 的第 3.6.4 节中有解释://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2021-05-12.pdf

Having said that, I do agree the part of the document you quoted isn't very clear about this, and perhaps can use a bit of a clarifying text.话虽如此,我确实同意你引用的文件部分对此不是很清楚,也许可以使用一些澄清文本。

Regarding what the motivation is for allowing this sort of usage: There are two main reasons.关于允许这种用法的动机是什么:有两个主要原因。 The first is o simplify generating SMTLib.第一个是简化 SMTLib 的生成。 Note that SMTLib is usually not intended to be hand-written.请注意,SMTLib 通常不适合手写。 It's often generated from a higher-level system that uses an SMT solver underneath.它通常由在底层使用 SMT 求解器的更高级别的系统生成。 So being flexible in allowing symbols to share name so long as they can be distinguished by explicit sort annotations can be beneficial when you use SMTLib as an intermediate language between a higher-level system and the solver itself.因此,当您将 SMTLib 用作高级系统和求解器本身之间的中间语言时,只要可以通过显式排序注释区分它们,就可以灵活地允许符号共享名称。 But when you're writing SMTLib by hand, you should probably avoid this sort of duplication if you can, for clarity if nothing else.但是,当您手动编写 SMTLib 时,如果可以的话,您可能应该避免这种重复,至少为了清楚起见。

The second reason is to allow for a limited form of "overloading" to be used.第二个原因是允许使用有限形式的“重载”。 For instance, think about the SMTLib function distinct .例如,想想 SMTLib function distinct This function can operate on any type of object ( Int , Bool , Real etc.), yet it's always called distinct .这个 function 可以对 object 的任何类型( IntBoolReal等)进行操作,但它总是被称为distinct (We don't have distinct-int , distinct-bool etc.) The solver "distinguishes" which one you meant by doing a bit of an analysis, but in cases it cannot, you can help it along with an as declaration as well. (我们没有distinct-intdistinct-bool等)求解器通过做一些分析来“区分”你的意思,但如果它不能,你也可以通过as声明来帮助它. So, theory symbols can be overloaded in this way, which is also the case for = , + , * , etc. Of course, SMTLib does not allow for users to define such overloaded names, but as the document states in footnote 29 on page 91, this restriction might be removed in the future.因此,可以以这种方式重载理论符号, =+*等也是如此。当然,SMTLib不允许用户定义此类重载名称,但正如文档在第 29 页脚注中所述91,将来可能会取消此限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM