Esempio n. 1
0
        private void TransformRegion(IRegion region)
        {
            List <PredicateCmd> genuineInvariants      = new List <PredicateCmd>();
            List <PredicateCmd> oldCandidateInvariants = new List <PredicateCmd>();

            foreach (var inv in region.RemoveInvariants())
            {
                string c;
                if (Houdini.MatchCandidate(inv.Expr, candidates, out c))
                {
                    Debug.Assert(inv is AssertCmd);
                    oldCandidateInvariants.Add(inv);
                }
                else
                {
                    genuineInvariants.Add(inv);
                }
            }

            TransformPow2Candidates(region, oldCandidateInvariants);
            TransformImplicationCandidates(region, oldCandidateInvariants);
            TransformRemainingCandidates(region, oldCandidateInvariants);

            foreach (var p in genuineInvariants)
            {
                region.AddInvariant(p);
            }
        }
        private IEnumerable <AnnotationInstance> AnnotationInstances()
        {
            foreach (var impl in prog.Implementations)
            {
                foreach (PredicateCmd p in impl.Blocks.SelectMany(Item => Item.Cmds).OfType <PredicateCmd>())
                {
                    string c;
                    if (Houdini.MatchCandidate(p.Expr, CandidateIdentifiers, out c))
                    {
                        yield return(new AnnotationInstance(c, impl.Name, p.Expr));
                    }
                    else if ((p is AssertCmd) && QKeyValue.FindBoolAttribute(p.Attributes, "originated_from_invariant"))
                    {
                        var tag = GetTagFromNonCandidateAttributes(p.Attributes);
                        if (tag != null)
                        {
                            yield return(new AnnotationInstance(tag, impl.Name, p.Expr));
                        }
                    }
                }
            }

            foreach (var proc in prog.NonInlinedProcedures())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, CandidateIdentifiers, out c))
                    {
                        yield return(new AnnotationInstance(c, proc.Name, r.Condition));
                    }
                    else
                    {
                        var tag = GetTagFromNonCandidateAttributes(r.Attributes);
                        if (tag != null)
                        {
                            yield return(new AnnotationInstance(tag, proc.Name, r.Condition));
                        }
                    }
                }

                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, CandidateIdentifiers, out c))
                    {
                        yield return(new AnnotationInstance(c, proc.Name, e.Condition));
                    }
                    else
                    {
                        var tag = GetTagFromNonCandidateAttributes(e.Attributes);
                        if (tag != null)
                        {
                            yield return(new AnnotationInstance(tag, proc.Name, e.Condition));
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        private void AddHoudiniConstant(AssertCmd assertCmd)
        {
            if (houdini.MatchCandidate(assertCmd.Expr, out Variable houdiniConstant))
            {
                houdiniAssertConstants.Add(houdiniConstant);
            }

            if (houdiniConstant != null && CommandLineOptions.Clo.ExplainHoudini &&
                !constToControl.ContainsKey(houdiniConstant.Name))
            {
                // For each houdini constant c, create two more constants c_pos and c_neg.
                // Then change the asserted condition (c ==> \phi) to
                // (c ==> (c_pos && (\phi || \not c_neg))
                var control = createNewExplainConstants(houdiniConstant);
                assertCmd.Expr = houdini.InsertCandidateControl(assertCmd.Expr, control.Item1, control.Item2);
                explainPositive.Add(control.Item1);
                explainNegative.Add(control.Item2);
                constToControl.Add(houdiniConstant.Name, control);
            }
        }
        internal CandidateReachabilityChecker(Program prog, IEnumerable <string> candidates)
        {
            this.prog                  = prog;
            this.candidates            = candidates;
            this.reachabilityGraph     = new InterproceduralReachabilityGraph(prog);
            this.candidateToOccurences = new Dictionary <string, HashSet <object> >();

            // Add all candidate occurrences in blocks
            foreach (Block b in prog.TopLevelDeclarations.OfType <Implementation>().Select(Item => Item.Blocks).SelectMany(Item => Item))
            {
                foreach (Cmd cmd in b.Cmds)
                {
                    AssertCmd assertCmd = cmd as AssertCmd;
                    if (assertCmd != null)
                    {
                        string c;
                        if (Houdini.MatchCandidate(assertCmd.Expr, candidates, out c))
                        {
                            AddCandidateOccurrence(c, b);
                        }
                    }
                }
            }

            // Add all candidate occurrences in preconditions
            foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, candidates, out c))
                    {
                        AddCandidateOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                    }
                }
            }

            // Add all candidate occurrences in preconditions
            foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, candidates, out c))
                    {
                        AddCandidateOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.POST));
                    }
                }
            }
        }
