Esempio n. 1
0
        public override Program VisitProgram(Program node)
        {
            //find a mem variable and add mem_oldbitmap of the same type as mem
            this.mem = Utils.FindGlobalVariableInProgram(node, "mem");
            if (Options.splitMemoryModel)
            {
                this.mem_stack  = Utils.FindGlobalVariableInProgram(node, "mem_stack");
                this.mem_bitmap = Utils.FindGlobalVariableInProgram(node, "mem_bitmap");
            }
            else
            {
                this.mem_bitmap = this.mem;
                this.mem_stack  = this.mem;
            }

            this.addrInBitmap          = Utils.FindFunctionInProgram(node, "addrInBitmap");
            this.load_64               = Utils.FindFunctionInProgram(node, "LOAD_LE_64");
            this._bitmap_low           = Utils.FindConstantInProgram(node, "_bitmap_low");
            this._guard_writeTable_ptr = Utils.FindConstantInProgram(node, "_guard_writeTable_ptr");

            this.mem_oldbitmap = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "mem_oldbitmap", this.mem.TypedIdent.Type));
            node.AddTopLevelDeclaration(this.mem_oldbitmap);

            existentials = new Queue <Constant>();
            for (int i = 0; i < 2 * loopHeaderLabels.Count; i++)
            {
                Constant existential = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "existential_b" + i.ToString(), BType.Bool));
                existential.AddAttribute("existential");
                node.AddTopLevelDeclaration(existential);
                this.existentials.Enqueue(existential);
            }

            return(base.VisitProgram(node));
        }
Esempio n. 2
0
        private static List <Constant> CreateOutputGuards(IEnumerable <Variable> modSet, string procName)
        {
            var outputGuards = new List <Constant>();

            foreach (var m in modSet)
            {
                var      og   = new Constant(Token.NoToken, new TypedIdent(new Token(), procName + "_" + RefineConsts.modSetGuardName + "_" + m, Microsoft.Boogie.Type.Bool), false);
                object[] vals = { procName, Expr.Ident(m) };  /* string, expr */
                og.AddAttribute(RefineConsts.modSetGuradAttribute, vals);
                outputGuards.Add(og);
            }
            return(outputGuards);
        }
Esempio n. 3
0
        private static List <Constant> CreateInputGuards(IEnumerable <Variable> readSet, string procName)
        {
            List <Constant> inputGuards = new List <Constant>();

            foreach (var r in readSet)
            {
                var      ig   = new Constant(Token.NoToken, new TypedIdent(new Token(), procName + "_" + RefineConsts.readSetGuardName + "_" + r, Microsoft.Boogie.Type.Bool), false);
                object[] vals = { procName, Expr.Ident(r) }; /* string, expr */
                ig.AddAttribute(RefineConsts.readSetGuradAttribute, vals);
                inputGuards.Add(ig);
            }
            return(inputGuards);
        }
Esempio n. 4
0
        public static List <Ensures> SimplifyEnsures(List <Ensures> ens, Dictionary <string, Constant> CandidateConstants)
        {
            var ret          = new List <Ensures>();
            var newConstants = new List <Constant>();

            var GetExistentialConstant = new Func <Constant>(() =>
            {
                var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                   "CnfConst" + (SimplifyCnt++), Microsoft.Boogie.Type.Bool), false);
                c.AddAttribute("existential");
                newConstants.Add(c);
                return(c);
            });

            foreach (var en in ens)
            {
                if (en.Free)
                {
                    ret.Add(en);
                    continue;
                }

                string constantName = null;
                Expr   expr         = null;

                var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant(
                    en.Condition, CandidateConstants.Keys, out constantName, out expr);

                if (!match)
                {
                    ret.Add(en);
                    continue;
                }

                var conjs = GetExprConjunctions(Simplify(expr));
                if (conjs.Count == 1)
                {
                    en.Condition = Expr.Imp(Expr.Ident(CandidateConstants[constantName]), conjs.First());
                    ret.Add(en);
                    continue;
                }

                foreach (var conj in conjs)
                {
                    var c = GetExistentialConstant();
                    ret.Add(new Ensures(false, Expr.Imp(Expr.Ident(c), conj)));
                }
            }
            newConstants.Iter(c => CandidateConstants.Add(c.Name, c));
            return(ret);
        }
Esempio n. 5
0
        static Program Process(Program program)
        {
            // Get rid of Synonyms
            RemoveTypeSynonyms.Remove(program);
            //BoogieUtil.PrintProgram(program, "tt.bpl");
            program = BoogieUtil.ReResolve(program);

            // add "allocator" to malloc
            program.TopLevelDeclarations.OfType <Procedure>()
            .Where(p => MallocNames.Contains(p.Name))
            .Iter(p => p.AddAttribute("allocator"));

            // Create "null"
            var nil = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "NULL", btype.Int), false);

            nil.AddAttribute("allocated");

            // axiom NULL == 0;
            var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0)));

            // Convert 0 to NULL in the program
            ConvertToNull.Convert(program, nil);

            program.AddTopLevelDeclaration(nil);
            program.AddTopLevelDeclaration(ax);

            // Add "assert !aliasQ(e, NULL)" for each expression M[e] appearing in the program
            InstrumentMemoryAccesses.Instrument(program, nil);

            // Put {:scalar} {:AllocatorVar}  on $CurrAddr
            var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar)
                        .FirstOrDefault();

            if (alloc != null)
            {
                alloc.AddAttribute("scalar");
                alloc.AddAttribute(AvUtil.AvnAnnotations.AllocatorVarAttr);
            }
            else
            {
                Console.WriteLine("Warning: Global variable $CurrAddr not found");
            }

            if (initMem)
            {
                InitMemory(program);
            }

            return(program);
        }
        private void AddAccessWatchdogConstants()
        {
            foreach (var mr in this.AC.SharedMemoryRegions)
            {
                var ti = new TypedIdent(Token.NoToken, "WATCHED_ACCESS_" + mr.Name,
                                        this.AC.MemoryModelType);
                var watchdog = new Constant(Token.NoToken, ti, false);
                watchdog.AddAttribute("watchdog", new object[] { });

                if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name)))
                {
                    this.AC.TopLevelDeclarations.Add(watchdog);
                }
            }
        }
Esempio n. 7
0
        private Constant LookupOrCreateNewGuardConst(AssignCmd assignCmd, Block blk)
        {
            if (guardWritesConsts.ContainsKey(assignCmd))
            {
                return(guardWritesConsts[assignCmd]);
            }

            //Count number of consts with the same proc+block
            //name of the guard is a function of (proc,block,position of assign), for both versions
            var IsSameBlock = new Predicate <Constant>(c =>
            {
                var p = QKeyValue.FindStringAttribute(c.Attributes, "proc");
                if (p == null || p != currImpl.Name)
                {
                    return(false);
                }
                var b = QKeyValue.FindStringAttribute(c.Attributes, "blockLabel");
                if (b == null || b != blk.Label)
                {
                    return(false);
                }
                return(true);
            });

            var count = guardWritesConsts.Where(x => IsSameBlock(x.Value)).Count();
            //Spent a few hours since the unique is default, and we have 3 boolean constants!!
            var name     = currImpl.Name + "_" + blk.Label + "_" + count;
            var newConst = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, guardConstNamePrefix + name, BType.Bool), false);

            newConst.AddAttribute(guardConstAttribute, Expr.True);
            newConst.AddAttribute("proc", currImpl.Name);
            newConst.AddAttribute("blockLabel", blk.Label);
            prog.AddTopLevelDeclaration(newConst);
            guardWritesConsts[assignCmd] = newConst;
            return(newConst);
        }
Esempio n. 8
0
        private void AddAccessWatchdogConstants()
        {
            for (int i = 0; i < this.MemoryRegions.Count; i++)
            {
                var ti = new TypedIdent(Token.NoToken,
                                        this.AC.GetAccessWatchdogConstantName(this.MemoryRegions[i].Name),
                                        this.AC.MemoryModelType);
                var watchdog = new Constant(Token.NoToken, ti, false);
                watchdog.AddAttribute("watchdog", new object[] { });

                if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name)))
                {
                    this.AC.TopLevelDeclarations.Add(watchdog);
                }
            }
        }
        public StagedHoudiniPlan ApplyStages()
        {
            if (NoStages())
            {
                return(null);
            }

            #region Assign candidates to stages at a given level of granularity

            switch (CommandLineOptions.Clo.StagedHoudini)
            {
            case COARSE_STAGES:
                Plan = ComputeCoarseStages();
                break;

            case FINE_STAGES:
                Plan = ComputeFineStages();
                break;

            case BALANCED_STAGES:
                Plan = ComputeBalancedStages();
                break;

            default:
                Debug.Assert(false);
                Plan = null;
                break;
            }

            foreach (var c in candidates)
            {
                Debug.Assert(Plan.StageForCandidate(c) != null);
            }
            #endregion

            #region Generate boolean variables to control stages
            var stageToActiveBoolean   = new Dictionary <int, Constant>();
            var stageToCompleteBoolean = new Dictionary <int, Constant>();

            foreach (var stage in Plan)
            {
                var stageActive = new Constant(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_active", Type.Bool),
                                               false);
                stageActive.AddAttribute("stage_active", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
                prog.TopLevelDeclarations.Add(stageActive);
                stageToActiveBoolean[stage.GetId()] = stageActive;

                var stageComplete = new Constant(Token.NoToken,
                                                 new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_complete", Type.Bool),
                                                 false);
                stageComplete.AddAttribute("stage_complete", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
                prog.TopLevelDeclarations.Add(stageComplete);
                stageToCompleteBoolean[stage.GetId()] = stageComplete;
            }
            #endregion

            #region Adapt candidate assertions to take account of stages
            foreach (var b in prog.TopLevelDeclarations.OfType <Implementation>().Select(Item => Item.Blocks).SelectMany(Item => Item))
            {
                List <Cmd> newCmds = new List <Cmd>();
                foreach (var cmd in b.Cmds)
                {
                    var    a = cmd as AssertCmd;
                    string c;
                    if (a != null && (Houdini.MatchCandidate(a.Expr, candidates, out c)))
                    {
                        newCmds.Add(new AssertCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                                                                                         new IdentifierExpr(Token.NoToken, stageToActiveBoolean[Plan.StageForCandidate(c).GetId()]), c), a.Attributes));
                        newCmds.Add(new AssumeCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                                                                                         new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[Plan.StageForCandidate(c).GetId()]), c), a.Attributes));
                    }
                    else
                    {
                        newCmds.Add(cmd);
                    }
                }
                b.Cmds = newCmds;
            }
            #endregion

            #region Adapt candidate pre/postconditions to take account of stages
            foreach (var p in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                #region Handle the preconditions
                List <Requires> newRequires = new List <Requires>();
                foreach (Requires r in p.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, candidates, out c))
                    {
                        newRequires.Add(new Requires(r.tok, false,
                                                     Houdini.AddConditionToCandidate(r.Condition,
                                                                                     new IdentifierExpr(Token.NoToken, stageToActiveBoolean[Plan.StageForCandidate(c).GetId()]), c),
                                                     r.Comment, r.Attributes));
                        newRequires.Add(new Requires(r.tok, true,
                                                     Houdini.AddConditionToCandidate(r.Condition,
                                                                                     new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[Plan.StageForCandidate(c).GetId()]), c),
                                                     r.Comment, r.Attributes));
                    }
                    else
                    {
                        newRequires.Add(r);
                    }
                }
                p.Requires = newRequires;
                #endregion

                #region Handle the postconditions
                List <Ensures> newEnsures = new List <Ensures>();
                foreach (Ensures e in p.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, candidates, out c))
                    {
                        int      stage         = Plan.StageForCandidate(c).GetId();
                        Constant activeBoolean = stageToActiveBoolean[stage];
                        newEnsures.Add(new Ensures(e.tok, false,
                                                   Houdini.AddConditionToCandidate(e.Condition,
                                                                                   new IdentifierExpr(Token.NoToken, activeBoolean), c),
                                                   e.Comment, e.Attributes));
                        newEnsures.Add(new Ensures(e.tok, true,
                                                   Houdini.AddConditionToCandidate(e.Condition,
                                                                                   new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[stage]), c),
                                                   e.Comment, e.Attributes));
                    }
                    else
                    {
                        newEnsures.Add(e);
                    }
                }
                p.Ensures = newEnsures;
                #endregion
            }
            #endregion

            return(Plan);
        }
Esempio n. 10
0
        // minimize disjunctions in the templates
        // Returns true if new constants were created
        // Add new templates (and existing ones for which new constants were created) to newTemplates
        public static bool PruneDisjuncts(int template, ref HashSet <int> newTemplates)
        {
            Console.WriteLine("Breaking down template {0}: {1}", template, templateToStr[template]);
            var newConstantsCreated = false;

            var files = new HashSet <string>(fileToProg.Keys);

            foreach (var file in files)
            {
                if (!templateMap[template].ContainsKey(file))
                {
                    continue;
                }
                var constants = templateMap[template][file].Difference(fileToKeepConstants[file]);
                if (constants.Count == 0)
                {
                    continue;
                }

                var program = fileToProg[file].getProgram();

                var newconstants = new List <Constant>();
                foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                {
                    var newEnsures = new List <Ensures>();
                    foreach (var ens in impl.Proc.Ensures.Where(e => !e.Free))
                    {
                        string constantName = null;
                        Expr   expr         = null;
                        var    isloop       = QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "LoopProcedure");

                        var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant(
                            ens.Condition, constants, out constantName, out expr);

                        if (!match)
                        {
                            continue;
                        }

                        var disjuncts = SimplifyExpr.GetExprDisjuncts(expr);
                        if (disjuncts.Count == 1)
                        {
                            continue;
                        }
                        var pow = SimplifyExpr.GetPowSetDisjunctions(disjuncts);
                        foreach (var d in pow)
                        {
                            var conjuncts = SimplifyExpr.GetExprConjunctions(d);
                            foreach (var c in conjuncts)
                            {
                                var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++),
                                                                                    btype.Bool), false);
                                nc.AddAttribute("existential");
                                newconstants.Add(nc);
                                templateMap[template][file].Add(nc.Name);
                                //Console.WriteLine("  New constant created: {0}", nc.Name);
                                newConstantsCreated = true;

                                var e = Expr.Imp(Expr.Ident(nc), c);
                                newEnsures.Add(new Ensures(false, e));

                                // Add template
                                var temp = SimplifyExpr.ExprToTemplateGeneral(c);
                                if (strToTemplate.ContainsKey(temp))
                                {
                                    // template for it exists
                                    addTemplate(strToTemplate[temp], file, nc.Name, Tuple.Create(isloop, c));
                                }
                                else
                                {
                                    // create new template
                                    int v = TemplateCounterStart + strToTemplate.Count;
                                    strToTemplate.Add(temp, v);
                                    templateToStr.Add(v, temp);
                                    addTemplate(strToTemplate[temp], file, nc.Name, Tuple.Create(isloop, c));
                                }

                                if (!candidateToCost.ContainsKey(strToTemplate[temp]))
                                {
                                    candidateToCost.Add(strToTemplate[temp], conjuncts.Count > 1 ? disjuncts.Count : disjuncts.Count - SimplifyExpr.GetExprDisjuncts(d).Count);
                                }
                                Console.WriteLine("  Template revived or created {0} :: {1} (cost = {2})", strToTemplate[temp], temp, candidateToCost[strToTemplate[temp]]);
                                newTemplates.Add(strToTemplate[temp]);
                            }
                        }
                    }
                    impl.Proc.Ensures.AddRange(newEnsures);
                }
                program.AddTopLevelDeclarations(newconstants);

                fileToProg[file] = new PersistentProgram(program);
            }
            return(newConstantsCreated);
        }
Esempio n. 11
0
        public static bool ApplyTemplates(HashSet <int> templates)
        {
            var commonGlobals = Minimize.FindCommonGlobals();
            var ret           = false;

            // Prune away ones that don't have constants associated with them
            templates = new HashSet <int>(
                templates.Where(t => !templateMap[t].All(tup => tup.Value.SetEquals(fileToKeepConstants[tup.Key]))));

            // Prune away ones that don't talk about common globals
            templates = new HashSet <int>(
                templates.Where(t =>
            {
                var expr = SimplifyExpr.ToExpr(templateToStr[t]);
                var vu   = new GlobalVarsUsed();
                vu.VisitExpr(expr);
                return(vu.globalsUsed.IsSubsetOf(commonGlobals));
            }));

            var newFileToProg = new Dictionary <string, PersistentProgram>();

            var templateToConstants = new Dictionary <int, int>();

            templates.Iter(t => templateToConstants.Add(t, 0));

            foreach (var tup in fileToProg)
            {
                var program = tup.Value.getProgram();
                BoogieUtil.DoModSetAnalysis(program);
                var globals = new HashSet <string>(program.TopLevelDeclarations.OfType <GlobalVariable>().Select(g => g.Name));

                var newconstants = new HashSet <Constant>();

                foreach (var t in templates)
                {
                    var expr   = SimplifyExpr.ToExpr(templateToStr[t]);
                    var nonold = new GatherNonOldVariables();
                    nonold.VisitExpr(expr);

                    var mustmod = new HashSet <string>(nonold.variables);
                    mustmod.IntersectWith(globals);

                    foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
                    {
                        var mod = new HashSet <string>(impl.Proc.Modifies.Select(ie => ie.Name));
                        if (!mustmod.IsSubsetOf(mod))
                        {
                            continue;
                        }

                        // create new constant
                        var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++),
                                                                            btype.Bool), false);
                        nc.AddAttribute("existential");
                        newconstants.Add(nc);
                        if (!templateMap[t].ContainsKey(tup.Key))
                        {
                            templateMap[t].Add(tup.Key, new HashSet <string>());
                        }
                        templateMap[t][tup.Key].Add(nc.Name);

                        ret = true;
                        templateToConstants[t]++;

                        impl.Proc.Ensures.Add(new Ensures(false, Expr.Imp(Expr.Ident(nc), expr)));
                    }
                }

                program.AddTopLevelDeclarations(newconstants);
                newFileToProg.Add(tup.Key, new PersistentProgram(program));
            }
            fileToProg = newFileToProg;

            foreach (var tup in templateToConstants)
            {
                Console.WriteLine("Applying template {0}: {1} ({2} constants created)", tup.Key, templateToStr[tup.Key], tup.Value);
            }

            return(ret);
        }
        public StagedHoudiniPlan ApplyStages()
        {
            if (NoStages())
            {
            return null;
            }

            #region Assign candidates to stages at a given level of granularity

            switch(CommandLineOptions.Clo.StagedHoudini) {
              case COARSE_STAGES:
            Plan = ComputeCoarseStages();
            break;
              case FINE_STAGES:
            Plan = ComputeFineStages();
            break;
              case BALANCED_STAGES:
            Plan = ComputeBalancedStages();
            break;
              default:
            Debug.Assert(false);
            Plan = null;
            break;
            }

            foreach(var c in candidates) {
              Debug.Assert(Plan.StageForCandidate(c) != null);
            }
            #endregion

            #region Generate boolean variables to control stages
            var stageToActiveBoolean = new Dictionary<int, Constant>();
            var stageToCompleteBoolean = new Dictionary<int, Constant>();

            foreach (var stage in Plan)
            {
            var stageActive = new Constant(Token.NoToken,
                new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_active", Type.Bool),
                false);
            stageActive.AddAttribute("stage_active", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
            prog.TopLevelDeclarations.Add(stageActive);
            stageToActiveBoolean[stage.GetId()] = stageActive;

            var stageComplete = new Constant(Token.NoToken,
                new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_complete", Type.Bool),
                false);
            stageComplete.AddAttribute("stage_complete", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
            prog.TopLevelDeclarations.Add(stageComplete);
            stageToCompleteBoolean[stage.GetId()] = stageComplete;
            }
            #endregion

            #region Adapt candidate assertions to take account of stages
            foreach (var b in prog.TopLevelDeclarations.OfType<Implementation>().Select(Item => Item.Blocks).SelectMany(Item => Item))
            {
            List<Cmd> newCmds = new List<Cmd>();
            foreach (var cmd in b.Cmds)
            {
                var a = cmd as AssertCmd;
                string c;
                if (a != null && (Houdini.MatchCandidate(a.Expr, candidates, out c)))
                {
                    newCmds.Add(new AssertCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                        new IdentifierExpr(Token.NoToken, stageToActiveBoolean[Plan.StageForCandidate(c).GetId()]), c), a.Attributes));
                    newCmds.Add(new AssumeCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                        new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[Plan.StageForCandidate(c).GetId()]), c), a.Attributes));
                }
                else
                {
                    newCmds.Add(cmd);
                }
            }
            b.Cmds = newCmds;
            }
            #endregion

            #region Adapt candidate pre/postconditions to take account of stages
            foreach (var p in prog.TopLevelDeclarations.OfType<Procedure>())
            {

              #region Handle the preconditions
              List<Requires> newRequires = new List<Requires>();
              foreach(Requires r in p.Requires) {
            string c;
            if (Houdini.MatchCandidate(r.Condition, candidates, out c)) {
              newRequires.Add(new Requires(r.tok, false,
                Houdini.AddConditionToCandidate(r.Condition,
                new IdentifierExpr(Token.NoToken, stageToActiveBoolean[Plan.StageForCandidate(c).GetId()]), c),
                r.Comment, r.Attributes));
              newRequires.Add(new Requires(r.tok, true,
                Houdini.AddConditionToCandidate(r.Condition,
                new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[Plan.StageForCandidate(c).GetId()]), c),
                r.Comment, r.Attributes));
            } else {
              newRequires.Add(r);
            }
              }
              p.Requires = newRequires;
              #endregion

              #region Handle the postconditions
              List<Ensures> newEnsures = new List<Ensures>();
              foreach(Ensures e in p.Ensures) {
            string c;
            if (Houdini.MatchCandidate(e.Condition, candidates, out c)) {
              int stage = Plan.StageForCandidate(c).GetId();
              Constant activeBoolean = stageToActiveBoolean[stage];
              newEnsures.Add(new Ensures(e.tok, false,
                Houdini.AddConditionToCandidate(e.Condition,
                new IdentifierExpr(Token.NoToken, activeBoolean), c),
                e.Comment, e.Attributes));
              newEnsures.Add(new Ensures(e.tok, true,
                Houdini.AddConditionToCandidate(e.Condition,
                new IdentifierExpr(Token.NoToken, stageToCompleteBoolean[stage]), c),
                e.Comment, e.Attributes));
            } else {
              newEnsures.Add(e);
            }
              }
              p.Ensures = newEnsures;
              #endregion

            }
            #endregion

            return Plan;
        }
    public StagedHoudiniPlan ApplyStages() {

        if (NoStages())
        {
          Debug.Assert(false);
          var TrivialGraph = new Graph<ScheduledStage>();
          TrivialGraph.AddSource(new ScheduledStage(0, new HashSet<string>()));
          return new StagedHoudiniPlan(TrivialGraph);
        }

        #region Assign annotations to stages at a given level of granularity
      
        switch(CommandLineOptions.Clo.StagedHoudini) {
          case COARSE_STAGES:
            Plan = ComputeCoarseStages();
            break;
          case FINE_STAGES:
            Plan = ComputeFineStages();
            break;
          case BALANCED_STAGES:
            Plan = ComputeBalancedStages();
            break;
          default:
            Debug.Assert(false);
            Plan = null;
            break;
        }

        foreach(var c in AllAnnotationIdentifiers()) {
          Debug.Assert(Plan.StageForAnnotation(c) != null);
        }
        #endregion

        #region Generate boolean variables to control stages
        var stageToActiveBoolean = new Dictionary<int, Constant>();
        var stageToCompleteBoolean = new Dictionary<int, Constant>();

        foreach (var stage in Plan)
        {
            var stageActive = new Constant(Token.NoToken,
                new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_active", Type.Bool),
                false);
            stageActive.AddAttribute("stage_active", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
            prog.AddTopLevelDeclaration(stageActive);
            stageToActiveBoolean[stage.GetId()] = stageActive;

            var stageComplete = new Constant(Token.NoToken, 
                new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_complete", Type.Bool),
                false);
            stageComplete.AddAttribute("stage_complete", new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
            prog.AddTopLevelDeclaration(stageComplete);
            stageToCompleteBoolean[stage.GetId()] = stageComplete;
        }
        #endregion

        #region Adapt annotation assertions to take account of stages
        foreach (var b in prog.Implementations.Select(Item => Item.Blocks).SelectMany(Item => Item))
        {
            List<Cmd> newCmds = new List<Cmd>();
            foreach (var cmd in b.Cmds)
            {
                var a = cmd as AssertCmd;
                string c;
                if (a != null) {
                    if (Houdini.MatchCandidate(a.Expr, CandidateIdentifiers, out c))
                    {
                        newCmds.Add(new AssertCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                            Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(c).GetId()]), c), a.Attributes));
                        newCmds.Add(new AssumeCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                            Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(c).GetId()]), c), a.Attributes));
                    } else if (QKeyValue.FindBoolAttribute(a.Attributes, "originated_from_invariant")) {
                        string tag = GetTagFromNonCandidateAttributes(a.Attributes);
                        if (tag == null) {
                          newCmds.Add(a);
                        } else {
                          newCmds.Add(new AssertCmd(a.tok, Expr.Imp(
                              Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), a.Expr),
                              a.Attributes));
                          newCmds.Add(new AssumeCmd(a.tok, Expr.Imp(
                              Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), a.Expr),
                              a.Attributes));
                        }
                    }
                }
                else
                {
                    newCmds.Add(cmd);
                }
            }
            b.Cmds = newCmds;
        }
        #endregion

        #region Adapt pre/postconditions to take account of stages
        foreach (var p in prog.NonInlinedProcedures())
        {

          #region Handle the preconditions
          {
            List<Requires> newRequires = new List<Requires>();
            foreach(Requires r in p.Requires) {
              string c;
              if (Houdini.MatchCandidate(r.Condition, CandidateIdentifiers, out c)) {
                newRequires.Add(new Requires(r.tok, false, 
                  Houdini.AddConditionToCandidate(r.Condition,
                  Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(c).GetId()]), c),
                  r.Comment, r.Attributes));
                newRequires.Add(new Requires(r.tok, true, 
                  Houdini.AddConditionToCandidate(r.Condition,
                  Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(c).GetId()]), c),
                  r.Comment, r.Attributes));
              } else {
                string tag = GetTagFromNonCandidateAttributes(r.Attributes);
                if (tag == null) {
                  newRequires.Add(r);
                } else {
                  newRequires.Add(new Requires(r.tok, false, 
                    Expr.Imp(Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), r.Condition),
                    r.Comment, r.Attributes));
                  newRequires.Add(new Requires(r.tok, true, 
                    Expr.Imp(Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), r.Condition),
                    r.Comment, r.Attributes));
                }
              }
            }
            p.Requires = newRequires;
          }
          #endregion

          #region Handle the postconditions
          {
            List<Ensures> newEnsures = new List<Ensures>();
            foreach(Ensures e in p.Ensures) {
              string c;
              if (Houdini.MatchCandidate(e.Condition, CandidateIdentifiers, out c)) {
                int stage = Plan.StageForAnnotation(c).GetId();
                newEnsures.Add(new Ensures(e.tok, false, 
                  Houdini.AddConditionToCandidate(e.Condition,
                  Expr.Ident(stageToActiveBoolean[stage]), c),
                  e.Comment, e.Attributes));
                newEnsures.Add(new Ensures(e.tok, true, 
                  Houdini.AddConditionToCandidate(e.Condition,
                  Expr.Ident(stageToCompleteBoolean[stage]), c),
                  e.Comment, e.Attributes));
              } else {
                string tag = GetTagFromNonCandidateAttributes(e.Attributes);
                if (tag == null) {
                  newEnsures.Add(e);
                } else {
                  newEnsures.Add(new Ensures(e.tok, false, 
                    Expr.Imp(Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), e.Condition),
                    e.Comment, e.Attributes));
                  newEnsures.Add(new Ensures(e.tok, true, 
                    Expr.Imp(Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), e.Condition),
                    e.Comment, e.Attributes));
                }
              }
            }
            p.Ensures = newEnsures;
          }
          #endregion

        }
        #endregion

        return Plan;

    }
Esempio n. 14
0
        static Program Process(Program program)
        {
            // Get rid of Synonyms
            RemoveTypeSynonyms.Remove(program);
            //BoogieUtil.PrintProgram(program, "tt.bpl");
            program = BoogieUtil.ReResolveInMem(program, false);

            // Create "null"
            var nil = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "NULL", btype.Int), false);

            nil.AddAttribute("allocated");

            // axiom NULL == 0;
            //var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0)));

            program.AddTopLevelDeclaration(nil);
            //program.AddTopLevelDeclaration(ax);

            // add "allocator" to malloc
            program.TopLevelDeclarations.OfType <Procedure>()
            .Where(p => MallocNames.Contains(p.Name))
            .Iter(p => p.AddAttribute("allocator"));

            // inline functions
            InlineFunctions(program);

            // Add attribute {:fpcondition} to assume cmds in charge of branching in function pointer dispatch procs
            var fpAt = new AnnotateFPDispatchProcVisitor();

            fpAt.Run(program);

            // Add MustReach function calls to the begining of each procedure and upon returns
            if (detectDeadCode)
            {
                var ddc = new SimpleDeadcodeDectectionVisitor();
                ddc.Run(program);
            }
            // if we don't check NULL, stop here
            if (!checkNULL && !checkUAF)
            {
                return(program);
            }

            if (checkUAF)
            {
                var iu = new InstrumentUAF();
                iu.Instrument(program, nil);
                program.AddTopLevelDeclaration(new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0))));
                return(program);
            }
            // Remove literal constants
            var CE = new ConstantElimination();

            CE.Run(program);

            // Convert 0 to NULL in the program
            ConvertToNull.Convert(program, nil);

            // Add NULL axiom here such that ConvertToNULL doesn't lead to dumb axiom
            var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0)));

            program.AddTopLevelDeclaration(ax);

            // Add "assert !aliasQ(e, NULL)" for each expression M[e] appearing in the program
            InstrumentMemoryAccesses.Instrument(program, nil);

            // Put {:scalar} {:AllocatorVar}  on $CurrAddr
            var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar)
                        .FirstOrDefault();

            if (alloc != null)
            {
                //alloc.AddAttribute("scalar");
                alloc.AddAttribute(AvUtil.AvnAnnotations.AllocatorVarAttr);
            }
            else
            {
                Console.WriteLine("Warning: Global variable $CurrAddr not found");
            }

            if (initMem)
            {
                InitMemory(program);
            }

            return(program);
        }
Esempio n. 15
0
        public static Program InjectDualityProof(Program program, string DualityProofFile)
        {
            Program DualityProof;

            using (var st = new System.IO.StreamReader(DualityProofFile))
            {
                var s = ParserHelper.Fill(st, new List <string>());
                // replace %i by bound_var_i
                for (int i = 0; i <= 9; i++)
                {
                    s = s.Replace(string.Format("%{0}", i), string.Format("pm_bv_{0}", i));
                }
                var v = Parser.Parse(s, DualityProofFile, out DualityProof);
                if (v != 0)
                {
                    throw new Exception("Failed to parse " + DualityProofFile);
                }
            }


            var implToContracts = new Dictionary <string, List <Expr> >();

            foreach (var proc in DualityProof.TopLevelDeclarations.OfType <Procedure>())
            {
                implToContracts.Add(proc.Name, new List <Expr>());
                foreach (var ens in proc.Ensures)
                {
                    implToContracts[proc.Name].AddRange(GetExprConjunctions(ens.Condition));
                }
            }

            var counter = 0;
            var GetExistentialConstant = new Func <Constant>(() =>
            {
                var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                   "DualityProofConst" + (counter++), Microsoft.Boogie.Type.Bool), false);
                c.AddAttribute("existential");
                return(c);
            });

            var constsToAdd = new List <Declaration>();

            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>())
            {
                if (!implToContracts.ContainsKey(proc.Name))
                {
                    continue;
                }
                if (QKeyValue.FindBoolAttribute(proc.Attributes, "nohoudini"))
                {
                    continue;
                }

                foreach (var expr in implToContracts[proc.Name])
                {
                    var c = GetExistentialConstant();
                    constsToAdd.Add(c);
                    proc.Ensures.Add(new Ensures(false,
                                                 Expr.Imp(Expr.Ident(c), expr)));
                }
            }

            program.AddTopLevelDeclarations(constsToAdd);

            return(program);
        }
        public StagedHoudiniPlan ApplyStages()
        {
            if (NoStages())
            {
                Debug.Assert(false);
                var TrivialGraph = new Graph <ScheduledStage>();
                TrivialGraph.AddSource(new ScheduledStage(0, new HashSet <string>()));
                return(new StagedHoudiniPlan(TrivialGraph));
            }

            #region Assign annotations to stages at a given level of granularity

            switch (CommandLineOptions.Clo.StagedHoudini)
            {
            case COARSE_STAGES:
                Plan = ComputeCoarseStages();
                break;

            case FINE_STAGES:
                Plan = ComputeFineStages();
                break;

            case BALANCED_STAGES:
                Plan = ComputeBalancedStages();
                break;

            default:
                Debug.Assert(false);
                Plan = null;
                break;
            }

            foreach (var c in AllAnnotationIdentifiers())
            {
                Debug.Assert(Plan.StageForAnnotation(c) != null);
            }

            #endregion

            #region Generate boolean variables to control stages

            var stageToActiveBoolean   = new Dictionary <int, Constant>();
            var stageToCompleteBoolean = new Dictionary <int, Constant>();

            foreach (var stage in Plan)
            {
                var stageActive = new Constant(Token.NoToken,
                                               new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_active", Type.Bool),
                                               false);
                stageActive.AddAttribute("stage_active",
                                         new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
                prog.AddTopLevelDeclaration(stageActive);
                stageToActiveBoolean[stage.GetId()] = stageActive;

                var stageComplete = new Constant(Token.NoToken,
                                                 new TypedIdent(Token.NoToken, "_stage_" + stage.GetId() + "_complete", Type.Bool),
                                                 false);
                stageComplete.AddAttribute("stage_complete",
                                           new object[] { new LiteralExpr(Token.NoToken, BigNum.FromInt(stage.GetId())) });
                prog.AddTopLevelDeclaration(stageComplete);
                stageToCompleteBoolean[stage.GetId()] = stageComplete;
            }

            #endregion

            #region Adapt annotation assertions to take account of stages

            foreach (var b in prog.Implementations.Select(Item => Item.Blocks).SelectMany(Item => Item))
            {
                List <Cmd> newCmds = new List <Cmd>();
                foreach (var cmd in b.Cmds)
                {
                    var    a = cmd as AssertCmd;
                    string c;
                    if (a != null)
                    {
                        if (Houdini.MatchCandidate(a.Expr, CandidateIdentifiers, out c))
                        {
                            newCmds.Add(new AssertCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                                                                                             Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(c).GetId()]), c), a.Attributes));
                            newCmds.Add(new AssumeCmd(a.tok, Houdini.AddConditionToCandidate(a.Expr,
                                                                                             Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(c).GetId()]), c), a.Attributes));
                        }
                        else if (QKeyValue.FindBoolAttribute(a.Attributes, "originated_from_invariant"))
                        {
                            string tag = GetTagFromNonCandidateAttributes(a.Attributes);
                            if (tag == null)
                            {
                                newCmds.Add(a);
                            }
                            else
                            {
                                newCmds.Add(new AssertCmd(a.tok, Expr.Imp(
                                                              Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), a.Expr),
                                                          a.Attributes));
                                newCmds.Add(new AssumeCmd(a.tok, Expr.Imp(
                                                              Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), a.Expr),
                                                          a.Attributes));
                            }
                        }
                    }
                    else
                    {
                        newCmds.Add(cmd);
                    }
                }

                b.Cmds = newCmds;
            }

            #endregion

            #region Adapt pre/postconditions to take account of stages

            foreach (var p in prog.NonInlinedProcedures())
            {
                #region Handle the preconditions

                {
                    List <Requires> newRequires = new List <Requires>();
                    foreach (Requires r in p.Requires)
                    {
                        string c;
                        if (Houdini.MatchCandidate(r.Condition, CandidateIdentifiers, out c))
                        {
                            newRequires.Add(new Requires(r.tok, false,
                                                         Houdini.AddConditionToCandidate(r.Condition,
                                                                                         Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(c).GetId()]), c),
                                                         r.Comment, r.Attributes));
                            newRequires.Add(new Requires(r.tok, true,
                                                         Houdini.AddConditionToCandidate(r.Condition,
                                                                                         Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(c).GetId()]), c),
                                                         r.Comment, r.Attributes));
                        }
                        else
                        {
                            string tag = GetTagFromNonCandidateAttributes(r.Attributes);
                            if (tag == null)
                            {
                                newRequires.Add(r);
                            }
                            else
                            {
                                newRequires.Add(new Requires(r.tok, false,
                                                             Expr.Imp(Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), r.Condition),
                                                             r.Comment, r.Attributes));
                                newRequires.Add(new Requires(r.tok, true,
                                                             Expr.Imp(Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), r.Condition),
                                                             r.Comment, r.Attributes));
                            }
                        }
                    }

                    p.Requires = newRequires;
                }

                #endregion

                #region Handle the postconditions

                {
                    List <Ensures> newEnsures = new List <Ensures>();
                    foreach (Ensures e in p.Ensures)
                    {
                        string c;
                        if (Houdini.MatchCandidate(e.Condition, CandidateIdentifiers, out c))
                        {
                            int stage = Plan.StageForAnnotation(c).GetId();
                            newEnsures.Add(new Ensures(e.tok, false,
                                                       Houdini.AddConditionToCandidate(e.Condition,
                                                                                       Expr.Ident(stageToActiveBoolean[stage]), c),
                                                       e.Comment, e.Attributes));
                            newEnsures.Add(new Ensures(e.tok, true,
                                                       Houdini.AddConditionToCandidate(e.Condition,
                                                                                       Expr.Ident(stageToCompleteBoolean[stage]), c),
                                                       e.Comment, e.Attributes));
                        }
                        else
                        {
                            string tag = GetTagFromNonCandidateAttributes(e.Attributes);
                            if (tag == null)
                            {
                                newEnsures.Add(e);
                            }
                            else
                            {
                                newEnsures.Add(new Ensures(e.tok, false,
                                                           Expr.Imp(Expr.Ident(stageToActiveBoolean[Plan.StageForAnnotation(tag).GetId()]), e.Condition),
                                                           e.Comment, e.Attributes));
                                newEnsures.Add(new Ensures(e.tok, true,
                                                           Expr.Imp(Expr.Ident(stageToCompleteBoolean[Plan.StageForAnnotation(tag).GetId()]), e.Condition),
                                                           e.Comment, e.Attributes));
                            }
                        }
                    }

                    p.Ensures = newEnsures;
                }

                #endregion
            }

            #endregion

            return(Plan);
        }
