如何证明 Leon 中列表的大小?
How to prove size of a list in Leon?
我试图证明列表中的大小(元素数量)是非负的,但 Leon 未能证明它——它只是超时了。这个属性是Leon真的无法证明,还是我用错了?我的起点是我在论文 "An Overview of the Leon Verification System".
中读到的一个函数
import leon.lang._
import leon.annotation._
object ListSize {
sealed abstract class List
case class Cons(head: Int, tail: List) extends List
case object Nil extends List
def size(l: List) : Int = (l match {
case Nil => 0
case Cons(_, t) => 1 + size(t)
}) ensuring(_ >= 0)
}
以前版本的 Leon 将 Scala 的 Int
类型视为数学上的、无界的整数。最新版本将 Int
的值视为带符号的 32 位向量,并要求使用 BigInt
来表示无限整数。
在提供的示例中,Leon 尝试构建大小为 Int.MaxValue
的列表时超时,这是一个反例,它表明后置条件不适用于有界整数。
如果将 size
的 return 类型更改为 BigInt
,程序将按预期进行验证。
前面的答案都对,但如果我们希望使用 Int 而不是 BigInt 并且感觉合理列表的大小是非负的,则对我们没有帮助。以下简单的技巧可以解决这个问题并适用于不锈钢:
def listLength(l: List[T]): Int = {
l match {
case head :: tl => {
val tlLen = listLength(tl)
if(tlLen < Int.MaxValue) {
tlLen + 1
} else {
0
}
}
case Nil() => 0
}
} ensuring(0 <= _)
参见,例如,https://github.com/epfl-lara/bolts/blob/master/data-structures/seqs/ArrayList.scala in the bolts repository of https://stainless.epfl.ch/
我试图证明列表中的大小(元素数量)是非负的,但 Leon 未能证明它——它只是超时了。这个属性是Leon真的无法证明,还是我用错了?我的起点是我在论文 "An Overview of the Leon Verification System".
中读到的一个函数import leon.lang._
import leon.annotation._
object ListSize {
sealed abstract class List
case class Cons(head: Int, tail: List) extends List
case object Nil extends List
def size(l: List) : Int = (l match {
case Nil => 0
case Cons(_, t) => 1 + size(t)
}) ensuring(_ >= 0)
}
以前版本的 Leon 将 Scala 的 Int
类型视为数学上的、无界的整数。最新版本将 Int
的值视为带符号的 32 位向量,并要求使用 BigInt
来表示无限整数。
在提供的示例中,Leon 尝试构建大小为 Int.MaxValue
的列表时超时,这是一个反例,它表明后置条件不适用于有界整数。
如果将 size
的 return 类型更改为 BigInt
,程序将按预期进行验证。
前面的答案都对,但如果我们希望使用 Int 而不是 BigInt 并且感觉合理列表的大小是非负的,则对我们没有帮助。以下简单的技巧可以解决这个问题并适用于不锈钢:
def listLength(l: List[T]): Int = {
l match {
case head :: tl => {
val tlLen = listLength(tl)
if(tlLen < Int.MaxValue) {
tlLen + 1
} else {
0
}
}
case Nil() => 0
}
} ensuring(0 <= _)
参见,例如,https://github.com/epfl-lara/bolts/blob/master/data-structures/seqs/ArrayList.scala in the bolts repository of https://stainless.epfl.ch/