epfl-lara / stainless

Verification framework and tool for higher-order Scala programs
https://epfl-lara.github.io/stainless/
Apache License 2.0
357 stars 51 forks source link

Crash in princess in code with Scala's Int (signed 32 bit) #1328

Open vkuncak opened 1 year ago

vkuncak commented 1 year ago

Running Stainless https://github.com/epfl-lara/stainless/commit/bcc5b4d4e2fe0cc975345e7244ad24ecc3b2585b on the bolts ScalaList https://github.com/epfl-lara/bolts/commit/3f4df349a45a7e62c020f55eaedaaeb626c2b41d using command line args --no-colors --timeout=5 ScalaList.scala --vc-cache=no --solvers=princess produces

inox.package$FatalError: method can only be applied to terms with a bit-vector sort
    at inox.package$FatalError$.apply(package.scala:24)
    at inox.Reporter.onFatal(Reporter.scala:43)
    at inox.Reporter.internalError(Reporter.scala:61)
    at inox.Reporter.internalError(Reporter.scala:113)
    at inox.Reporter.internalError(Reporter.scala:116)
    at stainless.verification.VerificationChecker.checkVC(VerificationChecker.scala:347)
    at stainless.verification.VerificationChecker.checkVC$(VerificationChecker.scala:52)
    at stainless.verification.VerificationChecker$Checker$1.checkVC(VerificationChecker.scala:431)
    at stainless.verification.VerificationChecker.processVC$1(VerificationChecker.scala:153)
    at stainless.verification.VerificationChecker.$anonfun$4(VerificationChecker.scala:181)
    at scala.concurrent.Future$.$anonfun$traverse$1(Future.scala:861)
    at scala.collection.IterableOnceOps.foldLeft(IterableOnce.scala:646)
    at scala.collection.IterableOnceOps.foldLeft$(IterableOnce.scala:642)
    at scala.collection.AbstractIterator.foldLeft(Iterator.scala:1293)
    at scala.concurrent.Future$.traverse(Future.scala:861)
    at stainless.verification.VerificationChecker.checkVCs(VerificationChecker.scala:182)
    at stainless.verification.VerificationChecker.checkVCs$(VerificationChecker.scala:52)
    at stainless.verification.VerificationChecker$Checker$1.checkVCs(VerificationChecker.scala:431)
    at stainless.verification.VerificationChecker.verify(VerificationChecker.scala:111)
    at stainless.verification.VerificationChecker.verify$(VerificationChecker.scala:52)
    at stainless.verification.VerificationChecker$Checker$1.verify(VerificationChecker.scala:431)
    at stainless.verification.VerificationChecker$.verify(VerificationChecker.scala:445)
    at stainless.verification.VerificationRun.execute(VerificationComponent.scala:117)
    at stainless.verification.VerificationRun.execute(VerificationComponent.scala:80)
    at stainless.ComponentRun.apply(Component.scala:106)
    at stainless.ComponentRun.apply$(Component.scala:54)
    at stainless.verification.VerificationRun.apply(VerificationComponent.scala:53)
    at stainless.frontend.SplitCallBack.$anonfun$10(SplitCallBack.scala:196)
    at scala.collection.immutable.List.map(List.scala:246)
    at scala.collection.immutable.List.map(List.scala:79)
    at stainless.frontend.SplitCallBack.processFunctionsSymbols(SplitCallBack.scala:198)
    at stainless.frontend.SplitCallBack.$anonfun$9(SplitCallBack.scala:170)
    at stainless.extraction.utils.ConcurrentCache.getOrElseUpdate(ConcurrentCaches.scala:15)
    at stainless.frontend.SplitCallBack.processFunctions(SplitCallBack.scala:170)
    at stainless.frontend.SplitCallBack.processSymbols(SplitCallBack.scala:156)
    at stainless.frontend.SplitCallBack.endExtractions(SplitCallBack.scala:78)
    at stainless.frontend.ThreadedFrontend$$anon$1.run(ThreadedFrontend.scala:34)
    at java.base/java.lang.Thread.run(Thread.java:833)

