Esempio n. 1
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]");
                return;
            }

            if (args.Any(a => a == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            if (args.Any(a => a == "/initMem"))
            {
                initMem = true;
            }


            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;


            // Read the input file
            var program = BoogieUtil.ReadAndResolve(args[0]);

            // Process it
            program = Process(program);

            // write the output
            BoogieUtil.PrintProgram(program, args[1]);
        }
Esempio n. 2
0
        public InsertAtBeginningRule(string plhs, string prhs, string globalDecls)
            : base(plhs, prhs, globalDecls)
        {
            //ProcedureToMatchToInsertion = new Dictionary<Procedure, List<Cmd>>();
            ProcedureToMatchToInsertion = new Dictionary <Implementation, List <Cmd> >();

            //bit hacky: we need to get the delcaration code for each procedure..
            // .. and we want them preferably without the semicolon..
            var procStrings = new List <string>((plhs.Split(new char[] { ';' })));

            procStrings.RemoveAt(procStrings.Count - 1);

            //we need a separate insertion for every progstring because the IdentifierExpression pointing
            // to one of the parameters must refer to the declaration in the procedure declaration..
            foreach (var procString in procStrings)
            {
                Program prog;
                string  progString = globalDecls + procString + "{\n" + prhs + "\n}";
                Parser.Parse(progString, "dummy.bpl", out prog);
                BoogieUtil.ResolveProgram(prog, "dummy.bpl");

                //Assumes that the only Implementation(s) correspond to those from ProcedureRule, and not in GlobalDeclarations
                //Debug.Assert(prog.Implementations.Count() == 1, "No implementations in property file allowed other than in ProcedureRule");
                //ProcedureToMatchToInsertion.Add(prog.Implementations.First(), prog.Implementations.First().Blocks.First().Cmds);

                //HACKY!!! Assumes that Implementations are ordered as they appear in the file, and GlobalDeclarations appear ahead of PF
                ProcedureToMatchToInsertion.Add(prog.Implementations.Last(), prog.Implementations.Last().Blocks.First().Cmds);
            }
        }
        // precondition: pathProgram has a single implementation
        // Suppress an assertion (that failed in the pathProgram) and
        // return its token
        public AssertToken SuppressAssert(Program pathProgram)
        {
            var impl = pathProgram.TopLevelDeclarations.OfType <Implementation>()
                       .First();

            var tokenId = -1;

            foreach (var acmd in impl.Blocks[0].Cmds.OfType <PredicateCmd>())
            {
                tokenId = QKeyValue.FindIntAttribute(acmd.Attributes, "avn", -1);
                if (tokenId == -1)
                {
                    continue;
                }
                break;
            }

            Debug.Assert(tokenId != -1);
            var token = new AssertToken(tokenId);

            SuppressToken(token);

            BoogieUtil.DoModSetAnalysis(currProg);

            suppressedTokens.Add(token);

            return(token);
        }
        private void UnsuppressToken(AssertToken token)
        {
            var location = tokenLocation[token];
            var p        = BoogieUtil.findProcedureImpl(currProg.TopLevelDeclarations, location.Item1);
            var block    = p.Blocks.Where(blk => blk.Label == location.Item2).FirstOrDefault();

            // disable assignment to assertsPassed
            var ncmds = new List <Cmd>();

            foreach (var cmd in block.Cmds)
            {
                if (!Options.DeepAsserts && cmd is AssumeCmd && QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "suppressAssert", -1) == token.id)
                {
                    ncmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssumeCmd).Expr));
                }
                else if (Options.DeepAsserts && cmd is AssumeCmd &&
                         QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "avn", -1) == token.id)
                {
                    ncmds.Add(new AssertCmd(Token.NoToken, (cmd as AssertCmd).Expr, (cmd as AssertCmd).Attributes));
                }
                else
                {
                    ncmds.Add(cmd);
                }
            }
            block.Cmds = ncmds;
        }
