From a0474680f6b64d3441199dfad90ff2124ee2b4f8 Mon Sep 17 00:00:00 2001
From: Etienne Kneuss <etienne.kneuss@epfl.ch>
Date: Mon, 29 Sep 2014 18:57:44 +0200
Subject: [PATCH] Implement maps for CVC4, now that it supports constant arrays

reactivate tests for CVC4, if available. Remove non-linear testcase that
worked only on z3 (SumAndMax)
---
 project/Build.scala                           |   2 +-
 .../solvers/smtlib/SMTLIBCVC4Target.scala     |  39 +++-
 .../leon/solvers/smtlib/SMTLIBTarget.scala    | 220 +++++++++++++-----
 .../leon/solvers/smtlib/SMTLIBZ3Target.scala  |  81 -------
 .../purescala/valid/SumAndMax.scala           |  48 ----
 .../PureScalaVerificationRegression.scala     |   4 +-
 6 files changed, 204 insertions(+), 190 deletions(-)
 delete mode 100644 src/test/resources/regression/verification/purescala/valid/SumAndMax.scala

diff --git a/project/Build.scala b/project/Build.scala
index 343e7dd8b..34aa37019 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -80,6 +80,6 @@ object Leon extends Build {
     def project(repo: String, version: String) = RootProject(uri(s"${repo}#${version}"))
 
     lazy val bonsai      = project("git://github.com/colder/bonsai.git",     "8f485605785bda98ac61885b0c8036133783290a")
-    lazy val scalaSmtLib = project("git://github.com/regb/scala-smtlib.git", "acd60b52bac56e47ef1b855d91a1515a6d9178de")
+    lazy val scalaSmtLib = project("git://github.com/regb/scala-smtlib.git", "1b85768a2a5384170a6d90f4aea56ca7330939fd")
   }
 }
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
index b68f06ec1..7f14022d6 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala
@@ -10,9 +10,11 @@ import Common._
 import Trees._
 import Extractors._
 import TypeTrees._
+import TreeOps.simplestValue
 
 import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, _}
 import _root_.smtlib.parser.Commands._
+import _root_.smtlib.theories._
 import _root_.smtlib.interpreters.CVC4Interpreter
 
 trait SMTLIBCVC4Target extends SMTLIBTarget {
@@ -31,8 +33,10 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
           val cmd = DeclareSort(s, 0)
           sendCommand(cmd)
           Sort(SMTIdentifier(s))
+
         case SetType(base) =>
           Sort(SMTIdentifier(SSymbol("Set")), Seq(declareSort(base)))
+
         case _ =>
           super[SMTLIBTarget].declareSort(t)
       }
@@ -47,9 +51,22 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
     case (QualifiedIdentifier(SMTIdentifier(SSymbol("emptyset"), Seq()), _), SetType(base)) =>
       FiniteSet(Set()).setType(tpe)
 
-    case (FunctionApplication(SimpleSymbol(SSymbol("setenum")), elems), SetType(base)) =>
+    case (FunctionApplication(SimpleSymbol(SSymbol("__array_store_all__")), Seq(_, elem)), RawArrayType(k,v)) =>
+      RawArrayValue(k, Map(), fromSMT(elem, v))
+
+    case (FunctionApplication(SimpleSymbol(SSymbol("store")), Seq(arr, key, elem)), RawArrayType(k,v)) =>
+      val RawArrayValue(_, elems, base) = fromSMT(arr, tpe)
+
+      RawArrayValue(k, elems + (fromSMT(key, k) -> fromSMT(elem, v)), base)
+
+    case (FunctionApplication(SimpleSymbol(SSymbol("singleton")), elems), SetType(base)) =>
       FiniteSet(elems.map(fromSMT(_, base)).toSet).setType(tpe)
 