Esempio n. 5
0
 public override Procedure VisitProcedure(Procedure node)
 {
     if (callGraph.Predecessors(node).Any(x => !procsToAnalyze.Contains(x)))
     {
         //has callers outside procsToAnalyze, drop any candidate requires
         string candidate;
         var    newRequires = node.Requires.Where(ens => !Houdini.MatchCandidate(ens.Condition, candidateConsts, out candidate)).ToList();
         node.Requires = newRequires;
     }
     if (!procsToAnalyze.Contains(node))
     {
         //outside procsToAnalyze, drop any candidate ensures
         string candidate;
         var    newEnsures = node.Ensures.Where(ens => !Houdini.MatchCandidate(ens.Condition, candidateConsts, out candidate)).ToList();
         node.Ensures = newEnsures;
     }
     return(base.VisitProcedure(node));
 }
        private IEnumerable <CandidateInstance> CandidateInstances()
        {
            foreach (var impl in prog.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var b in impl.Blocks)
                {
                    foreach (Cmd cmd in b.Cmds)
                    {
                        var p = cmd as PredicateCmd;
                        if (p != null)
                        {
                            string c;
                            if (Houdini.MatchCandidate(p.Expr, candidates, out c))
                            {
                                yield return(new CandidateInstance(c, impl.Name, p.Expr));
                            }
                        }
                    }
                }
            }

            foreach (var proc in prog.TopLevelDeclarations.OfType <Procedure>())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, candidates, out c))
                    {
                        yield return(new CandidateInstance(c, proc.Name, r.Condition));
                    }
                }
                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, candidates, out c))
                    {
                        yield return(new CandidateInstance(c, proc.Name, e.Condition));
                    }
                }
            }
        }
        internal AnnotationReachabilityChecker(Program prog, IEnumerable <string> AnnotationIdentifiers)
        {
            this.prog = prog;
            this.AnnotationIdentifiers  = AnnotationIdentifiers;
            this.reachabilityGraph      = new InterproceduralReachabilityGraph(prog);
            this.annotationToOccurences = new Dictionary <string, HashSet <object> >();

            // Add all annotation occurrences in blocks
            foreach (Block b in prog.Blocks())
            {
                foreach (var assertCmd in b.Cmds.OfType <AssertCmd>())
                {
                    string c;
                    if (Houdini.MatchCandidate(assertCmd.Expr, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, b);
                    }
                    else
                    {
                        var tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(assertCmd.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, b);
                        }
                    }
                }
            }

            // Add all annotation occurrences in pre and post conditions
            foreach (var proc in prog.NonInlinedProcedures())
            {
                foreach (Requires r in proc.Requires)
                {
                    string c;
                    if (Houdini.MatchCandidate(r.Condition, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                    }
                    else
                    {
                        string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(r.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                        }
                    }
                }

                foreach (Ensures e in proc.Ensures)
                {
                    string c;
                    if (Houdini.MatchCandidate(e.Condition, AnnotationIdentifiers, out c))
                    {
                        AddAnnotationOccurrence(c, new Tuple <string, PrePost>(proc.Name, PrePost.POST));
                    }
                    else
                    {
                        string tag = AnnotationDependenceAnalyser.GetTagFromNonCandidateAttributes(e.Attributes);
                        if (tag != null)
                        {
                            AddAnnotationOccurrence(tag, new Tuple <string, PrePost>(proc.Name, PrePost.PRE));
                        }
                    }
                }
            }
        }
        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);
        }
        private IEnumerable <string> GetNonCandidateAnnotations()
        {
            var Result  = new HashSet <string>();
            int Counter = 0;

            foreach (var Assertion in prog.Blocks().SelectMany(Item => Item.Cmds).OfType <AssertCmd>())
            {
                string unused;
                if (Houdini.MatchCandidate(Assertion.Expr, CandidateIdentifiers, out unused))
                {
                    continue;
                }

                if (!QKeyValue.FindBoolAttribute(Assertion.Attributes, "originated_from_invariant"))
                {
                    continue;
                }

                if (OnlyRefersToConstants(Assertion.Expr))
                {
                    continue;
                }

                string Tag = "staged_houdini_tag_" + Counter;
                Result.Add(Tag);
                Assertion.Attributes = new QKeyValue(Token.NoToken, "staged_houdini_tag",
                                                     new List <object> {
                    Tag
                }, Assertion.Attributes);
                Counter++;
            }

            foreach (var Req in prog.NonInlinedProcedures().SelectMany(Item => Item.Requires))
            {
                string unused;
                if (Houdini.MatchCandidate(Req.Condition, CandidateIdentifiers, out unused))
                {
                    continue;
                }

                if (OnlyRefersToConstants(Req.Condition))
                {
                    continue;
                }

                string Tag = "staged_houdini_tag_" + Counter;
                Result.Add(Tag);
                Req.Attributes = new QKeyValue(Token.NoToken, "staged_houdini_tag",
                                               new List <object> {
                    Tag
                }, Req.Attributes);
                Counter++;
            }

            foreach (var Ens in prog.NonInlinedProcedures().SelectMany(Item => Item.Ensures))
            {
                string unused;
                if (Houdini.MatchCandidate(Ens.Condition, CandidateIdentifiers, out unused))
                {
                    continue;
                }

                if (OnlyRefersToConstants(Ens.Condition))
                {
                    continue;
                }

                string Tag = "staged_houdini_tag_" + Counter;
                Result.Add(Tag);
                Ens.Attributes = new QKeyValue(Token.NoToken, "staged_houdini_tag",
                                               new List <object> {
                    Tag
                }, Ens.Attributes);
                Counter++;
            }

            return(Result);
        }
        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);
        }