Ejemplo n.º 1
0
        public static List <Block /*!*/> /*!*/ UnrollLoops(Block start, int unrollMaxDepth, bool soundLoopUnrolling)
        {
            Contract.Requires(start != null);

            Contract.Requires(0 <= unrollMaxDepth);
            Contract.Ensures(cce.NonNullElements(Contract.Result <List <Block> >()));
            Dictionary <Block, GraphNode /*!*/> gd = new Dictionary <Block, GraphNode /*!*/>();
            HashSet <Block> beingVisited           = new HashSet <Block>();
            GraphNode       gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited);

            // Compute SCCs
            StronglyConnectedComponents <GraphNode /*!*/> sccs =
                new StronglyConnectedComponents <GraphNode /*!*/>(gd.Values, Preds, Succs);

            Contract.Assert(sccs != null);
            sccs.Compute();
            Dictionary <GraphNode /*!*/, SCC <GraphNode /*!*/> > containingSCC =
                new Dictionary <GraphNode /*!*/, SCC <GraphNode /*!*/> >();

            foreach (SCC <GraphNode /*!*/> scc in sccs)
            {
                foreach (GraphNode /*!*/ n in scc)
                {
                    Contract.Assert(n != null);
                    containingSCC[n] = scc;
                }
            }

            LoopUnroll lu = new LoopUnroll(unrollMaxDepth, soundLoopUnrolling, containingSCC, new List <Block /*!*/>());

            lu.Visit(gStart);
            lu.newBlockSeqGlobal.Reverse();
            return(lu.newBlockSeqGlobal);
        }
Ejemplo n.º 2
0
        // Compute SCCs and determine a priority order for impls
        static Dictionary <string, int> DeterminePriorityOrder(Program program, Graph <string> callgraph)
        {
            var impls = new HashSet <string>();

            program.TopLevelDeclarations.OfType <Implementation>()
            .Iter(impl => impls.Add(impl.Name));

            var sccs = new StronglyConnectedComponents <string>(callgraph.Nodes,
                                                                new Adjacency <string>(n => DualHoudini ? callgraph.Successors(n) : callgraph.Predecessors(n)),
                                                                new Adjacency <string>(n => DualHoudini ? callgraph.Predecessors(n) : callgraph.Successors(n)));

            sccs.Compute();

            // impl -> priority
            var impl2Priority = new Dictionary <string, int>();
            int p             = 0;

            foreach (var scc in sccs)
            {
                foreach (var impl in scc)
                {
                    impl2Priority.Add(impl, p);
                    p++;
                }
            }

            return(impl2Priority);
        }
Ejemplo n.º 3
0
    public static List<Block/*!*/>/*!*/ UnrollLoops(Block start, int unrollMaxDepth, bool soundLoopUnrolling) {
      Contract.Requires(start != null);

      Contract.Requires(0 <= unrollMaxDepth);
      Contract.Ensures(cce.NonNullElements(Contract.Result<List<Block>>()));
      Dictionary<Block, GraphNode/*!*/> gd = new Dictionary<Block, GraphNode/*!*/>();
      HashSet<Block> beingVisited = new HashSet<Block>();
      GraphNode gStart = GraphNode.ComputeGraphInfo(null, start, gd, beingVisited);

      // Compute SCCs
      StronglyConnectedComponents<GraphNode/*!*/> sccs =
        new StronglyConnectedComponents<GraphNode/*!*/>(gd.Values, Preds, Succs);
      Contract.Assert(sccs != null);
      sccs.Compute();
      Dictionary<GraphNode/*!*/, SCC<GraphNode/*!*/>> containingSCC = new Dictionary<GraphNode/*!*/, SCC<GraphNode/*!*/>>();
      foreach (SCC<GraphNode/*!*/> scc in sccs) {
        foreach (GraphNode/*!*/ n in scc) {
          Contract.Assert(n != null);
          containingSCC[n] = scc;
        }
      }

      LoopUnroll lu = new LoopUnroll(unrollMaxDepth, soundLoopUnrolling, containingSCC, new List<Block/*!*/>());
      lu.Visit(gStart);
      lu.newBlockSeqGlobal.Reverse();
      return lu.newBlockSeqGlobal;
    }
Ejemplo n.º 4
0
 private static IReadOnlyList <HashSet <ValueTag> > ComputePhiSCCs(
     HashSet <ValueTag> phiFunctions,
     Dictionary <ValueTag, HashSet <ValueTag> > phiArgs,
     Dictionary <ValueTag, ValueTag> copyMap)
 {
     // Computes all phi SCCs in the subgraph induced by phis.
     return(StronglyConnectedComponents.Compute(
                phiFunctions,
                arg => phiArgs[arg].Where(phiFunctions.Contains)));
 }
