From ea95a62f98d1439777f95395d4fce73191f18d9b Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Fri, 19 Oct 2012 16:29:10 +0200 Subject: [PATCH] This is madness --- src/main/scala/leon/synthesis/Problem.scala | 9 +++- src/main/scala/leon/synthesis/Rules.scala | 9 +--- src/main/scala/leon/synthesis/Solution.scala | 13 +++++- src/main/scala/leon/synthesis/Step.scala | 4 -- .../scala/leon/synthesis/Synthesizer.scala | 39 +++++++++++++++++ src/main/scala/leon/synthesis/Task.scala | 43 +++++++++++++++++++ src/main/scala/leon/synthesis/package.scala | 1 - 7 files changed, 104 insertions(+), 14 deletions(-) delete mode 100644 src/main/scala/leon/synthesis/Step.scala create mode 100644 src/main/scala/leon/synthesis/Synthesizer.scala create mode 100644 src/main/scala/leon/synthesis/Task.scala diff --git a/src/main/scala/leon/synthesis/Problem.scala b/src/main/scala/leon/synthesis/Problem.scala index c60c0ca4d..b62d73254 100644 --- a/src/main/scala/leon/synthesis/Problem.scala +++ b/src/main/scala/leon/synthesis/Problem.scala @@ -1,4 +1,11 @@ package leon package synthesis -case class Problem(); +import leon.purescala.Trees._ +import leon.purescala.Common._ + +// Defines a synthesis triple of the form: +// ⟦ as ⟨ phi ⟩ xs ⟧ +case class Problem(as: Set[Identifier], phi: Expr, xs: Set[Identifier]) { + override def toString = "⟦ "+as.mkString(";")+" ⟨ "+phi+" ⟩ "+xs.mkString(";")+" ⟧ " +} diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala index 767f7584d..7cedb5d02 100644 --- a/src/main/scala/leon/synthesis/Rules.scala +++ b/src/main/scala/leon/synthesis/Rules.scala @@ -1,11 +1,6 @@ package leon package synthesis -/** AST definitions for Pure Scala. */ -object Rules { - - abstract class Rule { - def isApplicable(p: Problem): Option[Step]; - } - +abstract class Rule(val name: String) { + def isApplicable(p: Problem, parent: Task): List[Task] } diff --git a/src/main/scala/leon/synthesis/Solution.scala b/src/main/scala/leon/synthesis/Solution.scala index cdc4dcab6..30e19b2ef 100644 --- a/src/main/scala/leon/synthesis/Solution.scala +++ b/src/main/scala/leon/synthesis/Solution.scala @@ -1,4 +1,15 @@ package leon package synthesis -case class Solution(); +import leon.purescala.Trees.Expr + +// Defines a synthesis solution of the form: +// ⟨ P | T ⟩ +case class Solution(pre: Expr, term: Expr) { + override def toString = "⟨ "+pre+" | "+term+" ⟩" +} + +object Solution { + def fromProblem(p: Problem): Solution = + null +} diff --git a/src/main/scala/leon/synthesis/Step.scala b/src/main/scala/leon/synthesis/Step.scala deleted file mode 100644 index 12cad391a..000000000 --- a/src/main/scala/leon/synthesis/Step.scala +++ /dev/null @@ -1,4 +0,0 @@ -package leon -package synthesis - -case class Step(subProblems: List[Problem], construct: List[Solution] => Solution, score: Score); diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala new file mode 100644 index 000000000..6699bc080 --- /dev/null +++ b/src/main/scala/leon/synthesis/Synthesizer.scala @@ -0,0 +1,39 @@ +package leon +package synthesis + +import collection.mutable.PriorityQueue + +class Synthesizer(rules: List[Rule]) { + def applyRules(p: Problem, parent: Task): List[Task] = { + rules.flatMap(_.isApplicable(p, parent)) + } + + def synthesize(p: Problem): Solution = { + val workList = new PriorityQueue[Task]() + + var solution: Solution = null + + val rootTask = new RootTask(p) { + override def notifyParent(s: Solution) { + solution = s + } + } + + workList += rootTask + + while (!workList.isEmpty) { + val task = workList.dequeue() + + task.subProblems match { + case Nil => + task.onSuccess() + case subProblems => + workList ++= subProblems.flatMap(applyRules(_, task)) + } + + } + + solution + } +} + diff --git a/src/main/scala/leon/synthesis/Task.scala b/src/main/scala/leon/synthesis/Task.scala new file mode 100644 index 000000000..959f56452 --- /dev/null +++ b/src/main/scala/leon/synthesis/Task.scala @@ -0,0 +1,43 @@ +package leon +package synthesis + +class Task( + val parent: Task, + val problem: Problem, + val subProblems: List[Problem], + val construct: List[Solution] => Solution, + val score: Score + ) extends Ordered[Task] { + + var subSolutions = Map[Problem, Solution]() + + def compare(that: Task) = this.score - that.score + + def isSuccess = subProblems.isEmpty + + def onSuccess() { + assert(isSuccess) + notifyParent(construct(Nil)) + } + + def onSuccess(p: Problem, s: Solution) { + assert(subProblems contains p) + assert(!(subSolutions contains p)) + + subSolutions += p -> s + + if (subSolutions.size == subProblems.size) { + notifyParent(construct(subProblems map subSolutions)) + } + } + + def notifyParent(solution: Solution) { + parent.onSuccess(problem, solution) + } +} + +class RootTask(p: Problem) extends Task(null, p, List(p), xs => xs.head, 0) { + override def notifyParent(solution: Solution) { + sys.error("You need to extend this!") + } +} diff --git a/src/main/scala/leon/synthesis/package.scala b/src/main/scala/leon/synthesis/package.scala index 6e628ecff..30c04b2f5 100644 --- a/src/main/scala/leon/synthesis/package.scala +++ b/src/main/scala/leon/synthesis/package.scala @@ -2,5 +2,4 @@ package leon package object synthesis { type Score = Int - } -- GitLab