public static bool Verify(Dafny.Program dafnyProgram, ResolverTagger resolver, string uniqueIdPrefix, string requestId, ErrorReporterDelegate er) { Dafny.Translator translator = new Dafny.Translator(dafnyProgram.reporter, er); translator.InsertChecksums = true; translator.UniqueIdPrefix = uniqueIdPrefix; Bpl.Program boogieProgram = translator.Translate(dafnyProgram); resolver.ReInitializeVerificationErrors(requestId, boogieProgram.Implementations); // TODO(wuestholz): Maybe we should use a fixed program ID to limit the memory overhead due to the program cache in Boogie. PipelineOutcome oc = BoogiePipeline(boogieProgram, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? uniqueIdPrefix : null, requestId, er); switch (oc) { case PipelineOutcome.Done: case PipelineOutcome.VerificationCompleted: // TODO: This would be the place to proceed to compile the program, if desired return(true); case PipelineOutcome.FatalError: default: return(false); } }
public virtual Program VisitProgram(Program node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Program>() != null); var decls = node.TopLevelDeclarations.ToList(); node.ClearTopLevelDeclarations(); node.AddTopLevelDeclarations(this.VisitDeclarationList(decls)); return node; }
public ProgramModification(Program program, string procedure) { this.program = DeepCloneProgram(program); this.procedure = procedure; }
public bool RunOn(Microsoft.Boogie.Program prog, PassInfo passInfo) { var toRemove = new HashSet <Declaration>(); var implToFalsify = new List <Implementation>(); var procToKeep = new HashSet <Declaration>(); // Check there is at least one entry point bool containsEntryPoint = false; foreach (var impl in prog.TopLevelDeclarations.OfType <Implementation>()) { if (IsEntryPoint(impl)) { containsEntryPoint = true; break; } } if (!containsEntryPoint) { throw new EntryPointNotFoundException(); } // Determine which implementation we want to remove and // which implementations we will need to keep foreach (var decl in prog.TopLevelDeclarations) { var declAsImplementation = decl as Implementation; if (declAsImplementation == null) { continue; } if (!IsEntryPoint(declAsImplementation)) { // We want to remove this implementation toRemove.Add(declAsImplementation); } else { implToFalsify.Add(declAsImplementation); Debug.Assert(declAsImplementation.Proc != null); procToKeep.Add(declAsImplementation.Proc); } } // Determine which procedures we should remove foreach (var decl in prog.TopLevelDeclarations) { var declAsProc = decl as Procedure; if (declAsProc == null) { continue; } if (!procToKeep.Contains(declAsProc)) { toRemove.Add(declAsProc); } } // Now remove the procedures and implementations we don't need foreach (var decl in toRemove) { prog.RemoveTopLevelDeclaration(decl); } // Now change entry point bodies to just contain an "assert false" foreach (var impl in implToFalsify) { // Remove any ensures. We probably aren't maintaining it // any more if we remove the body. impl.Proc.Ensures.Clear(); // The body won't be modifying anything so clear the modset impl.Proc.Modifies.Clear(); // Remove existing blocks impl.Blocks.Clear(); // Add block that asserts false and then returns var newBlock = new Block(Token.NoToken, "entry", new List <Cmd>() { new AssertCmd(Token.NoToken, Expr.False) }, new ReturnCmd(Token.NoToken)); impl.Blocks.Add(newBlock); } return((toRemove.Count + implToFalsify.Count) > 0); }
internal Program(Microsoft.Boogie.Program boogieProgram) : base(null) { this.boogieProgram = boogieProgram; }
public static Expr FunctionCallReresolvingApply(Substitution always, Substitution forOld, Expr expr, Program program) { Contract.Requires(always != null); Contract.Requires(forOld != null); Contract.Requires(expr != null); Contract.Ensures(Contract.Result<Expr>() != null); return (Expr)new FunctionCallReresolvingNormalSubstituter(program, always, forOld).Visit(expr); }
private bool Translate() { var translator = new Dafny.Translator(reporter) { InsertChecksums = true, UniqueIdPrefix = fname }; boogieProgram = translator.Translate(dafnyProgram); // FIXME how are translation errors reported? return true; }
static ExitValue ProcessFiles(IList <string /*!*/> /*!*/ dafnyFileNames, ReadOnlyCollection <string> otherFileNames, ErrorReporter reporter, bool lookForSnapshots = true, string programId = null) { Contract.Requires(cce.NonNullElements(dafnyFileNames)); ExitValue exitValue = ExitValue.VERIFIED; if (CommandLineOptions.Clo.VerifySeparately && 1 < dafnyFileNames.Count) { foreach (var f in dafnyFileNames) { string extension = Path.GetExtension(f); if (extension != null) { extension = extension.ToLower(); } if (extension != ".dfy") { continue; } Console.WriteLine(); Console.WriteLine("-------------------- {0} --------------------", f); var ev = ProcessFiles(new List <string> { f }, new List <string>().AsReadOnly(), reporter, lookForSnapshots, f); if (exitValue != ev && ev != ExitValue.VERIFIED) { exitValue = ev; } } return(exitValue); } if (0 <= CommandLineOptions.Clo.VerifySnapshots && lookForSnapshots) { var snapshotsByVersion = ExecutionEngine.LookForSnapshots(dafnyFileNames); foreach (var s in snapshotsByVersion) { var ev = ProcessFiles(new List <string>(s), new List <string>().AsReadOnly(), reporter, false, programId); if (exitValue != ev && ev != ExitValue.VERIFIED) { exitValue = ev; } } return(exitValue); } Dafny.Program dafnyProgram; Resolver r = null; string programName = dafnyFileNames.Count == 1 ? dafnyFileNames[0] : "the program"; //Same as ParseCheck, except for the instance of out Resolver string err = Dafny.Main.Parse(dafnyFileNames, programName, reporter, out dafnyProgram); if (err == null) { err = Dafny.Main.Resolve(dafnyProgram, reporter, out r); } if (err != null) { exitValue = ExitValue.DAFNY_ERROR; ExecutionEngine.printer.ErrorWriteLine(Console.Out, err); } else if (dafnyProgram != null && !CommandLineOptions.Clo.NoResolve && !CommandLineOptions.Clo.NoTypecheck && DafnyOptions.O.DafnyVerify) { Bpl.Program boogieProgram = Translate(dafnyProgram, r); PipelineStatistics stats; PipelineOutcome oc; var verified = Boogie(dafnyFileNames, boogieProgram, programId, out stats, out oc); Compile(dafnyFileNames[0], otherFileNames, dafnyProgram, oc, stats, verified); exitValue = verified ? ExitValue.VERIFIED : ExitValue.NOT_VERIFIED; } if (err == null && dafnyProgram != null && DafnyOptions.O.PrintStats) { Util.PrintStats(dafnyProgram); } if (err == null && dafnyProgram != null && DafnyOptions.O.PrintFunctionCallGraph) { Util.PrintFunctionCallGraph(dafnyProgram); } return(exitValue); }
public virtual Program VisitProgram(Program node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Program>() != null); node.TopLevelDeclarations = this.VisitDeclarationList(node.TopLevelDeclarations); return node; }
/// <summary> /// Returns two things: an object that determines the heap representation, /// and (optionally) an initial program that contains declarations needed /// for the heap representation. /// </summary> /// <param name="sink"> /// The heap might need to generate declarations so it needs access to the Sink. /// </param> /// <returns> /// false if and only if an error occurrs and the heap and/or program are not in a /// good state to be used. /// </returns> public abstract bool MakeHeap(Sink sink, out Heap heap, out Bpl.Program /*?*/ program);
internal static bool ParsePrelude(string initialPreludeText, object instance, out Bpl.Program /*?*/ prelude) { prelude = null; var flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; var type = instance.GetType(); FieldInfo /*?*/[] fields = type.GetFields(flags); RepresentationFor[] rfs = new RepresentationFor[fields.Length]; for (int i = 0; i < fields.Length; i++) { var field = fields[i]; object[] cas = field.GetCustomAttributes(typeof(RepresentationFor), false); if (cas == null || cas.Length == 0) // only look at fields that have the attribute { fields[i] = null; } else { foreach (var a in cas) // should be exactly one { RepresentationFor rf = a as RepresentationFor; if (rf != null) { rfs[i] = rf; break; } } } } #region Gather all of the Boogie declarations from the fields of this class var preludeText = new StringBuilder(initialPreludeText); for (int i = 0; i < fields.Length; i++) { var field = fields[i]; if (field == null) { continue; } preludeText.AppendLine(rfs[i].declaration); } #endregion #region Parse the declarations int errorCount = Bpl.Parser.Parse(preludeText.ToString(), "foo", out prelude); if (prelude == null || errorCount > 0) { prelude = null; return(false); } #endregion #region Use the compiled program to get the ASTs for (int i = 0; i < fields.Length; i++) { var field = fields[i]; if (field == null) { continue; } if (!rfs[i].required) { continue; } var val = prelude.TopLevelDeclarations.First(d => { Bpl.NamedDeclaration nd = d as Bpl.NamedDeclaration; return(nd != null && nd.Name.Equals(rfs[i].name)); }); field.SetValue(instance, val); } #endregion #region Check that every field in this class has been set for (int i = 0; i < fields.Length; i++) { var field = fields[i]; if (field == null) { continue; } if (!rfs[i].required) { continue; } if (field.GetValue(instance) == null) { return(false); } } #endregion Check that every field in this class has been set return(true); }
public override Program VisitProgram(Program node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Program>() != null); return base.VisitProgram((Program)node.Clone()); }
public static Program makeProgram(Microsoft.Boogie.Program boogieProgram) { var pf = new ProgramFactory(); return(pf.makeProgram(boogieProgram)); }
public override Program VisitProgram(Program node) { Contract.Ensures(Contract.Result<Program>() == node); this.VisitDeclarationList(node.TopLevelDeclarations.ToList()); return node; }
/// <summary> /// The entry point of the program. /// </summary> /// <param name="args">The command line arguments.</param> public static void Main(string[] args) { int?statusCode = null; try { // standard command line options for Boogie CommandLineOptions.Install(new GRCommandLineOptions()); if (!CommandLineOptions.Clo.Parse(args)) { return; } CommandLineOptions.Clo.PrintUnstructured = 2; CommandLineOptions.Clo.DoModSetAnalysis = true; CommandLineOptions.Clo.PruneInfeasibleEdges = true; if (!CommandLineOptions.Clo.Files.Any()) { throw new Exception("An input file must be provided!"); } else if (CommandLineOptions.Clo.Files.Count > 1) { throw new Exception("GPURepair can work on only one file at a time!"); } Logger.FileName = CommandLineOptions.Clo.Files.First(); Logger.DetailedLogging = ((GRCommandLineOptions)CommandLineOptions.Clo).DetailedLogging; ClauseLogger.FileName = CommandLineOptions.Clo.Files.First(); ClauseLogger.LogCLauses = ((GRCommandLineOptions)CommandLineOptions.Clo).LogClauses; Barrier.LoopDepthWeight = ((GRCommandLineOptions)CommandLineOptions.Clo).LoopDepthWeight; Barrier.GridBarrierWeight = ((GRCommandLineOptions)CommandLineOptions.Clo).GridBarrierWeight; Dictionary <string, bool> assignments; // repair the program Solver.SolverType solverType = ((GRCommandLineOptions)CommandLineOptions.Clo).SolverType; bool disableInspection = ((GRCommandLineOptions)CommandLineOptions.Clo).DisableInspection; bool useAxioms = ((GRCommandLineOptions)CommandLineOptions.Clo).UseAxioms; Repairer repairer = new Repairer(Logger.FileName, disableInspection, useAxioms); Microsoft.Boogie.Program program = repairer.Repair(solverType, out assignments); SummaryGenerator generator = new SummaryGenerator(); IEnumerable <string> changes = generator.GenerateSummary(assignments, Logger.FileName.Replace(".cbpl", ".summary")); Logger.Log($"Changes;{changes.Count()}"); Console.WriteLine("Number of changes required: {0}.", changes.Count()); if (changes.Any()) { using (TokenTextWriter writer = new TokenTextWriter(Logger.FileName.Replace(".cbpl", ".fixed.cbpl"), true)) program.Emit(writer); } } catch (Exception ex) { Logger.Log($"ExceptionMessage;{ex.Message}"); Console.Error.WriteLine(ex.Message); if (ex is AssertionException) { statusCode = 201; } else if (ex is RepairException) { statusCode = 202; } else if (ex is NonBarrierException) { statusCode = 203; } else if (ex is SummaryGeneratorException) { statusCode = 204; } } if (statusCode != null) { Environment.Exit(statusCode.Value); } }
/// <summary> /// Creates an analysis context using information from the given analysis context. /// </summary> /// <param name="program">Program</param> /// <param name="rc">ResolutionContext</param> /// <returns>AnalysisContext</returns> internal static AnalysisContext Create(Microsoft.Boogie.Program program, ResolutionContext rc) { return(new AnalysisContext(program, rc)); }
static ExitValue ProcessFiles(IList <string /*!*/> /*!*/ dafnyFileNames, ReadOnlyCollection <string> otherFileNames, ErrorReporter reporter, bool lookForSnapshots = true, string programId = null) { Contract.Requires(cce.NonNullElements(dafnyFileNames)); if (programId == null) { programId = "main_program_id"; } ExitValue exitValue = ExitValue.VERIFIED; if (CommandLineOptions.Clo.VerifySeparately && 1 < dafnyFileNames.Count) { foreach (var f in dafnyFileNames) { string extension = Path.GetExtension(f); if (extension != null) { extension = extension.ToLower(); } if (extension != ".dfy") { continue; } Console.WriteLine(); Console.WriteLine("-------------------- {0} --------------------", f); var ev = ProcessFiles(new List <string> { f }, new List <string>().AsReadOnly(), reporter, lookForSnapshots, f); if (exitValue != ev && ev != ExitValue.VERIFIED) { exitValue = ev; } } return(exitValue); } if (0 <= CommandLineOptions.Clo.VerifySnapshots && lookForSnapshots) { var snapshotsByVersion = ExecutionEngine.LookForSnapshots(dafnyFileNames); foreach (var s in snapshotsByVersion) { var ev = ProcessFiles(new List <string>(s), new List <string>().AsReadOnly(), reporter, false, programId); if (exitValue != ev && ev != ExitValue.VERIFIED) { exitValue = ev; } } return(exitValue); } using (XmlFileScope xf = new XmlFileScope(CommandLineOptions.Clo.XmlSink, dafnyFileNames[dafnyFileNames.Count - 1])) { Dafny.Program dafnyProgram; string programName = dafnyFileNames.Count == 1 ? dafnyFileNames[0] : "the program"; string err = Dafny.Main.ParseCheck(dafnyFileNames, programName, reporter, out dafnyProgram); if (err != null) { exitValue = ExitValue.DAFNY_ERROR; ExecutionEngine.printer.ErrorWriteLine(Console.Out, err); } else if (dafnyProgram != null && !CommandLineOptions.Clo.NoResolve && !CommandLineOptions.Clo.NoTypecheck && DafnyOptions.O.DafnyVerify) { Dafny.Translator translator = new Dafny.Translator(dafnyProgram.reporter); Bpl.Program boogieProgram = translator.Translate(dafnyProgram); if (CommandLineOptions.Clo.PrintFile != null) { ExecutionEngine.PrintBplFile(CommandLineOptions.Clo.PrintFile, boogieProgram, false, false, CommandLineOptions.Clo.PrettyPrint); } string bplFilename; if (CommandLineOptions.Clo.PrintFile != null) { bplFilename = CommandLineOptions.Clo.PrintFile; } else { string baseName = cce.NonNull(Path.GetFileName(dafnyFileNames[dafnyFileNames.Count - 1])); baseName = cce.NonNull(Path.ChangeExtension(baseName, "bpl")); bplFilename = Path.Combine(Path.GetTempPath(), baseName); } PipelineStatistics stats = null; PipelineOutcome oc = BoogiePipelineWithRerun(boogieProgram, bplFilename, out stats, 1 < Dafny.DafnyOptions.Clo.VerifySnapshots ? programId : null); var allOk = stats.ErrorCount == 0 && stats.InconclusiveCount == 0 && stats.TimeoutCount == 0 && stats.OutOfMemoryCount == 0; var resultFileName = DafnyOptions.O.DafnyPrintCompiledFile ?? dafnyFileNames[0]; switch (oc) { case PipelineOutcome.VerificationCompleted: ExecutionEngine.printer.WriteTrailer(stats); if ((DafnyOptions.O.Compile && allOk && CommandLineOptions.Clo.ProcsToCheck == null) || DafnyOptions.O.ForceCompile) { CompileDafnyProgram(dafnyProgram, resultFileName, otherFileNames); } break; case PipelineOutcome.Done: ExecutionEngine.printer.WriteTrailer(stats); if (DafnyOptions.O.ForceCompile) { CompileDafnyProgram(dafnyProgram, resultFileName, otherFileNames); } break; default: // error has already been reported to user break; } exitValue = allOk ? ExitValue.VERIFIED : ExitValue.NOT_VERIFIED; } if (err == null && dafnyProgram != null && DafnyOptions.O.PrintStats) { Util.PrintStats(dafnyProgram); } if (err == null && dafnyProgram != null && DafnyOptions.O.PrintFunctionCallGraph) { Util.PrintFunctionCallGraph(dafnyProgram); } } return(exitValue); }
public CFG <BasicBlock, BasicEdge> getCFGFromDAG(Implementation imp, Program program) { // Console.WriteLine("getCFGFromDAG"); cfg = new CFG <BasicBlock, BasicEdge>(); entry = cfg.addNode("$start"); exit = cfg.addNode("$exit"); labelIndex = 0; // Console.WriteLine("\t\t\tDeclarations"); foreach (var tld in program.TopLevelDeclarations) { var a = tld as Axiom; if (a != null) { // Console.WriteLine("\t\tAdding axiom {0}",a.Expr.ToString()); var assume = new Assume(procedure.expressionFactory.makeExpression(a.Expr)); entry.appendStatement(assume); } else { var bf = tld as Function; if (bf != null && bf.Body != null) { var ft = scope.findFunctionTemplate(bf.Name); var b = ft.body; Debug.Assert(b != null); var eqF = BFunctionTemplate.eq.getInstance(TypeTuple.make(new[] { ft.signature.resultType })); var lhs = new BasicFAE(ft.getInstance(TypeTuple.make(from tv in ft.typeParameters select new VariableType(tv))), new ExpressionList(from bv in b.arguments select new BasicBoundVariableExpression(bv))); var eqe = new BasicFAE(eqF, new ExpressionList(lhs, b.expression)); var axiom = procedure.expressionFactory.makeSentence(eqe); var assume = new Assume(axiom); entry.appendStatement(assume); } } } // Console.WriteLine("\t\t\tBlocks"); // var topoSortedBlocks foreach (var b in topoSort(imp.Blocks, imp.Blocks[0])) { addBlock(b); } BasicBlock start = cfg.lookupOrAddNode(imp.Blocks[0].Label); entry.setControlStatement(new UnconditionalBranch(entry, start)); exit.setControlStatement(new Programs.Statements.Block(exit)); cfg.setStartNode("$start"); cfg.setEndNode("$exit"); foreach (var bb in cfg.nodes) { if (!ReferenceEquals(bb, exit) && bb.successors.Count == 0) { bb.setControlStatement(new UnconditionalBranch(bb, exit)); } } foreach (var bb in cfg.nodes) { if (!ReferenceEquals(bb, entry) && bb.predecessors.Count == 0) { Console.WriteLine("Warning - removing orphan - {0}", bb.label); bb.setControlStatement(new Programs.Statements.Block(bb)); bb.delete(); } } return(cfg); }
public bpl.Program split(bpl.Program prog) { originalProgram = prog; ////////////////// First identify the thread entries in the program //////////////////// // A procedure is a thread entry if there is any async call to it HashSet <string> threadEntries = new HashSet <string>(); var impls = new Func <bpl.Program, IEnumerable <bpl.Implementation> >(p => from impl in p.TopLevelDeclarations where impl is bpl.Implementation select impl as bpl.Implementation); foreach (var impl in impls(originalProgram)) { var cmdsRaw = from blk in impl.Blocks select blk.Cmds; var cmds = cmdsRaw.Aggregate(new List <bpl.Cmd>(), (curCmds, nextList) => { curCmds.AddRange(nextList); return(curCmds); }); var asyncCalls = from cmd in cmds where con.isAsyncCall(cmd as bpl.Cmd) select cmd; foreach (bpl.Cmd asyncCall in asyncCalls) { threadEntries.Add((asyncCall as bpl.CallCmd).callee); } } // Finally add the entry function also as a thread entry. threadEntries.Add(con.entryFunc); //////////////// Next, identify all the procedures belonging to each thread //////////// Dictionary <string, HashSet <string> > threadToProcs = new Dictionary <string, HashSet <string> >(); // This is done in two steps. // First step: Find all non-async calls in each procedure. var procToCalls = new Dictionary <string, HashSet <string> >(); //impls = from impl in prog.TopLevelDeclarations where impl is bpl.Implementation select impl as bpl.Implementation; foreach (var impl in impls(originalProgram)) { procToCalls[impl.Name] = new HashSet <string>(); var cmdsRaw = from blk in impl.Blocks select blk.Cmds; var cmds = cmdsRaw.Aggregate(new List <bpl.Cmd>(), (curCmds, nextList) => { curCmds.AddRange(nextList); return(curCmds); }); var syncCalls = from cmd in cmds where con.isSyncCall(cmd as bpl.Cmd) select cmd; foreach (bpl.Cmd syncCall in syncCalls) { procToCalls[impl.Name].Add((syncCall as bpl.CallCmd).callee); } } // Second step: Find all procedures in each thread. foreach (var thr in threadEntries) { threadToProcs[thr] = new HashSet <string>(); } foreach (var thr in threadEntries) { findReachable(procToCalls, thr, threadToProcs[thr]); } //DEBUGGING if (dbg) { System.Console.WriteLine("Threads in the original program:"); foreach (var iter in threadToProcs) { System.Console.Write(iter.Key + ": "); foreach (var proc in iter.Value) { System.Console.Write(proc + " "); } System.Console.WriteLine(); } } // [Optional] // Remove unreachable procs. // These procedures are neither reachable from Main, nor from a thread entry. They can obviously not be called in any execution. var reachableProcs = new HashSet <string>(); foreach (var vals in threadToProcs.Values) { foreach (var proc in vals) { reachableProcs.Add(proc); } } foreach (var val in threadToProcs.Keys) { reachableProcs.Add(val); } removeUnreachable(reachableProcs); //////////////// Finally, Actually split the procedures when needed ////////////////// // For every procedure, find out how many threads contain it. We need as many copies of // that procedure. // Note: We do not want to duplicate procedures without implementation. //impls = from impl in prog.TopLevelDeclarations where impl is bpl.Implementation select impl as bpl.Implementation; var implNames = from impl in impls(originalProgram) select impl.Name; Dictionary <string, int> procCopies = new Dictionary <string, int>(); var procs = from proc in originalProgram.TopLevelDeclarations where proc is bpl.Procedure select proc as bpl.Procedure; foreach (var proc in procs) { procCopies[proc.Name] = 0; } foreach (var iter in threadToProcs) { foreach (var proc in iter.Value) { if (implNames.Contains(proc)) { procCopies[proc]++; } } } // Now duplicate // The new procedures and implementations for each thread // thread name --> (old procedure name --> new procedure) var newProcsPerThread = new Dictionary <string, Dictionary <string, bpl.Procedure> >(); // thread name --> (old procedure name --> new implementation) var newImplsPerThread = new Dictionary <string, Dictionary <string, bpl.Implementation> >(); // old name --> proc, old name --> impl var oldNameToImpl = new Dictionary <string, bpl.Implementation>(); foreach (var impl in impls(originalProgram)) { oldNameToImpl[impl.Name] = impl; } var oldNameToProc = new Dictionary <string, bpl.Procedure>(); foreach (var proc in procs) { oldNameToProc[proc.Name] = proc; } foreach (var elem in threadToProcs) { string threadName = elem.Key; newProcsPerThread[threadName] = new Dictionary <string, bpl.Procedure>(); newImplsPerThread[threadName] = new Dictionary <string, bpl.Implementation>(); foreach (var procName in elem.Value) { if (procCopies[procName] > 1) { // We will duplicate this procedure. // Make a copy of the procedure and implementation var dup = new cba.Util.FixedDuplicator(); var impl = (bpl.Implementation)dup.VisitDeclaration(oldNameToImpl[procName]); var proc = (bpl.Procedure)dup.VisitDeclaration(oldNameToProc[procName]); impl.Proc = proc; // Rename the new instances using thread id. impl.Name = con.getSplitProcName(procName); proc.Name = con.getSplitProcName(procName); var origProcAttr = con.originalProcAttr(procName); origProcAttr.Next = proc.Attributes; proc.Attributes = origProcAttr; // Also add an attribute to the definition specifying the thread. var threadAttr = con.getThreadAttr(threadName); threadAttr.Next = proc.Attributes; proc.Attributes = threadAttr; //add to duplicated procedures/impls newProcsPerThread[threadName][procName] = proc; newImplsPerThread[threadName][procName] = impl; //Add to the program originalProgram.AddTopLevelDeclaration(proc); originalProgram.AddTopLevelDeclaration(impl); var s1 = new HashSet <string>(); var s2 = new HashSet <string>(); foreach (var im in originalProgram.TopLevelDeclarations.OfType <bpl.Implementation>()) { s1.Add(im.Name); } foreach (var im in impls(originalProgram)) { s2.Add(im.Name); } // We have split away the procedure calls for one thread. procCopies[procName]--; } else if (procCopies[procName] == 1) { //We still need to rename this procedure var impl = oldNameToImpl[procName]; var proc = oldNameToProc[procName]; //rename the new instances using thread id. impl.Name = con.getSplitProcName(procName); proc.Name = con.getSplitProcName(procName); var origProcAttr = con.originalProcAttr(procName); origProcAttr.Next = proc.Attributes; proc.Attributes = origProcAttr; // Also add an attribute to the definition specifying the thread. var threadAttr = con.getThreadAttr(threadName); threadAttr.Next = proc.Attributes; proc.Attributes = threadAttr; //add to duplicated procedures/impls newProcsPerThread[threadName][procName] = proc; newImplsPerThread[threadName][procName] = impl; // We have split away the procedure calls for one thread. procCopies[procName]--; } } // Tell con that we're done with one thread. con.nextThread(); } // New re-route procedure calls as needed // First async calls. foreach (var impl in impls(originalProgram)) { foreach (var blk in impl.Blocks) { for (int i = 0; i < blk.Cmds.Count; i++) { bpl.Cmd cmd = blk.Cmds[i]; if (con.isAsyncCall(cmd)) { var callCmd = cmd as bpl.CallCmd; var newCallCmd = new bpl.CallCmd(bpl.Token.NoToken, newProcsPerThread[callCmd.callee][callCmd.callee].Name, callCmd.Ins, callCmd.Outs, callCmd.Attributes, callCmd.IsAsync); newCallCmd.TypeParameters = callCmd.TypeParameters; newCallCmd.Proc = newProcsPerThread[callCmd.callee][callCmd.callee]; blk.Cmds[i] = newCallCmd; } } } } // Now sync calls. foreach (var elem in newImplsPerThread) { string threadName = elem.Key; var newImpls = newImplsPerThread[threadName]; foreach (var implTuple in newImpls) { var impl = implTuple.Value; foreach (var blk in impl.Blocks) { for (int i = 0; i < blk.Cmds.Count; ++i) { bpl.Cmd cmd = blk.Cmds[i]; if (con.isSyncCall(cmd) && newProcsPerThread[threadName].ContainsKey((cmd as bpl.CallCmd).callee)) { var callCmd = cmd as bpl.CallCmd; var newCallCmd = new bpl.CallCmd(bpl.Token.NoToken, newProcsPerThread[threadName][callCmd.callee].Name, callCmd.Ins, callCmd.Outs, callCmd.Attributes, callCmd.IsAsync); newCallCmd.TypeParameters = callCmd.TypeParameters; newCallCmd.Proc = newProcsPerThread[threadName][callCmd.callee]; blk.Cmds[i] = newCallCmd; } } } } } // Finally, label the entry of each thread as thread entry. foreach (var elem in newProcsPerThread) { var proc = elem.Value[elem.Key]; var threadEntryAttr = con.getThreadEntryAttr(); threadEntryAttr.Next = proc.Attributes; proc.Attributes = threadEntryAttr; } return(originalProgram); }
public override Program VisitProgram(Program node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Program>() != null); // If cloning an entire program we need to ensure that // Implementation.Proc gets resolved to the right Procedure // (i.e. we don't duplicate Procedure twice) and CallCmds // call the right Procedure. // The map below is used to achieve this. OldToNewProcedureMap = new Dictionary<Procedure, Procedure>(); var newProgram = base.VisitProgram((Program)node.Clone()); // We need to make sure that CallCmds get resolved to call Procedures we duplicated // instead of pointing to procedures in the old program var callCmds = newProgram.Blocks().SelectMany(b => b.Cmds).OfType<CallCmd>(); foreach (var callCmd in callCmds) { callCmd.Proc = OldToNewProcedureMap[callCmd.Proc]; } OldToNewProcedureMap = null; // This Visitor could be used for other things later so remove the map. return newProgram; }
/// <summary> /// Instantiates an instance of <see cref="ErrorReporter"/>. /// </summary> /// <param name="program">The program.</param> /// <param name="implName">The name of the implementation.</param> public ErrorReporter(Microsoft.Boogie.Program program, string implName) : base(program, implName) { }
public FunctionCallReresolvingNormalSubstituter(Program program, Substitution always, Substitution forold) : base(always, forold) { Program = program; }
/// <summary> /// Initilaizes an instance of <see cref="GraphAnalyzer"/>. /// </summary> /// <param name="program">The boogie program.</param> public GraphAnalyzer(Microsoft.Boogie.Program program) { Graph = new ProgramGraph(program); }