Ejemplo n.º 5
0
        public IEnumerable <Method> OrderedMethods()
        {
            // components are reverse ordered
            List <List <Method> > components = StronglyConnectedComponents.Compute(this.callGraph);

            for (int i = components.Count - 1; i >= 0; i--)
            {
                foreach (Method method in components[i])
                {
                    yield return(method);
                }
            }
        }
        public HashSet <VariableDescriptor> DependsOn(VariableDescriptor v)
        {
            if (DependsOnSCCsDAG == null)
            {
                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Variable dependence: computing SCCs");
                }

                Adjacency <VariableDescriptor> next = new Adjacency <VariableDescriptor>(dependsOnNonTransitive.Successors);
                Adjacency <VariableDescriptor> prev = new Adjacency <VariableDescriptor>(dependsOnNonTransitive.Predecessors);
                StronglyConnectedComponents <VariableDescriptor> DependsOnSCCs =
                    new StronglyConnectedComponents <VariableDescriptor>(
                        dependsOnNonTransitive.Nodes, next, prev);
                DependsOnSCCs.Compute();

                VariableDescriptorToSCC = new Dictionary <VariableDescriptor, SCC <VariableDescriptor> >();
                foreach (var scc in DependsOnSCCs)
                {
                    foreach (var s in scc)
                    {
                        VariableDescriptorToSCC[s] = scc;
                    }
                }

                DependsOnSCCsDAG = new Graph <SCC <VariableDescriptor> >();
                foreach (var edge in dependsOnNonTransitive.Edges)
                {
                    if (VariableDescriptorToSCC[edge.Item1] != VariableDescriptorToSCC[edge.Item2])
                    {
                        DependsOnSCCsDAG.AddEdge(VariableDescriptorToSCC[edge.Item1], VariableDescriptorToSCC[edge.Item2]);
                    }
                }

                SCC <VariableDescriptor> dummy = new SCC <VariableDescriptor>();
                foreach (var n in dependsOnNonTransitive.Nodes)
                {
                    DependsOnSCCsDAG.AddEdge(VariableDescriptorToSCC[n], dummy);
                }

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Variable dependence: SCCs computed!");
                }
            }

            return(DependsOn(VariableDescriptorToSCC[v]));
        }
Ejemplo n.º 7
0
        public bool MayReach(Block src, Block dst)
        {
            if (ReachabilityGraphSCCsDAG == null)
            {
                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Interprocedural reachability: computing SCCs");
                }

                Adjacency <Block> next = new Adjacency <Block>(reachabilityGraph.Successors);
                Adjacency <Block> prev = new Adjacency <Block>(reachabilityGraph.Predecessors);
                StronglyConnectedComponents <Block> ReachabilitySCCs = new StronglyConnectedComponents <Block>(
                    reachabilityGraph.Nodes, next, prev);
                ReachabilitySCCs.Compute();

                BlockToSCC = new Dictionary <Block, SCC <Block> >();
                foreach (var scc in ReachabilitySCCs)
                {
                    foreach (var s in scc)
                    {
                        BlockToSCC[s] = scc;
                    }
                }

                ReachabilityGraphSCCsDAG = new Graph <SCC <Block> >();
                foreach (var edge in reachabilityGraph.Edges)
                {
                    if (BlockToSCC[edge.Item1] != BlockToSCC[edge.Item2])
                    {
                        ReachabilityGraphSCCsDAG.AddEdge(BlockToSCC[edge.Item1], BlockToSCC[edge.Item2]);
                    }
                }

                SCC <Block> dummy = new SCC <Block>();
                foreach (var n in reachabilityGraph.Nodes)
                {
                    ReachabilityGraphSCCsDAG.AddEdge(BlockToSCC[n], dummy);
                }

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Interprocedural reachability: SCCs computed!");
                }
            }

            return(ReachableFrom(BlockToSCC[src]).Contains(dst));
        }
