/// <summary>
        /// The local function of each process running Improved MultiCore Tarjan algorithm
        /// </summary>
        /// <returns></returns>
        public void localImprovedTarjanGeldenhuysValmari()
        {
            //local data for on-the-fly and Tarjan algorithm
            Dictionary <string, List <string> >    outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            StringDictionary <int[]>               dfsData       = new StringDictionary <int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(1024);
            Stack <LocalPair> callStack    = new Stack <LocalPair>(5000);
            Stack <LocalPair> currentStack = new Stack <LocalPair>(1024);
            int    counter = 0;
            string goal    = null;

            int[] goalData = new int[2] {
                -2, 0
            };
            //--------------------------

            //create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            //create random variable for each process
            Random rand = null;

            lock (MultiCoreLock)
            {
                rand = new Random(MultiCoreSeed);
                MultiCoreSeed++;
            }

            //put all initial states to callStack in different order & init data
            int[] initPermutation = generatePermutation(initialStates.Count, rand);
            for (int i = 0; i < initPermutation.Length; i++)
            {
                //get data from initialStates
                LocalPair tmp = initialStates[initPermutation[i]];
                callStack.Push(tmp);
                string tmpID = tmp.GetCompressedState();
                dfsData.Add(tmpID, new int[] { VISITED_NOPREORDER, 0 });
                outgoingTransitionTable.Add(tmpID, new List <string>(8));
            }

            //start loop
            while (callStack.Count > 0)
            {
                //cancel if too long action
                if (CancelRequested || StopMutliCoreThreads)
                {
                    return;
                }

                //get the top of callStack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                int[]         vData    = dfsData.GetContainsKey(v);

                //if not expended then expend to next states from v
                if (!expendedNodes.ContainsKey(v))
                {
                    //create next states of v
                    ConfigurationBase[] nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    //update outgoing of v and set initial data for successors
                    //no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!dfsData.ContainsKey(w))
                        {
                            dfsData.Add(w, new int[] { VISITED_NOPREORDER, 0 });
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                //get successors of v
                List <LocalPair> successors = expendedNodes[v];

                //process if v is not numbered yet
                if (vData[0] == VISITED_NOPREORDER)
                {
                    vData[0] = counter;
                    vData[1] = counter;
                    counter  = counter + 1;

                    //push to currentStack
                    currentStack.Push(pair);

                    //check whether v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        goal     = v;
                        goalData = vData;
                    }

                    //update lowlink according to successors in currentStack
                    //remove already visited successors
                    //no need random because consider all successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ  = successors[i];
                        string    w     = succ.GetCompressedState();
                        int[]     wData = dfsData.GetContainsKey(w);
                        if (wData[0] >= 0 && !foundSCCTarjanGeldenhuysValmari.ContainsKey(w))
                        {
                            //update & remove from expendedNodes(v)
                            vData[1] = Math.Min(vData[1], wData[0]);
                            successors.RemoveAt(i);

                            //check for report accepting cycle
                            if (vData[1] <= goalData[0])
                            {
                                //REPORT COUNTEREXAMPLE
                                localReportAcceptingCycle(succ, callStack, dfsData, outgoingTransitionTable);
                                return;
                            }
                        }
                    }
                }

                //check if there is any successor not numbered & not visited by other threads
                //choose random
                bool      completed       = true;
                LocalPair firstUnnumbered = null;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    int       randIndex = rand.Next(successors.Count);
                    LocalPair succ      = successors[randIndex];
                    string    w         = succ.GetCompressedState();
                    int[]     wData     = dfsData.GetContainsKey(w);

                    //only check states not in foundSCCTarjanGeldenhuysValmari
                    if (wData[0] == VISITED_NOPREORDER && !foundSCCTarjanGeldenhuysValmari.ContainsKey(w))
                    {
                        completed       = false;
                        firstUnnumbered = succ;
                        successors.RemoveAt(randIndex);
                        break;
                    }
                    else
                    {
                        successors.RemoveAt(randIndex);
                    }
                }

                // if there at least one unnumbered successor
                if (!completed)
                {
                    callStack.Push(firstUnnumbered);
                }
                else //all successors are numbered
                {
                    //check for loop at an accepting & deadlock state
                    if (LTSState.IsDeadLock && pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        //report AcceptingCycle
                        localReportAcceptingCycle(pair, callStack, dfsData, outgoingTransitionTable);
                        return;
                    }

                    if (vData[0] == vData[1])
                    {
                        //find the root -> mark as local and global for all processes
                        LocalPair tmp   = null;
                        string    tmpID = null;

                        //pop currentStack and update SCC_FOUND and add to global memory until v
                        do
                        {
                            //local
                            tmp   = currentStack.Pop();
                            tmpID = tmp.GetCompressedState();
                            int[] tmpData = dfsData.GetContainsKey(tmpID);
                            tmpData[0] = SCC_FOUND;

                            //global
                            foundSCCTarjanGeldenhuysValmari.GetOrAdd(tmpID, true);
                        } while (!tmpID.Equals(v));

                        //pop callStack
                        callStack.Pop();
                    }
                    else
                    {
                        //pop callStack & update the parent
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsData.GetContainsKey(popID);
                        int[]     topData = dfsData.GetContainsKey(topID);
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Improved Nested DFS
        /// A Note on On-The-Fly Verification Algorithms - TACAS 2005
        /// Blue DFS
        /// </summary>
        public void BlueDFS()
        {
            VerificationOutput.CounterExampleTrace = null;

            //on-the-fly data
            Stack <LocalPair>                      blueStack     = new Stack <LocalPair>(5000);
            Dictionary <string, Color>             dfsColor      = new Dictionary <string, Color>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(5000);

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            //push initial states to call stack
            foreach (LocalPair tmp in initialStates)
            {
                blueStack.Push(tmp);
            }

            //start loop
            while (blueStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = dfsColor.Count;
                    return;
                }

                //get top of call stack
                LocalPair         pair     = blueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (expendedNodes.ContainsKey(v))
                {
                    successors = expendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, successors);
                }

                //if v is white
                if (!dfsColor.ContainsKey(v))
                {
                    //set v cyan
                    Color vColor = new Color();
                    vColor.setCyan();
                    dfsColor.Add(v, vColor);

                    //early cycle detection
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        //if w is cyan and (v or w is accepting)
                        if (dfsColor.ContainsKey(w))
                        {
                            Color wColor = dfsColor[w];
                            if (wColor.isCyan() && (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE)))
                            {
                                //REPORT COUNTEREXAMPLE
                                GetLoopCounterExample(w, blueStack, dfsColor);
                                return;
                            }
                        }
                    }
                }

                //check if there is an unnumbered successor
                bool isBlueCompleted = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is white
                    if (!dfsColor.ContainsKey(w))
                    {
                        blueStack.Push(succ);
                        isBlueCompleted = false;
                        break;
                    }
                }

                //if there is no unnumbered successor
                if (isBlueCompleted)
                {
                    Color vColor = dfsColor[v];

                    //if v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        //if v is deadlock
                        if (LTSState.IsDeadLock)
                        {
                            //REPORT COUNTEREXAMPLE
                            GetDeadlockCounterExample(blueStack, dfsColor);
                            return;
                        }
                        else
                        {
                            bool stop = RedDFS(pair, blueStack, dfsColor, expendedNodes);
                            if (stop)
                            {
                                return;
                            }
                        }

                        //set v pink
                        vColor.setPink();
                    }
                    else
                    {
                        vColor.setBlue();
                    }

                    //pop blue stack
                    blueStack.Pop();
                }
            }

            //no counter example
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = dfsColor.Count;
            return;
        }
