Пример #1
0
        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);
        }
Пример #2
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);
        }
Пример #3
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");
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
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);
        }
Пример #7
0
        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);
            }
        }
Пример #8
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);
        }
Пример #9
0
        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);
        }
Пример #10
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);
        }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
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;
        }