Ejemplo n.º 8
0
        private bool IsFinitelyInstantiable()
        {
            var sccs = new StronglyConnectedComponents <TypeVariable>(typeVariableDependencyGraph.Nodes, typeVariableDependencyGraph.Predecessors, typeVariableDependencyGraph.Successors);

            sccs.Compute();
            foreach (var scc in sccs)
            {
                foreach (var edge in strongDependencyEdges)
                {
                    if (scc.Contains(edge.Item1) && scc.Contains(edge.Item2))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        private void ConstructStagesDAG()
        {
            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Annotation dependence analysis: Computing SCCs");
            }

            Adjacency <string> next = new Adjacency <string>(AnnotationDependences.Successors);
            Adjacency <string> prev = new Adjacency <string>(AnnotationDependences.Predecessors);

            SCCs = new StronglyConnectedComponents <string>(
                AnnotationDependences.Nodes, next, prev);
            SCCs.Compute();

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Annotation dependence analysis: Building stages DAG");
            }

            Dictionary <string, SCC <string> > rep = new Dictionary <string, SCC <string> >();

            foreach (var scc in SCCs)
            {
                foreach (var s in scc)
                {
                    rep[s] = scc;
                }
            }

            StagesDAG = new Graph <SCC <string> >();

            foreach (var edge in AnnotationDependences.Edges)
            {
                if (rep[edge.Item1] != rep[edge.Item2])
                {
                    StagesDAG.AddEdge(rep[edge.Item1], rep[edge.Item2]);
                }
            }

            SCC <string> dummy = new SCC <string>();

            foreach (var scc in SCCs)
            {
                StagesDAG.AddEdge(scc, dummy);
            }
        }
Ejemplo n.º 10
0
    private void ConstructStagesDAG()
    {
      if (CommandLineOptions.Clo.Trace)
      {
        Console.WriteLine("Annotation dependence analysis: Computing SCCs");
      }

      Adjacency<string> next = new Adjacency<string>(AnnotationDependences.Successors);
      Adjacency<string> prev = new Adjacency<string>(AnnotationDependences.Predecessors);
      SCCs = new StronglyConnectedComponents<string>(
        AnnotationDependences.Nodes, next, prev);
      SCCs.Compute();

      if (CommandLineOptions.Clo.Trace)
      {
        Console.WriteLine("Annotation dependence analysis: Building stages DAG");
      }

      Dictionary<string, SCC<string>> rep = new Dictionary<string, SCC<string>>();
      foreach (var scc in SCCs)
      {
        foreach (var s in scc)
        {
          rep[s] = scc;
        }
      }

      StagesDAG = new Graph<SCC<string>>();

      foreach (var edge in AnnotationDependences.Edges)
      {
        if (rep[edge.Item1] != rep[edge.Item2])
        {
          StagesDAG.AddEdge(rep[edge.Item1], rep[edge.Item2]);
        }
      }

      SCC<string> dummy = new SCC<string>();
      foreach (var scc in SCCs)
      {
        StagesDAG.AddEdge(scc, dummy);
      }
    }
Ejemplo n.º 11
0
        public static List <SCC <Procedure> > ComputeOrderedSCCs(Graph <Procedure> graph)
        {
            Adjacency <Procedure> next = new Adjacency <Procedure>(graph.Successors);
            Adjacency <Procedure> prev = new Adjacency <Procedure>(graph.Predecessors);

            var sccs = new StronglyConnectedComponents <Procedure>(graph.Nodes, next, prev);

            sccs.Compute();
            //sccs.Iter(s => { s.Iter(p => Console.Write(p + ", ")); Console.WriteLine(); });

            var order = sccs.ToList();

            for (int i = 0; i < order.Count; i++)
            {
                for (int j = i + 1; j < order.Count; j++)
                {
                    Debug.Assert(order[i].All(p => order[j].All(p2 => !graph.Edge(p2, p))));
                }
            }

            return(order);
        }
Ejemplo n.º 12
0
        public RHS(CBAProgram program, IWeight iw)
        {
            this.iw      = iw;
            this.program = program;
            intraGraphs  = new List <IntraGraph>();
            id2Graph     = new Dictionary <string, IntraGraph>();
            Succ         = new Dictionary <string, HashSet <IntraGraph> >();
            Pred         = new Dictionary <string, HashSet <IntraGraph> >();
            computeTime  = TimeSpan.Zero;

            // Make all the graphs
            program.TopLevelDeclarations
            .OfType <Implementation>()
            .Iter(impl => intraGraphs.Add(
                      new IntraGraph(impl, iw, p =>
            {
                if (!id2Graph.ContainsKey(p))
                {
                    return(null);
                }
                else
                {
                    return(id2Graph[p].summary);
                }
            }
                                     )));

            intraGraphs.Iter(g => id2Graph.Add(g.Id, g));

            intraGraphs.Iter(g =>
            {
                Succ.Add(g.Id, new HashSet <IntraGraph>());
                Pred.Add(g.Id, new HashSet <IntraGraph>());
            });

            intraGraphs.Iter(g =>
                             g.Callees
                             .Where(s => id2Graph.ContainsKey(s))
                             .Iter(s =>
            {
                Succ[g.Id].Add(id2Graph[s]);
                Pred[s].Add(g);
            }
                                   ));

            // assign priorities
            var sccs = new StronglyConnectedComponents <IntraGraph>(
                intraGraphs,
                new Adjacency <IntraGraph>(g => Succ[g.Id]),
                new Adjacency <IntraGraph>(g => Pred[g.Id]));

            sccs.Compute();

            var priority = intraGraphs.Count;

            foreach (var scc in sccs)
            {
                /*
                 * if (scc.Count > 1)
                 * {
                 *  Console.WriteLine("SCC size: {0}", scc.Count);
                 *  scc.Iter(g => Console.WriteLine("{0}", g.Id));
                 * }
                 */
                scc.Iter(g => g.priority = priority);
                priority--;
            }
        }
Ejemplo n.º 13
0
        public void computeSummaries(ISummaryElement summaryClass)
        {
            this.summaryClass = summaryClass;

            var main = program.TopLevelDeclarations
                       .OfType <Implementation>()
                       .Where(impl => QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))
                       .FirstOrDefault();

            Debug.Assert(main != null);

            program.TopLevelDeclarations
            .OfType <Implementation>()
            .Iter(impl => impl2Summary.Add(impl.Name, summaryClass.GetFlaseSummary(program, impl)));

            // Build call graph
            var Succ = new Dictionary <Implementation, HashSet <Implementation> >();
            var Pred = new Dictionary <Implementation, HashSet <Implementation> >();

            name2Impl.Values.Iter(impl => Succ.Add(impl, new HashSet <Implementation>()));
            name2Impl.Values.Iter(impl => Pred.Add(impl, new HashSet <Implementation>()));

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                foreach (var blk in impl.Blocks)
                {
                    foreach (var cmd in blk.Cmds.OfType <CallCmd>())
                    {
                        if (!name2Impl.ContainsKey(cmd.callee))
                        {
                            continue;
                        }
                        Succ[impl].Add(name2Impl[cmd.callee]);
                        Pred[name2Impl[cmd.callee]].Add(impl);
                    }
                }
            }

            // Build SCC
            var sccs = new StronglyConnectedComponents <Implementation>(name2Impl.Values,
                                                                        new Adjacency <Implementation>(n => Succ[n]),
                                                                        new Adjacency <Implementation>(n => Pred[n]));

            sccs.Compute();

            // impl -> priority
            var impl2Priority = new Dictionary <string, int>();
            int p             = 0;

            foreach (var scc in sccs)
            {
                scc.Iter(n => impl2Priority.Add(n.Name, p));
                p++;
            }

            var worklist = new SortedSet <Tuple <int, Implementation> >();

            name2Impl.Values
            .Iter(impl => worklist.Add(Tuple.Create(impl2Priority[impl.Name], impl)));

            while (worklist.Any())
            {
                var impl = worklist.First().Item2;
                worklist.Remove(worklist.First());

                var changed = ProcessImpl(impl);

                if (changed)
                {
                    Pred[impl].Iter(pred => worklist.Add(Tuple.Create(impl2Priority[pred.Name], pred)));
                }
            }

            foreach (var tup in impl2Summary)
            {
                Console.WriteLine("Summary of {0}:", tup.Key);
                Console.WriteLine("{0}", tup.Value);
            }

            prover.Close();
            CommandLineOptions.Clo.TheProverFactory.Close();
        }
        public HashSet<VariableDescriptor> DependsOn(VariableDescriptor v)
        {
            if (DependsOnSCCsDAG == null) {
            if (CommandLineOptions.Clo.Trace) {
              Console.WriteLine("Variable dependence: computing SCCs");
            }
            Adjacency<VariableDescriptor> next = new Adjacency<VariableDescriptor>(dependsOnNonTransitive.Successors);
            Adjacency<VariableDescriptor> prev = new Adjacency<VariableDescriptor>(dependsOnNonTransitive.Predecessors);
            StronglyConnectedComponents<VariableDescriptor> DependsOnSCCs = new StronglyConnectedComponents<VariableDescriptor>(
              dependsOnNonTransitive.Nodes, next, prev);
            DependsOnSCCs.Compute();

            VariableDescriptorToSCC = new Dictionary<VariableDescriptor, SCC<VariableDescriptor>>();
            foreach (var scc in DependsOnSCCs) {
              foreach (var s in scc) {
            VariableDescriptorToSCC[s] = scc;
              }
            }

            DependsOnSCCsDAG = new Graph<SCC<VariableDescriptor>>();
            foreach (var edge in dependsOnNonTransitive.Edges) {
              if (VariableDescriptorToSCC[edge.Item1] != VariableDescriptorToSCC[edge.Item2]) {
            DependsOnSCCsDAG.AddEdge(VariableDescriptorToSCC[edge.Item1], VariableDescriptorToSCC[edge.Item2]);
              }
            }

            SCC<VariableDescriptor> dummy = new SCC<VariableDescriptor>();
            foreach (var n in dependsOnNonTransitive.Nodes) {
              DependsOnSCCsDAG.AddEdge(VariableDescriptorToSCC[n], dummy);
            }

            if (CommandLineOptions.Clo.Trace) {
              Console.WriteLine("Variable dependence: SCCs computed!");
            }
              }
              return DependsOn(VariableDescriptorToSCC[v]);
        }
