在不锈钢中证明功能终止时匹配错误

时间:2017-03-05 01:21:15

标签: scala leon

我有这个代码证明在Stainless / Leon中终止排序算法。请注意,所使用的排名功能或措施不是正确的,因为它来自家庭作业集。

import stainless.lang._
import stainless.collection._


object QuickSort {

  def isSorted(list: List[BigInt]): Boolean = list match {
    case Cons(x, xs @ Cons(y, _)) => x <= y && isSorted(xs)
    case _ => true
  }

  def quickSort(list: List[BigInt]): List[BigInt] = {
    decreases((list.size,0))
    list match {
      case Nil() => Nil[BigInt]()
      case Cons(x, xs) => par(x, Nil(), Nil(), xs)
    }
  } ensuring { res => isSorted(res) }

  def par(x: BigInt, l: List[BigInt], r: List[BigInt], ls: List[BigInt]): List[BigInt] = {
    decreases((l.size,l.size))
    ls match {
      case Nil() => quickSort(l) ++ Cons(x, quickSort(r))
      case Cons(x2, xs2) => if (x2 <= x) par(x, Cons(x2, l), r, xs2) else par(x, l, Cons(x2, r), xs2)
    }
  }
}

使用此代码我收到以下错误(我会说这来自scala前端):

[ Error  ] exercise.scala:14:5: error: overloaded method value decreases with alternatives:
[ Error  ]   (rank: (Int, Int, Int, Int, Int))Unit <and>
[ Error  ]   (rank: (Int, Int, Int, Int))Unit <and>
[ Error  ]   (rank: (Int, Int, Int))Unit <and>
[ Error  ]   (rank: (Int, Int))Unit <and>
[ Error  ]   (rank: Int)Unit <and>
[ Error  ]   (rank: (BigInt, BigInt, BigInt, BigInt, BigInt))Unit <and>
[ Error  ]   (rank: (BigInt, BigInt, BigInt, BigInt))Unit <and>
[ Error  ]   (rank: (BigInt, BigInt, BigInt))Unit <and>
[ Error  ]   (rank: (BigInt, BigInt))Unit <and>
[ Error  ]   (rank: BigInt)Unit
[ Error  ]  cannot be applied to ((BigInt, Int))
               decreases((list.size,0))
               ^

所以我import scala.BigInt._并将decreases((list.size,0))转换为decreases((list.size,BigInt(0)))。最后,这给出了以下例外(来自不锈钢/不锈钢部件):

Exception in thread "main" scala.MatchError: <untyped> (of class inox.ast.Types$Untyped$)
    at stainless.extraction.oo.MethodLifting$BaseTransformer$1.transform(MethodLifting.scala:139)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:115)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:114)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
    at scala.collection.immutable.List.map(List.scala:285)
    at inox.ast.TreeTransformer$class.transform(TreeOps.scala:114)
    at stainless.extraction.oo.MethodLifting$BaseTransformer$1.transform(MethodLifting.scala:149)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:115)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:114)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
    at scala.collection.immutable.List.map(List.scala:285)
    at inox.ast.TreeTransformer$class.transform(TreeOps.scala:114)
    at stainless.extraction.oo.MethodLifting$BaseTransformer$1.transform(MethodLifting.scala:149)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:115)
    at inox.ast.TreeTransformer$$anonfun$3.apply(TreeOps.scala:114)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
    at scala.collection.immutable.List.map(List.scala:285)
    at inox.ast.TreeTransformer$class.transform(TreeOps.scala:114)
    at stainless.extraction.oo.MethodLifting$BaseTransformer$1.transform(MethodLifting.scala:149)
    at inox.ast.TreeTransformer$class.transform(TreeOps.scala:185)
    at stainless.extraction.oo.MethodLifting$BaseTransformer$1.transform(MethodLifting.scala:133)
    at stainless.extraction.oo.MethodLifting$$anonfun$38.apply(MethodLifting.scala:285)
    at stainless.extraction.oo.MethodLifting$$anonfun$38.apply(MethodLifting.scala:281)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.Iterator$class.foreach(Iterator.scala:893)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1336)
    at scala.collection.MapLike$DefaultValuesIterable.foreach(MapLike.scala:206)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
    at scala.collection.AbstractTraversable.map(Traversable.scala:104)
    at stainless.extraction.oo.MethodLifting$class.transform(MethodLifting.scala:281)
    at stainless.extraction.oo.package$extractor$.transform(package.scala:16)
    at stainless.extraction.oo.package$extractor$.transform(package.scala:16)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.ast.SymbolTransformer$$anon$3.transform(TreeOps.scala:262)
    at inox.Program$$anon$2.<init>(Program.scala:78)
    at inox.Program$class.transform(Program.scala:76)
    at stainless.frontends.scalac.CodeExtraction$Extraction$$anon$1.transform(CodeExtraction.scala:187)
    at stainless.SimpleComponent$class.extract(Component.scala:46)
    at stainless.termination.TerminationComponent$.extract(TerminationComponent.scala:8)
    at stainless.SimpleComponent$class.apply(Component.scala:50)
    at stainless.termination.TerminationComponent$.apply(TerminationComponent.scala:8)
    at stainless.MainHelpers$$anonfun$main$1.apply(MainHelpers.scala:76)
    at stainless.MainHelpers$$anonfun$main$1.apply(MainHelpers.scala:76)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at stainless.MainHelpers$class.main(MainHelpers.scala:76)
    at stainless.Main$.main(Main.scala:5)
    at stainless.Main.main(Main.scala)

有关为何发生这种情况的任何想法以及如何解决?我也试过调用decreases(list.size,BigInt(0))和其他几个版本,但它没有用。

修改

显然,删除行import scala.BigInt._可以解决问题所以知道为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

不锈钢从scalac前端提取树的方式需要一个特定的树结构来进行BigInt提取。从BigInt(_)导入scala.BigInt._时,此结构略有不同。

这没有多大意义,可以通过使用符号而不是精确的树匹配来避免。我会考虑修复这个问题。