/// <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> /// 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; }