Ejemplo n.º 15
0
        public VCGenOutcome ComputeSummaries()
        {
            // Compute SCCs and determine a priority order for impls
            var Succ = new Dictionary<string, HashSet<string>>();
            var Pred = new Dictionary<string, HashSet<string>>();
            name2Impl.Keys.Iter(s => Succ[s] = new HashSet<string>());
            name2Impl.Keys.Iter(s => Pred[s] = new HashSet<string>());

            foreach(var impl in name2Impl.Keys) {
                Succ[impl] = new HashSet<string>();
                impl2functionsAsserted[impl].Iter(f =>
                    function2implAssumed[f].Iter(succ =>
                        {
                            Succ[impl].Add(succ);
                            Pred[succ].Add(impl);
                        }));
            }

            var sccs = new StronglyConnectedComponents<string>(name2Impl.Keys,
                new Adjacency<string>(n => Pred[n]),
                new Adjacency<string>(n => Succ[n]));
            sccs.Compute();

            // impl -> priority
            var impl2Priority = new Dictionary<string, int>();
            int p = 0;
            foreach (var scc in sccs)
            {
                foreach (var impl in scc)
                {
                    impl2Priority.Add(impl, p);
                    p++;
                }
            }

            VCGenOutcome overallOutcome = null;

            string[] templates = {"(1)", "(1;1)", "(2)", "((1;1);1)", "((1;1),1)", "(1;2)", "(3)", "(1;3)", "(4)", "(5;2)"};

            if (CommandLineOptions.Clo.Trace)
            {
                Console.WriteLine("Max integral value in the program: " + constantRange);
            }

            for (int i = 0; i < templates.Count(); i++)
            {
                var template = templates[i];
                TemplateParser.initialize(template);
                Template t = TemplateParser.Parse();

                List<int> cvalues = new List<int>();
                cvalues.Add(2);
                int maxRange = constantRange > i ? constantRange : i;
                if (maxRange > 2)
                    cvalues.Add(maxRange);

                foreach (var cvalue in cvalues)
                {
                    if (CommandLineOptions.Clo.Trace)
                    {
                        Console.WriteLine("Inferring Invariants in the template Octagons" + template + " with constantRange = " + cvalue);
                    }

                    ICEOutcome result = LearnInvFromTemplate(impl2Priority, t, cvalue, out overallOutcome);

                    // The program was verified with the current template!
                    if (result == ICEOutcome.InvariantFound)
                    {
                        if (CommandLineOptions.Clo.Trace)
                        {
                            Console.WriteLine("Inferred Invariants in the template Octagons" + template + " with constantRange = " + cvalue);
                        }
                        if (cvalue <= 2)
                            goto exit;

                        int min = 2;
                        int max = cvalue;
                        int mid = (min + max) / 2;
                        while (min <= max)
                        {
                            VCGenOutcome overallOutcomePrime = null;

                            if (CommandLineOptions.Clo.Trace)
                            {
                                Console.WriteLine("Inferring Invariants in the template Octagons" + template + " with constantRange = " + mid);
                            }
                            ICEOutcome resultPrime = LearnInvFromTemplate(impl2Priority, t, mid, out overallOutcomePrime);
                            if (resultPrime == ICEOutcome.InvariantFound)
                            {
                                max = mid - 1;
                                mid = (max + min) / 2;
                                if (CommandLineOptions.Clo.Trace)
                                {
                                    Console.WriteLine("Inferred Invariants in the template Octagons" + template + " with constantRange = " + mid);
                                }
                            }
                            else if (resultPrime == ICEOutcome.InvariantNotFound)
                            {
                                min = mid + 1;
                                mid = (min + max) / 2;
                            }
                            else if (resultPrime == ICEOutcome.ErrorFound)
                            {
                                throw new AbsHoudiniInternalError("Contrary results: Invariant found for constants < " + cvalue + "; error found for constants <" + mid);
                            }
                            else if (resultPrime == ICEOutcome.Timeout)
                            {
                                break;
                            }
                        }
                        // last iteration did not work. So try min again.
                        if (min != mid)
                        {
                            ICEOutcome resultPrime = LearnInvFromTemplate(impl2Priority, t, min, out overallOutcome);
                            Debug.Assert(resultPrime == ICEOutcome.InvariantFound);
                        }
                        goto exit;
                    }
                    else if (result == ICEOutcome.ErrorFound)
                        goto exit;

                    else if (result == ICEOutcome.Timeout)
                        return overallOutcome;

                    Debug.Assert(result == ICEOutcome.InvariantNotFound);

                } // end of loop over template constants

            } // end of loop over boolean (structure of the) templates

            exit:

            z3Context.context.Dispose();
            z3Context.config.Dispose();

            if (true)
            {
                Console.WriteLine("Prover time = {0}", proverTime.TotalSeconds.ToString("F2"));
                Console.WriteLine("Number of prover queries = " + numProverQueries);
                Console.WriteLine("Z3 Learner time = {0}", z3LearnerTime.TotalSeconds.ToString("F2"));
                Console.WriteLine("Number of Z3 Learner queries = " + numZ3LearnerQueries);

                Console.WriteLine("Total time: {0}", proverTime.Add(z3LearnerTime).TotalSeconds.ToString("F2"));

                Console.WriteLine("Number of examples:" + this.numPosExamples);
                Console.WriteLine("Number of counter-examples:" + this.numNegCounterExamples);
                Console.WriteLine("Number of implications:" + this.numImplications);
                Console.WriteLine("Total size of sample: " + (int)(this.numPosExamples + this.numNegCounterExamples + 2 * this.numImplications));
            #if C5
                Console.WriteLine("Total points repeated in the sample: " + this.C5repeatedPoints);
            #endif
                //Console.WriteLine("Range of constants in the template = " + constantRange);
            }

            if (CommandLineOptions.Clo.PrintAssignment)
            {
                // Print the answer
                existentialFunctions.Values.Iter(PrintFunction);
            }

            #if C5
            generateC5Files();
            #endif

            return overallOutcome;
        }
