// Report cycle detected at blue DFS public void SwarmNestedDFSReportBlueCycle(LocalPair step, LocalPair pair, Stack <LocalPair> BlueStack, Dictionary <string, StateColor> colorData, Dictionary <string, List <string> > OutgoingTransitionTable) { lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>(1024); string tmp = step.GetCompressedState(); string m = pair.GetCompressedState(); LocalPair node = BlueStack.Pop(); string nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); MultiCoreLocalTaskStack = BlueStack; MultiCoreResultedLoop = LoopPairs; MultiCoreOutgoingTransitionTable = OutgoingTransitionTable; } }
// report accepting cycle detected in blue DFS public void localBlueReportAcceptinCycle(LocalPair succ, Stack <LocalPair> blueStack, Dictionary <string, List <string> > outgoingTransitionTable) { lock (reportLocker) { if (isStop) { return; } Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); // get accepting cycle LocalPair tmp = blueStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { acceptingCycle.Add(tmpID, tmp); tmp = blueStack.Pop(); tmpID = tmp.GetCompressedState(); } acceptingCycle.Add(tmpID, tmp); // get final result finalLocalTaskStack = blueStack; finalAcceptingCycle = acceptingCycle; finalOutgoingTransitionTable = outgoingTransitionTable; isStop = true; } }
private void localImprovedTarjanGeldenhuysValmariReport_DotNet4(LocalPair succ, Stack <LocalPair> callStack, Dictionary <string, List <string> > outgoingTransitionTable) { //set flag to stop other thread lock (reportLocker) { if (isStop) { return; } Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); //get states in the cycle LocalPair tmp = callStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { acceptingCycle.Add(tmpID, tmp); tmp = callStack.Pop(); tmpID = tmp.GetCompressedState(); } acceptingCycle.Add(tmpID, tmp); //return the result for global multi-core finalLocalTaskStack = callStack; finalAcceptingCycle = acceptingCycle; finalOutgoingTransitionTable = outgoingTransitionTable; isStop = true; } }
private void localReportAcceptingCycle(LocalPair succ, Stack <LocalPair> callStack, StringDictionary <int[]> dfsData, Dictionary <string, List <string> > outgoingTransitionTable) { //set flag to stop other processes lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary <string, LocalPair> localAcceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); //get states in the cycle LocalPair tmp = callStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { localAcceptingCycle.Add(tmpID, tmp); tmp = callStack.Pop(); tmpID = tmp.GetCompressedState(); } localAcceptingCycle.Add(tmpID, tmp); //return the result for global multi-core MultiCoreLocalTaskStack = callStack; MultiCoreResultedLoop = localAcceptingCycle; MultiCoreOutgoingTransitionTable = outgoingTransitionTable; } }
// Report accepting cycle in red DFS private void redReportAcceptinCycle(LocalPair succ, Stack <LocalPair> blueStack, Stack <LocalPair> redStack, Dictionary <string, Color> colorData, Dictionary <string, List <string> > outgoingTransitionTable) { Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); // get from redStack while (redStack.Count > 0) { LocalPair tmpRed = redStack.Pop(); string tmpRedID = tmpRed.GetCompressedState(); acceptingCycle.Add(tmpRedID, tmpRed); } // pop the top of blueStack LocalPair topBlueStack = blueStack.Pop(); string topBlueStackID = topBlueStack.GetCompressedState(); if (!topBlueStackID.Equals(to)) { LocalPair tmpBlue = blueStack.Pop(); string tmpBlueID = tmpBlue.GetCompressedState(); while (!tmpBlueID.Equals(to)) { acceptingCycle.Add(tmpBlueID, tmpBlue); tmpBlue = blueStack.Pop(); tmpBlueID = tmpBlue.GetCompressedState(); } acceptingCycle.Add(tmpBlueID, tmpBlue); } VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = colorData.Count; LocalTaskStack = blueStack; LocalGetCounterExample(acceptingCycle, outgoingTransitionTable); }
/// <summary> /// Get counter example in case of loop in blue DFS /// </summary> /// <param name="s"></param> /// <param name="blueStack"></param> /// <param name="dfsColor"></param> public void GetLoopCounterExample(string s, Stack <LocalPair> blueStack, Dictionary <string, Color> dfsColor) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = dfsColor.Count; int traceLen = blueStack.Count; List <ConfigurationBase> trace = new List <ConfigurationBase>(traceLen); int count = 0; int reverseIndex = -1; while (blueStack.Count > 0) { LocalPair tmp = blueStack.Pop(); trace.Insert(0, tmp.configuration); string tmpID = tmp.GetCompressedState(); if (s.Equals(tmpID)) { reverseIndex = count; } count++; if (tmp.configuration.Event == Constants.INITIAL_EVENT) { break; } } VerificationOutput.CounterExampleTrace = trace; VerificationOutput.LoopIndex = count - 1 - reverseIndex; }
/// <summary> /// Get local counter example in case of deadlock in blue DFS /// </summary> /// <param name="localBlueStack"></param> public void GetLocalDeadlockCounterExample(Stack <LocalPair> localBlueStack) { int traceLen = localBlueStack.Count; List <ConfigurationBase> trace = new List <ConfigurationBase>(traceLen); int count = 0; while (localBlueStack.Count > 0) { LocalPair tmp = localBlueStack.Pop(); trace.Insert(0, tmp.configuration); string tmpID = tmp.GetCompressedState(); count++; if (tmp.configuration.Event == Constants.INITIAL_EVENT) { break; } } //get global counter example and stop lock (globalCounterExampleLocker) { if (isGlobalStop) { return; } finalTrace = trace; isGlobalStop = true; } }
// Report cycle detected at red DFS public void localRedReportAcceptinCycle(LocalPair succ, Stack <LocalPair> blueStack, Stack <LocalPair> redStack, Dictionary <string, List <string> > outgoingTransitionTable) { lock (reportLocker) { if (isStop) { return; } Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); // get from redStack while (redStack.Count > 0) { LocalPair tmpRed = redStack.Pop(); string tmpRedID = tmpRed.GetCompressedState(); acceptingCycle.Add(tmpRedID, tmpRed); } // pop the top of blueStack LocalPair topBlueStack = blueStack.Pop(); string topBlueStackID = topBlueStack.GetCompressedState(); if (!topBlueStackID.Equals(to)) { LocalPair tmpBlue = blueStack.Pop(); string tmpBlueID = tmpBlue.GetCompressedState(); while (!tmpBlueID.Equals(to)) { acceptingCycle.Add(tmpBlueID, tmpBlue); tmpBlue = blueStack.Pop(); tmpBlueID = tmpBlue.GetCompressedState(); } acceptingCycle.Add(tmpBlueID, tmpBlue); } // get final result finalLocalTaskStack = blueStack; finalAcceptingCycle = acceptingCycle; finalOutgoingTransitionTable = outgoingTransitionTable; isStop = true; } }
// Report accepting cycle in blue DFS private void blueReportAcceptinCycle(LocalPair succ, Stack <LocalPair> blueStack, Dictionary <string, Color> colorData, Dictionary <string, List <string> > outgoingTransitionTable) { Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); string to = succ.GetCompressedState(); // get accepting cycle LocalPair tmp = blueStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { acceptingCycle.Add(tmpID, tmp); tmp = blueStack.Pop(); tmpID = tmp.GetCompressedState(); } acceptingCycle.Add(tmpID, tmp); VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = colorData.Count; LocalTaskStack = blueStack; LocalGetCounterExample(acceptingCycle, outgoingTransitionTable); }
// Report cycle detected at red DFS public void SwarmNestedDFSReportRedCycle(LocalPair s, LocalPair step, LocalPair pair, Stack <LocalPair> BlueStack, Stack <LocalPair> RedStack, Dictionary <string, StateColor> colorData, Dictionary <string, List <string> > OutgoingTransitionTable) { lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>(1024); string tmp = step.GetCompressedState(); string v = pair.GetCompressedState(); string sID = s.GetCompressedState(); LocalPair node; string nodeID; // If s is start of the loop if (sID.Equals(tmp)) { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); } // If the start of the loop is the parent of s else { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); } MultiCoreLocalTaskStack = BlueStack; MultiCoreResultedLoop = LoopPairs; MultiCoreOutgoingTransitionTable = OutgoingTransitionTable; } }
private void reportAcceptingCycle(LocalPair succ, Stack <LocalPair> callStack, Dictionary <string, int[]> dfsData, Dictionary <string, List <string> > outgoingTransitionTable) { Dictionary <string, LocalPair> acceptingCycle = new Dictionary <string, LocalPair>(1024); // string from = pair.GetCompressedState(); string to = succ.GetCompressedState(); // get states in the cycle LocalPair tmp = callStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { acceptingCycle.Add(tmpID, tmp); tmp = callStack.Pop(); tmpID = tmp.GetCompressedState(); } acceptingCycle.Add(tmpID, tmp); // get the path to accepting cycle VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = dfsData.Count; LocalTaskStack = callStack; LocalGetCounterExample(acceptingCycle, outgoingTransitionTable); }
// Report cycle detected at blue DFS public void ReportBlueCycle(LocalPair step, LocalPair pair, Stack <LocalPair> BlueStack, StringDictionary <StateColor> colorData, Dictionary <string, List <string> > OutgoingTransitionTable) { Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>(1024); string tmp = step.GetCompressedState(); string v = pair.GetCompressedState(); LocalPair node = BlueStack.Pop(); string nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = colorData.Count; LocalTaskStack = BlueStack; LocalGetCounterExample(LoopPairs, OutgoingTransitionTable); }
// Report cycle detected at red DFS public void ReportRedCycle(LocalPair s, LocalPair step, LocalPair pair, Stack <LocalPair> BlueStack, Stack <LocalPair> RedStack, StringDictionary <StateColor> colorData, Dictionary <string, List <string> > OutgoingTransitionTable) { Dictionary <string, LocalPair> LoopPairs = new Dictionary <string, LocalPair>(1024); string tmp = step.GetCompressedState(); string v = pair.GetCompressedState(); string sID = s.GetCompressedState(); LocalPair node; string nodeID; // If s is start of the loop if (sID.Equals(tmp)) { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); } // If the start of the loop is the parent of s else { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); } LocalTaskStack = BlueStack; VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = colorData.Count; LocalGetCounterExample(LoopPairs, OutgoingTransitionTable); }
/// <summary> /// Get global counter example in red DFS and stop /// </summary> /// <param name="s"></param> /// <param name="localBlueStack"></param> /// <param name="localRedStack"></param> public void GetLocalLoopCounterExample(string s, Stack <LocalPair> localBlueStack, Stack <LocalPair> localRedStack) { int traceLen = localRedStack.Count + localBlueStack.Count - 1; List <ConfigurationBase> trace = new List <ConfigurationBase>(traceLen); int count = 0; int reverseIndex = -1; //get trace from red stack while (localRedStack.Count > 1) { LocalPair tmpRed = localRedStack.Pop(); trace.Insert(0, tmpRed.configuration); count++; } //get trace from blue stack while (localBlueStack.Count > 0) { LocalPair tmpBlue = localBlueStack.Pop(); trace.Insert(0, tmpBlue.configuration); string tmpBlueID = tmpBlue.GetCompressedState(); if (s.Equals(tmpBlueID)) { reverseIndex = count; } count++; if (tmpBlue.configuration.Event == Constants.INITIAL_EVENT) { break; } } //get global counter example and stop lock (globalCounterExampleLocker) { if (isGlobalStop) { return; } finalTrace = trace; finalLoopIndex = count - 1 - reverseIndex; isGlobalStop = true; } }
/// <summary> /// Get counter example in case of deadlock /// </summary> /// <param name="callStack"></param> /// <param name="dfsData"></param> public void GetDeadlockCounterExample(Stack <LocalPair> callStack, Dictionary <string, int[]> dfsData) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = dfsData.Count; int traceLen = callStack.Count; List <ConfigurationBase> trace = new List <ConfigurationBase>(traceLen); int count = 0; while (callStack.Count > 0) { LocalPair tmp = callStack.Pop(); trace.Insert(0, tmp.configuration); string tmpID = tmp.GetCompressedState(); count++; if (tmp.configuration.Event == Constants.INITIAL_EVENT) { break; } } VerificationOutput.CounterExampleTrace = trace; }
/// <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 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]); } } } }
/// <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; } } }
/// <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]); } } } }
/// <summary> /// Local red DFS in each thread /// </summary> /// <param name="acceptingState"></param> /// <param name="localBlueStack"></param> /// <param name="localDFSColor"></param> /// <param name="rand"></param> /// <returns></returns> public bool LocalRed1(LocalPair acceptingState, Stack <LocalPair> localBlueStack, Dictionary <string, Color> localDFSColor, Random rand, Dictionary <string, List <LocalPair> > localExpendedNodes) { Stack <LocalPair> localRedStack = new Stack <LocalPair>(5000); //push accepting state to red stack localRedStack.Push(acceptingState); //start loop while (localRedStack.Count > 0) { //cancel if take long time if (CancelRequested || isGlobalStop) { return(false); } //get top of red stack LocalPair pair = localRedStack.Peek(); string v = pair.GetCompressedState(); Color vColor = localDFSColor[v]; //get successors List <LocalPair> successors = localExpendedNodes[v]; if (!vColor.isPink()) { //set v pink vColor.setPink(); //check if there is cyan successor for (int i = successors.Count - 1; i >= 0; i--) { LocalPair succ = successors[i]; string w = succ.GetCompressedState(); if (localDFSColor.ContainsKey(w) && localDFSColor[w].isCyan()) { //REPORT COUNTER EXAMPLE GetLocalLoopCounterExample(w, localBlueStack, localRedStack); return(true); } } } //------------------------------------------------------------------------ //filter successors List <int> unvisitedIndexs = new List <int>(successors.Count);//not pink and not global red 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[w].isPink() && !globalRedStates.ContainsKey(w)) { unvisitedIndexs.Add(i); } } //------------------------------------------------------------------------ //get random unvisited successors if (unvisitedIndexs.Count > 0) { int r = rand.Next(unvisitedIndexs.Count); LocalPair succ = successors[unvisitedIndexs[r]]; localRedStack.Push(succ); } else { //v is accepting if (pair.state.EndsWith(Constants.ACCEPT_STATE)) { //decrease count at v by 1 globalAcceptingCounter[v]--; //wait for count at v equal 0 while (globalAcceptingCounter[v] != 0) { ; } } //set v global red globalRedStates.GetOrAdd(v, true); // pop red stack localRedStack.Pop(); } } //cannot report counter example return(false); }
/// <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; }
// 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; }
// Perform the redDFS public bool SwarmNestedDFSDepthFirstSearchRed(LocalPair s, Stack <LocalPair> BlueStack, Dictionary <string, List <string> > OutgoingTransitionTable, Dictionary <string, StateColor> colorData) { //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> >(256); Stack <LocalPair> RedStack = new Stack <LocalPair>(5000); RedStack.Push(s); do { if (CancelRequested || StopMutliCoreThreads) { return(false); } LocalPair pair = RedStack.Peek(); string v = pair.GetCompressedState(); ConfigurationBase evt = pair.configuration; string BAState = pair.state; List <string> outgoing = OutgoingTransitionTable[v]; bool redDone = true; if (!ExpendedNode.ContainsKey(v)) { //ConfigurationBase[] list = evt.MakeOneMove().ToArray(); IEnumerable <ConfigurationBase> list = evt.MakeOneMove(); pair.SetEnabled(list, FairnessType); List <LocalPair> product = LocalPair.NextLocal(BA, list, BAState); ExpendedNode.Add(v, product); } List <LocalPair> neighbourList = ExpendedNode[v]; //transverse all neighbour nodes for (int k = neighbourList.Count - 1; k >= 0; k--) { LocalPair step = neighbourList[k]; string tmp = step.GetCompressedState(); StateColor neighbourColor = colorData[tmp]; // if the neighbour node is blue if (neighbourColor.IsBlue()) { //only add the first unvisited node //for the second or more unvisited steps, ignore at the monent if (redDone) { neighbourColor.SetRed(); RedStack.Push(step); redDone = true; neighbourList.RemoveAt(k); } } // if the neighbour is cyan // report cycle else if (neighbourColor.IsCyan()) { SwarmNestedDFSReportRedCycle(s, step, pair, BlueStack, RedStack, colorData, OutgoingTransitionTable); return(true); } else { neighbourList.RemoveAt(k); } } if (redDone) { RedStack.Pop(); } } while (RedStack.Count > 0); return(false); }
/// <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); }
// Red DFS public bool localRedDFSNestedDFSSharedRed(LocalPair acceptingState, Stack <LocalPair> blueStack, Dictionary <string, Color> colorData, Dictionary <string, List <string> > outgoingTransitionTable, Random rand) { // local data for red DFS Stack <LocalPair> redStack = new Stack <LocalPair>(5000); Dictionary <string, List <LocalPair> > expendedNodes = new Dictionary <string, List <LocalPair> >(256); // push accepting state to redStack redStack.Push(acceptingState); // start loop while (redStack.Count > 0) { // too long action or counterexample reported if (CancelRequested || isStop) { return(false); } // get the top of redStack LocalPair pair = redStack.Peek(); ConfigurationBase LTSState = pair.configuration; string BAState = pair.state; string v = pair.GetCompressedState(); // local data of v in red DFS Color vColor = colorData[v]; // expend v in red DFS if (!expendedNodes.ContainsKey(v)) { // get successors & add to expendedNodes IEnumerable <ConfigurationBase> nextLTSStates = LTSState.MakeOneMove(); pair.SetEnabled(nextLTSStates, FairnessType); List <LocalPair> nextStates = LocalPair.NextLocal(BA, nextLTSStates, BAState); expendedNodes.Add(v, nextStates); } // successors of v List <LocalPair> successors = expendedNodes[v]; if (!vColor.isPink()) { vColor.setPink(); // check accepting cycle for (int i = successors.Count - 1; i >= 0; i--) { LocalPair succ = successors[i]; string w = succ.GetCompressedState(); Color wColor = colorData[w]; if (wColor.isCyan()) { // report accepting cycle localRedReportAcceptinCycle(succ, blueStack, redStack, outgoingTransitionTable); return(true); } // remove states visited in red DFS else if (wColor.isPink()) { successors.RemoveAt(i); } } } // traverse all successors in a random order bool redDone = true; for (int i = successors.Count - 1; i >= 0; i--) { int randIndex = rand.Next(successors.Count); LocalPair succ = successors[randIndex]; string w = succ.GetCompressedState(); Color wColor = colorData[w]; // if successor is cyan then report counterexample if (!wColor.isPink() && !sharedRedStates.ContainsKey(w)) { redStack.Push(succ); successors.RemoveAt(randIndex); redDone = false; break; } else { successors.RemoveAt(randIndex); } } // backtrack if (redDone) { // if accepting state then decrease count if (pair.state.EndsWith(Constants.ACCEPT_STATE)) { // decrease count sharedAcceptingCountRedDFS[v]--; // wait for count equal 0 while (sharedAcceptingCountRedDFS[v] != 0) { ; } } // mark v globally red sharedRedStates.GetOrAdd(v, true); // pop red stack redStack.Pop(); } } // return not found counterexample return(false); }
private void localReportAcceptingCycle(LocalPair succ, Stack<LocalPair> callStack, StringDictionary<int[]> dfsData, Dictionary<string, List<string>> outgoingTransitionTable) { //set flag to stop other processes lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary<string, LocalPair> localAcceptingCycle = new Dictionary<string, LocalPair>(1024); string to = succ.GetCompressedState(); //get states in the cycle LocalPair tmp = callStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { localAcceptingCycle.Add(tmpID, tmp); tmp = callStack.Pop(); tmpID = tmp.GetCompressedState(); } localAcceptingCycle.Add(tmpID, tmp); //return the result for global multi-core MultiCoreLocalTaskStack = callStack; MultiCoreResultedLoop = localAcceptingCycle; MultiCoreOutgoingTransitionTable = outgoingTransitionTable; } }
/// <summary> /// Local red DFS in each thread /// </summary> /// <param name="acceptingState"></param> /// <param name="localBlueStack"></param> /// <param name="localDFSColor"></param> /// <param name="rand"></param> /// <returns></returns> public bool LocalRedSwarm(LocalPair acceptingState, Stack <LocalPair> localBlueStack, Dictionary <string, Color> localDFSColor, Random rand, Dictionary <string, List <LocalPair> > localExpendedNodes) { Stack <LocalPair> localRedStack = new Stack <LocalPair>(5000); //push accepting state to red stack localRedStack.Push(acceptingState); //start loop while (localRedStack.Count > 0) { //cancel if take long time if (CancelRequested || isGlobalStop) { return(false); } //get top of red stack LocalPair pair = localRedStack.Peek(); string v = pair.GetCompressedState(); //get successors List <LocalPair> successors = localExpendedNodes[v]; //check if there is cyan successor for (int i = successors.Count - 1; i >= 0; i--) { LocalPair succ = successors[i]; string w = succ.GetCompressedState(); Color wColor = localDFSColor[w]; if (wColor.isCyan()) { //REPORT COUNTEREXAMPLE GetLocalLoopCounterExample(w, localBlueStack, localRedStack); return(true); } } //find a blue 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(); Color wColor = localDFSColor[w]; if (wColor.isBlue()) { unvisitedIndexs.Add(i); } } //choose randome successor if (unvisitedIndexs.Count > 0) { int r = rand.Next(unvisitedIndexs.Count); LocalPair succ = successors[unvisitedIndexs[r]]; string w = succ.GetCompressedState(); Color wColor = localDFSColor[w]; wColor.setPink(); localRedStack.Push(succ); } else { localRedStack.Pop(); } } //cannot report counter example return(false); }
// Report cycle detected at blue DFS public void SwarmNestedDFSReportBlueCycle(LocalPair step, LocalPair pair, Stack<LocalPair> BlueStack, Dictionary<string, StateColor> colorData, Dictionary<string, List<string>> OutgoingTransitionTable) { lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary<string, LocalPair> LoopPairs = new Dictionary<string, LocalPair>(1024); string tmp = step.GetCompressedState(); string m = pair.GetCompressedState(); LocalPair node = BlueStack.Pop(); string nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); MultiCoreLocalTaskStack = BlueStack; MultiCoreResultedLoop = LoopPairs; MultiCoreOutgoingTransitionTable = OutgoingTransitionTable; } }
/// <summary> /// Red DFS /// </summary> /// <param name="acceptingState"></param> /// <param name="blueStack"></param> /// <param name="dfsColor"></param> /// <returns></returns> public bool RedDFS(LocalPair acceptingState, Stack <LocalPair> blueStack, Dictionary <string, Color> dfsColor, Dictionary <string, List <LocalPair> > expendedNodes) { Stack <LocalPair> redStack = new Stack <LocalPair>(5000); //push accepting state to red stack redStack.Push(acceptingState); //start loop while (redStack.Count > 0) { //cancel if take long time if (CancelRequested) { VerificationOutput.NoOfStates = dfsColor.Count; return(false); } //get top of red stack LocalPair pair = redStack.Peek(); string v = pair.GetCompressedState(); //get successors List <LocalPair> successors = expendedNodes[v]; //check if there is cyan successor for (int i = successors.Count - 1; i >= 0; i--) { LocalPair succ = successors[i]; string w = succ.GetCompressedState(); Color wColor = dfsColor[w]; if (wColor.isCyan()) { //REPORT COUNTEREXAMPLE GetLoopCounterExample(w, blueStack, redStack, dfsColor); return(true); } } //find a blue successor bool isRedCompleted = true; for (int i = successors.Count - 1; i >= 0; i--) { LocalPair succ = successors[i]; string w = succ.GetCompressedState(); Color wColor = dfsColor[w]; if (wColor.isBlue()) { wColor.setPink(); redStack.Push(succ); isRedCompleted = false; break; } } //all successor are pink if (isRedCompleted) { redStack.Pop(); } } return(false); }
// Report cycle detected at red DFS public void SwarmNestedDFSReportRedCycle(LocalPair s, LocalPair step, LocalPair pair, Stack<LocalPair> BlueStack, Stack<LocalPair> RedStack, Dictionary<string, StateColor> colorData, Dictionary<string, List<string>> OutgoingTransitionTable) { lock (MultiCoreLock) { StopMutliCoreThreads = true; Dictionary<string, LocalPair> LoopPairs = new Dictionary<string, LocalPair>(1024); string tmp = step.GetCompressedState(); string v = pair.GetCompressedState(); string sID = s.GetCompressedState(); LocalPair node; string nodeID; // If s is start of the loop if (sID.Equals(tmp)) { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); } // If the start of the loop is the parent of s else { do { node = RedStack.Pop(); nodeID = node.GetCompressedState(); LoopPairs.Add(nodeID, node); } while (RedStack.Count > 0); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); while (!nodeID.Equals(tmp)) { LoopPairs.Add(nodeID, node); node = BlueStack.Pop(); nodeID = node.GetCompressedState(); } LoopPairs.Add(nodeID, node); } MultiCoreLocalTaskStack = BlueStack; MultiCoreResultedLoop = LoopPairs; MultiCoreOutgoingTransitionTable = OutgoingTransitionTable; } }
/// <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; }
/// <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(); } } }
private void reportAcceptingCycle(LocalPair succ, Stack<LocalPair> callStack, Dictionary<string, int[]> dfsData, Dictionary<string, List<string>> outgoingTransitionTable) { Dictionary<string, LocalPair> acceptingCycle = new Dictionary<string, LocalPair>(1024); // string from = pair.GetCompressedState(); string to = succ.GetCompressedState(); // get states in the cycle LocalPair tmp = callStack.Pop(); string tmpID = tmp.GetCompressedState(); while (!tmpID.Equals(to)) { acceptingCycle.Add(tmpID, tmp); tmp = callStack.Pop(); tmpID = tmp.GetCompressedState(); } acceptingCycle.Add(tmpID, tmp); // get the path to accepting cycle VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = dfsData.Count; LocalTaskStack = callStack; LocalGetCounterExample(acceptingCycle, outgoingTransitionTable); }