Пример #1
0
        private void btnRunReachabilityAlg_Click(object sender, EventArgs e)
        {
            ValidateProgram();

            gleeViewCFG.Graph = MyBMC.GetCFGasGLEEGraph();

            reachDebugBox.Clear();

            debugPrintDelegate matrix = delegate(string message)
            {
                reachDebugBox.AppendText(message);
                reachDebugBox.Refresh();
            };

            MyBMC.Reachable(matrix);

            labelsComboBox.Items.Clear();
            labelsComboBox.Items.AddRange(MyBMC.GetStatementLabels());
            if (labelsComboBox.Items.Count > 0)
            {
                labelsComboBox.SelectedIndex = 0;
            }
            else
            {
                labelsComboBox.Text = "Code contains no Labels!";
            }
        }
Пример #2
0
        public void Reachable(debugPrintDelegate debugPrint)
        {
            if (ProgramCFG.CfgNodes.Count <= 1)
            {
                debugPrint("Invalid Program, unable to proceed!\n");
                return;
            }

            m_PathEdges.Clear();
            m_SummaryEdges.Clear();

            BuildTransferFunctions();

            LinkedList <CFGNode> workList = new LinkedList <CFGNode>();

            CFGNodeProcedure tempNodeProc;
            CFGNode          tempNode;

            Bdd       bddLift, bddSummaryEdges, bddNew;
            PathEdges bddSelfLoop, bddJoin, bddPathEdges;

            Bdd [] array = new Bdd[3];

            foreach (CFGNode node in ProgramCFG.CfgNodes)
            {
                m_PathEdges.Add(node, new PathEdges());
                m_SummaryEdges.Add(node, m_BddManager.CreateBddZero());
            }


            ProgramCFG.ProcedureNameToNode().TryGetValue("main", out tempNodeProc);
            workList.AddFirst(tempNodeProc.FirstStmtOf);
            m_PathEdges.Remove(tempNodeProc.FirstStmtOf);
            PathEdges firstMain = new PathEdges();

            firstMain.AddPathEdge(new PathEdgesPartition(0, HelperFunctions.BuildIdentityTransfer
                                                             (m_BddManager, tempNodeProc.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId)), m_BddManager);
            m_PathEdges.Add(tempNodeProc.FirstStmtOf, firstMain);

            #region Debug part of the reachability algorithm

            /*
             * ///////Debug ////////////
             * Dictionary<string, int>.ValueCollection valCollection = tempNodeProc.LocalVariables.VariablesToId.Values;
             * foreach (int id in valCollection)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalXnor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             *
             * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             * array[0] = tempBdd;
             * tempBdd = m_BddManager.CreateBddOne();
             *
             * foreach (int id in valCollection)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalAnd(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalNor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             *
             * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
             * {
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id));
             *  tempBdd1.FreeBdd();
             *  tempBdd1 = tempBdd;
             *  tempBdd = m_BddManager.LogicalXor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2));
             *  tempBdd1.FreeBdd();
             * }
             * array[1] = tempBdd;
             *
             * //array[2] = Join(array[0], array[1], tempNodeProc.LocalVariables);
             * array[2] = SelfLoop(array[1], tempNodeProc.LocalVariables, tempNodeProc.LocalVariables);
             * m_BddManager.ForceGarbageCollection();
             * return array;
             * ////////////////////////
             */
            #endregion
            while (workList.Count != 0)
            {
                tempNode = workList.First.Value;

                debugPrint("Processing Node: " + tempNode.ToString() + ".\n");

                workList.RemoveFirst();

                if (tempNode is CFGNodeStmtProcCall)
                {
                    CFGNodeStmtProcCall procCall = tempNode as CFGNodeStmtProcCall;
                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);

                    bddJoin     = Join(bddPathEdges, procCall.Transfer, procCall.ProcOf.LocalVariables);
                    bddSelfLoop = SelfLoop(bddJoin, procCall.ProcOf.LocalVariables, (procCall.Succesor as CFGNodeStatement).ProcOf.LocalVariables);
                    Propagate(procCall.Succesor, bddSelfLoop, workList);

                    bddJoin.FreeAllBdd();
                    bddSelfLoop.FreeAllBdd();

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    m_SummaryEdges.TryGetValue(tempNode, out bddSummaryEdges);
                    if (bddSummaryEdges != null)
                    {
                        bddJoin = Join(bddPathEdges, bddSummaryEdges, procCall.ProcOf.LocalVariables);
                        Propagate(procCall.ReturnPoint, bddJoin, workList);
                        bddJoin.FreeAllBdd();
                    }
                }
                else if (tempNode is CFGNodeProcedure)
                {
                    foreach (CFGNodeStmtSkip node in (tempNode as CFGNodeProcedure).Succesor)
                    {
                        bddLift = Lift(node.previousProcCall, tempNode as CFGNodeProcedure);

                        m_SummaryEdges.TryGetValue(node.previousProcCall, out bddSummaryEdges);
                        m_PathEdges.TryGetValue(node.previousProcCall, out bddPathEdges);

                        if (bddSummaryEdges != null)
                        {
                            bddNew = m_BddManager.LogicalOr(bddLift, bddSummaryEdges);
                            bddLift.FreeBdd();
                        }
                        else
                        {
                            bddNew = bddLift;
                        }

                        if (bddSummaryEdges != bddNew)
                        {
                            m_SummaryEdges.Remove(node.previousProcCall);
                            m_SummaryEdges.Add(node.previousProcCall, bddNew);
                            bddSummaryEdges.FreeBdd();

                            bddJoin = Join(bddPathEdges, bddNew, (node as CFGNodeStmtSkip).previousProcCall.ProcOf.LocalVariables);

                            Propagate(node, bddJoin, workList);
                            bddJoin.FreeAllBdd();
                        }
                    }
                }
                else if (tempNode is CFGNodeStmtConditional)
                {
                    CFGNodeStmtConditional tempNode1 = tempNode as CFGNodeStmtConditional;

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    bddJoin = Join(bddPathEdges, tempNode1.TransferTrue, tempNode1.ProcOf.LocalVariables);
                    Propagate(tempNode1.TrueSuccesor, bddJoin, workList);
                    bddJoin.FreeAllBdd();

                    m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                    bddJoin = Join(bddPathEdges, tempNode1.TransferFalse, tempNode1.ProcOf.LocalVariables);
                    Propagate(tempNode1.FalseSuccesor, bddJoin, workList);
                    bddJoin.FreeAllBdd();
                }
                else
                {
                    if (!(tempNode is CFGNodeError))
                    {
                        m_PathEdges.TryGetValue(tempNode, out bddPathEdges);
                        bddJoin = Join(bddPathEdges, (tempNode as CFGNodeStatement).Transfer, (tempNode as CFGNodeStatement).ProcOf.LocalVariables);
                        Propagate(tempNode.Succesor, bddJoin, workList);
                        bddJoin.FreeAllBdd();
                    }
                }
            }

            m_BddManager.ForceGarbageCollection();
        }