Esempio n. 17
0
        static HashSet <string> BreakDownInvariants(Program program, HashSet <string> candidates)
        {
            var markkeep = new HashSet <string>();
            var added    = new HashSet <Constant>();

            var counter = 0;
            var GetExistentialConstant = new Func <Constant>(() =>
            {
                var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken,
                                                                   "DualityProofConstBrokenDown" + (counter++), Microsoft.Boogie.Type.Bool), false);
                c.AddAttribute("existential");
                return(c);
            });

            var constants = new Dictionary <string, Constant>();

            program.TopLevelDeclarations.OfType <Constant>()
            .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential"))
            .Iter(c => constants.Add(c.Name, c));

            foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>())
            {
                var newens = new List <Ensures>();

                foreach (var ens in proc.Ensures.Where(e => !e.Free))
                {
                    string constantName = null;
                    Expr   expr         = null;

                    var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant(
                        ens.Condition, candidates, out constantName, out expr);

                    if (!match)
                    {
                        continue;
                    }

                    var elements = SimplifyExpr.BreakDownExpr(expr);
                    if (elements.Count == 1)
                    {
                        markkeep.Add(constantName);
                        continue;
                    }

                    // add cost
                    constants[constantName].AddAttribute(Driver.CostAttr, Expr.Literal(1));

                    // add the constituents
                    foreach (var elem in elements)
                    {
                        var c = GetExistentialConstant();
                        added.Add(c);
                        newens.Add(new Ensures(false, Expr.Imp(Expr.Ident(c), elem)));
                    }
                }

                proc.Ensures.AddRange(newens);
            }

            program.TopLevelDeclarations.OfType <Constant>()
            .Where(c => markkeep.Contains(c.Name))
            .Iter(c => c.AddAttribute(Driver.MustKeepAttr));

            program.AddTopLevelDeclarations(added);

            return(markkeep);
        }