Пример #3
0
        /// <summary>
        /// Local Tarjan in each thread to find SCC
        /// </summary>
        /// <param name="o"></param>
        public void LocalImprovedFairTarjan(object o)
        {
            //order of this thread
            int    order = (int)o;
            Random rand  = new Random(order);

            //on-the-fly data
            Stack <LocalPair>          localCallStack    = new Stack <LocalPair>(5000);
            Stack <LocalPair>          localCurrentStack = new Stack <LocalPair>(1024);
            Stack <LocalPair>          localGoalStack    = new Stack <LocalPair>(256);
            Dictionary <string, int[]> localDFSNumber    = new Dictionary <string, int[]>(5000);
            int localNumber = 0;
            Dictionary <string, List <LocalPair> > localExpendedNodes = new Dictionary <string, List <LocalPair> >(5000);

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            //push local initial states to local call stack
            int[] localPerm = Permutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[localPerm[i]];
                localCallStack.Push(tmp);
            }

            //start loop
            while (localCallStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested || isGlobalStop)
                {
                    return;
                }

                //get top of call stack
                LocalPair         pair     = localCallStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (localExpendedNodes.ContainsKey(v))
                {
                    successors = localExpendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    localExpendedNodes.Add(v, successors);
                }

                //if v is not number yet
                if (!localDFSNumber.ContainsKey(v))
                {
                    //number v
                    int[] vData = new int[] { localNumber, localNumber };
                    localDFSNumber.Add(v, vData);
                    localNumber = localNumber + 1;

                    //push to currentStack
                    localCurrentStack.Push(pair);

                    //check whether v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        localGoalStack.Push(pair);
                    }

                    //update lowlink for already numbered successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        if (localDFSNumber.ContainsKey(w))
                        {
                            int[] wData = localDFSNumber[w];
                            //if w is in current stack
                            if (wData[0] >= 0)
                            {
                                vData[1] = Math.Min(vData[1], wData[0]);

                                //check for report accepting cycle
                                if (localGoalStack.Count > 0 && vData[1] <= localDFSNumber[localGoalStack.Peek().GetCompressedState()][0])
                                {
                                    //------------------------------------
                                    //get SCC
                                    Dictionary <string, LocalPair>      newSCC = new Dictionary <string, LocalPair>();
                                    Dictionary <string, List <string> > newOutgoingTransitionTable = new Dictionary <string, List <string> >();
                                    LocalPair[] callArray = localCallStack.ToArray();
                                    for (int j = 0; j < callArray.Length; j++)
                                    {
                                        LocalPair state   = callArray[i];
                                        string    stateID = state.GetCompressedState();
                                        newSCC.Add(stateID, state);

                                        List <string>    outgoing   = new List <string>(8);
                                        List <LocalPair> nextStates = localExpendedNodes[stateID];
                                        foreach (LocalPair next in nextStates)
                                        {
                                            string nextID = next.GetCompressedState();
                                            outgoing.Add(nextID);
                                        }
                                        newOutgoingTransitionTable.Add(stateID, outgoing);

                                        if (stateID.Equals(w))
                                        {
                                            break;
                                        }
                                    }

                                    Dictionary <string, LocalPair> fairSCC = IsFair(newSCC, newOutgoingTransitionTable);

                                    if (fairSCC != null)
                                    {
                                        //REPORT COUNTEREXAMPLE
                                        GetLocalLoopCounterExample(w, localCallStack);
                                        return;
                                    }

                                    return;
                                }
                            }
                        }
                    }
                }

                //------------------------------------------------------------------------
                //filter successors
                List <int> unvisitedIndexs = new List <int>(successors.Count);//not numbered and not global found
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is not cyan and not global red
                    if (!localDFSNumber.ContainsKey(w) && !globalFoundSCCs.ContainsKey(w))
                    {
                        unvisitedIndexs.Add(i);
                    }
                }
                //------------------------------------------------------------------------

                //get random unvisited successors
                if (unvisitedIndexs.Count > 0)
                {
                    bool       isFresh       = false;
                    List <int> unFreshIndexs = new List <int>();
                    while (unvisitedIndexs.Count > 0)
                    {
                        int       r    = rand.Next(unvisitedIndexs.Count);
                        LocalPair succ = successors[unvisitedIndexs[r]];
                        string    w    = succ.GetCompressedState();

                        //if w is fresh successor
                        if (!allVisitedStates.ContainsKey(w))
                        {
                            localCallStack.Push(succ);

                            allVisitedStates.GetOrAdd(w, 0);
                            allVisitedStates[w]++;

                            isFresh = true;
                            break;
                        }
                        else
                        {
                            unFreshIndexs.Add(unvisitedIndexs[r]);
                            unvisitedIndexs.RemoveAt(r);
                        }
                    }
                    if (!isFresh)
                    {
                        int       r    = rand.Next(unFreshIndexs.Count);
                        LocalPair succ = successors[unFreshIndexs[r]];
                        string    w    = succ.GetCompressedState();
                        localCallStack.Push(succ);

                        allVisitedStates.GetOrAdd(w, 0);
                        allVisitedStates[w]++;
                    }
                }
                else
                {
                    //update global
                    globalFoundSCCs.GetOrAdd(v, true);

                    int[] vData = localDFSNumber[v];
                    //if v is root
                    if (vData[0] == vData[1])
                    {
                        // check selfLoop
                        bool selfLoop = false;
                        foreach (LocalPair succ in successors)
                        {
                            string w = succ.GetCompressedState();
                            if (v.Equals(w))
                            {
                                selfLoop = true;
                                break;
                            }
                        }

                        //remove states from current stack and goal stack
                        //updata global
                        bool isBuchiFair = false;
                        Dictionary <string, LocalPair> newSCC = new Dictionary <string, LocalPair>(1024);
                        List <ConfigurationBase>       cycle  = new List <ConfigurationBase>(1024);
                        LocalPair tmp   = null;
                        string    tmpID = null;
                        do
                        {
                            //get states in SCC
                            tmp = localCurrentStack.Pop();
                            if (!isBuchiFair && tmp.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                isBuchiFair = true;
                            }
                            tmpID = tmp.GetCompressedState();
                            newSCC.Add(tmpID, tmp);
                            cycle.Insert(0, tmp.configuration);

                            //local
                            localDFSNumber[tmpID][0] = SCC_FOUND;
                        } while (tmp != pair);

                        //local check fairness
                        if (isBuchiFair && (selfLoop || newSCC.Count > 1 || LTSState.IsDeadLock))
                        {
                            //------------------------------------
                            //get outgoing transition table
                            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(newSCC.Count);
                            foreach (KeyValuePair <string, LocalPair> kv in newSCC)
                            {
                                string           s          = kv.Key;
                                List <LocalPair> nextStates = localExpendedNodes[s];
                                List <string>    outgoing   = new List <string>(nextStates.Count);
                                foreach (LocalPair next in nextStates)
                                {
                                    string n = next.GetCompressedState();
                                    outgoing.Add(n);
                                }
                                outgoingTransitionTable.Add(s, outgoing);
                            }
                            //------------------------------------

                            Dictionary <string, LocalPair> fairSCC = IsFair(newSCC, outgoingTransitionTable);

                            if (fairSCC != null)
                            {
                                //REPORT COUNTEREXAMPLE
                                GetLocalFairCounterExample(localCallStack, cycle, LTSState.IsDeadLock);
                                return;
                            }
                        }

                        //pop call stack
                        localCallStack.Pop();
                    }
                    else
                    {
                        //pop call stack and update lowlink of top
                        LocalPair pop     = localCallStack.Pop();
                        LocalPair top     = localCallStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = localDFSNumber[popID];
                        int[]     topData = localDFSNumber[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
        }
Пример #4
0
        // Blue DFS
        public void localBlueDFSNestedDFSSharedRed(object o)
        {
            // get order
            int order = (int)o;

            // local data for on-the-fly Nested DFS
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>                      blueStack            = new Stack <LocalPair>(5000);
            Dictionary <string, Color>             colorData            = new Dictionary <string, Color>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes        = new Dictionary <string, List <LocalPair> >(1024);

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            // create random variable for each thread
            Random rand = new Random(order);

            // push initial states to blueStack in random order & initialize data
            int[] permutation = generatePermutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[permutation[i]];
                blueStack.Push(tmp);
                string ID = tmp.GetCompressedState();
                colorData.Add(ID, new Color());
                outgoingTransitionTable.Add(ID, new List <string>(8));
            }

            // start loop
            while (blueStack.Count > 0)
            {
                // cancel if too long action or couterexample reported
                if (CancelRequested || isStop)
                {
                    return;
                }

                // get the top of blueStack
                LocalPair         pair     = blueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                Color         vColor   = colorData[v];

                // if v is not expended then expend successors of v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states from v & add to expendedNodes
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // add to visitedTimes in this thread
                    //visitedTimes.GetOrAdd(v, 0);
                    //visitedTimes[v]++;

                    // update outgoing of v and set initial data for successors
                    // no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!colorData.ContainsKey(w))
                        {
                            colorData.Add(w, new Color());
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successor of v
                List <LocalPair> successors = expendedNodes[v];

                // visit v & early accepting cycle detection
                if (vColor.isWhite())
                {
                    vColor.setCyan();

                    // early cycle detection
                    // use reverse order to remove visited states
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ   = successors[i];
                        string    w      = succ.GetCompressedState();
                        Color     wColor = colorData[w];

                        // if successor is not white then remove from expendedNodes
                        if (wColor.isCyan())
                        {
                            if (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                localBlueReportAcceptinCycle(succ, blueStack, outgoingTransitionTable);
                                return;
                            }
                            else
                            {
                                successors.RemoveAt(i);
                            }
                        }
                    }
                }

                // traverse all sucessors in a random order
                bool blueDone = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    int       randIndex = rand.Next(successors.Count);
                    LocalPair succ      = successors[randIndex];
                    string    w         = succ.GetCompressedState();

                    // only visite white & not red globally successors
                    if (colorData[w].isWhite() && !sharedRedStates.ContainsKey(w))
                    {
                        blueStack.Push(succ);
                        successors.RemoveAt(randIndex);
                        blueDone = false;
                        break;
                    }
                    else // remove already visited states in expendedNodes
                    {
                        successors.RemoveAt(randIndex);
                    }
                }

                // if all successors are visited by blue DFS
                if (blueDone)
                {
                    // check loop at an accepting & deadlock state
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE) && LTSState.IsDeadLock)
                    {
                        lock (reportLocker)
                        {
                            isStop = true;
                            Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>();
                            acceptingCycle.Add(v, pair);
                            blueStack.Pop();
                            finalLocalTaskStack          = blueStack;
                            finalAcceptingCycle          = acceptingCycle;
                            finalOutgoingTransitionTable = outgoingTransitionTable;
                            return;
                        }
                    }

                    // check whether all successors of v are already red
                    // also right for deadlock state
                    bool isAllRed = true;
                    foreach (string w in outgoing)
                    {
                        if (!sharedRedStates.ContainsKey(w))
                        {
                            isAllRed = false;
                            break;
                        }
                    }

                    // if all sucessors are red then v also red
                    if (isAllRed)
                    {
                        sharedRedStates.GetOrAdd(v, true);
                    }
                    // if v is accepting states
                    else if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        // increase count red of v by 1
                        sharedAcceptingCountRedDFS.GetOrAdd(v, 0);
                        sharedAcceptingCountRedDFS[v]++;

                        // initialize red DFS at v
                        bool stop = localRedDFSNestedDFSSharedRed(pair, blueStack, colorData, outgoingTransitionTable, rand);

                        if (stop)
                        {
                            return;
                        }
                    }

                    // set v to blue
                    colorData[v].setBlue();

                    //pop v out of blueStack
                    blueStack.Pop();
                }
            }

            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            return;
        }
        // local function of each thread
        public void localQueueTarjanFairnessChecking(object o)
        {
            // get order
            int order = (int)o;

            // local data for on-the-fly and Tarjan algorithm
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>                      callStack            = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      currentStack         = new Stack <LocalPair>(1024);
            Dictionary <string, int[]>             dfsData       = new Dictionary <string, int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(1024);
            int counter = 0;
            //--------------------------

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            // create random variable for each process
            Random rand = new Random(order);

            // push all initial states to callStack in different order & init data
            int[] initPermutation = generatePermutation(initialStates.Count, rand);
            for (int i = 0; i < initPermutation.Length; i++)
            {
                //get data from initialStates
                LocalPair tmp = initialStates[initPermutation[i]];
                callStack.Push(tmp);
                string tmpID = tmp.GetCompressedState();
                dfsData.Add(tmpID, new int[] { VISITED_NOPREORDER, 0 });
                outgoingTransitionTable.Add(tmpID, new List <string>(8));
            }

            // start loop
            while (callStack.Count > 0)
            {
                // cancel if too long action or any counterexample is reported
                if (CancelRequested || isStop)
                {
                    return;
                }

                // get the top of callStack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // get local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                int[]         vData    = dfsData[v];

                // if not expended then expend to next states from v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states of v
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // add to visitedTimes in this thread
                    //visitedTimes.GetOrAdd(v, 0);
                    //visitedTimes[v]++;

                    // update outgoing of v and set initial data for successors
                    // no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!dfsData.ContainsKey(w))
                        {
                            dfsData.Add(w, new int[] { VISITED_NOPREORDER, 0 });
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successors of v
                List <LocalPair> successors = expendedNodes[v];

                // process if v is not numbered yet
                if (vData[0] == VISITED_NOPREORDER)
                {
                    vData[0] = counter;
                    vData[1] = counter;
                    counter  = counter + 1;

                    // push to currentStack
                    currentStack.Push(pair);

                    // update lowlink according to successors in currentStack
                    // remove already visited successors
                    // no need to use random
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ  = successors[i];
                        string    w     = succ.GetCompressedState();
                        int[]     wData = dfsData[w];

                        if (wData[0] >= 0)
                        {
                            // update & remove from expendedNodes(v)
                            vData[1] = Math.Min(vData[1], wData[0]);
                            successors.RemoveAt(i);
                        }
                    }
                }

                // check if there is any successor not numbered & not visited by other threads
                // choose random
                bool completed = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    int       randIndex = rand.Next(successors.Count);
                    LocalPair succ      = successors[randIndex];
                    string    w         = succ.GetCompressedState();
                    int[]     wData     = dfsData[w];

                    // check states not locally visited & not in global shared found SCC
                    if (wData[0] == VISITED_NOPREORDER && !sharedSCCStates.ContainsKey(w))
                    {
                        callStack.Push(succ);
                        successors.RemoveAt(randIndex);
                        completed = false;
                        break;
                    }
                    else
                    {
                        successors.RemoveAt(randIndex);
                    }
                }

                // if all successors are visited
                if (completed)
                {
                    // check root
                    if (vData[0] == vData[1])
                    {
                        Dictionary <string, LocalPair> newSCC = new Dictionary <string, LocalPair>(1024);

                        // check selfLoop
                        bool selfLoop = false;
                        foreach (string w in outgoing)
                        {
                            if (v.Equals(w))
                            {
                                selfLoop = true;
                                break;
                            }
                        }

                        // get all states in a SCC & check Buchi fair
                        bool      isBuchiFair = false;
                        LocalPair tmp         = null;
                        string    tmpID       = null;
                        // get from current until v
                        do
                        {
                            tmp         = currentStack.Pop();
                            isBuchiFair = isBuchiFair || tmp.state.EndsWith(Constants.ACCEPT_STATE);
                            tmpID       = tmp.GetCompressedState();
                            int[] tmpData = dfsData[tmpID];
                            tmpData[0] = SCC_FOUND;
                            newSCC.Add(tmpID, tmp);

                            // update global
                            sharedSCCStates.GetOrAdd(tmpID, true);
                        } while (!tmpID.Equals(v));

                        if (isBuchiFair && (selfLoop || newSCC.Count > 1 || LTSState.IsDeadLock))
                        {
                            // queue new SCC to check fairness
                            localQueueSCC(order, newSCC, callStack, outgoingTransitionTable);
                        }

                        //pop callStack
                        callStack.Pop();
                    }
                    else
                    {
                        //pop callStack & update the parent
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsData[popID];
                        int[]     topData = dfsData[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
            isStop = true;
        }
        // Blue DFS
        public void localBlueDFSCombinationNestedDFS(object o)
        {
            // get order
            int order = (int)o;

            // local data of each thread for on-the-fly Nested DFS algorithm
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>         blueStack = new Stack <LocalPair>(5000);
            Dictionary <string, bool> cyanData  = new Dictionary <string, bool>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(1024);

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            // create random variable for each process
            Random rand = new Random(order);

            // push initial states to blueStack in random order & init data
            int[] permutation = generatePermutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[permutation[i]];
                blueStack.Push(tmp);
                string ID = tmp.GetCompressedState();
                cyanData.Add(ID, false);
                outgoingTransitionTable.Add(ID, new List <string>(8));
            }

            // start loop
            while (blueStack.Count > 0)
            {
                // cancel if too long action or couterexample reported
                if (CancelRequested || isStop)
                {
                    return;
                }

                // get the top of blueStack
                LocalPair         pair     = blueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // get local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                bool          isVCyan  = cyanData[v];

                // if v is not expended then expend successors of v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states from v & add to expendedNodes
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // add to visitedTimes in this thread
                    //visitedTimes.GetOrAdd(v, 0);
                    //visitedTimes[v]++;

                    // update outgoing of v and set cyan color false
                    // no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!cyanData.ContainsKey(w))
                        {
                            cyanData.Add(w, false);
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successor of v
                List <LocalPair> successors = expendedNodes[v];

                // if v is not cyan
                if (!isVCyan)
                {
                    cyanData[v] = true;

                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ    = successors[i];
                        string    w       = succ.GetCompressedState();
                        bool      isWCyan = cyanData[w];

                        if (isWCyan)
                        {
                            if (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                localBlueReportAcceptinCycle(succ, blueStack, outgoingTransitionTable);
                                return;
                            }
                            else
                            {
                                successors.RemoveAt(i);
                            }
                        }
                    }
                }

                // traverse all sucessors in a random order to find unvisited state
                bool blueDone = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    int       randIndex = rand.Next(successors.Count);
                    LocalPair succ      = successors[randIndex];
                    string    w         = succ.GetCompressedState();
                    bool      isWCyan   = cyanData[w];

                    // if w is not cyan & not global blue
                    // if w is in sharedBlueRedStates then w is global Blue
                    // if sharedBlueRedStates[w] is true then w is also global Red
                    if (!isWCyan && !sharedBlueRedStates.ContainsKey(w))
                    {
                        blueStack.Push(succ);
                        successors.RemoveAt(randIndex);
                        blueDone = false;
                        break;
                    }
                    else // remove already visited states in expendedNodes
                    {
                        successors.RemoveAt(randIndex);
                    }
                }

                // if all successors are visited by blue DFS
                if (blueDone)
                {
                    // mark v as global blue & false to indicate not globally red yet
                    sharedBlueRedStates.GetOrAdd(v, false);

                    // check loop at an accepting & deadlock state
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE) && LTSState.IsDeadLock)
                    {
                        lock (reportLocker)
                        {
                            isStop = true;
                            Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>();
                            acceptingCycle.Add(v, pair);
                            blueStack.Pop();
                            finalLocalTaskStack          = blueStack;
                            finalAcceptingCycle          = acceptingCycle;
                            finalOutgoingTransitionTable = outgoingTransitionTable;
                            return;
                        }
                    }

                    // check whether all successors of v are already red
                    // also right for deadlock state
                    bool isAllRed = true;
                    foreach (string w in outgoing)
                    {
                        // not in shareBlueRedStates or in but not yet red
                        if (!sharedBlueRedStates.ContainsKey(w) || !sharedBlueRedStates[w])
                        {
                            isAllRed = false;
                            break;
                        }
                    }

                    // if all sucessors are red then v also red
                    if (isAllRed)
                    {
                        sharedBlueRedStates[v] = true;
                    }
                    // if v is accepting state
                    else if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        Dictionary <LocalPair, bool> rSet = new Dictionary <LocalPair, bool>(1024);

                        // initialize red DFS at v
                        bool stop = localRedDFSCombinationNestedDFS(rSet, pair, blueStack, cyanData, outgoingTransitionTable, rand);
                        if (stop)
                        {
                            return;
                        }

                        // wait for all accepting states EXCEPT v in rSet become red
                        foreach (KeyValuePair <LocalPair, bool> kv in rSet)
                        {
                            string s = kv.Key.GetCompressedState();
                            if (kv.Key.state.EndsWith(Constants.ACCEPT_STATE) && !s.Equals(v))
                            {
                                while (!sharedBlueRedStates[s])
                                {
                                }
                                ;
                            }
                        }

                        // set all states in rSet to red
                        // states already blue and in shareBlueRedStates blue
                        foreach (KeyValuePair <LocalPair, bool> kv in rSet)
                        {
                            string kvID = kv.Key.GetCompressedState();
                            sharedBlueRedStates[kvID] = true;
                        }
                    }

                    //pop v out of blueStack
                    blueStack.Pop();

                    // uncyan v
                    cyanData[v] = false;
                }
            }

            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            return;
        }
        /// <summary>
        /// The function of each worker in swarm NDFS
        /// </summary>
        /// <returns></returns>
        public void SwarmNestedDFSModelCheckingWorker()
        {
            Dictionary <string, List <string> > OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            List <LocalPair> initials = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initials.Count == 0)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            Stack <LocalPair> BlueStack = new Stack <LocalPair>(5000);
            Dictionary <string, StateColor> colorData = new Dictionary <string, StateColor>(5000);

            int threadId;
            // Create random variable with different seed for each thread
            Random rand; // helps different threads access different region of the graph

            lock (MultiCoreLock)
            {
                threadId = MultiCoreSeed;
                rand     = new Random(MultiCoreSeed);
                MultiCoreSeed++;
            }


            // Create the list of initial states
            // May apply randomness here to increase performance
            int[] permutation = generatePermutation(initials.Count, rand);

            for (int z = 0; z < initials.Count; z++)
            {
                LocalPair initState = initials[permutation[z]];
                BlueStack.Push(initState);
                string ID = initState.GetCompressedState();
                colorData.Add(ID, new StateColor());
                OutgoingTransitionTable.Add(ID, new List <string>(8));
            }

            //store the expended event step of a node to avoid multiple invocation of the make one move.
            Dictionary <string, List <LocalPair> > ExpendedNode = new Dictionary <string, List <LocalPair> >(1024);

            do
            {
                if (CancelRequested || StopMutliCoreThreads)
                {
                    return;
                }

                LocalPair         pair    = BlueStack.Peek();
                ConfigurationBase evt     = pair.configuration;
                string            BAState = pair.state;

                string v = pair.GetCompressedState();

                List <string> outgoing = OutgoingTransitionTable[v];

                StateColor nodeColor = colorData[v];

                if (nodeColor.IsWhite())
                {
                    nodeColor.SetCyan();
                }

                bool blueDone = true;

                // Initialize the node if first time visited
                if (!ExpendedNode.ContainsKey(v))
                {
                    //ConfigurationBase[] configList = evt.MakeOneMove().ToArray();
                    IEnumerable <ConfigurationBase> configList = evt.MakeOneMove();
                    pair.SetEnabled(configList, FairnessType);
                    List <LocalPair> product = LocalPair.NextLocal(BA, configList, BAState);
                    ExpendedNode.Add(v, product);

                    for (int k = product.Count - 1; k >= 0; k--)
                    {
                        LocalPair step = product[k];
                        string    tmp  = step.GetCompressedState();
                        //update the incoming and outgoing edges
                        outgoing.Add(tmp);
                        if (!colorData.ContainsKey(tmp))
                        {
                            colorData.Add(tmp, new StateColor());
                            OutgoingTransitionTable.Add(tmp, new List <string>(8));
                        }
                    }
                }

                List <LocalPair> list = ExpendedNode[v];

                //transverse all neighbour nodes
                for (int k = list.Count - 1; k >= 0; k--)
                {
                    int randIndex = rand.Next(list.Count);
                    //int randIndex = list.Count - 1;
                    LocalPair  step           = list[randIndex];
                    string     tmp            = step.GetCompressedState();
                    StateColor neighbourColor = colorData[tmp];

                    //if the neighbour node is white
                    if (neighbourColor.IsWhite())
                    {
                        if (blueDone)
                        {
                            BlueStack.Push(step);
                            blueDone = false;
                            list.RemoveAt(randIndex);
                            break;
                        }
                    }
                    // if the neighbour node is cyan,
                    // and either this node or the neibour node is the accept state
                    // then report cycle
                    else if (neighbourColor.IsCyan())
                    {
                        if (step.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                        {
                            SwarmNestedDFSReportBlueCycle(step, pair, BlueStack, colorData, OutgoingTransitionTable);
                            return;
                        }
                        else
                        {
                            list.RemoveAt(randIndex);
                        }
                    }
                    // if the neighbour node is either blue or red,
                    // can remove from the list
                    else
                    {
                        list.RemoveAt(randIndex);
                    }
                }

                if (blueDone)
                {
                    BlueStack.Pop();

                    // If the current node is an accept state,
                    // do the red DFS
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        if (evt.IsDeadLock)
                        {
                            lock (MultiCoreLock)
                            {
                                StopMutliCoreThreads = true;
                                Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>();
                                LoopPairs.Add(v, pair);
                                MultiCoreLocalTaskStack          = BlueStack;
                                MultiCoreResultedLoop            = LoopPairs;
                                MultiCoreOutgoingTransitionTable = OutgoingTransitionTable;
                                return;
                            }
                        }


                        bool stop = SwarmNestedDFSDepthFirstSearchRed(pair, BlueStack, OutgoingTransitionTable, colorData);

                        if (stop)
                        {
                            return;
                        }

                        nodeColor.SetRed();
                    }
                    else
                    {
                        nodeColor.SetBlue();
                    }
                }
            } while (BlueStack.Count > 0);

            StopMutliCoreThreads = true;
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = colorData.Count;
            return;
        }