Esempio n. 5
0
        // Verify that the trace is a valid counterexample (i.e., it returns an assertion-failure counterexample
        // upon verification.
        // Returns a program that consists of a single implementation with a single basic
        // block that contains the trace.
        public bool verifyTrace(out Program newProg)
        {
            // Currently, this only works for intraprocedural traces
            Debug.Assert(acex.calleeCounterexamples.Count == 0);

            HashSet <string> calledProcs;
            Implementation   traceImpl = getImplementation(out calledProcs);

            newProg = new Program();

            // The set of called procedures should only be ones
            // that do not have an implementation
            foreach (Declaration decl in prog.TopLevelDeclarations)
            {
                if (decl is GlobalVariable)
                {
                    newProg.AddTopLevelDeclaration(decl);
                }
                else if (decl is Procedure)
                {
                    Procedure tmp = decl as Procedure;
                    if (calledProcs.Contains(tmp.Name))
                    {
                        newProg.AddTopLevelDeclaration(decl);
                    }
                    else if (tmp.Name == impl.Name)
                    {
                        Procedure pex = new Procedure(Token.NoToken, tmp.Name + "_cex", tmp.TypeParameters, tmp.InParams,
                                                      tmp.OutParams, tmp.Requires, tmp.Modifies, tmp.Ensures, tmp.Attributes);
                        newProg.AddTopLevelDeclaration(pex);
                    }
                }
                else if (decl is Implementation)
                {
                    Implementation tmp = decl as Implementation;
                    Debug.Assert(!calledProcs.Contains(tmp.Name));
                }
                else
                {
                    // Just add the other guys (axioms, functions, etc.)
                    newProg.AddTopLevelDeclaration(decl);
                }
            }

            newProg.AddTopLevelDeclaration(traceImpl);

            newProg = BoogieUtil.ReResolve(newProg, "cex.bpl");
            Program newProgCopy = BoogieUtil.ReadAndResolve("cex.bpl");
            // (We need to create a copy because Boogie.Verify changes the input program)

            var errors = new List <BoogieErrorTrace>();
            var ret    = BoogieVerify.Verify(newProgCopy, out errors);

            if (ret != BoogieVerify.ReturnStatus.NOK)
            {
                return(false);
            }

            return(true);
        }
        // convert {:Ebasic} to {:Ebasic n}
        void NameEnvironmentConstraints(Program program)
        {
            procsWithEnvAssumptions = new HashSet <string>();

            var cnt     = 0;
            var AddAttr = new Action <Implementation, Cmd>((impl, cmd) =>
            {
                var acmd = cmd as AssumeCmd;
                if (acmd == null)
                {
                    return;
                }
                if (!QKeyValue.FindBoolAttribute(acmd.Attributes, AvnAnnotations.EnvironmentAssumptionAttr))
                {
                    return;
                }

                acmd.Attributes = BoogieUtil.removeAttr(AvnAnnotations.EnvironmentAssumptionAttr, acmd.Attributes);
                acmd.Attributes = new QKeyValue(Token.NoToken, AvnAnnotations.EnvironmentAssumptionAttr, new List <object> {
                    Expr.Literal(cnt)
                }, acmd.Attributes);
                cnt++;
                procsWithEnvAssumptions.Add(impl.Name);
            });

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var block in impl.Blocks)
                {
                    block.Cmds.Iter(c => AddAttr(impl, c));
                }
            }
        }
Esempio n. 7
0
        void Instrument(Implementation impl)
        {
            var varDecls = new Dictionary <string, string>();
            var cb       = new CollectBasePointer(varDecls);

            cb.VisitImplementation(impl);
            foreach (var block in impl.Blocks)
            {
                var newcmds = new List <Cmd>();
                foreach (Cmd cmd in block.Cmds)
                {
                    if (cmd is AssumeCmd && BoogieUtil.checkAttrExists("nonnull", (cmd as AssumeCmd).Attributes))
                    {
                        continue;
                    }
                    if (cmd is AssignCmd)
                    {
                        newcmds.AddRange(ProcessAssign(cmd as AssignCmd, varDecls));
                    }
                    else if (cmd is AssumeCmd)
                    {
                        newcmds.AddRange(ProcessAssume(cmd as AssumeCmd, varDecls));
                    }
                    else if (cmd is CallCmd)
                    {
                        newcmds.AddRange(ProcessCall(cmd as CallCmd, varDecls));
                    }
                    else
                    {
                        newcmds.Add(cmd);
                    }
                }
                block.Cmds = newcmds;
            }
        }
Esempio n. 8
0
            private void ChangeStubsIntoUnkowns()
            {
                var procsWithImpl = prog.TopLevelDeclarations.OfType <Implementation>()
                                    .Select(x => x.Proc);
                var procs = prog.TopLevelDeclarations.OfType <Procedure>();

                // remove procedures that are never called
                var procsUsed = new HashSet <string>();

                prog.TopLevelDeclarations.OfType <Implementation>()
                .Iter(impl => impl.Blocks
                      .Iter(blk => blk.cmds.OfType <CallCmd>()
                            .Iter(cc => procsUsed.Add(cc.callee))));

                //TODO: this can be almost quadratic in the size of |Procedures|, cleanup
                var procsWithoutImpl = procs.Where(x => !procsWithImpl.Contains(x) && procsUsed.Contains(x.Name));

                var stubImpls = new List <Implementation>();

                foreach (var p in procsWithoutImpl)
                {
                    if (BoogieUtil.checkAttrExists("allocator", p.Attributes))
                    {
                        continue;
                    }
                    MkStubImplementation(stubImpls, p);
                }
                prog.AddTopLevelDeclarations(stubImpls);
            }
