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); } }
public HoudiniInferredFilter(HashSet <string> trueHoudinis, HashSet <string> falseHoudinis, Program p, Houdini h) : base(p, HoudiniInferredComment, HoudiniInferredAttribute) { this.trueHoudinis = trueHoudinis; this.falseHoudinis = falseHoudinis; this.houdini = h; }
public static void CollectHoudiniConstants(Houdini houdini, Implementation impl, out ExistentialConstantCollector collector) { collector = new ExistentialConstantCollector(houdini); collector.impl = impl; collector.VisitImplementation(impl); }
private void TransformRemainingCandidates(IRegion region, List <PredicateCmd> oldCandidateInvariants) { if (oldCandidateInvariants.Count() > 0) { List <TypedIdent> args = new List <TypedIdent>(); for (int i = 0; i < oldCandidateInvariants.Count(); i++) { args.Add(new TypedIdent(Token.NoToken, "x" + i, Type.Bool)); } Function existentialFunction = CreateExistentialFunction(args); existentialFunctions.Add(existentialFunction); List <Expr> oldCandidateInvariantExprs = new List <Expr>(); foreach (var p in oldCandidateInvariants) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); Debug.Assert(e != null); oldCandidateInvariantExprs.Add(e); } region.AddInvariant(new AssertCmd( Token.NoToken, new NAryExpr(Token.NoToken, new FunctionCall(existentialFunction), oldCandidateInvariantExprs))); } }
private void TransformRemainingCandidates(IRegion region, List <PredicateCmd> oldCandidateInvariants) { if (oldCandidateInvariants.Count() > 0) { List <Variable> args = new List <Variable>(); for (int i = 0; i < oldCandidateInvariants.Count(); i++) { args.Add(new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x" + i, Microsoft.Boogie.Type.Bool))); } Function existentialFunction = new Function(Token.NoToken, "_existential_func" + counter, args, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool))); existentialFunctions.Add(existentialFunction); existentialFunction.AddAttribute("existential", new object[] { Expr.True }); List <Expr> oldCandidateInvariantExprs = new List <Expr>(); foreach (var p in oldCandidateInvariants) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); Debug.Assert(e != null); oldCandidateInvariantExprs.Add(e); } region.AddInvariant(new AssertCmd(Token.NoToken, new NAryExpr(Token.NoToken, new FunctionCall(existentialFunction), oldCandidateInvariantExprs))); counter++; } }
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 Expr removeExistentialImplication(Expr expr) { string match; bool result = Houdini.GetCandidateWithoutConstant(expr, this.candidateConsts, out match, out expr); Debug.Assert(result); return(expr); }
public InvariantInferrer(AnalysisContext ac, AnalysisContext acPost, EntryPoint ep) { Contract.Requires(ac != null && acPost != null && ep != null); this.AC = ac; this.PostAC = acPost; this.EP = ep; this.Houdini = null; }
private void TransformImplicationCandidates(IRegion region, List <PredicateCmd> oldCandidateInvariants) { IdentifierExpr antecedent = null; HashSet <IdentifierExpr> visited = new HashSet <IdentifierExpr>(); do { PredicateCmd current = null; foreach (var p in oldCandidateInvariants) { antecedent = TryGetNegatedBooleanFromCandidate(p, visited); if (antecedent != null) { visited.Add(antecedent); current = p; break; } } if (antecedent != null) { Debug.Assert(current != null); HashSet <PredicateCmd> toRemove = new HashSet <PredicateCmd>(); foreach (var p in oldCandidateInvariants) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); Debug.Assert(e != null); NAryExpr ne = e as NAryExpr; if (ne != null && ne.Fun is BinaryOperator && ((BinaryOperator)ne.Fun).Op == BinaryOperator.Opcode.Imp && ne.Args[0] is IdentifierExpr && ((IdentifierExpr)ne.Args[0]).Name.Equals(antecedent.Name)) { Expr consequent = ne.Args[1]; toRemove.Add(current); toRemove.Add(p); Function implicationExistentialFunction = CreateExistentialFunction( new List <TypedIdent> { new TypedIdent(Token.NoToken, "x", Type.Bool), new TypedIdent(Token.NoToken, "y", Type.Bool) }); implicationExistentialFunction.AddAttribute("absdomain", new object[] { "ImplicationDomain" }); existentialFunctions.Add(implicationExistentialFunction); region.AddInvariant(new AssertCmd( Token.NoToken, new NAryExpr(Token.NoToken, new FunctionCall(implicationExistentialFunction), new List <Expr> { antecedent, consequent }))); } } oldCandidateInvariants.RemoveAll(item => toRemove.Contains(item)); } }while (antecedent != null); }
private ExistentialConstantCollector(Houdini houdini) { this.houdini = houdini; this.houdiniAssertConstants = new HashSet<Variable>(); this.houdiniAssumeConstants = new HashSet<Variable>(); this.explainNegative = new HashSet<Variable>(); this.explainPositive = new HashSet<Variable>(); this.constToControl = new Dictionary<string, Tuple<Variable, Variable>>(); }
private ExistentialConstantCollector(Houdini houdini) { this.houdini = houdini; this.houdiniAssertConstants = new HashSet <Variable>(); this.houdiniAssumeConstants = new HashSet <Variable>(); this.explainNegative = new HashSet <Variable>(); this.explainPositive = new HashSet <Variable>(); this.constToControl = new Dictionary <string, Tuple <Variable, Variable> >(); }
private void PerformHoudini() { var houdiniStats = new HoudiniSession.HoudiniStatistics(); GC.Collect(); try { this.Houdini = new Houdini(this.AC.BoogieProgram, houdiniStats); this.Outcome = this.Houdini.PerformHoudiniInference(); } catch (OutOfMemoryException) { Lockpwn.IO.Reporter.WarningWriteLine("Warning: Houdini run out of memory"); GC.Collect(); throw new AnalysisFailedException(); } catch (Exception ex) { Lockpwn.IO.Reporter.WarningWriteLine("Warning: Houdini failed: " + ex.Message); GC.Collect(); throw new AnalysisFailedException(); } if (CommandLineOptions.Clo.PrintAssignment) { Output.PrintLine("..... Assignment computed by Houdini:"); foreach (var x in this.Outcome.assignment) { Output.PrintLine(x.Key + " = " + x.Value); } } if (ToolCommandLineOptions.Get().SuperVerboseMode) { int numTrueAssigns = 0; foreach (var x in this.Outcome.assignment) { if (x.Value) { numTrueAssigns++; } } Output.PrintLine("..... Number of true assignments = " + numTrueAssigns); Output.PrintLine("..... Number of false assignments = " + (this.Outcome.assignment.Count - numTrueAssigns)); Output.PrintLine("..... Prover time = " + houdiniStats.proverTime.ToString("F2")); Output.PrintLine("..... Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Output.PrintLine("..... Number of prover queries = " + houdiniStats.numProverQueries); Output.PrintLine("..... Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Output.PrintLine("..... Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } }
private IdentifierExpr TryGetPow2VariableFromCandidate(PredicateCmd p) { IdentifierExpr v = null; string tag = QKeyValue.FindStringAttribute(p.Attributes, "tag"); if (tag != null && tag.Contains("pow2 less than")) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); v = (e as NAryExpr).Args[0] as IdentifierExpr; } return(v); }
public HoudiniSession(Houdini houdini, VCGen vcgen, ProverInterface proverInterface, Program program, Implementation impl, HoudiniStatistics stats, int taskID = -1) { this.descriptiveName = impl.Name; this.stats = stats; collector = new ConditionGeneration.CounterexampleCollector(); collector.OnProgress("HdnVCGen", 0, 0, 0.0); vcgen.ConvertCFG2DAG(impl, taskID: taskID); ModelViewInfo mvInfo; var gotoCmdOrigins = vcgen.PassifyImpl(impl, out mvInfo); ExistentialConstantCollector ecollector; ExistentialConstantCollector.CollectHoudiniConstants(houdini, impl, out ecollector); this.houdiniAssertConstants = ecollector.houdiniAssertConstants; this.houdiniAssumeConstants = ecollector.houdiniAssumeConstants; this.explainConstantsNegative = ecollector.explainNegative; this.explainConstantsPositive = ecollector.explainPositive; this.constantToControl = ecollector.constToControl; houdiniConstants = new HashSet <Variable>(); houdiniConstants.UnionWith(houdiniAssertConstants); houdiniConstants.UnionWith(houdiniAssumeConstants); var exprGen = proverInterface.Context.ExprGen; VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : exprGen.Integer(BigNum.ZERO); Dictionary <int, Absy> label2absy; conjecture = vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, proverInterface.Context); if (!CommandLineOptions.Clo.UseLabels) { VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(exprGen.Integer(BigNum.ZERO), exprGen.Integer(BigNum.ZERO)); VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); conjecture = exprGen.Implies(eqExpr, conjecture); } Macro macro = new Macro(Token.NoToken, descriptiveName, new List <Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Type.Bool), false)); proverInterface.DefineMacro(macro, conjecture); conjecture = exprGen.Function(macro); if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local) { handler = new VCGen.ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program); } else { handler = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program); } }
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)); } } } }
private IdentifierExpr TryGetNegatedBooleanFromCandidate(PredicateCmd p, HashSet <IdentifierExpr> visited) { string tag = QKeyValue.FindStringAttribute(p.Attributes, "tag"); if (tag != null && (tag.Contains("no read") || tag.Contains("no write"))) { string c; Expr e; Houdini.GetCandidateWithoutConstant(p.Expr, candidates, out c, out e); IdentifierExpr possibleResult = (e as NAryExpr).Args[0] as IdentifierExpr; if (!visited.Contains(possibleResult)) { return(possibleResult); } } return(null); }
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)); }
public HoudiniOutcome PerformStagedHoudiniInference() { if (NoStages()) { Houdini houdini = new Houdini(program, houdiniStats); return(houdini.PerformHoudiniInference()); } EmitProgram(tempFilename); #region Prepare the tasks, but do not launch them foreach (var s in plan) { Debug.Assert(!plan.GetDependences(s).Contains(s)); tasks.Add(new StagedHoudiniTask(s, new Task(o => { ExecuteStage((ScheduledStage)o); }, s, TaskCreationOptions.LongRunning))); } #endregion #region Launch the tasks, and wait for them to finish foreach (var t in tasks) { t.parallelTask.Start(); } Task.WaitAll(tasks.Select(Item => Item.parallelTask).ToArray()); int count = 0; foreach (var h in houdiniInstances) { if (h.Count() > 0) { count++; System.Diagnostics.Debug.Assert(h.Count() == 1); h[0].Close(); } } #endregion return(UnifyOutcomes()); }
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)); } } } }
private void PerformHoudini(ref HoudiniOutcome outcome) { var houdiniStats = new HoudiniSession.HoudiniStatistics(); this.Houdini = new Houdini(this.AC.Program, houdiniStats); outcome = this.Houdini.PerformHoudiniInference(); if (CommandLineOptions.Clo.PrintAssignment) { Console.WriteLine("Assignment computed by Houdini:"); foreach (var x in outcome.assignment) { Console.WriteLine(x.Key + " = " + x.Value); } } if (CommandLineOptions.Clo.Trace) { int numTrueAssigns = 0; foreach (var x in outcome.assignment) { if (x.Value) { numTrueAssigns++; } } Console.WriteLine("Number of true assignments = " + numTrueAssigns); Console.WriteLine("Number of false assignments = " + (outcome.assignment.Count - numTrueAssigns)); Console.WriteLine("Prover time = " + houdiniStats.proverTime.ToString("F2")); Console.WriteLine("Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Console.WriteLine("Number of prover queries = " + houdiniStats.numProverQueries); Console.WriteLine("Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Console.WriteLine("Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } }
private void PerformHoudini() { var houdiniStats = new HoudiniSession.HoudiniStatistics(); this.Houdini = new Houdini(this.AC.BoogieProgram, houdiniStats); this.Outcome = this.Houdini.PerformHoudiniInference(); if (CommandLineOptions.Clo.PrintAssignment) { Output.PrintLine("..... Assignment computed by Houdini:"); foreach (var x in this.Outcome.assignment) { Output.PrintLine(x.Key + " = " + x.Value); } } if (ToolCommandLineOptions.Get().SuperVerboseMode) { int numTrueAssigns = 0; foreach (var x in this.Outcome.assignment) { if (x.Value) { numTrueAssigns++; } } Output.PrintLine("..... Number of true assignments = " + numTrueAssigns); Output.PrintLine("..... Number of false assignments = " + (this.Outcome.assignment.Count - numTrueAssigns)); Output.PrintLine("..... Prover time = " + houdiniStats.proverTime.ToString("F2")); Output.PrintLine("..... Unsat core prover time = " + houdiniStats.unsatCoreProverTime.ToString("F2")); Output.PrintLine("..... Number of prover queries = " + houdiniStats.numProverQueries); Output.PrintLine("..... Number of unsat core prover queries = " + houdiniStats.numUnsatCoreProverQueries); Output.PrintLine("..... Number of unsat core prunings = " + houdiniStats.numUnsatCorePrunings); } }
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 static void CollectHoudiniConstants(Houdini houdini, Implementation impl, out ExistentialConstantCollector collector) { collector = new ExistentialConstantCollector(houdini); collector.impl = impl; collector.VisitImplementation(impl); }
public HoudiniSession(Houdini houdini, VCGen vcgen, ProverInterface proverInterface, Program program, Implementation impl, HoudiniStatistics stats, int taskID = -1) { this.descriptiveName = impl.Name; this.stats = stats; collector = new ConditionGeneration.CounterexampleCollector(); collector.OnProgress("HdnVCGen", 0, 0, 0.0); vcgen.ConvertCFG2DAG(impl, taskID: taskID); ModelViewInfo mvInfo; var gotoCmdOrigins = vcgen.PassifyImpl(impl, out mvInfo); ExistentialConstantCollector ecollector; ExistentialConstantCollector.CollectHoudiniConstants(houdini, impl, out ecollector); this.houdiniAssertConstants = ecollector.houdiniAssertConstants; this.houdiniAssumeConstants = ecollector.houdiniAssumeConstants; this.explainConstantsNegative = ecollector.explainNegative; this.explainConstantsPositive = ecollector.explainPositive; this.constantToControl = ecollector.constToControl; houdiniConstants = new HashSet<Variable>(); houdiniConstants.UnionWith(houdiniAssertConstants); houdiniConstants.UnionWith(houdiniAssumeConstants); var exprGen = proverInterface.Context.ExprGen; VCExpr controlFlowVariableExpr = CommandLineOptions.Clo.UseLabels ? null : exprGen.Integer(BigNum.ZERO); Dictionary<int, Absy> label2absy; conjecture = vcgen.GenerateVC(impl, controlFlowVariableExpr, out label2absy, proverInterface.Context); if (!CommandLineOptions.Clo.UseLabels) { VCExpr controlFlowFunctionAppl = exprGen.ControlFlowFunctionApplication(exprGen.Integer(BigNum.ZERO), exprGen.Integer(BigNum.ZERO)); VCExpr eqExpr = exprGen.Eq(controlFlowFunctionAppl, exprGen.Integer(BigNum.FromInt(impl.Blocks[0].UniqueId))); conjecture = exprGen.Implies(eqExpr, conjecture); } Macro macro = new Macro(Token.NoToken, descriptiveName, new List<Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Type.Bool), false)); proverInterface.DefineMacro(macro, conjecture); conjecture = exprGen.Function(macro); if (CommandLineOptions.Clo.vcVariety == CommandLineOptions.VCVariety.Local) { handler = new VCGen.ErrorReporterLocal(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, program); } else { handler = new VCGen.ErrorReporter(gotoCmdOrigins, label2absy, impl.Blocks, vcgen.incarnationOriginMap, collector, mvInfo, proverInterface.Context, 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); }
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()) { 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); }