public static void CreateProver(string z3exe) { CommandLineOptions.Clo.Z3ExecutablePath = z3exe; CommandLineOptions.Clo.ApplyDefaultOptions(); CommandLineOptions.Clo.StratifiedInlining = 1; prover = ProverInterface.CreateProver(new Program(), "log", CommandLineOptions.Clo.SimplifyLogFileAppend, -1); }
public ProverInterface.Outcome Verify(ProverInterface proverInterface, Dictionary <Variable, bool> assignment, out List <Counterexample> errors, int taskID = -1) { collector.examples.Clear(); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Verifying " + descriptiveName); } DateTime now = DateTime.UtcNow; VCExpr vc = proverInterface.VCExprGen.Implies(BuildAxiom(proverInterface, assignment), conjecture); proverInterface.BeginCheck(descriptiveName, vc, handler); ProverInterface.Outcome proverOutcome = proverInterface.CheckOutcome(handler, taskID: taskID); double queryTime = (DateTime.UtcNow - now).TotalSeconds; stats.proverTime += queryTime; stats.numProverQueries++; if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Outcome = " + proverOutcome); Console.WriteLine("Time taken = " + queryTime); } errors = collector.examples; return(proverOutcome); }
public static void InitializeVCGen(Program prog) { //create VC.vcgen/VC.proverInterface VC.vcgen = new VCGen(prog, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>()); VC.proverInterface = ProverInterface.CreateProver(prog, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime); VC.translator = VC.proverInterface.Context.BoogieExprTranslator; VC.exprGen = VC.proverInterface.Context.ExprGen; VC.collector = new ConditionGeneration.CounterexampleCollector(); }
public StratifiedVCGenBase(Program program, string /*?*/ logFilePath, bool appendLogFile, List<Checker> checkers, Action<Implementation> PassiveImplInstrumentation) : base(program, logFilePath, appendLogFile, checkers) { implName2StratifiedInliningInfo = new Dictionary<string, StratifiedInliningInfo>(); prover = ProverInterface.CreateProver(program, logFilePath, appendLogFile, CommandLineOptions.Clo.TimeLimit); foreach (var impl in program.Implementations) { implName2StratifiedInliningInfo[impl.Name] = new StratifiedInliningInfo(impl, this, PassiveImplInstrumentation); } GenerateRecordFunctions(); }
public HoudiniSession(Houdini houdini, VCGen vcgen, ProverInterface proverInterface, Program program, Implementation impl, HoudiniStatistics stats, int taskID = -1) { this.descriptiveName = impl.Name; this.stats = stats; collector = new ConditionGeneration.CounterexampleCollector(); collector.OnProgress("HdnVCGen", 0, 0, 0.0); vcgen.ConvertCFG2DAG(impl, taskID: taskID); ModelViewInfo mvInfo; var gotoCmdOrigins = vcgen.PassifyImpl(impl, out mvInfo); ExistentialConstantCollector ecollector; ExistentialConstantCollector.CollectHoudiniConstants(houdini, impl, out ecollector); this.houdiniAssertConstants = ecollector.houdiniAssertConstants; this.houdiniAssumeConstants = ecollector.houdiniAssumeConstants; this.explainConstantsNegative = ecollector.explainNegative; this.explainConstantsPositive = ecollector.explainPositive; this.constantToControl = ecollector.constToControl; houdiniConstants = new HashSet <Variable>(); houdiniConstants.UnionWith(houdiniAssertConstants); houdiniConstants.UnionWith(houdiniAssumeConstants); var exprGen = proverInterface.Context.ExprGen; VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : exprGen.Integer(BigNum.ZERO); Dictionary <int, Absy> label2absy; conjecture = vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, proverInterface.Context); if (!CommandLineOptions.Clo.UseLabels) { VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(exprGen.Integer(BigNum.ZERO), exprGen.Integer(BigNum.ZERO)); VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); conjecture = exprGen.Implies(eqExpr, conjecture); } Macro macro = new Macro(Token.NoToken, descriptiveName, new List <Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Type.Bool), false)); proverInterface.DefineMacro(macro, conjecture); conjecture = exprGen.Function(macro); if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local) { handler = new VCGen.ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program); } else { handler = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program); } }
private VCExpr BuildAxiom(ProverInterface proverInterface, Dictionary <Variable, bool> currentAssignment) { ProverContext proverContext = proverInterface.Context; Boogie2VCExprTranslator exprTranslator = proverContext.BoogieExprTranslator; VCExpressionGenerator exprGen = proverInterface.VCExprGen; VCExpr expr = VCExpressionGenerator.True; foreach (KeyValuePair <Variable, bool> kv in currentAssignment) { Variable constant = kv.Key; VCExprVar exprVar = exprTranslator.LookupVariable(constant); if (kv.Value) { expr = exprGen.And(expr, exprVar); } else { expr = exprGen.And(expr, exprGen.Not(exprVar)); } } if (CommandLineOptions.Clo.ExplainHoudini) { // default values for ExplainHoudini control variables foreach (var constant in explainConstantsNegative.Concat(explainConstantsPositive)) { expr = exprGen.And(expr, exprTranslator.LookupVariable(constant)); } } /* * foreach (Variable constant in this.houdiniConstants) { * VCExprVar exprVar = exprTranslator.LookupVariable(constant); * if (currentAssignment[constant]) { * expr = exprGen.And(expr, exprVar); * } * else { * expr = exprGen.And(expr, exprGen.Not(exprVar)); * } * } */ if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Houdini assignment axiom: " + expr); } return(expr); }
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++; }
public VCExpr Attach(StratifiedVC svc) { Contract.Assert(interfaceExprs.Count == svc.interfaceExprVars.Count); StratifiedInliningInfo info = svc.info; ProverInterface prover = info.vcgen.prover; VCExpressionGenerator gen = prover.VCExprGen; Dictionary<VCExprVar, VCExpr> substDict = new Dictionary<VCExprVar, VCExpr>(); for (int i = 0; i < svc.interfaceExprVars.Count; i++) { VCExprVar v = svc.interfaceExprVars[i]; substDict.Add(v, interfaceExprs[i]); } VCExprSubstitution subst = new VCExprSubstitution(substDict, new Dictionary<TypeVariable, Microsoft.Boogie.Type>()); SubstitutingVCExprVisitor substVisitor = new SubstitutingVCExprVisitor(prover.VCExprGen); svc.vcexpr = substVisitor.Mutate(svc.vcexpr, subst); foreach (StratifiedCallSite scs in svc.CallSites) { List<VCExpr> newInterfaceExprs = new List<VCExpr>(); foreach (VCExpr expr in scs.interfaceExprs) { newInterfaceExprs.Add(substVisitor.Mutate(expr, subst)); } scs.interfaceExprs = newInterfaceExprs; } foreach (StratifiedCallSite scs in svc.RecordProcCallSites) { List<VCExpr> newInterfaceExprs = new List<VCExpr>(); foreach (VCExpr expr in scs.interfaceExprs) { newInterfaceExprs.Add(substVisitor.Mutate(expr, subst)); } scs.interfaceExprs = newInterfaceExprs; } //return gen.Implies(callSiteExpr, svc.vcexpr); return svc.vcexpr; }
public AbstractHoudini(Program program) { this.program = program; this.impl2VC = new Dictionary <string, VCExpr>(); this.impl2EndStateVars = new Dictionary <string, List <VCExpr> >(); this.impl2CalleeSummaries = new Dictionary <string, List <Tuple <string, VCExprNAry> > >(); this.impl2Summary = new Dictionary <string, ISummaryElement>(); this.name2Impl = BoogieUtil.nameImplMapping(program); this.vcgen = new VCGen(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, new List <Checker>()); this.prover = ProverInterface.CreateProver(program, CommandLineOptions.Clo.ProverLogFilePath, CommandLineOptions.Clo.ProverLogFileAppend, CommandLineOptions.Clo.TimeLimit); this.reporter = new AbstractHoudiniErrorReporter(); var impls = new List <Implementation>( program.TopLevelDeclarations.OfType <Implementation>()); // Create all VCs impls .Iter(attachEnsures); impls .Iter(GenVC); }
// MAXSAT public void Explain(ProverInterface proverInterface, Dictionary <Variable, bool> assignment, Variable refutedConstant) { Contract.Assert(CommandLineOptions.Clo.ExplainHoudini); collector.examples.Clear(); // debugging houdiniAssertConstants.Iter(v => System.Diagnostics.Debug.Assert(assignment.ContainsKey(v))); houdiniAssumeConstants.Iter(v => System.Diagnostics.Debug.Assert(assignment.ContainsKey(v))); Contract.Assert(assignment.ContainsKey(refutedConstant)); Contract.Assert(houdiniAssertConstants.Contains(refutedConstant)); var hardAssumptions = new List <VCExpr>(); var softAssumptions = new List <VCExpr>(); Boogie2VCExprTranslator exprTranslator = proverInterface.Context.BoogieExprTranslator; VCExpressionGenerator exprGen = proverInterface.VCExprGen; var controlExpr = VCExpressionGenerator.True; foreach (var tup in assignment) { Variable constant = tup.Key; VCExprVar exprVar = exprTranslator.LookupVariable(constant); var val = tup.Value; if (houdiniAssumeConstants.Contains(constant)) { if (tup.Value) { hardAssumptions.Add(exprVar); } else { // Previously removed assumed candidates are the soft constraints softAssumptions.Add(exprVar); } } else if (houdiniAssertConstants.Contains(constant)) { if (constant == refutedConstant) { hardAssumptions.Add(exprVar); } else { hardAssumptions.Add(exprGen.Not(exprVar)); } } else { if (tup.Value) { hardAssumptions.Add(exprVar); } else { hardAssumptions.Add(exprGen.Not(exprVar)); } } // For an asserted condition (c ==> \phi), // ExplainHoudini's extra control constants (c_pos, c_neg) are used as follows: // (true, true): "assert \phi" // (false, _): "assert false" // (true, false): "assert true" if (constant != refutedConstant && constantToControl.ContainsKey(constant.Name)) { var posControl = constantToControl[constant.Name].Item1; var negControl = constantToControl[constant.Name].Item2; // Handle self-recursion if (houdiniAssertConstants.Contains(constant) && houdiniAssumeConstants.Contains(constant)) { // disable this assert controlExpr = exprGen.And(controlExpr, exprGen.And(exprTranslator.LookupVariable(posControl), exprGen.Not(exprTranslator.LookupVariable(negControl)))); } else { // default values for control variables controlExpr = exprGen.And(controlExpr, exprGen.And(exprTranslator.LookupVariable(posControl), exprTranslator.LookupVariable(negControl))); } } } hardAssumptions.Add(exprGen.Not(conjecture)); // default values for control variables Contract.Assert(constantToControl.ContainsKey(refutedConstant.Name)); var pc = constantToControl[refutedConstant.Name].Item1; var nc = constantToControl[refutedConstant.Name].Item2; var controlExprNoop = exprGen.And(controlExpr, exprGen.And(exprTranslator.LookupVariable(pc), exprTranslator.LookupVariable(nc))); var controlExprFalse = exprGen.And(controlExpr, exprGen.And(exprGen.Not(exprTranslator.LookupVariable(pc)), exprGen.Not(exprTranslator.LookupVariable(nc)))); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Verifying (MaxSat) " + descriptiveName); } DateTime now = DateTime.UtcNow; var el = CommandLineOptions.Clo.ProverCCLimit; CommandLineOptions.Clo.ProverCCLimit = 1; var outcome = ProverInterface.Outcome.Undetermined; do { List <int> unsatisfiedSoftAssumptions; hardAssumptions.Add(controlExprNoop); outcome = proverInterface.CheckAssumptions(hardAssumptions, softAssumptions, out unsatisfiedSoftAssumptions, handler); hardAssumptions.RemoveAt(hardAssumptions.Count - 1); if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined) { break; } var reason = new HashSet <string>(); unsatisfiedSoftAssumptions.Iter(i => reason.Add(softAssumptions[i].ToString())); if (CommandLineOptions.Clo.Trace) { Console.Write("Reason for removal of {0}: ", refutedConstant.Name); reason.Iter(r => Console.Write("{0} ", r)); Console.WriteLine(); } // Get rid of those constants from the "reason" that can even make // "assert false" pass hardAssumptions.Add(controlExprFalse); var softAssumptions2 = new List <VCExpr>(); for (int i = 0; i < softAssumptions.Count; i++) { if (unsatisfiedSoftAssumptions.Contains(i)) { softAssumptions2.Add(softAssumptions[i]); continue; } hardAssumptions.Add(softAssumptions[i]); } var unsatisfiedSoftAssumptions2 = new List <int>(); outcome = proverInterface.CheckAssumptions(hardAssumptions, softAssumptions2, out unsatisfiedSoftAssumptions2, handler); if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined) { break; } unsatisfiedSoftAssumptions2.Iter(i => reason.Remove(softAssumptions2[i].ToString())); var reason1 = new HashSet <string>(); //these are the reasons for inconsistency unsatisfiedSoftAssumptions2.Iter(i => reason1.Add(softAssumptions2[i].ToString())); if (CommandLineOptions.Clo.Trace) { Console.Write("Revised reason for removal of {0}: ", refutedConstant.Name); reason.Iter(r => Console.Write("{0} ", r)); Console.WriteLine(); } foreach (var r in reason) { Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=red ];", refutedConstant.Name, r, descriptiveName); } //also add the removed reasons using dotted edges (requires- x != 0, requires- x == 0 ==> assert x != 0) foreach (var r in reason1) { Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=blue style=dotted ];", refutedConstant.Name, r, descriptiveName); } } while (false); if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || outcome == ProverInterface.Outcome.OutOfResource || outcome == ProverInterface.Outcome.Undetermined) { Houdini.explainHoudiniDottyFile.WriteLine("{0} -> {1} [ label = \"{2}\" color=red ];", refutedConstant.Name, "TimeOut", descriptiveName); } CommandLineOptions.Clo.ProverCCLimit = el; double queryTime = (DateTime.UtcNow - now).TotalSeconds; stats.proverTime += queryTime; stats.numProverQueries++; if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Time taken = " + queryTime); } }
public void GenerateVC() { if (initialized) return; if (CommandLineOptions.Clo.SIBoolControlVC) { GenerateVCBoolControl(); initialized = true; return; } List<Variable> outputVariables = new List<Variable>(); List<Expr> assertConjuncts = new List<Expr>(); foreach (Variable v in impl.OutParams) { Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } foreach (IdentifierExpr e in impl.Proc.Modifies) { if (e.Decl == null) continue; Variable v = e.Decl; Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } exitAssertCmd = new AssertCmd(Token.NoToken, Expr.Not(Expr.BinaryTreeAnd(assertConjuncts))); Program program = vcgen.program; ProverInterface proverInterface = vcgen.prover; vcgen.ConvertCFG2DAG(impl); vcgen.PassifyImpl(impl, out mvInfo); VCExpressionGenerator gen = proverInterface.VCExprGen; var exprGen = proverInterface.Context.ExprGen; var translator = proverInterface.Context.BoogieExprTranslator; controlFlowVariable = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "@cfc", Microsoft.Boogie.Type.Int)); VCExpr controlFlowVariableExpr = translator.LookupVariable(controlFlowVariable); vcgen.InstrumentCallSites(impl); if (PassiveImplInstrumentation != null) PassiveImplInstrumentation(impl); label2absy = new Dictionary<int, Absy>(); VCGen.CodeExprConversionClosure cc = new VCGen.CodeExprConversionClosure(label2absy, proverInterface.Context); translator.SetCodeExprConverter(cc.CodeExprToVerificationCondition); vcexpr = gen.Not(vcgen.GenerateVCAux(impl, controlFlowVariableExpr, label2absy, proverInterface.Context)); if (controlFlowVariableExpr != null) { VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(controlFlowVariableExpr, exprGen.Integer(BigNum.ZERO)); VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); vcexpr = exprGen.And(eqExpr, vcexpr); } callSites = vcgen.CollectCallSites(impl); recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl); privateExprVars = new List<VCExprVar>(); foreach (Variable v in impl.LocVars) { privateExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.OutParams) { privateExprVars.Add(translator.LookupVariable(v)); } interfaceExprVars = new List<VCExprVar>(); foreach (Variable v in program.GlobalVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.InParams) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in outputVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } initialized = true; }
public void GenerateVCBoolControl() { Debug.Assert(!initialized); Debug.Assert(CommandLineOptions.Clo.SIBoolControlVC); // fix names for exit variables var outputVariables = new List<Variable>(); var assertConjuncts = new List<Expr>(); foreach (Variable v in impl.OutParams) { Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } foreach (IdentifierExpr e in impl.Proc.Modifies) { if (e.Decl == null) continue; Variable v = e.Decl; Constant c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, impl.Name + "_" + v.Name, v.TypedIdent.Type)); outputVariables.Add(c); Expr eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, c), new IdentifierExpr(Token.NoToken, v)); assertConjuncts.Add(eqExpr); } exitAssertCmd = new AssumeCmd(Token.NoToken, Expr.BinaryTreeAnd(assertConjuncts)); (exitAssertCmd as AssumeCmd).Attributes = new QKeyValue(Token.NoToken, "exitAssert", new List<object>(), null); // no need for label2absy label2absy = new Dictionary<int, Absy>(); // Passify Program program = vcgen.program; ProverInterface proverInterface = vcgen.prover; vcgen.ConvertCFG2DAG(impl); vcgen.PassifyImpl(impl, out mvInfo); VCExpressionGenerator gen = proverInterface.VCExprGen; var exprGen = proverInterface.Context.ExprGen; var translator = proverInterface.Context.BoogieExprTranslator; // add a boolean variable at each call site vcgen.InstrumentCallSites(impl); // typecheck var tc = new TypecheckingContext(null); impl.Typecheck(tc); /////////////////// // Generate the VC /////////////////// // block -> bool variable blockToControlVar = new Dictionary<Block, VCExprVar>(); foreach (var b in impl.Blocks) blockToControlVar.Add(b, gen.Variable(b.Label + "_holds", Bpl.Type.Bool)); vcexpr = VCExpressionGenerator.True; foreach (var b in impl.Blocks) { // conjoin all assume cmds VCExpr c = VCExpressionGenerator.True; foreach (var cmd in b.Cmds) { var acmd = cmd as AssumeCmd; if (acmd == null) { Debug.Assert(cmd is AssertCmd && (cmd as AssertCmd).Expr is LiteralExpr && ((cmd as AssertCmd).Expr as LiteralExpr).IsTrue); continue; } var expr = translator.Translate(acmd.Expr); c = gen.AndSimp(c, expr); } // block implies a disjunction of successors Debug.Assert(!(b.TransferCmd is ReturnExprCmd), "Not supported"); var gc = b.TransferCmd as GotoCmd; if (gc != null) { VCExpr succ = VCExpressionGenerator.False; foreach (var sb in gc.labelTargets) succ = gen.OrSimp(succ, blockToControlVar[sb]); c = gen.AndSimp(c, succ); } else { // nothing to do } vcexpr = gen.AndSimp(vcexpr, gen.Eq(blockToControlVar[b], c)); } // assert start block vcexpr = gen.AndSimp(vcexpr, blockToControlVar[impl.Blocks[0]]); //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr); // Collect other information callSites = vcgen.CollectCallSites(impl); recordProcCallSites = vcgen.CollectRecordProcedureCallSites(impl); // record interface variables privateExprVars = new List<VCExprVar>(); foreach (Variable v in impl.LocVars) { privateExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.OutParams) { privateExprVars.Add(translator.LookupVariable(v)); } privateExprVars.AddRange(blockToControlVar.Values); interfaceExprVars = new List<VCExprVar>(); foreach (Variable v in program.GlobalVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in impl.InParams) { interfaceExprVars.Add(translator.LookupVariable(v)); } foreach (Variable v in outputVariables) { interfaceExprVars.Add(translator.LookupVariable(v)); } }
// 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); }
public static void CloseProver() { prover.Close(); CommandLineOptions.Clo.TheProverFactory.Close(); prover = null; }
public ConcurrentHoudini(int id, Program program, HoudiniSession.HoudiniStatistics stats, string cexTraceFile = "houdiniCexTrace.bpl") { Contract.Assert(id >= 0); this.id = id; this.program = program; this.cexTraceFile = cexTraceFile; if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Collecting existential constants..."); } this.houdiniConstants = CollectExistentialConstants(); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Building call graph..."); } this.callGraph = Program.BuildCallGraph(program); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Number of implementations = {0}", callGraph.Nodes.Count); } if (CommandLineOptions.Clo.HoudiniUseCrossDependencies) { if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Computing procedure cross dependencies ..."); } this.crossDependencies = new CrossDependencies(this.houdiniConstants); this.crossDependencies.Visit(program); } Inline(); this.vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>()); this.proverInterface = ProverInterface.CreateProver(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime, id); vcgenFailures = new HashSet <Implementation>(); Dictionary <Implementation, HoudiniSession> houdiniSessions = new Dictionary <Implementation, HoudiniSession>(); if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Beginning VC generation for Houdini..."); } foreach (Implementation impl in callGraph.Nodes) { try { if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Generating VC for {0}", impl.Name); } HoudiniSession session = new HoudiniSession(this, vcgen, proverInterface, program, impl, stats, taskID: id); houdiniSessions.Add(impl, session); } catch (VCGenException) { if (CommandLineOptions.Clo.Trace) { Console.WriteLine("VC generation failed"); } vcgenFailures.Add(impl); } } this.houdiniSessions = new ReadOnlyDictionary <Implementation, HoudiniSession>(houdiniSessions); if (CommandLineOptions.Clo.ExplainHoudini) { // Print results of ExplainHoudini to a dotty file explainHoudiniDottyFile = new StreamWriter("explainHoudini.dot"); explainHoudiniDottyFile.WriteLine("digraph explainHoudini {"); foreach (var constant in houdiniConstants) { explainHoudiniDottyFile.WriteLine("{0} [ label = \"{0}\" color=black ];", constant.Name); } explainHoudiniDottyFile.WriteLine("TimeOut [label = \"TimeOut\" color=red ];"); } }
protected override bool UpdateAssignmentWorkList(ProverInterface.Outcome outcome, List<Counterexample> errors) { Contract.Assume(currentHoudiniState.Implementation != null); bool dequeue = true; switch (outcome) { case ProverInterface.Outcome.Valid: //yeah, dequeue break; case ProverInterface.Outcome.Invalid: Contract.Assume(errors != null); foreach (Counterexample error in errors) { RefutedAnnotation refutedAnnotation = ExtractRefutedAnnotation(error); // some candidate annotation removed if (refutedAnnotation != null) { refutedSharedAnnotations.TryAdd(refutedAnnotation.Constant.Name, refutedAnnotation); AddRelatedToWorkList(refutedAnnotation); UpdateAssignment(refutedAnnotation); dequeue = false; #region Extra debugging output if (CommandLineOptions.Clo.Trace) { using (var cexWriter = new System.IO.StreamWriter(cexTraceFile, true)) { cexWriter.WriteLine("Counter example for " + refutedAnnotation.Constant); cexWriter.Write(error.ToString()); cexWriter.WriteLine(); using (var writer = new Microsoft.Boogie.TokenTextWriter(cexWriter)) foreach (Microsoft.Boogie.Block blk in error.Trace) blk.Emit(writer, 15); //cexWriter.WriteLine(); } } #endregion } } if (ExchangeRefutedAnnotations()) dequeue = false; break; default: if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Timeout/Spaceout while verifying " + currentHoudiniState.Implementation.Name); } HoudiniSession houdiniSession; houdiniSessions.TryGetValue(currentHoudiniState.Implementation, out houdiniSession); foreach (Variable v in houdiniSession.houdiniAssertConstants) { if (CommandLineOptions.Clo.Trace) { Console.WriteLine("Removing " + v); } currentHoudiniState.Assignment.Remove(v); currentHoudiniState.Assignment.Add(v, false); this.NotifyConstant(v.Name); } currentHoudiniState.addToBlackList(currentHoudiniState.Implementation.Name); break; } return dequeue; }