From 9ea7cf9ffa33e94b73a849acb6d1dda911f4cc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Mayer?= <mikael.mayer@epfl.ch> Date: Wed, 13 Jan 2016 18:26:30 +0100 Subject: [PATCH] Corrected missing case Prevented to loop via the top-level function. Prevented the function escape to be considered as a standard string to string converter. --- .../leon/synthesis/rules/StringRender.scala | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/main/scala/leon/synthesis/rules/StringRender.scala b/src/main/scala/leon/synthesis/rules/StringRender.scala index a2abaf39c..61e3c309d 100644 --- a/src/main/scala/leon/synthesis/rules/StringRender.scala +++ b/src/main/scala/leon/synthesis/rules/StringRender.scala @@ -167,8 +167,10 @@ case object StringRender extends Rule("StringRender") { rec(lhs, rhstail, accEqs, accLeft, accRight append s) case (RegularStringFormToken(e)::lhstail, OtherStringChunk(s)::rhstail) => rec(lhstail, rhs, accEqs, accLeft += e, accRight) - case (RegularStringFormToken(e)::lhstail, RegularStringChunk(s)::rhstail) => - rec(lhstail, rhstail, accEqs, accLeft += e, accRight append s) + case (RegularStringFormToken(e)::lhstail, rhs) => + rec(lhstail, rhs, accEqs, accLeft += e, accRight) + case (Nil, RegularStringChunk(s)::rhstail) => + rec(Nil, rhstail, accEqs, accLeft, accRight append s) } rec(lhs, rhs, ListBuffer[Equation](), ListBuffer[StringFormToken](), new StringBuffer) } @@ -327,10 +329,12 @@ case object StringRender extends Rule("StringRender") { object StringSynthesisContext { def empty( definedStringConverters: StringConverters, - abstractStringConverters: StringConverters)(implicit hctx: SearchContext) = + abstractStringConverters: StringConverters, + originalInputs: Set[Identifier])(implicit hctx: SearchContext) = new StringSynthesisContext(None, new StringSynthesisResult(Map(), Set()), definedStringConverters, - abstractStringConverters) + abstractStringConverters, + originalInputs) } /** Context for the current synthesis process */ @@ -338,17 +342,20 @@ case object StringRender extends Rule("StringRender") { val currentCaseClassParent: Option[TypeTree], val result: StringSynthesisResult, val definedStringConverters: StringConverters, - val abstractStringConverters: StringConverters + val abstractStringConverters: StringConverters, + val originalInputs: Set[Identifier] )(implicit hctx: SearchContext) { def add(d: DependentType, f: FunDef, s: Stream[WithIds[Expr]]): StringSynthesisContext = { new StringSynthesisContext(currentCaseClassParent, result.add(d, f, s), definedStringConverters, - abstractStringConverters) + abstractStringConverters, + originalInputs) } def copy(currentCaseClassParent: Option[TypeTree]=currentCaseClassParent, result: StringSynthesisResult = result): StringSynthesisContext = new StringSynthesisContext(currentCaseClassParent, result, definedStringConverters, - abstractStringConverters) + abstractStringConverters, + originalInputs) def freshFunName(s: String) = result.freshFunName(s) } @@ -446,7 +453,11 @@ case object StringRender extends Rule("StringRender") { case Some(fd) => gatherInputs(ctx, q, result += Stream((functionInvocation(fd._1, Seq(input)), Nil))) case None => // No function can render the current type. - val exprs1 = ctx.definedStringConverters.getOrElse(input.getType, Nil).map(f => (f(input), Nil)) + val exprs1 = ctx.definedStringConverters.getOrElse(input.getType, Nil).flatMap(f => + f(input) match { + case FunctionInvocation(fd, Seq(Variable(id))) if ctx.originalInputs(id) => None + case e => Some((e, Nil)) + }) val exprs2 = ctx.abstractStringConverters.getOrElse(input.getType, Nil).map(f => (f(input), Nil)) val converters = (exprs1 ++ exprs2).toStream def mergeResults(defaultconverters: =>Stream[WithIds[Expr]]): Stream[WithIds[Expr]] = { @@ -556,11 +567,14 @@ case object StringRender extends Rule("StringRender") { val examplesFinder = new ExamplesFinder(hctx.context, hctx.program) val examples = examplesFinder.extractFromProblem(p) - val stringConverters: StringConverters = - hctx.program.definedFunctions.filter(fd => fd.returnType == StringType && fd.params.length == 1) + val definedStringConverters: StringConverters = + hctx.program.definedFunctions.filter(fd => + fd.returnType == StringType && fd.params.length == 1 + && fd != hctx.program.library.escape.get + ) .groupBy({ fd => fd.paramIds.head.getType }).mapValues(fds => fds.map((fd : FunDef) => ((x: Expr) => functionInvocation(fd, Seq(x))))) - val internalStringConverters: StringConverters = + val abstractStringConverters: StringConverters = (p.as.flatMap { case x => x.getType match { case FunctionType(Seq(aType), StringType) => List((aType, (arg: Expr) => application(Variable(x), Seq(arg)))) case _ => Nil @@ -569,7 +583,11 @@ case object StringRender extends Rule("StringRender") { val ruleInstantiations = ListBuffer[RuleInstantiation]() ruleInstantiations += RuleInstantiation("String conversion") { val (expr, synthesisResult) = createFunDefsTemplates( - StringSynthesisContext.empty(stringConverters, internalStringConverters), p.as.map(Variable)) + StringSynthesisContext.empty( + definedStringConverters, + abstractStringConverters, + p.as.toSet + ), p.as.map(Variable)) val funDefs = synthesisResult.adtToString /*val toDebug: String = (("\nInferred functions:" /: funDefs)( (t, s) => -- GitLab