Esempio n. 9
0
        public void ComputePreconditions()
        {
            var NameToImpl = new Func <string, Implementation>(name =>
                                                               BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, name));
            var main = id2Graph[program.mainProcName];

            main.UpdatePrecondition(main.precondition.Top(NameToImpl(main.Id)));

            IntraGraph.TopDown = true;
            var worklist = new SortedSet <IntraGraph>(main);

            worklist.Add(main);

            var SetPrecondition = new Action <string, IWeight>((name, weight) =>
            {
                var g       = id2Graph[name];
                var changed = g.UpdatePrecondition(weight);
                if (changed)
                {
                    worklist.Add(g);
                }
            });

            while (worklist.Any())
            {
                var proc = worklist.First();
                worklist.Remove(proc);
                proc.PropagatePrecondition(NameToImpl, SetPrecondition);
            }

            IntraGraph.TopDown = false;
        }
Esempio n. 10
0
        public override Expr VisitNAryExpr(NAryExpr node)
        {
            var nArgs = node.Args.Select(x => base.VisitExpr(x)).ToList();

            node.Args = nArgs;
            var fcall = node.Fun as FunctionCall;

            if (fcall != null && fcall.Func.HasAttribute(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn))
            {
                var formals = new List <Variable>();
                fcall.Func.InParams.Iter(a =>
                {
                    var z = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, a.Name, a.TypedIdent.Type), true);
                    formals.Add(z);
                });
                var r = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "r", fcall.Func.OutParams[0].TypedIdent.Type), false);

                var f = new Function(Token.NoToken, fcall.FunctionName + "__" + uniqFuncs.Count,
                                     formals, r);
                //inherit all attributes other than mkUniqueFn
                f.Attributes = BoogieUtil.removeAttr(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn, fcall.Func.Attributes);
                f.Body       = fcall.Func.Body;
                uniqFuncs.Add(f);
                program.AddTopLevelDeclaration(f);
                node.Fun = new FunctionCall(f);
            }
            return(node);
        }
Esempio n. 11
0
        public static VarSet GetAllVars(Program p)
        {
            //List<GlobalVariable> globalDecls = BoogieUtil.GetGlobalVariables(p);
            var procedures      = BoogieUtil.GetProcedures(p);
            var implementations = BoogieUtil.GetImplementations(p);
            var allVars         = new VarSet();

            foreach (var proc in procedures)
            {
                var uses = new GlobalVarsUsed();
                uses.VisitRequiresSeq(proc.Requires);
                uses.VisitEnsuresSeq(proc.Ensures);
                // skip visiting modifies clause
                allVars.Add(new VarSet(uses.globalsUsed, proc.Name));
            }

            foreach (var impl in implementations)
            {
                var uses = new GlobalVarsUsed();
                uses.VisitBlockList(impl.Blocks);
                allVars.Add(new VarSet(uses.globalsUsed, impl.Name));
            }

            //globalDecls.Iterate(x => procedures.Iterate(y => allVars.Add(x.Name, y.Name)));
            //globalDecls.Iterate(x => implementations.Iterate(y => allVars.Add(x.Name, y.Name)));
            return(allVars);
        }
Esempio n. 12
0
        public CmdRule(string plhs, string prhs, string pDeclarations)
            : base(plhs, prhs, pDeclarations)
        {
            var rhs = prhs;

            //allow keyword-command "#this;" instead of "call #this;":
            Debug.Assert(!Regex.Match(rhs, @"call\s* #this\(\)\s*;").Success, "call #this(); syntax is deprecated");
            const string onlyThisPattern = @"#this\s*;";
            var          onlyThisMatch   = Regex.Match(rhs, onlyThisPattern);

            if (onlyThisMatch.Success)
            {
                rhs = Regex.Replace(rhs, onlyThisPattern, "call #this();");
            }

            Program prog;
            string  progString = string.Format(CmdTemplate, pDeclarations, plhs, rhs);

            Parser.Parse(progString, "dummy.bpl", out prog);
            BoogieUtil.ResolveProgram(prog, "dummy.bpl");

            CmdsToMatch = new List <Cmd>();
            CmdsToMatch.AddRange(prog.Implementations.ElementAt(0).Blocks.First().Cmds);

            InsertionTemplate = new List <Cmd>();
            InsertionTemplate.AddRange(prog.Implementations.ElementAt(1).Blocks.First().Cmds);
            Prog = prog;
        }
Esempio n. 13
0
        bool IsAssumeNonNull(Cmd cmd)
        {
            var acmd = cmd as AssumeCmd;

            if (acmd == null)
            {
                return(false);
            }

            if (BoogieUtil.checkAttrExists("partition", acmd.Attributes))
            {
                return(false);
            }

            var expr = acmd.Expr as NAryExpr;

            if (expr == null)
            {
                return(false);
            }

            var exprIsNull = new Predicate <Expr>(e =>
            {
                return((e is IdentifierExpr) && (e as IdentifierExpr).Name == "null");
            });

            if (expr.Fun is BinaryOperator && (expr.Fun as BinaryOperator).Op == BinaryOperator.Opcode.Neq &&
                (exprIsNull(expr.Args[0]) || exprIsNull(expr.Args[1])))
            {
                return(true);
            }
            return(false);
        }
Esempio n. 14
0
        private void GenVC(Implementation impl)
        {
            ModelViewInfo          mvInfo;
            Dictionary <int, Absy> label2absy;

            vcgen.ConvertCFG2DAG(impl);
            vcgen.PassifyImpl(impl, out mvInfo);

            var gen    = prover.VCExprGen;
            var vcexpr = vcgen.GenerateVC(impl, null, out label2absy, prover.Context);

            // Create a macro so that the VC can sit with the theorem prover
            Macro macro = new Macro(Token.NoToken, impl.Name + "Macro", new List <Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false));

            prover.DefineMacro(macro, vcexpr);

            // Store VC
            impl2VC.Add(impl.Name, gen.Function(macro));

            //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr);

            // Find the assert
            impl2EndStateVars.Add(impl.Name, new List <VCExpr>());
            var found = false;

            foreach (var blk in impl.Blocks)
            {
                foreach (var cmd in blk.Cmds.OfType <AssertCmd>())
                {
                    if (BoogieUtil.isAssertTrue(cmd))
                    {
                        continue;
                    }
                    var nary = cmd.Expr as NAryExpr;
                    if (nary == null)
                    {
                        continue;
                    }
                    var pred = nary.Fun as FunctionCall;
                    if (pred == null || pred.FunctionName != (impl.Name + (AbstractHoudini.summaryPredSuffix)))
                    {
                        continue;
                    }

                    Debug.Assert(!found);
                    found = true;
                    nary.Args.OfType <Expr>()
                    .Iter(expr => impl2EndStateVars[impl.Name].Add(prover.Context.BoogieExprTranslator.Translate(expr)));
                }
            }
            Debug.Assert(found);

            // Grab summary predicates
            var visitor = new FindSummaryPred(prover.VCExprGen);

            visitor.Mutate(vcexpr, true);

            impl2CalleeSummaries.Add(impl.Name, new List <Tuple <string, VCExprNAry> >());
            visitor.summaryPreds.Iter(tup => impl2CalleeSummaries[impl.Name].Add(tup));
        }
Esempio n. 15
0
        private void attachEnsures(Implementation impl)
        {
            List <Variable> functionInterfaceVars = new List <Variable>();

            foreach (Variable v in BoogieUtil.GetGlobalVariables(vcgen.program))
            {
                functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true));
            }
            foreach (Variable v in impl.InParams)
            {
                functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true));
            }
            foreach (Variable v in impl.OutParams)
            {
                functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true));
            }
            foreach (IdentifierExpr e in impl.Proc.Modifies)
            {
                if (e.Decl == null)
                {
                    continue;
                }
                functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", e.Decl.TypedIdent.Type), true));
            }
            Formal returnVar = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false);
            var    function  = new Function(Token.NoToken, impl.Name + summaryPredSuffix, functionInterfaceVars, returnVar);

            prover.Context.DeclareFunction(function, "");

            List <Expr> exprs = new List <Expr>();

            foreach (Variable v in BoogieUtil.GetGlobalVariables(vcgen.program))
            {
                Contract.Assert(v != null);
                exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
            }
            foreach (Variable v in impl.Proc.InParams)
            {
                Contract.Assert(v != null);
                exprs.Add(new IdentifierExpr(Token.NoToken, v));
            }
            foreach (Variable v in impl.Proc.OutParams)
            {
                Contract.Assert(v != null);
                exprs.Add(new IdentifierExpr(Token.NoToken, v));
            }
            foreach (IdentifierExpr ie in impl.Proc.Modifies)
            {
                Contract.Assert(ie != null);
                if (ie.Decl == null)
                {
                    continue;
                }
                exprs.Add(ie);
            }
            Expr postExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs);

            impl.Proc.Ensures.Add(
                new Ensures(Token.NoToken, false, postExpr, ""));
        }
        private static void ComputeCallGraph(Program program)
        {
            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl =>
            {
                Succ.Add(impl.Name, new HashSet <Implementation>());
                Pred.Add(impl.Name, new HashSet <Implementation>());
            });

            var name2Impl = BoogieUtil.nameImplMapping(program);

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var blk in impl.Blocks)
                {
                    foreach (var cmd in blk.Cmds.OfType <CallCmd>())
                    {
                        if (!Succ.ContainsKey(cmd.callee))
                        {
                            continue;
                        }
                        Succ[impl.Name].Add(name2Impl[cmd.callee]);
                        Pred[cmd.callee].Add(impl);
                    }
                }
            }
        }
Esempio n. 17
0
        // Prune away EntryPoints that cannot reach an assertion
        static void PruneRedundantEntryPoints(Program program)
        {
            var procs = BoogieUtil.procsThatMaySatisfyPredicate(program, cmd => (cmd is AssertCmd && !BoogieUtil.isAssertTrue(cmd)));

            procs = harnessInstrumentation.entrypoints.Difference(procs);
            Console.WriteLine("Pruning away {0} entry points as they cannot reach an assert", procs.Count);
            harnessInstrumentation.PruneEntryPoints(program, procs);
        }
 public WorkItemR(Implementation i, string l)
 {
     impl          = i;
     labelBlockMap = BoogieUtil.labelBlockMapping(impl);
     label         = l;
     block         = getBlock(label, labelBlockMap);
     count         = 0;
 }
        public static bool getSourceInfo(Cmd cmd, out string file, out int line, out int column, out bool keepCmd)
        {
            file    = null;
            line    = -1;
            column  = -1;
            keepCmd = true;

            var acmd = cmd as PredicateCmd;

            if (acmd == null)
            {
                return(false);
            }

            var attr = BoogieUtil.getAttr("sourceloc", acmd.Attributes);

            if (attr != null && attr.Count == 3)
            {
                file = attr[0] as string;
                var tt = attr[1] as LiteralExpr;
                if (tt != null && (tt.Val is Microsoft.Basetypes.BigNum))
                {
                    line = ((Microsoft.Basetypes.BigNum)(tt.Val)).ToInt;
                }
                tt = attr[2] as LiteralExpr;
                if (tt != null && (tt.Val is Microsoft.Basetypes.BigNum))
                {
                    column = ((Microsoft.Basetypes.BigNum)(tt.Val)).ToInt;
                }
            }
            else
            {
                file = QKeyValue.FindStringAttribute(acmd.Attributes, "sourceFile");
                if (file == null)
                {
                    file = QKeyValue.FindStringAttribute(acmd.Attributes, "sourcefile");
                }
                line = QKeyValue.FindIntAttribute(acmd.Attributes, "sourceLine", -1);
                if (line == -1)
                {
                    line = QKeyValue.FindIntAttribute(acmd.Attributes, "sourceline", -1);
                }
            }

            if (file == null || line == -1)
            {
                return(false);
            }

            if (acmd.Expr is LiteralExpr && (acmd.Expr as LiteralExpr).IsTrue)
            {
                keepCmd = false;
            }

            return(true);
        }
Esempio n. 20
0
        static void MarkEntryPoint(Program program, string proc)
        {
            // remove existing entrypoints
            program.TopLevelDeclarations.OfType <NamedDeclaration>()
            .Iter(decl => decl.Attributes = BoogieUtil.removeAttr("entrypoint", decl.Attributes));

            program.TopLevelDeclarations.OfType <Implementation>()
            .Where(impl => impl.Name == proc)
            .Iter(impl => impl.Proc.AddAttribute("entrypoint"));
        }
Esempio n. 21
0
 static void Initalize(string boogieOptions)
 {
     CommandLineOptions.Install(new CommandLineOptions());
     CommandLineOptions.Clo.PrintInstrumented = true;
     CommandLineOptions.Clo.UseSubsumption    = CommandLineOptions.SubsumptionOption.Never;
     CommandLineOptions.Clo.ContractInfer     = true;
     BoogieUtil.InitializeBoogie(boogieOptions);
     CommandLineOptions.Clo.ErrorLimit = 1;
     cba.Util.BoogieVerify.options     = new BoogieVerifyOptions();
 }
Esempio n. 22
0
        public void Unify(string outfile)
        {
            // Gather all maps
            AllMaps = new HashSet <string>();

            program.TopLevelDeclarations
            .OfType <GlobalVariable>()
            .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt)
            .Iter(g => AllMaps.Add(g.Name));

            // Fix Cmds
            program.TopLevelDeclarations
            .OfType <Implementation>()
            .Iter(impl =>
                  impl.Blocks.Iter(block =>
                                   block.Cmds
                                   .OfType <Cmd>().Iter(cmd => Visit(cmd))));

            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitEnsuresSeq(p.Ensures));
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitRequiresSeq(p.Requires));

            var impls = new HashSet <string>();

            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => impls.Add(impl.Name));

            program.TopLevelDeclarations.OfType <Procedure>()
            .Where(p => impls.Contains(p.Name))
            .Iter(p => p.Modifies = new List <IdentifierExpr>());
            program.TopLevelDeclarations.OfType <Procedure>()
            .Iter(p => VisitIdentifierExprSeq(p.Modifies));

            // Remove globals
            var newDecls = new List <Declaration>();

            foreach (var decl in program.TopLevelDeclarations)
            {
                var glob = decl as GlobalVariable;
                if (glob == null || !AllMaps.Contains(glob.Name))
                {
                    newDecls.Add(decl);
                }
            }

            program.TopLevelDeclarations = newDecls;
            program.AddTopLevelDeclaration(U);

            // print program
            BoogieUtil.DoModSetAnalysis(program);
            BoogieUtil.PrintProgram(program, outfile);

            program = null;
        }
Esempio n. 23
0
        public override Expr VisitIdentifierExpr(IdentifierExpr node)
        {
            if (!Matches ||
                _toConsume.Count == 0)
            {
                Matches = false;
                return(base.VisitIdentifierExpr(node));
            }

            // check if we need to switch to anyExprMode
            if (_toConsume.Peek() is NAryExpr &&
                (((NAryExpr)_toConsume.Peek()).Fun) is FunctionCall &&
                BoogieUtil.checkAttrExists(BoogieKeyWords.AnyExpr, ((FunctionCall)((NAryExpr)_toConsume.Peek()).Fun).Func.Attributes))
            {
                _anyExprMode = true;

                _toConsume.Pop();
                ((NAryExpr)_toConsume.Peek()).Args.Iter(arg => _toConsume.Push(arg));
                var result = VisitIdentifierExpr(node);

                _anyExprMode = false;

                return(result);
            }

            if (!(_toConsume.Peek() is IdentifierExpr))
            {
                Matches = false;
                return(base.VisitIdentifierExpr(node));
            }

            var idexToConsume = (IdentifierExpr)_toConsume.Peek();

            if (idexToConsume.Decl != null)
            {
                if (Equals(node.Decl.TypedIdent.Type, idexToConsume.Decl.TypedIdent.Type) &&
                    AreAttributesASubset(idexToConsume.Decl.Attributes, node.Decl.Attributes))
                {
                    Substitution.Add(idexToConsume.Decl, node);
                    _toConsume.Pop();
                }
                else
                {
                    Matches = false;
                }
                return(base.VisitIdentifierExpr(node));
            }
            if (idexToConsume.Name == node.Name)
            {
                return(base.VisitIdentifierExpr(node));
            }

            Matches = false;
            return(base.VisitIdentifierExpr(node));
        }
Esempio n. 24
0
        //TODO: collect some stats about the instrumentation, mb some debugging output??

        private static void Main(string[] args)
        {
            if (args.Length < 3)
            {
                Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl");
                return;
            }

            if (args.Any(s => s == "/break"))
            {
                System.Diagnostics.Debugger.Launch();
            }

            // initialize Boogie
            CommandLineOptions.Install(new CommandLineOptions());
            CommandLineOptions.Clo.PrintInstrumented = true;

            // read the boogie program that is to be instrumented
            var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false);

            // parse the property file
            var         propLines = File.ReadLines(args[0]);
            string      globalDeclarations;
            List <Rule> rules;

            CreateRulesFromProperty(propLines, out globalDeclarations, out rules);

            // GlobalDeclarations: add the global declarations from the property to the Boogie program
            Program dummyProg;

            Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg);
            boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations);

            //resolve the program with the new declarations which may include funcs and procs with bodies
            boogieProgram.Resolve();

            // CmdRule: find insertions sites (Commands), insert code there
            InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>());

            // InsertAtBeginningRule: find insertion sites (Procedures), insert code there
            InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>());

            // make functions with {:mkUniqueFn} unique
            (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram);

            //augment the CorralExtraInit procedure (perform this after Matching/instrumentation)
            AugmentCorralExtraInit(boogieProgram);

            string outputFile = args[2];

            BoogieUtil.PrintProgram(boogieProgram, outputFile);

            Stats.printStats();
        }
