public override Program VisitProgram(Program node) { //find a mem variable and add mem_oldbitmap of the same type as mem this.mem = Utils.FindGlobalVariableInProgram(node, "mem"); if (Options.splitMemoryModel) { this.mem_stack = Utils.FindGlobalVariableInProgram(node, "mem_stack"); this.mem_bitmap = Utils.FindGlobalVariableInProgram(node, "mem_bitmap"); } else { this.mem_bitmap = this.mem; this.mem_stack = this.mem; } this.addrInBitmap = Utils.FindFunctionInProgram(node, "addrInBitmap"); this.load_64 = Utils.FindFunctionInProgram(node, "LOAD_LE_64"); this._bitmap_low = Utils.FindConstantInProgram(node, "_bitmap_low"); this._guard_writeTable_ptr = Utils.FindConstantInProgram(node, "_guard_writeTable_ptr"); this.mem_oldbitmap = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "mem_oldbitmap", this.mem.TypedIdent.Type)); node.AddTopLevelDeclaration(this.mem_oldbitmap); existentials = new Queue <Constant>(); for (int i = 0; i < 2 * loopHeaderLabels.Count; i++) { Constant existential = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "existential_b" + i.ToString(), BType.Bool)); existential.AddAttribute("existential"); node.AddTopLevelDeclaration(existential); this.existentials.Enqueue(existential); } return(base.VisitProgram(node)); }
private static List <Constant> CreateOutputGuards(IEnumerable <Variable> modSet, string procName) { var outputGuards = new List <Constant>(); foreach (var m in modSet) { var og = new Constant(Token.NoToken, new TypedIdent(new Token(), procName + "_" + RefineConsts.modSetGuardName + "_" + m, Microsoft.Boogie.Type.Bool), false); object[] vals = { procName, Expr.Ident(m) }; /* string, expr */ og.AddAttribute(RefineConsts.modSetGuradAttribute, vals); outputGuards.Add(og); } return(outputGuards); }
private static List <Constant> CreateInputGuards(IEnumerable <Variable> readSet, string procName) { List <Constant> inputGuards = new List <Constant>(); foreach (var r in readSet) { var ig = new Constant(Token.NoToken, new TypedIdent(new Token(), procName + "_" + RefineConsts.readSetGuardName + "_" + r, Microsoft.Boogie.Type.Bool), false); object[] vals = { procName, Expr.Ident(r) }; /* string, expr */ ig.AddAttribute(RefineConsts.readSetGuradAttribute, vals); inputGuards.Add(ig); } return(inputGuards); }
public static List <Ensures> SimplifyEnsures(List <Ensures> ens, Dictionary <string, Constant> CandidateConstants) { var ret = new List <Ensures>(); var newConstants = new List <Constant>(); var GetExistentialConstant = new Func <Constant>(() => { var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "CnfConst" + (SimplifyCnt++), Microsoft.Boogie.Type.Bool), false); c.AddAttribute("existential"); newConstants.Add(c); return(c); }); foreach (var en in ens) { if (en.Free) { ret.Add(en); continue; } string constantName = null; Expr expr = null; var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant( en.Condition, CandidateConstants.Keys, out constantName, out expr); if (!match) { ret.Add(en); continue; } var conjs = GetExprConjunctions(Simplify(expr)); if (conjs.Count == 1) { en.Condition = Expr.Imp(Expr.Ident(CandidateConstants[constantName]), conjs.First()); ret.Add(en); continue; } foreach (var conj in conjs) { var c = GetExistentialConstant(); ret.Add(new Ensures(false, Expr.Imp(Expr.Ident(c), conj))); } } newConstants.Iter(c => CandidateConstants.Add(c.Name, c)); return(ret); }
static Program Process(Program program) { // Get rid of Synonyms RemoveTypeSynonyms.Remove(program); //BoogieUtil.PrintProgram(program, "tt.bpl"); program = BoogieUtil.ReResolve(program); // add "allocator" to malloc program.TopLevelDeclarations.OfType <Procedure>() .Where(p => MallocNames.Contains(p.Name)) .Iter(p => p.AddAttribute("allocator")); // Create "null" var nil = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "NULL", btype.Int), false); nil.AddAttribute("allocated"); // axiom NULL == 0; var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0))); // Convert 0 to NULL in the program ConvertToNull.Convert(program, nil); program.AddTopLevelDeclaration(nil); program.AddTopLevelDeclaration(ax); // Add "assert !aliasQ(e, NULL)" for each expression M[e] appearing in the program InstrumentMemoryAccesses.Instrument(program, nil); // Put {:scalar} {:AllocatorVar} on $CurrAddr var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar) .FirstOrDefault(); if (alloc != null) { alloc.AddAttribute("scalar"); alloc.AddAttribute(AvUtil.AvnAnnotations.AllocatorVarAttr); } else { Console.WriteLine("Warning: Global variable $CurrAddr not found"); } if (initMem) { InitMemory(program); } return(program); }
private void AddAccessWatchdogConstants() { foreach (var mr in this.AC.SharedMemoryRegions) { var ti = new TypedIdent(Token.NoToken, "WATCHED_ACCESS_" + mr.Name, this.AC.MemoryModelType); var watchdog = new Constant(Token.NoToken, ti, false); watchdog.AddAttribute("watchdog", new object[] { }); if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name))) { this.AC.TopLevelDeclarations.Add(watchdog); } } }
private Constant LookupOrCreateNewGuardConst(AssignCmd assignCmd, Block blk) { if (guardWritesConsts.ContainsKey(assignCmd)) { return(guardWritesConsts[assignCmd]); } //Count number of consts with the same proc+block //name of the guard is a function of (proc,block,position of assign), for both versions var IsSameBlock = new Predicate <Constant>(c => { var p = QKeyValue.FindStringAttribute(c.Attributes, "proc"); if (p == null || p != currImpl.Name) { return(false); } var b = QKeyValue.FindStringAttribute(c.Attributes, "blockLabel"); if (b == null || b != blk.Label) { return(false); } return(true); }); var count = guardWritesConsts.Where(x => IsSameBlock(x.Value)).Count(); //Spent a few hours since the unique is default, and we have 3 boolean constants!! var name = currImpl.Name + "_" + blk.Label + "_" + count; var newConst = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, guardConstNamePrefix + name, BType.Bool), false); newConst.AddAttribute(guardConstAttribute, Expr.True); newConst.AddAttribute("proc", currImpl.Name); newConst.AddAttribute("blockLabel", blk.Label); prog.AddTopLevelDeclaration(newConst); guardWritesConsts[assignCmd] = newConst; return(newConst); }
private void AddAccessWatchdogConstants() { for (int i = 0; i < this.MemoryRegions.Count; i++) { var ti = new TypedIdent(Token.NoToken, this.AC.GetAccessWatchdogConstantName(this.MemoryRegions[i].Name), this.AC.MemoryModelType); var watchdog = new Constant(Token.NoToken, ti, false); watchdog.AddAttribute("watchdog", new object[] { }); if (!this.AC.TopLevelDeclarations.OfType <Variable>().Any(val => val.Name.Equals(watchdog.Name))) { this.AC.TopLevelDeclarations.Add(watchdog); } } }
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); }
// minimize disjunctions in the templates // Returns true if new constants were created // Add new templates (and existing ones for which new constants were created) to newTemplates public static bool PruneDisjuncts(int template, ref HashSet <int> newTemplates) { Console.WriteLine("Breaking down template {0}: {1}", template, templateToStr[template]); var newConstantsCreated = false; var files = new HashSet <string>(fileToProg.Keys); foreach (var file in files) { if (!templateMap[template].ContainsKey(file)) { continue; } var constants = templateMap[template][file].Difference(fileToKeepConstants[file]); if (constants.Count == 0) { continue; } var program = fileToProg[file].getProgram(); var newconstants = new List <Constant>(); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { var newEnsures = new List <Ensures>(); foreach (var ens in impl.Proc.Ensures.Where(e => !e.Free)) { string constantName = null; Expr expr = null; var isloop = QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "LoopProcedure"); var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant( ens.Condition, constants, out constantName, out expr); if (!match) { continue; } var disjuncts = SimplifyExpr.GetExprDisjuncts(expr); if (disjuncts.Count == 1) { continue; } var pow = SimplifyExpr.GetPowSetDisjunctions(disjuncts); foreach (var d in pow) { var conjuncts = SimplifyExpr.GetExprConjunctions(d); foreach (var c in conjuncts) { var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++), btype.Bool), false); nc.AddAttribute("existential"); newconstants.Add(nc); templateMap[template][file].Add(nc.Name); //Console.WriteLine(" New constant created: {0}", nc.Name); newConstantsCreated = true; var e = Expr.Imp(Expr.Ident(nc), c); newEnsures.Add(new Ensures(false, e)); // Add template var temp = SimplifyExpr.ExprToTemplateGeneral(c); if (strToTemplate.ContainsKey(temp)) { // template for it exists addTemplate(strToTemplate[temp], file, nc.Name, Tuple.Create(isloop, c)); } else { // create new template int v = TemplateCounterStart + strToTemplate.Count; strToTemplate.Add(temp, v); templateToStr.Add(v, temp); addTemplate(strToTemplate[temp], file, nc.Name, Tuple.Create(isloop, c)); } if (!candidateToCost.ContainsKey(strToTemplate[temp])) { candidateToCost.Add(strToTemplate[temp], conjuncts.Count > 1 ? disjuncts.Count : disjuncts.Count - SimplifyExpr.GetExprDisjuncts(d).Count); } Console.WriteLine(" Template revived or created {0} :: {1} (cost = {2})", strToTemplate[temp], temp, candidateToCost[strToTemplate[temp]]); newTemplates.Add(strToTemplate[temp]); } } } impl.Proc.Ensures.AddRange(newEnsures); } program.AddTopLevelDeclarations(newconstants); fileToProg[file] = new PersistentProgram(program); } return(newConstantsCreated); }
public static bool ApplyTemplates(HashSet <int> templates) { var commonGlobals = Minimize.FindCommonGlobals(); var ret = false; // Prune away ones that don't have constants associated with them templates = new HashSet <int>( templates.Where(t => !templateMap[t].All(tup => tup.Value.SetEquals(fileToKeepConstants[tup.Key])))); // Prune away ones that don't talk about common globals templates = new HashSet <int>( templates.Where(t => { var expr = SimplifyExpr.ToExpr(templateToStr[t]); var vu = new GlobalVarsUsed(); vu.VisitExpr(expr); return(vu.globalsUsed.IsSubsetOf(commonGlobals)); })); var newFileToProg = new Dictionary <string, PersistentProgram>(); var templateToConstants = new Dictionary <int, int>(); templates.Iter(t => templateToConstants.Add(t, 0)); foreach (var tup in fileToProg) { var program = tup.Value.getProgram(); BoogieUtil.DoModSetAnalysis(program); var globals = new HashSet <string>(program.TopLevelDeclarations.OfType <GlobalVariable>().Select(g => g.Name)); var newconstants = new HashSet <Constant>(); foreach (var t in templates) { var expr = SimplifyExpr.ToExpr(templateToStr[t]); var nonold = new GatherNonOldVariables(); nonold.VisitExpr(expr); var mustmod = new HashSet <string>(nonold.variables); mustmod.IntersectWith(globals); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { var mod = new HashSet <string>(impl.Proc.Modifies.Select(ie => ie.Name)); if (!mustmod.IsSubsetOf(mod)) { continue; } // create new constant var nc = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "PMnewConst" + (NewConstCounter++), btype.Bool), false); nc.AddAttribute("existential"); newconstants.Add(nc); if (!templateMap[t].ContainsKey(tup.Key)) { templateMap[t].Add(tup.Key, new HashSet <string>()); } templateMap[t][tup.Key].Add(nc.Name); ret = true; templateToConstants[t]++; impl.Proc.Ensures.Add(new Ensures(false, Expr.Imp(Expr.Ident(nc), expr))); } } program.AddTopLevelDeclarations(newconstants); newFileToProg.Add(tup.Key, new PersistentProgram(program)); } fileToProg = newFileToProg; foreach (var tup in templateToConstants) { Console.WriteLine("Applying template {0}: {1} ({2} constants created)", tup.Key, templateToStr[tup.Key], tup.Value); } return(ret); }
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; }
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; }
static Program Process(Program program) { // Get rid of Synonyms RemoveTypeSynonyms.Remove(program); //BoogieUtil.PrintProgram(program, "tt.bpl"); program = BoogieUtil.ReResolveInMem(program, false); // Create "null" var nil = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "NULL", btype.Int), false); nil.AddAttribute("allocated"); // axiom NULL == 0; //var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0))); program.AddTopLevelDeclaration(nil); //program.AddTopLevelDeclaration(ax); // add "allocator" to malloc program.TopLevelDeclarations.OfType <Procedure>() .Where(p => MallocNames.Contains(p.Name)) .Iter(p => p.AddAttribute("allocator")); // inline functions InlineFunctions(program); // Add attribute {:fpcondition} to assume cmds in charge of branching in function pointer dispatch procs var fpAt = new AnnotateFPDispatchProcVisitor(); fpAt.Run(program); // Add MustReach function calls to the begining of each procedure and upon returns if (detectDeadCode) { var ddc = new SimpleDeadcodeDectectionVisitor(); ddc.Run(program); } // if we don't check NULL, stop here if (!checkNULL && !checkUAF) { return(program); } if (checkUAF) { var iu = new InstrumentUAF(); iu.Instrument(program, nil); program.AddTopLevelDeclaration(new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0)))); return(program); } // Remove literal constants var CE = new ConstantElimination(); CE.Run(program); // Convert 0 to NULL in the program ConvertToNull.Convert(program, nil); // Add NULL axiom here such that ConvertToNULL doesn't lead to dumb axiom var ax = new Axiom(Token.NoToken, Expr.Eq(Expr.Ident(nil), Expr.Literal(0))); program.AddTopLevelDeclaration(ax); // Add "assert !aliasQ(e, NULL)" for each expression M[e] appearing in the program InstrumentMemoryAccesses.Instrument(program, nil); // Put {:scalar} {:AllocatorVar} on $CurrAddr var alloc = program.TopLevelDeclarations.OfType <GlobalVariable>().Where(g => g.Name == allocVar) .FirstOrDefault(); if (alloc != null) { //alloc.AddAttribute("scalar"); alloc.AddAttribute(AvUtil.AvnAnnotations.AllocatorVarAttr); } else { Console.WriteLine("Warning: Global variable $CurrAddr not found"); } if (initMem) { InitMemory(program); } return(program); }
public static Program InjectDualityProof(Program program, string DualityProofFile) { Program DualityProof; using (var st = new System.IO.StreamReader(DualityProofFile)) { var s = ParserHelper.Fill(st, new List <string>()); // replace %i by bound_var_i for (int i = 0; i <= 9; i++) { s = s.Replace(string.Format("%{0}", i), string.Format("pm_bv_{0}", i)); } var v = Parser.Parse(s, DualityProofFile, out DualityProof); if (v != 0) { throw new Exception("Failed to parse " + DualityProofFile); } } var implToContracts = new Dictionary <string, List <Expr> >(); foreach (var proc in DualityProof.TopLevelDeclarations.OfType <Procedure>()) { implToContracts.Add(proc.Name, new List <Expr>()); foreach (var ens in proc.Ensures) { implToContracts[proc.Name].AddRange(GetExprConjunctions(ens.Condition)); } } var counter = 0; var GetExistentialConstant = new Func <Constant>(() => { var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "DualityProofConst" + (counter++), Microsoft.Boogie.Type.Bool), false); c.AddAttribute("existential"); return(c); }); var constsToAdd = new List <Declaration>(); foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>()) { if (!implToContracts.ContainsKey(proc.Name)) { continue; } if (QKeyValue.FindBoolAttribute(proc.Attributes, "nohoudini")) { continue; } foreach (var expr in implToContracts[proc.Name]) { var c = GetExistentialConstant(); constsToAdd.Add(c); proc.Ensures.Add(new Ensures(false, Expr.Imp(Expr.Ident(c), expr))); } } program.AddTopLevelDeclarations(constsToAdd); return(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); }
static HashSet <string> BreakDownInvariants(Program program, HashSet <string> candidates) { var markkeep = new HashSet <string>(); var added = new HashSet <Constant>(); var counter = 0; var GetExistentialConstant = new Func <Constant>(() => { var c = new Constant(Token.NoToken, new TypedIdent(Token.NoToken, "DualityProofConstBrokenDown" + (counter++), Microsoft.Boogie.Type.Bool), false); c.AddAttribute("existential"); return(c); }); var constants = new Dictionary <string, Constant>(); program.TopLevelDeclarations.OfType <Constant>() .Where(c => QKeyValue.FindBoolAttribute(c.Attributes, "existential")) .Iter(c => constants.Add(c.Name, c)); foreach (var proc in program.TopLevelDeclarations.OfType <Procedure>()) { var newens = new List <Ensures>(); foreach (var ens in proc.Ensures.Where(e => !e.Free)) { string constantName = null; Expr expr = null; var match = Microsoft.Boogie.Houdini.Houdini.GetCandidateWithoutConstant( ens.Condition, candidates, out constantName, out expr); if (!match) { continue; } var elements = SimplifyExpr.BreakDownExpr(expr); if (elements.Count == 1) { markkeep.Add(constantName); continue; } // add cost constants[constantName].AddAttribute(Driver.CostAttr, Expr.Literal(1)); // add the constituents foreach (var elem in elements) { var c = GetExistentialConstant(); added.Add(c); newens.Add(new Ensures(false, Expr.Imp(Expr.Ident(c), elem))); } } proc.Ensures.AddRange(newens); } program.TopLevelDeclarations.OfType <Constant>() .Where(c => markkeep.Contains(c.Name)) .Iter(c => c.AddAttribute(Driver.MustKeepAttr)); program.AddTopLevelDeclarations(added); return(markkeep); }