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

Fix forAllTests, improve tests printing

parent e1b3629b
No related branches found
No related tags found
No related merge requests found
...@@ -141,18 +141,9 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -141,18 +141,9 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
private def focusRepair(program: Program, fd: FunDef, passingTests: List[Example], failingTests: List[Example]): (Expr, Expr) = { private def focusRepair(program: Program, fd: FunDef, passingTests: List[Example], failingTests: List[Example]): (Expr, Expr) = {
reporter.ifDebug { printer => reporter.ifDebug { printer =>
printer(title("Tests failing are: ")) printer(new ExamplesTable("Tests failing:", failingTests).toString)
failingTests.foreach { ex => printer(new ExamplesTable("Tests passing:", passingTests).toString)
printer(ex.ins.mkString(", "))
}
}
reporter.ifDebug { printer =>
printer(title("Tests passing are: "))
passingTests.foreach { ex =>
printer(ex.ins.mkString(", "))
}
} }
val pre = fd.precondition.getOrElse(BooleanLiteral(true)) val pre = fd.precondition.getOrElse(BooleanLiteral(true))
val args = fd.params.map(_.id) val args = fd.params.map(_.id)
...@@ -168,6 +159,7 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -168,6 +159,7 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
val evaluator = new DefaultEvaluator(ctx, program) val evaluator = new DefaultEvaluator(ctx, program)
// We exclude redundant failing tests, and only select the minimal tests
val minimalFailingTests = { val minimalFailingTests = {
// We don't want tests whose invocation will call other failing tests. // We don't want tests whose invocation will call other failing tests.
// This is because they will appear erroneous, // This is because they will appear erroneous,
...@@ -179,24 +171,24 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -179,24 +171,24 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
case _ => None case _ => None
} }
} }
val passingTs = for (test <- passingTests) yield InExample(test.ins) val passingTs = for (test <- passingTests) yield InExample(test.ins)
val failingTs = for (test <- failingTests) yield InExample(test.ins) val failingTs = for (test <- failingTests) yield InExample(test.ins)
val test2Tests : Map[InExample, Set[InExample]] = (failingTs ++ passingTs).map{ ts => val test2Tests : Map[InExample, Set[InExample]] = (failingTs ++ passingTs).map{ ts =>
testEval.eval(body, args.zip(ts.ins).toMap) testEval.eval(body, args.zip(ts.ins).toMap)
(ts, testEval.collected map (InExample(_))) (ts, testEval.collected map (InExample(_)))
}.toMap }.toMap
val recursiveTests : Set[InExample] = test2Tests.values.toSet.flatten -- (failingTs ++ passingTs) val recursiveTests : Set[InExample] = test2Tests.values.toSet.flatten -- (failingTs ++ passingTs)
val testsTransitive : Map[InExample,Set[InExample]] = val testsTransitive : Map[InExample,Set[InExample]] =
leon.utils.GraphOps.transitiveClosure[InExample]( leon.utils.GraphOps.transitiveClosure[InExample](
test2Tests ++ recursiveTests.map ((_,Set[InExample]())) test2Tests ++ recursiveTests.map ((_,Set[InExample]()))
) )
val knownWithResults : Map[InExample, Boolean] = (failingTs.map((_, false)).toMap) ++ (passingTs.map((_,true))) val knownWithResults : Map[InExample, Boolean] = (failingTs.map((_, false)).toMap) ++ (passingTs.map((_,true)))
val recWithResults : Map[InExample, Boolean] = recursiveTests.map { ex => val recWithResults : Map[InExample, Boolean] = recursiveTests.map { ex =>
(ex, evaluator.eval(spec, (args zip ex.ins).toMap + (out -> body)) match { (ex, evaluator.eval(spec, (args zip ex.ins).toMap + (out -> body)) match {
case EvaluationResults.Successful(BooleanLiteral(true)) => true case EvaluationResults.Successful(BooleanLiteral(true)) => true
...@@ -205,19 +197,16 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -205,19 +197,16 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
}.toMap }.toMap
val allWithResults = knownWithResults ++ recWithResults val allWithResults = knownWithResults ++ recWithResults
testsTransitive.collect { testsTransitive.collect {
case (rest, called) if !allWithResults(rest) && (called forall allWithResults) => case (rest, called) if !allWithResults(rest) && (called forall allWithResults) =>
rest rest
}.toSet }.toSeq
} }
reporter.ifDebug { printer => reporter.ifDebug { printer =>
printer(title("MinimalTests are: ")) printer(new ExamplesTable("Minimal failing:", minimalFailingTests).toString)
minimalFailingTests.foreach { ex =>
printer(ex.ins.mkString(", "))
}
} }
// Check how an expression behaves on tests // Check how an expression behaves on tests
...@@ -230,9 +219,9 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout ...@@ -230,9 +219,9 @@ class Repairman(ctx: LeonContext, initProgram: Program, fd: FunDef, verifTimeout
evaluator.eval(e, env ++ (args zip ins)) match { evaluator.eval(e, env ++ (args zip ins)) match {
case EvaluationResults.Successful(BooleanLiteral(true)) => Some(true) case EvaluationResults.Successful(BooleanLiteral(true)) => Some(true)
case EvaluationResults.Successful(BooleanLiteral(false)) => Some(false) case EvaluationResults.Successful(BooleanLiteral(false)) => Some(false)
case _ => None case e => None
} }
} }.distinct
if (results.size == 1) { if (results.size == 1) {
results.head results.head
......
...@@ -4,8 +4,31 @@ package leon ...@@ -4,8 +4,31 @@ package leon
package synthesis package synthesis
import purescala.Trees._ import purescala.Trees._
import leon.utils.ASCIIHelpers._
class Example(val ins: Seq[Expr]) class Example(val ins: Seq[Expr])
case class InOutExample(is: Seq[Expr], val outs: Seq[Expr]) extends Example(is) case class InOutExample(is: Seq[Expr], val outs: Seq[Expr]) extends Example(is)
case class InExample(is: Seq[Expr]) extends Example(is) case class InExample(is: Seq[Expr]) extends Example(is)
class ExamplesTable(title: String, ts: Seq[Example]) {
override def toString = {
var tt = new Table(title)
for (t <- ts) {
val os = t match {
case InOutExample(_, outs) =>
outs.map(Cell(_))
case _ =>
Seq(Cell("?"))
}
tt += Row(
t.ins.map(Cell(_)) ++ Seq(Cell("->")) ++ os
)
}
tt.render
}
}
...@@ -22,7 +22,8 @@ object GraphOps { ...@@ -22,7 +22,8 @@ object GraphOps {
} }
tSort(toPreds, Seq()) tSort(toPreds, Seq())
} }
def transitiveClosure[A](graph: Map[A,Set[A]]) : Map[A,Set[A]] = { def transitiveClosure[A](graph: Map[A,Set[A]]) : Map[A,Set[A]] = {
def step(graph : Map[A, Set[A]]) : Map[A,Set[A]] = graph map { def step(graph : Map[A, Set[A]]) : Map[A,Set[A]] = graph map {
case (k, vs) => (k, vs ++ (vs flatMap { v => case (k, vs) => (k, vs ++ (vs flatMap { v =>
...@@ -39,7 +40,6 @@ object GraphOps { ...@@ -39,7 +40,6 @@ object GraphOps {
def sinks[A](graph : Map[A,Set[A]]) = def sinks[A](graph : Map[A,Set[A]]) =
graph.collect{ case (v, out) if out.isEmpty => v }.toSet graph.collect{ case (v, out) if out.isEmpty => v }.toSet
/** /**
* Returns the set of reachable nodes from a given node, * Returns the set of reachable nodes from a given node,
* not including the node itself (unless it is member of a cycle) * not including the node itself (unless it is member of a cycle)
...@@ -73,4 +73,4 @@ object GraphOps { ...@@ -73,4 +73,4 @@ object GraphOps {
rec(source) rec(source)
} }
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment