static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("usage: SmackInst.exe infile.bpl outfile.bpl [options]"); return; } if (args.Any(a => a == "/break")) { System.Diagnostics.Debugger.Launch(); } if (args.Any(a => a == "/initMem")) { initMem = true; } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // Read the input file var program = BoogieUtil.ReadAndResolve(args[0]); // Process it program = Process(program); // write the output BoogieUtil.PrintProgram(program, args[1]); }
public InsertAtBeginningRule(string plhs, string prhs, string globalDecls) : base(plhs, prhs, globalDecls) { //ProcedureToMatchToInsertion = new Dictionary<Procedure, List<Cmd>>(); ProcedureToMatchToInsertion = new Dictionary <Implementation, List <Cmd> >(); //bit hacky: we need to get the delcaration code for each procedure.. // .. and we want them preferably without the semicolon.. var procStrings = new List <string>((plhs.Split(new char[] { ';' }))); procStrings.RemoveAt(procStrings.Count - 1); //we need a separate insertion for every progstring because the IdentifierExpression pointing // to one of the parameters must refer to the declaration in the procedure declaration.. foreach (var procString in procStrings) { Program prog; string progString = globalDecls + procString + "{\n" + prhs + "\n}"; Parser.Parse(progString, "dummy.bpl", out prog); BoogieUtil.ResolveProgram(prog, "dummy.bpl"); //Assumes that the only Implementation(s) correspond to those from ProcedureRule, and not in GlobalDeclarations //Debug.Assert(prog.Implementations.Count() == 1, "No implementations in property file allowed other than in ProcedureRule"); //ProcedureToMatchToInsertion.Add(prog.Implementations.First(), prog.Implementations.First().Blocks.First().Cmds); //HACKY!!! Assumes that Implementations are ordered as they appear in the file, and GlobalDeclarations appear ahead of PF ProcedureToMatchToInsertion.Add(prog.Implementations.Last(), prog.Implementations.Last().Blocks.First().Cmds); } }
// precondition: pathProgram has a single implementation // Suppress an assertion (that failed in the pathProgram) and // return its token public AssertToken SuppressAssert(Program pathProgram) { var impl = pathProgram.TopLevelDeclarations.OfType <Implementation>() .First(); var tokenId = -1; foreach (var acmd in impl.Blocks[0].Cmds.OfType <PredicateCmd>()) { tokenId = QKeyValue.FindIntAttribute(acmd.Attributes, "avn", -1); if (tokenId == -1) { continue; } break; } Debug.Assert(tokenId != -1); var token = new AssertToken(tokenId); SuppressToken(token); BoogieUtil.DoModSetAnalysis(currProg); suppressedTokens.Add(token); return(token); }
private void UnsuppressToken(AssertToken token) { var location = tokenLocation[token]; var p = BoogieUtil.findProcedureImpl(currProg.TopLevelDeclarations, location.Item1); var block = p.Blocks.Where(blk => blk.Label == location.Item2).FirstOrDefault(); // disable assignment to assertsPassed var ncmds = new List <Cmd>(); foreach (var cmd in block.Cmds) { if (!Options.DeepAsserts && cmd is AssumeCmd && QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "suppressAssert", -1) == token.id) { ncmds.Add(BoogieAstFactory.MkVarEqExpr(assertsPassed, (cmd as AssumeCmd).Expr)); } else if (Options.DeepAsserts && cmd is AssumeCmd && QKeyValue.FindIntAttribute((cmd as AssumeCmd).Attributes, "avn", -1) == token.id) { ncmds.Add(new AssertCmd(Token.NoToken, (cmd as AssertCmd).Expr, (cmd as AssertCmd).Attributes)); } else { ncmds.Add(cmd); } } block.Cmds = ncmds; }
// Verify that the trace is a valid counterexample (i.e., it returns an assertion-failure counterexample // upon verification. // Returns a program that consists of a single implementation with a single basic // block that contains the trace. public bool verifyTrace(out Program newProg) { // Currently, this only works for intraprocedural traces Debug.Assert(acex.calleeCounterexamples.Count == 0); HashSet <string> calledProcs; Implementation traceImpl = getImplementation(out calledProcs); newProg = new Program(); // The set of called procedures should only be ones // that do not have an implementation foreach (Declaration decl in prog.TopLevelDeclarations) { if (decl is GlobalVariable) { newProg.AddTopLevelDeclaration(decl); } else if (decl is Procedure) { Procedure tmp = decl as Procedure; if (calledProcs.Contains(tmp.Name)) { newProg.AddTopLevelDeclaration(decl); } else if (tmp.Name == impl.Name) { Procedure pex = new Procedure(Token.NoToken, tmp.Name + "_cex", tmp.TypeParameters, tmp.InParams, tmp.OutParams, tmp.Requires, tmp.Modifies, tmp.Ensures, tmp.Attributes); newProg.AddTopLevelDeclaration(pex); } } else if (decl is Implementation) { Implementation tmp = decl as Implementation; Debug.Assert(!calledProcs.Contains(tmp.Name)); } else { // Just add the other guys (axioms, functions, etc.) newProg.AddTopLevelDeclaration(decl); } } newProg.AddTopLevelDeclaration(traceImpl); newProg = BoogieUtil.ReResolve(newProg, "cex.bpl"); Program newProgCopy = BoogieUtil.ReadAndResolve("cex.bpl"); // (We need to create a copy because Boogie.Verify changes the input program) var errors = new List <BoogieErrorTrace>(); var ret = BoogieVerify.Verify(newProgCopy, out errors); if (ret != BoogieVerify.ReturnStatus.NOK) { return(false); } return(true); }
// convert {:Ebasic} to {:Ebasic n} void NameEnvironmentConstraints(Program program) { procsWithEnvAssumptions = new HashSet <string>(); var cnt = 0; var AddAttr = new Action <Implementation, Cmd>((impl, cmd) => { var acmd = cmd as AssumeCmd; if (acmd == null) { return; } if (!QKeyValue.FindBoolAttribute(acmd.Attributes, AvnAnnotations.EnvironmentAssumptionAttr)) { return; } acmd.Attributes = BoogieUtil.removeAttr(AvnAnnotations.EnvironmentAssumptionAttr, acmd.Attributes); acmd.Attributes = new QKeyValue(Token.NoToken, AvnAnnotations.EnvironmentAssumptionAttr, new List <object> { Expr.Literal(cnt) }, acmd.Attributes); cnt++; procsWithEnvAssumptions.Add(impl.Name); }); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { foreach (var block in impl.Blocks) { block.Cmds.Iter(c => AddAttr(impl, c)); } } }
void Instrument(Implementation impl) { var varDecls = new Dictionary <string, string>(); var cb = new CollectBasePointer(varDecls); cb.VisitImplementation(impl); foreach (var block in impl.Blocks) { var newcmds = new List <Cmd>(); foreach (Cmd cmd in block.Cmds) { if (cmd is AssumeCmd && BoogieUtil.checkAttrExists("nonnull", (cmd as AssumeCmd).Attributes)) { continue; } if (cmd is AssignCmd) { newcmds.AddRange(ProcessAssign(cmd as AssignCmd, varDecls)); } else if (cmd is AssumeCmd) { newcmds.AddRange(ProcessAssume(cmd as AssumeCmd, varDecls)); } else if (cmd is CallCmd) { newcmds.AddRange(ProcessCall(cmd as CallCmd, varDecls)); } else { newcmds.Add(cmd); } } block.Cmds = newcmds; } }
private void ChangeStubsIntoUnkowns() { var procsWithImpl = prog.TopLevelDeclarations.OfType <Implementation>() .Select(x => x.Proc); var procs = prog.TopLevelDeclarations.OfType <Procedure>(); // remove procedures that are never called var procsUsed = new HashSet <string>(); prog.TopLevelDeclarations.OfType <Implementation>() .Iter(impl => impl.Blocks .Iter(blk => blk.cmds.OfType <CallCmd>() .Iter(cc => procsUsed.Add(cc.callee)))); //TODO: this can be almost quadratic in the size of |Procedures|, cleanup var procsWithoutImpl = procs.Where(x => !procsWithImpl.Contains(x) && procsUsed.Contains(x.Name)); var stubImpls = new List <Implementation>(); foreach (var p in procsWithoutImpl) { if (BoogieUtil.checkAttrExists("allocator", p.Attributes)) { continue; } MkStubImplementation(stubImpls, p); } prog.AddTopLevelDeclarations(stubImpls); }
public void ComputePreconditions() { var NameToImpl = new Func <string, Implementation>(name => BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, name)); var main = id2Graph[program.mainProcName]; main.UpdatePrecondition(main.precondition.Top(NameToImpl(main.Id))); IntraGraph.TopDown = true; var worklist = new SortedSet <IntraGraph>(main); worklist.Add(main); var SetPrecondition = new Action <string, IWeight>((name, weight) => { var g = id2Graph[name]; var changed = g.UpdatePrecondition(weight); if (changed) { worklist.Add(g); } }); while (worklist.Any()) { var proc = worklist.First(); worklist.Remove(proc); proc.PropagatePrecondition(NameToImpl, SetPrecondition); } IntraGraph.TopDown = false; }
public override Expr VisitNAryExpr(NAryExpr node) { var nArgs = node.Args.Select(x => base.VisitExpr(x)).ToList(); node.Args = nArgs; var fcall = node.Fun as FunctionCall; if (fcall != null && fcall.Func.HasAttribute(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn)) { var formals = new List <Variable>(); fcall.Func.InParams.Iter(a => { var z = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, a.Name, a.TypedIdent.Type), true); formals.Add(z); }); var r = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "r", fcall.Func.OutParams[0].TypedIdent.Type), false); var f = new Function(Token.NoToken, fcall.FunctionName + "__" + uniqFuncs.Count, formals, r); //inherit all attributes other than mkUniqueFn f.Attributes = BoogieUtil.removeAttr(ExprMatchVisitor.BoogieKeyWords.MkUniqueFn, fcall.Func.Attributes); f.Body = fcall.Func.Body; uniqFuncs.Add(f); program.AddTopLevelDeclaration(f); node.Fun = new FunctionCall(f); } return(node); }
public static VarSet GetAllVars(Program p) { //List<GlobalVariable> globalDecls = BoogieUtil.GetGlobalVariables(p); var procedures = BoogieUtil.GetProcedures(p); var implementations = BoogieUtil.GetImplementations(p); var allVars = new VarSet(); foreach (var proc in procedures) { var uses = new GlobalVarsUsed(); uses.VisitRequiresSeq(proc.Requires); uses.VisitEnsuresSeq(proc.Ensures); // skip visiting modifies clause allVars.Add(new VarSet(uses.globalsUsed, proc.Name)); } foreach (var impl in implementations) { var uses = new GlobalVarsUsed(); uses.VisitBlockList(impl.Blocks); allVars.Add(new VarSet(uses.globalsUsed, impl.Name)); } //globalDecls.Iterate(x => procedures.Iterate(y => allVars.Add(x.Name, y.Name))); //globalDecls.Iterate(x => implementations.Iterate(y => allVars.Add(x.Name, y.Name))); return(allVars); }
public CmdRule(string plhs, string prhs, string pDeclarations) : base(plhs, prhs, pDeclarations) { var rhs = prhs; //allow keyword-command "#this;" instead of "call #this;": Debug.Assert(!Regex.Match(rhs, @"call\s* #this\(\)\s*;").Success, "call #this(); syntax is deprecated"); const string onlyThisPattern = @"#this\s*;"; var onlyThisMatch = Regex.Match(rhs, onlyThisPattern); if (onlyThisMatch.Success) { rhs = Regex.Replace(rhs, onlyThisPattern, "call #this();"); } Program prog; string progString = string.Format(CmdTemplate, pDeclarations, plhs, rhs); Parser.Parse(progString, "dummy.bpl", out prog); BoogieUtil.ResolveProgram(prog, "dummy.bpl"); CmdsToMatch = new List <Cmd>(); CmdsToMatch.AddRange(prog.Implementations.ElementAt(0).Blocks.First().Cmds); InsertionTemplate = new List <Cmd>(); InsertionTemplate.AddRange(prog.Implementations.ElementAt(1).Blocks.First().Cmds); Prog = prog; }
bool IsAssumeNonNull(Cmd cmd) { var acmd = cmd as AssumeCmd; if (acmd == null) { return(false); } if (BoogieUtil.checkAttrExists("partition", acmd.Attributes)) { return(false); } var expr = acmd.Expr as NAryExpr; if (expr == null) { return(false); } var exprIsNull = new Predicate <Expr>(e => { return((e is IdentifierExpr) && (e as IdentifierExpr).Name == "null"); }); if (expr.Fun is BinaryOperator && (expr.Fun as BinaryOperator).Op == BinaryOperator.Opcode.Neq && (exprIsNull(expr.Args[0]) || exprIsNull(expr.Args[1]))) { return(true); } return(false); }
private void GenVC(Implementation impl) { ModelViewInfo mvInfo; Dictionary <int, Absy> label2absy; vcgen.ConvertCFG2DAG(impl); vcgen.PassifyImpl(impl, out mvInfo); var gen = prover.VCExprGen; var vcexpr = vcgen.GenerateVC(impl, null, out label2absy, prover.Context); // Create a macro so that the VC can sit with the theorem prover Macro macro = new Macro(Token.NoToken, impl.Name + "Macro", new List <Variable>(), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false)); prover.DefineMacro(macro, vcexpr); // Store VC impl2VC.Add(impl.Name, gen.Function(macro)); //Console.WriteLine("VC of {0}: {1}", impl.Name, vcexpr); // Find the assert impl2EndStateVars.Add(impl.Name, new List <VCExpr>()); var found = false; foreach (var blk in impl.Blocks) { foreach (var cmd in blk.Cmds.OfType <AssertCmd>()) { if (BoogieUtil.isAssertTrue(cmd)) { continue; } var nary = cmd.Expr as NAryExpr; if (nary == null) { continue; } var pred = nary.Fun as FunctionCall; if (pred == null || pred.FunctionName != (impl.Name + (AbstractHoudini.summaryPredSuffix))) { continue; } Debug.Assert(!found); found = true; nary.Args.OfType <Expr>() .Iter(expr => impl2EndStateVars[impl.Name].Add(prover.Context.BoogieExprTranslator.Translate(expr))); } } Debug.Assert(found); // Grab summary predicates var visitor = new FindSummaryPred(prover.VCExprGen); visitor.Mutate(vcexpr, true); impl2CalleeSummaries.Add(impl.Name, new List <Tuple <string, VCExprNAry> >()); visitor.summaryPreds.Iter(tup => impl2CalleeSummaries[impl.Name].Add(tup)); }
private void attachEnsures(Implementation impl) { List <Variable> functionInterfaceVars = new List <Variable>(); foreach (Variable v in BoogieUtil.GetGlobalVariables(vcgen.program)) { functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true)); } foreach (Variable v in impl.InParams) { functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true)); } foreach (Variable v in impl.OutParams) { functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", v.TypedIdent.Type), true)); } foreach (IdentifierExpr e in impl.Proc.Modifies) { if (e.Decl == null) { continue; } functionInterfaceVars.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", e.Decl.TypedIdent.Type), true)); } Formal returnVar = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "", Bpl.Type.Bool), false); var function = new Function(Token.NoToken, impl.Name + summaryPredSuffix, functionInterfaceVars, returnVar); prover.Context.DeclareFunction(function, ""); List <Expr> exprs = new List <Expr>(); foreach (Variable v in BoogieUtil.GetGlobalVariables(vcgen.program)) { Contract.Assert(v != null); exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); } foreach (Variable v in impl.Proc.InParams) { Contract.Assert(v != null); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } foreach (Variable v in impl.Proc.OutParams) { Contract.Assert(v != null); exprs.Add(new IdentifierExpr(Token.NoToken, v)); } foreach (IdentifierExpr ie in impl.Proc.Modifies) { Contract.Assert(ie != null); if (ie.Decl == null) { continue; } exprs.Add(ie); } Expr postExpr = new NAryExpr(Token.NoToken, new FunctionCall(function), exprs); impl.Proc.Ensures.Add( new Ensures(Token.NoToken, false, postExpr, "")); }
private static void ComputeCallGraph(Program program) { program.TopLevelDeclarations.OfType <Implementation>() .Iter(impl => { Succ.Add(impl.Name, new HashSet <Implementation>()); Pred.Add(impl.Name, new HashSet <Implementation>()); }); var name2Impl = BoogieUtil.nameImplMapping(program); foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>()) { foreach (var blk in impl.Blocks) { foreach (var cmd in blk.Cmds.OfType <CallCmd>()) { if (!Succ.ContainsKey(cmd.callee)) { continue; } Succ[impl.Name].Add(name2Impl[cmd.callee]); Pred[cmd.callee].Add(impl); } } } }
// Prune away EntryPoints that cannot reach an assertion static void PruneRedundantEntryPoints(Program program) { var procs = BoogieUtil.procsThatMaySatisfyPredicate(program, cmd => (cmd is AssertCmd && !BoogieUtil.isAssertTrue(cmd))); procs = harnessInstrumentation.entrypoints.Difference(procs); Console.WriteLine("Pruning away {0} entry points as they cannot reach an assert", procs.Count); harnessInstrumentation.PruneEntryPoints(program, procs); }
public WorkItemR(Implementation i, string l) { impl = i; labelBlockMap = BoogieUtil.labelBlockMapping(impl); label = l; block = getBlock(label, labelBlockMap); count = 0; }
public static bool getSourceInfo(Cmd cmd, out string file, out int line, out int column, out bool keepCmd) { file = null; line = -1; column = -1; keepCmd = true; var acmd = cmd as PredicateCmd; if (acmd == null) { return(false); } var attr = BoogieUtil.getAttr("sourceloc", acmd.Attributes); if (attr != null && attr.Count == 3) { file = attr[0] as string; var tt = attr[1] as LiteralExpr; if (tt != null && (tt.Val is Microsoft.Basetypes.BigNum)) { line = ((Microsoft.Basetypes.BigNum)(tt.Val)).ToInt; } tt = attr[2] as LiteralExpr; if (tt != null && (tt.Val is Microsoft.Basetypes.BigNum)) { column = ((Microsoft.Basetypes.BigNum)(tt.Val)).ToInt; } } else { file = QKeyValue.FindStringAttribute(acmd.Attributes, "sourceFile"); if (file == null) { file = QKeyValue.FindStringAttribute(acmd.Attributes, "sourcefile"); } line = QKeyValue.FindIntAttribute(acmd.Attributes, "sourceLine", -1); if (line == -1) { line = QKeyValue.FindIntAttribute(acmd.Attributes, "sourceline", -1); } } if (file == null || line == -1) { return(false); } if (acmd.Expr is LiteralExpr && (acmd.Expr as LiteralExpr).IsTrue) { keepCmd = false; } return(true); }
static void MarkEntryPoint(Program program, string proc) { // remove existing entrypoints program.TopLevelDeclarations.OfType <NamedDeclaration>() .Iter(decl => decl.Attributes = BoogieUtil.removeAttr("entrypoint", decl.Attributes)); program.TopLevelDeclarations.OfType <Implementation>() .Where(impl => impl.Name == proc) .Iter(impl => impl.Proc.AddAttribute("entrypoint")); }
static void Initalize(string boogieOptions) { CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; CommandLineOptions.Clo.UseSubsumption = CommandLineOptions.SubsumptionOption.Never; CommandLineOptions.Clo.ContractInfer = true; BoogieUtil.InitializeBoogie(boogieOptions); CommandLineOptions.Clo.ErrorLimit = 1; cba.Util.BoogieVerify.options = new BoogieVerifyOptions(); }
public void Unify(string outfile) { // Gather all maps AllMaps = new HashSet <string>(); program.TopLevelDeclarations .OfType <GlobalVariable>() .Where(g => g.TypedIdent.Type.IsMap && (g.TypedIdent.Type as MapType).Result.IsInt) .Iter(g => AllMaps.Add(g.Name)); // Fix Cmds program.TopLevelDeclarations .OfType <Implementation>() .Iter(impl => impl.Blocks.Iter(block => block.Cmds .OfType <Cmd>().Iter(cmd => Visit(cmd)))); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitEnsuresSeq(p.Ensures)); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitRequiresSeq(p.Requires)); var impls = new HashSet <string>(); program.TopLevelDeclarations.OfType <Implementation>() .Iter(impl => impls.Add(impl.Name)); program.TopLevelDeclarations.OfType <Procedure>() .Where(p => impls.Contains(p.Name)) .Iter(p => p.Modifies = new List <IdentifierExpr>()); program.TopLevelDeclarations.OfType <Procedure>() .Iter(p => VisitIdentifierExprSeq(p.Modifies)); // Remove globals var newDecls = new List <Declaration>(); foreach (var decl in program.TopLevelDeclarations) { var glob = decl as GlobalVariable; if (glob == null || !AllMaps.Contains(glob.Name)) { newDecls.Add(decl); } } program.TopLevelDeclarations = newDecls; program.AddTopLevelDeclaration(U); // print program BoogieUtil.DoModSetAnalysis(program); BoogieUtil.PrintProgram(program, outfile); program = null; }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (!Matches || _toConsume.Count == 0) { Matches = false; return(base.VisitIdentifierExpr(node)); } // check if we need to switch to anyExprMode if (_toConsume.Peek() is NAryExpr && (((NAryExpr)_toConsume.Peek()).Fun) is FunctionCall && BoogieUtil.checkAttrExists(BoogieKeyWords.AnyExpr, ((FunctionCall)((NAryExpr)_toConsume.Peek()).Fun).Func.Attributes)) { _anyExprMode = true; _toConsume.Pop(); ((NAryExpr)_toConsume.Peek()).Args.Iter(arg => _toConsume.Push(arg)); var result = VisitIdentifierExpr(node); _anyExprMode = false; return(result); } if (!(_toConsume.Peek() is IdentifierExpr)) { Matches = false; return(base.VisitIdentifierExpr(node)); } var idexToConsume = (IdentifierExpr)_toConsume.Peek(); if (idexToConsume.Decl != null) { if (Equals(node.Decl.TypedIdent.Type, idexToConsume.Decl.TypedIdent.Type) && AreAttributesASubset(idexToConsume.Decl.Attributes, node.Decl.Attributes)) { Substitution.Add(idexToConsume.Decl, node); _toConsume.Pop(); } else { Matches = false; } return(base.VisitIdentifierExpr(node)); } if (idexToConsume.Name == node.Name) { return(base.VisitIdentifierExpr(node)); } Matches = false; return(base.VisitIdentifierExpr(node)); }
//TODO: collect some stats about the instrumentation, mb some debugging output?? private static void Main(string[] args) { if (args.Length < 3) { Console.WriteLine("usage: PropInst.exe propertyFile.avp boogieInputFile.bpl boogieOutputFile.bpl"); return; } if (args.Any(s => s == "/break")) { System.Diagnostics.Debugger.Launch(); } // initialize Boogie CommandLineOptions.Install(new CommandLineOptions()); CommandLineOptions.Clo.PrintInstrumented = true; // read the boogie program that is to be instrumented var boogieProgram = BoogieUtil.ReadAndResolve(args[1], false); // parse the property file var propLines = File.ReadLines(args[0]); string globalDeclarations; List <Rule> rules; CreateRulesFromProperty(propLines, out globalDeclarations, out rules); // GlobalDeclarations: add the global declarations from the property to the Boogie program Program dummyProg; Parser.Parse(globalDeclarations, "dummy.bpl", out dummyProg); boogieProgram.AddTopLevelDeclarations(dummyProg.TopLevelDeclarations); //resolve the program with the new declarations which may include funcs and procs with bodies boogieProgram.Resolve(); // CmdRule: find insertions sites (Commands), insert code there InstrumentCmdRule.Instrument(boogieProgram, rules.OfType <CmdRule>()); // InsertAtBeginningRule: find insertion sites (Procedures), insert code there InstrumentProcedureRule.Instrument(boogieProgram, rules.OfType <InsertAtBeginningRule>()); // make functions with {:mkUniqueFn} unique (new MkUniqueFnVisitor(boogieProgram)).Visit(boogieProgram); //augment the CorralExtraInit procedure (perform this after Matching/instrumentation) AugmentCorralExtraInit(boogieProgram); string outputFile = args[2]; BoogieUtil.PrintProgram(boogieProgram, outputFile); Stats.printStats(); }
public static bool checkFunctionsAreInlined(Program program) { foreach (var func in program.TopLevelDeclarations.OfType <Function>()) { if (func.Body != null && !BoogieUtil.checkAttrExists("inline", func.Attributes)) { Console.WriteLine("Function {0} does not have an inline attribute", func.Name); return(false); } } return(true); }
// Prune away non-candidates, verify using the rest static BoogieVerify.ReturnStatus PruneAndRun(PersistentProgram inp, HashSet <string> candidates, out HashSet <string> assignment, ref int inlined) { var program = inp.getProgram(); program.Typecheck(); program = BoogieUtil.ReResolve(program); // Remove non-candidates CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, candidates, true); program.RemoveTopLevelDeclarations(decl => (decl is Constant) && QKeyValue.FindBoolAttribute(decl.Attributes, "existential") && !candidates.Contains((decl as Constant).Name)); //BoogieUtil.PrintProgram(program, "hi_query" + IterCnt + ".bpl"); // Run Houdini var ot = CommandLineOptions.Clo.ProverKillTime; CommandLineOptions.Clo.ProverKillTime = HoudiniTimeout; assignment = CoreLib.HoudiniInlining.RunHoudini(program, true); CommandLineOptions.Clo.ProverKillTime = ot; //Console.WriteLine(" >> Contracts: {0}", assignment.Count); // Read the program again, add contracts program = inp.getProgram(); program.Typecheck(); CoreLib.HoudiniInlining.InstrumentHoudiniAssignment(program, assignment); //BoogieUtil.PrintProgram(program, "si_query" + IterCnt + ".bpl"); // Run SI var err = new List <BoogieErrorTrace>(); // Set bound BoogieVerify.options.maxInlinedBound = 0; if (inlined != 0) { BoogieVerify.options.maxInlinedBound = PerfMetric(inlined); } var rstatus = BoogieVerify.Verify(program, out err, true); //Console.WriteLine(string.Format(" >> Procedures Inlined: {0}", BoogieVerify.CallTreeSize)); //Console.WriteLine(string.Format("Boogie verification time: {0} s", BoogieVerify.verificationTime.TotalSeconds.ToString("F2"))); inlined = BoogieVerify.CallTreeSize + 1; BoogieVerify.options.CallTree = new HashSet <string>(); BoogieVerify.CallTreeSize = 0; BoogieVerify.verificationTime = TimeSpan.Zero; return(rstatus); }
// Rename basic blocks, local variables // Add "havoc locals" at the beginning // block return private static void RenameImpl(Implementation impl, Dictionary <string, Tuple <Block, Implementation> > origProg) { var origImpl = (new FixedDuplicator(true)).VisitImplementation(impl); var origBlocks = BoogieUtil.labelBlockMapping(origImpl); // create new locals var newLocals = new Dictionary <string, Variable>(); foreach (var l in impl.LocVars.Concat(impl.InParams).Concat(impl.OutParams)) { // substitute even formal variables with LocalVariables. This is fine // because we finally just merge all implemnetations together var nl = BoogieAstFactory.MkLocal(l.Name + "_" + impl.Name + "_copy", l.TypedIdent.Type); newLocals.Add(l.Name, nl); } // rename locals var subst = new VarSubstituter(newLocals, new Dictionary <string, Variable>()); subst.VisitImplementation(impl); // Rename blocks foreach (var blk in impl.Blocks) { var newName = impl.Name + "_" + blk.Label; origProg.Add(newName, Tuple.Create(origBlocks[blk.Label], origImpl)); blk.Label = newName; if (blk.TransferCmd is GotoCmd) { var gc = blk.TransferCmd as GotoCmd; gc.labelNames = new List <string>( gc.labelNames.Select(lab => impl.Name + "_" + lab)); } if (blk.TransferCmd is ReturnCmd) { // block return blk.Cmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); } } /* * // havoc locals -- not necessary * if (newLocals.Count > 0) * { * var ies = new List<IdentifierExpr>(); * newLocals.Values.Iter(v => ies.Add(Expr.Ident(v))); * impl.Blocks[0].Cmds.Insert(0, new HavocCmd(Token.NoToken, ies)); * } */ }
// Adds a new main: // assertsPassed := true; // call main(); // assert assertsPassed; string addMain(CBAProgram program) { var dup = new FixedDuplicator(); var origMain = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, program.mainProcName); var newMain = dup.VisitImplementation(origMain); var newProc = dup.VisitProcedure(origMain.Proc); newMain.Name += "_SeqInstr"; newProc.Name += "_SeqInstr"; newMain.Proc = newProc; var mainIns = new List <Expr>(); foreach (Variable v in newMain.InParams) { mainIns.Add(Expr.Ident(v)); } var mainOuts = new List <IdentifierExpr>(); foreach (Variable v in newMain.OutParams) { mainOuts.Add(Expr.Ident(v)); } var callMain = new CallCmd(Token.NoToken, program.mainProcName, mainIns, mainOuts); callMain.Proc = origMain.Proc; var cmds = new List <Cmd>(); cmds.Add(BoogieAstFactory.MkVarEqConst(assertsPassed, true)); cmds.Add(callMain); cmds.Add(new AssertCmd(Token.NoToken, Expr.Ident(assertsPassed))); var blk = new Block(Token.NoToken, "start", cmds, new ReturnCmd(Token.NoToken)); newMain.Blocks = new List <Block>(); newMain.Blocks.Add(blk); program.AddTopLevelDeclaration(newProc); program.AddTopLevelDeclaration(newMain); program.mainProcName = newMain.Name; // Set entrypoint origMain.Attributes = BoogieUtil.removeAttr("entrypoint", origMain.Attributes); origMain.Proc.Attributes = BoogieUtil.removeAttr("entrypoint", origMain.Proc.Attributes); newMain.AddAttribute("entrypoint"); return(newMain.Name); }
// Remove the dispatch to certain entrypoints public static void RemoveEntryPoints(Program program, HashSet <string> procs) { var mainImpl = BoogieUtil.findProcedureImpl(program.TopLevelDeclarations, AvnAnnotations.CORRAL_MAIN_PROC); foreach (var block in mainImpl.Blocks) { if (block.Cmds.OfType <CallCmd>().Any(cc => procs.Contains(cc.callee))) { block.Cmds.Clear(); } } BoogieUtil.pruneProcs(program, mainImpl.Name); }
public void VisitImplementation(Implementation impl) { // callee -> id var cnt = new Dictionary <string, int>(); foreach (var block in impl.Blocks) { var callcnt = 0; for (int i = 0; i < block.Cmds.Count; i++) { var cc = block.Cmds[i] as CallCmd; if (cc == null) { continue; } if (!cnt.ContainsKey(cc.callee)) { cnt[cc.callee] = 0; } var uniqueId = useGlobalCounter ? counter : cnt[cc.callee]; var attr = new List <object>(); attr.Add(new LiteralExpr(Token.NoToken, Microsoft.BaseTypes.BigNum.FromInt(uniqueId))); cc.Attributes = BoogieUtil.removeAttr("si_old_unique_call", cc.Attributes); var oldAttr = BoogieUtil.getAttr("si_unique_call", cc.Attributes); if (oldAttr != null) { cc.Attributes = BoogieUtil.removeAttr("si_unique_call", cc.Attributes); var newattr = new QKeyValue(Token.NoToken, "si_old_unique_call", oldAttr, null); if (cc.Attributes == null) { cc.Attributes = newattr; } else { cc.Attributes.AddLast(newattr); } } cc.Attributes = new QKeyValue(Token.NoToken, "si_unique_call", attr, cc.Attributes); callIdToLocation.Add(Tuple.Create(impl.Name, cc.callee, uniqueId), Tuple.Create(block.Label, callcnt)); cnt[cc.callee]++; callcnt++; counter++; } } }