예제 #1
0
        private static BoogieMethodData MethodDataFromImpl(
            Implementation impl,
            BoogieGlobalData globalData,
            List <Variable> extraLocalVariables = null
            )
        {
            //add out params to local variables for now
            var locals = new List <Variable>(impl.LocVars).Union(impl.OutParams);

            if (extraLocalVariables != null)
            {
                locals = locals.Union(extraLocalVariables);
            }


            /* procedures and implementations do not use the same objects for the variables in the spec --> need to sync
             * for pre- and postcondition
             */
            var formalProcImplSubst = Substituter.SubstitutionFromDictionary(impl.GetImplFormalMap());
            var preconditions       = new List <Tuple <Expr, bool> >();

            foreach (var req in impl.Proc.Requires)
            {
                var e = Substituter.Apply(formalProcImplSubst, req.Condition);
                preconditions.Add(Tuple.Create(e, req.Free));
            }

            var postconditions = new List <Tuple <Expr, bool> >();

            foreach (var ens in impl.Proc.Ensures)
            {
                var e = Substituter.Apply(formalProcImplSubst, ens.Condition);
                postconditions.Add(Tuple.Create(e, ens.Free));
            }


            return(new BoogieMethodData(
                       globalData,
                       new List <TypeVariable>(impl.TypeParameters),
                       new List <Variable>(impl.InParams),
                       locals,
                       null,
                       new List <IdentifierExpr>(impl.Proc.Modifies),
                       preconditions,
                       postconditions));
        }
예제 #2
0
        /// <summary>
        /// Compute and apply the invariants for the program using the underlying abstract domain.
        /// </summary>
        public static void ComputeProgramInvariants(Program program, Dictionary <Procedure, Implementation[]> procedureImplementations, NativeLattice lattice)
        {
            Contract.Requires(program != null);
            Contract.Requires(procedureImplementations != null);
            Contract.Requires(lattice != null);

            // Gather all the axioms to create the initial lattice element
            // Differently stated, it is the \alpha from axioms (i.e. first order formulae) to the underlyng abstract domain
            var initialElement = lattice.Top;

            Contract.Assert(initialElement != null);
            foreach (var decl in program.TopLevelDeclarations)
            {
                var ax = decl as Axiom;
                if (ax != null)
                {
                    initialElement = lattice.Constrain(initialElement, ax.Expr);
                }
            }

            // analyze each procedure
            foreach (var decl in program.TopLevelDeclarations)
            {
                var proc = decl as Procedure;
                if (proc != null && procedureImplementations.ContainsKey(proc))
                {
                    // analyze each implementation of the procedure
                    foreach (var impl in procedureImplementations[proc])
                    {
                        // add the precondition to the axioms
                        Substitution formalProcImplSubst = Substituter.SubstitutionFromHashtable(impl.GetImplFormalMap());
                        var          start = initialElement;
                        foreach (Requires pre in proc.Requires)
                        {
                            Expr e = Substituter.Apply(formalProcImplSubst, pre.Condition);
                            start = lattice.Constrain(start, e);
                        }

                        lattice.Specialize(impl);
                        Analyze(impl, lattice, start);
                        lattice.Specialize(null);
                    }
                }
            }
        }
예제 #3
0
        //completely clobbers all the existing SCmd constraints
        public static Constraint ExecBlockUp(SymbolicBlock sb, Constraint consIntoBlock)
        {
            var curCons = consIntoBlock;

            for (int i = sb.SCmds.Count - 1; i >= 0; i--)
            {
                var curCmd = sb.SCmds[i];

                var assume = curCmd.Source as AssumeCmd;
                if (assume != null)
                {
                    curCmd.Cons = new Constraint(curCons, false);
                    curCmd.Cons.Add(assume.Expr);
                }

                var assign = curCmd.Source as AssignCmd;
                if (assign != null)
                {
                    curCmd.Cons = new Constraint(curCons, true);

                    for (int j = 0; j < assign.Lhss.Count; j++)
                    {
                        var lhs   = assign.Lhss[j];
                        var gamma = curCmd.Gammas[j];

                        var vToReplace = lhs.DeepAssignedVariable;
                        var rExpr      = gamma.Get(new StoreLhs(vToReplace));
                        curCmd.Cons =
                            new Constraint(curCmd.Cons.Conjuncts.Map(y => Substituter.Apply(x => (x == vToReplace) ? rExpr : null, y)).ToArray());
                    }
                }

                if (assign == null && assume == null)
                {
                    curCmd.Cons = new Constraint(curCons, true);
                }
                else
                {
                    curCons = curCmd.Cons;
                }
            }

            return(curCons);
        }
        public static void SubstituteIncarnationInInstantiationSources(Cmd cmd, Substitution incarnationSubst)
        {
            QKeyValue iter = null;

            if (cmd is AssignCmd assignCmd)
            {
                iter = assignCmd.Attributes;
            }
            else if (cmd is PredicateCmd predicateCmd)
            {
                iter = predicateCmd.Attributes;
            }
            while (iter != null)
            {
                if (iter.Key == "add_to_pool" && iter.Params.Count > 1)
                {
                    var label = iter.Params[0] as string;
                    if (label != null)
                    {
                        var newParams = new List <object> {
                            label
                        };
                        for (int i = 1; i < iter.Params.Count; i++)
                        {
                            var instance = iter.Params[i] as Expr;
                            if (instance != null)
                            {
                                instance = Substituter.Apply(incarnationSubst, instance);
                                newParams.Add(instance);
                            }
                        }
                        iter.ClearParams();
                        iter.AddParams(newParams);
                    }
                }
                iter = iter.Next;
            }
        }
