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); }