public void UpdateUnsatCore(ProverInterface proverInterface, Dictionary <Variable, bool> assignment) { DateTime now = DateTime.UtcNow; Boogie2VCExprTranslator exprTranslator = proverInterface.Context.BoogieExprTranslator; proverInterface.Push(); proverInterface.Assert(conjecture, false); foreach (var v in assignment.Keys) { if (assignment[v]) { continue; } proverInterface.Assert(exprTranslator.LookupVariable(v), false); } List <Variable> assumptionVars = new List <Variable>(); List <VCExpr> assumptionExprs = new List <VCExpr>(); foreach (var v in assignment.Keys) { if (!assignment[v]) { continue; } assumptionVars.Add(v); assumptionExprs.Add(exprTranslator.LookupVariable(v)); } List <int> unsatCore; ProverInterface.Outcome tmp = proverInterface.CheckAssumptions(assumptionExprs, out unsatCore, handler); System.Diagnostics.Debug.Assert(tmp == ProverInterface.Outcome.Valid); unsatCoreSet = new HashSet <Variable>(); foreach (int i in unsatCore) { unsatCoreSet.Add(assumptionVars[i]); } proverInterface.Pop(); double unsatCoreQueryTime = (DateTime.UtcNow - now).TotalSeconds; stats.unsatCoreProverTime += unsatCoreQueryTime; stats.numUnsatCoreProverQueries++; }
// Is a UNSAT? private static bool CheckIfUnsat(Expr a) { var gen = prover.VCExprGen; var gatherLitA = new GatherLiterals(); gatherLitA.Visit(a); // Create fresh variables var counter = 0; var incarnations = new Dictionary <string, VCExpr>(); foreach (var literal in gatherLitA.literals) { if (incarnations.ContainsKey(literal.Item2.ToString())) { continue; } //if(!literal.Item1.TypedIdent.Type.IsInt && !literal.Item1.TypedIdent.Type.IsBool) var v = gen.Variable("UNSATCheck" + counter, literal.Item1.TypedIdent.Type); incarnations.Add(literal.Item2.ToString(), v); counter++; } var vc1 = ToVcExpr(a, incarnations, gen); var vc = gen.LabelPos("Temp", vc1); // check prover.AssertAxioms(); prover.Push(); prover.Assert(vc, true); prover.Check(); var outcome = prover.CheckOutcomeCore(new DummyErrorReporter()); prover.Pop(); if (outcome == ProverInterface.Outcome.Valid) { return(true); } return(false); }
// Prove candidates that hold (using an over-approximation, at the current inline depth). // Return the set of candidates proved correct static HashSet <string> ProveCandidates(ProverInterface prover, Dictionary <string, VCExpr> constantToAssertedExpr, List <Tuple <string, VCExpr, VCExpr> > constantToAssumedExpr, HashSet <string> candidates) { var remaining = new HashSet <string>(candidates); var reporter = new EmptyErrorReporter(); var failed = new HashSet <string>(); // for dual houdini, we have to iterate once around to the loop // even if remaining is empty bool secondtry = false; while (true) { remaining.ExceptWith(failed); if (remaining.Count == 0 && (!DualHoudini || secondtry)) { break; } if (remaining.Count == 0) { secondtry = true; } else { secondtry = false; } HoudiniStats.ProverCount++; HoudiniStats.Start("ProverTime"); prover.Push(); var nameToCallSiteVar = new Dictionary <string, VCExprVar>(); var callSiteVarToConstantToExpr = new Dictionary <string, Dictionary <string, VCExpr> >(); if (!DualHoudini) { // assert post VCExpr toassert = VCExpressionGenerator.True; foreach (var k in remaining) { toassert = prover.VCExprGen.And(toassert, constantToAssertedExpr[k]); } prover.Assert(toassert, false); } else { // assume post of callees foreach (var tup in constantToAssumedExpr) { if (!remaining.Contains(tup.Item1)) { continue; } var csVar = tup.Item2 as VCExprVar; Debug.Assert(csVar != null); if (!nameToCallSiteVar.ContainsKey(csVar.ToString())) { nameToCallSiteVar.Add(csVar.ToString(), csVar); } if (!callSiteVarToConstantToExpr.ContainsKey(csVar.ToString())) { callSiteVarToConstantToExpr.Add(csVar.ToString(), new Dictionary <string, VCExpr>()); } callSiteVarToConstantToExpr[csVar.ToString()].Add(tup.Item1, tup.Item3); } foreach (var tup in callSiteVarToConstantToExpr) { var expr = VCExpressionGenerator.False; tup.Value.Values.Iter(e => expr = prover.VCExprGen.Or(expr, e)); prover.Assert(prover.VCExprGen.Implies(nameToCallSiteVar[tup.Key], expr), true); } } Dictionary <string, VCExprVar> recordingBool = null; if (RobustAgainstEvaluate) { recordingBool = new Dictionary <string, VCExprVar>(); VCExpr torecord = VCExpressionGenerator.True; foreach (var k in remaining) { var b = prover.VCExprGen.Variable("recordingVar_" + k, Microsoft.Boogie.Type.Bool); recordingBool.Add(k, b); torecord = prover.VCExprGen.And(torecord, prover.VCExprGen.Eq(b, constantToAssertedExpr[k])); } prover.Assert(torecord, true); } prover.Check(); var outcome = prover.CheckOutcomeCore(reporter); // check which ones failed if (outcome == ProverInterface.Outcome.Invalid || outcome == ProverInterface.Outcome.Undetermined) { var removed = 0; if (!DualHoudini) { foreach (var k in remaining) { var b = recordingBool == null ? (bool)prover.Evaluate(constantToAssertedExpr[k]) : (bool)prover.Evaluate(recordingBool[k]); if (!b) { failed.Add(k); if (dbg) { Console.WriteLine("Failed: {0}", k); } removed++; } } } else { foreach (var tup in callSiteVarToConstantToExpr) { if (!(bool)prover.Evaluate(nameToCallSiteVar[tup.Key])) { continue; } // call site taken foreach (var tup2 in tup.Value) { if ((bool)prover.Evaluate(tup2.Value)) { failed.Add(tup2.Key); if (dbg) { Console.WriteLine("Failed: {0}", tup2.Key); } removed++; } } } if (removed == 0) { throw new DualHoudiniFail("Nothing to drop"); } } Debug.Assert(removed != 0); //if(dbg) Console.WriteLine("Query {0}: Invalid, {1} removed", HoudiniStats.ProverCount, removed); } HoudiniStats.Stop("ProverTime"); prover.Pop(); if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory) { if (DualHoudini) { throw new DualHoudiniFail("Timeout"); } failed.UnionWith(remaining); break; } if (outcome == ProverInterface.Outcome.Valid) { //if(dbg) Console.WriteLine("Query {0}: Valid", HoudiniStats.ProverCount); break; } } remaining.ExceptWith(failed); return(remaining); }