Esempio n. 25
0
 public static bool checkFunctionsAreInlined(Program program)
 {
     foreach (var func in program.TopLevelDeclarations.OfType <Function>())
     {
         if (func.Body != null && !BoogieUtil.checkAttrExists("inline", func.Attributes))
         {
             Console.WriteLine("Function {0} does not have an inline attribute", func.Name);
             return(false);
         }
     }
     return(true);
 }
Esempio n. 26
0
        // Prune away non-candidates, verify using the rest
        static BoogieVerify.ReturnStatus PruneAndRun(PersistentProgram inp, HashSet <string> candidates, out HashSet <string> assignment, ref int inlined)
        {
            var program = inp.getProgram();

            program.Typecheck();

            program = BoogieUtil.ReResolve(program);

            // Remove non-candidates
            CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, candidates, true);
            program.RemoveTopLevelDeclarations(decl => (decl is Constant) && QKeyValue.FindBoolAttribute(decl.Attributes, "existential") &&
                                               !candidates.Contains((decl as Constant).Name));

            //BoogieUtil.PrintProgram(program, "hi_query" + IterCnt + ".bpl");

            // Run Houdini
            var ot = CommandLineOptions.Clo.ProverKillTime;

            CommandLineOptions.Clo.ProverKillTime = HoudiniTimeout;
            assignment = CoreLib.HoudiniInlining.RunHoudini(program, true);
            CommandLineOptions.Clo.ProverKillTime = ot;
            //Console.WriteLine("  >> Contracts: {0}", assignment.Count);

            // Read the program again, add contracts
            program = inp.getProgram();
            program.Typecheck();

            CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment);
            //BoogieUtil.PrintProgram(program, "si_query" + IterCnt + ".bpl");

            // Run SI
            var err = new List <BoogieErrorTrace>();

            // Set bound
            BoogieVerify.options.maxInlinedBound = 0;
            if (inlined != 0)
            {
                BoogieVerify.options.maxInlinedBound = PerfMetric(inlined);
            }

            var rstatus = BoogieVerify.Verify(program, out err, true);

            //Console.WriteLine(string.Format("  >> Procedures Inlined: {0}", BoogieVerify.CallTreeSize));
            //Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2")));

            inlined = BoogieVerify.CallTreeSize + 1;
            BoogieVerify.options.CallTree = new HashSet <string>();
            BoogieVerify.CallTreeSize     = 0;
            BoogieVerify.verificationTime = TimeSpan.Zero;

            return(rstatus);
        }
