From 0cb1ea618fd2af34281b71bfa4fa020d59b5d8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Mayer?= <a-mikmay@microsoft.com> Date: Mon, 7 Dec 2015 21:43:36 +0100 Subject: [PATCH] Removing the body of the function when adding examples. --- .../synthesis/disambiguation/ExamplesAdder.scala | 8 ++++++++ .../leon/synthesis/disambiguation/Question.scala | 2 +- .../synthesis/disambiguation/QuestionBuilder.scala | 10 +++++----- .../scala/leon/synthesis/rules/StringRender.scala | 14 +++----------- testcases/stringrender/GrammarRender.scala | 3 +++ 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala b/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala index 31463d4e7..109cd677d 100644 --- a/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala +++ b/src/main/scala/leon/synthesis/disambiguation/ExamplesAdder.scala @@ -40,6 +40,7 @@ class ExamplesAdder(ctx0: LeonContext, program: Program) { } } if(i == -1) { fd.postcondition = Some(Lambda(Seq(ValDef(id, tpe)), and(post, Passes(inputVariables, Variable(id), newCases)))) + ctx0.reporter.info("No top-level passes in postcondition, adding it: " + fd) } else { val newPasses = exprs(i) match { case Passes(in, out, cases) => @@ -48,14 +49,21 @@ class ExamplesAdder(ctx0: LeonContext, program: Program) { } val newPost = and(exprs.updated(i, newPasses) : _*) fd.postcondition = Some(Lambda(Seq(ValDef(id, tpe)), newPost)) + ctx0.reporter.info("Adding the example to the passes postcondition: " + fd) } } } else { fd.postcondition = Some(Lambda(Seq(ValDef(id, tpe)), and(post, Passes(inputVariables, Variable(id), newCases)))) + ctx0.reporter.info("No passes in postcondition, adding it:" + fd) } case None => val id = FreshIdentifier("res", fd.returnType, false) fd.postcondition = Some(Lambda(Seq(ValDef(id, None)), Passes(inputVariables, Variable(id), newCases))) + ctx0.reporter.info("No postcondition, adding it: " + fd) + } + fd.body match { // TODO: Is it correct to discard the choose construct inside the body? + case Some(Choose(Lambda(Seq(ValDef(id, tpe)), bodyChoose))) => fd.body = Some(Hole(id.getType, Nil)) + case _ => } } diff --git a/src/main/scala/leon/synthesis/disambiguation/Question.scala b/src/main/scala/leon/synthesis/disambiguation/Question.scala index 4074b0abe..eed7bfc1a 100644 --- a/src/main/scala/leon/synthesis/disambiguation/Question.scala +++ b/src/main/scala/leon/synthesis/disambiguation/Question.scala @@ -6,4 +6,4 @@ import purescala.Expressions.Expr /** * @author Mikael */ -case class Question[T <: Expr](inputs: List[Expr], current_output: T, other_outputs: List[T]) \ No newline at end of file +case class Question[T <: Expr](inputs: Seq[Expr], current_output: T, other_outputs: List[T]) \ No newline at end of file diff --git a/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala b/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala index cb29b9b19..08d2daabc 100644 --- a/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala +++ b/src/main/scala/leon/synthesis/disambiguation/QuestionBuilder.scala @@ -83,7 +83,7 @@ object QuestionBuilder { * @return An ordered * */ -class QuestionBuilder[T <: Expr](input: List[Identifier], ruleApplication: RuleClosed, filter: Expr => Option[T])(implicit c: LeonContext, p: Program) { +class QuestionBuilder[T <: Expr](input: Seq[Identifier], solutions: Stream[Solution], filter: Expr => Option[T])(implicit c: LeonContext, p: Program) { import QuestionBuilder._ private var _argTypes = input.map(_.getType) private var _questionSorMethod: QuestionSortingType = QuestionSortingType.IncreasingInputSize @@ -113,7 +113,7 @@ class QuestionBuilder[T <: Expr](input: List[Identifier], ruleApplication: RuleC /** Returns a list of input/output questions to ask to the user. */ def result(): List[Question[T]] = { - if(ruleApplication.solutions.isEmpty) return Nil + if(solutions.isEmpty) return Nil val enum = new MemoizedEnumerator[TypeTree, Expr](ValueGrammar.getProductions) val values = enum.iterator(tupleTypeWrap(_argTypes)) @@ -123,8 +123,8 @@ class QuestionBuilder[T <: Expr](input: List[Identifier], ruleApplication: RuleC val enumerated_inputs = instantiations.take(expressionsToTake).toList - val solution = ruleApplication.solutions.head - val alternatives = ruleApplication.solutions.drop(1).take(solutionsToTake).toList + val solution = solutions.head + val alternatives = solutions.drop(1).take(solutionsToTake).toList val questions = ListBuffer[Question[T]]() for{possible_input <- enumerated_inputs current_output_nonfiltered <- run(solution, possible_input) @@ -136,7 +136,7 @@ class QuestionBuilder[T <: Expr](input: List[Identifier], ruleApplication: RuleC if alternative_output != current_output } yield alternative_output_filtered).distinct if(alternative_outputs.nonEmpty) { - questions += Question(possible_input.map(_._2), current_output, alternative_outputs.sortWith((e,f) => _alternativeSortMethod.compare(e, f) < 0)) + questions += Question(possible_input.map(_._2), current_output, alternative_outputs.sortWith((e,f) => _alternativeSortMethod.compare(e, f) <= 0)) } } questions.toList.sortBy(_questionSorMethod(_)) diff --git a/src/main/scala/leon/synthesis/rules/StringRender.scala b/src/main/scala/leon/synthesis/rules/StringRender.scala index c088c2018..30ef401de 100644 --- a/src/main/scala/leon/synthesis/rules/StringRender.scala +++ b/src/main/scala/leon/synthesis/rules/StringRender.scala @@ -189,7 +189,7 @@ case object StringRender extends Rule("StringRender") { /** Find ambiguities not containing _edit_me_ to ask to the user */ def askQuestion(input: List[Identifier], r: RuleClosed)(implicit c: LeonContext, p: Program): List[disambiguation.Question[StringLiteral]] = { //if !s.contains(EDIT_ME) - val qb = new disambiguation.QuestionBuilder(input, r, (expr: Expr) => expr match { + val qb = new disambiguation.QuestionBuilder(input, r.solutions, (expr: Expr) => expr match { case s@StringLiteral(slv) if !slv.contains(EDIT_ME) => Some(s) case _ => None }) @@ -257,7 +257,7 @@ case object StringRender extends Rule("StringRender") { } val funName3 = funName2.replaceAll("[^a-zA-Z0-9_]","") val funName = funName3(0).toLower + funName3.substring(1) - val funId = FreshIdentifier(funName, alwaysShowUniqueID = false) + val funId = FreshIdentifier(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. fd @@ -425,15 +425,7 @@ case object StringRender extends Rule("StringRender") { )) hctx.reporter.debug("Inferred expression:\n" + expr + toDebug) - val res = findSolutions(examples, expr, funDefs.values.toSeq) - res match { - case r: RuleClosed => - val questions = askQuestion(p.as, r)(hctx.context, hctx.program) - println("Questions:") - println(questions.map(q => "For (" + q.inputs.mkString(", ") + "), res = " + q.current_output + ", could also be " + q.other_outputs.toSet.map((s: StringLiteral) => s.asString).mkString(",")).mkString("\n")) - case _ => - } - res + findSolutions(examples, expr, funDefs.values.toSeq) } ruleInstantiations.toList diff --git a/testcases/stringrender/GrammarRender.scala b/testcases/stringrender/GrammarRender.scala index 59928dceb..f0c1e5929 100644 --- a/testcases/stringrender/GrammarRender.scala +++ b/testcases/stringrender/GrammarRender.scala @@ -238,4 +238,7 @@ S0 -> S0 t1""" def synthesizePlainTextRules(s: Grammar): String = { ???[String] } ensuring psPlainTextRules(s) + + def allGrammarsAreIdentical(g: Grammar, g2: Grammar) = (g == g2 || g.rules == g2.rules) holds + } \ No newline at end of file -- GitLab