英文:
Are Int and Real somehow compatible in SMT-LIB?
问题
在SMT-LIB中,等号运算符通常要求它的操作数具有相同的类型。例如,这是一个错误:
(set-logic QF_LIRA)
(declare-fun a () Bool)
(declare-fun b () Real)
(assert (= a b))
(check-sat)
然而,我预期这个也会是一个错误:
(set-logic QF_LIRA)
(declare-fun a () Int)
(declare-fun b () Real)
(assert (= a b))
(check-sat)
但是Yices和Z3都接受它而没有投诉。
我漏掉了什么?
英文:
The equality operator in SMT-LIB generally requires, unsurprisingly, that its operands be of the same type. For example, this is an error:
(set-logic QF_LIRA)
(declare-fun a () Bool)
(declare-fun b () Real)
(assert (= a b))
(check-sat)
However, I expected this to be likewise an error:
(set-logic QF_LIRA)
(declare-fun a () Int)
(declare-fun b () Real)
(assert (= a b))
(check-sat)
But Yices and Z3 both accept it without complaint.
What am I missing?
答案1
得分: 2
严格来说,SMTLib 不允许这样的混合和匹配。(请参阅 https://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2021-05-12.pdf 的第37页,其中明确指出 =
必须接受两个相同排序的参数。)
然而,大多数求解器在处理时都比较“宽松”,也就是说,它们会在认为有必要时引入强制转换。我个人认为这是有问题的:强制转换几乎从不有用(特别是在一种通常由工具生成的语言中),有时它们会隐藏用户本想表达的一件事,而用户却表达了错误的东西,而系统不知何故地赋予了它一种含义。(你可以将这与许多编程语言中不同类型的算术混合和匹配进行比较。但我离题了。)
话虽如此,你可以要求大多数求解器“更加符合要求”:
$ z3 smtlib2_compliant=true a.smt2
success
success
success
(error "line 4 column 14: Sort mismatch at argument #1 for function (declare-fun = (Real Real) Bool) supplied sort is Int")
sat
请注意命令行上的 smtlib2_compliant
参数。类似地,cvc5 也可以更加严格:
$ cvc5 --strict-parsing a.smt2
(error "Parse Error: a.smt2:4.15: Subexpressions must have the same type:
Equation: (= a b)
Type 1: Int
Type 2: Real")
请注意,我明确需要传递 --strict-parsing
参数,因为如果没有该标志,它也会插入强制转换。
我个人的意见是,它们应该始终保持符合要求;但现实状况是,大多数求解器都引入了这些强制转换,最好的情况下会导致混淆,最糟糕的情况下会隐藏错误。例如,你无法真正知道它是将实数“向下转换”(即以某种方式截断)为整数并检查相等性;还是将整数“向上转换”为实数。除非实际检查代码本身,否则很难判断发生了哪种情况。(在这种特定情况下,这两个求解器都将整数向上转换为实数;所以它是安全的。)
英文:
Strictly speaking, such mixing-and-matching is not allowed by SMTLib. (See page 37 of https://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2021-05-12.pdf, where it clearly states =
must take two arguments of the same sort.)
However, most solvers are "lenient" in their processing; i.e., they introduce coercions when they think it "makes sense." I personally find that problematic: Coercions are hardly ever useful (especially in a language that's meant to be generated by tools in general), and sometimes they can hide bugs where the user wanted to say one thing but said the wrong thing, and the system somehow assigned a meaning to it. (You can compare this to mixing and matching of arithmetic with different types in many programming languages. But I digress.)
Having said that, you can ask most solvers to be "more compliant:"
$ z3 smtlib2_compliant=true a.smt2
success
success
success
(error "line 4 column 14: Sort mismatch at argument #1 for function (declare-fun = (Real Real) Bool) supplied sort is Int")
sat
Note the smtlib2_compliant
parameter on the command line. Similarly, cvc5 can be made more strict too:
$ cvc5 --strict-parsing a.smt2
(error "Parse Error: a.smt2:4.15: Subexpressions must have the same type:
Equation: (= a b)
Type 1: Int
Type 2: Real
")
Note that I explicitly had to pass --strict-parsing
argument, as it also inserts the coercion without that flag.
My personal opinion is that they should all be compliant at all times; but the state of the affairs is that most solvers introduce these coercions leading to confusion at best, and hiding bugs at worst. For instance, you don't really know if it "downcasts" (i.e., truncates in some way) the real to an integer and checks the equality; or if it "upcasts" the integer to a real. There's no easy way to tell which one has happened without actually checking the code itself. (In this particular case, both solvers upcast the integer to a real; so it's sound.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论