From 33777002b7ccd15af322160aa4afce15c6dcc4e9 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Tue, 11 Aug 2015 18:27:16 +0200 Subject: [PATCH] Remove toString, rely on asString instead when printing stuff --- .../scala/leon/datagen/VanuatooDataGen.scala | 10 ++++----- .../leon/evaluators/RecursiveEvaluator.scala | 22 ++++++++++--------- .../frontends/scalac/CodeExtraction.scala | 2 +- .../frontends/scalac/LeonExtraction.scala | 2 +- .../leon/purescala/CheckADTFieldsTypes.scala | 2 +- src/main/scala/leon/purescala/Common.scala | 13 ++++++++--- src/main/scala/leon/purescala/Types.scala | 2 ++ src/main/scala/leon/repair/rules/Focus.scala | 4 ++-- src/main/scala/leon/repair/rules/Split.scala | 4 ++-- .../leon/solvers/smtlib/SMTLIBSolver.scala | 16 +++++++------- .../leon/solvers/z3/AbstractZ3Solver.scala | 2 +- .../scala/leon/synthesis/FileInterface.scala | 7 +++--- src/main/scala/leon/synthesis/Problem.scala | 8 ------- src/main/scala/leon/synthesis/Rules.scala | 6 +++-- src/main/scala/leon/synthesis/Solution.scala | 2 -- .../scala/leon/synthesis/graph/Graph.scala | 8 ++++--- .../scala/leon/synthesis/graph/Search.scala | 8 +++---- .../scala/leon/synthesis/rules/ADTDual.scala | 1 - .../leon/synthesis/rules/ADTInduction.scala | 2 +- .../synthesis/rules/ADTLongInduction.scala | 2 +- .../scala/leon/synthesis/rules/ADTSplit.scala | 2 +- .../scala/leon/synthesis/rules/Assert.scala | 2 +- .../leon/synthesis/rules/CEGISLike.scala | 7 +++--- .../scala/leon/synthesis/rules/CEGLESS.scala | 7 +++--- .../leon/synthesis/rules/DetupleInput.scala | 3 +-- .../synthesis/rules/EquivalentInputs.scala | 2 +- .../synthesis/utils/ExpressionGrammar.scala | 10 ++++----- .../SynthesisProblemExtractionPhase.scala | 2 +- .../leon/verification/DefaultTactic.scala | 2 +- .../leon/verification/InductionTactic.scala | 6 ++--- src/main/scala/leon/verification/Tactic.scala | 2 ++ .../test/synthesis/StablePrintingSuite.scala | 4 ++-- .../leon/test/synthesis/SynthesisSuite.scala | 2 +- .../leon/test/helpers/WithLikelyEq.scala | 8 +++++-- 34 files changed, 97 insertions(+), 85 deletions(-) diff --git a/src/main/scala/leon/datagen/VanuatooDataGen.scala b/src/main/scala/leon/datagen/VanuatooDataGen.scala index 013b8d870..1751a1e55 100644 --- a/src/main/scala/leon/datagen/VanuatooDataGen.scala +++ b/src/main/scala/leon/datagen/VanuatooDataGen.scala @@ -66,7 +66,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { (1 to size).map(i => sub).toList, at, s => finiteArray(s, None, sub), - at.toString+"@"+size + at.asString(ctx)+"@"+size ) } constructors += at -> cs @@ -80,7 +80,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { (1 to size).map(i => sub).toList, st, s => FiniteSet(s.toSet, sub), - st.toString+"@"+size + st.asString(ctx)+"@"+size ) } constructors += st -> cs @@ -89,7 +89,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { case tt @ TupleType(parts) => constructors.getOrElse(tt, { - val cs = List(Constructor[Expr, TypeTree](parts, tt, s => tupleWrap(s), tt.toString)) + val cs = List(Constructor[Expr, TypeTree](parts, tt, s => tupleWrap(s), tt.asString(ctx))) constructors += tt -> cs cs }) @@ -99,7 +99,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { val cs = for (size <- List(0, 1, 2, 5)) yield { val subs = (1 to size).flatMap(i => List(from, to)).toList - Constructor[Expr, TypeTree](subs, mt, s => FiniteMap(s.grouped(2).map(t => (t(0), t(1))).toSeq, from, to), mt.toString+"@"+size) + Constructor[Expr, TypeTree](subs, mt, s => FiniteMap(s.grouped(2).map(t => (t(0), t(1))).toSeq, from, to), mt.asString(ctx)+"@"+size) } constructors += mt -> cs cs @@ -117,7 +117,7 @@ class VanuatooDataGen(ctx: LeonContext, p: Program) extends DataGenerator { IfExpr(Equals(argsTuple, tupleWrap(t.init)), t.last, elze) } Lambda(args.map(id => ValDef(id)), body) - }, ft.toString + "@" + size) + }, ft.asString(ctx) + "@" + size) } constructors += ft -> cs cs diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala index 1eb6398ea..4c4340848 100644 --- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala +++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala @@ -19,6 +19,8 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int val name = "evaluator" val description = "Recursive interpreter for PureScala expressions" + private implicit val ctx0 = ctx + type RC <: RecContext type GC <: GlobalContext @@ -80,7 +82,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case Some(v) => v case None => - throw EvalError("No value for identifier " + id.asString(ctx) + " in mapping.") + throw EvalError("No value for identifier " + id.asString + " in mapping.") } case Application(caller, args) => @@ -90,7 +92,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int val mapping = l.paramSubst(newArgs) e(body)(rctx.withNewVars(mapping), gctx) case f => - throw EvalError("Cannot apply non-lambda function " + f) + throw EvalError("Cannot apply non-lambda function " + f.asString) } case Tuple(ts) => @@ -153,7 +155,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int e(tfd.precondition.get)(frame, gctx) match { case BooleanLiteral(true) => case BooleanLiteral(false) => - throw RuntimeError("Precondition violation for " + tfd.id.name + " reached in evaluation.: " + tfd.precondition.get) + throw RuntimeError("Precondition violation for " + tfd.id.asString + " reached in evaluation.: " + tfd.precondition.get.asString) case other => throw RuntimeError(typeErrorMsg(other, BooleanType)) } @@ -170,7 +172,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case Some(post) => e(application(post, Seq(callResult)))(frame, gctx) match { case BooleanLiteral(true) => - case BooleanLiteral(false) => throw RuntimeError("Postcondition violation for " + tfd.id.name + " reached in evaluation.") + case BooleanLiteral(false) => throw RuntimeError("Postcondition violation for " + tfd.id.asString + " reached in evaluation.") case other => throw EvalError(typeErrorMsg(other, BooleanType)) } case None => @@ -517,7 +519,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case g @ MapGet(m,k) => (e(m), e(k)) match { case (FiniteMap(ss, _, _), e) => ss.find(_._1 == e) match { case Some((_, v0)) => v0 - case None => throw RuntimeError("Key not found: " + e) + case None => throw RuntimeError("Key not found: " + e.asString) } case (l,r) => throw EvalError(typeErrorMsg(l, MapType(r.getType, g.getType))) } @@ -577,7 +579,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int val total = System.currentTimeMillis-tStart ctx.reporter.debug("Synthesis took "+total+"ms") - ctx.reporter.debug("Finished synthesis with "+leonRes.asString(ctx)) + ctx.reporter.debug("Finished synthesis with "+leonRes.asString) clpCache += (choose, ins) -> leonRes leonRes @@ -599,14 +601,14 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case Some(Some((c, mappings))) => e(c.rhs)(rctx.withNewVars(mappings), gctx) case _ => - throw RuntimeError("MatchError: "+rscrut+" did not match any of the cases") + throw RuntimeError("MatchError: "+rscrut.asString+" did not match any of the cases") } case l : Literal[_] => l case other => - context.reporter.error(other.getPos, "Error: don't know how to handle " + other + " in Evaluator ("+other.getClass+").") - throw EvalError("Unhandled case in Evaluator : " + other) + context.reporter.error(other.getPos, "Error: don't know how to handle " + other.asString + " in Evaluator ("+other.getClass+").") + throw EvalError("Unhandled case in Evaluator : " + other.asString) } def matchesCase(scrut: Expr, caze: MatchCase)(implicit rctx: RC, gctx: GC): Option[(MatchCase, Map[Identifier, Expr])] = { @@ -683,6 +685,6 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int } } - def typeErrorMsg(tree : Expr, expected : TypeTree) : String = s"Type error : expected $expected, found $tree." + def typeErrorMsg(tree : Expr, expected : TypeTree) : String = s"Type error : expected ${expected.asString}, found ${tree.asString}." } diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala index cda2d5fae..e96ad2d5f 100644 --- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala @@ -1349,7 +1349,7 @@ trait CodeExtraction extends ASTExtractors { Not(Equals(rl, InfiniteIntegerLiteral(v))) case (IsTyped(_, rt), IsTyped(_, lt)) => - outOfSubsetError(tr, "Invalid comparison: (_: "+rt+") != (_: "+lt+")") + outOfSubsetError(tr, "Invalid comparison: (_: "+rt.asString+") != (_: "+lt.asString+")") } } diff --git a/src/main/scala/leon/frontends/scalac/LeonExtraction.scala b/src/main/scala/leon/frontends/scalac/LeonExtraction.scala index 1de899e28..3bc1a0d05 100644 --- a/src/main/scala/leon/frontends/scalac/LeonExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/LeonExtraction.scala @@ -12,7 +12,7 @@ trait LeonExtraction extends SubComponent with CodeExtraction { var units: List[CompilationUnit] = Nil - val ctx: LeonContext + implicit val ctx: LeonContext var imports : Map[RefTree,List[Import]] = Map() diff --git a/src/main/scala/leon/purescala/CheckADTFieldsTypes.scala b/src/main/scala/leon/purescala/CheckADTFieldsTypes.scala index ee78b4b5f..a62837f00 100644 --- a/src/main/scala/leon/purescala/CheckADTFieldsTypes.scala +++ b/src/main/scala/leon/purescala/CheckADTFieldsTypes.scala @@ -17,7 +17,7 @@ object CheckADTFieldsTypes extends UnitPhase[Program] { for(vd <- ccd.fields) { val tpe = vd.getType if (bestRealType(tpe) != tpe) { - ctx.reporter.warning("Definition of "+ccd.id+" has a field of a sub-type ("+vd+"): " + + ctx.reporter.warning("Definition of "+ccd.id.asString(ctx)+" has a field of a sub-type ("+vd.asString(ctx)+"): " + "this type is not supported as-is by solvers and will be up-cast. " + "This may cause issues such as crashes.") } diff --git a/src/main/scala/leon/purescala/Common.scala b/src/main/scala/leon/purescala/Common.scala index 764320d23..e10036a36 100644 --- a/src/main/scala/leon/purescala/Common.scala +++ b/src/main/scala/leon/purescala/Common.scala @@ -17,9 +17,7 @@ object Common { this } - override def toString: String = { - PrettyPrinter(this) - } + // @EK: toString is considered harmful for non-internal things. Use asString(ctx) instead. def asString(implicit ctx: LeonContext): String = { ScalaPrinter(this, ctx) @@ -60,6 +58,15 @@ object Common { } + implicit object IdentifierOrdering extends Ordering[Identifier] { + def compare(a: Identifier, b: Identifier) = { + val ord = implicitly[Ordering[Tuple3[String, Int, Int]]] + + ord.compare((a.name, a.id, a.globalId), + (b.name, b.id, b.globalId)) + } + } + private object UniqueCounter { private var globalId = -1 private var nameIds = Map[String, Int]().withDefaultValue(-1) diff --git a/src/main/scala/leon/purescala/Types.scala b/src/main/scala/leon/purescala/Types.scala index 775a82c19..b780cfb69 100644 --- a/src/main/scala/leon/purescala/Types.scala +++ b/src/main/scala/leon/purescala/Types.scala @@ -15,6 +15,8 @@ object Types { trait Typed { val getType: TypeTree def isTyped : Boolean = getType != Untyped + + def asString(implicit ctx: LeonContext): String } class TypeErrorException(msg: String) extends Exception(msg) diff --git a/src/main/scala/leon/repair/rules/Focus.scala b/src/main/scala/leon/repair/rules/Focus.scala index e4a5e3404..edf5cdcf3 100644 --- a/src/main/scala/leon/repair/rules/Focus.scala +++ b/src/main/scala/leon/repair/rules/Focus.scala @@ -109,7 +109,7 @@ case object Focus extends PreprocessingRule("Focus") { // Focus on condition val np = Problem(p.as, ws(c), p.pc, letTuple(p.xs, IfExpr(cx.toVariable, thn, els), p.phi), List(cx), p.eb.stripOuts) - Some(decomp(List(np), termWrap(IfExpr(_, thn, els)), s"Focus on if-cond '$c'")(p)) + Some(decomp(List(np), termWrap(IfExpr(_, thn, els)), s"Focus on if-cond '${c.asString}'")(p)) case _ => // Try to focus on branches @@ -173,7 +173,7 @@ case object Focus extends PreprocessingRule("Focus") { decomp(List(np), termWrap(x => MatchExpr(scrut, cases.map { case `c` => c.copy(rhs = x) case c2 => c2 - }), cond), s"Focus on match-case '${c.pattern}'")(p) + }), cond), s"Focus on match-case '${c.pattern.asString}'")(p) ) ) diff --git a/src/main/scala/leon/repair/rules/Split.scala b/src/main/scala/leon/repair/rules/Split.scala index 94b7ff24b..da066cefa 100644 --- a/src/main/scala/leon/repair/rules/Split.scala +++ b/src/main/scala/leon/repair/rules/Split.scala @@ -60,7 +60,7 @@ case object Split extends Rule("Split") { None } - Some(decomp(List(sub1, sub2), onSuccess, s"Guided If-Split on '$c'")) + Some(decomp(List(sub1, sub2), onSuccess, s"Guided If-Split on '${c.asString}'")) case m @ MatchExpr(scrut, cases) => @@ -112,7 +112,7 @@ case object Split extends Rule("Split") { } Some( - decomp(infos.map(_._2).toList, onSuccess, s"Split match on '$scrut'") + decomp(infos.map(_._2).toList, onSuccess, s"Split match on '${scrut.asString}'") ) case e => diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala index 8bfb6d92f..5a4450e58 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala @@ -163,8 +163,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)) { - reporter.warning("Co-finite sets are not supported.") - throw new IllegalArgumentException + unsupported("Co-finite sets are not supported.") } require(r.keyTpe == base, s"Type error in solver model, expected $base, found ${r.keyTpe}") @@ -180,8 +179,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)) { - reporter.warning("Co-finite maps are not supported. (Default was "+r.default+")") - throw new IllegalArgumentException + unsupported("Co-finite maps are not supported.") } require(r.keyTpe == from, s"Type error in solver model, expected $from, found ${r.keyTpe}") @@ -195,7 +193,10 @@ abstract class SMTLIBSolver(val context: LeonContext, unsupported("Unable to extract from raw array for "+tpe) } - protected def unsupported(str: Any) = reporter.fatalError(s"Unsupported in smt-$targetName: $str") + protected def unsupported(str: String) = { + reporter.warning(s"Unsupported in smt-$targetName: $str") + throw new IllegalArgumentException(str) + } protected def declareSort(t: TypeTree): Sort = { val tpe = normalizeType(t) @@ -563,8 +564,7 @@ abstract class SMTLIBSolver(val context: LeonContext, ) } case o => - reporter.warning(s"Unsupported Tree in smt-$targetName: $o") - throw new IllegalArgumentException + unsupported(s"Tree ${o.asString}") } } @@ -604,7 +604,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) + unsupported("woot? for a single constructor for non-case-object: "+t.asString) } case (SimpleSymbol(s), tpe) if lets contains s => diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala index d24b88473..11cf31b27 100644 --- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala @@ -82,7 +82,7 @@ trait AbstractZ3Solver def genericValueToDecl(gv: GenericValue): Z3FuncDecl = { generics.cachedB(gv) { - z3.mkFreshFuncDecl(gv.tp.toString+"#"+gv.id+"!val", Seq(), typeToSort(gv.tp)) + z3.mkFreshFuncDecl(gv.tp.id.uniqueName+"#"+gv.id+"!val", Seq(), typeToSort(gv.tp)) } } diff --git a/src/main/scala/leon/synthesis/FileInterface.scala b/src/main/scala/leon/synthesis/FileInterface.scala index d94f78268..251c6af0e 100644 --- a/src/main/scala/leon/synthesis/FileInterface.scala +++ b/src/main/scala/leon/synthesis/FileInterface.scala @@ -15,7 +15,7 @@ import leon.utils.RangePosition import java.io.File class FileInterface(reporter: Reporter) { - def updateFile(origFile: File, solutions: Map[ChooseInfo, Expr]) { + def updateFile(origFile: File, solutions: Map[ChooseInfo, Expr])(implicit ctx: LeonContext) { import java.io.{File, BufferedWriter, FileWriter} val FileExt = """^(.+)\.([^.]+)$""".r @@ -70,9 +70,10 @@ class FileInterface(reporter: Reporter) { } - def substitute(str: String, fromTree: Tree, toTree: Tree): String = { + def substitute(str: String, fromTree: Tree, toTree: Tree)(implicit ctx: LeonContext): String = { substitute(str, fromTree, (indent: Int) => { - val p = new ScalaPrinter(PrinterOptions(), None) + val opts = PrinterOptions.fromContext(ctx) + val p = new ScalaPrinter(opts, None) p.pp(toTree)(PrinterContext(toTree, Nil, indent, p)) p.toString }) diff --git a/src/main/scala/leon/synthesis/Problem.scala b/src/main/scala/leon/synthesis/Problem.scala index 4ae607f81..08e9c25d3 100644 --- a/src/main/scala/leon/synthesis/Problem.scala +++ b/src/main/scala/leon/synthesis/Problem.scala @@ -33,14 +33,6 @@ case class Problem(as: List[Identifier], ws: Expr, pc: Expr, phi: Expr, xs: List "⟦ "+as.map(_.asString).mkString(";")+", "+(if (pcws != BooleanLiteral(true)) pcws.asString+" ≺ " else "")+" ⟨ "+phi.asString+" ⟩ "+xs.map(_.asString).mkString(";")+" ⟧ "+ebInfo } - override def toString = { - val pcws = and(ws, pc) - - val ebInfo = "/"+eb.valids.size+","+eb.invalids.size+"/" - - "⟦ "+as.mkString(";")+", "+(if (pcws != BooleanLiteral(true)) pcws+" ≺ " else "")+" ⟨ "+phi+" ⟩ "+xs.mkString(";")+" ⟧ "+ebInfo - } - // Qualified example bank, allows us to perform operations (e.g. filter) with expressions def qeb(implicit sctx: SearchContext) = QualifiedExampleBank(this.as, this.xs, eb) } diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala index 908b753d9..e9c3fdcae 100644 --- a/src/main/scala/leon/synthesis/Rules.scala +++ b/src/main/scala/leon/synthesis/Rules.scala @@ -20,7 +20,9 @@ abstract class Rule(val name: String) extends RuleDSL { implicit val thisRule = this - override def toString = name + implicit def hctxToCtx(implicit hctx: SearchContext): LeonContext = hctx.sctx.context + + def asString(implicit ctx: LeonContext) = name } abstract class NormalizingRule(name: String) extends Rule(name) { @@ -75,7 +77,7 @@ abstract class RuleInstantiation(val description: String, def apply(hctx: SearchContext): RuleApplication - override def toString = description + def asString(implicit ctx: LeonContext) = description } /** diff --git a/src/main/scala/leon/synthesis/Solution.scala b/src/main/scala/leon/synthesis/Solution.scala index 812b75353..3a44131eb 100644 --- a/src/main/scala/leon/synthesis/Solution.scala +++ b/src/main/scala/leon/synthesis/Solution.scala @@ -20,8 +20,6 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr, val isTrust "⟨ "+pre.asString+" | "+defs.map(_.asString).mkString(" ")+" "+term.asString+" ⟩" } - override def toString = "⟨ "+pre+" | "+defs.mkString(" ")+" "+term+" ⟩" - def guardedTerm = { if (pre == BooleanLiteral(true)) { term diff --git a/src/main/scala/leon/synthesis/graph/Graph.scala b/src/main/scala/leon/synthesis/graph/Graph.scala index aac4d2fd2..b4db0e471 100644 --- a/src/main/scala/leon/synthesis/graph/Graph.scala +++ b/src/main/scala/leon/synthesis/graph/Graph.scala @@ -30,6 +30,8 @@ sealed abstract class Node(cm: CostModel, val parent: Option[Node]) { var parents: List[Node] = parent.toList var descendants: List[Node] = Nil + def asString(implicit ctx: LeonContext): String + // indicates whether this particular node has already been expanded var isExpanded: Boolean = false def expand(hctx: SearchContext) @@ -98,7 +100,7 @@ sealed abstract class Node(cm: CostModel, val parent: Option[Node]) { class AndNode(cm: CostModel, parent: Option[Node], val ri: RuleInstantiation) extends Node(cm, parent) { val p = ri.problem - override def toString = "\u2227 "+ri + override def asString(implicit ctx: LeonContext) = "\u2227 "+ri.asString def expand(hctx: SearchContext): Unit = { require(!isExpanded) @@ -172,7 +174,7 @@ class AndNode(cm: CostModel, parent: Option[Node], val ri: RuleInstantiation) ex class OrNode(cm: CostModel, parent: Option[Node], val p: Problem) extends Node(cm, parent) { - override def toString = "\u2228 "+p + override def asString(implicit ctx: LeonContext) = "\u2228 "+p.asString def getInstantiations(hctx: SearchContext): List[RuleInstantiation] = { val rules = hctx.sctx.rules @@ -181,7 +183,7 @@ class OrNode(cm: CostModel, parent: Option[Node], val p: Problem) extends Node(c for ((_, rs) <- rulesPrio) { val results = rs.flatMap{ r => - hctx.context.timers.synthesis.instantiations.get(r.toString).timed { + hctx.context.timers.synthesis.instantiations.get(r.asString(hctx.sctx.context)).timed { r.instantiateOn(hctx, p) } }.toList diff --git a/src/main/scala/leon/synthesis/graph/Search.scala b/src/main/scala/leon/synthesis/graph/Search.scala index 9f1726d98..d63bca0b5 100644 --- a/src/main/scala/leon/synthesis/graph/Search.scala +++ b/src/main/scala/leon/synthesis/graph/Search.scala @@ -21,7 +21,7 @@ abstract class Search(ctx: LeonContext, ci: ChooseInfo, p: Problem, costModel: C ctx.timers.synthesis.step.timed { n match { case an: AndNode => - ctx.timers.synthesis.applications.get(an.ri.toString).timed { + ctx.timers.synthesis.applications.get(an.ri.asString(sctx.context)).timed { an.expand(SearchContext(sctx, ci, an, this)) } @@ -214,15 +214,15 @@ class ManualSearch(ctx: LeonContext, ci: ChooseInfo, problem: Problem, costModel def displayNode(n: Node): String = n match { case an: AndNode => - val app = an.ri + val app = an.ri.asString(ctx) s"(${n.cost.asString}) ${indent(app)}" case on: OrNode => val p = on.p.asString(ctx) s"(${n.cost.asString}) ${indent(p)}" } - def indent(a: Any): String = { - a.toString.replaceAll("\n", "\n"+(" "*12)) + def indent(a: String): String = { + a.replaceAll("\n", "\n"+(" "*12)) } def pathToString(cd: List[Int]): String = { diff --git a/src/main/scala/leon/synthesis/rules/ADTDual.scala b/src/main/scala/leon/synthesis/rules/ADTDual.scala index ddf37760e..59fcabb3b 100644 --- a/src/main/scala/leon/synthesis/rules/ADTDual.scala +++ b/src/main/scala/leon/synthesis/rules/ADTDual.scala @@ -16,7 +16,6 @@ case object ADTDual extends NormalizingRule("ADTDual") { val TopLevelAnds(exprs) = p.phi - val (toRemove, toAdd) = exprs.collect { case eq @ Equals(cc @ CaseClass(ct, args), e) if (variablesOf(e) -- as).isEmpty && (variablesOf(cc) & xs).nonEmpty => (eq, IsInstanceOf(ct, e) +: (ct.fields zip args).map{ case (vd, ex) => Equals(ex, caseClassSelector(ct, e, vd.id)) } ) diff --git a/src/main/scala/leon/synthesis/rules/ADTInduction.scala b/src/main/scala/leon/synthesis/rules/ADTInduction.scala index 45509bdb7..3b6df4524 100644 --- a/src/main/scala/leon/synthesis/rules/ADTInduction.scala +++ b/src/main/scala/leon/synthesis/rules/ADTInduction.scala @@ -113,7 +113,7 @@ case object ADTInduction extends Rule("ADT Induction") { } } - Some(decomp(subProblemsInfo.map(_._1).toList, onSuccess, s"ADT Induction on '$origId'")) + Some(decomp(subProblemsInfo.map(_._1).toList, onSuccess, s"ADT Induction on '${origId.asString}'")) } else { None } diff --git a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala b/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala index 3f39582e3..093897196 100644 --- a/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala +++ b/src/main/scala/leon/synthesis/rules/ADTLongInduction.scala @@ -162,7 +162,7 @@ case object ADTLongInduction extends Rule("ADT Long Induction") { } } - Some(decomp(subProblemsInfo.map(_._1), onSuccess, s"ADT Long Induction on '$origId'")) + Some(decomp(subProblemsInfo.map(_._1), onSuccess, s"ADT Long Induction on '${origId.asString}'")) } else { None } diff --git a/src/main/scala/leon/synthesis/rules/ADTSplit.scala b/src/main/scala/leon/synthesis/rules/ADTSplit.scala index a57cdfb15..5d0ab6ce1 100644 --- a/src/main/scala/leon/synthesis/rules/ADTSplit.scala +++ b/src/main/scala/leon/synthesis/rules/ADTSplit.scala @@ -87,7 +87,7 @@ case object ADTSplit extends Rule("ADT Split.") { Some(Solution(orJoin(globalPre), sols.flatMap(_.defs).toSet, matchExpr(Variable(id), cases), sols.forall(_.isTrusted))) } - decomp(subInfo.map(_._2).toList, onSuccess, s"ADT Split on '$id'") + decomp(subInfo.map(_._2).toList, onSuccess, s"ADT Split on '${id.asString}'") } } } diff --git a/src/main/scala/leon/synthesis/rules/Assert.scala b/src/main/scala/leon/synthesis/rules/Assert.scala index 270392aa1..4cdb0fbf2 100644 --- a/src/main/scala/leon/synthesis/rules/Assert.scala +++ b/src/main/scala/leon/synthesis/rules/Assert.scala @@ -24,7 +24,7 @@ case object Assert extends NormalizingRule("Assert") { Some(decomp(List(sub), { case (s @ Solution(pre, defs, term)) :: Nil => Some(Solution(andJoin(exprsA :+ pre), defs, term, s.isTrusted)) case _ => None - }, "Assert "+andJoin(exprsA))) + }, "Assert "+andJoin(exprsA).asString)) } } else { None diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala index c78750adc..386148ce6 100644 --- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala +++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala @@ -43,7 +43,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { val nProgramsLimit = 100000 val sctx = hctx.sctx - implicit val ctx = sctx.context + val ctx = sctx.context // CEGIS Flags to activate or deactivate features @@ -125,7 +125,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { private var slots = Map[SizedLabel[T], Int]().withDefaultValue(0) private def streamOf(t: SizedLabel[T]): Stream[Identifier] = { - FreshIdentifier(t.toString, t.getType, true) #:: streamOf(t) + FreshIdentifier(t.asString, t.getType, true) #:: streamOf(t) } def rewind(): Unit = { @@ -285,7 +285,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { // Define all C-def for ((c, alts) <- cTree) yield { - cToFd += c -> new FunDef(FreshIdentifier(c.toString, alwaysShowUniqueID = true), + cToFd += c -> new FunDef(FreshIdentifier(c.asString, alwaysShowUniqueID = true), Seq(), c.getType, p.as.map(id => ValDef(id))) @@ -641,6 +641,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { def apply(hctx: SearchContext): RuleApplication = { var result: Option[RuleApplication] = None val sctx = hctx.sctx + implicit val ctx = sctx.context val ndProgram = new NonDeterministicProgram(p) ndProgram.init() diff --git a/src/main/scala/leon/synthesis/rules/CEGLESS.scala b/src/main/scala/leon/synthesis/rules/CEGLESS.scala index 31484628a..c19a4203e 100644 --- a/src/main/scala/leon/synthesis/rules/CEGLESS.scala +++ b/src/main/scala/leon/synthesis/rules/CEGLESS.scala @@ -13,9 +13,10 @@ import Witnesses._ case object CEGLESS extends CEGISLike[Label[String]]("CEGLESS") { def getParams(sctx: SynthesisContext, p: Problem) = { - val TopLevelAnds(clauses) = p.ws + val ctx = sctx.context + val guides = clauses.collect { case Guide(e) => e } @@ -23,9 +24,9 @@ case object CEGLESS extends CEGISLike[Label[String]]("CEGLESS") { val inputs = p.as.map(_.toVariable) sctx.reporter.ifDebug { printer => - printer("Guides available:") + printer("Guides available:") for (g <- guides) { - printer(" - "+g) + printer(" - "+g.asString(ctx)) } } diff --git a/src/main/scala/leon/synthesis/rules/DetupleInput.scala b/src/main/scala/leon/synthesis/rules/DetupleInput.scala index bb0f1b4ba..ed68fbfac 100644 --- a/src/main/scala/leon/synthesis/rules/DetupleInput.scala +++ b/src/main/scala/leon/synthesis/rules/DetupleInput.scala @@ -72,7 +72,6 @@ case object DetupleInput extends NormalizingRule("Detuple In") { } val newAs = subAs.flatten - //sctx.reporter.warning("newOuts: " + newOuts.toString) // Recompose CaseClasses and Tuples. // E.g. Cons(l.head, l.tail) ~~> l @@ -83,7 +82,7 @@ case object DetupleInput extends NormalizingRule("Detuple In") { case (CaseClassSelector(ct, e, id), field) if field.id == id => (ct, e) case _ => return e }.unzip - + if (cts.distinct.size == 1 && es.distinct.size == 1) { es.head } else { diff --git a/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala b/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala index 10ba905b8..4754f6bc5 100644 --- a/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala +++ b/src/main/scala/leon/synthesis/rules/EquivalentInputs.scala @@ -84,7 +84,7 @@ case object EquivalentInputs extends NormalizingRule("EquivalentInputs") { _:Expr ) - val substString = substs.map { case (f, t) => f+" -> "+t } + val substString = substs.map { case (f, t) => f.asString+" -> "+t.asString } List(decomp(List(sub), forwardMap(subst), "Equivalent Inputs ("+substString.mkString(", ")+")")) } else { diff --git a/src/main/scala/leon/synthesis/utils/ExpressionGrammar.scala b/src/main/scala/leon/synthesis/utils/ExpressionGrammar.scala index 0aad97735..82c6552fe 100644 --- a/src/main/scala/leon/synthesis/utils/ExpressionGrammar.scala +++ b/src/main/scala/leon/synthesis/utils/ExpressionGrammar.scala @@ -50,9 +50,9 @@ abstract class ExpressionGrammar[T <% Typed] { } - final def printProductions(printer: String => Unit) { + final def printProductions(printer: String => Unit)(implicit ctx: LeonContext) { for ((t, gs) <- cache; g <- gs) { - val subs = g.subTrees.map { t => FreshIdentifier(Console.BOLD+t.toString+Console.RESET, t.getType).toVariable} + val subs = g.subTrees.map { t => FreshIdentifier(Console.BOLD+t.asString+Console.RESET, t.getType).toVariable} val gen = g.builder(subs) printer(f"${Console.BOLD}$t%30s${Console.RESET} ::= $gen") @@ -210,7 +210,7 @@ object ExpressionGrammars { case class Label[T](t: TypeTree, l: T, depth: Option[Int] = None) extends Typed { val getType = t - override def toString = t.toString+"#"+l+depth.map(d => "@"+d).getOrElse("") + override def asString(implicit ctx: LeonContext) = t.asString+"#"+l+depth.map(d => "@"+d).getOrElse("") } case class SimilarTo(e: Expr, terminals: Set[Expr] = Set(), sctx: SynthesisContext, p: Problem) extends ExpressionGrammar[Label[String]] { @@ -356,7 +356,7 @@ object ExpressionGrammars { val res = rec(e, gl) //for ((t, g) <- res) { - // val subs = g.subTrees.map { t => FreshIdentifier(t.toString, t.getType).toVariable} + // val subs = g.subTrees.map { t => FreshIdentifier(t.asString, t.getType).toVariable} // val gen = g.builder(subs) // println(f"$t%30s ::= "+gen) @@ -435,7 +435,7 @@ object ExpressionGrammars { case class SizedLabel[T <% Typed](underlying: T, size: Int) extends Typed { val getType = underlying.getType - override def toString = underlying.toString+"|"+size+"|" + override def asString(implicit ctx: LeonContext) = underlying.asString+"|"+size+"|" } case class SizeBoundedGrammar[T <% Typed](g: ExpressionGrammar[T]) extends ExpressionGrammar[SizedLabel[T]] { diff --git a/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala b/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala index ae4632031..7aa46f7a0 100644 --- a/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala +++ b/src/main/scala/leon/synthesis/utils/SynthesisProblemExtractionPhase.scala @@ -13,7 +13,7 @@ object SynthesisProblemExtractionPhase extends LeonPhase[Program, (Program, Map[ def run(ctx: LeonContext)(p: Program): (Program, Map[FunDef, Seq[ChooseInfo]]) = { // Look for choose() - val results = for (f <- funDefsFromMain(p).toSeq.sortBy(_.id.toString) if f.body.isDefined) yield { + val results = for (f <- funDefsFromMain(p).toSeq.sortBy(_.id) if f.body.isDefined) yield { f -> ChooseInfo.extractFromFunction(ctx, p, f) } diff --git a/src/main/scala/leon/verification/DefaultTactic.scala b/src/main/scala/leon/verification/DefaultTactic.scala index 43ef19dfd..11de3159c 100644 --- a/src/main/scala/leon/verification/DefaultTactic.scala +++ b/src/main/scala/leon/verification/DefaultTactic.scala @@ -33,7 +33,7 @@ class DefaultTactic(vctx: VerificationContext) extends Tactic(vctx) { case ((fi @ FunctionInvocation(tfd, args), pre), path) => val pre2 = tfd.withParamSubst(args, pre) val vc = implies(and(precOrTrue(fd), path), pre2) - val fiS = sizeLimit(fi.toString, 40) + val fiS = sizeLimit(fi.asString, 40) VC(vc, fd, VCKinds.Info(VCKinds.Precondition, s"call $fiS"), this).setPos(fi) } diff --git a/src/main/scala/leon/verification/InductionTactic.scala b/src/main/scala/leon/verification/InductionTactic.scala index 8ce88e490..878b902ce 100644 --- a/src/main/scala/leon/verification/InductionTactic.scala +++ b/src/main/scala/leon/verification/InductionTactic.scala @@ -44,7 +44,7 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) { implies(andJoin(subCases), application(post, Seq(body))) ) - VC(vc, fd, VCKinds.Info(VCKinds.Postcondition, s"ind. on ${arg.id} / ${cct.classDef.id}"), this).setPos(fd) + VC(vc, fd, VCKinds.Info(VCKinds.Postcondition, s"ind. on ${arg.asString} / ${cct.classDef.id.asString}"), this).setPos(fd) } case (body, _, post) => @@ -82,9 +82,9 @@ class InductionTactic(vctx: VerificationContext) extends DefaultTactic(vctx) { ) // Crop the call to display it properly - val fiS = sizeLimit(fi.toString, 25) + val fiS = sizeLimit(fi.asString, 25) - VC(vc, fd, VCKinds.Info(VCKinds.Precondition, s"call $fiS, ind. on ($arg : ${cct.classDef.id})"), this).setPos(fi) + VC(vc, fd, VCKinds.Info(VCKinds.Precondition, s"call $fiS, ind. on (${arg.asString} : ${cct.classDef.id.asString})"), this).setPos(fi) } case (body, _) => diff --git a/src/main/scala/leon/verification/Tactic.scala b/src/main/scala/leon/verification/Tactic.scala index 105c61d61..2295cb191 100644 --- a/src/main/scala/leon/verification/Tactic.scala +++ b/src/main/scala/leon/verification/Tactic.scala @@ -10,6 +10,8 @@ import purescala.ExprOps._ abstract class Tactic(vctx: VerificationContext) { val description : String + implicit val ctx = vctx.context + def generateVCs(fd: FunDef): Seq[VC] = { generatePostconditions(fd) ++ generatePreconditions(fd) ++ diff --git a/src/regression/scala/leon/test/synthesis/StablePrintingSuite.scala b/src/regression/scala/leon/test/synthesis/StablePrintingSuite.scala index aec2a04a3..d602a05a2 100644 --- a/src/regression/scala/leon/test/synthesis/StablePrintingSuite.scala +++ b/src/regression/scala/leon/test/synthesis/StablePrintingSuite.scala @@ -84,7 +84,7 @@ class StablePrintingSuite extends LeonTestSuite { val search = synthesizer.getSearch val hctx = SearchContext(sctx, ci, search.g.root, search) val problem = ci.problem - info(j.info("synthesis "+problem)) + info(j.info("synthesis "+problem.asString(sctx.context))) val apps = sctx.rules flatMap { _.instantiateOn(hctx, problem)} for (a <- apps) { @@ -101,7 +101,7 @@ class StablePrintingSuite extends LeonTestSuite { p.toString }) - workList push Job(newContent, (i to i+sub.size).toSet, a.toString :: j.rules) + workList push Job(newContent, (i to i+sub.size).toSet, a.asString(ctx) :: j.rules) case None => } } diff --git a/src/regression/scala/leon/test/synthesis/SynthesisSuite.scala b/src/regression/scala/leon/test/synthesis/SynthesisSuite.scala index a4804afeb..e949f139d 100644 --- a/src/regression/scala/leon/test/synthesis/SynthesisSuite.scala +++ b/src/regression/scala/leon/test/synthesis/SynthesisSuite.scala @@ -76,7 +76,7 @@ class SynthesisSuite extends LeonTestSuite { def matchingDesc(app: RuleInstantiation, n: String): Boolean = { import java.util.regex.Pattern val pattern = Pattern.quote(n).replace("*", "\\E.*\\Q") - app.toString.matches(pattern) + app.asString(ctx).matches(pattern) } } diff --git a/src/test/scala/leon/test/helpers/WithLikelyEq.scala b/src/test/scala/leon/test/helpers/WithLikelyEq.scala index aee9e7671..c998591f5 100644 --- a/src/test/scala/leon/test/helpers/WithLikelyEq.scala +++ b/src/test/scala/leon/test/helpers/WithLikelyEq.scala @@ -38,7 +38,9 @@ trait WithLikelyEq { val r1 = evaluator.eval(e1) val r2 = evaluator.eval(e2) - assert(r1 === r2, s"'$e1' != '$e2' ('$r1' != '$r2')") + if (r1 != r2) { + fail(s"'${e1.asString(ctx)}' != '${e2.asString(ctx)}' ('$r1' != '$r2')") + } } else { val allValues = freeVars.map(id => values.get(id).map(Seq(_)).getOrElse(typesValues(id.getType))) @@ -57,7 +59,9 @@ trait WithLikelyEq { val r1 = evaluator.eval(e1, m) val r2 = evaluator.eval(e2, m) - assert(r1 === r2, s"'$e1' != '$e2' with '$m' ('$r1' != '$r2')") + if (r1 != r2) { + fail(s"'${e1.asString(ctx)}' != '${e2.asString(ctx)}' with '$m' ('$r1' != '$r2')") + } } } } -- GitLab