Skip to content
Snippets Groups Projects
Commit 50b03820 authored by Etienne Kneuss's avatar Etienne Kneuss
Browse files

Verify preconditions for heuristics

parent 0aab7ba6
No related branches found
No related tags found
No related merge requests found
...@@ -168,8 +168,9 @@ object Trees { ...@@ -168,8 +168,9 @@ object Trees {
/* Propositional logic */ /* Propositional logic */
object And { object And {
def apply(l: Expr, r: Expr) : Expr = (l,r) match { def apply(l: Expr, r: Expr) : Expr = (l,r) match {
case (BooleanLiteral(true),_) => r case (BooleanLiteral(false),_) => BooleanLiteral(false)
case (_,BooleanLiteral(true)) => l case (BooleanLiteral(true),_) => r
case (_,BooleanLiteral(true)) => l
case _ => new And(Seq(l,r)) case _ => new And(Seq(l,r))
} }
def apply(exprs: Seq[Expr]) : Expr = { def apply(exprs: Seq[Expr]) : Expr = {
......
...@@ -19,6 +19,23 @@ trait Heuristic { ...@@ -19,6 +19,23 @@ trait Heuristic {
this: Rule => this: Rule =>
override def toString = "H: "+name override def toString = "H: "+name
}
object HeuristicStep {
def verifyPre(synth: Synthesizer)(s: Solution): (Solution, Boolean) = {
synth.solver.solveSAT(And(Not(s.pre), s.fullTerm)) match {
case (Some(true), model) =>
synth.reporter.warning("Heuristic failed to produce strongest precondition for solution: \n"+s.toExpr)
(s, false)
case _ =>
(s, true)
}
}
def apply(synth: Synthesizer, subProblems: List[Problem], onSuccess: List[Solution] => Solution) = {
RuleMultiSteps(subProblems, Nil, onSuccess.andThen(verifyPre(synth)))
}
} }
......
...@@ -30,11 +30,11 @@ case object RuleInapplicable extends RuleResult ...@@ -30,11 +30,11 @@ case object RuleInapplicable extends RuleResult
case class RuleSuccess(solution: Solution) extends RuleResult case class RuleSuccess(solution: Solution) extends RuleResult
case class RuleMultiSteps(subProblems: List[Problem], case class RuleMultiSteps(subProblems: List[Problem],
steps: List[List[Solution] => List[Problem]], steps: List[List[Solution] => List[Problem]],
onSuccess: List[Solution] => Solution) extends RuleResult onSuccess: List[Solution] => (Solution, Boolean)) extends RuleResult
object RuleStep { object RuleStep {
def apply(subProblems: List[Problem], onSuccess: List[Solution] => Solution) = { def apply(subProblems: List[Problem], onSuccess: List[Solution] => Solution) = {
RuleMultiSteps(subProblems, Nil, onSuccess) RuleMultiSteps(subProblems, Nil, onSuccess.andThen((_, true)))
} }
} }
......
...@@ -23,6 +23,9 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr) { ...@@ -23,6 +23,9 @@ class Solution(val pre: Expr, val defs: Set[FunDef], val term: Expr) {
defs.foldLeft(result){ case (t, fd) => LetDef(fd, t) } defs.foldLeft(result){ case (t, fd) => LetDef(fd, t) }
} }
def fullTerm =
defs.foldLeft(term){ case (t, fd) => LetDef(fd, t) }
} }
object Solution { object Solution {
......
...@@ -35,7 +35,7 @@ class Task(synth: Synthesizer, ...@@ -35,7 +35,7 @@ class Task(synth: Synthesizer,
var steps: List[TaskStep] = Nil var steps: List[TaskStep] = Nil
var nextSteps: List[List[Solution] => List[Problem]] = Nil var nextSteps: List[List[Solution] => List[Problem]] = Nil
var onSuccess: List[Solution] => Solution = _ var onSuccess: List[Solution] => (Solution, Boolean) = _
def currentStep = steps.head def currentStep = steps.head
...@@ -55,9 +55,15 @@ class Task(synth: Synthesizer, ...@@ -55,9 +55,15 @@ class Task(synth: Synthesizer,
steps = new TaskStep(newProblems) :: steps steps = new TaskStep(newProblems) :: steps
} else { } else {
solution = Some(onSuccess(solutions)) onSuccess(solutions) match {
case (s, true) =>
parent.partlySolvedBy(this, solution.get) solution = Some(s)
parent.partlySolvedBy(this, solution.get)
case _ =>
// solution is there, but it is incomplete (precondition not strongest)
parent.partlySolvedBy(this, Solution.choose(problem))
}
} }
} }
} }
...@@ -94,7 +100,7 @@ class Task(synth: Synthesizer, ...@@ -94,7 +100,7 @@ class Task(synth: Synthesizer,
// To each problem we assign the most basic solution, fold on all inner // To each problem we assign the most basic solution, fold on all inner
// steps, and then reconstruct final solution // steps, and then reconstruct final solution
val simplestSubSolutions = interSteps.foldLeft(subProblems.map(Solution.basic(_))){ (sols, step) => step(sols).map(Solution.basic(_)) } val simplestSubSolutions = interSteps.foldLeft(subProblems.map(Solution.basic(_))){ (sols, step) => step(sols).map(Solution.basic(_)) }
val simplestSolution = onSuccess(simplestSubSolutions) val simplestSolution = onSuccess(simplestSubSolutions)._1
minComplexity = new FixedSolComplexity(parent.minComplexity.value + simplestSolution.complexity.value) minComplexity = new FixedSolComplexity(parent.minComplexity.value + simplestSolution.complexity.value)
val prefix = "[%-20s] ".format(Option(rule).map(_.toString).getOrElse("root")) val prefix = "[%-20s] ".format(Option(rule).map(_.toString).getOrElse("root"))
synth.reporter.info(prefix+"Got: "+problem) synth.reporter.info(prefix+"Got: "+problem)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment