-
Ivan Kuraj authoredIvan Kuraj authored
SynthesizerExamples.scala 28.87 KiB
package lesynth
import scala.collection.mutable.{ Map => MutableMap }
import scala.collection.mutable.{ Set => MutableSet }
import scala.collection.mutable.PriorityQueue
import leon.{Reporter, DefaultReporter, SilentReporter, LeonContext}
import leon.solvers.{ Solver, TimeoutSolver }
import leon.solvers.z3.{ FairZ3Solver }
import leon.verification.AnalysisPhase
import leon.purescala.TypeTrees.{ TypeTree => LeonType, _ }
import leon.purescala.Trees.{ Variable => LeonVariable, _ }
import leon.purescala.Definitions.{FunDef, Program}
import leon.purescala.Common.{ Identifier, FreshIdentifier }
import leon.purescala.TreeOps
import insynth.util.logging.HasLogger
import insynth.interfaces.Declaration
import insynth.InSynth
import insynth.leon.loader.LeonLoader
import insynth.leon.LeonDeclaration
import insynth.leon.ImmediateExpression
import insynth.engine.InitialEnvironmentBuilder
import insynth.interfaces.Declaration
import insynth.engine.InitialEnvironmentBuilder
import insynth.leon.TypeTransformer
import insynth.reconstruction.Output
import leon.synthesis.{ Problem, SynthesisContext }
import leon.Main.processOptions
import leon.purescala.TypeTrees._
import scala.collection.mutable.{Map => MutableMap}
import scala.collection.mutable.{Set => MutableSet}
import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable
class SynthesizerForRuleExamples(
// some synthesis instance information
val solver: Solver,
val program: Program,
val desiredType: LeonType,
val holeFunDef: FunDef,
val problem: Problem,
val synthesisContext: SynthesisContext,
val freshResVar: LeonVariable,
// number of condition expressions to try before giving up on that branch expression
numberOfBooleanSnippets: Int = 5,
numberOfCounterExamplesToGenerate: Int = 5,
leonTimeout: Int = 2, // seconds
analyzeSynthesizedFunctionOnly: Boolean = false,
showLeonOutput: Boolean = false,
reporter: Reporter = new DefaultReporter,
//examples: List[Map[Identifier, Expr]] = Nil,
// we need the holeDef to know the right ids
introduceExamples: ((Seq[Identifier], LeonLoader) => List[Map[Identifier, Expr]]) = { (_, _) => Nil },
collectCounterExamplesFromLeon: Boolean = false,
filterOutAlreadySeenBranchExpressions: Boolean = true,
useStringSetForFilterOutAlreadySeenBranchExpressions: Boolean = true,
numberOfTestsInIteration: Int = 50,
numberOfCheckInIteration: Int = 5
) extends HasLogger {
val fileName: String = "noFileName"
info("Synthesizer:")
info("fileName: %s".format(fileName))
info("numberOfBooleanSnippets: %d".format(numberOfBooleanSnippets))
info("numberOfCounterExamplesToGenerate: %d".format(numberOfCounterExamplesToGenerate))
info("leonTimeout: %d".format(leonTimeout))
//info("examples: " + examples.mkString(", "))
info("holeFunDef: %s".format(holeFunDef))
info("problem: %s".format(problem.toString))
private var hole: Hole = _
// initial declarations
private var allDeclarations: List[Declaration] = _
// objects used in the synthesis
private var loader: LeonLoader = _
private var inSynth: InSynth = _
private var inSynthBoolean: InSynth = _
private var refiner: Refiner = _
//private var solver: Solver = _
private var ctx: LeonContext = _
private var initialPrecondition: Expr = _
private var variableRefinements: MutableMap[Identifier, MutableSet[ClassType]] = _
// can be used to unnecessary syntheses
private var variableRefinedBranch = false
private var variableRefinedCondition = true // assure initial synthesis
private var booleanExpressionsSaved: Stream[Output] = _
private var seenBranchExpressions: Set[String] = Set.empty
// flag denoting if a correct body has been synthesized
private var found = false
// accumulate precondition for the remaining branch to synthesize
private var accumulatingPrecondition: Expr = _
// accumulate the final expression of the hole
private var accumulatingExpression: Expr => Expr = _
//private var accumulatingExpressionMatch: Expr => Expr = _
var flag1 = false
var flag2 = false
// time
var startTime: Long = _
var verTime: Long = 0
var synTime: Long = 0
// filtering/ranking with examples support
var exampleRunner: ExampleRunner = _
def analyzeProgram = {
val temp = System.currentTimeMillis
Globals.allSolved = Some(true)
import TreeOps._
val body = holeFunDef.getBody
val theExpr = {
val resFresh = FreshIdentifier("result", true).setType(body.getType)
val bodyAndPost =
Let(
resFresh, body,
replace(Map(ResultVariable() -> LeonVariable(resFresh)), matchToIfThenElse(holeFunDef.getPostcondition))
)
val withPrec = if( holeFunDef.precondition.isEmpty) {
bodyAndPost
} else {
Implies(matchToIfThenElse(holeFunDef.precondition.get), bodyAndPost)
}
withPrec
}
val reporter = //new DefaultReporter
new SilentReporter
val args =
if (analyzeSynthesizedFunctionOnly)
Array(fileName, "--timeout=" + leonTimeout, "--functions=" + holeFunDef.id.name)
else
Array(fileName, "--timeout=" + leonTimeout)
info("Leon context array: " + args.mkString(","))
ctx = processOptions(reporter, args.toList)
val solver = new TimeoutSolver(new FairZ3Solver(ctx), 1000L)
solver.setProgram(program)
Globals.allSolved = solver.solve(theExpr)
fine("solver said " + Globals.allSolved + " for " + theExpr)
//interactivePause
val time = System.currentTimeMillis - temp
//fine("Analysis took: " + time + ", from report: " + report.totalTime)
// accumulate
verTime += time
}
// TODO return boolean (do not do unecessary analyze)
def generateCounterexamples(program: Program, funDef: FunDef, number: Int): (Seq[Map[Identifier, Expr]], Expr) = {
fine("generate counter examples with funDef.prec= " + funDef.precondition.getOrElse(BooleanLiteral(true)))
val temp = System.currentTimeMillis
// get current precondition
var precondition = funDef.precondition.getOrElse(BooleanLiteral(true))
// where we will accumulate counterexamples as sequence of maps
var maps: Seq[Map[Identifier, Expr]] = Seq.empty
// iterate specific number of times or until no further counterexample can be generated
var changed = true
var ind = 0
while (ind < number && changed) {
// analyze the program
analyzeProgram
// check if solver could solved this instance
if (Globals.allSolved == Some(false) && !Globals.asMap.isEmpty) {
fine("found coounterexample: " + Globals.asMap)
// add current counterexample
maps :+= Globals.asMap
// prevent this counterexample to re-occur
val precAddition = Not(And(Globals.asMap map { case (id, value) => Equals(LeonVariable(id), value) } toSeq))
precondition = And(Seq(precondition, precAddition))
// update precondition
funDef.precondition = Some(precondition)
} else
changed = false
ind += 1
}
val temptime = System.currentTimeMillis - temp
fine("Generation of counter-examples took: " + temptime)
verTime += temptime
// return found counterexamples and the formed precondition
(maps, precondition)
}
def getCurrentBuilder = new InitialEnvironmentBuilder(allDeclarations)
def synthesizeBranchExpressions =
inSynth.getExpressions(getCurrentBuilder)
def synthesizeBooleanExpressions = {
if ( variableRefinedCondition ) {
// store for later fetch (will memoize values)
booleanExpressionsSaved =
inSynthBoolean.getExpressions(getCurrentBuilder) take numberOfBooleanSnippets
// reset flag
variableRefinedCondition = false
}
booleanExpressionsSaved
}
def interactivePause = {
System.out.println("Press Any Key To Continue...");
new java.util.Scanner(System.in).nextLine();
}
def getNewExampleQueue = PriorityQueue[(Expr, Int)]()(
new Ordering[(Expr, Int)] {
def compare(pair1: (Expr, Int), pair2: (Expr, Int)) =
pair1._2.compare(pair2._2)
})
def initialize = {
hole = Hole(desiredType)
// TODO lose this - globals are bad
Globals.allSolved = None
// context needed for verification
import leon.Main._
// val reporter =
// if (showLeonOutput) new DefaultReporter
// else new SilentReporter
//
// val args =
// if (analyzeSynthesizedFunctionOnly)
// Array(fileName, "--timeout=" + leonTimeout, "--functions=" + holeFunDef.id.name)
// else
// Array(fileName, "--timeout=" + leonTimeout)
// info("Leon context array: " + args.mkString(","))
// ctx = processOptions(reporter, args.toList)
//solver = //new FairZ3Solver(ctx)
// new TimeoutSolver(new FairZ3Solver(ctx), leonTimeout)
// create new insynth object
loader = new LeonLoader(program, hole, problem.as, false)
inSynth = new InSynth(loader, true)
// save all declarations seen
allDeclarations = inSynth.getCurrentBuilder.getAllDeclarations
// make conditions synthesizer
inSynthBoolean = new InSynth(allDeclarations, BooleanType, true)
// funDef of the hole
fine("postcondition is: " + holeFunDef.getPostcondition)
// accumulate precondition for the remaining branch to synthesize
accumulatingPrecondition = holeFunDef.precondition.getOrElse(BooleanLiteral(true))
// save initial precondition
initialPrecondition = accumulatingPrecondition
// accumulate the final expression of the hole
accumulatingExpression = (finalExp: Expr) => finalExp
//accumulatingExpressionMatch = accumulatingExpression
// each variable of super type can actually have a subtype
// get sine declaration maps to be able to refine them
val directSubclassMap = loader.directSubclassesMap
val variableDeclarations = loader.variableDeclarations
// map from identifier into a set of possible subclasses
variableRefinements = MutableMap.empty
for (varDec <- variableDeclarations) {
varDec match {
case LeonDeclaration(_, _, typeOfVar: ClassType, ImmediateExpression(_, LeonVariable(id))) =>
variableRefinements += (id -> MutableSet(directSubclassMap(typeOfVar).toList: _*))
case _ =>
}
}
// calculate cases that should not happen
refiner = new Refiner(program, hole, holeFunDef)
fine("Refiner initialized. Recursive call: " + refiner.recurentExpression)
exampleRunner = new ExampleRunner(program, 4000)
exampleRunner.counterExamples ++= //examples
introduceExamples(holeFunDef.args.map(_.id), loader)
fine("Introduced examples: " + exampleRunner.counterExamples.mkString(", "))
}
def countPassedExamples(snippet: Expr) = {
val oldPreconditionSaved = holeFunDef.precondition
val oldBodySaved = holeFunDef.body
// restore initial precondition
holeFunDef.precondition = Some(initialPrecondition)
// get the whole body (if else...)
val accumulatedExpression = accumulatingExpression(snippet)
// set appropriate body to the function for the correct evaluation
holeFunDef.body = Some(accumulatedExpression)
import TreeOps._
val expressionToCheck =
//Globals.bodyAndPostPlug(exp)
{
val resFresh = FreshIdentifier("result", true).setType(accumulatedExpression.getType)
Let(
resFresh, accumulatedExpression,
replace(Map(ResultVariable() -> LeonVariable(resFresh)), matchToIfThenElse(holeFunDef.getPostcondition)))
}
fine("going to count passed for: " + holeFunDef)
fine("going to count passed for: " + expressionToCheck)
val count = exampleRunner.countPassed(expressionToCheck)
// if (snippet.toString == "Cons(l1.head, concat(l1.tail, l2))")
// interactivePause
holeFunDef.precondition = oldPreconditionSaved
holeFunDef.body = oldBodySaved
count
}
def evaluateCandidate(snippet: Expr, mapping: Map[Identifier, Expr]) = {
val oldPreconditionSaved = holeFunDef.precondition
val oldBodySaved = holeFunDef.body
// restore initial precondition
holeFunDef.precondition = Some(initialPrecondition)
// get the whole body (if else...)
val accumulatedExpression = accumulatingExpression(snippet)
// set appropriate body to the function for the correct evaluation
holeFunDef.body = Some(accumulatedExpression)
import TreeOps._
val expressionToCheck =
//Globals.bodyAndPostPlug(exp)
{
val resFresh = FreshIdentifier("result", true).setType(accumulatedExpression.getType)
Let(
resFresh, accumulatedExpression,
replace(Map(ResultVariable() -> LeonVariable(resFresh)), matchToIfThenElse(holeFunDef.getPostcondition)))
}
fine("going to evaluate candidate for: " + holeFunDef)
fine("going to evaluate candidate for: " + expressionToCheck)
val count = exampleRunner.evaluate(expressionToCheck, mapping)
// if (snippet.toString == "Cons(l1.head, concat(l1.tail, l2))")
// interactivePause
holeFunDef.precondition = oldPreconditionSaved
holeFunDef.body = oldBodySaved
count
}
def synthesize: Report = {
reporter.info("Synthesis called on file: " + fileName)
// get start time
startTime = System.currentTimeMillis
reporter.info("Initializing synthesizer: ")
reporter.info("numberOfBooleanSnippets: %d".format(numberOfBooleanSnippets))
reporter.info("numberOfCounterExamplesToGenerate: %d".format(numberOfCounterExamplesToGenerate))
reporter.info("leonTimeout: %d".format(leonTimeout))
initialize
reporter.info("Synthesizer initialized")
// keeps status of validity
var keepGoing = Globals.allSolved match {
case Some(true) => false
case _ => true
}
// update flag in case of time limit overdue
def checkTimeout =
if (synthesisContext.shouldStop.get) {
keepGoing = false
true
} else
false
// initial snippets (will update in the loop)
var snippets = synthesizeBranchExpressions
var snippetsIterator = snippets.iterator
// ordering of expressions according to passed examples
var pq = getNewExampleQueue
// iterate while the program is not valid
import scala.util.control.Breaks._
var iteration = 0
var noBranchFoundIteration = 0
breakable {
while (keepGoing) {
if (checkTimeout) break
// next iteration
iteration += 1
noBranchFoundIteration += 1
reporter.info("####################################")
reporter.info("######Iteration #" + iteration + " ###############")
reporter.info("####################################")
reporter.info("# precondition is: " + holeFunDef.precondition.getOrElse(BooleanLiteral(true)))
reporter.info("# accumulatingPrecondition is: " + accumulatingPrecondition)
reporter.info("# accumulatingExpression(Unit) is: " + accumulatingExpression(UnitLiteral))
reporter.info("####################################")
var numberOfTested = 0
// just printing of expressions and pass counts
fine( {
val (it1, it2) = snippetsIterator.duplicate // we are dealing with iterators, need to duplicate
val logString = ((it1 zip Iterator.range(0, numberOfTestsInIteration)) map {
case ((snippet: Output, ind: Int)) => ind + ": snippet is " + snippet.getSnippet +
" pass count is " + countPassedExamples(snippet.getSnippet)
}).mkString("\n")
snippetsIterator = it2
logString
})
//interactivePause
reporter.info("Going into a enumeration/testing phase.")
fine("evaluating examples: " + exampleRunner.counterExamples.mkString("\n"))
breakable {
while(true) {
val batchSize = numberOfTestsInIteration * (1 << noBranchFoundIteration)
reporter.info("numberOfTested: " + numberOfTested)
// ranking of candidates
val candidates = {
val (it1, it2) = snippetsIterator.duplicate
snippetsIterator = it2.drop(batchSize)
it1.take(batchSize).
map(_.getSnippet).filterNot(
snip => {
if (snip.toString == "merge(sort(split(list).fst), sort(split(list).snd))") println("AAA")
(seenBranchExpressions contains snip.toString) || refiner.isAvoidable(snip, problem.as)
}
).toSeq
}
info("got candidates of size: " + candidates.size)
//interactivePause
if (candidates.size > 0) {
val ranker = new Ranker(candidates,
Evaluation(exampleRunner.counterExamples, this.evaluateCandidate _, candidates, exampleRunner),
false)
val maxCandidate = ranker.getMax
info("maxCandidate is: " + maxCandidate)
numberOfTested += batchSize
// if (candidates.exists(_.toString == "merge(sort(split(list).fst), sort(split(list).snd))")) {
// println(ranker.printTuples)
// println("AAA2")
// println("Candidates: " + candidates.zipWithIndex.map({
// case (cand, ind) => "[" + ind + "]" + cand.toString
// }).mkString(", "))
// println("Examples: " + exampleRunner.counterExamples.zipWithIndex.map({
// case (example, ind) => "[" + ind + "]" + example.toString
// }).mkString(", "))
// interactivePause
// }
//interactivePause
if (tryToSynthesizeBranch(maxCandidate)) {
noBranchFoundIteration = 0
break
}
noBranchFoundIteration += 1
}
}
}
// add to seen if branch was not found for it
//seenBranchExpressions += snippetTree.toString
// if did not found for any of the branch expressions
if (found) {
val endTime = System.currentTimeMillis
reporter.info("We are done, in time: " + (endTime - startTime))
return new FullReport(holeFunDef, (endTime - startTime))
}
if ( variableRefinedBranch ) {
fine("Variable refined, doing branch synthesis again")
// get new snippets
snippets = synthesizeBranchExpressions
snippetsIterator = snippets.iterator
pq = getNewExampleQueue
// reset flag
variableRefinedBranch = false
} else
// reseting iterator needed because we may have some expressions that previously did not work
snippetsIterator = snippets.iterator
fine("filtering based on: " + holeFunDef.precondition.get)
fine("counterexamples before filter: " + exampleRunner.counterExamples.size)
exampleRunner.filter(holeFunDef.precondition.get)
fine("counterexamples after filter: " + exampleRunner.counterExamples.size)
fine("counterexamples after filter: " + exampleRunner.counterExamples.mkString("\n"))
}
} //breakable { while (!keepGoing) {
EmptyReport
}
def tryToSynthesizeBranch(snippetTree: Expr): Boolean = {
// replace hole in the body with the whole if-then-else structure, with current snippet tree
val oldBody = holeFunDef.getBody
val newBody = accumulatingExpression(snippetTree)
holeFunDef.body = Some(newBody)
// precondition
val oldPrecondition = holeFunDef.precondition.getOrElse(BooleanLiteral(true))
holeFunDef.precondition = Some(initialPrecondition)
snippetTree.setType(hole.desiredType)
//holeFunDef.getBody.setType(hole.desiredType)
// TODO spare one analyzing step
// analyze the program
fine("analyzing program for funDef:" + holeFunDef)
solver.setProgram(program)
analyzeProgram
// check if solver could solved this instance
if (Globals.allSolved == Some(true)) {
// mark the branch found
found = true
reporter.info("Wooooooow we have a winner!")
reporter.info("************************************")
reporter.info("*********And the winner is**********")
reporter.info(accumulatingExpression(snippetTree).toString)
reporter.info("************************************")
return true
}
// store appropriate values here, will be update in a finally branch
var bodyToRestore = oldBody
var preconditionToRestore = Some(oldPrecondition)
// because first initial test
holeFunDef.precondition = preconditionToRestore
// get counterexamples
fine("Going to generating counterexamples: " + holeFunDef)
val (maps, precondition) = generateCounterexamples(program, holeFunDef, numberOfCounterExamplesToGenerate)
// collect (add) counterexamples from leon
if (collectCounterExamplesFromLeon)
exampleRunner.counterExamples ++= maps
// this should not be possible
// val keepGoing = Globals.allSolved match {
// case Some(true) => false
// case _ => true
// }
//
// // if no counterexamples and all are solved, we are done
// if (maps.isEmpty && !keepGoing) {
// // mark the branch found
// found = true
//
// println("Wooooooow we have a winner!")
// println("************************************")
// println("*********And the winner is**********")
// println(accumulatingExpression(snippetTree))
// println("************************************")
//
// return true
// }
//if(maps.isEmpty) throw new RuntimeException("asdasdasd")
// will modify funDef body and precondition, restore it later
try {
{ //if (!maps.isEmpty) {
// proceed with synthesizing boolean expressions
//solver.setProgram(program)
// reconstruct (only defined number of boolean expressions)
val innerSnippets = synthesizeBooleanExpressions
// just printing of expressions
fine(
((innerSnippets zip Iterator.range(0, numberOfBooleanSnippets).toStream) map {
case ((snippet: Output, ind: Int)) => ind + ": snippet is " + snippet.getSnippet
}).mkString("\n"))
for (
innerSnippetTree <- innerSnippets map { _.getSnippet };
if (
{ val flag = !refiner.isAvoidable(innerSnippetTree, problem.as)
if (!flag) fine("Refiner filtered this snippet: " + innerSnippetTree)
flag }
)
) {
fine("boolean snippet is: " + innerSnippetTree)
val (innerFound, innerPrec) = tryToSynthesizeBooleanCondition(snippetTree, innerSnippetTree, precondition)
// if precondition found
if (innerFound) {
reporter.info("Precondition " + innerPrec + " found for " + snippetTree)
innerPrec match {
case s @ Some(_) =>
// new precondition (restore in finally)
preconditionToRestore = s
case _ =>
}
return true
}
} // iterating over all boolean solutions
reporter.info("No precondition found for branch expression: " + snippetTree)
return false
} // if ( !maps.isEmpty ) {
// no counter examples, we just say that we cannot do anything
false
} // try
finally {
// set these to the FunDef
holeFunDef.precondition = preconditionToRestore
// restore old body (we accumulate expression)
holeFunDef.body = Some(oldBody)
}
}
def tryToSynthesizeBooleanCondition(snippetTree: Expr, innerSnippetTree: Expr, precondition: Expr): (Boolean, Option[Expr]) = {
// trying some examples that cannot be verified
if (snippetTree.toString == "Cons(l.head, insert(e, l.tail))" //&&
//innerSnippetTree.toString.contains("aList.head < bList.head")
) {
val endTime = System.currentTimeMillis
reporter.info("We are done, in time: " + (endTime - startTime))
interactivePause
}
if (snippetTree.toString == "Cons(aList.head, merge(aList.tail, bList))" //&&
//innerSnippetTree.toString.contains("aList.head < bList.head")
) {
val endTime = System.currentTimeMillis
reporter.info("We are done, in time: " + (endTime - startTime))
interactivePause
}
// new condition together with existing precondition
val newCondition = And(Seq(accumulatingPrecondition, innerSnippetTree))
// new expression should not be false
val notFalseEquivalence = Not(newCondition)
val notFalseSolveReturn = solver.solve(notFalseEquivalence)
fine("solve for not false returned: " + notFalseSolveReturn)
notFalseSolveReturn match {
case Some(true) =>
(false, None)
case None =>
(false, None)
// nothing here
// here, our expression is not contradictory, continue
case Some(false) =>
// check if synthesized boolean expression implies precondition (counterexamples)
val implyExpression = Implies(newCondition, precondition)
fine("implyExpression is: " + implyExpression)
// check if synthesized condition implies counter-examples
val solveReturn = solver.solve(implyExpression)
fine("solve returned: " + solveReturn)
solveReturn match {
case Some(true) =>
// if expression implies counterexamples add it to the precondition and try to validate program
holeFunDef.precondition = Some(newCondition)
// do analysis
solver.setProgram(program)
analyzeProgram
// program is valid, we have a branch
if (Globals.allSolved == Some(true)) {
// we found a branch
reporter.info("We found a branch, for expression %s, with condition %s.".format(snippetTree, innerSnippetTree))
// update accumulating expression
val oldAccumulatingExpression = accumulatingExpression
val newAccumulatingExpression =
(finalExpr: Expr) =>
oldAccumulatingExpression({
val innerIf = IfExpr(innerSnippetTree, snippetTree, finalExpr)
innerIf.setType(snippetTree.getType)
innerIf
})
accumulatingExpression = newAccumulatingExpression
// update accumulating precondition
fine("updating accumulatingPrecondition")
accumulatingPrecondition = And(Seq(accumulatingPrecondition, Not(innerSnippetTree)))
fine("updating hole fun precondition and body (to be hole)")
// set to set new precondition
val preconditionToRestore = Some(accumulatingPrecondition)
// check for refinements
checkRefinements(innerSnippetTree) match {
case Some(refinementPair @ (id, classType)) =>
fine("And now we have refinement type: " + refinementPair)
fine("variableRefinements(id) before" + variableRefinements(id))
variableRefinements(id) -= loader.classMap(classType.id)
fine("variableRefinements(id) after" + variableRefinements(id))
// if we have a single subclass possible to refine
if (variableRefinements(id).size == 1) {
reporter.info("We do variable refinement for " + id)
val newType = variableRefinements(id).head
fine("new type is: " + newType)
// update declarations
allDeclarations =
for (dec <- allDeclarations)
yield dec match {
case LeonDeclaration(inSynthType, _, decClassType, imex @ ImmediateExpression(_, LeonVariable(`id`))) =>
LeonDeclaration(
imex, TypeTransformer(newType), newType)
case _ =>
dec
}
// the reason for two flags is for easier management of re-syntheses only if needed
variableRefinedBranch = true
variableRefinedCondition = true
} else
fine("we cannot do variable refinement :(")
case _ =>
}
// found a boolean snippet, break
(true, preconditionToRestore)
} else {
// reset funDef and continue with next boolean snippet
val preconditionToRestore = Some(accumulatingPrecondition)
(false, preconditionToRestore)
}
case _ =>
fine("solver filtered out the precondition (does not imply counterexamples)")
(false, None)
} //solveReturn match { (for implying counterexamples)
} // notFalseSolveReturn match {
}
// inspect the expression if some refinements can be done
def checkRefinements(expr: Expr) = expr match {
case CaseClassInstanceOf(classDef, LeonVariable(id)) =>
Some((id, classDef))
case _ =>
None
}
}