Esempio n. 27
0
        // Rename basic blocks, local variables
        // Add "havoc locals" at the beginning
        // block return
        private static void RenameImpl(Implementation impl, Dictionary <string, Tuple <Block, Implementation> > origProg)
        {
            var origImpl   = (new FixedDuplicator(true)).VisitImplementation(impl);
            var origBlocks = BoogieUtil.labelBlockMapping(origImpl);

            // create new locals
            var newLocals = new Dictionary <string, Variable>();

            foreach (var l in impl.LocVars.Concat(impl.InParams).Concat(impl.OutParams))
            {
                // substitute even formal variables with LocalVariables. This is fine
                // because we finally just merge all implemnetations together
                var nl = BoogieAstFactory.MkLocal(l.Name + "_" + impl.Name + "_copy", l.TypedIdent.Type);
                newLocals.Add(l.Name, nl);
            }

            // rename locals
            var subst = new VarSubstituter(newLocals, new Dictionary <string, Variable>());

            subst.VisitImplementation(impl);

            // Rename blocks
            foreach (var blk in impl.Blocks)
            {
                var newName = impl.Name + "_" + blk.Label;
                origProg.Add(newName, Tuple.Create(origBlocks[blk.Label], origImpl));
                blk.Label = newName;

                if (blk.TransferCmd is GotoCmd)
                {
                    var gc = blk.TransferCmd as GotoCmd;
                    gc.labelNames = new List <string>(
                        gc.labelNames.Select(lab => impl.Name + "_" + lab));
                }

                if (blk.TransferCmd is ReturnCmd)
                {
                    // block return
                    blk.Cmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                }
            }

            /*
             * // havoc locals -- not necessary
             * if (newLocals.Count > 0)
             * {
             *  var ies = new List<IdentifierExpr>();
             *  newLocals.Values.Iter(v => ies.Add(Expr.Ident(v)));
             *  impl.Blocks[0].Cmds.Insert(0, new HavocCmd(Token.NoToken, ies));
             * }
             */
        }
        // Adds a new main:
        //   assertsPassed := true;
        //   call main();
        //   assert assertsPassed;
        string addMain(CBAProgram program)
        {
            var dup      = new FixedDuplicator();
            var origMain = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, program.mainProcName);
            var newMain  = dup.VisitImplementation(origMain);
            var newProc  = dup.VisitProcedure(origMain.Proc);

            newMain.Name += "_SeqInstr";
            newProc.Name += "_SeqInstr";
            newMain.Proc  = newProc;

            var mainIns = new List <Expr>();

            foreach (Variable v in newMain.InParams)
            {
                mainIns.Add(Expr.Ident(v));
            }
            var mainOuts = new List <IdentifierExpr>();

            foreach (Variable v in newMain.OutParams)
            {
                mainOuts.Add(Expr.Ident(v));
            }

            var callMain = new CallCmd(Token.NoToken, program.mainProcName, mainIns, mainOuts);

            callMain.Proc = origMain.Proc;

            var cmds = new List <Cmd>();

            cmds.Add(BoogieAstFactory.MkVarEqConst(assertsPassed, true));
            cmds.Add(callMain);
            cmds.Add(new AssertCmd(Token.NoToken, Expr.Ident(assertsPassed)));

            var blk = new Block(Token.NoToken, "start", cmds, new ReturnCmd(Token.NoToken));

            newMain.Blocks = new List <Block>();
            newMain.Blocks.Add(blk);

            program.AddTopLevelDeclaration(newProc);
            program.AddTopLevelDeclaration(newMain);

            program.mainProcName = newMain.Name;

            // Set entrypoint
            origMain.Attributes      = BoogieUtil.removeAttr("entrypoint", origMain.Attributes);
            origMain.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", origMain.Proc.Attributes);

            newMain.AddAttribute("entrypoint");

            return(newMain.Name);
        }
Esempio n. 29
0
            // Remove the dispatch to certain entrypoints
            public static void RemoveEntryPoints(Program program, HashSet <string> procs)
            {
                var mainImpl = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, AvnAnnotations.CORRAL_MAIN_PROC);

                foreach (var block in mainImpl.Blocks)
                {
                    if (block.Cmds.OfType <CallCmd>().Any(cc => procs.Contains(cc.callee)))
                    {
                        block.Cmds.Clear();
                    }
                }
                BoogieUtil.pruneProcs(program, mainImpl.Name);
            }
Esempio n. 30
0
        public void VisitImplementation(Implementation impl)
        {
            // callee -> id
            var cnt = new Dictionary <string, int>();

            foreach (var block in impl.Blocks)
            {
                var callcnt = 0;
                for (int i = 0; i < block.Cmds.Count; i++)
                {
                    var cc = block.Cmds[i] as CallCmd;
                    if (cc == null)
                    {
                        continue;
                    }

                    if (!cnt.ContainsKey(cc.callee))
                    {
                        cnt[cc.callee] = 0;
                    }

                    var uniqueId = useGlobalCounter ? counter : cnt[cc.callee];
                    var attr     = new List <object>();
                    attr.Add(new LiteralExpr(Token.NoToken, Microsoft.BaseTypes.BigNum.FromInt(uniqueId)));

                    cc.Attributes = BoogieUtil.removeAttr("si_old_unique_call", cc.Attributes);
                    var oldAttr = BoogieUtil.getAttr("si_unique_call", cc.Attributes);
                    if (oldAttr != null)
                    {
                        cc.Attributes = BoogieUtil.removeAttr("si_unique_call", cc.Attributes);
                        var newattr = new QKeyValue(Token.NoToken, "si_old_unique_call", oldAttr, null);
                        if (cc.Attributes == null)
                        {
                            cc.Attributes = newattr;
                        }
                        else
                        {
                            cc.Attributes.AddLast(newattr);
                        }
                    }

                    cc.Attributes = new QKeyValue(Token.NoToken, "si_unique_call", attr, cc.Attributes);
                    callIdToLocation.Add(Tuple.Create(impl.Name, cc.callee, uniqueId), Tuple.Create(block.Label, callcnt));

                    cnt[cc.callee]++;

                    callcnt++;
                    counter++;
                }
            }
        }