Пример #1
0
        private void BuildTransferFunctions()
        {
            foreach (CFGNode node in ProgramCFG.CfgNodes)
            {
                if (node is CFGNodeStatement)
                {
                    if ((node is CFGNodeStmtSkip) || (node is CFGNodeStmtPrint) ||
                        (node is CFGNodeStmtGoto) || (node is CFGNodeStmtReturn))
                    {
                        (node as CFGNodeStatement).Transfer = HelperFunctions.BuildIdentityTransfer(m_BddManager,
                                                                                                    (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId,
                                                                                                    ProgramCFG.GlobalVariables.VariablesToId);
                    }
                    else

                    if (node is CFGNodeStmtAssignment)
                    {
                        (node as CFGNodeStmtAssignment).Transfer =
                            CFGNodeStmtAssignment.BuildAssignmentTransfer(node.GetAST(), m_BddManager,
                                                                          (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId,
                                                                          ProgramCFG.GlobalVariables.VariablesToId);
                    }
                    else

                    if (node is CFGNodeStmtConditional)
                    {
                        Bdd       TransferTrue, TransferFalse;
                        CommonAST decider = node.GetAST().getFirstChild() as CommonAST;

                        HelperFunctions.BuildDeciderTransfers(decider, m_BddManager,
                                                              (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId,
                                                              ProgramCFG.GlobalVariables.VariablesToId, out TransferTrue, out TransferFalse);

                        (node as CFGNodeStmtConditional).TransferTrue  = TransferTrue;
                        (node as CFGNodeStmtConditional).TransferFalse = TransferFalse;
                    }
                    else

                    if (node is CFGNodeStmtProcCall)
                    {
                        CFGNodeProcedure procedureCalled;
                        if (!(ProgramCFG.ProcedureNameToNode().TryGetValue(
                                  node.GetAST().getFirstChild().getText(), out procedureCalled)))
                        {
                            System.Diagnostics.Debug.Assert(false);
                        }

                        (node as CFGNodeStmtProcCall).Transfer =
                            CFGNodeStmtProcCall.buildProcCallTransfer(node.GetAST(), procedureCalled, m_BddManager,
                                                                      (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId,
                                                                      ProgramCFG.GlobalVariables.VariablesToId);
                    }
                }
            }
        }
Пример #2
0
        public Trajectory BuildTrajectory(CFGNode node)
        {
            int len, i;

            Trajectory tempTrajectory = new Trajectory();

            PathEdges          paths, predecessorPaths;
            PathEdgesPartition pathPart;

            Bdd pathBdd = null;

            m_PathEdges.TryGetValue(node, out paths);

            if (paths.PathEdgesByLength.Count != 0)
            {
                pathPart = paths.PathEdgesByLength[0];
                len      = pathPart.Length;

                pathBdd = BuildRandomPath(pathPart.PathEdges);

                while (len > 0)
                {
                    tempTrajectory.Add(new TrajectoryItem(node, pathBdd));

                    #region Node is not first statement of procedure
                    if ((node is CFGNodeProcedure) || ((node is CFGNodeStatement) && (node as CFGNodeStatement).ProcOf.FirstStmtOf != node))
                    {
                        Bdd tempPathEdges, reverseJoin, bddOK;

                        if (((node is CFGNodeStmtSkip) && (node as CFGNodeStmtSkip).previousProcCall != null))
                        {
                            CFGNodeStmtProcCall nodePredecessor = (node as CFGNodeStmtSkip).previousProcCall;
                            Bdd[] bddArray = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 4 + ProgramCFG.GlobalVariables.Length * 4];
                            Bdd   summaryEdges, summaryEdgesReverse;

                            m_PathEdges.TryGetValue(nodePredecessor as CFGNode, out predecessorPaths);
                            m_SummaryEdges.TryGetValue(nodePredecessor as CFGNode, out summaryEdges);
                            tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1);

                            if (tempPathEdges != null)
                            {
                                i = -1;
                                foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values)
                                {
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                }
                                foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
                                {
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                    bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                }

                                summaryEdgesReverse = summaryEdges.Replace(bddArray);
                                reverseJoin         = Join(pathBdd, summaryEdgesReverse, nodePredecessor.ProcOf.LocalVariables);
                                summaryEdgesReverse.FreeBdd();

                                bddOK = m_BddManager.LogicalAnd(reverseJoin, tempPathEdges);
                                reverseJoin.FreeBdd();

                                pathBdd = BuildRandomPath(bddOK);
                                bddOK.FreeBdd();

                                node = nodePredecessor as CFGNode;
                                len--;
                            }
                        }
                        else
                        {
                            foreach (CFGNode tempNode in node.Predecessor)
                            {
                                CFGNodeStatement nodePredecessor = tempNode as CFGNodeStatement;
                                Bdd[]            bddArray        = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 4 + ProgramCFG.GlobalVariables.Length * 4];
                                Bdd transferReverse;

                                m_PathEdges.TryGetValue(tempNode, out predecessorPaths);
                                tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1);

                                if (tempPathEdges != null)
                                {
                                    i = -1;
                                    foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values)
                                    {
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                    }
                                    foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
                                    {
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                        bddArray[++i] = m_BddManager.GetBddVariableWithID(id);
                                    }

                                    if (nodePredecessor is CFGNodeStmtConditional)
                                    {
                                        if ((nodePredecessor as CFGNodeStmtConditional).TrueSuccesor == node)
                                        {
                                            transferReverse = (nodePredecessor as CFGNodeStmtConditional).TransferTrue.Replace(bddArray);
                                            reverseJoin     = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables);
                                            transferReverse.FreeBdd();
                                        }
                                        else
                                        {
                                            transferReverse = (nodePredecessor as CFGNodeStmtConditional).TransferFalse.Replace(bddArray);
                                            reverseJoin     = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables);
                                            transferReverse.FreeBdd();
                                        }
                                    }
                                    else
                                    {
                                        transferReverse = nodePredecessor.Transfer.Replace(bddArray);
                                        reverseJoin     = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables);
                                        transferReverse.FreeBdd();
                                    }

                                    bddOK = m_BddManager.LogicalAnd(reverseJoin, tempPathEdges);

                                    if (bddOK.ReturnBddType() != BddType.Zero)
                                    {
                                        pathBdd = BuildRandomPath(bddOK);
                                        bddOK.FreeBdd();
                                        node = tempNode;
                                        len--;
                                        break;
                                    }
                                    else
                                    {
                                        bddOK.FreeBdd();
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                    #region Node is first statement of procedure
                    else
                    {
                        Bdd[] bddArray = new Bdd[(node as CFGNodeStatement).ProcOf.LocalVariables.Length + ProgramCFG.GlobalVariables.Length];
                        Bdd[] bddArrayForTransfer = new Bdd[(node as CFGNodeStatement).ProcOf.LocalVariables.Length + ProgramCFG.GlobalVariables.Length];
                        Bdd   bddExist, tempPathEdges, bddAndWithTransfer, bddAndWithProcCall, bddExistTransfer, bddReplaceTransfer;

                        i = -1;

                        foreach (int id in (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId.Values)
                        {
                            bddArray[++i]          = m_BddManager.GetBddVariableWithID(id);
                            bddArrayForTransfer[i] = m_BddManager.GetBddVariableWithID(id + 2);
                        }
                        foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
                        {
                            bddArray[++i]          = m_BddManager.GetBddVariableWithID(id);
                            bddArrayForTransfer[i] = m_BddManager.GetBddVariableWithID(id + 2);
                        }

                        bddExist = pathBdd.Exists(bddArray);


                        foreach (CFGNodeStmtProcCall nodePredecessor in node.Predecessor)
                        {
                            m_PathEdges.TryGetValue(nodePredecessor, out predecessorPaths);
                            tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1);
                            Bdd[] bddArrayReplace = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 2 + ProgramCFG.GlobalVariables.Length * 2];

                            if (tempPathEdges != null)
                            {
                                bddAndWithTransfer = m_BddManager.LogicalAnd(nodePredecessor.Transfer, bddExist);
                                bddExistTransfer   = bddAndWithTransfer.Exists(bddArrayForTransfer);
                                bddAndWithTransfer.FreeBdd();

                                i = -1;
                                foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values)
                                {
                                    bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id);
                                    bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                }
                                foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values)
                                {
                                    bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id);
                                    bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id + 2);
                                }

                                bddReplaceTransfer = bddExistTransfer.Replace(bddArrayReplace);
                                bddExistTransfer.FreeBdd();

                                bddAndWithProcCall = m_BddManager.LogicalAnd(bddReplaceTransfer, tempPathEdges);
                                bddReplaceTransfer.FreeBdd();

                                if (bddAndWithProcCall.GetBddRootVariable().ReturnBddType() != BddType.Zero)
                                {
                                    pathBdd = BuildRandomPath(bddAndWithProcCall);
                                    bddAndWithProcCall.FreeBdd();
                                    node = nodePredecessor as CFGNode;
                                    len--;
                                    break;
                                }
                                else
                                {
                                    bddAndWithProcCall.FreeBdd();
                                }
                            }
                        }
                    }
                    #endregion
                }
            }
            tempTrajectory.Add(new TrajectoryItem(node, pathBdd));
            tempTrajectory.TrajectoryList.Reverse();
            return(tempTrajectory);
        }
