diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala index 5d7af0d5f1e4659335c6f24e8471e4f5c805418c..e561579409b0c4779bf8a8043de09a91bc6207ac 100644 --- a/src/main/scala/leon/synthesis/Rules.scala +++ b/src/main/scala/leon/synthesis/Rules.scala @@ -68,7 +68,7 @@ class Ground(synth: Synthesizer) extends Rule("Ground", synth) { synth.solveSAT(p.phi) match { case (Some(true), model) => val onSuccess: List[Solution] => Solution = { - case Nil => Solution(BooleanLiteral(true), replaceFromIDs(model, p.phi)) + case Nil => Solution(BooleanLiteral(true), Tuple(p.xs.map(model))) } List(new Task(synth, parent, this, p, Nil, onSuccess, 200)) diff --git a/src/main/scala/leon/synthesis/SynthesisPhase.scala b/src/main/scala/leon/synthesis/SynthesisPhase.scala index da729fe3c23143f87ad3ff0cdb0f0243e6d6eeaf..84a63890547fc80478b3187d9fa2f8423a5dae3d 100644 --- a/src/main/scala/leon/synthesis/SynthesisPhase.scala +++ b/src/main/scala/leon/synthesis/SynthesisPhase.scala @@ -8,9 +8,10 @@ class SynthesisPhase(reporter: Reporter) extends plugin.TransformationPhase { val description = "Synthesis" def apply(program: Program): Program = { + val quietReporter = new QuietReporter val solvers = List( - new TrivialSolver(reporter), - new FairZ3Solver(reporter) + new TrivialSolver(quietReporter), + new FairZ3Solver(quietReporter) ) new Synthesizer(reporter, solvers).synthesizeAll(program) diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala index c8dccc8ba481d013fd073419d6cc4a3c725869d8..437556701dafef6f1087ef1eb119662b9b2e74e9 100644 --- a/src/main/scala/leon/synthesis/Synthesizer.scala +++ b/src/main/scala/leon/synthesis/Synthesizer.scala @@ -43,6 +43,8 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver]) { info(" => Success!") ss.succeeded() case None => + info(" => Possible Next Steps:") + alternatives.foreach(t => info(" - "+t.description)) workList ++= alternatives } @@ -52,9 +54,6 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver]) { val sol = Solution.choose(sp) warning(" => Solved (by choose): "+sp+" ⊢ "+sol) task.subSucceeded(sp, sol) - } else { - info(" => Possible Next Steps:") - alternatives.foreach(t => info(" - "+t.description)) } } } @@ -78,12 +77,12 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver]) { } def onTaskSucceeded(task: Task, solution: Solution) { - info(" => Solved "+task.problem+" ⊢ "+solution) task match { case rt: RootTask => info(" SUCCESS!") this.solution = solution case t: Task => + info(" => Solved "+task.problem+" ⊢ "+solution) t.parent.subSucceeded(t.problem, solution) } } @@ -101,7 +100,33 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver]) { } def synthesizeAll(program: Program) = { + import purescala.Trees._ + solvers.foreach(_.setProgram(program)) + + val rules = Rules.all(this) + + def noop(u:Expr, u2: Expr) = u + + def actOnChoose(e: Expr, a: Expr): Expr = e match { + case Choose(vars, pred) => + val xs = vars + val as = (variablesOf(pred)--xs).toList + val phi = pred + + synthesize(Problem(as, phi, xs), rules) + + a + case _ => + a + } + + // Look for choose() + for (f <- program.definedFunctions if f.body.isDefined) { + println(f) + treeCatamorphism(x => x, noop, actOnChoose, f.body.get) + } + program } } diff --git a/testcases/Choose.scala b/testcases/Choose.scala index 2591bc123277d36be81393b3b665d827f80873f7..3d7740348902a92d9e5610cf726ed52b1770b312 100644 --- a/testcases/Choose.scala +++ b/testcases/Choose.scala @@ -2,10 +2,12 @@ import leon.Utils._ object ChooseTest { - def c1(x: Int): Int = choose{ (a1: Int) => a1 > x } - def c2(x: Int): (Int, Int) = choose{ (a1: Int, a2: Int) => a1 > x && a2 > x } - def c3(x: Int): (Int, Int, Int) = choose{ (a1: Int, a2: Int, a3: Int) => a1 > x && a2 > x } - def c4(x: Int): (Int, Int, Int, Int) = choose{ (a1: Int, a2: Int, a3: Int, a4: Int) => a1 > x && a2 > x } - def c5(x: Int): (Int, Int, Int, Int, Int) = choose{ (a1: Int, a2: Int, a3: Int, a4: Int, a5: Int) => a1 > x && a2 > x } + def c0(): Int = choose{ (x1: Int) => x1 > 13 } + + def c1(a: Int): Int = choose{ (x1: Int) => x1 > a } + def c2(a: Int): (Int, Int) = choose{ (x1: Int, x2: Int) => x1 > a && x2 > a } + def c3(a: Int): (Int, Int, Int) = choose{ (x1: Int, x2: Int, x3: Int) => x1 > a && x2 > a } + def c4(a: Int): (Int, Int, Int, Int) = choose{ (x1: Int, x2: Int, x3: Int, x4: Int) => x1 > a && x2 > a } + def c5(a: Int): (Int, Int, Int, Int, Int) = choose{ (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int) => x1 > a && x2 > a } }