Ejemplo n.º 16
0
        public VCGenOutcome ComputeSummaries()
        {
            // Compute SCCs and determine a priority order for impls
            var Succ = new Dictionary<string, HashSet<string>>();
            var Pred = new Dictionary<string, HashSet<string>>();
            name2Impl.Keys.Iter(s => Succ[s] = new HashSet<string>());
            name2Impl.Keys.Iter(s => Pred[s] = new HashSet<string>());

            foreach(var impl in name2Impl.Keys) {
                Succ[impl] = new HashSet<string>();
                impl2functionsAsserted[impl].Iter(f => 
                    function2implAssumed[f].Iter(succ =>
                        {
                            Succ[impl].Add(succ);
                            Pred[succ].Add(impl);
                        }));
            }

            var sccs = new StronglyConnectedComponents<string>(name2Impl.Keys,
                new Adjacency<string>(n => Pred[n]),
                new Adjacency<string>(n => Succ[n]));
            sccs.Compute();
            
            // impl -> priority
            var impl2Priority = new Dictionary<string, int>();
            int p = 0;
            foreach (var scc in sccs)
            {
                foreach (var impl in scc)
                {
                    impl2Priority.Add(impl, p);
                    p++;
                }
            }

            VCGenOutcome overallOutcome = null;

            var start = DateTime.Now;

            overallOutcome = LearnInv(impl2Priority);

            var elapsed = DateTime.Now;
            this.totaltime = elapsed - start;

            if (true)
            {
                Console.WriteLine("Prover time = {0}", proverTime.TotalSeconds.ToString("F2"));
                Console.WriteLine("Number of prover queries = " + numProverQueries);
                Console.WriteLine("C5 Learner time = {0}", c5LearnerTime.TotalSeconds.ToString("F2"));
                //Console.WriteLine("time to parse JSON and construct Boogie Model = {0}", jsontime.TotalSeconds.ToString("F2"));
                Console.WriteLine("Number of C5 Learner queries = " + c5LearnerQueries);

                //Console.WriteLine("Total time: {0}", proverTime.Add(c5LearnerTime).TotalSeconds.ToString("F2"));
                Console.WriteLine("Total time: {0}", totaltime.Subtract(jsontime).TotalSeconds.ToString("F2"));

                Console.WriteLine("Number of examples:" + this.numPosExamples);
                Console.WriteLine("Number of counter-examples:" + this.numNegCounterExamples);
                Console.WriteLine("Number of implications:" + this.numImplications);

                /*Console.WriteLine("Average tree size: " + ((double)this.totalTreeSize / (double)this.c5LearnerQueries));
                Console.WriteLine("Last tree size: " + this.lastTreeSize);
                Console.WriteLine("Average truetrue implications: " + ((double)this.total_truetrue_implications / (double)this.c5LearnerQueries));
                Console.WriteLine("last truetrue implications: " + this.last_truetrue_implications);
                Console.WriteLine("Average falsetrue implications: " + ((double)this.total_falsetrue_implications/ (double)this.c5LearnerQueries));
                Console.WriteLine("last falsetrue implications: " + this.last_falsetrue_implications);
                Console.WriteLine("Average falsefalse implications: " + ((double)this.total_falsefalse_implications / (double)this.c5LearnerQueries));
                Console.WriteLine("last falsefalse implications: " + this.last_falsefalse_implications);                */
            }

            if (CommandLineOptions.Clo.PrintAssignment)
            {
                // Print the existential functions
                existentialFunctions.Values.Iter(PrintFunction);
            }
            
            return overallOutcome;
        }