Пример #8
0
        /// <summary>
        /// Improved Tarjan Algorithm
        /// A Note on On-The-Fly Verification Algorithms - TACAS 2005
        /// </summary>
        public void ImprovedTarjan()
        {
            VerificationOutput.CounterExampleTrace = null;

            //on-the-fly data
            Stack <LocalPair>                      callStack     = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      currentStack  = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      goalStack     = new Stack <LocalPair>(1024);
            Dictionary <string, int[]>             dfsNumber     = new Dictionary <string, int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(5000);
            int counter = 0;

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            //push initial states to call stack
            foreach (LocalPair tmp in initialStates)
            {
                callStack.Push(tmp);
            }

            //start loop
            while (callStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = dfsNumber.Count;
                    return;
                }

                //get top of call stack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (expendedNodes.ContainsKey(v))
                {
                    successors = expendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, successors);
                }

                //if v is not number yet
                if (!dfsNumber.ContainsKey(v))
                {
                    //number v
                    int[] vData = new int[] { counter, counter };
                    dfsNumber.Add(v, vData);
                    counter = counter + 1;

                    //push to currentStack
                    currentStack.Push(pair);

                    //check whether v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        goalStack.Push(pair);
                    }

                    //update lowlink for already numbered successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        //if w is already numbered
                        if (dfsNumber.ContainsKey(w))
                        {
                            int[] wData = dfsNumber[w];

                            //if w is in current stack
                            if (wData[0] >= 0)
                            {
                                vData[1] = Math.Min(vData[1], wData[0]);

                                //check for report accepting cycle
                                if (goalStack.Count > 0 && vData[1] <= dfsNumber[goalStack.Peek().GetCompressedState()][0])
                                {
                                    //REPORT COUNTEREXAMPLE
                                    GetLoopCounterExample(w, callStack, dfsNumber);
                                    return;
                                }
                            }
                        }
                    }
                }

                //check if there is an unnumbered successor
                bool isCompleted = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is not already numbered
                    if (!dfsNumber.ContainsKey(w))
                    {
                        callStack.Push(succ);
                        isCompleted = false;
                        break;
                    }
                }

                //if there is no unnumbered successor
                if (isCompleted)
                {
                    //deadlock at accepting state
                    if (LTSState.IsDeadLock && pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        //REPORT COUNTEREXAMPLE
                        GetDeadlockCounterExample(callStack, dfsNumber);
                        return;
                    }

                    int[] vData = dfsNumber[v];
                    //if v is root
                    if (vData[0] == vData[1])
                    {
                        //remove states from current stack and goal stack
                        LocalPair tmp   = null;
                        string    tmpID = null;
                        do
                        {
                            //current stack
                            tmp   = currentStack.Pop();
                            tmpID = tmp.GetCompressedState();
                            dfsNumber[tmpID][0] = SCC_FOUND;

                            //goal stack
                            if (goalStack.Count > 0 && tmp == goalStack.Peek())
                            {
                                goalStack.Pop();
                            }
                        } while (tmp != pair);

                        //pop call stack
                        callStack.Pop();
                    }
                    else
                    {
                        //pop call stack and update lowlink of top
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsNumber[popID];
                        int[]     topData = dfsNumber[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }

            //no counter example
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = dfsNumber.Count;
            return;
        }
Пример #9
0
        /// <summary>
        /// Local blue DFS in each thread
        /// </summary>
        /// <param name="o"></param>
        public void LocalBlue2(object o)
        {
            //order of this thread
            int    order = (int)o;
            Random rand  = new Random(order);

            //on-the-fly data
            Stack <LocalPair>         localBlueStack = new Stack <LocalPair>(5000);
            Dictionary <string, bool> localCyanData  = new Dictionary <string, bool>(5000);
            Dictionary <string, List <LocalPair> > localExpendedNodes = new Dictionary <string, List <LocalPair> >(5000);

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            //push local initial states to local blue stack
            int[] localPerm = Permutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[localPerm[i]];
                localBlueStack.Push(tmp);
            }

            //start loop
            while (localBlueStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested || isGlobalStop)
                {
                    return;
                }

                //get top of blue stack
                LocalPair         pair     = localBlueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (localExpendedNodes.ContainsKey(v))
                {
                    successors = localExpendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    localExpendedNodes.Add(v, successors);
                }

                //if v is not cyan
                if (!localCyanData.ContainsKey(v))
                {
                    //set v cyan
                    localCyanData.Add(v, true);

                    //early cycle detection
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        //if w is cyan and (v or w is accepting)
                        if (localCyanData.ContainsKey(w))
                        {
                            bool isWcyan = localCyanData[w];
                            if (isWcyan && (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE)))
                            {
                                //REPORT COUNTEREXAMPLE
                                GetLocalLoopCounterExample(w, localBlueStack);
                                return;
                            }
                        }
                    }
                }

                //------------------------------------------------------------------------
                //filter successors and check if all successors are red
                bool       isAllRed        = true;
                List <int> unvisitedIndexs = new List <int>(successors.Count);//not visited and not global red
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is not cyan and not global blue
                    if (!localCyanData.ContainsKey(w) && !globalBlueRedStates.ContainsKey(w))
                    {
                        unvisitedIndexs.Add(i);
                    }

                    //set all red variable to false if w not global red
                    if (isAllRed)
                    {
                        if (!globalBlueRedStates.ContainsKey(w) || !globalBlueRedStates[w])
                        {
                            isAllRed = false;
                        }
                    }
                }
                //------------------------------------------------------------------------

                //get random unvisited successors
                if (unvisitedIndexs.Count > 0)
                {
                    bool       isFresh       = false;
                    List <int> unFreshIndexs = new List <int>();
                    while (unvisitedIndexs.Count > 0)
                    {
                        int       r    = rand.Next(unvisitedIndexs.Count);
                        LocalPair succ = successors[unvisitedIndexs[r]];
                        string    w    = succ.GetCompressedState();

                        //if w is fresh successor
                        if (!allVisitedStates.ContainsKey(w))
                        {
                            localBlueStack.Push(succ);

                            allVisitedStates.GetOrAdd(w, 0);
                            allVisitedStates[w]++;

                            isFresh = true;
                            break;
                        }
                        else
                        {
                            unFreshIndexs.Add(unvisitedIndexs[r]);
                            unvisitedIndexs.RemoveAt(r);
                        }
                    }
                    if (!isFresh)
                    {
                        int       r    = rand.Next(unFreshIndexs.Count);
                        LocalPair succ = successors[unFreshIndexs[r]];
                        string    w    = succ.GetCompressedState();
                        localBlueStack.Push(succ);

                        allVisitedStates.GetOrAdd(w, 0);
                        allVisitedStates[w]++;
                    }
                }
                else
                {
                    //mark v global blue
                    globalBlueRedStates.GetOrAdd(v, false);

                    //deadlock at accepting state
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE) && LTSState.IsDeadLock)
                    {
                        //REPORT COUNTEREXAMPLE
                        GetLocalDeadlockCounterExample(localBlueStack);
                        return;
                    }

                    //if all successors are global red
                    if (isAllRed)
                    {
                        globalBlueRedStates[v] = true;
                    }
                    else if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        Dictionary <LocalPair, bool> rSet = new Dictionary <LocalPair, bool>(1024);

                        //start local red DFS
                        bool isStop = LocalRed2(rSet, pair, localBlueStack, localCyanData, rand, localExpendedNodes);

                        if (isStop)
                        {
                            return;
                        }

                        //wait for all accepting states EXCEPT v in rSet become red
                        foreach (KeyValuePair <LocalPair, bool> kv in rSet)
                        {
                            string s = kv.Key.GetCompressedState();
                            if (kv.Key.state.EndsWith(Constants.ACCEPT_STATE) && !s.Equals(v))
                            {
                                while (!globalBlueRedStates[s])
                                {
                                    ;
                                }
                            }
                        }

                        //set all states in rSet to red
                        foreach (KeyValuePair <LocalPair, bool> kv in rSet)
                        {
                            string kvID = kv.Key.GetCompressedState();
                            globalBlueRedStates[kvID] = true;
                        }
                    }

                    //pop blue stack
                    localBlueStack.Pop();

                    //uncyan v
                    localCyanData[v] = false;
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Local Improved Tarjan in each thread
        /// </summary>
        /// <param name="o"></param>
        public void LocalImprovedTarjanSwarm(object o)
        {
            //order of this thread
            int    order = (int)o;
            Random rand  = new Random(order);

            //on-the-fly data
            Stack <LocalPair>          localCallStack    = new Stack <LocalPair>(5000);
            Stack <LocalPair>          localCurrentStack = new Stack <LocalPair>(1024);
            Stack <LocalPair>          localGoalStack    = new Stack <LocalPair>(256);
            Dictionary <string, int[]> localDFSNumber    = new Dictionary <string, int[]>(5000);
            int localNumber = 0;
            Dictionary <string, List <LocalPair> > localExpendedNodes = new Dictionary <string, List <LocalPair> >(5000);

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            //push local initial states to local call stack
            int[] localPerm = Permutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[localPerm[i]];
                localCallStack.Push(tmp);
            }

            //start loop
            while (localCallStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested || isGlobalStop)
                {
                    return;
                }

                //get top of call stack
                LocalPair         pair     = localCallStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (localExpendedNodes.ContainsKey(v))
                {
                    successors = localExpendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    localExpendedNodes.Add(v, successors);
                }

                //if v is not number yet
                if (!localDFSNumber.ContainsKey(v))
                {
                    //number v
                    int[] vData = new int[] { localNumber, localNumber };
                    localDFSNumber.Add(v, vData);
                    localNumber = localNumber + 1;

                    //push to currentStack
                    localCurrentStack.Push(pair);

                    //check whether v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        localGoalStack.Push(pair);
                    }

                    //update lowlink for already numbered successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        if (localDFSNumber.ContainsKey(w))
                        {
                            int[] wData = localDFSNumber[w];
                            //if w is in current stack
                            if (wData[0] >= 0)
                            {
                                vData[1] = Math.Min(vData[1], wData[0]);

                                //check for report accepting cycle
                                if (localGoalStack.Count > 0 && vData[1] <= localDFSNumber[localGoalStack.Peek().GetCompressedState()][0])
                                {
                                    //REPORT COUNTEREXAMPLE
                                    GetLocalLoopCounterExample(w, localCallStack);
                                    return;
                                }
                            }
                        }
                    }
                }

                //------------------------------------------------------------------------
                //filter successors
                List <int> unvisitedIndexs = new List <int>(successors.Count);//not numbered and not global found
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is not cyan and not global red
                    if (!localDFSNumber.ContainsKey(w))
                    {
                        unvisitedIndexs.Add(i);
                    }
                }
                //------------------------------------------------------------------------

                //get random unvisited successors
                if (unvisitedIndexs.Count > 0)
                {
                    bool       isFresh       = false;
                    List <int> unFreshIndexs = new List <int>();
                    while (unvisitedIndexs.Count > 0)
                    {
                        int       r    = rand.Next(unvisitedIndexs.Count);
                        LocalPair succ = successors[unvisitedIndexs[r]];
                        string    w    = succ.GetCompressedState();

                        //if w is fresh successor
                        if (!allVisitedStates.ContainsKey(w))
                        {
                            localCallStack.Push(succ);

                            allVisitedStates.GetOrAdd(w, 0);
                            allVisitedStates[w]++;

                            isFresh = true;
                            break;
                        }
                        else
                        {
                            unFreshIndexs.Add(unvisitedIndexs[r]);
                            unvisitedIndexs.RemoveAt(r);
                        }
                    }
                    if (!isFresh)
                    {
                        int       r    = rand.Next(unFreshIndexs.Count);
                        LocalPair succ = successors[unFreshIndexs[r]];
                        string    w    = succ.GetCompressedState();
                        localCallStack.Push(succ);

                        allVisitedStates.GetOrAdd(w, 0);
                        allVisitedStates[w]++;
                    }
                }
                else
                {
                    //deadlock at accepting state
                    if (LTSState.IsDeadLock && pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        //REPORT COUNTEREXAMPLE
                        GetLocalDeadlockCounterExample(localCallStack);
                        return;
                    }

                    int[] vData = localDFSNumber[v];
                    //if v is root
                    if (vData[0] == vData[1])
                    {
                        //remove states from current stack and goal stack
                        LocalPair tmp   = null;
                        string    tmpID = null;
                        do
                        {
                            //current stack
                            tmp   = localCurrentStack.Pop();
                            tmpID = tmp.GetCompressedState();
                            localDFSNumber[tmpID][0] = SCC_FOUND;

                            //goal stack
                            if (localGoalStack.Count > 0 && tmp == localGoalStack.Peek())
                            {
                                localGoalStack.Pop();
                            }
                        } while (tmp != pair);

                        //pop call stack
                        localCallStack.Pop();
                    }
                    else
                    {
                        //pop call stack and update lowlink of top
                        LocalPair pop     = localCallStack.Pop();
                        LocalPair top     = localCallStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = localDFSNumber[popID];
                        int[]     topData = localDFSNumber[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Run the verification and get the result.
        /// </summary>
        /// <returns></returns>
        public void ModelCheckingLivenessWithFairness()
        {
            Dictionary <string, List <string> > OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);

            LocalTaskStack = new Stack <LocalPair>(5000);
            VerificationOutput.CounterExampleTrace = null;

            List <LocalPair>         initials = LocalPair.GetInitialPairsLocal(BA, InitialStep);
            StringDictionary <int[]> DFSData  = new StringDictionary <int[]>();

            if (initials.Count == 0)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            for (int z = 0; z < initials.Count; z++)
            {
                LocalPair initState = initials[z];
                LocalTaskStack.Push(initState);
                string ID = initState.GetCompressedState(FairnessType);
                DFSData.Add(ID, new int[] { VISITED_NOPREORDER, 0 });
                OutgoingTransitionTable.Add(ID, new List <string>(8));
            }

            Dictionary <string, LocalPair> SCCPairs = new Dictionary <string, LocalPair>(1024);
            Stack <LocalPair> stepStack             = new Stack <LocalPair>(1024);

            int i = 0;

            //store the expended event step of a node to avoid multiple invocation of the make one move.
            Dictionary <string, List <LocalPair> > ExpendedNode = new Dictionary <string, List <LocalPair> >(1024);

            do
            {
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = DFSData.Count; // VisitedWithID.Count;
                    return;
                }

                LocalPair         pair    = LocalTaskStack.Peek();
                ConfigurationBase evt     = pair.configuration;
                string            BAState = pair.state;

                string v = pair.GetCompressedState(FairnessType);

                List <string> outgoing = OutgoingTransitionTable[v];


                int[] nodeData = DFSData.GetContainsKey(v);

                if (nodeData[0] == VISITED_NOPREORDER)
                {
                    nodeData[0] = i;
                    i++;
                }

                bool done = true;

                if (ExpendedNode.ContainsKey(v))
                {
                    List <LocalPair> list = ExpendedNode[v];
                    if (list.Count > 0)
                    {
                        //transverse all steps
                        for (int k = list.Count - 1; k >= 0; k--)
                        {
                            LocalPair step = list[k];

                            //if the step is a unvisited step
                            string tmp = step.GetCompressedState(FairnessType);
                            if (DFSData.GetContainsKey(tmp)[0] == VISITED_NOPREORDER)
                            //if (!preorder.ContainsKey(step.GetCompressedState()))
                            {
                                //only add the first unvisited step
                                //for the second or more unvisited steps, ignore at the monent
                                if (done)
                                {
                                    LocalTaskStack.Push(step);
                                    done = false;
                                    list.RemoveAt(k);
                                }
                            }
                            else
                            {
                                list.RemoveAt(k);
                            }
                        }
                    }
                }
                else
                {
                    //ConfigurationBase[] list = evt.MakeOneMove().ToArray();
                    IEnumerable <ConfigurationBase> list = evt.MakeOneMove();
                    pair.SetEnabled(list, FairnessType);
                    List <LocalPair> product = LocalPair.NextLocal(BA, list, BAState);

                    //count the transitions visited
                    VerificationOutput.Transitions += product.Count;

                    for (int k = product.Count - 1; k >= 0; k--)
                    {
                        LocalPair step = product[k];
                        string    tmp  = step.GetCompressedState(FairnessType);

                        //if (VisitedWithID.ContainsKey(tmp))
                        int[] data = DFSData.GetContainsKey(tmp);
                        if (data != null)
                        {
                            //update the incoming and outgoing edges
                            //int t = VisitedWithID.GetContainsKey(tmp); //DataStore.DataManager.GetID(tmp);
                            outgoing.Add(tmp);

                            //if this node is still not visited
                            if (data[0] == VISITED_NOPREORDER)
                            {
                                //step.ID = t;
                                //only put the first one to the work list stack.
                                //if there are more than one node to be visited,
                                //simply ignore them and keep its event step in the list.
                                if (done)
                                {
                                    LocalTaskStack.Push(step);
                                    done = false;
                                    product.RemoveAt(k);
                                }
                                else
                                {
                                    product[k] = step;
                                }
                            }
                            //this node is truly visited. can be removed
                            else
                            {
                                product.RemoveAt(k);
                            }
                        }
                        else
                        {
                            //int stateID = VisitedWithID.Count;
                            //VisitedWithID.Add(tmp,false);
                            DFSData.Add(tmp, new int[] { VISITED_NOPREORDER, 0 });

                            OutgoingTransitionTable.Add(tmp, new List <string>(8));
                            //step.ID = stateID;
                            outgoing.Add(tmp);

                            //only put the first one into the stack.
                            if (done)
                            {
                                LocalTaskStack.Push(step);
                                done = false;
                                product.RemoveAt(k);
                            }
                            else
                            {
                                product[k] = step;
                            }
                        }
                    }

                    //create the remaining steps as the expending list for v
                    ExpendedNode.Add(v, product);
                }

                if (done)
                {
                    int lowlinkV  = nodeData[0]; // preorder[v];
                    int preorderV = lowlinkV;

                    bool selfLoop = false;
                    for (int j = 0; j < outgoing.Count; j++)
                    {
                        string w = outgoing[j];
                        if (w == v)
                        {
                            selfLoop = true;
                        }

                        int[] wdata = DFSData.GetContainsKey(w);
                        if (wdata[0] != SCC_FOUND)
                        {
                            if (wdata[0] > preorderV)
                            {
                                lowlinkV = Math.Min(lowlinkV, wdata[1]);
                            }
                            else
                            {
                                lowlinkV = Math.Min(lowlinkV, wdata[0]);
                            }
                        }
                    }

                    nodeData[1] = lowlinkV;

                    LocalTaskStack.Pop();

                    if (lowlinkV == preorderV)
                    {
                        SCCPairs.Add(v, pair);
                        nodeData[0] = SCC_FOUND;

                        //checking for buchi-fair
                        bool BuchiFair = pair.state.EndsWith(Constants.ACCEPT_STATE);

                        //while (stepStack.Count > 0 && preorder[stepStack.Peek().GetCompressedState()] > preorderV)
                        while (stepStack.Count > 0 && DFSData.GetContainsKey(stepStack.Peek().GetCompressedState(FairnessType))[0] > preorderV)
                        {
                            LocalPair s = stepStack.Pop();
                            string    k = s.GetCompressedState(FairnessType);

                            DFSData.GetContainsKey(k)[0] = SCC_FOUND;

                            SCCPairs.Add(k, s);

                            if (!BuchiFair && s.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                BuchiFair = true;
                            }
                        }

                        int SCCSize = SCCPairs.Count;

                        if (BuchiFair && (evt.IsDeadLock || SCCSize > 1 || selfLoop))
                        {
                            PrintMessage("A SCC of size " + SCCSize + " is found");

                            Dictionary <string, LocalPair> value = IsFair(SCCPairs, OutgoingTransitionTable);
                            if (value != null)
                            {
                                PrintMessage("The SCC found is FAIR.");

                                VerificationOutput.VerificationResult = VerificationResultType.INVALID;
                                VerificationOutput.NoOfStates         = DFSData.Count; // VisitedWithID.Count;
                                LocalGetCounterExample(value, OutgoingTransitionTable);
                                return;
                            }

                            PrintMessage("The SCC found is NOT fair.");
                        }

                        foreach (string componet in SCCPairs.Keys)
                        {
                            ExpendedNode.Remove(componet);
                            OutgoingTransitionTable.Remove(componet);
                        }

                        //StronglyConnectedComponets.Clear();
                        SCCPairs.Clear();
                    }
                    else
                    {
                        stepStack.Push(pair);
                    }
                }
            } while (LocalTaskStack.Count > 0);

            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = DFSData.Count; // VisitedWithID.Count;
        }
Пример #12
0
        /// <summary>
        /// Improve Tarjan-Geldenhuy algorithm
        /// Iterative version
        /// </summary>
        public void ImprovedTarjanGeldenhuysValmari()
        {
            VerificationOutput.CounterExampleTrace = null;
            // data for on-the-fly and Tarjan algorithm
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>                      callStack            = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      currentStack         = new Stack <LocalPair>(1024);
            Stack <LocalPair>                      goalStack            = new Stack <LocalPair>(256);
            Dictionary <string, int[]>             dfsData       = new Dictionary <string, int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(1024);
            int counter = 0;
            //--------------------------

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            // test
            //expendedNodesNumber = 0;

            // put all initial states to callStack & init data
            foreach (LocalPair tmp in initialStates)
            {
                callStack.Push(tmp);
                string tmpID = tmp.GetCompressedState();
                dfsData.Add(tmpID, new int[] { VISITED_NOPREORDER, 0 });
                outgoingTransitionTable.Add(tmpID, new List <string>(8));
            }

            // start loop
            while (callStack.Count > 0)
            {
                // cancel if too long action
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = dfsData.Count;
                    return;
                }

                // get the top of callStack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // get data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                int[]         vData    = dfsData[v];

                // if not expended then expend to next states from v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states of v & add to expendedNodes
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove(); //.ToArray()
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // increase number of states expended
                    //expendedNodesNumber++;

                    // increase transitions visited
                    VerificationOutput.Transitions += nextStates.Count;

                    // update outgoing of v and set initial data for successors
                    // no need to use inverse for statement
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!dfsData.ContainsKey(w))
                        {
                            dfsData.Add(w, new int[] { VISITED_NOPREORDER, 0 });
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successors of v
                List <LocalPair> successors = expendedNodes[v];

                // process if v is not numbered yet
                if (vData[0] == VISITED_NOPREORDER)
                {
                    vData[0] = counter;
                    vData[1] = counter;
                    counter  = counter + 1;

                    // push to currentStack
                    currentStack.Push(pair);

                    // check whether v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        goalStack.Push(pair);
                    }

                    // update lowlink according to successors in currentStack
                    // remove already visited successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ  = successors[i];
                        string    w     = succ.GetCompressedState();
                        int[]     wData = dfsData[w];
                        if (wData[0] >= 0)
                        {
                            // update & remove from expendedNodes(v)
                            vData[1] = Math.Min(vData[1], wData[0]);
                            successors.RemoveAt(i);

                            // check for report accepting cycle
                            if (goalStack.Count > 0 && vData[1] <= dfsData[goalStack.Peek().GetCompressedState()][0])
                            {
                                // REPORT COUNTEREXAMPLE
                                reportAcceptingCycle(succ, callStack, dfsData, outgoingTransitionTable);
                                return;
                            }
                        }
                    }
                }

                // check if there is any successor not numbered
                bool completed = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ  = successors[i];
                    string    w     = succ.GetCompressedState();
                    int[]     wData = dfsData[w];
                    if (wData[0] == VISITED_NOPREORDER)
                    {
                        callStack.Push(succ);
                        successors.RemoveAt(i);
                        completed = false;
                        break;
                    }
                    else
                    {
                        successors.RemoveAt(i);
                    }
                }

                // if all successors are visited
                if (completed)
                {
                    // check for loop at deadlock & accepting state
                    if (LTSState.IsDeadLock && pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        // report accepting cycle
                        reportAcceptingCycle(pair, callStack, dfsData, outgoingTransitionTable);
                        return;
                    }

                    if (vData[0] == vData[1])
                    {
                        LocalPair tmp   = null;
                        string    tmpID = null;

                        // pop currentStack and update SCC_FOUND until v
                        do
                        {
                            // remove from currentStack
                            tmp   = currentStack.Pop();
                            tmpID = tmp.GetCompressedState();
                            int[] tmpData = dfsData[tmpID];
                            tmpData[0] = SCC_FOUND;

                            // remove from goalStack
                            if (goalStack.Count > 0 && tmp == goalStack.Peek())
                            {
                                goalStack.Pop();
                            }
                        } while (!tmpID.Equals(v));

                        // pop callStack
                        callStack.Pop();
                    }
                    else
                    {
                        // pop callStack & update the parent
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsData[popID];
                        int[]     topData = dfsData[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
            // end while loop
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = dfsData.Count;
            return;
        }
Пример #13
0
        /// <summary>
        /// Run the verification using the Nested DFS algorithm and get the result.
        /// Based on:
        /// A Note on On-The-Fly Verification Algorithms
        /// http://dl.acm.org/citation.cfm?id=2140670
        /// Stefan Schwoon and Javier Esparza
        /// Proceeding TACAS'05 Proceedings of the 11th international conference on
        /// Tools and Algorithms for the Construction and Analysis of Systems
        /// Springer-Verlag Berlin, Heidelberg, 2005
        /// </summary>
        /// <returns></returns>
        public void NestedDFSModelChecking()
        {
            Dictionary <string, List <string> > OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);

            VerificationOutput.CounterExampleTrace = null;

            List <LocalPair> initials = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initials.Count == 0)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            Stack <LocalPair>             BlueStack = new Stack <LocalPair>(5000);
            StringDictionary <StateColor> colorData = new StringDictionary <StateColor>(5000);

            for (int z = 0; z < initials.Count; z++)
            {
                LocalPair initState = initials[z];
                BlueStack.Push(initState);
                string ID = initState.GetCompressedState();
                colorData.Add(ID, new StateColor());
                OutgoingTransitionTable.Add(ID, new List <string>(8));
            }

            //store the expended event step of a node to avoid multiple invocation of the make one move.
            Dictionary <string, List <LocalPair> > ExpendedNode = new Dictionary <string, List <LocalPair> >(1024);

            do
            {
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = colorData.Count; // VisitedWithID.Count;
                    return;
                }

                LocalPair         pair    = BlueStack.Peek();
                ConfigurationBase evt     = pair.configuration;
                string            BAState = pair.state;

                string v = pair.GetCompressedState();

                List <string> outgoing = OutgoingTransitionTable[v];

                StateColor nodeColor = colorData.GetContainsKey(v);

                if (nodeColor.IsWhite())
                {
                    nodeColor.SetCyan();
                }

                bool blueDone = true;

                if (ExpendedNode.ContainsKey(v))
                {
                    List <LocalPair> list = ExpendedNode[v];

                    if (list.Count > 0)
                    {
                        //transverse all neighbour nodes
                        for (int k = list.Count - 1; k >= 0; k--)
                        {
                            LocalPair  step           = list[k];
                            string     tmp            = step.GetCompressedState();
                            StateColor neighbourColor = colorData.GetContainsKey(tmp);

                            //if the neighbour node is white
                            if (neighbourColor.IsWhite())
                            {
                                //only add the first unvisited node
                                //for the second or more unvisited steps, ignore at the monent
                                if (blueDone)
                                {
                                    BlueStack.Push(step);
                                    blueDone = false;
                                    list.RemoveAt(k);
                                }
                            }

                            // if the neighbour node is cyan,
                            // and either this node or the neibour node is the accept state
                            // then report cycle
                            else if (neighbourColor.IsCyan())
                            {
                                if (step.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                                {
                                    // Report cycle
                                    ReportBlueCycle(step, pair, BlueStack, colorData, OutgoingTransitionTable);
                                    return;
                                }
                                else
                                {
                                    list.RemoveAt(k);
                                }
                            }
                            // if the neighbour node is either blue or red,
                            // can remove from the list
                            else
                            {
                                list.RemoveAt(k);
                            }
                        }
                    }
                }
                else
                {
                    //ConfigurationBase[] list = evt.MakeOneMove().ToArray();
                    IEnumerable <ConfigurationBase> list = evt.MakeOneMove();
                    pair.SetEnabled(list, FairnessType);
                    List <LocalPair> product = LocalPair.NextLocal(BA, list, BAState);

                    //count the transitions visited
                    VerificationOutput.Transitions += product.Count;

                    for (int k = product.Count - 1; k >= 0; k--)
                    {
                        LocalPair  step           = product[k];
                        string     tmp            = step.GetCompressedState();
                        StateColor neighbourColor = colorData.GetContainsKey(tmp);

                        if (neighbourColor != null)
                        {
                            //update the incoming and outgoing edges
                            outgoing.Add(tmp);

                            //if this node is still not visited
                            if (neighbourColor.IsWhite())
                            {
                                //only add the first unvisited node
                                //for the second or more unvisited steps, ignore at the monent
                                if (blueDone)
                                {
                                    BlueStack.Push(step);
                                    blueDone = false;
                                    product.RemoveAt(k);
                                }
                            }
                            // if the neighbour node is cyan,
                            // and either this node or the neibour node is the accept state
                            // then report cycle
                            else if (neighbourColor.IsCyan())
                            {
                                if (step.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                                {
                                    // Report cycle
                                    ReportBlueCycle(step, pair, BlueStack, colorData, OutgoingTransitionTable);
                                    return;
                                }
                                else
                                {
                                    product.RemoveAt(k);
                                }
                            }
                            // if the neighbour node is either blue or red,
                            // can remove from the list
                            else
                            {
                                product.RemoveAt(k);
                            }
                        }

                        // If the node is not initiated
                        else
                        {
                            colorData.Add(tmp, new StateColor());
                            OutgoingTransitionTable.Add(tmp, new List <string>(8));
                            outgoing.Add(tmp);

                            if (blueDone)
                            {
                                BlueStack.Push(step);
                                blueDone = false;
                                product.RemoveAt(k);
                            }
                        }
                    }

                    //create the remaining steps as the expending list for v
                    ExpendedNode.Add(v, product);
                }

                if (blueDone)
                {
                    BlueStack.Pop();

                    // If the current node is an accept state,
                    // do the red DFS
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        if (evt.IsDeadLock)
                        {
                            VerificationOutput.VerificationResult = VerificationResultType.INVALID;
                            VerificationOutput.NoOfStates         = colorData.Count;
                            Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>();
                            LoopPairs.Add(v, pair);
                            LocalTaskStack = BlueStack;
                            LocalGetCounterExample(LoopPairs, OutgoingTransitionTable);
                            return;
                        }

                        bool stop = DepthFirstSearchRed(pair, BlueStack, OutgoingTransitionTable, colorData);

                        if (stop)
                        {
                            return;
                        }

                        nodeColor.SetRed();
                    }
                    else
                    {
                        nodeColor.SetBlue();
                    }
                }
            } while (BlueStack.Count > 0);

            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = colorData.Count;
            return;
        }
        // local function of each thread
        public void TarjanFairnessChecking()
        {
            // local data for on-the-fly and Tarjan algorithm
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>                      callStack            = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      currentStack         = new Stack <LocalPair>(1024);
            Dictionary <string, int[]>             dfsData       = new Dictionary <string, int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(1024);
            int counter = 0;
            //--------------------------

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            // put all initial states to callStack & init data
            foreach (LocalPair tmp in initialStates)
            {
                callStack.Push(tmp);
                string tmpID = tmp.GetCompressedState();
                dfsData.Add(tmpID, new int[] { VISITED_NOPREORDER, 0 });
                outgoingTransitionTable.Add(tmpID, new List <string>(8));
            }

            // start loop
            while (callStack.Count > 0)
            {
                // cancel if too long action or any counterexample is reported
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = dfsData.Count;
                    return;
                }

                // get the top of callStack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // get local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                int[]         vData    = dfsData[v];

                // if not expended then expend to next states from v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states of v
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // add to visitedTimes in this thread
                    //visitedTimes.GetOrAdd(v, 0);
                    //visitedTimes[v]++;

                    // update outgoing of v and set initial data for successors
                    // no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!dfsData.ContainsKey(w))
                        {
                            dfsData.Add(w, new int[] { VISITED_NOPREORDER, 0 });
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successors of v
                List <LocalPair> successors = expendedNodes[v];

                // process if v is not numbered yet
                if (vData[0] == VISITED_NOPREORDER)
                {
                    vData[0] = counter;
                    vData[1] = counter;
                    counter  = counter + 1;

                    // push to currentStack
                    currentStack.Push(pair);

                    // update lowlink according to successors in currentStack
                    // remove already visited successors
                    // no need to use random
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ  = successors[i];
                        string    w     = succ.GetCompressedState();
                        int[]     wData = dfsData[w];

                        if (wData[0] >= 0)
                        {
                            // update & remove from expendedNodes(v)
                            vData[1] = Math.Min(vData[1], wData[0]);
                            successors.RemoveAt(i);
                        }
                    }
                }

                // check if there is any successor not numbered
                bool completed = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ  = successors[i];
                    string    w     = succ.GetCompressedState();
                    int[]     wData = dfsData[w];
                    if (wData[0] == VISITED_NOPREORDER)
                    {
                        callStack.Push(succ);
                        successors.RemoveAt(i);
                        completed = false;
                        break;
                    }
                    else
                    {
                        successors.RemoveAt(i);
                    }
                }

                // if all successors are visited
                if (completed)
                {
                    // check root
                    if (vData[0] == vData[1])
                    {
                        //pop callStack
                        callStack.Pop();

                        Dictionary <string, LocalPair> newSCC = new Dictionary <string, LocalPair>(1024);

                        // check selfLoop
                        bool selfLoop = false;
                        foreach (string w in outgoing)
                        {
                            if (v.Equals(w))
                            {
                                selfLoop = true;
                                break;
                            }
                        }

                        // get all states in a SCC & check Buchi fair
                        bool      isBuchiFair = false;
                        LocalPair tmp         = null;
                        string    tmpID       = null;
                        // get from current until v
                        do
                        {
                            tmp         = currentStack.Pop();
                            isBuchiFair = isBuchiFair || tmp.state.EndsWith(Constants.ACCEPT_STATE);
                            tmpID       = tmp.GetCompressedState();
                            int[] tmpData = dfsData[tmpID];
                            tmpData[0] = SCC_FOUND;
                            newSCC.Add(tmpID, tmp);
                        } while (!tmpID.Equals(v));

                        if (isBuchiFair && (selfLoop || newSCC.Count > 1 || LTSState.IsDeadLock))
                        {
                            Dictionary <string, LocalPair> fairSCC = IsFair(newSCC, outgoingTransitionTable);
                            if (fairSCC != null)
                            {
                                // get the path to accepting cycle
                                VerificationOutput.VerificationResult = VerificationResultType.INVALID;
                                VerificationOutput.NoOfStates         = dfsData.Count;
                                LocalTaskStack = callStack;
                                LocalGetCounterExample(fairSCC, outgoingTransitionTable);
                                return;
                            }
                        }
                    }
                    else
                    {
                        //pop callStack & update the parent
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsData[popID];
                        int[]     topData = dfsData[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = dfsData.Count;
        }
Пример #15
0
        /// <summary>
        /// Tarjan algorithm with farness checking
        /// </summary>
        public void FairTarjan()
        {
            VerificationOutput.CounterExampleTrace = null;

            //on-the-fly data
            Stack <LocalPair>                      callStack     = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      currentStack  = new Stack <LocalPair>(5000);
            Stack <LocalPair>                      goalStack     = new Stack <LocalPair>(1024);
            Dictionary <string, int[]>             dfsNumber     = new Dictionary <string, int[]>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(5000);
            int    number = 0;
            Random rand   = new Random();

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            //push initial states to call stack
            foreach (LocalPair tmp in initialStates)
            {
                callStack.Push(tmp);
            }

            //start loop
            while (callStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = dfsNumber.Count;
                    return;
                }

                //get top of call stack
                LocalPair         pair     = callStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (expendedNodes.ContainsKey(v))
                {
                    successors = expendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, successors);
                }

                //if v is not number yet
                if (!dfsNumber.ContainsKey(v))
                {
                    //number v
                    int[] vData = new int[] { number, number };
                    dfsNumber.Add(v, vData);
                    number = number + 1;

                    //push to currentStack
                    currentStack.Push(pair);

                    //update lowlink for already numbered successors
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        //if w is already numbered
                        if (dfsNumber.ContainsKey(w))
                        {
                            int[] wData = dfsNumber[w];

                            //if w is in current stack
                            if (wData[0] >= 0)
                            {
                                vData[1] = Math.Min(vData[1], wData[0]);
                            }
                        }
                    }
                }

                //------------------------------------------------------------------------
                //check if there is an unnumbered successor
                List <int> unvisitedIndexs = new List <int>(successors.Count);//not visited
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is not already numbered
                    if (!dfsNumber.ContainsKey(w))
                    {
                        unvisitedIndexs.Add(i);
                    }
                }
                //------------------------------------------------------------------------

                //get random unvisited successors
                if (unvisitedIndexs.Count > 0)
                {
                    int       r    = rand.Next(unvisitedIndexs.Count);
                    LocalPair succ = successors[unvisitedIndexs[r]];
                    callStack.Push(succ);
                }
                else
                {
                    int[] vData = dfsNumber[v];
                    //if v is root
                    if (vData[0] == vData[1])
                    {
                        // check selfLoop
                        bool selfLoop = false;
                        foreach (LocalPair succ in successors)
                        {
                            string w = succ.GetCompressedState();
                            if (v.Equals(w))
                            {
                                selfLoop = true;
                                break;
                            }
                        }

                        //remove states from current stack and goal stack
                        Dictionary <string, LocalPair> newSCC = new Dictionary <string, LocalPair>(1024);
                        List <ConfigurationBase>       cycle  = new List <ConfigurationBase>(1024);
                        bool      isBuchiFair = false;
                        LocalPair tmp         = null;
                        string    tmpID       = null;
                        do
                        {
                            //current stack
                            tmp = currentStack.Pop();
                            if (!isBuchiFair && tmp.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                isBuchiFair = true;
                            }
                            tmpID = tmp.GetCompressedState();
                            newSCC.Add(tmpID, tmp);
                            cycle.Insert(0, tmp.configuration);

                            //mark visited
                            dfsNumber[tmpID][0] = SCC_FOUND;
                        } while (tmp != pair);

                        //check fairness
                        if (isBuchiFair && (selfLoop || newSCC.Count > 1 || LTSState.IsDeadLock))
                        {
                            //get outgoing transition table
                            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(newSCC.Count);
                            foreach (KeyValuePair <string, LocalPair> kv in newSCC)
                            {
                                string           s          = kv.Key;
                                List <LocalPair> nextStates = expendedNodes[s];
                                List <string>    outgoing   = new List <string>(nextStates.Count);
                                foreach (LocalPair next in nextStates)
                                {
                                    string n = next.GetCompressedState();
                                    outgoing.Add(n);
                                }
                                outgoingTransitionTable.Add(s, outgoing);
                            }

                            Dictionary <string, LocalPair> fairSCC = IsFair(newSCC, outgoingTransitionTable);

                            if (fairSCC != null)
                            {
                                //REPORT COUNTEREXAMPLE
                                GetFairCounterExample(callStack, cycle, dfsNumber, LTSState.IsDeadLock);
                                return;
                            }
                        }

                        //pop call stack
                        callStack.Pop();
                    }
                    else
                    {
                        //pop call stack and update lowlink of top
                        LocalPair pop     = callStack.Pop();
                        LocalPair top     = callStack.Peek();
                        string    popID   = pop.GetCompressedState();
                        string    topID   = top.GetCompressedState();
                        int[]     popData = dfsNumber[popID];
                        int[]     topData = dfsNumber[topID];
                        topData[1] = Math.Min(topData[1], popData[1]);
                    }
                }
            }

            //no counter example
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = dfsNumber.Count;
            return;
        }
        /// <summary>
        /// The function of each worker in MultiCore Tarjan Model Checking
        /// </summary>
        /// <returns></returns>
        public void MultiCoreWithSharedMemoryTarjanModelCheckingWorker()
        {
            Dictionary <string, List <string> > OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair> TaskStack = new Stack <LocalPair>(5000);

            List <LocalPair>           initials = LocalPair.GetInitialPairsLocal(BA, InitialStep);
            Dictionary <string, int[]> DFSData  = new Dictionary <string, int[]>(5000);

            if (initials.Count == 0)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            int threadId;
            // Create random variable with different seed for each thread
            Random rand; // helps different threads access different region of the graph

            lock (MultiCoreLock)
            {
                threadId = MultiCoreSeed;
                rand     = new Random(MultiCoreSeed);
                MultiCoreSeed++;
            }

            // Create the list of initial states
            // May apply randomness here to increase performance
            int[] permutation = generatePermutation(initials.Count, rand);

            for (int z = 0; z < initials.Count; z++)
            {
                LocalPair initState = initials[permutation[z]];
                TaskStack.Push(initState);
                string ID = initState.GetCompressedState();
                DFSData.Add(ID, new int[] { VISITED_NOPREORDER, 0 });
                OutgoingTransitionTable.Add(ID, new List <string>(8));
            }

            Dictionary <string, LocalPair> SCCPairs = new Dictionary <string, LocalPair>(1024);
            Stack <LocalPair> stepStack             = new Stack <LocalPair>(1024);

            // Preorder counter
            int i       = 0;
            int numSCCs = 0;

            //store the expended event step of a node to avoid multiple invocation of the make one move.
            Dictionary <string, List <LocalPair> > ExpendedNode = new Dictionary <string, List <LocalPair> >(1024);

            do
            {
                if (CancelRequested || StopMutliCoreThreads)
                {
                    return;
                }

                LocalPair         pair    = TaskStack.Peek();
                ConfigurationBase evt     = pair.configuration;
                string            BAState = pair.state;

                string v = pair.GetCompressedState();

                List <string> outgoing = OutgoingTransitionTable[v];
                int[]         nodeData = DFSData[v];

                if (nodeData[0] == VISITED_NOPREORDER)
                {
                    nodeData[0] = i;
                    i++;
                }

                bool done = true;

                // Initialize the states if first time visited
                if (!ExpendedNode.ContainsKey(v))
                {
                    List <LocalPair> product;
                    //lock (MultiCoreLock)
                    //{
                    ConfigurationBase[] configList = evt.MakeOneMove();
                    pair.SetEnabled(configList, FairnessType);
                    product = LocalPair.NextLocal(BA, configList, BAState);

                    int[]            randomPermutation = generatePermutation(product.Count, rand);
                    List <LocalPair> randomProduct     = new List <LocalPair>();
                    for (int k = 0; k < product.Count; k++)
                    {
                        randomProduct.Add(product[randomPermutation[k]]);
                    }

                    ExpendedNode.Add(v, randomProduct);
                    //}

                    for (int k = product.Count - 1; k >= 0; k--)
                    {
                        LocalPair step = product[k];
                        string    tmp  = step.GetCompressedState();
                        //update the incoming and outgoing edges
                        outgoing.Add(tmp);
                        if (!DFSData.ContainsKey(tmp))
                        {
                            DFSData.Add(tmp, new int[] { VISITED_NOPREORDER, 0 });
                            OutgoingTransitionTable.Add(tmp, new List <string>(8));
                        }
                    }
                }

                List <LocalPair> list = ExpendedNode[v];

                //transverse all neighbour nodes
                for (int k = list.Count - 1; k >= 0; k--)
                {
                    //int randIndex = rand.Next(list.Count);
                    int       randIndex        = k;
                    LocalPair step             = list[randIndex];
                    string    tmp              = step.GetCompressedState();
                    int[]     neighbourDFSData = DFSData[tmp];

                    //if the step is a unvisited step
                    if (neighbourDFSData[0] == VISITED_NOPREORDER && !SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(tmp))
                    {
                        if (done)
                        {
                            TaskStack.Push(step);
                            done = false;
                            list.RemoveAt(randIndex);
                            break;
                        }
                    }
                    else
                    {
                        list.RemoveAt(randIndex);
                    }
                }

                if (done)
                {
                    TaskStack.Pop();

                    int lowlinkV  = nodeData[0];
                    int preorderV = lowlinkV;

                    bool selfLoop = false;
                    for (int j = 0; j < outgoing.Count; j++)
                    {
                        string w = outgoing[j];
                        if (w == v)
                        {
                            selfLoop = true;
                        }

                        int[] wdata = DFSData[w];
                        if (wdata[0] != SCC_FOUND && !SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(w))
                        {
                            if (wdata[0] > preorderV)
                            {
                                lowlinkV = Math.Min(lowlinkV, wdata[1]);
                            }
                            else
                            {
                                lowlinkV = Math.Min(lowlinkV, wdata[0]);
                            }
                        }
                    }

                    nodeData[1] = lowlinkV;

                    if (lowlinkV == preorderV)
                    {
                        bool stopCheckSCC = false;

                        SCCPairs.Add(v, pair);
                        nodeData[0] = SCC_FOUND;
                        //if (!SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(v))
                        //{
                        lock (MultiCoreLock)
                        {
                            if (!SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(v))
                            {
                                numSCCs++;
                                SharedSCCFoundStatesMultiCoreTarjan.Add(v, true);
                            }
                            else
                            {
                                stopCheckSCC = true;
                            }
                        }
                        //}
                        //else
                        //{
                        //    stopCheckSCC = true;
                        //}

                        //checking for buchi-fair
                        bool BuchiFair = pair.state.EndsWith(Constants.ACCEPT_STATE);

                        while (stepStack.Count > 0 && DFSData[stepStack.Peek().GetCompressedState()][0] > preorderV)
                        {
                            LocalPair stepStackNode   = stepStack.Pop();
                            string    stepStackNodeID = stepStackNode.GetCompressedState();
                            DFSData[stepStackNodeID][0] = SCC_FOUND;


                            if (!stopCheckSCC)
                            {
                                SCCPairs.Add(stepStackNodeID, stepStackNode);

                                //if (!SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(stepStackNodeID))
                                //{
                                lock (MultiCoreLock)
                                {
                                    if (!SharedSCCFoundStatesMultiCoreTarjan.ContainsKey(stepStackNodeID))
                                    {
                                        SharedSCCFoundStatesMultiCoreTarjan.Add(stepStackNodeID, true);
                                    }
                                }
                                //}

                                if (!BuchiFair && stepStackNode.state.EndsWith(Constants.ACCEPT_STATE))
                                {
                                    BuchiFair = true;
                                }
                            }
                            else
                            {
                                ExpendedNode.Remove(stepStackNodeID);
                                OutgoingTransitionTable.Remove(stepStackNodeID);
                            }
                        }

                        int SCCSize = SCCPairs.Count;

                        if (!stopCheckSCC && BuchiFair && (evt.IsDeadLock || SCCSize > 1 || selfLoop))
                        {
                            Dictionary <string, LocalPair> value = IsFair(SCCPairs, OutgoingTransitionTable);
                            if (value != null)
                            {
                                lock (MultiCoreLock)
                                {
                                    StopMutliCoreThreads             = true;
                                    MultiCoreResultedLoop            = value;
                                    MultiCoreOutgoingTransitionTable = OutgoingTransitionTable;
                                    MultiCoreLocalTaskStack          = TaskStack;
                                }
                                return;
                            }
                        }

                        // Avoid access to found SCCs
                        foreach (string componet in SCCPairs.Keys)
                        {
                            ExpendedNode.Remove(componet);
                            OutgoingTransitionTable.Remove(componet);
                        }

                        //StronglyConnectedComponets.Clear();
                        SCCPairs.Clear();
                    }
                    else
                    {
                        stepStack.Push(pair);
                    }
                }
            } while (TaskStack.Count > 0);

            //Console.WriteLine("Thread {0} has traversed {1} SCCs", threadId, numSCCs);
        }
