Beispiel #1
0
 public Config()
 {
     procMap     = new ProcedureMap("procedure");
     functionMap = new ProcedureMap("function");
     globalMap   = new ParamMap();
     typeMap     = new ParamMap();
     constMap    = new ParamMap();
 }
Beispiel #2
0
        public ParamMap Filter(Predicate <HDuple <string> > f)
        {
            var npm = new ParamMap();

            foreach (var m in this)
            {
                if (f(m))
                {
                    npm.Add(m);
                }
            }
            return(npm);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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());
        }
Beispiel #5
0
        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);
        }
Beispiel #6
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));
        }
Beispiel #7
0
        //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);
                }
            }
        }