public static int PrintCallGraph(string filename) { var program = BoogieUtils.ParseProgram(filename); if (program == null) { Console.WriteLine("parse failed"); return(1); } if (BoogieUtils.ResolveAndTypeCheckThrow(program, filename)) { if (program == null) { Console.WriteLine("check failed"); return(1); } } var cg = CallGraph.Make(program); Console.WriteLine("digraph G {"); cg.Print(); Console.WriteLine("}"); return(0); }
public static int RecursionCheck(string filename) { var program = BoogieUtils.ParseProgram(filename); if (program == null) { return(1); } BoogieUtils.ResolveAndTypeCheckThrow(program, filename); var flag = false; var mflag = false; var nflag = false; var cg = CallGraph.Make(program); var recs = cg.SinglyRecursiveFns(); foreach (var node in recs) { Console.WriteLine(node.Name); } nflag = cg.HasCycle(); foreach (var scc in cg.ComputeSCCs()) { if ((scc.Count == 1 && scc[0].IsSinglyRecursive())) { flag = true; } if (scc.Count > 1) { mflag = true; } } if (flag) { Console.WriteLine("Recursive."); } if (mflag) { Console.WriteLine("Multi_Recursive"); } if (nflag) { Console.WriteLine("Naive cycle detector found a non-singleton cycle!"); } return(0); }
static void Main(string[] args) { if (args.Count() != 4) { Console.WriteLine("The program is to be run as: SymDiffPostProcess.exe tainted.csv tainted.dac.csv v1.bpl_changed_lines.txt _v2.bpl"); return; } if (args.ToList().Any(x => x == "-break")) { Debugger.Launch(); } var taintDependency = args[0]; var taintDac = args[1]; var changedFile = args[2]; var bplFile = args[3]; Dictionary <string, HashSet <int> > procToDacTaint = getProcToLinesMap(taintDac); Dictionary <string, HashSet <int> > procToDepTaint = getProcToLinesMap(taintDependency); Dictionary <string, HashSet <int> > procToChange = getProcToLinesMap(changedFile); FilterChangedFromTainted(procToDacTaint, procToChange); FilterChangedFromTainted(procToDepTaint, procToChange); BoogieUtils.InitializeBoogie(""); Program program = BoogieUtils.ParseProgram(bplFile); program.Resolve(); program.Typecheck(); var callGraph = CallGraphHelper.ComputeCallGraph(program); var lengths = BoogieUtils.FindProcsAtDistance(callGraph, procToChange.Keys.ToList()); Dictionary <int, int> distanceToLinesDac = ComputeDistanceToLines(lengths, procToDacTaint); PrintDistanceBuckets(distanceToLinesDac, "dacTaintBuckets.csv"); Dictionary <int, int> distanceToLinesDep = ComputeDistanceToLines(lengths, procToDepTaint); PrintDistanceBuckets(distanceToLinesDep, "depTaintBuckets.csv"); }
private static PersistentProgram ParseAndTypeCheckProgram(string programFileName) { Program program; program = BoogieUtils.ParseProgram(programFileName); int errors = program.Resolve(); if (errors > 0) { throw new ArgumentException("Unable to resolve " + programFileName); } ModSetCollector c = new ModSetCollector(); c.DoModSetAnalysis(program); errors = program.Typecheck(); if (errors > 0) { throw new ArgumentException("Unable to typecheck " + programFileName); } PersistentProgram persistentProgram = new PersistentProgram(program); return(persistentProgram); }
public static int LoopUnroller(string[] args) { var filename = args[2]; int iterationsToUnroll = Int16.Parse(args[1]); var outfilename = args[3]; string boogieOptions = "/printInstrumented " + Options.BoogieUserOpts; //Log.Out(Log.Normal, "Initializing Boogie"); if (SDiff.Boogie.Process.InitializeBoogie(boogieOptions)) { return(1); } var program = BoogieUtils.ParseProgram(filename); if (program == null) { Log.Out(Log.Error, "Parse failed."); return(1); } if (BoogieUtils.ResolveAndTypeCheckThrow(program, filename)) { Log.Out(Log.Error, "Check failed."); return(1); } program.UnrollLoops(iterationsToUnroll, false); //setting it to true breaks ex7 var outchan = new TokenTextWriter(outfilename, true); program.Emit(outchan); outchan.Close(); return(0); }
static int Main(string[] args) { CommandLineOptions.Install(new CommandLineOptions()); int argc = args.Length; if (argc < 4) { System.Console.WriteLine("Boogiewrapper.exe a.bpl EQ LEFT RIGHT [v1name] [v2name] [bvdfriendly]"); System.Console.WriteLine("\t EQ: name of the combined procedure to be verified"); System.Console.WriteLine("\t RIGHT: name of the right procedure"); System.Console.WriteLine("\t RIGHT: name of the right procedure"); System.Console.WriteLine("\t viname: optional prefix of the left/right procedure (when not checking EQ_v1.foo__xx__v2.foo)"); System.Console.WriteLine("\t bvdfriendly: optional instrument the input file to add some captureStates for bvd to display (no checking)"); return(-1); } string fileName = args[0]; string funcName = args[1]; //TODO: Make it aware of the other Boogie options var boogieOptions = " -doModSetAnalysis -printInstrumented -z3multipleErrors -typeEncoding:m -timeLimit:" + Options.Timeout + " -removeEmptyBlocks:0 -printModel:1 -printModelToFile:model.dmp " + Options.BoogieUserOpts; SDiff.Boogie.Process.InitializeBoogie(boogieOptions); Program prog = BoogieUtils.ParseProgram(args[0]); if (prog == null) { Log.Out(Log.Verifier, "Parse Error!!! in " + args[1]); return(-1); } if (BoogieUtils.ResolveAndTypeCheckThrow(prog, args[0])) { return(-1); } //code duplication //Not having "-printInstrumented" just prints the old version of hte program!!!! if (args.Length == 7 && args[6] == "/bvdfriendly") { //System.Diagnostics.Debugger.Break(); var bvdI = new BvdInstrument(); Program prog1 = bvdI.VisitProgram(prog); if (BoogieUtils.ResolveAndTypeCheckThrow(prog, fileName)) { return(-1); } Util.DumpBplAST(prog, "merged_bvd.bpl"); return(-1); } var newProg = prog; VC.ConditionGeneration vcgen = BoogieVerify.InitializeVC(newProg); var newDict = SDiff.Boogie.Process.BuildProgramDictionary(newProg.TopLevelDeclarations.ToList()); //RS: Uncomment this var newEq = (Implementation)newDict.Get(funcName + "$IMPL"); SDiffCounterexamples SErrors; List <Model> errModelList; var Result = BoogieVerify.VerifyImplementation(vcgen, newEq, newProg, out SErrors, out errModelList); switch (Result) { case VerificationResult.Error: Log.Out(Log.Verifier, "Result: Error"); break; case VerificationResult.Verified: Log.Out(Log.Verifier, "Result: Verified"); break; case VerificationResult.OutOfMemory: Log.Out(Log.Verifier, "Result: OutOfMemory"); return(-2); //break; case VerificationResult.TimeOut: Log.Out(Log.Verifier, "Result: TimeOut"); return(-3); // break; default: Log.Out(Log.Verifier, "Result: Unhandled"); return(-4); } Implementation n1, n2; GetImplementations(newDict, funcName, out n1, out n2, args[2], args[3]); var outputVars = new List <Variable>(); foreach (Variable v in n1.OutParams) { outputVars.Add(newDict.Get(v.Name + "$VAR") as Variable); } foreach (Variable v in n2.OutParams) { outputVars.Add(newDict.Get(v.Name + "$VAR") as Variable); } var globals = new List <Variable>(); foreach (IdentifierExpr ie in newEq.Proc.Modifies) { globals.Add(ie.Decl); } if (SErrors != null) { //somewhat misnamed... if (Options.DumpBeforeVerifying) { Log.Out(Log.SymEx, "Dumping procedure under verification"); newEq.Emit(Log.LogWriter, 0); } if (Options.DoSymEx) { if (Options.PreciseDifferentialInline) { IEnumerable <Declaration> consts = prog.TopLevelDeclarations.Where(x => x is Constant); if (args.Length < 6) { BoogieVerify.ProcessCounterexamplesWOSymbolicOut(SErrors, globals, newEq.LocVars, null, null, consts.ToList(), errModelList); } else { BoogieVerify.ProcessCounterexamplesWOSymbolicOut(SErrors, globals, newEq.LocVars, null, null, consts.ToList(), errModelList, args[4], args[5]); } } else { BoogieVerify.ProcessCounterexamples(SErrors, globals, outputVars, newProg, null, null); } } } return(SErrors == null ? 0 : SErrors.Count); }
public static int RVTRunVerificationTask(SDiff.VerificationTask vt, VC.ConditionGeneration vcgen, Program prog, HashSet <int> inlinedFns1, HashSet <int> inlinedFns2, out bool crashed) { Log.Out(Log.Verifier, "Verifying " + vt.Eq.Name); crashed = false; var attList = new List <Object>(1); attList.Add(Expr.Literal(1)); //save attributes var sqkLeft = vt.Left.Attributes; var sqkpLeft = vt.Left.Proc.Attributes; var sqkRight = vt.Right.Attributes; var sqkpRight = vt.Right.Proc.Attributes; //save postconditions var leftPosts = vt.Left.Proc.Ensures; var rightPosts = vt.Right.Proc.Ensures; //Keep the postconditions correpsonding to the //free ensures (out == uf_Foo(inp)) //vt.Left.Proc.Ensures = new List<Ensures>(); //vt.Right.Proc.Ensures = new List<Ensures>(); //inline procedures under analysis vt.Left.Attributes = Util.MkInlinedAttribute(attList); vt.Left.Proc.Attributes = vt.Left.Attributes; vt.Right.Attributes = Util.MkInlinedAttribute(attList); vt.Right.Proc.Attributes = vt.Right.Attributes; vt.Left.OriginalBlocks = vt.Left.Blocks; vt.Left.OriginalLocVars = vt.Left.LocVars; vt.Right.OriginalBlocks = vt.Right.Blocks; vt.Right.OriginalLocVars = vt.Right.LocVars; IEnumerable <Declaration> procImplPIter = prog.TopLevelDeclarations.Where(x => x is Implementation); List <Implementation> inlinedImpls = new List <Implementation>(); foreach (Implementation currentProcImpl in procImplPIter) { bool match = false; int indx = -1; if (fnNameToIndex1.ContainsKey(currentProcImpl.Proc.Name)) { match = true; indx = fnNameToIndex1[currentProcImpl.Proc.Name]; } else if (fnNameToIndex2.ContainsKey(currentProcImpl.Proc.Name)) { match = true; indx = fnNameToIndex2[currentProcImpl.Proc.Name]; } //Inline if present in if (match && (inlinedFns1.Contains(indx) || inlinedFns2.Contains(indx))) { inlinedImpls.Add(currentProcImpl); currentProcImpl.Attributes = Util.MkInlinedAttribute(attList); currentProcImpl.Proc.Attributes = Util.MkInlinedAttribute(attList); //RUN INLINER OVER EQ FUNCTION currentProcImpl.OriginalBlocks = currentProcImpl.Blocks; currentProcImpl.OriginalLocVars = currentProcImpl.LocVars; } } //RUN INLINER OVER EQ FUNCTION // prog = EQ program // vt.Eq = EQ_f_f' procedure with f, f' having {inline} tags Inliner.ProcessImplementation(prog, vt.Eq); if (Options.TraceVerify) { Log.Out(Log.Normal, "Ready to verify:"); Log.LogEmit(Log.Normal, prog.Emit); } // To print the EQ files in Util.DumpBplAST(prog, vt.Eq.Name + "_out.bpl"); // prog = SDiff.Boogie.Process.ParseProgram(vt.Eq.Name + "_out.bpl"); if (BoogieUtils.ResolveAndTypeCheckThrow(prog, Options.MergedProgramOutputFile)) { return(1); } Implementation newEq = vt.Eq; var newProg = prog; vcgen = BoogieVerify.InitializeVC(newProg); //SDiff.Boogie.Process.ResolveAndTypeCheck(newProg, ""); var newDict = SDiff.Boogie.Process.BuildProgramDictionary(newProg.TopLevelDeclarations.ToList()); //newEq = (Implementation)newDict.Get(vt.Eq.Name + "$IMPL"); SDiffCounterexamples SErrors; List <Model> errModelList; //Clear up the state since it might call the same procedure twice vt.Result = BoogieVerify.VerifyImplementation(vcgen, newEq, newProg, out SErrors, out errModelList); switch (vt.Result) { case SDiff.VerificationResult.Error: Log.Out(Log.Verifier, "Result: Error"); break; case SDiff.VerificationResult.Verified: Log.Out(Log.Verifier, "Result: Verified"); break; default: Log.Out(Log.Verifier, "Result: Unhandled"); crashed = true; break; } //restore postconditions IN THE OLD IN-MEMORY PROGRAM vt.Left.Proc.Ensures = leftPosts; vt.Right.Proc.Ensures = rightPosts; //remove the inline annotation IN THE OLD IN-MEMORY PROGRAM vt.Left.Attributes = sqkLeft; vt.Left.Proc.Attributes = sqkpLeft; vt.Right.Attributes = sqkRight; vt.Right.Proc.Attributes = sqkpRight; //remove the inline annotation in the Inlined Procedures foreach (Implementation currentProcImpl in procImplPIter) { if (inlinedImpls.Contains(currentProcImpl)) { currentProcImpl.Attributes = null; currentProcImpl.Proc.Attributes = null; } } if (vt.Result == SDiff.VerificationResult.Verified) { return(1); } else { return(0); } }
/// <summary> /// Create the EQ_f_f' procedure statically (eagerly) to avoid generating it again and again /// </summary> /// <param name="f"></param> /// Outputs the list of synEq functions for stubs that have no bodies on both sides private static bool RVTCreateEQProcs(int f, ref List <int> synEq, ref List <int> empty1, ref List <int> empty2) { //name of the function string fname = fnIndexToName1[f]; var n1 = cg.NodeOfName(fname); var n2Name = funs.Get(n1.Name); if (n2Name == null) { Log.Out(Log.Error, "Could not find mapping for " + n1.Name); Log.Out(Log.Error, "Dumping config..."); Log.Out(Log.Error, cfg.ToString()); return(false); } var n2 = cg.NodeOfName(n2Name); if (n2 == null) { Log.Out(Log.Error, "ERROR: Could not find " + n2Name + " in ARGS[1]"); return(false); } if (n1.Proc == null || n2.Proc == null) { Log.Out(Log.Error, "Missing procedure for " + n1.Name + " or " + n2.Name + ": skipping..."); return(false); } //TODO: currently return false for corner cases...FIX this carefully if (n1.Name.EndsWith("nondet_choice")) { Log.Out(Log.Normal, "skipping nondet_choice"); return(false); } if (n1.Impl == null && n2.Impl == null) { Log.Out(Log.Normal, "No implementation for " + n1.Name + ": skipping..."); synEq.Add(f); empty1.Add(f); empty2.Add(fnNameToIndex2[n2.Name]); return(true); } if (n1.Impl == null) { Log.Out(Log.Error, "!Missing implementation for " + n1.Name); empty1.Add(f); return(false); } if (n2.Impl == null) { Log.Out(Log.Error, "!Missing implementation for " + n2.Name); empty2.Add(fnNameToIndex2[n2.Name]); return(false); } var ignores = new HashSet <Variable>(n1.IgnoreSet); ignores.UnionWith(n2.IgnoreSet); // Creates EQ_f_f' function List <Variable> outputVars; string eqpName = Transform.mkEqProcName(n1.Name, n2.Name); Duple <Procedure, Implementation> eqp; eqp = Transform.EqualityReduction(n1.Impl, n2.Impl, cfg.FindProcedure(n1.Name, n2.Name), ignores, out outputVars); // if any visible output //VerificationTask vt; if (eqp != null) { mergedProgram.AddTopLevelDeclarations(outputVars.Map(x => x as Declaration)); mergedProgram.AddTopLevelDeclaration(eqp.fst); mergedProgram.AddTopLevelDeclaration(eqp.snd); } //declare the uninterpreted funcs/canonical set of constants in merged program //mergedProgram.AddTopLevelDeclarations(newDecls); var canonicalConst = SDiff.Boogie.ConstantFactory.Get().Constants.Map(x => x as Declaration); mergedProgram.AddTopLevelDeclarations(canonicalConst); //Log.Out(Log.Normal, "Resolving and Typechecking again.."); if (BoogieUtils.ResolveAndTypeCheckThrow(mergedProgram, Options.MergedProgramOutputFile)) { Log.LogEmit(Log.Normal, mergedProgram.Emit); return(false); } if (Options.TraceVerify) { Log.Out(Log.Normal, "merged program with ufs etc"); Log.LogEmit(Log.Normal, mergedProgram.Emit); } // callgraph has changed because EQ programs are added Log.Out(Log.Normal, "Building callgraphs and computing read and write sets"); cg = CallGraph.Make(mergedProgram); ReadWriteSetDecorator.DoDecorate(cg); //start from scratch to fill in the read/write sets var mergedProgramNewDecl = new Program(); mergedProgram.AddTopLevelDeclarations(mergedProgramNewDecl.TopLevelDeclarations); mergedProgram.TopLevelDeclarations = SDiff.Boogie.Process.RemoveDuplicateDeclarations(mergedProgram.TopLevelDeclarations.ToList()); Duple <Duple <Procedure, Implementation>, List <Variable> > tmp = new Duple <Duple <Procedure, Implementation>, List <Variable> >(eqp, outputVars); eqProcsCreated.Add(eqpName, tmp); return(true); }
public static int Main(string[] args) { CommandLineOptions.Install(new CommandLineOptions()); if (args.Length == 0) { Console.WriteLine("Options:"); Console.WriteLine("for option usage, run the option with no arguments"); Console.WriteLine("for debugging, run the options a -break"); Console.WriteLine("\nTop level options\n"); Console.WriteLine("-inferConfig"); Console.WriteLine(" guess the most obvious configuration for a pair of BPL files"); Console.WriteLine("-allInOne"); Console.WriteLine(" option to do analyze two BPL programs"); Console.WriteLine("-loopUnroll"); Console.WriteLine(" unroll loops in a boogie program"); Console.WriteLine("-extractLoops[:n]"); Console.WriteLine(" extracts loops as tail-recursive functions (optional :n makes extracted proc non-deterministic)"); Console.WriteLine("\nHelper options\n"); Console.WriteLine("-recurCheck"); Console.WriteLine(" check a file for recursion (mutual or single)"); Console.WriteLine("-tryParse"); Console.WriteLine(" try to parse a bpl file"); Console.WriteLine("-printCallGraph"); Console.WriteLine(" print a callgraph in graphviz format"); Console.WriteLine("-dumpeq"); Console.WriteLine(" Dump the equivalent procedures in dump_f1_f2.txt"); //RS: Display the new options return(1); } bool breakSeen = false; for (int i = 0; i < args.Length; i++) { if (breakSeen) { args[i - 1] = args[i]; args[i] = "-break"; } if (args[i] == "-break" || args[i] == "/break") { breakSeen = true; //eat the "-break" } } if (breakSeen) { System.Diagnostics.Debugger.Launch(); } if (args[0].Equals("-inferConfig")) { if (args.Length < 3) { Console.WriteLine("Usage: SymDiff -inferConfig <a.bpl> <b.bpl>"); return(1); } args[0] = args[1]; args[1] = args[2]; return(GuessConfig(args)); } else if (args[0].Equals("-allInOne")) { var nargs = new List <string>(); for (int i = 0; i < args.Length - 1; i++) { nargs.Add(args[i + 1]); } try { return(AllInOneDriver.AllInOneMain(nargs.ToArray())); } catch (Exception e) { Console.WriteLine("Fatal error: SymDiff failed with exception " + e.Message); return(1); } } else if (args[0].Equals("-loopUnroll")) { if (args.Length < 4) { Console.WriteLine("Usage: SymDiff -loopUnroll depth infile outfile"); return(1); } return(LoopUnroller(args)); } else if (args[0].StartsWith("-extractLoops")) //can be -extractLoops:n to make non-det loop extract { if (args.Length < 3) { Console.WriteLine("Usage: SymDiff -extractLoops[:n] infile outfile //optional :n"); return(1); } return(ExtractLoops(args)); } else if (args[0].Equals("-tryParse")) { if (args.Length < 2) { Console.WriteLine("Usage: Symdiff -tryParse infile"); return(1); } var prog = BoogieUtils.ParseProgram(args[1]); if (prog == null) { return(1); } if (BoogieUtils.ResolveAndTypeCheckThrow(prog, args[1])) { return(1); } return(0); } else if (args[0].Equals("-recurCheck")) { if (args.Length < 2) { Console.WriteLine("Usage: SymDiff -recurCheck test.bpl"); return(1); } return(RecursionCheck(args[1])); } else if (args[0].Equals("-printCallGraph")) { if (args.Length < 2) { Console.WriteLine("Usage: Symdiff -printCallGraph test.bpl"); return(1); } return(PrintCallGraph(args[1])); } Console.WriteLine("Symdiff: run with no arguments to see options"); return(0); }
public static int GuessConfig(string[] args) { string boogieOptions = Options.BoogieUserOpts; //Log.Out(Log.Normal, "Initializing Boogie"); if (SDiff.Boogie.Process.InitializeBoogie(boogieOptions)) { return(1); } string first = args[0], second = args[1]; // First program Program p = BoogieUtils.ParseProgram(first); if (p == null) { return(1); } BoogieUtils.ResolveProgram(p, first); BoogieUtils.TypecheckProgram(p, first); // Second program Program q = BoogieUtils.ParseProgram(second); if (q == null) { return(1); } BoogieUtils.ResolveProgram(q, second); BoogieUtils.TypecheckProgram(q, second); first = first.Substring(0, first.LastIndexOf('.') + 1); second = second.Substring(0, second.LastIndexOf('.') + 1); Config config = new Config(); //store the procs of q by name Dictionary <string, Declaration> qProcs = new Dictionary <string, Declaration>(); Dictionary <string, HashSet <string> > qLoops = new Dictionary <string, HashSet <string> >(); foreach (Declaration d in q.TopLevelDeclarations) { var proc = d as Procedure; if (proc != null) { qProcs.Add(proc.Name, proc); if (proc.Name.Contains("_loop_")) { int indx = proc.Name.IndexOf("_loop_"); string loopProc = proc.Name.Substring(0, indx); if (!qLoops.ContainsKey(loopProc)) { qLoops.Add(loopProc, new HashSet <string>()); } qLoops[loopProc].Add(proc.Name); } } } foreach (Declaration d in p.TopLevelDeclarations) { var proc = d as Procedure; if (proc != null) { if (Util.IsInlinedProc(proc)) { continue; } var pmap = new ParamMap(); foreach (Variable v in proc.InParams) { pmap.Add(new HDuple <string>(v.Name, v.Name)); } foreach (Variable v in proc.OutParams) { pmap.Add(new HDuple <string>(v.Name, v.Name)); } //config.AddProcedure(new Duple<HDuple<string>, ParamMap>(new HDuple<string>(first + proc.Name, second + proc.Name), pmap)); if (qProcs.ContainsKey(proc.Name)) { config.AddProcedure(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + proc.Name, second + proc.Name), pmap)); } else //match loops (A BIG HACK that pretends that the enclosing procedure has only one loop and the mappings are same) { if (proc.Name.Contains("_loop_")) { int indx = proc.Name.IndexOf("_loop_"); string loopProc = proc.Name.Substring(0, indx); if (qLoops.ContainsKey(loopProc) && qLoops[loopProc].Count == 1) { HashSet <string> matchQProcs = qLoops[loopProc]; string qProcName = ""; foreach (string s in matchQProcs) //ugly way to get the singleton string { qProcName = s; } config.AddProcedure(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + proc.Name, second + qProcName), pmap)); } } } } var global = d as GlobalVariable; if (global != null) { config.AddGlobal(new HDuple <string>(first + global.Name, second + global.Name)); } var constant = d as Constant; if (constant != null) { config.AddConstant(new HDuple <string>(first + constant.Name, second + constant.Name)); } var function = d as Function; if (function != null) { var pmap = new ParamMap(); int i = 0; foreach (Variable v in function.InParams) { if (v.Name.Trim().Equals("")) { v.Name = "arg_" + i++; } pmap.Add(new HDuple <string>(v.Name, v.Name)); } if (function.OutParams[0].Name.Equals("")) { function.OutParams[0].Name = "out_ret"; } pmap.Add(new HDuple <string>(function.OutParams[0].Name, function.OutParams[0].Name)); config.AddFunction(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + function.Name, second + function.Name), pmap)); } var typector = d as TypeCtorDecl; if (typector != null) { config.AddType(new HDuple <string>(first + typector.Name, second + typector.Name)); } var typesyn = d as TypeSynonymDecl; if (typesyn != null) { config.AddType(new HDuple <string>(first + typesyn.Name, second + typesyn.Name)); } } Console.WriteLine(config.ToString()); return(0); }
public static int ExtractLoops(string[] args) { var filename = args[1]; var outfilename = args[2]; string boogieOptions = "/printInstrumented " + Options.BoogieUserOpts; if (args[0] == "-extractLoops") //if -extractLoops:n then don't pass the flag (need to fix a bug 7/1/15) { boogieOptions += " /deterministicExtractLoops "; } //Log.Out(Log.Normal, "Initializing Boogie"); if (SDiff.Boogie.Process.InitializeBoogie(boogieOptions)) { return(1); } var program = BoogieUtils.ParseProgram(filename); if (program == null) { Log.Out(Log.Error, "Parse failed."); return(1); } if (BoogieUtils.ResolveAndTypeCheckThrow(program, filename)) { Log.Out(Log.Error, "Check failed."); return(1); } Dictionary <string, Dictionary <string, Block> > tmp = program.ExtractLoops(); // the hacks below should be history now with the deterministic Loop extract in Boogie ///* // * iterate over each procedure in program // * find the extracted procedures by name // * Find the exit block in the extracted procedure // * The name of the exit block is "exit" // * The exit block should have no statements // * add "assume false" as the single statement // * [FIXME] This is possibly buggy for the simple example {for(i=0..2) l++;} {for(i=0..3) l++;} // * [FIX for modular checking]: make the non-det deterministic (see email on Current Loop extract fix for SymDiff, 5/4/12) // * This fix may not be ok for the case of inlining, as all instances either execute the body or exit // */ //List<Declaration> impls = program.TopLevelDeclarations.Where(x => x is Implementation); //TypedIdent tid = new TypedIdent(new Token(), "__loop_nondet_" /*+ impl.Name*/, new BasicType(SimpleType.Bool)); //GlobalVariable loopNonDet = new GlobalVariable(new Token(), tid); //program.TopLevelDeclarations.Insert(0, loopNonDet); //foreach (Implementation impl in impls) // if (impl.Name.Contains("_loop_")) //TODO: this is just too hacky // { // //add a boolean constant // //HACK: We don't add the impl.Name to avoid mapping problems with different loop names // // This may cause problem if these functions are inlined more than once // string loopHeadLabel = ""; // foreach (Block bl in impl.Blocks) // { // if (bl.Label == "entry") // loopHeadLabel = FindLoopHeadLabel(bl); // if (bl.Label == loopHeadLabel) { // AssumeCmd ac = new AssumeCmd(Token.NoToken, Expr.Ident(loopNonDet)); // bl.Cmds = new List<Cmd>(); // bl.Cmds.Add(ac); // } // if (bl.Label == "exit") { // //insert assume false // //AssumeCmd ac = new AssumeCmd(Token.NoToken, Expr.False); // AssumeCmd ac = new AssumeCmd(Token.NoToken, Expr.Not(Expr.Ident(loopNonDet))); // bl.Cmds = new List<Cmd>(); // bl.Cmds.Add(ac); // } // } // if (loopHeadLabel == "") { // throw new Exception("Could not find loophead during loop extraction"); // } // } var outchan = new TokenTextWriter(outfilename, true); program.Emit(outchan); outchan.Close(); return(0); }
public static int RunVerificationTask(VerificationTask vt, VC.ConditionGeneration vcgen, Program prog, out bool crashed, bool wrapper = true) { crashed = false; var attList = new List <Object>(1); attList.Add(Expr.Literal(1)); //save attributes var sqkLeft = vt.Left.Attributes; var sqkpLeft = vt.Left.Proc.Attributes; var sqkRight = vt.Right.Attributes; var sqkpRight = vt.Right.Proc.Attributes; //save postconditions var leftPosts = vt.Left.Proc.Ensures; var rightPosts = vt.Right.Proc.Ensures; //The ensures must have been removed at the time of stripContracts //The recursive case is handled by RVT option anyway. //vt.Left.Proc.Ensures = new List<Ensures>(); //vt.Right.Proc.Ensures = new List<Ensures>(); //inline procedures under analysis vt.Left.Attributes = Util.MkInlinedAttribute(attList); vt.Left.Proc.Attributes = vt.Left.Attributes; vt.Right.Attributes = Util.MkInlinedAttribute(attList); vt.Right.Proc.Attributes = vt.Right.Attributes; //RUN INLINER OVER EQ FUNCTION vt.Left.OriginalBlocks = vt.Left.Blocks; vt.Left.OriginalLocVars = vt.Left.LocVars; vt.Right.OriginalBlocks = vt.Right.Blocks; vt.Right.OriginalLocVars = vt.Right.LocVars; // inline diff_inline procedures IEnumerable <Declaration> procImplPIter = prog.TopLevelDeclarations.Where(x => x is Implementation); foreach (Implementation currentProcImpl in procImplPIter) { if (currentProcImpl.Name.Contains("_Diff_Inline")) { currentProcImpl.Attributes = Util.MkInlinedAttribute(attList); currentProcImpl.Proc.Attributes = Util.MkInlinedAttribute(attList); //RUN INLINER OVER EQ FUNCTION currentProcImpl.OriginalBlocks = currentProcImpl.Blocks; currentProcImpl.OriginalLocVars = currentProcImpl.LocVars; } } // prog = EQ program // vt.Eq = EQ_f_f' procedure with f, f' having {inline} tags Inliner.ProcessImplementation(prog, vt.Eq); SDiffCounterexamples SErrors = null; List <Model> errModelList = null; Implementation newEq = null; Program newProg = null; Dictionary <string, Declaration> newDict = null; Log.Out(Log.Verifier, "Verifying " + vt.Eq.Name); if (Options.TraceVerify) { Log.Out(Log.Normal, "Ready to verify:"); Log.LogEmit(Log.Normal, prog.Emit); } // To print the EQ files in Util.DumpBplAST(prog, vt.Eq.Name + "_out.bpl"); //RS: Uncomment this /*if (wrapper) * { * prog.RemoveTopLevelDeclaration(vt.Eq); * prog.RemoveTopLevelDeclaration(vt.Eq.Proc); * }*/ prog = null; ReplaceInFile(vt.Eq.Name + "_out.bpl", "@", "_"); if (!wrapper) { prog = BoogieUtils.ParseProgram("RS" + vt.Eq.Name + "_out.bpl"); if (prog == null) { Log.Out(Log.Verifier, "Parse Error!!! in " + vt.Eq.Name); return(1); } if (BoogieUtils.ResolveAndTypeCheckThrow(prog, Options.MergedProgramOutputFile)) { return(1); } newEq = vt.Eq; newProg = prog; vcgen = InitializeVC(newProg); //SDiff.Boogie.Process.ResolveAndTypeCheck(newProg, ""); newDict = SDiff.Boogie.Process.BuildProgramDictionary(newProg.TopLevelDeclarations.ToList()); //RS: Uncomment this newEq = (Implementation)newDict.Get(vt.Eq.Name + "$IMPL"); vt.Result = VerifyImplementation(vcgen, newEq, newProg, out SErrors, out errModelList); switch (vt.Result) { case VerificationResult.Error: Log.Out(Log.Verifier, "Result: Error"); break; case VerificationResult.Verified: Log.Out(Log.Verifier, "Result: Verified"); break; case VerificationResult.OutOfMemory: Log.Out(Log.Verifier, "Result: OutOfMemory"); break; case VerificationResult.TimeOut: Log.Out(Log.Verifier, "Result: TimeOut"); break; default: Log.Out(Log.Verifier, "Result: Unhandled"); crashed = true; break; } vcgen.Close(); } //restore postconditions IN THE OLD IN-MEMORY PROGRAM vt.Left.Proc.Ensures = leftPosts; vt.Right.Proc.Ensures = rightPosts; //remove the inline annotation IN THE OLD IN-MEMORY PROGRAM vt.Left.Attributes = sqkLeft; vt.Left.Proc.Attributes = sqkpLeft; vt.Right.Attributes = sqkRight; vt.Right.Proc.Attributes = sqkpRight; //remove the inline annotation in the Diff_Inline Procedures foreach (Implementation currentProcImpl in procImplPIter) { if (currentProcImpl.Name.Contains("_Diff_Inline")) { currentProcImpl.Attributes = null; currentProcImpl.Proc.Attributes = null; } } if (!wrapper) { if (vt.Result != VerificationResult.Error) { return(0); //even timeouts/unhandled, as we see timeouts with 1 error, 0 model } //process counterexamples OVER THE NEW IN-MEMORY PROGRAM var outputVars = new List <Variable>(); foreach (var v in vt.DesiredOutputVars) { outputVars.Add(newDict.Get(v.Name + "$VAR") as Variable); } var globals = new List <Variable>(); foreach (IdentifierExpr ie in newEq.Proc.Modifies) { globals.Add(ie.Decl); } if (SErrors != null && SErrors.Count > 0 && errModelList.Count == SErrors.Count) //change as now SErrors can be nonnull, yet Count == 0. Sometimes model.Count < SErrror!! { //somewhat misnamed... if (Options.DumpBeforeVerifying) { Log.Out(Log.SymEx, "Dumping procedure under verification"); newEq.Emit(Log.LogWriter, 0); } if (Options.DoSymEx) { var vtLeftProcImpl = (Implementation)Util.getDeclarationByName(vt.Left.Name + "_Diff_Inline", procImplPIter); var vtRightProcImpl = (Implementation)Util.getDeclarationByName(vt.Right.Name + "_Diff_Inline", procImplPIter); if (Options.PreciseDifferentialInline) { List <Declaration> consts = prog.TopLevelDeclarations.Where(x => x is Constant).ToList(); ProcessCounterexamplesWOSymbolicOut(SErrors, globals, vt.Eq.LocVars, vtLeftProcImpl, vtRightProcImpl, consts, errModelList); } else { ProcessCounterexamples(SErrors, globals, outputVars, newProg, vtLeftProcImpl, vtRightProcImpl); } } } return(SErrors == null ? 0 : SErrors.Count); } return(0); }
static void Main(string[] args) { if (args.Count() < 3) { Console.WriteLine("Usage: v1.bpl v2.bpl v1v2.config"); Console.WriteLine(" The source files are implicitly specified inside the bpl files"); Console.WriteLine(" v1v2.config: a mapping between entities in v1.bpl and v2.bpl (default generated by SymDiff.exe -inferConfig v1.bpl v2.bpl)"); return; } if (args.Any(x => x == "-break")) { Debugger.Launch(); } var CoarseDiff = args.Any(x => x.Contains("/coarseDiff")); BoogieUtils.InitializeBoogie(""); var v1 = args[0]; var v2 = args[1]; v1v2Config = new SDiff.Config(args[2]); Debug.Assert(v1v2Config != null); var v1Prog = BoogieUtils.ParseProgram(v1); var v2Prog = BoogieUtils.ParseProgram(v2); var v1srcInfo = new SourceInfoManager(v1Prog, Path.GetDirectoryName(v1)); v1srcInfo.ComputeSourceInfoForImplementations(); var v2srcInfo = new SourceInfoManager(v2Prog, Path.GetDirectoryName(v2)); v2srcInfo.ComputeSourceInfoForImplementations(); //remove any sourcefile/sourceline info before doing a syntactic diff new RemoveSrcInfoStmts().Visit(v1Prog); new RemoveSrcInfoStmts().Visit(v2Prog); var v1Changes = new List <string>(); var v2Changes = new List <string>(); //remove those implementations that are syntactically identical var diffImpls = GetImplementationPairs(v1Prog, v2Prog); if (CoarseDiff) { diffImpls = diffImpls.Where(pair => !IsEqualStringRepresentation(pair.Item1, pair.Item2)); foreach (var implPair in diffImpls) { if (implPair.Item1 != null) { v1Changes.AddRange(FormatChangedLinesForProcedure(implPair.Item1.Name, new List <int>() { 0 }, v1srcInfo.srcInfoPerImpl[implPair.Item1].Item1)); } if (implPair.Item2 != null) { v2Changes.AddRange(FormatChangedLinesForProcedure(implPair.Item2.Name, new List <int>() { 0 }, v2srcInfo.srcInfoPerImpl[implPair.Item2].Item1)); } } } else { //perform the diff on the source files in which the implemnation pair is present foreach (var i12 in diffImpls) { var d12 = FindDiffSourceLinesInImplementation(i12.Item1, v1srcInfo, i12.Item2, v2srcInfo); if (i12.Item1 != null) { v1Changes.AddRange(FormatChangedLinesForProcedure(i12.Item1.Name, d12.Item1, v1srcInfo.srcInfoPerImpl[i12.Item1].Item1)); } if (i12.Item2 != null) { v2Changes.AddRange(FormatChangedLinesForProcedure(i12.Item2.Name, d12.Item2, v2srcInfo.srcInfoPerImpl[i12.Item2].Item1)); } } } PrintChangedLinesToFile(v1Changes, Path.Combine(Path.GetDirectoryName(v1), v1 + "_changed_lines.txt")); PrintChangedLinesToFile(v2Changes, Path.Combine(Path.GetDirectoryName(v2), v2 + "_changed_lines.txt")); return; }