with Princess trace

error: Error: method can only be applied to terms with a bit-vector sort. Trace:
error: - ap.theories.bitvectors.ModuloArithmetic$.extractBitWidth(ModuloArithmetic.scala:295)
error: - ap.theories.bitvectors.ModuloArithmetic$.extractBitWidth(ModuloArithmetic.scala:282)
error: - ap.theories.bitvectors.ModuloArithmetic$.bvslt(ModuloArithmetic.scala:144)
error: - ap.theories.bitvectors.ModuloArithmetic$.bvsgt(ModuloArithmetic.scala:150)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.parseFormula(AbstractPrincessSolver.scala:176)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.$anonfun$7(AbstractPrincessSolver.scala:150)
error: - scala.collection.immutable.ArraySeq.map(ArraySeq.scala:75)
error: - scala.collection.immutable.ArraySeq.map(ArraySeq.scala:35)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.parseFormula(AbstractPrincessSolver.scala:150)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.$anonfun$6(AbstractPrincessSolver.scala:146)
error: - scala.collection.immutable.ArraySeq.map(ArraySeq.scala:75)
error: - scala.collection.immutable.ArraySeq.map(ArraySeq.scala:35)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.parseFormula(AbstractPrincessSolver.scala:146)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.parseFormula(AbstractPrincessSolver.scala:162)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.parseFormula(AbstractPrincessSolver.scala:156)
error: - inox.solvers.princess.AbstractPrincessSolver$inoxToPrincess$.apply(AbstractPrincessSolver.scala:381)
error: - inox.solvers.princess.PrincessSolver$TemplatesImpl.mkEncoder(PrincessSolver.scala:92)
error: - inox.solvers.princess.PrincessSolver$TemplatesImpl.mkEncoder(PrincessSolver.scala:91)
error: - inox.solvers.unrolling.Templates$Template$.$anonfun$30(Templates.scala:648)
error: - inox.solvers.unrolling.Templates$Template$.$anonfun$38$$anonfun$1(Templates.scala:686)
error: - scala.collection.immutable.List.map(List.scala:246)
error: - scala.collection.immutable.List.map(List.scala:79)
error: - inox.solvers.unrolling.Templates$Template$.$anonfun$38(Templates.scala:686)
error: - scala.collection.Iterator$$anon$10.nextCur(Iterator.scala:587)
error: - scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:601)
error: - scala.collection.immutable.List.prependedAll(List.scala:155)
error: - scala.collection.immutable.List$.from(List.scala:684)
error: - scala.collection.immutable.List$.from(List.scala:681)
error: - scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
error: - scala.collection.immutable.Iterable$.from(Iterable.scala:35)
error: - scala.collection.immutable.Iterable$.from(Iterable.scala:32)
error: - scala.collection.IterableOps$WithFilter.flatMap(Iterable.scala:894)
error: - inox.solvers.unrolling.Templates$Template$.encode(Templates.scala:686)
error: - inox.solvers.unrolling.Templates.instantiate(Templates.scala:856)
error: - inox.solvers.unrolling.Templates.instantiateExpr(Templates.scala:893)
error: - inox.solvers.unrolling.Templates.instantiateExpr$(Templates.scala:11)
error: - inox.solvers.princess.PrincessSolver$TemplatesImpl.instantiateExpr(PrincessSolver.scala:78)
error: - inox.solvers.unrolling.AbstractUnrollingSolver.$anonfun$5(UnrollingSolver.scala:231)
error: - scala.util.Try$.apply(Try.scala:210)
error: - inox.utils.TimerStorage.runAndGetTime(Timer.scala:93)
error: - inox.utils.TimerStorage.run(Timer.scala:88)
error: - inox.solvers.unrolling.AbstractUnrollingSolver.assertCnstr$$anonfun$1(UnrollingSolver.scala:233)
error: - scala.util.Try$.apply(Try.scala:210)
error: - inox.utils.TimerStorage.runAndGetTime(Timer.scala:93)
error: - inox.utils.TimerStorage.run(Timer.scala:88)
error: - inox.solvers.unrolling.AbstractUnrollingSolver.assertCnstr(UnrollingSolver.scala:242)
error: - inox.solvers.unrolling.AbstractUnrollingSolver.assertCnstr(UnrollingSolver.scala:211)
error: - stainless.verification.VerificationChecker.$anonfun$10(VerificationChecker.scala:299)
error: - scala.util.Try$.apply(Try.scala:210)
error: - inox.utils.TimerStorage.runAndGetTime(Timer.scala:93)
error: - stainless.verification.VerificationChecker.checkVC(VerificationChecker.scala:302)
error: - stainless.verification.VerificationChecker.checkVC$(VerificationChecker.scala:52)
error: - stainless.verification.VerificationChecker$Checker$1.checkVC(VerificationChecker.scala:431)
error: - stainless.verification.VerificationChecker.processVC$1(VerificationChecker.scala:153)
error: - stainless.verification.VerificationChecker.$anonfun$4(VerificationChecker.scala:181)
error: - scala.concurrent.Future$.$anonfun$traverse$1(Future.scala:861)
error: - scala.collection.IterableOnceOps.foldLeft(IterableOnce.scala:646)
error: - scala.collection.IterableOnceOps.foldLeft$(IterableOnce.scala:642)
error: - scala.collection.AbstractIterator.foldLeft(Iterator.scala:1293)
error: - scala.concurrent.Future$.traverse(Future.scala:861)
error: - stainless.verification.VerificationChecker.checkVCs(VerificationChecker.scala:182)
error: - stainless.verification.VerificationChecker.checkVCs$(VerificationChecker.scala:52)
error: - stainless.verification.VerificationChecker$Checker$1.checkVCs(VerificationChecker.scala:431)
error: - stainless.verification.VerificationChecker.verify(VerificationChecker.scala:111)
error: - stainless.verification.VerificationChecker.verify$(VerificationChecker.scala:52)
error: - stainless.verification.VerificationChecker$Checker$1.verify(VerificationChecker.scala:431)
error: - stainless.verification.VerificationChecker$.verify(VerificationChecker.scala:445)
error: - stainless.verification.VerificationRun.execute(VerificationComponent.scala:117)
error: - stainless.verification.VerificationRun.execute(VerificationComponent.scala:80)
error: - stainless.ComponentRun.apply(Component.scala:106)
error: - stainless.ComponentRun.apply$(Component.scala:54)
error: - stainless.verification.VerificationRun.apply(VerificationComponent.scala:53)
error: - stainless.frontend.SplitCallBack.$anonfun$10(SplitCallBack.scala:196)
error: - scala.collection.immutable.List.map(List.scala:246)
error: - scala.collection.immutable.List.map(List.scala:79)
error: - stainless.frontend.SplitCallBack.processFunctionsSymbols(SplitCallBack.scala:198)
error: - stainless.frontend.SplitCallBack.$anonfun$9(SplitCallBack.scala:170)
error: - stainless.extraction.utils.ConcurrentCache.getOrElseUpdate(ConcurrentCaches.scala:15)
error: - stainless.frontend.SplitCallBack.processFunctions(SplitCallBack.scala:170)
error: - stainless.frontend.SplitCallBack.processSymbols(SplitCallBack.scala:156)
error: - stainless.frontend.SplitCallBack.endExtractions(SplitCallBack.scala:78)
error: - stainless.frontend.ThreadedFrontend$$anon$1.run(ThreadedFrontend.scala:34)
error: - java.base/java.lang.Thread.run(Thread.java:833)
error: method can only be applied to terms with a bit-vector sort
mario-bucev commented 1 year ago