예제 #5
0
        // replace formal-ins and outs with a unique variable
        public static string ExprToTemplateGeneral(Expr expr)
        {
            var GetFin = new Func <btype, Variable>(ty =>
                                                    BoogieAstFactory.MkFormal("v_fin_" + ty.ToString(), ty, true));
            var GetFout = new Func <btype, Variable>(ty =>
                                                     BoogieAstFactory.MkFormal("v_fout_" + ty.ToString(), ty, true));

            var ret =
                Substituter.Apply(new Substitution(v =>
            {
                if (v is Formal && (v as Formal).InComing)
                {
                    return(Expr.Ident(GetFin(v.TypedIdent.Type)));
                }
                if (v is Formal && !(v as Formal).InComing)
                {
                    return(Expr.Ident(GetFout(v.TypedIdent.Type)));
                }
                return(Expr.Ident(v));
            }), expr);

            return(ret.ToString());
        }
예제 #6
0
        public static SymbolicBlock ExecBlockDown(Block b, SymbolicStore gammaIntoBlock, out SymbolicStore gammaOutOfBlock)
        {
            var duper = new Duplicator();
            var sb    = new SymbolicBlock(b);

            SymbolicStore gammaIntoCmd = gammaIntoBlock;

            foreach (Cmd c in b.Cmds)
            {
                var sc = new SymbolicCmd(c);
                if (c is AssumeCmd)
                {
                    if (!((AssumeCmd)c).Expr.Equals(Expr.True))
                    {
                        var tmp = ((AssumeCmd)c).Expr;
                        sc.AddCons(((AssumeCmd)c).Expr);
                    }
                }
                else if (c is AssignCmd)
                {
                    SymbolicStore newGamma; //= new SymbolicStore(gammaIntoCmd);

                    AssignCmd assgn = c as AssignCmd;
                    if (assgn.Lhss.Count != assgn.Rhss.Count)
                    {
                        Console.WriteLine("Bizzare: uneven assignment command in ExecDown");
                        continue;
                    }
                    //each AssignCmd contains a list of assignments
                    for (int i = 0; i < assgn.Lhss.Count; i++)
                    {
                        var lhsrhs = StoreLhs.Make(assgn.Lhss[i], assgn.Rhss[i]);
                        var lhs    = lhsrhs.fst;
                        var rhs    = lhsrhs.snd;

                        Expr oldrhs;
                        gammaIntoCmd.TryGetValue(lhs, out oldrhs);

                        //if lhs was uninitialized, we just add the new binding to the old gamma
                        if (oldrhs == null)
                        {
                            newGamma = new SymbolicStore(gammaIntoCmd);
                            newGamma.Add(lhs, rhs);
                        }
                        //otherwise we have to do substitution over everything
                        else
                        {
                            newGamma = new SymbolicStore();
                            newGamma.Add(lhs, Substituter.Apply(x => (x == lhs.Var) ? duper.VisitExpr(oldrhs) : null, rhs));

                            //otherwise, we need to substitute the old value for lhs into Gamma
                            foreach (var entry in gammaIntoCmd)
                            {
                                if (!entry.Key.Equals(lhs))
                                {
                                    newGamma.Add(entry.Key, Substituter.Apply(x => (x == lhs.Var) ? duper.VisitExpr(oldrhs) : null, entry.Value));
                                }
                            }
                        }
                        gammaIntoCmd = newGamma;
                        sc.AddGamma(newGamma);
                    }
                }
                else if (c is HavocCmd)
                {
                    Log.Out(Log.Warning, "Help! HavocCmd in ExecBlockDown!");
                }

                // if(sc.Gammas.Count != 0)
                sb.SCmds.Add(sc);
            }

            gammaOutOfBlock = gammaIntoCmd;
            return(sb);
        }
예제 #7
0
 public override Expr _Substitute(Expr e, Expr orig, Expr replacement)
 {
     Substituter s = new Substituter(orig, replacement, false);
     return s.Substitute(e);
 }
예제 #8
0
        public static void ProcessCounterexamplesWOSymbolicOut(SDiffCounterexamples errors, List <Variable> globals, List <Variable> eqLocVars,
                                                               Implementation vtLeftProcImpl, Implementation vtRightProcImpl, List <Declaration> consts, List <Model> errModelList,
                                                               string v1Name, string v2Name)
        {
            List <Expr>  constraintExprs = new List <Expr>();
            List <Block> listBlocksV1    = new List <Block>();
            List <Block> listBlocksV2    = new List <Block>();

            Model[] errModelArray = errModelList.ToArray();

            var label = new GotoCmd(Token.NoToken, new List <String>()
            {
                "DONE"
            });

            label.labelNames = new List <string>(); // label.labelTargets = new List<Block>();
            label.labelNames.Add("DONE");           //label.labelTargets.Add("DONE");


            // First block
            var labels = new List <String>();

            for (int j = 0; j < errors.Count; j++)
            {
                labels.Add("Cex" + j);
            }

            labels.Add("ELSE");
            var labelEntry = new GotoCmd(Token.NoToken, labels);

            labelEntry.labelTargets = new List <Block>();

            for (int j = 0; j < errors.Count; j++)
            {
                labelEntry.labelNames.Add("Cex" + j);//labelEntry.labelTargets.Add("Cex" + j);
            }

            for (int i = 0; i < errors.Count; i++)
            {
                var impl  = errors[i].Impl;
                var trace = errors[i].Trace;

                //Log.Out(Log.Normal, "Attempting symbolic execution of [" + i + "] $ " + impl.Name);


                if (Options.GenerateCTrace)
                {
                    Log.Out(Log.Normal, "Constructing metatrace from location annotations");
                    var extractor = new SDiff.SymEx.TraceExtractor();
                    extractor.VisitTrace(trace);
                    //Log.Out(Log.CTrace, CTrace.Make(extractor.metaTrace));
                    var cTrace = CTrace.Make(extractor.metaTrace, consts, errModelArray[i], v1Name, v2Name);
                    //var cTrace = "";
                    if (cTrace.Trim() != "")
                    {
                        //note that the index for cex on the output shows 1,2,..., instead of 0,1,2....
                        var fname  = impl.Name + "_cex_" + (i + 1) + "_out.c";
                        var cexOut = new TokenTextWriter(impl.Name + "_cex_" + (i + 1) + "_out.c", true);
                        cexOut.WriteLine(cTrace);
                        cexOut.Close();
                        Log.Out(Log.CTrace, "n:" + (i + 1) + ":" + fname);
                        Log.Out(Log.CTrace, "w:" + fname);
                    }
                }

                Log.Out(Log.Normal, "Desugaring calls");
                //HACK!!!: changes havoc x; assume (x= uf(..)); --> x := uf(...)
                var deCall = new SDiff.SymEx.DesugarCallCmds();
                trace = deCall.VisitTrace(trace);

                //symbolic constants
                var symInParams = new List <Variable>(impl.InParams);
                foreach (var g in globals)
                {
                    symInParams.Add(g);
                }

                Log.Out(Log.Normal, "Executing trace downward");
                //symbolic stores (look at symex.cs for the datastructure)
                // var sTrace = SDiff.SymEx.Cexecutor.ExecDown(trace, symInParams);
                Log.Out(Log.Normal, "Executing trace upward");
                //looks at each assume to create the path constants
                //clean up the duplication of assignments
                //SDiff.SymEx.Cexecutor.ExecUp(sTrace);

                Log.Out(Log.Normal, "Grabbing final execution values");
                // var lastStore = sTrace.LastSCmd().Gammas.Last();
                // var firstCons = sTrace.FirstSCmd().Cons;

                // constraintExprs.Add(firstCons.Conjoin());

                //#hemr - generating new strategy right here with inlining counterexamples!

                // Second block
                List <Cmd> cmdsV1_Diff_inline = new List <Cmd>();
                List <Cmd> cmdsV2_Diff_inline = new List <Cmd>();

                Substitution replaceScopeV1 = delegate(Variable x)
                {
                    return(replaceScopeGeneric(vtLeftProcImpl, x));
                };

                Substitution replaceScopeV2 = delegate(Variable x)
                {
                    return(replaceScopeGeneric(vtRightProcImpl, x));
                };

                foreach (Block currentBlock in trace)
                {
                    if (currentBlock.ToString().Contains("inline$" + v1Name))
                    {
                        foreach (Cmd currentCmd in currentBlock.Cmds)
                        {
                            Cmd newCmd = Substituter.Apply(replaceScopeV1, currentCmd);
                            cmdsV1_Diff_inline.Add(newCmd);
                        }
                    }
                    else if (currentBlock.ToString().Contains("inline$" + v2Name))
                    {
                        foreach (Cmd currentCmd in currentBlock.Cmds)
                        {
                            Cmd newCmd = Substituter.Apply(replaceScopeV2, currentCmd);
                            cmdsV2_Diff_inline.Add(newCmd);
                        }
                    }
                }

                Block blockV1 = new Block(Token.NoToken, "Cex" + i, cmdsV1_Diff_inline, label);
                Block blockV2 = new Block(Token.NoToken, "Cex" + i, cmdsV2_Diff_inline, label);

                listBlocksV1.Add(blockV1);
                listBlocksV2.Add(blockV2);

                //#hemr - displaying values related to error model (at console level)

                Model currentModel = errModelArray[i];

                //var keys = currentModel.identifierToPartition.Keys;
                var keys = currentModel.Functions.Where(f => f.Arity == 0).Select(f => f.GetConstant());
            }

            Expr disjunctionDiffCond = Expr.False;

            foreach (Expr currentExpr in constraintExprs)
            {
                disjunctionDiffCond = Expr.Or(disjunctionDiffCond, currentExpr);
            }

            ProcessCounterexampleForDiffInliningWOSymbolicOut(eqLocVars, vtLeftProcImpl, vtRightProcImpl, v1Name, v2Name, listBlocksV1, listBlocksV2, labelEntry);
        }