Пример #17
0
        /// <summary>
        /// Local blue DFS in each thread
        /// </summary>
        /// <param name="o"></param>
        public void LocalBlueSwarm(object o)
        {
            //order of this thread
            int    order = (int)o;
            Random rand  = new Random(order);

            //on-the-fly data
            Stack <LocalPair>                      localBlueStack     = new Stack <LocalPair>(5000);
            Dictionary <string, Color>             localDFSColor      = new Dictionary <string, Color>(5000);
            Dictionary <string, List <LocalPair> > localExpendedNodes = new Dictionary <string, List <LocalPair> >(5000);

            //initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            //check valid result
            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                return;
            }

            //push local initial states to local blue stack
            int[] localPerm = Permutation(initialStates.Count, rand);
            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[localPerm[i]];
                localBlueStack.Push(tmp);
            }

            //start loop
            while (localBlueStack.Count > 0)
            {
                //cancel if take long time
                if (CancelRequested || isGlobalStop)
                {
                    return;
                }

                //get top of blue stack
                LocalPair         pair     = localBlueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                //get successors
                List <LocalPair> successors = null;
                if (localExpendedNodes.ContainsKey(v))
                {
                    successors = localExpendedNodes[v];
                }
                else
                {
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    successors = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    localExpendedNodes.Add(v, successors);
                }

                //if v is white
                if (!localDFSColor.ContainsKey(v))
                {
                    //set v cyan
                    Color vColor = new Color();
                    vColor.setCyan();
                    localDFSColor.Add(v, vColor);

                    //early cycle detection
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ = successors[i];
                        string    w    = succ.GetCompressedState();

                        //if w is cyan and (v or w is accepting)
                        if (localDFSColor.ContainsKey(w))
                        {
                            Color wColor = localDFSColor[w];
                            if (wColor.isCyan() && (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE)))
                            {
                                //REPORT COUNTEREXAMPLE
                                GetLocalLoopCounterExample(w, localBlueStack);
                                return;
                            }
                        }
                    }
                }

                //------------------------------------------------------------------------
                //filter successors
                List <int> unvisitedIndexs = new List <int>(successors.Count);
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();

                    //if w is white and not global red
                    if (!localDFSColor.ContainsKey(w))
                    {
                        unvisitedIndexs.Add(i);
                    }
                }
                //------------------------------------------------------------------------

                //get random unvisited successors
                if (unvisitedIndexs.Count > 0)
                {
                    bool       isFresh       = false;
                    List <int> unFreshIndexs = new List <int>();
                    while (unvisitedIndexs.Count > 0)
                    {
                        int       r    = rand.Next(unvisitedIndexs.Count);
                        LocalPair succ = successors[unvisitedIndexs[r]];
                        string    w    = succ.GetCompressedState();

                        //if w is fresh successor
                        if (!allVisitedStates.ContainsKey(w))
                        {
                            localBlueStack.Push(succ);

                            allVisitedStates.GetOrAdd(w, 0);
                            allVisitedStates[w]++;

                            isFresh = true;
                            break;
                        }
                        else
                        {
                            unFreshIndexs.Add(unvisitedIndexs[r]);
                            unvisitedIndexs.RemoveAt(r);
                        }
                    }
                    if (!isFresh)
                    {
                        int       r    = rand.Next(unFreshIndexs.Count);
                        LocalPair succ = successors[unFreshIndexs[r]];
                        string    w    = succ.GetCompressedState();
                        localBlueStack.Push(succ);

                        allVisitedStates.GetOrAdd(w, 0);
                        allVisitedStates[w]++;
                    }
                }
                else
                {
                    Color vColor = localDFSColor[v];

                    //if v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        //if v is deadlock
                        if (LTSState.IsDeadLock)
                        {
                            //REPORT COUNTEREXAMPLE
                            GetLocalDeadlockCounterExample(localBlueStack);
                            return;
                        }
                        else
                        {
                            bool isStop = LocalRedSwarm(pair, localBlueStack, localDFSColor, rand, localExpendedNodes);
                            if (isStop)
                            {
                                return;
                            }
                        }

                        //set v pink
                        vColor.setPink();
                    }
                    else
                    {
                        vColor.setBlue();
                    }

                    //pop v out of blueStack
                    localBlueStack.Pop();
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Improved Nested DFS
        /// A Note on On-The-Fly Verification Algorithms - TACAS 2005
        /// Stefan Schwoon and Javier Esparza
        /// </summary>
        public void ImprovedNestedDFS()
        {
            // data for on-the-fly Nested DFS
            Dictionary <string, List <string> > outgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE);
            Stack <LocalPair>                      blueStack            = new Stack <LocalPair>(5000);
            Dictionary <string, Color>             colorData            = new Dictionary <string, Color>(5000);
            Dictionary <string, List <LocalPair> > expendedNodes        = new Dictionary <string, List <LocalPair> >(1024);

            // create initial states
            List <LocalPair> initialStates = LocalPair.GetInitialPairsLocal(BA, InitialStep);

            if (initialStates.Count == 0 || !BA.HasAcceptState)
            {
                VerificationOutput.VerificationResult = VerificationResultType.VALID;
                return;
            }

            // test
            //expendedNodesNumber = 0;

            for (int i = 0; i < initialStates.Count; i++)
            {
                LocalPair tmp = initialStates[i];
                blueStack.Push(tmp);
                string ID = tmp.GetCompressedState();
                colorData.Add(ID, new Color());
                outgoingTransitionTable.Add(ID, new List <string>(8));
            }

            while (blueStack.Count > 0)
            {
                // cancel if too long action or couterexample reported
                if (CancelRequested)
                {
                    VerificationOutput.NoOfStates = colorData.Count;
                    return;
                }

                // get the top of blueStack
                LocalPair         pair     = blueStack.Peek();
                ConfigurationBase LTSState = pair.configuration;
                string            BAState  = pair.state;
                string            v        = pair.GetCompressedState();

                // local data of the top
                List <string> outgoing = outgoingTransitionTable[v];
                Color         vColor   = colorData[v];

                // if v is not expended then expend successors of v
                if (!expendedNodes.ContainsKey(v))
                {
                    // create next states from v & add to expendedNodes
                    IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove();
                    pair.SetEnabled(nextLTSStates, FairnessType);
                    List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState);
                    expendedNodes.Add(v, nextStates);

                    // increase number of states expended
                    //expendedNodesNumber++;

                    // update outgoing of v and set initial data for successors
                    // no need to use inverse for statement and use nextStates
                    foreach (LocalPair next in nextStates)
                    {
                        string w = next.GetCompressedState();
                        outgoing.Add(w);
                        if (!colorData.ContainsKey(w))
                        {
                            colorData.Add(w, new Color());
                            outgoingTransitionTable.Add(w, new List <string>(8));
                        }
                    }
                }

                // get successor of v
                List <LocalPair> successors = expendedNodes[v];

                // visit v & early accepting cycle detection
                if (vColor.isWhite())
                {
                    vColor.setCyan();

                    // early cycle detection
                    // use reverse order to remove visited states
                    for (int i = successors.Count - 1; i >= 0; i--)
                    {
                        LocalPair succ   = successors[i];
                        string    w      = succ.GetCompressedState();
                        Color     wColor = colorData[w];
                        // if successor is not white then remove from expendedNodes
                        if (wColor.isCyan())
                        {
                            if (succ.state.EndsWith(Constants.ACCEPT_STATE) || pair.state.EndsWith(Constants.ACCEPT_STATE))
                            {
                                blueReportAcceptinCycle(succ, blueStack, colorData, outgoingTransitionTable);
                                return;
                            }
                            else
                            {
                                successors.RemoveAt(i);
                            }
                        }
                    }
                }

                // find unvisited successor
                bool blueDone = true;
                for (int i = successors.Count - 1; i >= 0; i--)
                {
                    LocalPair succ = successors[i];
                    string    w    = succ.GetCompressedState();
                    if (colorData[w].isWhite())
                    {
                        blueStack.Push(succ);
                        successors.RemoveAt(i);
                        blueDone = false;
                        break;
                    }
                    else
                    {
                        successors.RemoveAt(i);
                    }
                }

                // if there is no unvisited successor
                if (blueDone)
                {
                    // if v is accepting
                    if (pair.state.EndsWith(Constants.ACCEPT_STATE))
                    {
                        if (LTSState.IsDeadLock)
                        {
                            blueReportAcceptinCycle(pair, blueStack, colorData, outgoingTransitionTable);
                            return;
                        }
                        else // start red DFS
                        {
                            bool stop = redDFSImprovedNestedDFS(pair, blueStack, colorData, outgoingTransitionTable);
                            if (stop)
                            {
                                return;
                            }
                        }

                        // SET PINK FOR ACCEPTING STATE
                        vColor.setPink();
                    }
                    else // v is not accepting
                    {
                        vColor.setBlue();
                    }

                    // pop blueStack
                    blueStack.Pop();
                }
            }

            // report no couterexample
            VerificationOutput.VerificationResult = VerificationResultType.VALID;
            VerificationOutput.NoOfStates         = colorData.Count;
            return;
        }