Minimized:

object Test {
  def app(x: Int) = {
    require(x > 0)
    x + x
  }.ensuring(_ > 0)
}

Apparently, this stems from https://github.com/uuverifiers/princess/blob/b8280e70269a554c20b52dccb735af80e4bf1ab0/src/ap/theories/bitvectors/ModuloArithmetic.scala#L306-L312 Maybe there is a case SignedBVSort missing?

vkuncak commented 1 year ago

@mario-bucev what is the status of this including the potential fix to Princess?

mario-bucev commented 1 year ago

The small typo fix has been merged https://github.com/uuverifiers/princess/pull/3 this issue can be resumed

vkuncak commented 1 year ago

Great! This would be indeed of value for having some checks on Scala idomatic code, done for Scala and in Scala :)

mario-bucev commented 1 year ago

Running the fix on the minimized example works but not on the ScalaList:

Click to expand ``` java.lang.UnsupportedOperationException: Value too big to be converted to int at ap.basetypes.IdealInt.intValueSafe(IdealInt.scala:842) at ap.types.UninterpretedSortTheory$InfUninterpretedSort.decodeToTerm(UninterpretedSort.scala:110) at ap.types.TypeTheory$.$anonfun$generateDecoderData$15(TypeTheory.scala:249) at scala.collection.Iterator$$anon$10.nextCur(Iterator.scala:587) at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:601) at scala.collection.mutable.Growable.addAll(Growable.scala:61) at scala.collection.mutable.Growable.addAll$(Growable.scala:57) at scala.collection.immutable.SetBuilderImpl.addAll(Set.scala:396) at scala.collection.immutable.Set$.from(Set.scala:353) at scala.collection.IterableOnceOps.toSet(IterableOnce.scala:1258) at scala.collection.IterableOnceOps.toSet$(IterableOnce.scala:1258) at scala.collection.AbstractIterator.toSet(Iterator.scala:1293) at ap.types.TypeTheory$.generateDecoderData(TypeTheory.scala:248) at ap.SimpleAPI$$anon$2.$anonfun$getDataFor$1(SimpleAPI.scala:3239) at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:454) at ap.SimpleAPI$$anon$2.getDataFor(SimpleAPI.scala:3237) at ap.types.Sort$$anon$1.apply(Sort.scala:351) at ap.types.Sort$$anon$1.apply(Sort.scala:348) at ap.SimpleAPI.toTerm$1(SimpleAPI.scala:3126) at ap.SimpleAPI.$anonfun$partialModel$5(SimpleAPI.scala:3144) at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563) at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561) at ap.terfor.equations.EquationSet.foreach(EquationSet.scala:37) at ap.SimpleAPI.partialModel(SimpleAPI.scala:3136) at inox.solvers.princess.AbstractPrincessSolver.internalCheck(AbstractPrincessSolver.scala:631) at inox.solvers.princess.AbstractPrincessSolver.checkAssumptions(AbstractPrincessSolver.scala:656) at inox.solvers.unrolling.AbstractUnrollingSolver.$anonfun$48(UnrollingSolver.scala:829) at scala.util.Try$.apply(Try.scala:210) at inox.utils.TimerStorage.runAndGetTime(Timer.scala:93) at inox.utils.TimerStorage.run(Timer.scala:88) at inox.solvers.unrolling.AbstractUnrollingSolver.checkAssumptions$$anonfun$1$$anonfun$1(UnrollingSolver.scala:831) at scala.util.Try$.apply(Try.scala:210) at inox.solvers.unrolling.AbstractUnrollingSolver.checkAssumptions$$anonfun$1(UnrollingSolver.scala:899) at scala.util.Try$.apply(Try.scala:210) at inox.utils.TimerStorage.runAndGetTime(Timer.scala:93) at inox.utils.TimerStorage.run(Timer.scala:88) at inox.solvers.unrolling.AbstractUnrollingSolver.checkAssumptions(UnrollingSolver.scala:904) at inox.solvers.SolverFactory$PrincessImpl$1.inox$solvers$combinators$TimeoutSolver$$super$checkAssumptions(SolverFactory.scala:309) at inox.solvers.combinators.TimeoutSolver.checkAssumptions$$anonfun$1(TimeoutSolver.scala:44) at inox.utils.TimeoutFor.interruptAfter(TimeoutFor.scala:36) at inox.solvers.combinators.TimeoutSolver.checkAssumptions(TimeoutSolver.scala:45) at inox.solvers.combinators.TimeoutSolver.checkAssumptions$(TimeoutSolver.scala:10) at inox.solvers.SolverFactory$PrincessImpl$1.checkAssumptions(SolverFactory.scala:309) at inox.solvers.unrolling.AbstractUnrollingSolver.check(UnrollingSolver.scala:134) at inox.solvers.SolverFactory$PrincessImpl$1.inox$solvers$combinators$TimeoutSolver$$super$check(SolverFactory.scala:309) at inox.solvers.combinators.TimeoutSolver.check$$anonfun$1(TimeoutSolver.scala:32) at inox.utils.TimeoutFor.interruptAfter(TimeoutFor.scala:36) at inox.solvers.combinators.TimeoutSolver.check(TimeoutSolver.scala:33) at inox.solvers.combinators.TimeoutSolver.check$(TimeoutSolver.scala:10) at inox.solvers.SolverFactory$PrincessImpl$1.check(SolverFactory.scala:309) at inox.solvers.SimpleSolverAPI.solveVALID(SimpleSolverAPI.scala:22) at inox.solvers.SimpleSolverAPI.solveVALID$(SimpleSolverAPI.scala:6) at inox.solvers.SimpleSolverAPI$$anon$1.solveVALID(SimpleSolverAPI.scala:57) at stainless.termination.Strengthener.strengthen$1(Strengthener.scala:91) at stainless.termination.Strengthener.strengthenPostconditions$$anonfun$3(Strengthener.scala:100) at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15) at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10) at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563) at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561) at scala.collection.AbstractIterable.foreach(Iterable.scala:926) at scala.collection.IterableOps$WithFilter.foreach(Iterable.scala:896) at stainless.termination.Strengthener.strengthenPostconditions(Strengthener.scala:111) at stainless.termination.Strengthener.strengthenPostconditions$(Strengthener.scala:10) at stainless.termination.TerminationChecker$ProcessingPipelineImpl$1$IntegerOrderingImpl.strengthenPostconditions(TerminationChecker.scala:122) at stainless.termination.RelationProcessor.run$$anonfun$1(RelationProcessor.scala:29) at scala.util.Try$.apply(Try.scala:210) at inox.utils.TimerStorage.runAndGetTime(Timer.scala:93) at inox.utils.TimerStorage.run(Timer.scala:88) at stainless.termination.RelationProcessor.run(RelationProcessor.scala:108) at stainless.termination.ProcessingPipeline$$anon$3.next(ProcessingPipeline.scala:230) at stainless.termination.ProcessingPipeline$$anon$3.next(ProcessingPipeline.scala:225) at scala.collection.Iterator$$anon$6.hasNext(Iterator.scala:471) at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563) at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561) at scala.collection.AbstractIterator.foreach(Iterator.scala:1293) at stainless.termination.ProcessingPipeline.runPipeline(ProcessingPipeline.scala:258) at stainless.termination.ProcessingPipeline.terminates(ProcessingPipeline.scala:158) at stainless.termination.ProcessingPipeline.terminates$(ProcessingPipeline.scala:9) at stainless.termination.TerminationChecker$ProcessingPipelineImpl$1.terminates(TerminationChecker.scala:115) at stainless.termination.MeasureInference$TransformerContext.$anonfun$3(MeasureInference.scala:130) at scala.util.Try$.apply(Try.scala:210) at inox.utils.TimerStorage.runAndGetTime(Timer.scala:93) at inox.utils.TimerStorage.run(Timer.scala:88) at stainless.termination.MeasureInference$TransformerContext.inferMeasure(MeasureInference.scala:131) at stainless.termination.MeasureInference.extractFunction(MeasureInference.scala:183) at stainless.termination.MeasureInference.$anonfun$8$$anonfun$1(MeasureInference.scala:199) at stainless.extraction.utils.ConcurrentCache.cached(ConcurrentCaches.scala:26) at stainless.extraction.ExtractionCaches$ExtractionCache.cached(ExtractionCaches.scala:165) at stainless.termination.MeasureInference.$anonfun$8(MeasureInference.scala:199) at scala.collection.Iterator$$anon$9.next(Iterator.scala:577) at scala.collection.immutable.List.prependedAll(List.scala:156) at scala.collection.immutable.List$.from(List.scala:684) at scala.collection.immutable.List$.from(List.scala:681) at scala.collection.IterableFactory$Delegate.from(Factory.scala:288) at scala.collection.immutable.Iterable$.from(Iterable.scala:35) at scala.collection.immutable.Iterable$.from(Iterable.scala:32) at scala.collection.IterableFactory$Delegate.from(Factory.scala:288) at scala.collection.IterableOps.map(Iterable.scala:675) at scala.collection.IterableOps.map$(Iterable.scala:675) at scala.collection.AbstractIterable.map(Iterable.scala:926) at stainless.termination.MeasureInference.extractSymbols(MeasureInference.scala:199) at stainless.termination.MeasureInference.extractSymbols(MeasureInference.scala:194) at stainless.extraction.CachingPhase.extract(ExtractionPipeline.scala:126) at stainless.extraction.CachingPhase.extract$(ExtractionPipeline.scala:105) at stainless.termination.MeasureInference.extract(MeasureInference.scala:10) at stainless.extraction.utils.DebugPipeline.extract$$anonfun$1$$anonfun$1(DebugPipeline.scala:139) at scala.util.Try$.apply(Try.scala:210) at inox.utils.TimerStorage.runAndGetTime(Timer.scala:93) at inox.utils.TimerStorage.run(Timer.scala:88) at stainless.extraction.utils.DebugPipeline.extract$$anonfun$1(DebugPipeline.scala:139) at stainless.extraction.utils.DebugSymbols.debug(DebugPipeline.scala:64) at stainless.extraction.utils.DebugSymbols.debug$(DebugPipeline.scala:29) at stainless.extraction.utils.DebugPipeline.debug(DebugPipeline.scala:127) at stainless.extraction.utils.DebugPipeline.extract(DebugPipeline.scala:140) at stainless.extraction.ExtractionPipeline$AndThenImpl$1.extract(ExtractionPipeline.scala:48) at stainless.extraction.ExtractionPipeline$AndThenImpl$1.extract(ExtractionPipeline.scala:47) at stainless.extraction.ExtractionPipeline$AndThenImpl$1.extract(ExtractionPipeline.scala:47) at stainless.ComponentRun.extract(Component.scala:95) at stainless.ComponentRun.extract$(Component.scala:55) at stainless.verification.VerificationRun.extract(VerificationComponent.scala:48) at stainless.ComponentRun.apply(Component.scala:105) at stainless.ComponentRun.apply$(Component.scala:55) at stainless.verification.VerificationRun.apply(VerificationComponent.scala:48) at stainless.frontend.SplitCallBack.$anonfun$10(SplitCallBack.scala:196) at scala.collection.immutable.List.map(List.scala:246) at scala.collection.immutable.List.map(List.scala:79) at stainless.frontend.SplitCallBack.processFunctionsSymbols(SplitCallBack.scala:198) at stainless.frontend.SplitCallBack.$anonfun$9(SplitCallBack.scala:170) at stainless.extraction.utils.ConcurrentCache.getOrElseUpdate(ConcurrentCaches.scala:15) at stainless.frontend.SplitCallBack.processFunctions(SplitCallBack.scala:170) at stainless.frontend.SplitCallBack.processSymbols(SplitCallBack.scala:156) at stainless.frontend.SplitCallBack.endExtractions(SplitCallBack.scala:78) at stainless.frontend.ThreadedFrontend$$anon$1.run(ThreadedFrontend.scala:34) at java.base/java.lang.Thread.run(Thread.java:833) ```

