FunctionCaching.scala [raw]


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

object FunctionCaching {

  case class FunCache(var cached: Map[BigInt, BigInt])

  def fun(x: BigInt)(implicit funCache: FunCache): BigInt = {
    funCache.cached.get(x) match {
      case None() =>
        val res = 2*x + 42
        funCache.cached = funCache.cached.updated(x, res)
        res
      case Some(cached) =>
        cached + 1
    }
  }

  def funWronglyCached(x: BigInt, trash: List[BigInt]): Boolean = {
    implicit val cache = FunCache(Map())
    val res1 = fun(x)
    multipleCalls(trash)
    val res2 = fun(x)
    res1 == res2
  } holds
// Counterexample for postcondition violation in `funWronglyCached`:
//   when x is:
//     -21
//   when trash is:
//     Nil[BigInt]()


  def multipleCalls(args: List[BigInt])(implicit funCache: FunCache): Unit = args match {
    case Nil() => ()
    case x::xs => fun(x); multipleCalls(xs)
  }

}

back