From 859cfa888a0049c386cbab5808b0a6e1bbaee905 Mon Sep 17 00:00:00 2001 From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch> Date: Mon, 31 Aug 2015 13:10:14 +0200 Subject: [PATCH] Improve Identifier API, and "undefined" errors Identifier fields which can be private are now private. Identifier now inherits Ordered. Define Undefined error, and its subclass SolverUndefinedError. Use it mainly in solvers. --- ...nFatalError.scala => LeonExceptions.scala} | 5 ++ .../scala/leon/codegen/CompilationUnit.scala | 11 ++-- .../scala/leon/datagen/VanuatooDataGen.scala | 2 +- .../leon/evaluators/CodeGenEvaluator.scala | 2 +- src/main/scala/leon/purescala/Common.scala | 35 +++++++----- src/main/scala/leon/solvers/ADTManager.scala | 8 ++- src/main/scala/leon/solvers/Solver.scala | 13 ++++- .../leon/solvers/SolverUnsupportedError.scala | 15 +++++ .../smtlib/SMTLIBCVC4ProofSolver.scala | 3 +- .../smtlib/SMTLIBCVC4QuantifiedSolver.scala | 7 ++- .../solvers/smtlib/SMTLIBCVC4Solver.scala | 4 +- .../leon/solvers/smtlib/SMTLIBSolver.scala | 36 +++++------- .../smtlib/SMTLIBZ3QuantifiedSolver.scala | 3 +- .../leon/solvers/smtlib/SMTLIBZ3Solver.scala | 6 +- .../leon/solvers/z3/AbstractZ3Solver.scala | 55 ++++++++----------- .../scala/leon/solvers/z3/FairZ3Solver.scala | 2 +- .../leon/synthesis/rules/CEGISLike.scala | 5 +- .../leon/test/helpers/WithLikelyEq.scala | 2 +- 18 files changed, 122 insertions(+), 92 deletions(-) rename src/main/scala/leon/{LeonFatalError.scala => LeonExceptions.scala} (59%) create mode 100644 src/main/scala/leon/solvers/SolverUnsupportedError.scala diff --git a/src/main/scala/leon/LeonFatalError.scala b/src/main/scala/leon/LeonExceptions.scala similarity index 59% rename from src/main/scala/leon/LeonFatalError.scala rename to src/main/scala/leon/LeonExceptions.scala index 70646a94c..eeaadd09a 100644 --- a/src/main/scala/leon/LeonFatalError.scala +++ b/src/main/scala/leon/LeonExceptions.scala @@ -2,8 +2,13 @@ package leon +import purescala.Common.Tree + case class LeonFatalError(msg: Option[String]) extends Exception(msg.getOrElse("")) object LeonFatalError { def apply(msg: String) = new LeonFatalError(Some(msg)) } + +class Unsupported(t: Tree, msg: String)(implicit ctx: LeonContext) + extends Exception(s"${t.asString}@${t.getPos} $msg") \ No newline at end of file diff --git a/src/main/scala/leon/codegen/CompilationUnit.scala b/src/main/scala/leon/codegen/CompilationUnit.scala index 3d7fbe17d..54e3485d6 100644 --- a/src/main/scala/leon/codegen/CompilationUnit.scala +++ b/src/main/scala/leon/codegen/CompilationUnit.scala @@ -178,9 +178,12 @@ class CompilationUnit(val ctx: LeonContext, } l - // Just slightly overkill... case _ => - compileExpression(e, Seq()).evalToJVM(Seq(),monitor) + throw LeonFatalError("Unexpected expression in exprToJVM") + + // Just slightly overkill... + //case _ => + // compileExpression(e, Seq()).evalToJVM(Seq(),monitor) } // Note that this may produce untyped expressions! (typically: sets, maps) @@ -274,9 +277,9 @@ class CompilationUnit(val ctx: LeonContext, var compiledN = 0 - def compileExpression(e: Expr, args: Seq[Identifier]): CompiledExpression = { + def compileExpression(e: Expr, args: Seq[Identifier])(implicit ctx: LeonContext): CompiledExpression = { if(e.getType == Untyped) { - throw new IllegalArgumentException(s"Cannot compile untyped expression [$e].") + throw new Unsupported(e, s"Cannot compile untyped expression.") } compiledN += 1 diff --git a/src/main/scala/leon/datagen/VanuatooDataGen.scala b/src/main/scala/leon/datagen/VanuatooDataGen.scala index 72a905b82..0cf311562 100644 --- a/src/main/scala/leon/datagen/VanuatooDataGen.scala +++ b/src/main/scala/leon/datagen/VanuatooDataGen.scala @@ -236,7 +236,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { val newExpr = replaceFromIDs(map, expression) - val ce = unit.compileExpression(newExpr, Seq(tid)) + val ce = unit.compileExpression(newExpr, Seq(tid))(ctx) Some((args : Expr) => { try { diff --git a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala index caf22c1e9..64456226b 100644 --- a/src/main/scala/leon/evaluators/CodeGenEvaluator.scala +++ b/src/main/scala/leon/evaluators/CodeGenEvaluator.scala @@ -36,7 +36,7 @@ class CodeGenEvaluator(ctx : LeonContext, val unit : CompilationUnit) extends Ev ctx.timers.evaluators.codegen.compilation.start() try { - val ce = unit.compileExpression(expression, argorder) + val ce = unit.compileExpression(expression, argorder)(ctx) Some((args : Seq[Expr]) => { try { diff --git a/src/main/scala/leon/purescala/Common.scala b/src/main/scala/leon/purescala/Common.scala index 4399dc2bf..f04cbc99f 100644 --- a/src/main/scala/leon/purescala/Common.scala +++ b/src/main/scala/leon/purescala/Common.scala @@ -33,8 +33,15 @@ object Common { * The name is stored in the decoded (source code) form rather than encoded (JVM) form. * The type may be left blank (Untyped) for Identifiers that are not variables. */ - class Identifier private[Common](val name: String, val globalId: Int, val id: Int, val tpe: TypeTree, alwaysShowUniqueID: Boolean = false) extends Tree with Typed { - self : Serializable => + class Identifier private[Common]( + val name: String, + private[Common] val globalId: Int, + private[Common] val id: Int, + private val tpe: TypeTree, + private val alwaysShowUniqueID: Boolean = false + ) extends Tree with Typed with Ordered[Identifier] { + + self: Serializable => val getType = tpe @@ -47,27 +54,27 @@ object Common { override def hashCode: Int = globalId override def toString: String = { - if(alwaysShowUniqueID) { - name + (if(id > 0) id else "") + if (alwaysShowUniqueID) { + name + (if (id > 0) id else "") } else { name } } - def uniqueName : String = name + id + def uniqueNameDelimited(delim: String) = name + delim + id - def toVariable : Variable = Variable(this) + def uniqueName: String = uniqueNameDelimited("") - def freshen: Identifier = FreshIdentifier(name, tpe, alwaysShowUniqueID).copiedFrom(this) + def toVariable: Variable = Variable(this) - } - - implicit object IdentifierOrdering extends Ordering[Identifier] { - def compare(a: Identifier, b: Identifier) = { - val ord = implicitly[Ordering[Tuple3[String, Int, Int]]] + def freshen: Identifier = FreshIdentifier(name, tpe, alwaysShowUniqueID).copiedFrom(this) - ord.compare((a.name, a.id, a.globalId), - (b.name, b.id, b.globalId)) + override def compare(that: Identifier): Int = { + val ord = implicitly[Ordering[(String, Int, Int)]] + ord.compare( + (this.name, this.id, this.globalId), + (that.name, that.id, that.globalId) + ) } } diff --git a/src/main/scala/leon/solvers/ADTManager.scala b/src/main/scala/leon/solvers/ADTManager.scala index 3339fe2b7..e811feaa1 100644 --- a/src/main/scala/leon/solvers/ADTManager.scala +++ b/src/main/scala/leon/solvers/ADTManager.scala @@ -49,9 +49,11 @@ class ADTManager(ctx: LeonContext) { if (conflicts(t)) { // There is no way to solve this, the type we requested is in conflict - reporter.warning(s"Encountered ADT '$t' that can't be defined.") - reporter.warning("It appears it has recursive references through non-structural types (such as arrays, maps, or sets).") - throw new IllegalArgumentException + val str = "Encountered ADT that can't be defined.\n" + + "It appears it has recursive references through non-structural types (such as arrays, maps, or sets)." + val err = new Unsupported(t, str)(ctx) + reporter.warning(err.getMessage) + throw err } else { // We might be able to define some despite conflicts if (conflicts.isEmpty) { diff --git a/src/main/scala/leon/solvers/Solver.scala b/src/main/scala/leon/solvers/Solver.scala index 9f8aaace4..a9018b2de 100644 --- a/src/main/scala/leon/solvers/Solver.scala +++ b/src/main/scala/leon/solvers/Solver.scala @@ -5,7 +5,7 @@ package solvers import utils.{DebugSectionSolver, Interruptible} import purescala.Expressions._ -import purescala.Common.Identifier +import leon.purescala.Common.{Tree, Identifier} import verification.VC trait Solver extends Interruptible { @@ -33,6 +33,17 @@ trait Solver extends Interruptible { def checkAssumptions(assumptions: Set[Expr]): Option[Boolean] def getUnsatCore: Set[Expr] + protected def unsupported(t: Tree): Nothing = { + val err = SolverUnsupportedError(t, this, None) + leonContext.reporter.warning(err.getMessage) + throw err + } + protected def unsupported(t: Tree, str: String): Nothing = { + val err = SolverUnsupportedError(t, this, Some(str)) + leonContext.reporter.warning(err.getMessage) + throw err + } + implicit val debugSection = DebugSectionSolver private[solvers] def debugS(msg: String) = { diff --git a/src/main/scala/leon/solvers/SolverUnsupportedError.scala b/src/main/scala/leon/solvers/SolverUnsupportedError.scala new file mode 100644 index 000000000..5d519160d --- /dev/null +++ b/src/main/scala/leon/solvers/SolverUnsupportedError.scala @@ -0,0 +1,15 @@ +/* Copyright 2009-2015 EPFL, Lausanne */ + +package leon +package solvers + +import purescala.Common.Tree + +object SolverUnsupportedError { + def msg(t: Tree, s: Solver, reason: Option[String]) = { + s" is unsupported by solver ${s.name}" + reason.map(":\n " + _ ).getOrElse("") + } +} + +case class SolverUnsupportedError(t: Tree, s: Solver, reason: Option[String] = None) + extends Unsupported(t, SolverUnsupportedError.msg(t,s,reason))(s.leonContext) diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala index 83076f8dc..86da0be80 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4ProofSolver.scala @@ -6,6 +6,7 @@ package solvers.smtlib import leon.purescala.Common.Identifier import leon.purescala.Definitions.Program import leon.purescala.Expressions.Expr +import leon.solvers.SolverUnsupportedError import smtlib.parser.Commands.{Assert => SMTAssert} import smtlib.parser.Terms.{Exists => SMTExists} @@ -31,7 +32,7 @@ class SMTLIBCVC4ProofSolver(context: LeonContext, program: Program) extends SMTL override def assertCnstr(e: Expr) = try { sendCommand(SMTAssert(quantifiedTerm(SMTExists, e))) } catch { - case _: IllegalArgumentException => + case _ : SolverUnsupportedError => addError() } diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala index 6bc216b53..232867dcc 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala @@ -3,6 +3,7 @@ package leon package solvers.smtlib +import leon.solvers.SolverUnsupportedError import purescala._ import Expressions._ import Definitions._ @@ -51,7 +52,7 @@ abstract class SMTLIBCVC4QuantifiedSolver(context: LeonContext, program: Program Seq(bodyAssert) ++ specAssert } catch { - case _ : IllegalArgumentException => + case _ : SolverUnsupportedError => addError() Seq() } @@ -79,7 +80,7 @@ abstract class SMTLIBCVC4QuantifiedSolver(context: LeonContext, program: Program (p.id, id2sym(p.id): Term) }.toMap) } catch { - case _: IllegalArgumentException => + case _: SolverUnsupportedError => addError() toSMT(Error(tfd.body.get.getType, ""))(Map()) } @@ -101,7 +102,7 @@ abstract class SMTLIBCVC4QuantifiedSolver(context: LeonContext, program: Program try { sendCommand(SMTAssert(quantifiedTerm(SMTForall, term))) } catch { - case _ : IllegalArgumentException => + case _ : SolverUnsupportedError => addError() } } diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala index 801a71662..fa11aa421 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala @@ -96,9 +96,9 @@ class SMTLIBCVC4Solver(context: LeonContext, program: Program) extends SMTLIBSol FiniteSet(se ++ selems, base) case (FunctionApplication(SimpleSymbol(SSymbol("union")), elems), SetType(base)) => - FiniteSet(elems.map(fromSMT(_, tpe) match { + FiniteSet(elems.flatMap(fromSMT(_, tpe) match { case FiniteSet(elems, _) => elems - }).flatten.toSet, base) + }).toSet, base) // FIXME (nicolas) // some versions of CVC4 seem to generate array constants with "as const" notation instead of the __array_store_all__ diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala index 25b7a6c0f..29540f2f4 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala @@ -28,7 +28,6 @@ import _root_.smtlib.parser.CommandsResponses.{Error => ErrorResponse, _} import _root_.smtlib.theories._ import _root_.smtlib.{Interpreter => SMTInterpreter} - abstract class SMTLIBSolver(val context: LeonContext, val program: Program) extends Solver with NaiveAssumptionSolver { @@ -109,7 +108,7 @@ abstract class SMTLIBSolver(val context: LeonContext, protected val library = program.library - protected def id2sym(id: Identifier): SSymbol = SSymbol(id.name+"!"+id.id) + protected def id2sym(id: Identifier): SSymbol = SSymbol(id.uniqueNameDelimited("!")) protected def freshSym(id: Identifier): SSymbol = freshSym(id.name) protected def freshSym(name: String): SSymbol = id2sym(FreshIdentifier(name)) @@ -160,7 +159,7 @@ abstract class SMTLIBSolver(val context: LeonContext, protected def fromRawArray(r: RawArrayValue, tpe: TypeTree): Expr = tpe match { case SetType(base) => if (r.default != BooleanLiteral(false)) { - unsupported("Co-finite sets are not supported.") + unsupported(r, "Solver returned a co-finite set which is not supported.") } require(r.keyTpe == base, s"Type error in solver model, expected $base, found ${r.keyTpe}") @@ -176,7 +175,7 @@ abstract class SMTLIBSolver(val context: LeonContext, // We expect a RawArrayValue with keys in from and values in Option[to], // with default value == None if (r.default.getType != library.noneType(to)) { - unsupported("Co-finite maps are not supported.") + unsupported(r, "Solver returned a co-finite map which is not supported.") } require(r.keyTpe == from, s"Type error in solver model, expected $from, found ${r.keyTpe}") @@ -186,13 +185,8 @@ abstract class SMTLIBSolver(val context: LeonContext, }.toSeq FiniteMap(elems, from, to) - case _ => - unsupported("Unable to extract from raw array for "+tpe) - } - - protected def unsupported(str: String) = { - reporter.warning(s"Unsupported in smt-$targetName: $str") - throw new IllegalArgumentException(str) + case other => + unsupported(other, "Unable to extract from raw array for "+tpe) } protected def declareSort(t: TypeTree): Sort = { @@ -223,8 +217,8 @@ abstract class SMTLIBSolver(val context: LeonContext, case _: ClassType | _: TupleType | _: ArrayType | UnitType => declareStructuralSort(tpe) - case _ => - unsupported("Sort "+t) + case other => + unsupported(other, s"Could not transform $other into an SMT sort") } } } @@ -565,7 +559,7 @@ abstract class SMTLIBSolver(val context: LeonContext, ) } case o => - unsupported(s"Tree ${o.asString}") + unsupported(o, "") } } @@ -605,7 +599,7 @@ abstract class SMTLIBSolver(val context: LeonContext, case cct: CaseClassType => CaseClass(cct, Nil) case t => - unsupported("woot? for a single constructor for non-case-object: "+t.asString) + unsupported(t, "woot? for a single constructor for non-case-object") } case (SimpleSymbol(s), tpe) if lets contains s => @@ -613,7 +607,7 @@ abstract class SMTLIBSolver(val context: LeonContext, case (SimpleSymbol(s), _) => variables.getA(s).map(_.toVariable).getOrElse { - unsupported("Unknown symbol: "+s) + reporter.fatalError("Unknown symbol: "+s) } case (FunctionApplication(SimpleSymbol(SSymbol("ite")), Seq(cond, thenn, elze)), t) => @@ -649,7 +643,7 @@ abstract class SMTLIBSolver(val context: LeonContext, } case t => - unsupported("Woot? structural type that is non-structural: "+t) + unsupported(t, "Woot? structural type that is non-structural") } // EK: Since we have no type information, we cannot do type-directed @@ -676,13 +670,13 @@ abstract class SMTLIBSolver(val context: LeonContext, } case _ => - unsupported("Function "+app+" not handled in fromSMT: "+s) + reporter.fatalError("Function "+app+" not handled in fromSMT: "+s) } } case (QualifiedIdentifier(id, sort), tpe) => - unsupported("Unhandled case in fromSMT: " + id +": "+sort +" ("+tpe+")") + reporter.fatalError("Unhandled case in fromSMT: " + id +": "+sort +" ("+tpe+")") case _ => - unsupported("Unhandled case in fromSMT: " + (s, tpe)) + reporter.fatalError("Unhandled case in fromSMT: " + (s, tpe)) } @@ -719,7 +713,7 @@ abstract class SMTLIBSolver(val context: LeonContext, val term = toSMT(expr)(Map()) sendCommand(SMTAssert(term)) } catch { - case i : IllegalArgumentException => + case _ : SolverUnsupportedError => // Store that there was an error. Now all following check() // invocations will return None addError() diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala index b520dfe5b..2ec571f1e 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedSolver.scala @@ -3,6 +3,7 @@ package leon package solvers.smtlib +import leon.solvers.SolverUnsupportedError import purescala._ import DefOps._ import Definitions._ @@ -63,7 +64,7 @@ class SMTLIBZ3QuantifiedSolver(context: LeonContext, program: Program) try { sendCommand(SMTAssert(quantifiedTerm(SMTForall, term))) } catch { - case _ : IllegalArgumentException => + case _ : SolverUnsupportedError => addError() } } diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala index 3a7b345fb..36c4523da 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala @@ -79,7 +79,7 @@ class SMTLIBZ3Solver(context: LeonContext, program: Program) extends SMTLIBSolve // Need to recover value form function model fromRawArray(extractRawArray(letDefs(k), tpe), tpe) } else { - unsupported(" as-array on non-function or unknown symbol "+k) + throw LeonFatalError("Array on non-function or unknown symbol "+k) } case (FunctionApplication( @@ -141,7 +141,7 @@ class SMTLIBZ3Solver(context: LeonContext, program: Program) extends SMTLIBSolve case ArrayType(base) => (Int32Type, base) case FunctionType(args, ret) => (tupleTypeWrap(args), ret) case RawArrayType(from, to) => (from, to) - case _ => unsupported("Unsupported type for (un)packing into raw arrays: "+tpe +" (got kinds "+akind+" -> "+rkind+")") + case _ => unsupported(tpe, "Unsupported type for (un)packing into raw arrays (got kinds "+akind+" -> "+rkind+")") } def extractCases(e: Term): (Map[Expr, Expr], Expr) = e match { @@ -157,7 +157,7 @@ class SMTLIBZ3Solver(context: LeonContext, program: Program) extends SMTLIBSolve RawArrayValue(argTpe, cases, default) case _ => - unsupported("Unable to extract "+s) + throw LeonFatalError("Unable to extract "+s) } // EK: We use get-model instead in order to extract models for arrays diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala index 9eb08e152..9492e8b93 100644 --- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala @@ -259,11 +259,7 @@ trait AbstractZ3Solver extends Solver { } case other => - sorts.cachedB(other) { - reporter.warning(other.getPos, "Resorting to uninterpreted type for : " + other.asString) - val symbol = z3.mkIntSymbol(FreshIdentifier("unint").globalId) - z3.mkUninterpretedSort(symbol) - } + throw SolverUnsupportedError(other, this) } protected[leon] def toZ3Formula(expr: Expr, initialMap: Map[Identifier, Z3AST] = Map.empty): Z3AST = { @@ -545,10 +541,8 @@ trait AbstractZ3Solver extends Solver { case gv @ GenericValue(tp, id) => z3.mkApp(genericValueToDecl(gv)) - case _ => { - reporter.warning(ex.getPos, "Can't handle this in translation to Z3: " + ex.asString) - throw new IllegalArgumentException - } + case other => + unsupported(other) } rec(expr) @@ -587,13 +581,11 @@ trait AbstractZ3Solver extends Solver { tpe match { case Int32Type => IntLiteral(hexa.toInt) case CharType => CharLiteral(hexa.toInt.toChar) - case _ => - reporter.warning("Unexpected target type for BV value: " + tpe.asString) - throw new IllegalArgumentException + case other => + unsupported(other, "Unexpected target type for BV value") } case None => { - reporter.warning("Z3NumeralIntAST with None: " + t) - throw new IllegalArgumentException + throw LeonFatalError(s"Could not translate hexadecimal Z3 numeral $t") } } } else { @@ -607,12 +599,10 @@ trait AbstractZ3Solver extends Solver { case Int32Type => IntLiteral(hexa.toInt) case CharType => CharLiteral(hexa.toInt.toChar) case _ => - reporter.warning("Unexpected target type for BV value: " + tpe.asString) - throw new IllegalArgumentException + reporter.fatalError("Unexpected target type for BV value: " + tpe.asString) } case None => { - reporter.warning("Z3NumeralIntAST with None: " + t) - throw new IllegalArgumentException + reporter.fatalError(s"Could not translate Z3NumeralIntAST numeral $t") } } } @@ -648,12 +638,12 @@ trait AbstractZ3Solver extends Solver { case (s : IntLiteral, RawArrayValue(_, elems, default)) => val entries = elems.map { case (IntLiteral(i), v) => i -> v - case _ => throw new IllegalArgumentException + case _ => reporter.fatalError("Translation from Z3 to Array failed") } finiteArray(entries, Some(s, default), to) case _ => - throw new IllegalArgumentException + reporter.fatalError("Translation from Z3 to Array failed") } } } else { @@ -667,7 +657,7 @@ trait AbstractZ3Solver extends Solver { } RawArrayValue(from, entries, default) - case None => throw new IllegalArgumentException + case None => reporter.fatalError("Translation from Z3 to Array failed") } case tp: TypeParameter => @@ -680,8 +670,7 @@ trait AbstractZ3Solver extends Solver { // We expect a RawArrayValue with keys in from and values in Option[to], // with default value == None if (r.default.getType != library.noneType(to)) { - reporter.warning("Co-finite maps are not supported. (Default was "+r.default.asString+")") - throw new IllegalArgumentException + unsupported(r, "Solver returned a co-finite set which is not supported.") } require(r.keyTpe == from, s"Type error in solver model, expected ${from.asString}, found ${r.keyTpe.asString}") @@ -696,7 +685,7 @@ trait AbstractZ3Solver extends Solver { case FunctionType(fts, tt) => model.getArrayValue(t) match { - case None => throw new IllegalArgumentException + case None => reporter.fatalError("Translation from Z3 to function value failed") case Some((map, elseZ3Value)) => val leonElseValue = rec(elseZ3Value, tt) val leonMap = map.toSeq.map(p => rec(p._1, tupleTypeWrap(fts)) -> rec(p._2, tt)) @@ -705,7 +694,7 @@ trait AbstractZ3Solver extends Solver { case tpe @ SetType(dt) => model.getSetValue(t) match { - case None => throw new IllegalArgumentException + case None => reporter.fatalError("Translation from Z3 to set failed") case Some(set) => val elems = set.map(e => rec(e, dt)) FiniteSet(elems, dt) @@ -736,17 +725,17 @@ trait AbstractZ3Solver extends Solver { // case OpIDiv => Division(rargs(0), rargs(1)) // case OpMod => Modulo(rargs(0), rargs(1)) case other => - reporter.warning("Don't know what to do with this declKind : " + other) - reporter.warning("Expected type: " + tpe.asString) - reporter.warning("Tree: " + t) - reporter.warning("The arguments are : " + args) - throw new IllegalArgumentException + reporter.fatalError( + s"""|Don't know what to do with this declKind: $other + |Expected type: ${tpe.asString} + |Tree: $t + |The arguments are: $args""".stripMargin + ) } } } case _ => - reporter.warning("Can't handle "+t) - throw new IllegalArgumentException + reporter.fatalError(s"Don't know what to do with this Z3 tree: $t") } } rec(tree, tpe) @@ -756,7 +745,7 @@ trait AbstractZ3Solver extends Solver { try { Some(fromZ3Formula(model, tree, tpe)) } catch { - case e: IllegalArgumentException => None + case e: Unsupported => None } } diff --git a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala index eef9ffb90..a1fc339da 100644 --- a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala @@ -218,7 +218,7 @@ class FairZ3Solver(val context: LeonContext, val program: Program) solver.assertCnstr(cl) } } catch { - case _: IllegalArgumentException => + case _: SolverUnsupportedError => addError() } } diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala index 480960777..f745abec9 100644 --- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala +++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala @@ -192,7 +192,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { grammar.printProductions(printer) } - bsOrdered = bs.toSeq.sortBy(_.id) + bsOrdered = bs.toSeq.sorted setCExpr(computeCExpr()) } @@ -545,7 +545,8 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { for ((c, alts) <- cTree) { val activeBs = alts.map(_._1).filter(isBActive) - val either = for (a1 <- activeBs; a2 <- activeBs if a1.globalId < a2.globalId) yield { + val ord = implicitly[Ordering[Identifier]] + val either = for (a1 <- activeBs; a2 <- activeBs if a1 < a2) yield { Or(Not(a1.toVariable), Not(a2.toVariable)) } diff --git a/src/test/scala/leon/test/helpers/WithLikelyEq.scala b/src/test/scala/leon/test/helpers/WithLikelyEq.scala index aee9e7671..d499f5617 100644 --- a/src/test/scala/leon/test/helpers/WithLikelyEq.scala +++ b/src/test/scala/leon/test/helpers/WithLikelyEq.scala @@ -32,7 +32,7 @@ trait WithLikelyEq { def checkLikelyEq(ctx: LeonContext, pgm: Program = Program.empty)(e1: Expr, e2: Expr, pre: Option[Expr] = None, values: Map[Identifier, Expr] = Map()): Unit = { val evaluator = new DefaultEvaluator(ctx, pgm) - val freeVars = (variablesOf(e1) ++ variablesOf(e2)).toSeq.sortBy(_.globalId) + val freeVars = (variablesOf(e1) ++ variablesOf(e2)).toSeq.sorted if (freeVars.isEmpty) { val r1 = evaluator.eval(e1) -- GitLab