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

Confidence is now over 9000

parent c372e659
No related branches found
No related tags found
No related merge requests found
...@@ -197,7 +197,7 @@ object FunctionTemplate { ...@@ -197,7 +197,7 @@ object FunctionTemplate {
None None
} }
val activatingBool : Identifier = FreshIdentifier("a", true).setType(BooleanType) val activatingBool : Identifier = FreshIdentifier("start", true).setType(BooleanType)
funDef match { funDef match {
case Some(fd) => case Some(fd) =>
...@@ -206,7 +206,7 @@ object FunctionTemplate { ...@@ -206,7 +206,7 @@ object FunctionTemplate {
case None => case None =>
storeGuarded(activatingBool, false, BooleanLiteral(false)) storeGuarded(activatingBool, false, BooleanLiteral(false))
val newFormula = rec(activatingBool, true, body.get) val newFormula = rec(activatingBool, true, newBody.get)
storeGuarded(activatingBool, true, newFormula) storeGuarded(activatingBool, true, newFormula)
} }
......
...@@ -221,7 +221,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -221,7 +221,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
varsInVC ++= variablesOf(expandedVC) varsInVC ++= variablesOf(expandedVC)
reporter.info(" - Initial unrolling...") reporter.info(" - Initial unrolling...")
val (clauses, guards) = unrollingBank.initialUnrolling(expandedVC) val (clauses, guards) = unrollingBank.scanForNewTemplates(expandedVC)
val cc = toZ3Formula(And(clauses)).get val cc = toZ3Formula(And(clauses)).get
solver.assertCnstr(cc) solver.assertCnstr(cc)
...@@ -579,7 +579,17 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -579,7 +579,17 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
} }
def scanForNewTemplates(expr: Expr): (Seq[Expr], Seq[(Identifier, Boolean)]) = { def scanForNewTemplates(expr: Expr): (Seq[Expr], Seq[(Identifier, Boolean)]) = {
(Seq(), Seq()) val tmp = FunctionTemplate.mkTemplate(expr)
val allBlocks : MutableSet[(Identifier,Boolean)] = MutableSet.empty
for (((i, p), fis) <- tmp.blockers) {
if(registerBlocked(i, p, fis)) {
allBlocks += i -> p
}
}
(tmp.asClauses, allBlocks.toSeq)
} }
private def treatFunctionInvocationSet(sVar : Identifier, pol : Boolean, fis : Set[FunctionInvocation]) : (Seq[Expr],Seq[(Identifier,Boolean)]) = { private def treatFunctionInvocationSet(sVar : Identifier, pol : Boolean, fis : Set[FunctionInvocation]) : (Seq[Expr],Seq[(Identifier,Boolean)]) = {
...@@ -590,9 +600,9 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -590,9 +600,9 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
val temp = FunctionTemplate.mkTemplate(fi.funDef) val temp = FunctionTemplate.mkTemplate(fi.funDef)
val (newExprs,newBlocks) = temp.instantiate(sVar, pol, fi.args) val (newExprs,newBlocks) = temp.instantiate(sVar, pol, fi.args)
for(((i,p),fis) <- newBlocks) { for(((i, p), fis) <- newBlocks) {
if(registerBlocked(i,p,fis)) { if(registerBlocked(i, p, fis)) {
allBlocks += ((i,p)) allBlocks += i -> p
} }
} }
allNewExprs = allNewExprs ++ newExprs allNewExprs = allNewExprs ++ newExprs
...@@ -600,16 +610,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -600,16 +610,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
(allNewExprs, allBlocks.toSeq) (allNewExprs, allBlocks.toSeq)
} }
def initialUnrolling(formula : Expr) : (Seq[Expr], Seq[(Identifier,Boolean)]) = {
val tmp = FunctionTemplate.mkTemplate(formula)
for (((p1, p2), calls) <- tmp.blockers) {
registerBlocked(p1, p2, calls)
}
(tmp.asClauses, tmp.blockers.keySet.toSeq)
}
def unlock(id: Identifier, pol: Boolean) : (Seq[Expr], Seq[(Identifier,Boolean)]) = { def unlock(id: Identifier, pol: Boolean) : (Seq[Expr], Seq[(Identifier,Boolean)]) = {
if(!blockMap.isDefinedAt((id,pol))) { if(!blockMap.isDefinedAt((id,pol))) {
(Seq.empty,Seq.empty) (Seq.empty,Seq.empty)
...@@ -624,26 +624,24 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -624,26 +624,24 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
def getNewSolver = new solvers.IncrementalSolver { def getNewSolver = new solvers.IncrementalSolver {
val solver = z3.mkSolver val solver = z3.mkSolver
private var ownStack = List[Set[Z3AST]](Set()) private var frameGuards = List[Z3AST](z3.mkFreshConst("frame", z3.mkBoolSort))
private var assertionsStack = List[List[Expr]](Nil) private var frameExpressions = List[List[Expr]](Nil)
private var varsInVC = Set[Identifier]() private var varsInVC = Set[Identifier]()
def allClausePredicates = ownStack.flatten def entireFormula = And(frameExpressions.flatten)
def push() { def push() {
ownStack = Set[Z3AST]() :: ownStack frameGuards = z3.mkFreshConst("frame", z3.mkBoolSort) :: frameGuards
assertionsStack = Nil :: assertionsStack frameExpressions = Nil :: frameExpressions
} }
def pop(lvl: Int = 1) { def pop(lvl: Int = 1) {
val frame = ownStack.head // We make sure we discard the expressions guarded by this frame
ownStack = ownStack.tail solver.assertCnstr(z3.mkNot(frameGuards.head))
assertionsStack = assertionsStack.tail // Pop the frames
frameGuards = frameGuards.tail
frame.foreach { b => frameExpressions = frameExpressions.tail
solver.assertCnstr(z3.mkNot(b))
}
} }
def check: Option[Boolean] = { def check: Option[Boolean] = {
...@@ -655,7 +653,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -655,7 +653,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
} }
val unrollingBank = new UnrollingBank() val unrollingBank = new UnrollingBank()
var isBankInitialized = false
var foundDefinitiveAnswer = false var foundDefinitiveAnswer = false
var definitiveAnswer : Option[Boolean] = None var definitiveAnswer : Option[Boolean] = None
...@@ -666,21 +663,21 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -666,21 +663,21 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
private var blockingSet: Set[Expr] = Set.empty private var blockingSet: Set[Expr] = Set.empty
def assertCnstr(expression: Expr) { def assertCnstr(expression: Expr) {
val b = z3.mkFreshConst("b", z3.mkBoolSort) val guard = frameGuards.head
varsInVC ++= variablesOf(expression) varsInVC ++= variablesOf(expression)
ownStack = (ownStack.head + b) :: ownStack.tail frameExpressions = (expression :: frameExpressions.head) :: frameExpressions.tail
assertionsStack = (expression :: assertionsStack.head) :: assertionsStack.tail
solver.assertCnstr(z3.mkImplies(b, toZ3Formula(expression).get)) solver.assertCnstr(z3.mkImplies(guard, toZ3Formula(expression).get))
if (isBankInitialized) { val (newClauses, newGuards) = unrollingBank.scanForNewTemplates(expression)
val (newClauses, newGuards) = unrollingBank.scanForNewTemplates(expression)
for (cl <- newClauses) { for (cl <- newClauses) {
solver.assertCnstr(toZ3Formula(cl).get) solver.assertCnstr(z3.mkImplies(guard, toZ3Formula(cl).get))
}
blockingSet ++= newGuards.map(p => if(p._2) Not(Variable(p._1)) else Variable(p._1))
} }
blockingSet ++= newGuards.map(p => if(p._2) Not(Variable(p._1)) else Variable(p._1))
} }
def getModel = { def getModel = {
...@@ -702,7 +699,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -702,7 +699,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
} }
def z3CoreToCore(core: Seq[Z3AST]): Set[Expr] = { def z3CoreToCore(core: Seq[Z3AST]): Set[Expr] = {
val internalAssumptions = allClausePredicates.toSet val internalAssumptions = frameGuards.toSet
val userlandAssumptions = core.filterNot(internalAssumptions) val userlandAssumptions = core.filterNot(internalAssumptions)
userlandAssumptions.map(ast => fromZ3Formula(null, ast, None) match { userlandAssumptions.map(ast => fromZ3Formula(null, ast, None) match {
...@@ -712,17 +709,8 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -712,17 +709,8 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
}).toSet }).toSet
} }
if (!isBankInitialized) {
reporter.info(" - Initial unrolling...")
val (clauses, guards) = unrollingBank.initialUnrolling(And(assertionsStack.flatten))
solver.assertCnstr(toZ3Formula(And(clauses)).get)
blockingSet ++= guards.map(p => if(p._2) Not(Variable(p._1)) else Variable(p._1))
}
// these are the optional sequence of assumption literals // these are the optional sequence of assumption literals
val assumptionsAsZ3: Seq[Z3AST] = allClausePredicates ++ assumptions.map(toZ3Formula(_).get) val assumptionsAsZ3: Seq[Z3AST] = frameGuards ++ assumptions.map(toZ3Formula(_).get)
var iterationsLeft : Int = if(Settings.unrollingLevel > 0) Settings.unrollingLevel else 16121984 var iterationsLeft : Int = if(Settings.unrollingLevel > 0) Settings.unrollingLevel else 16121984
...@@ -732,14 +720,9 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -732,14 +720,9 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
val blockingSetAsZ3 : Seq[Z3AST] = blockingSet.toSeq.map(toZ3Formula(_).get) val blockingSetAsZ3 : Seq[Z3AST] = blockingSet.toSeq.map(toZ3Formula(_).get)
// println("Blocking set : " + blockingSet) // println("Blocking set : " + blockingSet)
solver.push()
for (block <- blockingSetAsZ3) {
solver.assertCnstr(block)
}
reporter.info(" - Running Z3 search...") reporter.info(" - Running Z3 search...")
val res = solver.checkAssumptions(assumptionsAsZ3 :_*) val res = solver.checkAssumptions((blockingSetAsZ3 ++ assumptionsAsZ3) :_*)
reporter.info(" - Finished search with blocked literals") reporter.info(" - Finished search with blocked literals")
...@@ -754,7 +737,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -754,7 +737,7 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
val z3model = solver.getModel val z3model = solver.getModel
if (Settings.verifyModel && false) { if (Settings.verifyModel && false) {
val (isValid, model) = validateAndDeleteModel(z3model, toCheckAgainstModels, varsInVC) val (isValid, model) = validateAndDeleteModel(z3model, entireFormula, varsInVC)
if (isValid) { if (isValid) {
foundAnswer(Some(true), model) foundAnswer(Some(true), model)
...@@ -777,7 +760,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -777,7 +760,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
val core = z3CoreToCore(solver.getUnsatCore) val core = z3CoreToCore(solver.getUnsatCore)
foundAnswer(Some(false), core = core) foundAnswer(Some(false), core = core)
solver.pop(1)
// This branch is both for with and without unsat cores. The // This branch is both for with and without unsat cores. The
// distinction is made inside. // distinction is made inside.
...@@ -785,9 +767,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -785,9 +767,6 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
val core = z3CoreToCore(solver.getUnsatCore) val core = z3CoreToCore(solver.getUnsatCore)
// Removes blocking literals
solver.pop(1)
if (!forceStop) { if (!forceStop) {
if (Settings.luckyTest) { if (Settings.luckyTest) {
// we need the model to perform the additional test // we need the model to perform the additional test
...@@ -804,10 +783,8 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ ...@@ -804,10 +783,8 @@ class FairZ3Solver(context : LeonContext) extends Solver(context) with AbstractZ
case Some(true) => case Some(true) =>
if (Settings.luckyTest && !forceStop) { if (Settings.luckyTest && !forceStop) {
// we might have been lucky :D // we might have been lucky :D
val (wereWeLucky, cleanModel) = validateAndDeleteModel(solver.getModel, toCheckAgainstModels, varsInVC) val (wereWeLucky, cleanModel) = validateAndDeleteModel(solver.getModel, entireFormula, varsInVC)
if(wereWeLucky) { if(wereWeLucky) {
reporter.info("Found lucky to "+solver.getAssertions.toSeq+" with "+assumptionsAsZ3)
reporter.info("Stack: "+ownStack)
foundAnswer(Some(true), cleanModel) foundAnswer(Some(true), cleanModel)
} }
} }
......
...@@ -9,6 +9,8 @@ import purescala.TypeTrees._ ...@@ -9,6 +9,8 @@ import purescala.TypeTrees._
import purescala.TreeOps._ import purescala.TreeOps._
import purescala.Extractors._ import purescala.Extractors._
import solvers.z3.FairZ3Solver
case object CEGIS extends Rule("CEGIS", 150) { case object CEGIS extends Rule("CEGIS", 150) {
def attemptToApplyOn(sctx: SynthesisContext, p: Problem): RuleResult = { def attemptToApplyOn(sctx: SynthesisContext, p: Problem): RuleResult = {
case class Generator(tpe: TypeTree, altBuilder: () => List[(Expr, Set[Identifier])]); case class Generator(tpe: TypeTree, altBuilder: () => List[(Expr, Set[Identifier])]);
...@@ -138,41 +140,51 @@ case object CEGIS extends Rule("CEGIS", 150) { ...@@ -138,41 +140,51 @@ case object CEGIS extends Rule("CEGIS", 150) {
var continue = true var continue = true
val mainSolver: FairZ3Solver = sctx.solver.asInstanceOf[FairZ3Solver]
// solver1 is used for the initial SAT queries // solver1 is used for the initial SAT queries
val solver1 = sctx.solver.getNewSolver val solver1 = mainSolver.getNewSolver
val basePhi = currentF.entireFormula val basePhi = currentF.entireFormula
solver1.assertCnstr(basePhi) solver1.assertCnstr(basePhi)
// solver2 is used for the CE search // solver2 is used for the CE search
val solver2 = sctx.solver.getNewSolver val solver2 = mainSolver.getNewSolver
solver2.assertCnstr(And(currentF.pathcond :: currentF.program :: Not(currentF.phi) :: Nil)) solver2.assertCnstr(And(currentF.pathcond :: currentF.program :: Not(currentF.phi) :: Nil))
// solver3 is used for the unsatcore search // solver3 is used for the unsatcore search
val solver3 = sctx.solver.getNewSolver val solver3 = mainSolver.getNewSolver
solver3.assertCnstr(And(currentF.pathcond :: currentF.program :: currentF.phi :: Nil)) solver3.assertCnstr(And(currentF.pathcond :: currentF.program :: currentF.phi :: Nil))
while (result.isEmpty && continue) { while (result.isEmpty && continue) {
//println("-"*80) //println("-"*80)
//println(basePhi)
//println("To satisfy: "+constrainedPhi) //println("To satisfy: "+constrainedPhi)
solver1.check match { solver1.check match {
case Some(true) => case Some(true) =>
val satModel = solver1.getModel val satModel = solver1.getModel
//println("Found solution: "+satModel)
//println("Corresponding program: "+simplifyTautologies(synth.solver)(valuateWithModelIn(currentF.program, bss, satModel))) //println("Corresponding program: "+simplifyTautologies(synth.solver)(valuateWithModelIn(currentF.program, bss, satModel)))
val fixedBss = And(bss.map(b => Equals(Variable(b), satModel(b))).toSeq) val fixedBss = And(bss.map(b => Equals(Variable(b), satModel(b))).toSeq)
//println("Phi with fixed sat bss: "+fixedBss) //println("Phi with fixed sat bss: "+fixedBss)
solver2.push() solver2.push()
solver2.assertCnstr(fixedBss) solver2.assertCnstr(fixedBss)
//println("Formula to validate: "+counterPhi)
//println("FORMULA: "+And(currentF.pathcond :: currentF.program :: Not(currentF.phi) :: fixedBss :: Nil))
//println("#"*80)
solver2.check match { solver2.check match {
case Some(true) => case Some(true) =>
//println("#"*80)
val invalidModel = solver2.getModel val invalidModel = solver2.getModel
val fixedAss = And(ass.map(a => Equals(Variable(a), invalidModel(a))).toSeq) val fixedAss = And(ass.map(a => Equals(Variable(a), invalidModel(a))).toSeq)
//println("Found counter example: "+fixedAss)
solver3.push() solver3.push()
solver3.assertCnstr(fixedAss) solver3.assertCnstr(fixedAss)
...@@ -221,10 +233,11 @@ case object CEGIS extends Rule("CEGIS", 150) { ...@@ -221,10 +233,11 @@ case object CEGIS extends Rule("CEGIS", 150) {
} }
case Some(false) => case Some(false) =>
//println("#"*80)
//println("UNSAT!")
//println("Sat model: "+satModel.toSeq.sortBy(_._1.toString).map{ case (id, v) => id+" -> "+v }.mkString(", ")) //println("Sat model: "+satModel.toSeq.sortBy(_._1.toString).map{ case (id, v) => id+" -> "+v }.mkString(", "))
var mapping = currentF.mappings.filterKeys(satModel.mapValues(_ == BooleanLiteral(true))).values.toMap var mapping = currentF.mappings.filterKeys(satModel.mapValues(_ == BooleanLiteral(true))).values.toMap
//println("Mapping: "+mapping)
// Resolve mapping // Resolve mapping
for ((c, e) <- mapping) { for ((c, e) <- mapping) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment