public Counterexample ToCounterexample(ProverContext context) { Contract.Requires(context != null); Contract.Ensures(Contract.Result <Counterexample>() != null); List <Block> trace = new List <Block>(); foreach (Block b in blocks) { Contract.Assert(b != null); trace.Add(b); } foreach (Block b in blocks) { Contract.Assert(b != null); foreach (Cmd c in b.Cmds) { Contract.Assert(c != null); if (c is AssertCmd) { return(VCGen.AssertCmdToCounterexample((AssertCmd)c, cce.NonNull(b.TransferCmd), trace, null, null, null, context)); } } } Contract.Assume(false); throw new cce.UnreachableException(); }
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 Split(List <Block /*!*/> /*!*/ blocks, Dictionary <TransferCmd, ReturnCmd> /*!*/ gotoCmdOrigins, VCGen /*!*/ par, Implementation /*!*/ impl) { Contract.Requires(cce.NonNullElements(blocks)); Contract.Requires(gotoCmdOrigins != null); Contract.Requires(par != null); Contract.Requires(impl != null); this.blocks = blocks; this.gotoCmdOrigins = gotoCmdOrigins; this.parent = par; this.impl = impl; Interlocked.Increment(ref currentId); }
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); } }
List <Cmd> SliceCmds(Block b) { Contract.Requires(b != null); Contract.Ensures(Contract.Result <List <Cmd> >() != null); List <Cmd> seq = b.Cmds; Contract.Assert(seq != null); if (!doingSlice && !ShouldAssumize(b)) { return(seq); } List <Cmd> res = new List <Cmd>(); foreach (Cmd c in seq) { Contract.Assert(c != null); AssertCmd a = c as AssertCmd; Cmd theNewCmd = c; bool swap = false; if (a != null) { if (doingSlice) { double cost = AssertionCost(a); bool first = (sliceLimit - cost) >= 0 || sliceInitialLimit == sliceLimit; sliceLimit -= cost; swap = slicePos == first; } else if (assertToAssume) { swap = true; } else { Contract.Assert(false); throw new cce.UnreachableException(); } if (swap) { theNewCmd = VCGen.AssertTurnedIntoAssume(a); } } res.Add(theNewCmd); } return(res); }
/// <summary> /// Gets the errors and associated metadata after verifying the program. /// </summary> /// <returns>The metadata of the errors.</returns> public IEnumerable <RepairableError> GetErrors() { List <Error> errors = new List <Error>(); VCGen gen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>()); foreach (Declaration declaration in program.TopLevelDeclarations) { if (declaration is Implementation) { Implementation implementation = declaration as Implementation; List <Counterexample> examples; ConditionGeneration.Outcome outcome = gen.VerifyImplementation(implementation, out examples); if (outcome == ConditionGeneration.Outcome.Errors) { foreach (Counterexample example in examples) { errors.AddRange(GenerateErrors(example, implementation)); } } } } gen.Close(); // there are no repairable errors that have a variable assigned to them if (!errors.Any(x => x is RepairableError && (x as RepairableError).Barriers.Any())) { if (errors.Any(x => x.CounterExample is AssertCounterexample)) { throw new AssertionException("Assertions do not hold!"); } if (errors.Any(x => !(x is RepairableError))) { throw new NonBarrierException("The program cannot be repaired since it has errors besides race and divergence errors!"); } if (errors.Any(x => x is RepairableError)) { throw new RepairException("Encountered a counterexample without any barrier assignments!"); } } return(errors.Where(x => x is RepairableError && (x as RepairableError).Barriers.Any()) .Select(x => x as RepairableError).ToList()); }
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); }
private static ConditionGeneration CreateVCGen(Program program, List<Checker> checkers) { ConditionGeneration vcgen = null; if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Doomed) { vcgen = new DCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers); } else if (CommandLineOptions.Clo.FixedPointEngine != null) { vcgen = new FixedpointVC(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers); } else if (CommandLineOptions.Clo.StratifiedInlining > 0) { vcgen = new StratifiedVCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers); } else if (CommandLineOptions.Clo.SecureVcGen != null) { vcgen = new SecureVCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers); } else { vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, checkers); } return vcgen; }
public static List <Split /*!*/> FindManualSplits(Implementation /*!*/ impl, Dictionary <TransferCmd, ReturnCmd> /*!*/ gotoCmdOrigins, VCGen /*!*/ par) { Contract.Requires(impl != null); Contract.Ensures(Contract.Result <List <Split> >() == null || cce.NonNullElements(Contract.Result <List <Split> >())); var splitPoints = new Dictionary <Block, int>(); foreach (var b in impl.Blocks) { foreach (Cmd c in b.Cmds) { var p = c as PredicateCmd; if (p != null && QKeyValue.FindBoolAttribute(p.Attributes, "split_here")) { int count; splitPoints.TryGetValue(b, out count); splitPoints[b] = count + 1; } } } if (splitPoints.Count() == 0) { // No manual split points here return(null); } List <Split> splits = new List <Split>(); Block entryPoint = impl.Blocks[0]; var newEntryBlocks = DoManualSplit(impl.Blocks, entryPoint, -1, splitPoints.Keys.Contains(entryPoint), splitPoints.Keys); splits.Add(new Split(newEntryBlocks, gotoCmdOrigins, par, impl)); // REVIEW: Does gotoCmdOrigins need to be changed at all? foreach (KeyValuePair <Block, int> pair in splitPoints) { for (int i = 0; i < pair.Value; i++) { bool blockInternalSplit = i < pair.Value - 1; // There's at least one more split, after this one, in the current block var newBlocks = DoManualSplit(impl.Blocks, pair.Key, i, blockInternalSplit, splitPoints.Keys); Split s = new Split(newBlocks, gotoCmdOrigins, par, impl); // REVIEW: Does gotoCmdOrigins need to be changed at all? splits.Add(s); } } return(splits); }
/// <summary> /// Starting from the 0-index "split_here" annotation in begin, verifies until it reaches a subsequent "split_here" annotation /// Returns a list of blocks where all code not verified has asserts converted into assumes /// </summary> /// <param name="blocks">Implementation's collection of blocks</param> /// <param name="begin">Block containing the first split_here from which to start verifying</param> /// <param name="beginSplitId">0-based ID of the "split_here" annotation within begin at which to start verifying</param> /// <param name="blockInternalSplit">True if the entire split is contained within block begin</param> /// <param name="endPoints">Set of all blocks containing a "split_here" annotation</param> /// <returns></returns> // Note: Current implementation may over report errors. // For example, if the control flow graph is a diamond (e.g., A -> B, C, B->D, C->D), // and there is a split in B and an error in D, then D will be verified twice and hence report the error twice. // Best solution may be to memoize blocks that have been fully verified and be sure not to verify them again private static List <Block> DoManualSplit(List <Block> blocks, Block begin, int beginSplitId, bool blockInternalSplit, IEnumerable <Block> endPoints) { // Compute the set of blocks reachable from begin but not included in endPoints. These will be verified in their entirety. var blocksToVerifyEntirely = new HashSet <Block>(); var reachableEndPoints = new HashSet <Block>(); // Reachable end points will be verified up to their first split point var todo = new Stack <Block>(); todo.Push(begin); while (todo.Count > 0) { var currentBlock = todo.Pop(); if (blocksToVerifyEntirely.Contains(currentBlock)) { continue; } blocksToVerifyEntirely.Add(currentBlock); var exit = currentBlock.TransferCmd as GotoCmd; if (exit != null) { foreach (Block targetBlock in exit.labelTargets) { if (!endPoints.Contains(targetBlock)) { todo.Push(targetBlock); } else { reachableEndPoints.Add(targetBlock); } } } } blocksToVerifyEntirely.Remove(begin); // Convert assumes to asserts in "unreachable" blocks, including portions of blocks containing "split_here" var newBlocks = new List <Block>(blocks.Count()); // Copies of the original blocks var duplicator = new Duplicator(); var oldToNewBlockMap = new Dictionary <Block, Block>(blocks.Count()); // Maps original blocks to their new copies in newBlocks foreach (var currentBlock in blocks) { var newBlock = (Block)duplicator.VisitBlock(currentBlock); oldToNewBlockMap[currentBlock] = newBlock; newBlocks.Add(newBlock); if (!blockInternalSplit && blocksToVerifyEntirely.Contains(currentBlock)) { continue; // All reachable blocks must be checked in their entirety, so don't change anything } // Otherwise, we only verify a portion of the current block, so we'll need to look at each of its commands // !verify -> convert assert to assume var verify = (currentBlock == begin && beginSplitId == -1 ) || // -1 tells us to start verifying from the very beginning (i.e., there is no split in the begin block) ( reachableEndPoints .Contains(currentBlock) && // This endpoint is reachable from begin, so we verify until we hit the first split point !blockInternalSplit); // Don't bother verifying if all of the splitting is within the begin block var newCmds = new List <Cmd>(); var splitHereCount = 0; foreach (Cmd c in currentBlock.Cmds) { var p = c as PredicateCmd; if (p != null && QKeyValue.FindBoolAttribute(p.Attributes, "split_here")) { if (currentBlock == begin) { // Verify everything between the beginSplitId we were given and the next split if (splitHereCount == beginSplitId) { verify = true; } else if (splitHereCount == beginSplitId + 1) { verify = false; } } else { // We're in an endpoint so we stop verifying as soon as we hit a "split_here" verify = false; } splitHereCount++; } var asrt = c as AssertCmd; if (verify || asrt == null) { newCmds.Add(c); } else { newCmds.Add(VCGen.AssertTurnedIntoAssume(asrt)); } } newBlock.Cmds = newCmds; } // Patch the edges between the new blocks foreach (var oldBlock in blocks) { if (oldBlock.TransferCmd is ReturnCmd) { continue; } var gotoCmd = (GotoCmd)oldBlock.TransferCmd; var newLabelTargets = new List <Block>(gotoCmd.labelTargets.Count()); var newLabelNames = new List <string>(gotoCmd.labelTargets.Count()); foreach (var target in gotoCmd.labelTargets) { newLabelTargets.Add(oldToNewBlockMap[target]); newLabelNames.Add(oldToNewBlockMap[target].Label); } oldToNewBlockMap[oldBlock].TransferCmd = new GotoCmd(gotoCmd.tok, newLabelNames, newLabelTargets); } return(newBlocks); }
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); }
//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); }
private static ResultCounter VerifyProgram(Program program) { var counters = new ResultCounter(); ConditionGeneration vcgen = null; try { vcgen = new VCGen(program, CommandLineOptions.Clo.SimplifyLogFilePath, CommandLineOptions.Clo.SimplifyLogFileAppend, new List <Checker>()); } catch (ProverException e) { GVUtil.IO.ErrorWriteLine("Fatal Error: ProverException: {0}", e); return(ResultCounter.GetNewCounterWithInternalError()); } // operate on a stable copy, in case it gets updated while we're running var decls = program.TopLevelDeclarations.ToArray(); foreach (Declaration decl in decls) { Contract.Assert(decl != null); int prevAssertionCount = vcgen.CumulativeAssertionCount; Implementation impl = decl as Implementation; if (impl != null && CommandLineOptions.Clo.UserWantsToCheckRoutine(cce.NonNull(impl.Name)) && !impl.SkipVerification) { List <Counterexample /*!*/> /*?*/ errors; DateTime start = new DateTime(); // to please compiler's definite assignment rules if (CommandLineOptions.Clo.Trace) { start = DateTime.UtcNow; if (CommandLineOptions.Clo.Trace) { Console.WriteLine(); Console.WriteLine("Verifying {0} ...", impl.Name); } } VCGen.Outcome outcome; try { outcome = vcgen.VerifyImplementation(impl, out errors); } catch (VCGenException e) { GVUtil.IO.ReportBplError(impl, string.Format("Error BP5010: {0} Encountered in implementation {1}.", e.Message, impl.Name), true, true); errors = null; outcome = VCGen.Outcome.Inconclusive; } catch (UnexpectedProverOutputException upo) { GVUtil.IO.AdvisoryWriteLine("Advisory: {0} SKIPPED because of internal error: unexpected prover output: {1}", impl.Name, upo.Message); errors = null; outcome = VCGen.Outcome.Inconclusive; } string timeIndication = ""; DateTime end = DateTime.UtcNow; TimeSpan elapsed = end - start; if (CommandLineOptions.Clo.Trace) { int poCount = vcgen.CumulativeAssertionCount - prevAssertionCount; timeIndication = string.Format(" [{0:F3} s, {1} proof obligation{2}] ", elapsed.TotalSeconds, poCount, poCount == 1 ? "" : "s"); } KernelAnalyser.ProcessOutcome(program, impl.Name, outcome, errors, timeIndication, ref counters); if (outcome == VCGen.Outcome.Errors || CommandLineOptions.Clo.Trace) { Console.Out.Flush(); } } } vcgen.Close(); cce.NonNull(CommandLineOptions.Clo.TheProverFactory).Close(); GVUtil.IO.WriteTrailer(counters); return(counters); }
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); } }