This error should not be too hard to fix, it's just about indexing into a Stream with something bigger than an Int.

mario-bucev commented 1 year ago

Actually, the problem may be on our side. Minimized example:

import stainless.lang._

object ScalaListMin {
  sealed abstract class List[+A] {
    def :: [B >: A](elem: B): List[B] =  Cons(elem, this)
  }
  case object Nil extends List[Nothing]
  final case class Cons[+A](first: A, next: List[A]) extends List[A]

  def listOfCons(n: Int): List[List[Int]] = {
    if (n <= 0) Nil
    else Cons(42, Nil) :: listOfCons(n-1)
  }
}

The crash happens during measure inference for listOfCons. Having an invariant list makes the error go away.

vkuncak commented 1 year ago

@mario-bucev this seems resolved?

mario-bucev commented 1 year ago

It does not crash anymore, however two VCs timeout for zipWith, namely match exhaustiveness and the precondition of the recursive call.

mario-bucev commented 1 year ago

@samarion We were wondering whether you could shed some light (if possible!) on this snippet that does not verify with Princess:

import stainless.lang._
object ScalaList {
  sealed abstract class List[+A] {
    def :: [B >: A](elem: B): List[B] =  Cons(elem, this)

    def length: Long = {
      this match {
        case Nil => 0
        case Cons(h, t) =>
          val tLen = t.length
          if (tLen == Long.MaxValue) tLen
          else 1 + tLen
      }
    } ensuring(_ >= 0)
  }
  case object Nil extends List[Nothing]
  final case class Cons[+A](first: A, next: List[A]) extends List[A]

