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

Conflate inputs when possible

parent 7cb5bddd
No related branches found
No related tags found
No related merge requests found
Showing with 158 additions and 39 deletions
...@@ -336,6 +336,14 @@ object TreeOps { ...@@ -336,6 +336,14 @@ object TreeOps {
postMap(substs.lift)(expr) postMap(substs.lift)(expr)
} }
def replaceSeq(substs: Seq[(Expr, Expr)], expr: Expr): Expr = {
var res = expr
for (s <- substs) {
res = replace(Map(s), res)
}
res
}
def replaceFromIDs(substs: Map[Identifier, Expr], expr: Expr) : Expr = { def replaceFromIDs(substs: Map[Identifier, Expr], expr: Expr) : Expr = {
postMap( { postMap( {
......
...@@ -58,9 +58,10 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -58,9 +58,10 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
val soptions = soptions0.copy( val soptions = soptions0.copy(
costModel = RepairCostModel(soptions0.costModel), costModel = RepairCostModel(soptions0.costModel),
rules = (soptions0.rules ++ Seq( rules = (soptions0.rules ++ Seq(
GuidedDecomp, //GuidedDecomp,
GuidedCloser, //GuidedCloser,
CEGLESS CEGLESS,
TEGLESS
)) diff Seq(ADTInduction) )) diff Seq(ADTInduction)
); );
...@@ -149,23 +150,15 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -149,23 +150,15 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
var res: Option[(Expr, Expr)] = None var res: Option[(Expr, Expr)] = None
// in case scrut is an non-variable expr, we simplify to a variable + inject in env // in case scrut is an non-variable expr, we simplify to a variable + inject in env
val (sid, nenv) = scrut match {
case Variable(id) =>
(id, env)
case expr =>
val id = FreshIdentifier("scrut", true).copiedFrom(scrut)
(id, env + (id -> scrut))
}
for (c <- cases if res.isEmpty) { for (c <- cases if res.isEmpty) {
val cond = and(conditionForPattern(sid.toVariable, c.pattern, includeBinders = false), val cond = and(conditionForPattern(scrut, c.pattern, includeBinders = false),
c.optGuard.getOrElse(BooleanLiteral(true))) c.optGuard.getOrElse(BooleanLiteral(true)))
val map = mapForPattern(sid.toVariable, c.pattern) val map = mapForPattern(scrut, c.pattern)
forAllTests(cond, nenv ++ map) match { forAllTests(cond, env ++ map) match {
case Some(true) => case Some(true) =>
val (b, r) = focus(c.rhs, nenv ++ map) val (b, r) = focus(c.rhs, env ++ map)
res = Some((MatchExpr(scrut, cases.map { c2 => res = Some((MatchExpr(scrut, cases.map { c2 =>
if (c2 eq c) { if (c2 eq c) {
c2.copy(rhs = b) c2.copy(rhs = b)
......
...@@ -20,6 +20,7 @@ object Rules { ...@@ -20,6 +20,7 @@ object Rules {
CaseSplit, CaseSplit,
IfSplit, IfSplit,
UnusedInput, UnusedInput,
EquivalentInputs,
UnconstrainedOutput, UnconstrainedOutput,
OptimisticGround, OptimisticGround,
EqualitySplit, EqualitySplit,
......
...@@ -600,6 +600,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { ...@@ -600,6 +600,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) {
val e = examples.next() val e = examples.next()
if (!ndProgram.testForProgram(bs)(e)) { if (!ndProgram.testForProgram(bs)(e)) {
failedTestsStats(e) += 1 failedTestsStats(e) += 1
//sctx.reporter.debug(" Program: "+ndProgram.determinize(bs)+" failed on "+e)
wrongPrograms += bs wrongPrograms += bs
prunedPrograms -= bs prunedPrograms -= bs
......
...@@ -26,6 +26,13 @@ case object CEGLESS extends CEGISLike[Label[String]]("CEGLESS") { ...@@ -26,6 +26,13 @@ case object CEGLESS extends CEGISLike[Label[String]]("CEGLESS") {
val inputs = p.as.map(_.toVariable) val inputs = p.as.map(_.toVariable)
sctx.reporter.ifDebug { printer =>
printer("Guides available:")
for (g <- guides) {
printer(" - "+g)
}
}
val guidedGrammar = guides.map(SimilarTo(_, inputs.toSet, sctx, p)).foldLeft[ExpressionGrammar[Label[String]]](Empty())(_ || _) val guidedGrammar = guides.map(SimilarTo(_, inputs.toSet, sctx, p)).foldLeft[ExpressionGrammar[Label[String]]](Empty())(_ || _)
CegisParams( CegisParams(
......
/* Copyright 2009-2014 EPFL, Lausanne */
package leon
package synthesis
package rules
import leon.utils._
import purescala.Trees._
import purescala.TreeOps._
import purescala.Extractors._
case object EquivalentInputs extends NormalizingRule("EquivalentInputs") {
def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
val TopLevelAnds(clauses) = p.pc
def discoverEquivalences(allClauses: Seq[Expr]): Seq[(Expr, Expr)] = {
val instanceOfs = allClauses.collect {
case ccio @ CaseClassInstanceOf(cct, s) => ccio
}
var clauses = allClauses.filterNot(instanceOfs.toSet)
val ccSubsts = for (CaseClassInstanceOf(cct, s) <- instanceOfs) yield {
val fieldsVals = (for (f <- cct.fields) yield {
val id = f.id
clauses.find {
case Equals(e, CaseClassSelector(`cct`, `s`, `id`)) => true
case _ => false
} match {
case Some(Equals(e, _)) =>
Some(e)
case _ =>
None
}
}).flatten
if (fieldsVals.size == cct.fields.size) {
Some((s, CaseClass(cct, fieldsVals)))
} else {
None
}
}
ccSubsts.flatten
}
val substs = discoverEquivalences(clauses)
if (substs.nonEmpty) {
val simplifier = Simplifiers.bestEffort(sctx.context, sctx.program) _
val sub = p.copy(ws = replaceSeq(substs, p.ws),
pc = simplifier(replaceSeq(substs, p.pc)),
phi = simplifier(replaceSeq(substs, p.phi)))
List(RuleInstantiation.immediateDecomp(p, this, List(sub), forward, this.name))
} else {
Nil
}
}
}
...@@ -28,14 +28,6 @@ case object GuidedDecomp extends Rule("Guided Decomp") { ...@@ -28,14 +28,6 @@ case object GuidedDecomp extends Rule("Guided Decomp") {
val simplify = Simplifiers.bestEffort(sctx.context, sctx.program)_ val simplify = Simplifiers.bestEffort(sctx.context, sctx.program)_
def doSubstitute(substs: Seq[(Expr, Expr)], e: Expr): Expr = {
var res = e
for (s <- substs) {
res = postMap(Map(s).lift)(res)
}
res
}
val alts = guides.collect { val alts = guides.collect {
case g @ IfExpr(c, thn, els) => case g @ IfExpr(c, thn, els) =>
val sub1 = p.copy(ws = replace(Map(g -> thn), p.ws), pc = and(c, replace(Map(g -> thn), p.pc))) val sub1 = p.copy(ws = replace(Map(g -> thn), p.ws), pc = and(c, replace(Map(g -> thn), p.pc)))
...@@ -66,11 +58,11 @@ case object GuidedDecomp extends Rule("Guided Decomp") { ...@@ -66,11 +58,11 @@ case object GuidedDecomp extends Rule("Guided Decomp") {
val pc = simplify(and( val pc = simplify(and(
scrutCond, scrutCond,
replace(Map(scrut0 -> scrut), doSubstitute(substs,scrutConstraint)), replace(Map(scrut0 -> scrut), replaceSeq(substs,scrutConstraint)),
replace(Map(scrut0 -> scrut), replace(Map(m -> c.rhs), andJoin(cond))) replace(Map(scrut0 -> scrut), replace(Map(m -> c.rhs), andJoin(cond)))
)) ))
val ws = replace(Map(m -> c.rhs), p.ws) val ws = replace(Map(m -> c.rhs), p.ws)
val phi = doSubstitute(substs, p.phi) val phi = replaceSeq(substs, p.phi)
val free = variablesOf(and(pc, phi)) -- p.xs val free = variablesOf(and(pc, phi)) -- p.xs
val asPrefix = p.as.filter(free) val asPrefix = p.as.filter(free)
......
...@@ -16,9 +16,10 @@ import datagen._ ...@@ -16,9 +16,10 @@ import datagen._
import utils._ import utils._
case object TEGIS extends TEGISLike[TypeTree]("TEGIS") { case object TEGIS extends TEGISLike[TypeTree]("TEGIS") {
def getGrammar(sctx: SynthesisContext, p: Problem) = { def getParams(sctx: SynthesisContext, p: Problem) = {
ExpressionGrammars.default(sctx, p) TegisParams(
grammar = ExpressionGrammars.default(sctx, p),
rootLabel = {(tpe: TypeTree) => tpe }
)
} }
def getRootLabel(tpe: TypeTree): TypeTree = tpe
} }
...@@ -21,19 +21,22 @@ import bonsai._ ...@@ -21,19 +21,22 @@ import bonsai._
import bonsai.enumerators._ import bonsai.enumerators._
abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) { abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) {
def getGrammar(sctx: SynthesisContext, p: Problem): ExpressionGrammar[T] case class TegisParams(
grammar: ExpressionGrammar[T],
rootLabel: TypeTree => T,
enumLimit: Int = 10000,
reorderInterval: Int = 50
);
def getRootLabel(tpe: TypeTree): T def getParams(sctx: SynthesisContext, p: Problem): TegisParams
val enumLimit = 10000;
val testsReorderInterval = 50; // Every X test filterings, we reorder tests with most filtering first.
def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = { def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = {
List(new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) { List(new RuleInstantiation(p, this, SolutionBuilder.none, this.name, this.priority) {
def apply(sctx: SynthesisContext): RuleApplication = { def apply(sctx: SynthesisContext): RuleApplication = {
val grammar = getGrammar(sctx, p) val params = getParams(sctx, p)
val grammar = params.grammar
var tests = p.getTests(sctx).map(_.ins).distinct var tests = p.getTests(sctx).map(_.ins).distinct
if (tests.nonEmpty) { if (tests.nonEmpty) {
...@@ -53,7 +56,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) { ...@@ -53,7 +56,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) {
val timers = sctx.context.timers.synthesis.rules.tegis; val timers = sctx.context.timers.synthesis.rules.tegis;
val allExprs = enum.iterator(getRootLabel(targetType)) val allExprs = enum.iterator(params.rootLabel(targetType))
var failStat = Map[Seq[Expr], Int]().withDefaultValue(0) var failStat = Map[Seq[Expr], Int]().withDefaultValue(0)
...@@ -63,7 +66,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) { ...@@ -63,7 +66,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) {
def findNext(): Option[Expr] = { def findNext(): Option[Expr] = {
candidate = None candidate = None
timers.generating.start() timers.generating.start()
allExprs.take(enumLimit).takeWhile(e => candidate.isEmpty).foreach { e => allExprs.take(params.enumLimit).takeWhile(e => candidate.isEmpty).foreach { e =>
val exprToTest = if (!isWrapped) { val exprToTest = if (!isWrapped) {
Let(p.xs.head, e, p.phi) Let(p.xs.head, e, p.phi)
} else { } else {
...@@ -93,7 +96,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) { ...@@ -93,7 +96,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) {
} }
timers.testing.stop() timers.testing.stop()
if (n % testsReorderInterval == 0) { if (n % params.reorderInterval == 0) {
tests = tests.sortBy(t => -failStat(t)) tests = tests.sortBy(t => -failStat(t))
} }
n += 1 n += 1
...@@ -114,6 +117,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) { ...@@ -114,6 +117,7 @@ abstract class TEGISLike[T <% Typed](name: String) extends Rule(name) {
RuleClosed(toStream()) RuleClosed(toStream())
} else { } else {
sctx.reporter.debug("No test available")
RuleFailed() RuleFailed()
} }
} }
......
/* Copyright 2009-2014 EPFL, Lausanne */
package leon
package synthesis
package rules
import purescala.Trees._
import purescala.TreeOps._
import purescala.TypeTrees._
import purescala.Common._
import purescala.Definitions._
import purescala.Extractors._
import utils._
import utils.ExpressionGrammars._
case object TEGLESS extends TEGISLike[Label[String]]("TEGLESS") {
def getParams(sctx: SynthesisContext, p: Problem) = {
val TopLevelAnds(clauses) = p.ws
val guide = sctx.program.library.guide.get
val guides = clauses.collect {
case FunctionInvocation(TypedFunDef(`guide`, _), Seq(expr)) => expr
}
val inputs = p.as.map(_.toVariable)
sctx.reporter.ifDebug { printer =>
printer("Guides available:")
for (g <- guides) {
printer(" - "+g)
}
}
val guidedGrammar = guides.map(SimilarTo(_, inputs.toSet, sctx, p)).foldLeft[ExpressionGrammar[Label[String]]](Empty())(_ || _)
TegisParams(
grammar = guidedGrammar,
rootLabel = { (tpe: TypeTree) => Label(tpe, "G0") }
)
}
}
...@@ -222,7 +222,7 @@ object ExpressionGrammars { ...@@ -222,7 +222,7 @@ object ExpressionGrammars {
gl -> Generator(subEls.updated(i, sgl), builder) gl -> Generator(subEls.updated(i, sgl), builder)
} }
val swaps = if (subs.size > 1 || isCommutative(e)) { val swaps = if (subs.size > 1 && !isCommutative(e)) {
(for (i <- 0 until subs.size; (for (i <- 0 until subs.size;
j <- i+1 until subs.size) yield { j <- i+1 until subs.size) yield {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment