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