From 32d9775fd47f09922a28de47ffa868a4740b0873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Mayer?= <mikael.mayer@epfl.ch> Date: Thu, 14 Jan 2016 19:10:40 +0100 Subject: [PATCH] Fixed the import of the abstract pretty printers in the sub-functions. added the incremental grammar based example. --- .../leon/synthesis/rules/StringRender.scala | 42 ++++++++++++------- .../stringrender/SymbolGrammarRender.scala | 14 +++++++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/scala/leon/synthesis/rules/StringRender.scala b/src/main/scala/leon/synthesis/rules/StringRender.scala index 1591f5ce9..1f62ec67b 100644 --- a/src/main/scala/leon/synthesis/rules/StringRender.scala +++ b/src/main/scala/leon/synthesis/rules/StringRender.scala @@ -330,11 +330,13 @@ case object StringRender extends Rule("StringRender") { def empty( definedStringConverters: StringConverters, abstractStringConverters: StringConverters, - originalInputs: Set[Identifier])(implicit hctx: SearchContext) = + originalInputs: Set[Identifier], + provided_functions: Seq[Identifier])(implicit hctx: SearchContext) = new StringSynthesisContext(None, new StringSynthesisResult(Map(), Set()), definedStringConverters, abstractStringConverters, - originalInputs) + originalInputs, + provided_functions) } /** Context for the current synthesis process */ @@ -343,19 +345,22 @@ case object StringRender extends Rule("StringRender") { val result: StringSynthesisResult, val definedStringConverters: StringConverters, val abstractStringConverters: StringConverters, - val originalInputs: Set[Identifier] + val originalInputs: Set[Identifier], + val provided_functions: Seq[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, - originalInputs) + originalInputs, + provided_functions) } def copy(currentCaseClassParent: Option[TypeTree]=currentCaseClassParent, result: StringSynthesisResult = result): StringSynthesisContext = new StringSynthesisContext(currentCaseClassParent, result, definedStringConverters, abstractStringConverters, - originalInputs) + originalInputs, + provided_functions) def freshFunName(s: String) = result.freshFunName(s) } @@ -375,7 +380,7 @@ case object StringRender extends Rule("StringRender") { val funName = funName3(0).toLower + funName3.substring(1) val funId = FreshIdentifier(ctx.freshFunName(funName), alwaysShowUniqueID = true) val argId= FreshIdentifier(tpe.typeToConvert.asString(hctx.context).toLowerCase()(0).toString, tpe.typeToConvert) - val fd = new FunDef(funId, Nil, ValDef(argId) :: Nil, StringType) // Empty function. + val fd = new FunDef(funId, Nil, ValDef(argId) :: ctx.provided_functions.map(ValDef(_, false)).toList, StringType) // Empty function. fd } @@ -451,11 +456,11 @@ case object StringRender extends Rule("StringRender") { val dependentType = DependentType(ctx.currentCaseClassParent, input.asString(hctx.program)(hctx.context), input.getType) ctx.result.adtToString.get(dependentType) match { case Some(fd) => - gatherInputs(ctx, q, result += Stream((functionInvocation(fd._1, Seq(input)), Nil))) + gatherInputs(ctx, q, result += Stream((functionInvocation(fd._1, input::ctx.provided_functions.toList.map(Variable)), Nil))) case None => // No function can render the current type. 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 FunctionInvocation(fd, 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)) @@ -470,9 +475,9 @@ case object StringRender extends Rule("StringRender") { case StringType => gatherInputs(ctx, q, result += mergeResults(Stream((input, Nil), - (FunctionInvocation( - hctx.program.library.escape.get.typed, - Seq(input)): Expr, Nil)))) + (functionInvocation( + hctx.program.library.escape.get, + input::ctx.provided_functions.toList.map(Variable)): Expr, Nil)))) case BooleanType => val (bTemplate, vs) = booleanTemplate(input).instantiateWithVars gatherInputs(ctx, q, result += mergeResults(Stream((BooleanToString(input), Nil), (bTemplate, vs)))) @@ -508,16 +513,20 @@ case object StringRender extends Rule("StringRender") { Stream(constantPatternMatching(fd, act)) ++ allMatchExprsEnd } else allMatchExprsEnd gatherInputs(ctx3.add(dependentType, fd, allMatchExprs), q, - result += Stream((functionInvocation(fd, Seq(input)), Nil))) + result += Stream((functionInvocation(fd, input::ctx.provided_functions.toList.map(Variable)), Nil))) case cct@CaseClassType(ccd@CaseClassDef(id, tparams, parent, isCaseObject), tparams2) => val (newCases, result3) = extractCaseVariants(cct, ctx2) val allMatchExprs = newCases.map(acase => mergeMatchCases(fd)(Seq(acase))) gatherInputs(ctx2.copy(result = result3).add(dependentType, fd, allMatchExprs), q, - result += Stream((functionInvocation(fd, Seq(input)), Nil))) + result += Stream((functionInvocation(fd, input::ctx.provided_functions.toList.map(Variable)), Nil))) } } case TypeParameter(t) => - hctx.reporter.fatalError("Could not handle type parameter for string rendering " + t) + if(converters.isEmpty) { + hctx.reporter.fatalError("Could not handle type parameter for string rendering " + t) + } else { + gatherInputs(ctx, q, result += mergeResults(Stream.empty)) + } case tpe => hctx.reporter.fatalError("Could not handle class type for string rendering " + tpe) } @@ -580,7 +589,7 @@ case object StringRender extends Rule("StringRender") { case _ => Nil }}).groupBy(_._1).mapValues(_.map(_._2)) - val inputVariables = p.as.filter( x => x.getType match { + val (inputVariables, functionVariables) = p.as.partition ( x => x.getType match { case f: FunctionType => false case _ => true }) @@ -591,7 +600,8 @@ case object StringRender extends Rule("StringRender") { StringSynthesisContext.empty( definedStringConverters, abstractStringConverters, - p.as.toSet + p.as.toSet, + functionVariables ), inputVariables.map(Variable)) val funDefs = synthesisResult.adtToString diff --git a/testcases/stringrender/SymbolGrammarRender.scala b/testcases/stringrender/SymbolGrammarRender.scala index 7d22b44c9..91c1517a7 100644 --- a/testcases/stringrender/SymbolGrammarRender.scala +++ b/testcases/stringrender/SymbolGrammarRender.scala @@ -18,6 +18,11 @@ object GrammarRender { case class NonTerminal(tag: String, vcontext: List[Symbol], hcontext: List[Symbol]) extends Symbol /** A tagged terminal */ case class Terminal(tag: String) extends Symbol + + /** All possible right-hand-side of rules */ + case class Expansion(ls: List[List[Symbol]]) + /** A grammar here has a start sequence instead of a start symbol */ + case class Grammar(start: List[Symbol], rules: List[(Symbol, Expansion)]) def symbol_markov(s: Grammar): String = { ???[String] @@ -43,4 +48,13 @@ object GrammarRender { "Nfoo_vNfoo_Nfoo" } } + + def grammarToString(p : Grammar): String = { + ???[String] + } ensuring { + (res : String) => (p, res) passes { + case _ if false => + "" + } + } } \ No newline at end of file -- GitLab