Ejemplo n.º 17
0
        public static bool Check(Program program)
        {
            var checkingContext           = new CheckingContext(null);
            var functionDependencyChecker = new FunctionDependencyChecker();

            program.TopLevelDeclarations.OfType <Function>().Iter(function =>
            {
                var expr = QKeyValue.FindExprAttribute(function.Attributes, "inline");
                if (expr != null && expr.Type != Type.Bool)
                {
                    checkingContext.Error(function.tok, "Parameter to :inline attribute on a function must be Boolean");
                }
                if (QKeyValue.FindBoolAttribute(function.Attributes, "inline") &&
                    QKeyValue.FindBoolAttribute(function.Attributes, "define"))
                {
                    checkingContext.Error(function.tok, "A function may not have both :inline and :define attributes");
                }
                if (QKeyValue.FindBoolAttribute(function.Attributes, "inline") &&
                    function.Body == null)
                {
                    checkingContext.Error(function.tok, "Function with :inline attribute must have a body");
                }
                if (QKeyValue.FindBoolAttribute(function.Attributes, "define") &&
                    function.DefinitionBody == null)
                {
                    checkingContext.Error(function.tok, "Function with :define attribute must have a body");
                }
            });
            if (checkingContext.ErrorCount > 0)
            {
                return(false);
            }
            program.TopLevelDeclarations.OfType <Function>()
            .Iter(function => functionDependencyChecker.VisitFunction(function));
            var functionDependencyGraph = functionDependencyChecker.functionDependencyGraph;
            var selfLoops = functionDependencyGraph.Edges.SelectMany(edge =>
                                                                     edge.Item1 == edge.Item2 ? new[] { edge.Item1 } : Enumerable.Empty <Function>()).ToHashSet();
            var sccs = new StronglyConnectedComponents <Function>(
                functionDependencyGraph.Nodes,
                functionDependencyGraph.Predecessors,
                functionDependencyGraph.Successors);

            sccs.Compute();
            sccs.Iter(scc =>
            {
                if (scc.Count > 1 ||
                    scc.Count == 1 && selfLoops.Contains(scc.First()))
                {
                    var errorMsg = "Call cycle detected among functions";
                    var first    = true;
                    var token    = Token.NoToken;
                    scc.Iter(function =>
                    {
                        if (first)
                        {
                            first     = false;
                            errorMsg += ": ";
                            token     = function.tok;
                        }
                        else
                        {
                            errorMsg += ", ";
                        }
                        errorMsg += function.Name;
                    });
                    checkingContext.Error(token, errorMsg);
                }
            });
            return(checkingContext.ErrorCount == 0);
        }
Ejemplo n.º 18
0
        public override CBAProgram runCBAPass(CBAProgram program)
        {
            var nameImplMap = BoogieUtil.nameImplMapping(program);

            // Construct call graph, compute SCCs
            var graph = new Graph <string>();

            foreach (var impl in program.TopLevelDeclarations.OfType <Implementation>())
            {
                impl.Blocks.Iter(block =>
                                 block.Cmds.OfType <CallCmd>().Iter(cmd =>
                                                                    graph.AddEdge(impl.Name, cmd.callee)));
            }
            graph.AddSource(program.mainProcName);
            var preds = new Adjacency <string>(st => graph.Predecessors(st));
            var succs = new Adjacency <string>(st => graph.Successors(st));
            var sccs  = new StronglyConnectedComponents <string>(graph.Nodes, preds, succs);

            sccs.Compute();

            //var dotFileCnt = 1;

            // For each SCC, compute backedges
            foreach (var scc in sccs)
            {
                if (scc.Count == 1)
                {
                    var onlyProc = scc.First();
                    if (nameImplMap.ContainsKey(onlyProc) && QKeyValue.FindBoolAttribute(nameImplMap[onlyProc].Attributes, "LoopProcedure"))
                    {
                        continue;
                    }

                    if (graph.Successors(onlyProc).All(callee => callee != onlyProc))
                    {
                        continue;
                    }
                }

                Console.Write("Considering SCC: ");
                scc.Iter(s => Console.Write("{0} ", s));
                Console.WriteLine();

                foundRecursion = true;

                // pick source
                var sccProcs = new HashSet <string>(scc);
                var src      = scc.FirstOrDefault(proc => graph.Predecessors(proc).Any(pred => !sccProcs.Contains(pred)));
                if (src == null)
                {
                    src = scc.First();
                }

                var grey  = new HashSet <string>();
                var black = new HashSet <string>();
                grey.Add(src);

                backedges     = new HashSet <Tuple <string, string> >();
                dfsTreeParent = new Dictionary <string, string>();
                someCycles    = new List <HashSet <string> >();

                dfs(graph, src, sccProcs, grey, black);

                InferWhatToCut(graph, scc);

                // create copies
                var procCopies = new Dictionary <Tuple <string, int>, Procedure>();
                var implCopies = new Dictionary <Tuple <string, int>, Implementation>();
                foreach (var name in scc)
                {
                    var impl = nameImplMap[name];
                    program.RemoveTopLevelDeclaration(impl);
                    program.RemoveTopLevelDeclaration(impl.Proc);

                    for (int i = 0; i < CommandLineOptions.Clo.RecursionBound; i++)
                    {
                        var dup   = new FixedDuplicator(true);
                        var nimpl = dup.VisitImplementation(impl);
                        var nproc = dup.VisitProcedure(impl.Proc);

                        nimpl.Name += string.Format("#{0}", i);
                        nproc.Name += string.Format("#{0}", i);
                        nimpl.Proc  = nproc;

                        program.AddTopLevelDeclaration(nimpl);
                        program.AddTopLevelDeclaration(nproc);

                        procCopies.Add(Tuple.Create(impl.Name, i), nproc);
                        implCopies.Add(Tuple.Create(impl.Name, i), nimpl);
                    }
                }

                // redirect calls
                foreach (var name in scc)
                {
                    foreach (var pred in graph.Predecessors(name))
                    {
                        if (sccProcs.Contains(pred))
                        {
                            continue;
                        }
                        var pimpl = nameImplMap[pred];
                        foreach (var blk in pimpl.Blocks)
                        {
                            var newcmds = new List <Cmd>();
                            foreach (var cmd in blk.Cmds)
                            {
                                var ccmd = cmd as CallCmd;
                                if (ccmd == null || !sccProcs.Contains(ccmd.callee))
                                {
                                    newcmds.Add(cmd);
                                    continue;
                                }
                                newcmds.Add(
                                    new CallCmd(ccmd.tok, ccmd.callee + string.Format("#{0}", CommandLineOptions.Clo.RecursionBound - 1),
                                                ccmd.Ins, ccmd.Outs, ccmd.Attributes, ccmd.IsAsync));
                            }
                            blk.Cmds = newcmds;
                        }
                    }

                    for (int i = 0; i < CommandLineOptions.Clo.RecursionBound; i++)
                    {
                        var impl = implCopies[Tuple.Create(name, i)];
                        foreach (var blk in impl.Blocks)
                        {
                            var newcmds = new List <Cmd>();
                            foreach (var cmd in blk.Cmds)
                            {
                                var ccmd = cmd as CallCmd;
                                if (ccmd == null || !sccProcs.Contains(ccmd.callee))
                                {
                                    newcmds.Add(cmd);
                                    continue;
                                }
                                var cnt = i;
                                if (CutEdge(name, ccmd.callee))
                                {
                                    cnt--;
                                }

                                if (cnt < 0)
                                {
                                    newcmds.Add(new AssumeCmd(Token.NoToken, Expr.False));
                                }
                                else
                                {
                                    newcmds.Add(new CallCmd(ccmd.tok, ccmd.callee + string.Format("#{0}", cnt),
                                                            ccmd.Ins, ccmd.Outs, ccmd.Attributes, ccmd.IsAsync));
                                }
                            }
                            blk.Cmds = newcmds;
                        }
                    }
                }
            }

            return(program);
        }
Ejemplo n.º 19
0
    /// <summary>
    /// Compute the strongly connected compontents of the blocks in the implementation.
    /// As a side effect, it also computes the "predecessor" relation for the block in the implementation
    /// </summary>
    override public void ComputeStronglyConnectedComponents() {
      if (!this.BlockPredecessorsComputed)
        ComputePredecessorsForBlocks();

      Adjacency<Block/*!*/> next = new Adjacency<Block/*!*/>(Successors);
      Adjacency<Block/*!*/> prev = new Adjacency<Block/*!*/>(Predecessors);

      this.scc = new StronglyConnectedComponents<Block/*!*/>(this.Blocks, next, prev);
      scc.Compute();


      foreach (Block/*!*/ block in this.Blocks) {
        Contract.Assert(block != null);
        block.Predecessors = new List<Block>();
      }

    }
Ejemplo n.º 20
0
        public IntraGraph(Implementation impl, IWeight iw, Func <string, IWeight> ProcSummary)
        {
            this.impl         = impl;
            this.Id           = impl.Name;
            this.ProcSummary  = ProcSummary;
            priority          = 0;
            idToNode          = new Dictionary <string, Node>();
            Nodes             = new List <Node>();
            Edges             = new List <Edge>();
            calleeToEdgeSrc   = new Dictionary <string, HashSet <Node> >();
            this.iw           = iw;
            this.summary      = iw.Zero(impl);
            this.precondition = iw.Zero(impl);

            returnNodes         = new List <Node>();
            summaryChanged      = false;
            preconditionChanged = false;
            computedBefore      = false;

            // Create nodes
            foreach (var block in impl.Blocks)
            {
                var n1 = new Node(block.Label + "::in", iw.Zero(impl));
                var n2 = new Node(block.Label + "::out", iw.Zero(impl));
                Nodes.Add(n1);
                Nodes.Add(n2);

                var edge = new Edge(n1, n2, block.Cmds.OfType <Cmd>());
                n1.AddEdge(edge);
                n2.AddEdge(edge);
                Edges.Add(edge);

                // return nodes
                if (block.TransferCmd is ReturnCmd)
                {
                    returnNodes.Add(n2);
                }

                // calls
                foreach (var callee in edge.Callees)
                {
                    if (!calleeToEdgeSrc.ContainsKey(callee))
                    {
                        calleeToEdgeSrc.Add(callee, new HashSet <Node>());
                    }
                    calleeToEdgeSrc[callee].Add(n1);
                }
            }

            Nodes.Iter(n => idToNode.Add(n.Id, n));
            entryNode = idToNode[impl.Blocks[0].Label + "::in"];

            // connecting edges
            foreach (var block in impl.Blocks)
            {
                var gc = block.TransferCmd as GotoCmd;
                if (gc == null)
                {
                    continue;
                }

                var src = idToNode[block.Label + "::out"];

                var edges = gc.labelNames
                            .OfType <string>()
                            .Select(s => idToNode[s + "::in"])
                            .Select(tgt => new Edge(src, tgt, new Cmd[] { }));

                edges.Iter(e => { Edges.Add(e); e.src.AddEdge(e); e.tgt.AddEdge(e); });
            }

            // Compute priorities
            var sccs = new StronglyConnectedComponents <Node>(Nodes,
                                                              new Adjacency <Node>(n => n.Successors.Select(e => e.tgt)),
                                                              new Adjacency <Node>(n => n.Predecessors.Select(e => e.src)));

            sccs.Compute();

            int p = 0;

            foreach (var scc in sccs)
            {
                scc.Iter(n => n.priority = p);
                p++;
            }
        }