  def zipWith[A,B,C](f: (A,B) => C)(l1: List[A], l2: List[B]): List[C] = {
    decreases(l1)
    require(l1.length == l2.length && l1.length < Int.MaxValue)
    /*
    Match exhaustiveness:
    !isList$0(l1$29, A$147) || !isList$0(l2$27, B$83) || length$1(A$147, l1$29) != length$1(B$83, l2$27) 
      || length$1(A$147, l1$29) >= 2147483647.toLong || l1$29.isInstanceOf[Nil$2] && l2$27.isInstanceOf[Nil$2] 
      || !l1$29.isInstanceOf[Cons$2] || !l2$27.isInstanceOf[Cons$2] || {
      val l1$32: { x$115: Object$0 | (isList$0(x$115, A$147)): @dropConjunct  } = l1$29.next$1
      length$1(A$147, l1$32) == length$1(B$83, l2$27.next$1) && length$1(A$147, l1$32) < 2147483647.toLong
    }
    */
    (l1, l2) match {
      case (Nil, Nil) => Nil
      case (Cons(a,as), Cons(b,bs)) => 
        /*
        Precondition of recursive call:
        !isList$0(l1$29, A$147) || !isList$0(l2$27, B$83) || length$1(A$147, l1$29) != length$1(B$83, l2$27) 
          || length$1(A$147, l1$29) >= 2147483647.toLong || l1$29.isInstanceOf[Nil$2] && l2$27.isInstanceOf[Nil$2] 
          || l1$29.isInstanceOf[Cons$2] && l2$27.isInstanceOf[Cons$2]
        */
        Cons[C](f(a,b), zipWith(f)(as, bs))
    }
  }
}