示例#1
0
        /// <summary>
        /// Create the EQ_f_f' procedure statically (eagerly) to avoid generating it again and again
        /// </summary>
        /// <param name="f"></param>
        /// Outputs the list of synEq functions for stubs that have no bodies on both sides
        private static bool RVTCreateEQProcs(int f, ref List <int> synEq, ref List <int> empty1, ref List <int> empty2)
        {
            //name of the function
            string fname = fnIndexToName1[f];

            var n1     = cg.NodeOfName(fname);
            var n2Name = funs.Get(n1.Name);

            if (n2Name == null)
            {
                Log.Out(Log.Error, "Could not find mapping for " + n1.Name);
                Log.Out(Log.Error, "Dumping config...");
                Log.Out(Log.Error, cfg.ToString());
                return(false);
            }

            var n2 = cg.NodeOfName(n2Name);

            if (n2 == null)
            {
                Log.Out(Log.Error, "ERROR: Could not find " + n2Name + " in ARGS[1]");
                return(false);
            }

            if (n1.Proc == null || n2.Proc == null)
            {
                Log.Out(Log.Error, "Missing procedure for " + n1.Name + " or " + n2.Name + ": skipping...");
                return(false);
            }

            //TODO: currently return false for corner cases...FIX this carefully

            if (n1.Name.EndsWith("nondet_choice"))
            {
                Log.Out(Log.Normal, "skipping nondet_choice");
                return(false);
            }

            if (n1.Impl == null && n2.Impl == null)
            {
                Log.Out(Log.Normal, "No implementation for " + n1.Name + ": skipping...");
                synEq.Add(f);
                empty1.Add(f);
                empty2.Add(fnNameToIndex2[n2.Name]);
                return(true);
            }

            if (n1.Impl == null)
            {
                Log.Out(Log.Error, "!Missing implementation for " + n1.Name);
                empty1.Add(f);
                return(false);
            }

            if (n2.Impl == null)
            {
                Log.Out(Log.Error, "!Missing implementation for " + n2.Name);
                empty2.Add(fnNameToIndex2[n2.Name]);
                return(false);
            }

            var ignores = new HashSet <Variable>(n1.IgnoreSet);

            ignores.UnionWith(n2.IgnoreSet);

            // Creates EQ_f_f' function
            List <Variable> outputVars;
            string          eqpName = Transform.mkEqProcName(n1.Name, n2.Name);

            Duple <Procedure, Implementation> eqp;

            eqp = Transform.EqualityReduction(n1.Impl, n2.Impl, cfg.FindProcedure(n1.Name, n2.Name), ignores, out outputVars);

            // if any visible output
            //VerificationTask vt;
            if (eqp != null)
            {
                mergedProgram.AddTopLevelDeclarations(outputVars.Map(x => x as Declaration));
                mergedProgram.AddTopLevelDeclaration(eqp.fst);
                mergedProgram.AddTopLevelDeclaration(eqp.snd);
            }

            //declare the uninterpreted funcs/canonical set of constants  in merged program
            //mergedProgram.AddTopLevelDeclarations(newDecls);
            var canonicalConst = SDiff.Boogie.ConstantFactory.Get().Constants.Map(x => x as Declaration);

            mergedProgram.AddTopLevelDeclarations(canonicalConst);


            //Log.Out(Log.Normal, "Resolving and Typechecking again..");
            if (BoogieUtils.ResolveAndTypeCheckThrow(mergedProgram, Options.MergedProgramOutputFile))
            {
                Log.LogEmit(Log.Normal, mergedProgram.Emit);
                return(false);
            }

            if (Options.TraceVerify)
            {
                Log.Out(Log.Normal, "merged program with ufs etc");
                Log.LogEmit(Log.Normal, mergedProgram.Emit);
            }

            // callgraph has changed because EQ programs are added
            Log.Out(Log.Normal, "Building callgraphs and computing read and write sets");
            cg = CallGraph.Make(mergedProgram);
            ReadWriteSetDecorator.DoDecorate(cg); //start from scratch to fill in the read/write sets
            var mergedProgramNewDecl = new Program();

            mergedProgram.AddTopLevelDeclarations(mergedProgramNewDecl.TopLevelDeclarations);
            mergedProgram.TopLevelDeclarations = SDiff.Boogie.Process.RemoveDuplicateDeclarations(mergedProgram.TopLevelDeclarations.ToList());

            Duple <Duple <Procedure, Implementation>, List <Variable> > tmp = new Duple <Duple <Procedure, Implementation>, List <Variable> >(eqp, outputVars);

            eqProcsCreated.Add(eqpName, tmp);


            return(true);
        }