Пример #3
0
        private Bdd Lift(CFGNodeStmtProcCall procCallNode, CFGNodeProcedure exitNode)
        {
            int i = 0;
            int id;

            Bdd[] bddArrayFormalsNot = new Bdd[2 * exitNode.LocalVariables.Length - exitNode.FormalParameters.Length];
            //Bdd[] bddArrayFormals = new Bdd[2 * exitNode.FormalParameters.Length];
            Bdd[]     bddArrayForSubstitution = new Bdd[2 * exitNode.FormalParameters.Length];
            Bdd       tempBdd, tempBddAnd, tempBddXnor, tempBddReplace;
            Bdd       var, exp, identity;
            CommonAST walkerVar = exitNode.GetAST().getFirstChild() as CommonAST;
            CommonAST walkerExp = procCallNode.GetAST().getFirstChild().getFirstChild() as CommonAST;

            foreach (string varName in exitNode.LocalVariables.VariablesToId.Keys)
            {
                exitNode.LocalVariables.VariablesToId.TryGetValue(varName, out id);
                if (exitNode.FormalParameters.VariablesToId.ContainsKey(varName) == false)
                {
                    bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id);
                    bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id + 2);
                }
                else
                {
                    bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id + 2);
                }
            }

            PathEdges tempPath;

            m_PathEdges.TryGetValue(exitNode, out tempPath);
            tempBdd = tempPath.GetJointPaths(m_BddManager);

            tempBdd = tempBdd.Exists(bddArrayFormalsNot);

            i = 0;

            while (walkerVar.Type == BoolParserTokenTypes.ID)
            {
                exitNode.LocalVariables.VariablesToId.TryGetValue(walkerVar.getText(), out id);
                exp = HelperFunctions.ExprToBdd(walkerExp, m_BddManager, procCallNode.ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId);
                var = m_BddManager.GetBddVariableWithID(id);

                bddArrayForSubstitution[i++] = var;
                bddArrayForSubstitution[i++] = exp;

                /*
                 * tempBddXnor = m_BddManager.LogicalXnor(exp, var);
                 * tempBddAnd = m_BddManager.LogicalAnd(tempBddXnor, tempBdd);
                 *
                 * tempBdd.FreeBdd();
                 * exp.FreeBdd();
                 * tempBdd = tempBddAnd;
                 */
                walkerExp = walkerExp.getNextSibling() as CommonAST;
                walkerVar = walkerVar.getNextSibling() as CommonAST;
            }

            i = 0;

            /*
             * foreach (int bddId in exitNode.FormalParameters.VariablesToId.Values)
             * {
             *  bddArrayFormals[i++] = m_BddManager.GetBddVariableWithID(bddId);
             *  bddArrayFormals[i++] = m_BddManager.GetBddVariableWithID(bddId + 2);
             * }*/

            tempBddReplace = tempBdd.Replace(bddArrayForSubstitution);

            tempBdd.FreeBdd();
            tempBdd = tempBddReplace;

            identity = HelperFunctions.BuildIdentityTransfer(m_BddManager, procCallNode.ProcOf.LocalVariables.VariablesToId, null);

            tempBddAnd = m_BddManager.LogicalAnd(tempBdd, identity);

            tempBdd.FreeBdd();
            identity.FreeBdd();

            tempBdd = tempBddAnd;

            return(tempBdd);
        }
Пример #4
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();
        }