+    case (FunctionApplication(SimpleSymbol(SSymbol("insert")), elems), SetType(base)) =>
+      val selems = elems.init.map(fromSMT(_, base))
+      val FiniteSet(se) = fromSMT(elems.last, tpe)
+      FiniteSet(se ++ selems).setType(tpe)
+
     case (FunctionApplication(SimpleSymbol(SSymbol("union")), elems), SetType(base)) =>
       FiniteSet(elems.map(fromSMT(_, tpe) match {
         case FiniteSet(elems) => elems
@@ -59,6 +76,12 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
       super[SMTLIBTarget].fromSMT(s, tpe)
   }
 
+  def encodeMapType(tpe: TypeTree): TypeTree = tpe match {
+    case MapType(from, to) =>
+      TupleType(Seq(SetType(from), RawArrayType(from, to)))
+    case _ => sys.error("Woot")
+  }
+
   override def toSMT(e: Expr)(implicit bindings: Map[Identifier, Term]) = e match {
     case a @ FiniteArray(elems) =>
       val tpe @ ArrayType(base) = normalizeType(a.getType)
@@ -79,14 +102,22 @@ trait SMTLIBCVC4Target extends SMTLIBTarget {
       if (elems.isEmpty) {
         QualifiedIdentifier(SMTIdentifier(SSymbol("emptyset")), Some(declareSort(fs.getType)))
       } else {
-        FunctionApplication(SSymbol("singleton"), elems.toSeq.map(toSMT))
+        val selems = elems.toSeq.map(toSMT)
+
+        val sgt = FunctionApplication(SSymbol("singleton"), Seq(selems.head));
+
+        if (selems.size > 1) {
+          FunctionApplication(SSymbol("insert"), selems.tail :+ sgt)
+        } else {
+          sgt
+        }
       }
 
     case SubsetOf(ss, s) =>
-      FunctionApplication(SSymbol("subseteq"), Seq(toSMT(ss), toSMT(s)))
+      FunctionApplication(SSymbol("subset"), Seq(toSMT(ss), toSMT(s)))
 
     case ElementOfSet(e, s) =>
-      FunctionApplication(SSymbol("in"), Seq(toSMT(e), toSMT(s)))
+      FunctionApplication(SSymbol("member"), Seq(toSMT(e), toSMT(s)))
 
     case SetDifference(a, b) =>
       FunctionApplication(SSymbol("setminus"), Seq(toSMT(a), toSMT(b)))
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
index da8533fc4..303276bdf 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala
@@ -69,6 +69,19 @@ trait SMTLIBTarget {
   // Should NEVER escape past SMT-world
   case class RawArrayValue(keyTpe: TypeTree, elems: Map[Expr, Expr], default: Expr) extends Expr
 
+  def fromRawArray(r: RawArrayValue, tpe: TypeTree): Expr = tpe match {
+    case SetType(base) =>
+      assert(r.default == BooleanLiteral(false) && r.keyTpe == base)
+
+      FiniteSet(r.elems.keySet).setType(tpe)
+
+    case RawArrayType(from, to) =>
+      r
+
+    case _ =>
+      unsupported("Unable to extract from raw array for "+tpe)
+  }
+
   def unsupported(str: Any) = reporter.fatalError(s"Unsupported in smt-$targetName: $str")
 
   def declareSort(t: TypeTree): Sort = {
@@ -81,99 +94,164 @@ trait SMTLIBTarget {
         case RawArrayType(from, to) =>
           Sort(SMTIdentifier(SSymbol("Array")), Seq(declareSort(from), declareSort(to)))
 
+        case MapType(from, to) =>
+          declareMapSort(from, to)
+
         case TypeParameter(id) =>
           val s = id2sym(id)
           val cmd = DeclareSort(s, 0)
           sendCommand(cmd)
           Sort(SMTIdentifier(s))
+
         case _: ClassType | _: TupleType | _: ArrayType | UnitType =>
           declareStructuralSort(tpe)
+
         case _ =>
           unsupported("Sort "+t)
       }
     }
   }
 
-  def freshSym(id: Identifier): SSymbol = freshSym(id.name)
-  def freshSym(name: String): SSymbol = id2sym(FreshIdentifier(name))
+  var mapSort: Option[SSymbol] = None
+  var optionSort: Option[SSymbol] = None
 
-  def declareStructuralSort(t: TypeTree): Sort = {
+  def declareOptionSort(of: TypeTree): Sort = {
+    optionSort match {
+      case None =>
+        val t      = SSymbol("T")
 
-    def getHierarchy(ct: ClassType): (ClassType, Seq[CaseClassType]) = ct match {
-      case act: AbstractClassType =>
-        (act, act.knownCCDescendents)
-      case cct: CaseClassType =>
-        cct.parent match {
-          case Some(p) =>
-            getHierarchy(p)
-          case None =>
-            (cct, List(cct))
-        }
+        val s      = SSymbol("Option")
+        val some   = SSymbol("Some")
+        val some_v = SSymbol("Some_v")
+        val none   = SSymbol("None")
+
+        val caseSome = SList(some, SList(some_v, t))
+        val caseNone = SList(none)
+
+        val cmd = NonStandardCommand(SList(SSymbol("declare-datatypes"), SList(t), SList(SList(s, caseSome, caseNone))))
+        sendCommand(cmd)
+
+        optionSort = Some(s)
+      case _ =>
     }
 
-    case class DataType(sym: SSymbol, cases: Seq[Constructor])
-    case class Constructor(sym: SSymbol, tpe: TypeTree, fields: Seq[(SSymbol, TypeTree)])
+    Sort(SMTIdentifier(optionSort.get), Seq(declareSort(of)))
+  }
+
+  def declareMapSort(from: TypeTree, to: TypeTree): Sort = {
+    mapSort match {
+      case None =>
+        val m = SSymbol("Map")
+        val a = SSymbol("A")
+        val b = SSymbol("B")
+        mapSort = Some(m)
 
-    var datatypes = Map[TypeTree, DataType]()
+        val optSort = declareOptionSort(to)
 
+        val arraySort = Sort(SMTIdentifier(SSymbol("Array")),
+                             Seq(Sort(SMTIdentifier(a)), optSort))
 
-    def findDependencies(t: TypeTree): Unit = t match {
-      case ct: ClassType =>
-        val (root, sub) = getHierarchy(ct)
+        val cmd = DefineSort(m, Seq(a, b), arraySort)
+        sendCommand(cmd)
+      case _ =>
+    }
 
-        if (!(datatypes contains root) && !(sorts containsA root)) {
-          val sym = freshSym(ct.id)
+    Sort(SMTIdentifier(mapSort.get), Seq(declareSort(from), declareSort(to)))
+  }
 
-          val conss = sub.map { case cct =>
-            Constructor(freshSym(cct.id), cct, cct.fields.map(vd => (freshSym(vd.id), vd.tpe)))
-          }
 
-          datatypes += root -> DataType(sym, conss)
 
-          // look for dependencies
-          for (ct <- root +: sub; f <- ct.fields) findDependencies(f.tpe)
-        }
-      case tt @ TupleType(bases) =>
-        if (!(datatypes contains t) && !(sorts containsA t)) {
-          val sym = freshSym("tuple"+bases.size)
+  def freshSym(id: Identifier): SSymbol = freshSym(id.name)
+  def freshSym(name: String): SSymbol = id2sym(FreshIdentifier(name))
+
+  def getHierarchy(ct: ClassType): (ClassType, Seq[CaseClassType]) = ct match {
+    case act: AbstractClassType =>
+      (act, act.knownCCDescendents)
+    case cct: CaseClassType =>
+      cct.parent match {
+        case Some(p) =>
+          getHierarchy(p)
+        case None =>
+          (cct, List(cct))
+      }
+  }
 
-          val c = Constructor(freshSym(sym.name), tt, bases.zipWithIndex.map {
-            case (tpe, i) => (freshSym("_"+(i+1)), tpe)
-          })
 
-          datatypes += tt -> DataType(sym, Seq(c))
+  case class DataType(sym: SSymbol, cases: Seq[Constructor])
+  case class Constructor(sym: SSymbol, tpe: TypeTree, fields: Seq[(SSymbol, TypeTree)])
 
-          bases.foreach(findDependencies)
-        }
+  def findDependencies(t: TypeTree, dts: Map[TypeTree, DataType] = Map()): Map[TypeTree, DataType] = t match {
+    case ct: ClassType =>
+      val (root, sub) = getHierarchy(ct)
 
-      case UnitType =>
-        if (!(datatypes contains t) && !(sorts containsA t)) {
+      if (!(dts contains root) && !(sorts containsA root)) {
+        val sym = freshSym(ct.id)
+
+        val conss = sub.map { case cct =>
+          Constructor(freshSym(cct.id), cct, cct.fields.map(vd => (freshSym(vd.id), vd.tpe)))
+        }
 
-          val sym = freshSym("Unit")
+        var cdts = dts + (root -> DataType(sym, conss))
 
-          datatypes += t -> DataType(sym, Seq(Constructor(freshSym(sym.name), t, Nil)))
+        // look for dependencies
+        for (ct <- root +: sub; f <- ct.fields) {
+          cdts ++= findDependencies(f.tpe, cdts)
         }
 
-      case at @ ArrayType(base) =>
-        if (!(datatypes contains t) && !(sorts containsA t)) {
-          val sym = freshSym("array")
+        cdts
+      } else {
+        dts
+      }
 
-          val c = Constructor(freshSym(sym.name), at, List(
-            (freshSym("size"), Int32Type),
-            (freshSym("content"), RawArrayType(Int32Type, base))
-          ))
+    case tt @ TupleType(bases) =>
+      if (!(dts contains t) && !(sorts containsA t)) {
+        val sym = freshSym("tuple"+bases.size)
 
-          datatypes += at -> DataType(sym, Seq(c))
+        val c = Constructor(freshSym(sym.name), tt, bases.zipWithIndex.map {
+          case (tpe, i) => (freshSym("_"+(i+1)), tpe)
+        })
 
-          findDependencies(base)
+        var cdts = dts + (tt -> DataType(sym, Seq(c)))
+
+        for (b <- bases) {
+          cdts ++= findDependencies(b, cdts)
         }
+        cdts
+      } else {
+        dts
+      }
 
-      case _ =>
-    }
+    case UnitType =>
+      if (!(dts contains t) && !(sorts containsA t)) {
 
-    // Populates the dependencies of the structural type to define.
-    findDependencies(t)
+        val sym = freshSym("Unit")
+
+        dts + (t -> DataType(sym, Seq(Constructor(freshSym(sym.name), t, Nil))))
+      } else {
+        dts
+      }
+
+    case at @ ArrayType(base) =>
+      if (!(dts contains t) && !(sorts containsA t)) {
+        val sym = freshSym("array")
+
+        val c = Constructor(freshSym(sym.name), at, List(
+          (freshSym("size"), Int32Type),
+          (freshSym("content"), RawArrayType(Int32Type, base))
+        ))
+
+        var cdts = dts + (at -> DataType(sym, Seq(c)))
+
+        findDependencies(base, cdts)
+      } else {
+        dts
+      }
+
+    case _ =>
+      dts
+  }
 
+  def declareDatatypes(datatypes: Map[TypeTree, DataType]): Unit = {
     // We pre-declare ADTs
     for ((tpe, DataType(sym, _)) <- datatypes) {
       sorts += tpe -> Sort(SMTIdentifier(sym))
@@ -199,6 +277,13 @@ trait SMTLIBTarget {
 
     val cmd = DeclareDatatypes(adts)
     sendCommand(cmd)
+  }
+
+  def declareStructuralSort(t: TypeTree): Sort = {
+    // Populates the dependencies of the structural type to define.
+    val datatypes = findDependencies(t)
+
+    declareDatatypes(datatypes)
 
     sorts.toB(t)
   }
@@ -310,6 +395,33 @@ trait SMTLIBTarget {
         val constructor = constructors.toB(tpe)
         FunctionApplication(constructor, Seq(ssize, newcontent))
 
+      /**
+       * ===== Map operations =====
+       */
+      case m @ FiniteMap(elems) =>
+        val mt @ MapType(from, to) = m.getType
+        val ms = declareSort(mt)
+
+        val opt = declareOptionSort(to)
+
+        var res: Term = FunctionApplication(QualifiedIdentifier(SMTIdentifier(SSymbol("const")), Some(ms)), List(QualifiedIdentifier(SMTIdentifier(SSymbol("None")), Some(opt))))
+        for ((k, v) <- elems) {
+          res = ArraysEx.Store(res, toSMT(k), FunctionApplication(SSymbol("Some"), List(toSMT(v))))
+        }
+
+        res
+
+      case MapGet(m, k) =>
+        declareSort(m.getType)
+        FunctionApplication(SSymbol("Some_v"), List(ArraysEx.Select(toSMT(m), toSMT(k))))
+
+      case MapIsDefinedAt(m, k) =>
+        declareSort(m.getType)
+        FunctionApplication(SSymbol("is-Some"), List(ArraysEx.Select(toSMT(m), toSMT(k))))
+
+      /**
+       * ===== Everything else =====
+       */
 
       case e @ UnaryOperator(u, _) =>
         e match {
diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
index 48d602402..f781cdc48 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala
@@ -29,15 +29,11 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
   val extSym = SSymbol("_")
 
   var setSort: Option[SSymbol] = None
-  var mapSort: Option[SSymbol] = None
-  var optionSort: Option[SSymbol] = None
 
   override def declareSort(t: TypeTree): Sort = {
     val tpe = normalizeType(t)
     sorts.cachedB(tpe) {
       tpe match {
-        case MapType(from, to) =>
-          declareMapSort(from, to)
         case SetType(base) =>
           declareSetSort(base)
         case _ =>
@@ -64,49 +60,6 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
     Sort(SMTIdentifier(setSort.get), Seq(declareSort(of)))
   }
 
-  def declareOptionSort(of: TypeTree): Sort = {
-    optionSort match {
-      case None =>
-        val t      = SSymbol("T")
-
-        val s      = SSymbol("Option")
-        val some   = SSymbol("Some")
-        val some_v = SSymbol("Some_v")
-        val none   = SSymbol("None")
-
-        val caseSome = SList(some, SList(some_v, t))
-        val caseNone = none
-
-        val cmd = NonStandardCommand(SList(SSymbol("declare-datatypes"), SList(t), SList(SList(s, caseSome, caseNone))))
-        sendCommand(cmd)
-
-        optionSort = Some(s)
-      case _ =>
-    }
-
-    Sort(SMTIdentifier(optionSort.get), Seq(declareSort(of)))
-  }
-
-  def declareMapSort(from: TypeTree, to: TypeTree): Sort = {
-    mapSort match {
-      case None =>
-        val m = SSymbol("Map")
-        val a = SSymbol("A")
-        val b = SSymbol("B")
-        mapSort = Some(m)
-        declareOptionSort(to)
-
-        val arraySort = Sort(SMTIdentifier(SSymbol("Array")),
-                             Seq(Sort(SMTIdentifier(a)), Sort(SMTIdentifier(optionSort.get), Seq(Sort(SMTIdentifier(b))))))
-
-        val cmd = DefineSort(m, Seq(a, b), arraySort)
-        sendCommand(cmd)
-      case _ =>
-    }
-
-    Sort(SMTIdentifier(mapSort.get), Seq(declareSort(from), declareSort(to)))
-  }
-
   override def fromSMT(s: Term, tpe: TypeTree)(implicit lets: Map[SSymbol, Term], letDefs: Map[SSymbol, DefineFun]): Expr = (s, tpe) match {
     case (SimpleSymbol(s), tp: TypeParameter) =>
       val n = s.name.split("!").toList.last
@@ -145,27 +98,6 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
 
         FunctionApplication(constructors.toB(tpe), List(toSMT(IntLiteral(elems.size)), ar))
 
-      /**
-       * ===== Map operations =====
-       */
-      case MapGet(m, k) =>
-        declareSort(m.getType)
-        FunctionApplication(SSymbol("Some_v"), List(ArraysEx.Select(toSMT(m), toSMT(k))))
-
-      case MapIsDefinedAt(m, k) =>
-        declareSort(m.getType)
-        FunctionApplication(SSymbol("is-Some"), List(ArraysEx.Select(toSMT(m), toSMT(k))))
-
-      case m @ FiniteMap(elems) =>
-        val ms = declareSort(m.getType)
-
-        var res: Term = FunctionApplication(QualifiedIdentifier(SMTIdentifier(SSymbol("const")), Some(ms)), List(SSymbol("None")))
-        for ((k, v) <- elems) {
-          res = ArraysEx.Store(res, toSMT(k), FunctionApplication(SSymbol("Some"), List(toSMT(v))))
-        }
-
-        res
-
       /**
        * ===== Set operations =====
        */
@@ -230,19 +162,6 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
       unsupported("Unable to extract "+s)
   }
 
-  def fromRawArray(r: RawArrayValue, tpe: TypeTree): Expr = tpe match {
-    case SetType(base) =>
-      assert(r.default == BooleanLiteral(false) && r.keyTpe == base)
-
-      FiniteSet(r.elems.keySet).setType(tpe)
-
-    case RawArrayType(from, to) =>
-      r
-
-    case _ =>
-      unsupported("Unable to extract from raw array for "+tpe)
-  }
-
   // EK: We use get-model instead in order to extract models for arrays
   override def getModel: Map[Identifier, Expr] = {
 
diff --git a/src/test/resources/regression/verification/purescala/valid/SumAndMax.scala b/src/test/resources/regression/verification/purescala/valid/SumAndMax.scala
deleted file mode 100644
index ea6305cd9..000000000
--- a/src/test/resources/regression/verification/purescala/valid/SumAndMax.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2009-2014 EPFL, Lausanne */
-
-import leon.lang._
-import leon.annotation._
-
-object SumAndMax {
-  sealed abstract class List
-  case class Cons(head : Int, tail : List) extends List
-  case class Nil() extends List
-
-  def max(list : List) : Int = {
-    require(list != Nil())
-    list match {
-      case Cons(x, Nil()) => x
-      case Cons(x, xs) => {
-        val m2 = max(xs)
-        if(m2 > x) m2 else x
-      }
-    }
-  }
-
-  def sum(list : List) : Int = list match {
-    case Nil() => 0
-    case Cons(x, xs) => x + sum(xs)
-  }
-
-  def size(list : List) : Int = (list match {
-    case Nil() => 0
-    case Cons(_, xs) => 1 + size(xs)
-  }) ensuring(_ >= 0)
-
-  def allPos(list : List) : Boolean = list match {
-    case Nil() => true
-    case Cons(x, xs) => x >= 0 && allPos(xs)
-  }
-
-  def prop0(list : List) : Boolean = {
-    require(list != Nil())
-    !allPos(list) || max(list) >= 0
-  }.holds
-
-  @induct
-  def property(list : List) : Boolean = {
-    // This precondition was given in the problem but isn't actually useful :D
-    // require(allPos(list))
-    sum(list) <= size(list) * (if(list == Nil()) 0 else max(list))
-  }.holds
-}
diff --git a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
index 878bc19da..a52125854 100644
--- a/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
+++ b/src/test/scala/leon/test/verification/PureScalaVerificationRegression.scala
@@ -71,9 +71,9 @@ class PureScalaVerificationRegression extends LeonTestSuite {
     }
 
     val isCVC4Available = try {
-      //new CVC4Interpreter()
+      new CVC4Interpreter()
       // @EK: CVC4 works on most testcases already, but not all and thus cannot be used in regression.
-      false
+      true
     } catch {
       case e: java.io.IOException =>
         false
-- 
GitLab