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

Propagate expected types to onSuccess

This allows CostModels to estimate correctly the minimal cost of a
applying a rule.

With type information on the expected types of a solution
reconstruction, the cost model can provide dummy values of the correct
type, avoiding assertion errors when composing solutions.
parent e9bb6d75
No related branches found
No related tags found
No related merge requests found
...@@ -854,6 +854,7 @@ object TreeOps { ...@@ -854,6 +854,7 @@ object TreeOps {
CaseClass(ccd, fields.map(f => simplestValue(f.getType))) CaseClass(ccd, fields.map(f => simplestValue(f.getType)))
case SetType(baseType) => FiniteSet(Seq()).setType(tpe) case SetType(baseType) => FiniteSet(Seq()).setType(tpe)
case MapType(fromType, toType) => FiniteMap(Seq()).setType(tpe) case MapType(fromType, toType) => FiniteMap(Seq()).setType(tpe)
case TupleType(tpes) => Tuple(tpes.map(simplestValue))
case _ => throw new Exception("I can't choose simplest value for type " + tpe) case _ => throw new Exception("I can't choose simplest value for type " + tpe)
} }
......
...@@ -12,7 +12,7 @@ abstract class CostModel(val name: String) { ...@@ -12,7 +12,7 @@ abstract class CostModel(val name: String) {
def problemCost(p: Problem): Cost def problemCost(p: Problem): Cost
def ruleAppCost(app: RuleInstantiation): Cost = new Cost { def ruleAppCost(app: RuleInstantiation): Cost = new Cost {
val subSols = (1 to app.onSuccess.arity).map {i => Solution.simplest }.toList val subSols = app.onSuccess.types.map {t => Solution.simplest(t) }.toList
val simpleSol = app.onSuccess(subSols) val simpleSol = app.onSuccess(subSols)
val value = simpleSol match { val value = simpleSol match {
......
...@@ -2,6 +2,7 @@ package leon ...@@ -2,6 +2,7 @@ package leon
package synthesis package synthesis
import purescala.Trees._ import purescala.Trees._
import purescala.TypeTrees.TupleType
import heuristics._ import heuristics._
...@@ -38,7 +39,9 @@ object HeuristicInstantiation { ...@@ -38,7 +39,9 @@ object HeuristicInstantiation {
} }
def apply(problem: Problem, rule: Rule, subProblems: List[Problem], onSuccess: List[Solution] => Option[Solution]): RuleInstantiation = { def apply(problem: Problem, rule: Rule, subProblems: List[Problem], onSuccess: List[Solution] => Option[Solution]): RuleInstantiation = {
val builder = new SolutionBuilder(subProblems.size) { val subTypes = subProblems.map(p => TupleType(p.xs.map(_.getType)))
val builder = new SolutionBuilder(subProblems.size, subTypes) {
def apply(sols: List[Solution]) = { def apply(sols: List[Solution]) = {
onSuccess(sols) onSuccess(sols)
} }
......
...@@ -3,6 +3,7 @@ package synthesis ...@@ -3,6 +3,7 @@ package synthesis
import purescala.Common._ import purescala.Common._
import purescala.Trees._ import purescala.Trees._
import purescala.TypeTrees._
import purescala.TreeOps._ import purescala.TreeOps._
import rules._ import rules._
...@@ -27,11 +28,13 @@ object Rules { ...@@ -27,11 +28,13 @@ object Rules {
) )
} }
abstract class SolutionBuilder(val arity: Int) { abstract class SolutionBuilder(val arity: Int, val types: Seq[TypeTree]) {
def apply(sols: List[Solution]): Option[Solution] def apply(sols: List[Solution]): Option[Solution]
assert(types.size == arity)
} }
class SolutionCombiner(arity: Int, f: List[Solution] => Option[Solution]) extends SolutionBuilder(arity) { class SolutionCombiner(arity: Int, types: Seq[TypeTree], f: List[Solution] => Option[Solution]) extends SolutionBuilder(arity, types) {
def apply(sols: List[Solution]) = { def apply(sols: List[Solution]) = {
assert(sols.size == arity) assert(sols.size == arity)
f(sols) f(sols)
...@@ -39,7 +42,7 @@ class SolutionCombiner(arity: Int, f: List[Solution] => Option[Solution]) extend ...@@ -39,7 +42,7 @@ class SolutionCombiner(arity: Int, f: List[Solution] => Option[Solution]) extend
} }
object SolutionBuilder { object SolutionBuilder {
val none = new SolutionBuilder(0) { val none = new SolutionBuilder(0, Seq()) {
def apply(sols: List[Solution]) = None def apply(sols: List[Solution]) = None
} }
} }
...@@ -48,14 +51,6 @@ abstract class RuleInstantiation(val problem: Problem, val rule: Rule, val onSuc ...@@ -48,14 +51,6 @@ abstract class RuleInstantiation(val problem: Problem, val rule: Rule, val onSuc
def apply(sctx: SynthesisContext): RuleApplicationResult def apply(sctx: SynthesisContext): RuleApplicationResult
} }
//abstract class RuleApplication(val subProblemsCount: Int,
// val onSuccess: List[Solution] => Solution) {
//
// def apply(sctx: SynthesisContext): RuleApplicationResult
//}
//
//abstract class RuleImmediateApplication extends RuleApplication(0, s => Solution.simplest)
sealed abstract class RuleApplicationResult sealed abstract class RuleApplicationResult
case class RuleSuccess(solution: Solution) extends RuleApplicationResult case class RuleSuccess(solution: Solution) extends RuleApplicationResult
case class RuleDecomposed(sub: List[Problem]) extends RuleApplicationResult case class RuleDecomposed(sub: List[Problem]) extends RuleApplicationResult
...@@ -63,13 +58,15 @@ case object RuleApplicationImpossible extends RuleApplicationResult ...@@ -63,13 +58,15 @@ case object RuleApplicationImpossible extends RuleApplicationResult
object RuleInstantiation { object RuleInstantiation {
def immediateDecomp(problem: Problem, rule: Rule, sub: List[Problem], onSuccess: List[Solution] => Option[Solution]) = { def immediateDecomp(problem: Problem, rule: Rule, sub: List[Problem], onSuccess: List[Solution] => Option[Solution]) = {
new RuleInstantiation(problem, rule, new SolutionCombiner(sub.size, onSuccess)) { val subTypes = sub.map(p => TupleType(p.xs.map(_.getType)))
new RuleInstantiation(problem, rule, new SolutionCombiner(sub.size, subTypes, onSuccess)) {
def apply(sctx: SynthesisContext) = RuleDecomposed(sub) def apply(sctx: SynthesisContext) = RuleDecomposed(sub)
} }
} }
def immediateSuccess(problem: Problem, rule: Rule, solution: Solution) = { def immediateSuccess(problem: Problem, rule: Rule, solution: Solution) = {
new RuleInstantiation(problem, rule, new SolutionCombiner(0, ls => Some(solution))) { new RuleInstantiation(problem, rule, new SolutionCombiner(0, Seq(), ls => Some(solution))) {
def apply(sctx: SynthesisContext) = RuleSuccess(solution) def apply(sctx: SynthesisContext) = RuleSuccess(solution)
} }
} }
......
...@@ -2,6 +2,7 @@ package leon ...@@ -2,6 +2,7 @@ package leon
package synthesis package synthesis
import leon.purescala.Trees._ import leon.purescala.Trees._
import leon.purescala.TypeTrees.TypeTree
import leon.purescala.Definitions._ import leon.purescala.Definitions._
import leon.purescala.TreeOps._ import leon.purescala.TreeOps._
import leon.xlang.Trees.LetDef import leon.xlang.Trees.LetDef
...@@ -45,7 +46,7 @@ object Solution { ...@@ -45,7 +46,7 @@ object Solution {
new Solution(BooleanLiteral(true), Set(), Tuple(p.xs.map(id => simplestValue(id.getType)))) new Solution(BooleanLiteral(true), Set(), Tuple(p.xs.map(id => simplestValue(id.getType))))
} }
def simplest: Solution = { def simplest(t: TypeTree): Solution = {
new Solution(BooleanLiteral(true), Set(), BooleanLiteral(true)) new Solution(BooleanLiteral(true), Set(), simplestValue(t))
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment