ChooseWithWitness.scala [raw]


/* Copyright 2009-2016 EPFL, Lausanne */

import stainless.annotation._
import stainless.lang._

object ChooseWithWitness {
    sealed abstract class List
    case class Cons(head: Int, tail: List) extends List
    case class Nil() extends List

    def size(l: List) : BigInt = (l match {
        case Nil() => BigInt(0)
        case Cons(_, t) => 1 + size(t)
    }) ensuring(res => res >= 0)

    def content(l: List) : Set[Int] = l match {
      case Nil() => Set.empty[Int]
      case Cons(x, xs) => Set(x) ++ content(xs)
    }

    def createListOfSize(i: BigInt): List = {
      require(i >= 0)

      if (i == BigInt(0)) {
        Nil()
      } else {
        Cons(0, createListOfSize(i - 1))
      }
    } ensuring ( size(_) == i )

    def listOfSize(i: BigInt): List = {
      require(i >= 0)

      if (i == BigInt(0)) {
        Nil()
      } else {
        assert(size(createListOfSize(i)) == i) // provides choose quantification with a matcher
        choose[List] { (res: List) => size(res) == i }
      }
    } ensuring ( size(_) == i )

    def listOfSize2(i: BigInt): List = {
      require(i >= 0)

      if (i > 0) {
        Cons(0, listOfSize(i-1))
      } else {
        Nil()
      }
    } ensuring ( size(_) == i )
}

back