예제 #9
0
        public static string ExprToTemplateSpecific(Expr expr, bool loop)
        {
            int cnt      = 0;
            var inCache  = new Dictionary <string, Expr>();
            var outCache = new Dictionary <string, Expr>();
            var inToOut  = new Func <string, string>(s => s.StartsWith("in_") ? "out_" + s.Substring("in_".Length) : "");
            var outToIn  = new Func <string, string>(s => s.StartsWith("out_") ? "in_" + s.Substring("out_".Length) : "");

            var GetFin = new Func <Variable, Expr>(v =>
            {
                if (inCache.ContainsKey(v.Name))
                {
                    return(inCache[v.Name]);
                }
                if (loop && outCache.ContainsKey(inToOut(v.Name)))
                {
                    return(new OldExpr(Token.NoToken, outCache[inToOut(v.Name)]));
                }

                var prefix      = loop ? "v_loop_" : "v_fin_";
                prefix         += v.TypedIdent.Type.ToString();
                prefix         += string.Format("_{0}", cnt++);
                var outv        = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, true);
                var outexpr     = loop ? (Expr)(new OldExpr(Token.NoToken, Expr.Ident(outv))) : Expr.Ident(outv);
                inCache[v.Name] = outexpr;
                return(outexpr);
            });

            var GetFout = new Func <Variable, Expr>(v =>
            {
                if (outCache.ContainsKey(v.Name))
                {
                    return(outCache[v.Name]);
                }
                if (loop && inCache.ContainsKey(outToIn(v.Name)) && inCache[outToIn(v.Name)] is OldExpr)
                {
                    return((inCache[outToIn(v.Name)] as OldExpr).Expr);
                }

                var prefix       = loop ? "v_loop_" : "v_fout_";
                prefix          += v.TypedIdent.Type.ToString();
                prefix          += string.Format("_{0}", cnt++);
                var outv         = BoogieAstFactory.MkFormal(prefix, v.TypedIdent.Type, false);
                var outexpr      = Expr.Ident(outv);
                outCache[v.Name] = outexpr;
                return(outexpr);
            });

            var ret =
                Substituter.Apply(new Substitution(v =>
            {
                if (v is Formal && (v as Formal).InComing)
                {
                    return(GetFin(v));
                }
                if (v is Formal && !(v as Formal).InComing)
                {
                    return(GetFout(v));
                }
                return(Expr.Ident(v));
            }), expr);

            return(ret.ToString());
        }