///////////////////////////////////////////////////////////////////////////////// /// <summary> /// Constructor. Initialize a checker with the program and log file. /// Optionally, use prover context provided by parameter "ctx". /// </summary> public Checker(VC.ConditionGeneration vcgen, Program prog, string /*?*/ logFilePath, bool appendLogFile, int timeout, ProverContext ctx = null) { Contract.Requires(vcgen != null); Contract.Requires(prog != null); this.timeout = timeout; this.Program = prog; ProverOptions options = cce.NonNull(CommandLineOptions.Clo.TheProverFactory).BlankProverOptions(); if (logFilePath != null) { options.LogFilename = logFilePath; if (appendLogFile) { options.AppendLogFile = appendLogFile; } } if (timeout > 0) { options.TimeLimit = timeout * 1000; } options.Parse(CommandLineOptions.Clo.ProverOptions); ContextCacheKey key = new ContextCacheKey(prog); ProverInterface prover; if (vcgen.CheckerCommonState == null) { vcgen.CheckerCommonState = new Dictionary <ContextCacheKey, ProverContext>(); } IDictionary <ContextCacheKey, ProverContext> /*!>!*/ cachedContexts = (IDictionary <ContextCacheKey, ProverContext /*!*/>)vcgen.CheckerCommonState; if (ctx == null && cachedContexts.TryGetValue(key, out ctx)) { ctx = (ProverContext)cce.NonNull(ctx).Clone(); prover = (ProverInterface) CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx); } else { if (ctx == null) { ctx = (ProverContext)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options); } Setup(prog, ctx); // we first generate the prover and then store a clone of the // context in the cache, so that the prover can setup stuff in // the context to be cached prover = (ProverInterface) CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx); cachedContexts.Add(key, cce.NonNull((ProverContext)ctx.Clone())); } this.thmProver = prover; this.gen = prover.VCExprGen; }
public override void OnModel(IList<string>/*!>!*/ labels, Model model, ProverInterface.Outcome proverOutcome) { // TODO: it would be better to check which reachability variables are actually set to one! List<Block> traceNodes = new List<Block>(); List<AssertCmd> assertNodes = new List<AssertCmd>(); foreach (string s in labels) { Contract.Assert(s != null); Absy node = Label2Absy(s); if (node is Block) { Block b = (Block)node; traceNodes.Add(b); //Console.Write("{0}, ", b.Label); } } m_CurrentTrace.AddRange(traceNodes); }
public ICEHoudini(Program program, string defaultDomainName, string filename) { this.program = program; this.impl2VC = new Dictionary<string, VCExpr>(); this.impl2FuncCalls = new Dictionary<string, List<Tuple<string, Function, NAryExpr>>>(); this.existentialFunctions = new Dictionary<string, Function>(); this.name2Impl = new Dictionary<string, Implementation>(); this.impl2functionsAsserted = new Dictionary<string, HashSet<string>>(); this.impl2functionsAssumed = new Dictionary<string, HashSet<string>>(); this.function2implAsserted = new Dictionary<string, HashSet<string>>(); this.function2implAssumed = new Dictionary<string, HashSet<string>>(); this.impl2ErrorHandler = new Dictionary<string, Tuple<ProverInterface.ErrorHandler, ICEHoudiniCounterexampleCollector>>(); this.constant2FuncCall = new Dictionary<string, NAryExpr>(); // Find the existential functions foreach (var func in program.TopLevelDeclarations.OfType<Function>() .Where(f => QKeyValue.FindBoolAttribute(f.Attributes, "existential"))) existentialFunctions.Add(func.Name, func); // extract the constants in the program to determine the range for the template domain elements var extractConstants = new ExtractConstants(); extractConstants.Visit(program); constantRange = extractConstants.maxConst + 1; TemplateParser.DSInit(); this.function2Value = new Dictionary<string, ICEDomain>(); counterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>(); existentialFunctions.Keys.Iter(f => function2implAssumed.Add(f, new HashSet<string>())); existentialFunctions.Keys.Iter(f => function2implAsserted.Add(f, new HashSet<string>())); // type check existentialFunctions.Values.Iter(func => { if (func.OutParams.Count != 1 || !func.OutParams[0].TypedIdent.Type.IsBool) throw new ICEHoudiniInternalError(string.Format("Existential function {0} must return bool", func.Name)); if(func.Body != null) throw new ICEHoudiniInternalError(string.Format("Existential function {0} should not have a body", func.Name)); func.InParams.Iter(v => { if (!v.TypedIdent.Type.IsInt) { throw new ICEHoudiniInternalError("TypeError: Illegal tpe, expecting int"); } }); }); //if (CommandLineOptions.Clo.ProverKillTime > 0) // CommandLineOptions.Clo.ProverOptions.Add(string.Format("TIME_LIMIT={0}", CommandLineOptions.Clo.ProverKillTime)); Inline(); this.vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List<Checker>()); this.prover = ProverInterface.CreateProver(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime); this.proverTime = TimeSpan.Zero; this.numProverQueries = 0; this.z3LearnerTime = TimeSpan.Zero; this.numZ3LearnerQueries = 0; this.numPosExamples = 0; this.numNegCounterExamples = 0; this.numImplications = 0; #if C5 this.C5index = 0; this.C5implications = new List<Tuple<int, int>>(); this.C5samplePointToClassAttr = new Dictionary<dataPoint, int>(); this.C5samplePointToIndex = new Dictionary<dataPoint, int>(); this.C5repeatedPoints = 0; #endif this.filename = filename; var impls = program.TopLevelDeclarations.OfType<Implementation>().Where( impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification); /* program.TopLevelDeclarations.OfType<Implementation>() .Where(impl => !impl.SkipVerification) .Iter(impl => name2Impl.Add(impl.Name, impl)); */ impls.Iter(impl => name2Impl.Add(impl.Name, impl)); // Let's do VC Gen (and also build dependencies) name2Impl.Values.Iter(GenVC); }
public bool CheckReachvar(List<Variable> lv,Dictionary<Expr, int> finalreachvars, int k, int l, bool usenew , out ProverInterface.Outcome outcome) { Contract.Requires(lv != null); VCExpr vc = VCExpressionGenerator.False; if (usenew ) { foreach (Variable v in lv) { vc = m_Checker.VCExprGen.Or( m_Checker.VCExprGen.Neq( m_Checker.VCExprGen.Integer(BigNum.ZERO), m_Checker.TheoremProver.Context.BoogieExprTranslator.LookupVariable(v)), vc); } //Console.WriteLine("TPQuery k={0}, l={1}, |Sp|={2}", k, l, finalreachvars.Count); VCExpr vc21 = m_Checker.VCExprGen.Integer(BigNum.ZERO); // Ask: is the necessary or can we use the same instance term in two inequalities? VCExpr vc22 = m_Checker.VCExprGen.Integer(BigNum.ZERO); foreach (KeyValuePair<Expr, int> kvp in finalreachvars) { vc21 = m_Checker.VCExprGen.Add(vc21, m_Checker.TheoremProver.Context.BoogieExprTranslator.Translate(kvp.Key)); vc22 = m_Checker.VCExprGen.Add(vc22, m_Checker.TheoremProver.Context.BoogieExprTranslator.Translate(kvp.Key)); } VCExpr post = m_Checker.VCExprGen.Gt(m_Checker.VCExprGen.Integer(BigNum.FromInt(l)), vc21); if (k != -1) { post = m_Checker.VCExprGen.Or( post, m_Checker.VCExprGen.Gt(vc22, m_Checker.VCExprGen.Integer(BigNum.FromInt(k))) ); } vc = (m_Checker.VCExprGen.Or(vc, (post) )); } else { foreach (Variable v in lv) { vc = m_Checker.VCExprGen.Or( m_Checker.VCExprGen.Eq( m_Checker.VCExprGen.Integer(BigNum.ONE), m_Checker.TheoremProver.Context.BoogieExprTranslator.LookupVariable(v)), vc); } Contract.Assert(vc != null); // Add the desired outcome of the reachability variables foreach (KeyValuePair<Expr, int> kvp in finalreachvars) { vc = m_Checker.VCExprGen.Or( m_Checker.VCExprGen.Neq( m_Checker.VCExprGen.Integer(BigNum.FromInt(kvp.Value)), m_Checker.TheoremProver.Context.BoogieExprTranslator.Translate(kvp.Key)), vc); } } // Todo: Check if vc is trivial true or false outcome = ProverInterface.Outcome.Undetermined; Contract.Assert(m_ErrorHandler != null); try { m_Checker.BeginCheck(lv[0].Name, vc, m_ErrorHandler); m_Checker.ProverTask.Wait(); outcome = m_Checker.ReadOutcome(); } catch (UnexpectedProverOutputException e) { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("Prover is unable to check {0}! Reason:", lv[0].Name); Console.WriteLine(e.ToString()); } return false; } finally { m_Checker.GoBackToIdle(); } return true; }
/* - Checking a label means to ask the prover if |= ( rvar=false -> vc ) holds. - outcome is set to Outcome.Invalid if the Block denoted by reachvar is doomed. - returns false if the theorem prover throws an exception, otherwise true. */ public bool CheckLabel(List<Variable> lv,Dictionary<Expr, int> finalreachvars, out ProverInterface.Outcome outcome) { Contract.Requires(lv != null); outcome = ProverInterface.Outcome.Undetermined; DEBUG_ProverTime.Reset(); DEBUG_ProverTime.Start(); if (m_Evc.CheckReachvar(lv,finalreachvars,m_Order.MaxBlocks,m_Order.MinBlocks,m_Order.HACK_NewCheck, out outcome) ) { DEBUG_ProverTime.Stop(); if (!m_Order.SetCurrentResult(lv, outcome, m_ErrHandler)) { outcome = ProverInterface.Outcome.Undetermined; } return true; } else { DEBUG_ProverTime.Stop(); Console.WriteLine(outcome); m_Order.SetCurrentResult(lv, ProverInterface.Outcome.Undetermined, m_ErrHandler); return false; } }
//bool realErrorEncountered; //bool newSamplesAdded; // tracks whether new ICE samples added in a round or not? public MLHoudini(Program program, string config, string filename) { this.program = program; this.impl2VC = new Dictionary<string, VCExpr>(); this.impl2FuncCalls = new Dictionary<string, List<Tuple<string, Function, NAryExpr>>>(); this.existentialFunctions = new Dictionary<string, Function>(); this.name2Impl = new Dictionary<string, Implementation>(); this.impl2functionsAsserted = new Dictionary<string, HashSet<string>>(); this.impl2functionsAssumed = new Dictionary<string, HashSet<string>>(); this.function2implAsserted = new Dictionary<string, HashSet<string>>(); this.function2implAssumed = new Dictionary<string, HashSet<string>>(); this.impl2ErrorHandler = new Dictionary<string, Tuple<ProverInterface.ErrorHandler, MLHoudiniCounterexampleCollector>>(); this.constant2FuncCall = new Dictionary<string, NAryExpr>(); // Find the existential functions foreach (var func in program.TopLevelDeclarations.OfType<Function>() .Where(f => QKeyValue.FindBoolAttribute(f.Attributes, "existential"))) existentialFunctions.Add(func.Name, func); // extract the constants in the program to determine the range for the template domain elements this.function2Value = new Dictionary<string, MLICEDomain>(); foreach (var func in existentialFunctions.Values) { function2Value[func.Name] = new C5Domain(func.InParams); } counterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>(); implicationCounterExamples = new HashSet<Tuple<List<Tuple<string, List<Model.Element>>>, List<Tuple<string, List<Model.Element>>>>>(); bounds4cex = new List<int>(); this.filename = filename; this.config = config; // config = alg1, alg2, alg3, alg4, smallcex_alg1, smallcex_alg2, ... #if false int posOfUnderScore = this.config.IndexOf("_", 0); if (posOfUnderScore != -1) { // The teacher has to preferentially return small counter-examples Debug.Assert(posOfUnderScore == 8); //bounds4cex.Add(50); bounds4cex.Add(2); bounds4cex.Add(5); bounds4cex.Add(10); this.config = this.config.Substring(posOfUnderScore + 1); } // else this.config remains unchanged #else bounds4cex.Add(2); bounds4cex.Add(5); bounds4cex.Add(10); #endif existentialFunctions.Keys.Iter(f => function2implAssumed.Add(f, new HashSet<string>())); existentialFunctions.Keys.Iter(f => function2implAsserted.Add(f, new HashSet<string>())); // type check existentialFunctions.Values.Iter(func => { if (func.OutParams.Count != 1 || !func.OutParams[0].TypedIdent.Type.IsBool) throw new MLHoudiniInternalError(string.Format("Existential function {0} must return bool", func.Name)); if (func.Body != null) throw new MLHoudiniInternalError(string.Format("Existential function {0} should not have a body", func.Name)); func.InParams.Iter(v => { if (!v.TypedIdent.Type.IsInt && !v.TypedIdent.Type.IsBool) { throw new MLHoudiniInternalError("TypeError: Illegal tpe, expecting int or bool"); } }); }); Inline(); this.vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List<Checker>()); this.prover = ProverInterface.CreateProver(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, CommandLineOptions.Clo.ProverKillTime); this.proverTime = TimeSpan.Zero; this.numProverQueries = 0; this.c5LearnerTime = TimeSpan.Zero; this.c5LearnerQueries = 0; this.totaltime = TimeSpan.Zero; this.jsontime = TimeSpan.Zero; this.numPosExamples = 0; this.numNegCounterExamples = 0; this.numImplications = 0; this.total_falsefalse_implications = 0; this.total_falsetrue_implications = 0; this.total_truetrue_implications = 0; this.totalTreeSize = 0; this.last_falsefalse_implications = 0; this.last_falsetrue_implications = 0; this.last_truetrue_implications = 0; this.lastTreeSize = 0; //this.posNegCexAdded = false; #if C5 this.c5DataPointsIndex = 0; this.c5samplePointToClassAttr = new Dictionary<dataPoint, int>(); this.c5samplePointToIndex = new Dictionary<dataPoint, int>(); this.c5implications = new List<Tuple<int, int>>(); #endif var impls = program.TopLevelDeclarations.OfType<Implementation>().Where( impl => impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification); /* program.TopLevelDeclarations.OfType<Implementation>() .Where(impl => !impl.SkipVerification) .Iter(impl => name2Impl.Add(impl.Name, impl)); */ impls.Iter(impl => name2Impl.Add(impl.Name, impl)); // Call setupC5 only after the filename has been initialized! setupC5(); // Let's do VC Gen (and also build dependencies) name2Impl.Values.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.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.Undetermined) break; unsatisfiedSoftAssumptions2.Iter(i => reason.Remove(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); } } while (false); if (outcome == ProverInterface.Outcome.TimeOut || outcome == ProverInterface.Outcome.OutOfMemory || 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 BeginCheck(string descriptiveName, VCExpr vc, ProverInterface.ErrorHandler handler) { Contract.Requires(descriptiveName != null); Contract.Requires(vc != null); Contract.Requires(handler != null); Contract.Requires(IsReady); status = CheckerStatus.Busy; hasOutput = false; outputExn = null; this.handler = handler; thmProver.Reset(gen); SetTimeout(); proverStart = DateTime.UtcNow; thmProver.BeginCheck(descriptiveName, vc, handler); // gen.ClearSharedFormulas(); PR: don't know yet what to do with this guy ProverTask = Task.Factory.StartNew(() => { WaitForOutput(null); }, TaskCreationOptions.LongRunning); }
// This method is called to inform about the prover outcome for the previous GetNextBlock call. override public bool SetCurrentResult(List<Variable> reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) { this.__DEBUG_BlocksChecked++; // outcome==Valid means that there is no feasible execution for the current block/path (i.e., might be doomed) if (outcome == ProverInterface.Outcome.Valid && m_Current != null) { m_doomedBlocks.Add(m_Current); } else if (outcome == ProverInterface.Outcome.Invalid) { List<Block> errortrace = m_GetErrorTraceFromCE(cb); foreach (Block b in errortrace) { if (m_Blocks.Contains(b)) { m_Blocks.Remove(b); } } cb.TraceNodes.Clear(); } return true; }
// This method is called to inform about the prover outcome for the previous GetNextBlock call. override public bool SetCurrentResult(List<Variable> reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) { this.__DEBUG_BlocksChecked++; // outcome==Valid means that there is no feasible execution for the current block/path (i.e., might be doomed) if (outcome == ProverInterface.Outcome.Valid && m_Current <= m_Blocks.Count) { m_doomedBlocks.Add(m_Blocks[m_Current - 1]); } if (__DEBUGOUT) Console.WriteLine("K := {0,3} , out {1,8}, time {2,12}", MaxBlocks, outcome, sw.ElapsedTicks); sw.Stop(); sw.Reset(); return true; }
// This method is called to inform about the prover outcome for the previous GetNextBlock call. override public bool SetCurrentResult(List<Variable> reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) { this.__DEBUG_BlocksChecked++; // outcome==Valid means that there is no feasible execution for the current block/path (i.e., might be doomed) if (outcome == ProverInterface.Outcome.Valid && m_Current <= m_Blocks.Count) { List<Block> lb = new List<Block>(); lb.Add(m_Blocks[m_Current - 1]); DetectedBlock.Add(lb); } return true; }
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 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("Time taken = " + queryTime); } errors = collector.examples; return proverOutcome; }
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++; }
bool ReCheckImpl(Variable reachvar, Implementation impl, VerifierCallback callback, out ProverInterface.Outcome outcome) { Contract.Requires(reachvar != null); Contract.Requires(impl != null); Contract.Requires(callback != null); Checker checker = FindCheckerFor(impl, 1000); Contract.Assert(checker != null); DoomCheck dc = new DoomCheck(impl, this.exitBlock, checker, m_UncheckableBlocks); dc.ErrorHandler = new DoomErrorHandler(dc.Label2Absy, callback); outcome = ProverInterface.Outcome.Undetermined; List<Variable> rv = new List<Variable>(); rv.Add(reachvar); if (!dc.CheckLabel(rv,null, out outcome)) { checker.Close(); return false; } checker.Close(); return true; }
override public bool SetCurrentResult(List<Variable> reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb) { this.__DEBUG_BlocksChecked++; // Valid means infeasible... int oldk = MaxBlocks; int oldl = MinBlocks; int oldsize = m_Uncheckedlocks.Count; if (outcome == ProverInterface.Outcome.Valid) { this.__DEBUG_InfeasibleTraces++; if (MaxBlocks == 1) { m_NoMoreMoves = true; } else { MaxBlocks /= 2; } } else if (outcome == ProverInterface.Outcome.Invalid) { this.__DEBUG_TracesChecked++; List<Block> errortrace = m_GetErrorTraceFromCE(cb); foreach (Block b in errortrace) { if (m_Uncheckedlocks.Contains(b)) { m_Uncheckedlocks.Remove(b); } } cb.TraceNodes.Clear(); int k = m_BlockH.GetMaxK(m_Uncheckedlocks); MaxBlocks = (k > MaxBlocks) ? MaxBlocks : k; } else { m_NoMoreMoves = true; m_Uncheckedlocks.Clear(); } if (__DEBUGOUT) Console.WriteLine("K := {0,3}, L := {1,3}, deltaSp {2,3}, out {3,8}, time {4,8}", oldk, oldl, (oldsize - m_Uncheckedlocks.Count), outcome, sw.ElapsedTicks); sw.Stop(); sw.Reset(); return true; }
// This method is called to inform about the prover outcome for the previous GetNextBlock call. abstract public bool SetCurrentResult(List<Variable> reachvar, ProverInterface.Outcome outcome, DoomErrorHandler cb);
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// Constructor. Initialize a checker with the program and log file. /// Optionally, use prover context provided by parameter "ctx". /// </summary> public Checker(VC.ConditionGeneration vcgen, Program prog, string/*?*/ logFilePath, bool appendLogFile, int timeout, ProverContext ctx = null) { Contract.Requires(vcgen != null); Contract.Requires(prog != null); this.timeout = timeout; this.Program = prog; ProverOptions options = cce.NonNull(CommandLineOptions.Clo.TheProverFactory).BlankProverOptions(); if (logFilePath != null) { options.LogFilename = logFilePath; if (appendLogFile) options.AppendLogFile = appendLogFile; } if (timeout > 0) { options.TimeLimit = timeout * 1000; } options.Parse(CommandLineOptions.Clo.ProverOptions); ContextCacheKey key = new ContextCacheKey(prog); ProverInterface prover; if (vcgen.CheckerCommonState == null) { vcgen.CheckerCommonState = new Dictionary<ContextCacheKey, ProverContext>(); } IDictionary<ContextCacheKey, ProverContext>/*!>!*/ cachedContexts = (IDictionary<ContextCacheKey, ProverContext/*!*/>)vcgen.CheckerCommonState; if (ctx == null && cachedContexts.TryGetValue(key, out ctx)) { ctx = (ProverContext)cce.NonNull(ctx).Clone(); prover = (ProverInterface) CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx); } else { if (ctx == null) ctx = (ProverContext)CommandLineOptions.Clo.TheProverFactory.NewProverContext(options); Setup(prog, ctx); // we first generate the prover and then store a clone of the // context in the cache, so that the prover can setup stuff in // the context to be cached prover = (ProverInterface) CommandLineOptions.Clo.TheProverFactory.SpawnProver(options, ctx); cachedContexts.Add(key, cce.NonNull((ProverContext)ctx.Clone())); } this.thmProver = prover; this.gen = prover.VCExprGen; }
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); } }