예제 #1
0
        public StagedHoudini(Program program, Func <string, Program> ProgramFromFile)
        {
            this.program          = program;
            this.ProgramFromFile  = ProgramFromFile;
            this.houdiniInstances = new List <Houdini> [CommandLineOptions.Clo.StagedHoudiniThreads];
            for (int i = 0; i < CommandLineOptions.Clo.StagedHoudiniThreads; i++)
            {
                houdiniInstances[i] = new List <Houdini>();
            }

            var candidateDependenceAnalyser = new CandidateDependenceAnalyser(program);

            candidateDependenceAnalyser.Analyse();
            this.plan = candidateDependenceAnalyser.ApplyStages();
            if (CommandLineOptions.Clo.Trace)
            {
                candidateDependenceAnalyser.dump();
                EmitProgram("staged.bpl");
            }
        }
예제 #2
0
        public StagedHoudini(Program program, HoudiniSession.HoudiniStatistics houdiniStats,
                             Func <string, Program> ProgramFromFile)
        {
            this.program          = program;
            this.houdiniStats     = houdiniStats;
            this.ProgramFromFile  = ProgramFromFile;
            this.houdiniInstances = new List <Houdini> [CommandLineOptions.Clo.StagedHoudiniThreads];
            for (int i = 0; i < CommandLineOptions.Clo.StagedHoudiniThreads; i++)
            {
                houdiniInstances[i] = new List <Houdini>();
            }

            BreakApartConjunctionsInAnnotations();

            var annotationDependenceAnalyser = new AnnotationDependenceAnalyser(program);

            annotationDependenceAnalyser.Analyse();
            this.plan = annotationDependenceAnalyser.ApplyStages();
            if (CommandLineOptions.Clo.Trace)
            {
                annotationDependenceAnalyser.dump();

                if (CommandLineOptions.Clo.DebugStagedHoudini)
                {
                    Console.WriteLine("Plan\n====\n");
                    if (plan == null)
                    {
                        Console.WriteLine("No plan, as there were no stages");
                    }
                    else
                    {
                        Console.WriteLine(this.plan);
                    }
                }

                EmitProgram("staged.bpl");
            }
        }
        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);
        }
        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);
        }