Ejemplo n.º 21
0
        // Callgraph-ordered
        public override IEnumerable <Method> OrderedMethods()
        {
            var components = StronglyConnectedComponents.Compute(this.callGraph);

            // components are in caller to callee order, so reverse it
            components.Reverse();

            var classGraph    = new SingleEdgeGraph <Type, Unit>(null);
            var mAlreadyThere = new Set <Type>();
            Predicate <Node> nodeStartVisitor = n =>
            {
                if (n.Kind != Node.Tag.method)
                {
                    return(true);
                }
                var m  = n.Method;
                var dt = this.md.DeclaringType(m);
                if (mAlreadyThere.Add(dt))
                {
                    classGraph.AddNode(dt);
                }
                // add edge dt -> type(each successor)
                foreach (var suc in this.callGraph.Successors(n))
                {
                    if (suc.Two.Kind != Node.Tag.method)
                    {
                        continue;
                    }
                    var succmethod = suc.Two.Method;
                    var tsuc       = this.md.DeclaringType(succmethod);
                    if (mAlreadyThere.Add(tsuc))
                    {
                        classGraph.AddNode(tsuc);
                    }
                    classGraph.AddEdge(dt, Unit.Value, tsuc);
                }
                return(true);
            };
            var dfs_construct_class_graph = new DepthFirst.Visitor <Node, Unit>(this.callGraph, nodeStartVisitor);

            dfs_construct_class_graph.VisitAll();

            // Now get the ordering of the class graph
            var class_components = StronglyConnectedComponents.Compute(classGraph);

            class_components.Reverse();

            // Stores the class order
            var class_order = new Dictionary <Type, int>();
            int index       = 0;

            foreach (var compo in class_components)
            {
                foreach (var cl in compo)
                {
                    class_order.Add(cl, index++);
                }
            }

            var indexes = new Dictionary <Method, int>();

            Comparison <Method> compareMethods = (m1, m2) =>
            {
                var t1 = class_order[this.md.DeclaringType(m1)];
                var t2 = class_order[this.md.DeclaringType(m2)];
                if (t1 != t2)
                {
                    return(t2 - t1);
                }
                // regarding to class order, m1 == m2, i.e. keep global methods order
                return(indexes[m2] - indexes[m1]);
            };

            // Stores the global method order to decide inside class graph strong components
            // And populate the method list
            var ordered_methods = new PriorityQueue <Method>(compareMethods);

            index = 0;
            foreach (var component in components)
            {
                foreach (var node in component)
                {
                    if (node.Kind == Node.Tag.method)
                    {
                        indexes[node.Method] = index++;
                        ordered_methods.Add(node.Method);
                    }
                }
            }

            while (ordered_methods.Count > 0)
            {
                yield return(ordered_methods.Pull());
            }
        }
        public bool MayReach(Block src, Block dst)
        {
            if (ReachabilityGraphSCCsDAG == null) {
            if (CommandLineOptions.Clo.Trace) {
              Console.WriteLine("Interprocedural reachability: computing SCCs");
            }
            Adjacency<Block> next = new Adjacency<Block>(reachabilityGraph.Successors);
            Adjacency<Block> prev = new Adjacency<Block>(reachabilityGraph.Predecessors);
            StronglyConnectedComponents<Block> ReachabilitySCCs = new StronglyConnectedComponents<Block>(
              reachabilityGraph.Nodes, next, prev);
            ReachabilitySCCs.Compute();

            BlockToSCC = new Dictionary<Block, SCC<Block>>();
            foreach (var scc in ReachabilitySCCs) {
              foreach (var s in scc) {
            BlockToSCC[s] = scc;
              }
            }

            ReachabilityGraphSCCsDAG = new Graph<SCC<Block>>();
            foreach (var edge in reachabilityGraph.Edges) {
              if (BlockToSCC[edge.Item1] != BlockToSCC[edge.Item2]) {
            ReachabilityGraphSCCsDAG.AddEdge(BlockToSCC[edge.Item1], BlockToSCC[edge.Item2]);
              }
            }

            SCC<Block> dummy = new SCC<Block>();
            foreach (var n in reachabilityGraph.Nodes) {
              ReachabilityGraphSCCsDAG.AddEdge(BlockToSCC[n], dummy);
            }

            if (CommandLineOptions.Clo.Trace) {
              Console.WriteLine("Interprocedural reachability: SCCs computed!");
            }
              }
              return ReachableFrom(BlockToSCC[src]).Contains(dst);
        }