public Config() { procMap = new ProcedureMap("procedure"); functionMap = new ProcedureMap("function"); globalMap = new ParamMap(); typeMap = new ParamMap(); constMap = new ParamMap(); }
public ParamMap Filter(Predicate <HDuple <string> > f) { var npm = new ParamMap(); foreach (var m in this) { if (f(m)) { npm.Add(m); } } return(npm); }
public bool AddFromArray(string[] fs, string[] ps) { HDuple <string> d = HDuple <string> .OfArray(fs); ParamMap p = ParamMap.OfArray(ps); if (d == null) { return(true); } if (p == null) { p = new ParamMap(); } Add(new Duple <HDuple <string>, ParamMap>(d, p)); return(false); }
public static ParamMap OfArray(string[] ps) { ParamMap m = new ParamMap(); try { foreach (string p in ps) { var pr = HDuple <string> .OfArray(p.Split(',')); if (pr != null) { m.Add(pr); } } } catch { return(null); } return((ParamMap)m.Maybe()); }
public static int GuessConfig(string[] args) { string boogieOptions = Options.BoogieUserOpts; //Log.Out(Log.Normal, "Initializing Boogie"); if (SDiff.Boogie.Process.InitializeBoogie(boogieOptions)) { return(1); } string first = args[0], second = args[1]; // First program Program p = BoogieUtils.ParseProgram(first); if (p == null) { return(1); } BoogieUtils.ResolveProgram(p, first); BoogieUtils.TypecheckProgram(p, first); // Second program Program q = BoogieUtils.ParseProgram(second); if (q == null) { return(1); } BoogieUtils.ResolveProgram(q, second); BoogieUtils.TypecheckProgram(q, second); first = first.Substring(0, first.LastIndexOf('.') + 1); second = second.Substring(0, second.LastIndexOf('.') + 1); Config config = new Config(); //store the procs of q by name Dictionary <string, Declaration> qProcs = new Dictionary <string, Declaration>(); Dictionary <string, HashSet <string> > qLoops = new Dictionary <string, HashSet <string> >(); foreach (Declaration d in q.TopLevelDeclarations) { var proc = d as Procedure; if (proc != null) { qProcs.Add(proc.Name, proc); if (proc.Name.Contains("_loop_")) { int indx = proc.Name.IndexOf("_loop_"); string loopProc = proc.Name.Substring(0, indx); if (!qLoops.ContainsKey(loopProc)) { qLoops.Add(loopProc, new HashSet <string>()); } qLoops[loopProc].Add(proc.Name); } } } foreach (Declaration d in p.TopLevelDeclarations) { var proc = d as Procedure; if (proc != null) { if (Util.IsInlinedProc(proc)) { continue; } var pmap = new ParamMap(); foreach (Variable v in proc.InParams) { pmap.Add(new HDuple <string>(v.Name, v.Name)); } foreach (Variable v in proc.OutParams) { pmap.Add(new HDuple <string>(v.Name, v.Name)); } //config.AddProcedure(new Duple<HDuple<string>, ParamMap>(new HDuple<string>(first + proc.Name, second + proc.Name), pmap)); if (qProcs.ContainsKey(proc.Name)) { config.AddProcedure(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + proc.Name, second + proc.Name), pmap)); } else //match loops (A BIG HACK that pretends that the enclosing procedure has only one loop and the mappings are same) { if (proc.Name.Contains("_loop_")) { int indx = proc.Name.IndexOf("_loop_"); string loopProc = proc.Name.Substring(0, indx); if (qLoops.ContainsKey(loopProc) && qLoops[loopProc].Count == 1) { HashSet <string> matchQProcs = qLoops[loopProc]; string qProcName = ""; foreach (string s in matchQProcs) //ugly way to get the singleton string { qProcName = s; } config.AddProcedure(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + proc.Name, second + qProcName), pmap)); } } } } var global = d as GlobalVariable; if (global != null) { config.AddGlobal(new HDuple <string>(first + global.Name, second + global.Name)); } var constant = d as Constant; if (constant != null) { config.AddConstant(new HDuple <string>(first + constant.Name, second + constant.Name)); } var function = d as Function; if (function != null) { var pmap = new ParamMap(); int i = 0; foreach (Variable v in function.InParams) { if (v.Name.Trim().Equals("")) { v.Name = "arg_" + i++; } pmap.Add(new HDuple <string>(v.Name, v.Name)); } if (function.OutParams[0].Name.Equals("")) { function.OutParams[0].Name = "out_ret"; } pmap.Add(new HDuple <string>(function.OutParams[0].Name, function.OutParams[0].Name)); config.AddFunction(new Duple <HDuple <string>, ParamMap>(new HDuple <string>(first + function.Name, second + function.Name), pmap)); } var typector = d as TypeCtorDecl; if (typector != null) { config.AddType(new HDuple <string>(first + typector.Name, second + typector.Name)); } var typesyn = d as TypeSynonymDecl; if (typesyn != null) { config.AddType(new HDuple <string>(first + typesyn.Name, second + typesyn.Name)); } } Console.WriteLine(config.ToString()); return(0); }
public static Duple <Procedure, Implementation> EqualityReduction(Implementation i1, Implementation i2, ParamMap argMap, HashSet <Variable> ignoreSet, out List <Variable> outputVarsForVFTask) { //map ins1 //map outs1 //save globals (1) //... //call //... //save outs //save globals (2) //restore globals (1) //... //call //... //compare Procedure d1 = i1.Proc, d2 = i2.Proc; var globals = new List <Variable>(); foreach (IdentifierExpr ie in d1.Modifies) { globals.Add(ie.Decl); } foreach (IdentifierExpr ie in d2.Modifies) { if (!globals.Contains(ie.Decl)) { globals.Add(ie.Decl); } } /***** Produce mapped list of identifiers *****/ string d1n = d1.Name, d2n = d2.Name; List <Variable> outs1 = FreshVariables(d1.OutParams, B.Factory.MakeLocal), outs2 = FreshVariables(d2.OutParams, B.Factory.MakeLocal), ins1 = FreshVariables(d1.InParams, (x, y) => B.Factory.MakeFormal(x, y, true)), ins2 = FreshVariables(d2.InParams, (x, y) => B.Factory.MakeFormal(x, y, true)); /***** Compute correspondence between d1's ins/outs and d2's ins/outs *****/ List <Variable> unionIns, unionOuts, newIns1, newOuts1, interIns, interOuts; MergeVariableSequencesByMap(ins1, ins2, argMap, out newIns1, out unionIns, out interIns); MergeVariableSequencesByMap(outs1, outs2, argMap, out newOuts1, out unionOuts, out interOuts); ins1 = newIns1; outs1 = newOuts1; /***** Map ignore set to the new variables *****/ for (int i = 0; i < i2.OutParams.Count; i++) { if (ignoreSet.Contains(i2.OutParams[i])) { Log.Out(Log.Warning, "Equality reduction ignoring variable: " + outs2[i].Name); ignoreSet.Add(outs2[i]); } } /***** Emit instructions for saving and restoring *****/ SaveBlock savedInitialGlobals = new SaveBlock(globals.Count); SaveBlock savedc1Globals = new SaveBlock(globals.Count); SaveBlock savedOutputs = new SaveBlock(interOuts.Count); var globalsArr = B.U.VariablesOfVariableSeq(globals); Cmd[] prec1Copy = savedInitialGlobals.EmitSave(globalsArr), postc1Copy = savedc1Globals.EmitSave(globalsArr), postc1Restore = savedInitialGlobals.EmitRestore(globalsArr), prec2Copy = savedOutputs.EmitSave(B.U.VariablesOfVariableSeq(interOuts)); /***** Emit function calls *****/ var c1Ins = B.U.ExprSeqOfVariableSeq(ins1); var c1Outs = B.U.IdentifierExprSeqOfVariableSeq(outs1); var c2Ins = B.U.ExprSeqOfVariableSeq(ins2); var c2Outs = B.U.IdentifierExprSeqOfVariableSeq(outs2); CallCmd c1 = new CallCmd(Token.NoToken, d1n, c1Ins, c1Outs), c2 = new CallCmd(Token.NoToken, d2n, c2Ins, c2Outs); /***** Emit comparison, outputVars *****/ var outputVars = new List <Duple <string, Variable> >(); int numComparables = savedOutputs.Count + savedc1Globals.Count; //wait! if there aren't any comparable values, don't bother emitting a comparator if (numComparables == 0) { Log.Out(Log.Verifier, "No outputs: skipping (" + d1n + ", " + d2n + ")"); outputVarsForVFTask = null; return(null); } if (Options.CheckOutputsForMaps) { foreach (Variable v in savedOutputs.Decls) { if (v.TypedIdent.Type is MapType) { Log.Out(Log.MapEquivs, v.Name + " in " + i1.Name + " is a map comparable!"); } } foreach (Variable v in savedc1Globals.Decls) { if (v.TypedIdent.Type is MapType || v.TypedIdent.Type is TypeSynonymAnnotation) { Log.Out(Log.MapEquivs, v.Name + " global is a map comparable!"); } } } StateBlock outputEqualityState = new StateBlock(numComparables, StateBlock.StateKind.FormalOut); Tuple <Expr, Variable>[] outputEqualityExprs = new Tuple <Expr, Variable> [numComparables]; outputEqualityState.Initialize(Microsoft.Boogie.Type.Bool); IdentifierExpr[] comparisonPostc1Vars = savedc1Globals.Idents, comparisonPrec2Vars = savedOutputs.Idents; List <IdentifierExpr> comparisonOutIds = B.U.IdentifierExprSeqOfVariableSeq(outs2), comparisonGlobals = B.U.IdentifierExprSeqOfVariableSeq(globals); for (int i = 0; i < savedOutputs.Count; i++) { outputEqualityExprs[i] = Tuple.Create(EmitEq(comparisonPrec2Vars[i], comparisonOutIds[i], ignoreSet), comparisonOutIds[i].Decl); outputVars.Add(new Duple <string, Variable>("Output_of_" + d1.Name + "_" + outs1[i].Name, savedOutputs.Decls[i])); outputVars.Add(new Duple <string, Variable>("Output_of_" + d2.Name + "_" + outs2[i].Name, outs2[i])); } for (int i = 0; i < savedc1Globals.Count; i++) { outputEqualityExprs[savedOutputs.Count + i] = Tuple.Create(EmitEq(comparisonPostc1Vars[i], comparisonGlobals[i], ignoreSet), comparisonGlobals[i].Decl); outputVars.Add(new Duple <string, Variable>("Output_of_" + d1.Name + "_" + globals[i].Name, savedc1Globals.Decls[i])); outputVars.Add(new Duple <string, Variable>("Output_of_" + d2.Name + "_" + globals[i].Name, globals[i])); } //new: we translate equalities as havoc lhs; lhs := lhs || x == x'; to enable diff counterexamples for each equality //havoc all lhs HavocCmd hcmd = new HavocCmd(Token.NoToken, outputEqualityState.Idents.ToList()); List <Expr> rhs = new List <Expr>(outputEqualityExprs.Map(i => i.Item1)); for (int i = 0; i < rhs.Count; ++i) { rhs[i] = Expr.Or(outputEqualityState.Idents[i], rhs[i]); } List <AssignLhs> lhs = new List <AssignLhs>(outputEqualityState.Idents.Map(x => new SimpleAssignLhs(Token.NoToken, x))); Cmd assgnCmd = new AssignCmd(Token.NoToken, lhs, rhs); /***** Save outputVars as globals (outputVarsForVFTask) *****/ //note that this list is order dependent. later code will assume that variables are paired SaveBlock leftRightOutputs = new SaveBlock(outputVars.Count, StateBlock.StateKind.Global); leftRightOutputs.Initialize(outputVars.Map(x => new Duple <string, Microsoft.Boogie.Type>(x.fst, x.snd.TypedIdent.Type))); Cmd[] saveOutputsIntoGlobals = leftRightOutputs.EmitSave(outputVars.Map(x => x.snd).ToArray()); outputVarsForVFTask = leftRightOutputs.Decls.ToList(); /***** Compile procedure body ****/ List <Cmd> body = new List <Cmd>(); foreach (Cmd c in prec1Copy) { body.Add(c); } body.Add(c1); foreach (Cmd c in postc1Copy) { body.Add(c); } foreach (Cmd c in postc1Restore) { body.Add(c); } foreach (Cmd c in prec2Copy) { body.Add(c); } body.Add(c2); foreach (Cmd c in saveOutputsIntoGlobals) { body.Add(c); } body.Add(hcmd); body.Add(assgnCmd); //special hack to limit outvar to {:stmtTaintCollectorGlobalVar} if (Options.refinedStmtTaint) { Options.OutputVars.Clear(); globals.Where(x => QKeyValue.FindBoolAttribute(x.Attributes, "stmtTaintCollectorGlobalVar")).Iter(x => Options.OutputVars.Add(x.ToString())); } List <Ensures> outputPostConditions = new List <Ensures>(); if (Options.splitOutputEqualities) { outputPostConditions.AddRange(outputEqualityState.Idents.Map(y => new Ensures(false, y))); System.Diagnostics.Debug.Assert(outputEqualityState.Count == outputEqualityExprs.Length); for (int i = 0; i < outputPostConditions.Count; ++i) { var name = outputEqualityExprs[i].Item2.Name; //check if name matches with at least one of the outputVars patterns if (Options.OutputVars.Count() > 0 && !Options.OutputVars.Any(x => name.Contains(x))) { outputPostConditions[i] = new Ensures(true, outputPostConditions[i].Condition); } outputPostConditions[i].Attributes = new QKeyValue(Token.NoToken, "EqVar", new List <object>() { name }, null); } } else if (!Options.EnumerateAllPaths) { outputPostConditions.Add(new Ensures(false, B.U.BigAnd(outputEqualityState.Idents))); } else //assert(false) causes all the paths to be enumerated { outputPostConditions.Add(new Ensures(false, Expr.False)); //to get exhaustive paths } var eqModifiesDupe = new List <IdentifierExpr>(d1.Modifies); eqModifiesDupe.AddRange(d2.Modifies); foreach (var v in leftRightOutputs.Decls) { eqModifiesDupe.Add(Expr.Ident(v)); } //uniqueify eqModifies var eqModifiesUn = new List <IdentifierExpr>(); var eqModifiesVars = new HashSet <Variable>(); var eqModifies = new List <IdentifierExpr>(); foreach (IdentifierExpr ie in eqModifiesDupe) { if (!eqModifiesVars.Contains(ie.Decl)) { eqModifies.Add(ie); } eqModifiesVars.Add(ie.Decl); } //var procName = "EQ_" + d1.Name + "__xx__" + d2.Name; var procName = mkEqProcName(d1.Name, d2.Name); Procedure eqProc = new Procedure(Token.NoToken, procName, B.C.empTypeVariableSeq, unionIns, new List <Variable>(outputEqualityState.Decls), B.C.empRequiresSeq, eqModifies, new List <Ensures>(outputPostConditions)); BigBlock bl = new BigBlock(Token.NoToken, "AA_INSTR_EQ_BODY", body, null, B.C.dmyTransferCmd); List <BigBlock> bll = new List <BigBlock>(); bll.Add(bl); List <Variable> locals = new List <Variable>(); foreach (Variable v in savedOutputs.Decls) { locals.Add(v); } foreach (Variable v in savedc1Globals.Decls) { locals.Add(v); } foreach (Variable v in savedInitialGlobals.Decls) { locals.Add(v); } locals.AddRange(unionOuts); Implementation eqImp = new Implementation(Token.NoToken, procName, B.C.empTypeVariableSeq, unionIns, new List <Variable>(outputEqualityState.Decls), locals, new StmtList(bll, Token.NoToken)); List <Declaration> l = new List <Declaration>(); return(new Duple <Procedure, Implementation>(eqProc, eqImp)); }
//merges two variable sequences using a map. returns mapped seqs and their union //node map is ordered by argument order public static void MergeVariableSequencesByMap(List <Variable> v1, List <Variable> v2, ParamMap map, out List <Variable> newV1, out List <Variable> union, out List <Variable> inter) { var renamer = new VariableRenamer(map, v2); newV1 = renamer.VisitVariableSeq(new List <Variable>(v1)); union = new List <Variable>(v2); inter = new List <Variable>(); foreach (Variable v in newV1) { if (!v2.Contains(v)) { union.Add(v); } else { inter.Add(v); } } }