public static void CheckVariableRange(string x, ExpressionValue v) { #if !OPTIMAL_FOR_EXP if (HasVariableConstraints && v is IntConstant) { int val = (v as IntConstant).Value; if (VariableLowerBound.ContainsKey(x)) { int bound = VariableLowerBound.GetContainsKey(x); if (bound > val) { throw new VariableValueOutOfRangeException("Variable " + x + "'s current value " + val + " is smaller than its lower bound " + bound); } } if (VariableUpperLowerBound.ContainsKey(x)) { int bound = VariableUpperLowerBound.GetContainsKey(x); if (val > bound) { throw new VariableValueOutOfRangeException("Variable " + x + "'s current value " + val + " is greater than its upper bound " + bound); } } } #endif }
public virtual string GetID() { if (ID == null) { StringBuilder IDBuilder = new StringBuilder(); if (Variables != null) { if (HiddenVars != null) { foreach (StringDictionaryEntryWithKey <ExpressionValue> pair in this.Variables._entries) { if (pair != null && !HiddenVars.ContainsKey(pair.Key)) { IDBuilder.Append(pair.Value.ExpressionID + "&"); } } } else { foreach (StringDictionaryEntryWithKey <ExpressionValue> pair in this.Variables._entries) { if (pair != null) { IDBuilder.Append(pair.Value.ExpressionID + "&"); } } } } if (Channels != null && Channels.Count > 0) { foreach (ChannelQueue value in Channels.Values) { IDBuilder.Append(value.GetID()); IDBuilder.Append("+"); } } ID = IDBuilder.ToString(); string newID = ValutionHashTable.GetContainsKey(ID); if (newID == null) { newID = ValutionHashTable.Count.ToString(); ValutionHashTable.Add(ID, newID); } ID = newID; } return(ID); }
/// <summary> /// Hash a given string representing a Process Expression to the length of a singple integer. /// </summary> /// <param name="key"></param> /// <returns></returns> public string InitializeProcessID(string key) { LastProcessString = key; string value = ExpressionHashTable.GetContainsKey(key); if (value != null) { return(value); } string id = ExpressionHashTable.Count.ToString(); ExpressionHashTable.Add(key, id); return(id); }
public void TarjanModelChecking() { OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE); TaskStack = new Stack <LocalPair>(Ultility.Ultility.MC_INITIAL_SIZE); DFSData = new StringDictionary <int[]>(Ultility.Ultility.MC_INITIAL_SIZE); List <LocalPair> initials = LocalPair.GetInitialPairsLocal(BA, initialStep); if (initials.Count == 0 || !BA.HasAcceptState) { VerificationResult = VerificationResultType.VALID; return; } for (int z = 0; z < initials.Count; z++) { LocalPair initState = initials[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; //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); //PrintMessage("Start to find the Strongly Connected Component of graph."); do { if (SearchedDepth < TaskStack.Count) { SearchedDepth = TaskStack.Count; } if (JobFinished) { 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.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]; string tmp = step.GetCompressedState(); //if the step is a unvisited step if (DFSData.GetContainsKey(tmp)[0] == VISITED_NOPREORDER) { //only add the first unvisited step //for the second or more unvisited steps, ignore at the monent if (done) { TaskStack.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 Transitions += product.Count; for (int k = product.Count - 1; k >= 0; k--) { LocalPair step = product[k]; string tmp = step.GetCompressedState(); //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) { TaskStack.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) { TaskStack.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]; int preorderV = lowlinkV; bool selfLoop = false; // Calculate the low link of an explored state 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; TaskStack.Pop(); // Check whether the current state is the root of the SCC if (lowlinkV == preorderV) { SCCPairs.Add(v, pair); nodeData[0] = SCC_FOUND; bool BuchiFair = pair.state.EndsWith(Constants.ACCEPT_STATE); //for buchi-fair // Get the elements of the SCC from the step stack while (stepStack.Count > 0 && DFSData.GetContainsKey(stepStack.Peek().GetCompressedState())[0] > preorderV) { LocalPair s = stepStack.Pop(); string k = s.GetCompressedState(); SCCPairs.Add(k, s); DFSData.GetContainsKey(k)[0] = SCC_FOUND; if (!BuchiFair && s.state.EndsWith(Constants.ACCEPT_STATE)) { BuchiFair = true; } } //outgoing.Count == 0 --> deadlock, we need to check //outgoing.Count == 0 //StronglyConnectedComponets.Count > 1 || selfLoop -> non-trivial case, we need to check int SCCSize = SCCPairs.Count; if (BuchiFair && (evt.IsDeadLock || SCCSize > 1 || selfLoop)) { //SCCCount++; SCCTotalSize += SCCSize; //System.Diagnostics.Debug.WriteLine(size); // If forking condition is met, create new thread to process the SCC if (SCCSize >= SCC_MINIMUM_SIZE_BOUND_FOR_THREAD_FORKING && ThreadPool.ThreadNumber < Ultility.Ultility.PARALLEL_MODEL_CHECKIMG_BOUND) { //System.Diagnostics.Debug.WriteLine("fork"); //BigSCCCount++; Dictionary <string, LocalPair> SCC = new Dictionary <string, LocalPair>(SCCPairs); StartFairThread(SCC); //System.Diagnostics.Debug.WriteLine("(" + ThreadPool.ThreadNumber + ")"); } // If the size of scc is small or the thread pool is full, // process the SCC locally is more efficient else { //System.Diagnostics.Debug.WriteLine("self"); Dictionary <string, LocalPair> value = IsFair(SCCPairs, OutgoingTransitionTable); if (value != null) { JobFinished = true; VerificationResult = VerificationResultType.INVALID; FairSCC = value; ThreadPool.StopAllThreads(); return; } } } foreach (string componet in SCCPairs.Keys) { ExpendedNode.Remove(componet); //BuchiFairTable.Remove(componet.ToString()); //OutgoingTransitionTable.Remove(componet); } SCCPairs = new Dictionary <string, LocalPair>(1024); } else { stepStack.Push(pair); } } } while (TaskStack.Count > 0); JobFinished = true; 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]); } } } }
public void TarjanModelChecking() { OutgoingTransitionTable = new Dictionary<string, List<string>>(Ultility.Ultility.MC_INITIAL_SIZE); TaskStack = new Stack<LocalPair>(Ultility.Ultility.MC_INITIAL_SIZE); DFSData = new StringDictionary<int[]>(Ultility.Ultility.MC_INITIAL_SIZE); List<LocalPair> initials = LocalPair.GetInitialPairsLocal(BA, initialStep); if (initials.Count == 0 || !BA.HasAcceptState) { VerificationResult = VerificationResultType.VALID; return; } for (int z = 0; z < initials.Count; z++) { LocalPair initState = initials[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; //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); //PrintMessage("Start to find the Strongly Connected Component of graph."); do { if (SearchedDepth < TaskStack.Count) { SearchedDepth = TaskStack.Count; } if (JobFinished) { 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.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]; string tmp = step.GetCompressedState(); //if the step is a unvisited step if (DFSData.GetContainsKey(tmp)[0] == VISITED_NOPREORDER) { //only add the first unvisited step //for the second or more unvisited steps, ignore at the monent if (done) { TaskStack.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 Transitions += product.Count; for (int k = product.Count - 1; k >= 0; k--) { LocalPair step = product[k]; string tmp = step.GetCompressedState(); //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) { TaskStack.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) { TaskStack.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]; int preorderV = lowlinkV; bool selfLoop = false; // Calculate the low link of an explored state 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; TaskStack.Pop(); // Check whether the current state is the root of the SCC if (lowlinkV == preorderV) { SCCPairs.Add(v, pair); nodeData[0] = SCC_FOUND; bool BuchiFair = pair.state.EndsWith(Constants.ACCEPT_STATE); //for buchi-fair // Get the elements of the SCC from the step stack while (stepStack.Count > 0 && DFSData.GetContainsKey(stepStack.Peek().GetCompressedState())[0] > preorderV) { LocalPair s = stepStack.Pop(); string k = s.GetCompressedState(); SCCPairs.Add(k, s); DFSData.GetContainsKey(k)[0] = SCC_FOUND; if (!BuchiFair && s.state.EndsWith(Constants.ACCEPT_STATE)) { BuchiFair = true; } } //outgoing.Count == 0 --> deadlock, we need to check //outgoing.Count == 0 //StronglyConnectedComponets.Count > 1 || selfLoop -> non-trivial case, we need to check int SCCSize = SCCPairs.Count; if (BuchiFair && (evt.IsDeadLock || SCCSize > 1 || selfLoop)) { //SCCCount++; SCCTotalSize += SCCSize; //System.Diagnostics.Debug.WriteLine(size); // If forking condition is met, create new thread to process the SCC if (SCCSize >= SCC_MINIMUM_SIZE_BOUND_FOR_THREAD_FORKING && ThreadPool.ThreadNumber < Ultility.Ultility.PARALLEL_MODEL_CHECKIMG_BOUND) { //System.Diagnostics.Debug.WriteLine("fork"); //BigSCCCount++; Dictionary<string, LocalPair> SCC = new Dictionary<string, LocalPair>(SCCPairs); StartFairThread(SCC); //System.Diagnostics.Debug.WriteLine("(" + ThreadPool.ThreadNumber + ")"); } // If the size of scc is small or the thread pool is full, // process the SCC locally is more efficient else { //System.Diagnostics.Debug.WriteLine("self"); Dictionary<string, LocalPair> value = IsFair(SCCPairs, OutgoingTransitionTable); if(value != null) { JobFinished = true; VerificationResult = VerificationResultType.INVALID; FairSCC = value; ThreadPool.StopAllThreads(); return; } } } foreach (string componet in SCCPairs.Keys) { ExpendedNode.Remove(componet); //BuchiFairTable.Remove(componet.ToString()); //OutgoingTransitionTable.Remove(componet); } SCCPairs = new Dictionary<string, LocalPair>(1024); } else { stepStack.Push(pair); } } } while (TaskStack.Count > 0); JobFinished = true; return; }
/// <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; }
/// <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; }
public MDPStat BuildQuotientMDP(VerificationOutput VerificationOutput) { //return this; MDPStat toReturn = new MDPStat(Precision, MAX_DIFFERENCE); //todo change to set List <KeyValuePair <string, string> > BoundaryOneTransition = new List <KeyValuePair <string, string> >(); //todo change to set List <DistributionStat> ProbTransitions = new List <DistributionStat>(); Dictionary <string, List <DistributionStat> > GlobalProbTransitions = new Dictionary <string, List <DistributionStat> >(); StringDictionary <bool> visited = new StringDictionary <bool>(States.Count); List <KeyValuePair <HashSet <string>, MDPStateStat> > sccs = new List <KeyValuePair <HashSet <string>, MDPStateStat> >(); Dictionary <string, int> preorder = new Dictionary <string, int>(); Dictionary <string, int> lowlink = new Dictionary <string, int>(); //HashSet<string> scc_found = new HashSet<string>(); Stack <MDPStateStat> TaskStack = new Stack <MDPStateStat>(); //Dictionary<string, List<string>> OutgoingTransitionTable = new Dictionary<string, List<string>>(); Stack <MDPStateStat> stepStack = new Stack <MDPStateStat>(1024); visited.Add(InitState.ID, false); TaskStack.Push(InitState); //# Preorder counter int preor = 0; do { while (TaskStack.Count > 0) { MDPStateStat pair = TaskStack.Peek(); string v = pair.ID; if (visited.GetContainsKey(v) && visited.GetContainsKey(v)) { TaskStack.Pop(); continue; } if (!preorder.ContainsKey(v)) { preorder.Add(v, preor); preor++; } bool done = true; List <DistributionStat> list = pair.Distributions; List <MDPStateStat> nonProbTrans = new List <MDPStateStat>(); List <DistributionStat> ProbTrans = new List <DistributionStat>(); for (int i = 0; i < list.Count; i++) { if (list[i].IsTrivial()) { nonProbTrans.Add(list[i].States[0].Value); } else { ProbTrans.Add(list[i]); } } if (ProbTrans.Count > 0 && !GlobalProbTransitions.ContainsKey(v)) { GlobalProbTransitions.Add(v, ProbTrans); ProbTransitions.AddRange(ProbTrans); } for (int k = nonProbTrans.Count - 1; k >= 0; k--) { MDPStateStat step = nonProbTrans[k]; string tmp = step.ID; if (visited.ContainsKey(tmp)) { //if this node is still not visited if (!preorder.ContainsKey(tmp)) { //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) { TaskStack.Push(step); done = false; } } } else { visited.Add(tmp, false); //OutgoingTransitionTable.Add(tmp, new List<string>(8)); //only put the first one into the stack. if (done) { TaskStack.Push(step); done = false; } } } if (done) { int lowlinkV = preorder[v]; int preorderV = preorder[v]; bool selfLoop = false; for (int j = 0; j < nonProbTrans.Count; j++) { string w = nonProbTrans[j].ID; if (w == v) { selfLoop = true; } if (!visited.GetContainsKey(w)) { if (preorder[w] > preorderV) { lowlinkV = Math.Min(lowlinkV, lowlink[w]); } else { lowlinkV = Math.Min(lowlinkV, preorder[w]); } } else //in this case, there is a tau transition leading to an SCC; must add the transition into the toReturn automaton { BoundaryOneTransition.Add(new KeyValuePair <string, string>(v, w)); } } lowlink[v] = lowlinkV; TaskStack.Pop(); HashSet <string> scc = new HashSet <string>(); if (lowlinkV == preorderV) { scc.Add(v); visited.SetValue(v, true); while (stepStack.Count > 0 && preorder[stepStack.Peek().ID] > preorderV) { string s = stepStack.Pop().ID; scc.Add(s); visited.SetValue(s, true); } MDPStateStat newstate = new MDPStateStat(toReturn.States.Count.ToString()); if (scc.Count > 1 || (scc.Count == 1 && selfLoop)) { newstate.AddDistribution(new DistributionStat(Constants.TAU, newstate)); //add self loop: sun jun } sccs.Add(new KeyValuePair <HashSet <string>, MDPStateStat>(scc, newstate)); toReturn.AddState(newstate); if (scc.Contains(InitState.ID)) { toReturn.SetInit(newstate); } foreach (MDPStateStat state in TargetStates) { if (scc.Contains(state.ID)) { toReturn.AddTargetStates(newstate); } } } else { stepStack.Push(pair); } } } if (ProbTransitions.Count > 0) { foreach (DistributionStat step in ProbTransitions) { foreach (KeyValuePair <double, MDPStateStat> pair in step.States) { string stateID = pair.Value.ID; if (!visited.ContainsKey(stateID)) { TaskStack.Push(pair.Value); visited.Add(stateID, false); } } } ProbTransitions.Clear(); } } while (TaskStack.Count > 0); foreach (KeyValuePair <string, string> pair in BoundaryOneTransition) { MDPStateStat source = null; MDPStateStat target = null; foreach (KeyValuePair <HashSet <string>, MDPStateStat> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; } if (sccstate.Key.Contains(pair.Value)) { target = sccstate.Value; } } toReturn.AddDistribution(source.ID, new DistributionStat(Constants.TAU, target)); VerificationOutput.ReducedMDPTransitions++; } foreach (KeyValuePair <string, List <DistributionStat> > pair in GlobalProbTransitions) { MDPStateStat source = null; foreach (KeyValuePair <HashSet <string>, MDPStateStat> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; break; } } foreach (DistributionStat distribution in pair.Value) { DistributionStat disNew = new DistributionStat(distribution.Event); foreach (KeyValuePair <double, MDPStateStat> state in distribution.States) { foreach (KeyValuePair <HashSet <string>, MDPStateStat> sccstate in sccs) { if (sccstate.Key.Contains(state.Value.ID)) { disNew.AddProbStatePair(state.Key, sccstate.Value); VerificationOutput.ReducedMDPTransitions++; break; } } } toReturn.AddDistribution(source.ID, disNew); } } VerificationOutput.ReducedMDPStates = toReturn.States.Count; return(toReturn); }
public MDP BuildQuotientMDP(VerificationOutput VerificationOutput) { //return this; MDP toReturn = new MDP(Precision, MAX_DIFFERENCE); //todo change to set List<KeyValuePair<string, string>> BoundaryOneTransition = new List<KeyValuePair<string, string>>(); //todo change to set List<Distribution> ProbTransitions = new List<Distribution>(); Dictionary<string, List<Distribution>> GlobalProbTransitions = new Dictionary<string, List<Distribution>>(); StringDictionary<bool> visited = new StringDictionary<bool>(States.Count); List<KeyValuePair<HashSet<string>, MDPState>> sccs = new List<KeyValuePair<HashSet<string>, MDPState>>(); Dictionary<string, int> preorder = new Dictionary<string, int>(); Dictionary<string, int> lowlink = new Dictionary<string, int>(); //HashSet<string> scc_found = new HashSet<string>(); Stack<MDPState> TaskStack = new Stack<MDPState>(); //Dictionary<string, List<string>> OutgoingTransitionTable = new Dictionary<string, List<string>>(); Stack<MDPState> stepStack = new Stack<MDPState>(1024); visited.Add(InitState.ID, false); TaskStack.Push(InitState); //# Preorder counter int preor = 0; do { while (TaskStack.Count > 0) { MDPState pair = TaskStack.Peek(); string v = pair.ID; if (visited.GetContainsKey(v) && visited.GetContainsKey(v)) { TaskStack.Pop(); continue; } if (!preorder.ContainsKey(v)) { preorder.Add(v, preor); preor++; } bool done = true; List<Distribution> list = pair.Distributions; List<MDPState> nonProbTrans = new List<MDPState>(); List<Distribution> ProbTrans = new List<Distribution>(); for (int i = 0; i < list.Count; i++) { if (list[i].IsTrivial()) { nonProbTrans.Add(list[i].States[0].Value); } else { ProbTrans.Add(list[i]); } } if (ProbTrans.Count > 0 && !GlobalProbTransitions.ContainsKey(v)) { GlobalProbTransitions.Add(v, ProbTrans); ProbTransitions.AddRange(ProbTrans); } for (int k = nonProbTrans.Count - 1; k >= 0; k--) { MDPState step = nonProbTrans[k]; string tmp = step.ID; if (visited.ContainsKey(tmp)) { //if this node is still not visited if (!preorder.ContainsKey(tmp)) { //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) { TaskStack.Push(step); done = false; } } } else { visited.Add(tmp, false); //OutgoingTransitionTable.Add(tmp, new List<string>(8)); //only put the first one into the stack. if (done) { TaskStack.Push(step); done = false; } } } if (done) { int lowlinkV = preorder[v]; int preorderV = preorder[v]; bool selfLoop = false; for (int j = 0; j < nonProbTrans.Count; j++) { string w = nonProbTrans[j].ID; if (w == v) { selfLoop = true; } if (!visited.GetContainsKey(w)) { if (preorder[w] > preorderV) { lowlinkV = Math.Min(lowlinkV, lowlink[w]); } else { lowlinkV = Math.Min(lowlinkV, preorder[w]); } } else //in this case, there is a tau transition leading to an SCC; must add the transition into the toReturn automaton { BoundaryOneTransition.Add(new KeyValuePair<string, string>(v, w)); } } lowlink[v] = lowlinkV; TaskStack.Pop(); HashSet<string> scc = new HashSet<string>(); if (lowlinkV == preorderV) { scc.Add(v); visited.SetValue(v, true); while (stepStack.Count > 0 && preorder[stepStack.Peek().ID] > preorderV) { string s = stepStack.Pop().ID; scc.Add(s); visited.SetValue(s, true); } MDPState newstate = new MDPState(toReturn.States.Count.ToString()); if (scc.Count > 1 || (scc.Count == 1 && selfLoop)) { newstate.AddDistribution(new Distribution(Constants.TAU, newstate)); //add self loop: sun jun } sccs.Add(new KeyValuePair<HashSet<string>, MDPState>(scc, newstate)); toReturn.AddState(newstate); if (scc.Contains(InitState.ID)) { toReturn.SetInit(newstate); } foreach (MDPState state in TargetStates) { if (scc.Contains(state.ID)) { toReturn.AddTargetStates(newstate); } } } else { stepStack.Push(pair); } } } if (ProbTransitions.Count > 0) { foreach (Distribution step in ProbTransitions) { foreach (KeyValuePair<double, MDPState> pair in step.States) { string stateID = pair.Value.ID; if (!visited.ContainsKey(stateID)) { TaskStack.Push(pair.Value); visited.Add(stateID, false); } } } ProbTransitions.Clear(); } } while (TaskStack.Count > 0); foreach (KeyValuePair<string, string> pair in BoundaryOneTransition) { MDPState source = null; MDPState target = null; foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; } if (sccstate.Key.Contains(pair.Value)) { target = sccstate.Value; } } toReturn.AddDistribution(source.ID, new Distribution(Constants.TAU, target)); VerificationOutput.ReducedMDPTransitions++; } foreach (KeyValuePair<string, List<Distribution>> pair in GlobalProbTransitions) { MDPState source = null; foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(pair.Key)) { source = sccstate.Value; break; } } foreach (Distribution distribution in pair.Value) { Distribution disNew = new Distribution(distribution.Event); foreach (KeyValuePair<double, MDPState> state in distribution.States) { foreach (KeyValuePair<HashSet<string>, MDPState> sccstate in sccs) { if (sccstate.Key.Contains(state.Value.ID)) { disNew.AddProbStatePair(state.Key, sccstate.Value); VerificationOutput.ReducedMDPTransitions++; break; } } } toReturn.AddDistribution(source.ID, disNew); } } VerificationOutput.ReducedMDPStates = toReturn.States.Count; return toReturn; }
public bool DepthFirstSearchRed(LocalPair s, Stack <LocalPair> BlueStack, Dictionary <string, List <string> > OutgoingTransitionTable, StringDictionary <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) { VerificationOutput.NoOfStates = colorData.Count; // VisitedWithID.Count; 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]; if (neighbourList.Count > 0) { //transverse all neighbour nodes for (int k = neighbourList.Count - 1; k >= 0; k--) { LocalPair step = neighbourList[k]; string tmp = step.GetCompressedState(); StateColor neighbourColor = colorData.GetContainsKey(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()) { ReportRedCycle(s, step, pair, BlueStack, RedStack, colorData, OutgoingTransitionTable); return(true); } else { neighbourList.RemoveAt(k); } } } if (redDone) { RedStack.Pop(); } } while (RedStack.Count > 0); return(false); }
/// <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; }
/// <summary> /// On the fly feasible checking, /// https://networkx.lanl.gov/Reference/networkx.component-pysrc.html#strongly_connected_components // Returns list of strongly connected components in G. Uses Tarjan's algorithm with Nuutila's modifications. // Nonrecursive version of algorithm. // // References: // // R. Tarjan (1972). Depth-first search and linear graph algorithms. SIAM Journal of Computing 1(2):146-160. // // E. Nuutila and E. Soisalon-Soinen (1994). On finding the strongly connected components in a directed graph. // Information Processing Letters 49(1): 9-14. // http://coblitz.codeen.org:3125/citeseer.ist.psu.edu/cache/papers/cs/549/http:zSzzSzwww.cs.hut.fizSz~enuzSzpszSzipl-scc.pdf/nuutila94finding.pdf // neighbors=G.neighbors // preorder={} // lowlink={} // scc_found={} // scc_queue = [] // scc_list=[] // i=0 # Preorder counter // for source in G: // if source not in scc_found: // queue=[source] // while queue: // v=queue[-1] // if v not in preorder: // i=i+1 // preorder[v]=i // done=1 // for w in neighbors(v): // if w not in preorder: // queue.append(w) // done=0 // break // if done==1: // lowlink[v]=preorder[v] // for w in neighbors(v): // if w not in scc_found: // if preorder[w]>preorder[v]: // lowlink[v]=min([lowlink[v],lowlink[w]]) // else: // lowlink[v]=min([lowlink[v],preorder[w]]) // queue.pop() // if lowlink[v]==preorder[v]: // scc_found[v]=True // scc=[v] // while scc_queue and preorder[scc_queue[-1]]>preorder[v]: // k=scc_queue.pop() // scc_found[k]=True // scc.append(k) // scc_list.append(scc) // else: // scc_queue.append(v) // scc_list.sort(lambda x, y: cmp(len(y),len(x))) // return scc_list /// </summary> /// <returns>true if feasible, otherwise return false</returns> public void TarjanModelChecking() { VerificationOutput.CounterExampleTrace = null; //out-going table. Dictionary<string, List<string>> OutgoingTransitionTable = new Dictionary<string, List<string>>(Ultility.Ultility.MC_INITIAL_SIZE); //DFS Stack Stack<KeyValuePair<ConfigurationBase, string>> TaskStack = new Stack<KeyValuePair<ConfigurationBase, string>>(5000); //DFS data, which mapping each state to an int[] of size 2, first is the pre-order, second is the lowlink StringDictionary<int[]> DFSData = new StringDictionary<int[]>(Ultility.Ultility.MC_INITIAL_SIZE); List<KeyValuePair<ConfigurationBase, string>> initials = new List<KeyValuePair<ConfigurationBase, string>>(); HashSet<string> existed = new HashSet<string>(); foreach (string s in BA.InitialStates) { List<string> next = BA.MakeOneMove(s, InitialStep); foreach (string var in next) { //if (!existed.Contains(var)) //{ // existed.Add(var); // initials.Add(new KeyValuePair<ConfigurationBase, string>(InitialStep, var)); //} if (existed.Add(var)) { initials.Add(new KeyValuePair<ConfigurationBase, string>(InitialStep, var)); } } } if (initials.Count == 0) { VerificationOutput.VerificationResult = VerificationResultType.VALID; return; } for (int z = 0; z < initials.Count; z++) { KeyValuePair<ConfigurationBase, string> initState = initials[z]; TaskStack.Push(initState); string ID = initState.Key.GetIDWithEvent() + Constants.SEPARATOR + initState.Value; DFSData.Add(ID, new int[] { VISITED_NOPREORDER, 0 }); OutgoingTransitionTable.Add(ID, new List<string>(8)); } List<string> StronglyConnectedComponets = new List<string>(1024); Stack<KeyValuePair<ConfigurationBase, string>> stepStack = new Stack<KeyValuePair<ConfigurationBase, string>>(1024); //# Preorder counter int i = 0; //store the expended event step of a node to avoid multiple invocation of the make one move. Dictionary<string, List<KeyValuePair<ConfigurationBase, string>>> ExpendedNode = new Dictionary<string, List<KeyValuePair<ConfigurationBase, string>>>(1024); do { if (CancelRequested) { VerificationOutput.NoOfStates = DFSData.Count; // VisitedWithID.Count; return; } KeyValuePair<ConfigurationBase, string> pair = TaskStack.Peek(); ConfigurationBase config = pair.Key; string v = pair.Key.GetIDWithEvent() + Constants.SEPARATOR + pair.Value; 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<KeyValuePair<ConfigurationBase, string>> list = ExpendedNode[v]; if (list.Count > 0) { //transverse all steps for (int k = list.Count - 1; k >= 0; k--) { KeyValuePair<ConfigurationBase, string> step = list[k]; //if the step is a unvisited step string tmp = step.Key.GetIDWithEvent() + Constants.SEPARATOR + step.Value; if(DFSData.GetContainsKey(tmp)[0] == VISITED_NOPREORDER) { if (done) { TaskStack.Push(step); done = false; list.RemoveAt(k); } } else { list.RemoveAt(k); } } } } else { IEnumerable<ConfigurationBase> list = config.MakeOneMove(); List<KeyValuePair<ConfigurationBase, string>> product = new List<KeyValuePair<ConfigurationBase, string>>(); foreach (ConfigurationBase step in list) { List<string> states = BA.MakeOneMove(pair.Value, step); for (int j = 0; j < states.Count; j++) { product.Add(new KeyValuePair<ConfigurationBase, string>(step, states[j])); } } //count the transitions visited VerificationOutput.Transitions += product.Count; for (int k = product.Count - 1; k >= 0; k--) { KeyValuePair<ConfigurationBase, string> step = product[k]; string tmp = step.Key.GetIDWithEvent() + Constants.SEPARATOR + step.Value; int[] data = DFSData.GetContainsKey(tmp); if (data != null) { outgoing.Add(tmp); if(data[0] == VISITED_NOPREORDER) { if (done) { TaskStack.Push(step); done = false; product.RemoveAt(k); } else { product[k] = step; } } else { product.RemoveAt(k); } } else { DFSData.Add(tmp, new int[]{VISITED_NOPREORDER, 0}); OutgoingTransitionTable.Add(tmp, new List<string>(8)); outgoing.Add(tmp); if (done) { TaskStack.Push(step); done = false; product.RemoveAt(k); } else { product[k] = step; } } } ExpendedNode.Add(v, product); } if (done) { 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.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; TaskStack.Pop(); if (lowlinkV == preorderV) { StronglyConnectedComponets.Add(v); nodeData[0] = SCC_FOUND; //checking for buchi-fair bool BuchiFair = pair.Value.EndsWith(Constants.ACCEPT_STATE); if (stepStack.Count > 0) { KeyValuePair<ConfigurationBase, string> valuePair = stepStack.Peek(); string k = valuePair.Key.GetIDWithEvent() + Constants.SEPARATOR + valuePair.Value; while (stepStack.Count > 0 && DFSData.GetContainsKey(k)[0] > preorderV) { stepStack.Pop(); StronglyConnectedComponets.Add(k); DFSData.GetContainsKey(k)[0] = SCC_FOUND; if (!BuchiFair && valuePair.Value.EndsWith(Constants.ACCEPT_STATE)) { BuchiFair = true; } if (stepStack.Count > 0) { valuePair = stepStack.Peek(); k = valuePair.Key.GetIDWithEvent() + Constants.SEPARATOR + valuePair.Value; } } } if (BuchiFair && (config.IsDeadLock || StronglyConnectedComponets.Count > 1 || selfLoop)) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = DFSData.Count; while (TaskStack.Count > 0 && TaskStack.Peek().Key.Event != Constants.INITIAL_EVENT) { TaskStack.Pop(); } string startID = null; if (TaskStack.Count > 0) { startID = TaskStack.Peek().Key.GetIDWithEvent() + Constants.SEPARATOR + TaskStack.Peek().Value; } VerificationOutput.CounterExampleTrace = GetConcreteTrace(InitialStep, GetCounterExample(StronglyConnectedComponets, startID, OutgoingTransitionTable)); return; } foreach (string componet in StronglyConnectedComponets) { ExpendedNode.Remove(componet); } StronglyConnectedComponets.Clear(); } else { stepStack.Push(pair); } } } while (TaskStack.Count > 0); VerificationOutput.VerificationResult = VerificationResultType.VALID; VerificationOutput.NoOfStates = DFSData.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().ToArray(); IEnumerable<ConfigurationBase> nextLTSStates = LTSState.MakeOneMove(); //.ToArray() 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 lock (MultiCoreLock) { if (!foundSCCTarjanGeldenhuysValmari.ContainsKey(tmpID)) { foundSCCTarjanGeldenhuysValmari.Add(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> /// On the fly feasible checking, /// https://networkx.lanl.gov/Reference/networkx.component-pysrc.html#strongly_connected_components // Returns list of strongly connected components in G. Uses Tarjan's algorithm with Nuutila's modifications. // Nonrecursive version of algorithm. // // References: // // R. Tarjan (1972). Depth-first search and linear graph algorithms. SIAM Journal of Computing 1(2):146-160. // // E. Nuutila and E. Soisalon-Soinen (1994). On finding the strongly connected components in a directed graph. // Information Processing Letters 49(1): 9-14. // http://coblitz.codeen.org:3125/citeseer.ist.psu.edu/cache/papers/cs/549/http:zSzzSzwww.cs.hut.fizSz~enuzSzpszSzipl-scc.pdf/nuutila94finding.pdf // neighbors=G.neighbors // preorder={} // lowlink={} // scc_found={} // scc_queue = [] // scc_list=[] // i=0 # Preorder counter // for source in G: // if source not in scc_found: // queue=[source] // while queue: // v=queue[-1] // if v not in preorder: // i=i+1 // preorder[v]=i // done=1 // for w in neighbors(v): // if w not in preorder: // queue.append(w) // done=0 // break // if done==1: // lowlink[v]=preorder[v] // for w in neighbors(v): // if w not in scc_found: // if preorder[w]>preorder[v]: // lowlink[v]=min([lowlink[v],lowlink[w]]) // else: // lowlink[v]=min([lowlink[v],preorder[w]]) // queue.pop() // if lowlink[v]==preorder[v]: // scc_found[v]=True // scc=[v] // while scc_queue and preorder[scc_queue[-1]]>preorder[v]: // k=scc_queue.pop() // scc_found[k]=True // scc.append(k) // scc_list.append(scc) // else: // scc_queue.append(v) // scc_list.sort(lambda x, y: cmp(len(y),len(x))) // return scc_list /// </summary> /// <returns>true if feasible, otherwise return false</returns> public void TarjanModelChecking() { VerificationOutput.CounterExampleTrace = null; //out-going table. Dictionary <string, List <string> > OutgoingTransitionTable = new Dictionary <string, List <string> >(Ultility.Ultility.MC_INITIAL_SIZE); //DFS Stack Stack <KeyValuePair <ConfigurationBase, string> > TaskStack = new Stack <KeyValuePair <ConfigurationBase, string> >(5000); //DFS data, which mapping each state to an int[] of size 2, first is the pre-order, second is the lowlink StringDictionary <int[]> DFSData = new StringDictionary <int[]>(Ultility.Ultility.MC_INITIAL_SIZE); List <KeyValuePair <ConfigurationBase, string> > initials = new List <KeyValuePair <ConfigurationBase, string> >(); HashSet <string> existed = new HashSet <string>(); foreach (string s in BA.InitialStates) { List <string> next = BA.MakeOneMove(s, InitialStep); foreach (string var in next) { //if (!existed.Contains(var)) //{ // existed.Add(var); // initials.Add(new KeyValuePair<ConfigurationBase, string>(InitialStep, var)); //} if (existed.Add(var)) { initials.Add(new KeyValuePair <ConfigurationBase, string>(InitialStep, var)); } } } if (initials.Count == 0) { VerificationOutput.VerificationResult = VerificationResultType.VALID; return; } for (int z = 0; z < initials.Count; z++) { KeyValuePair <ConfigurationBase, string> initState = initials[z]; TaskStack.Push(initState); string ID = initState.Key.GetIDWithEvent() + Constants.SEPARATOR + initState.Value; DFSData.Add(ID, new int[] { VISITED_NOPREORDER, 0 }); OutgoingTransitionTable.Add(ID, new List <string>(8)); } List <string> StronglyConnectedComponets = new List <string>(1024); Stack <KeyValuePair <ConfigurationBase, string> > stepStack = new Stack <KeyValuePair <ConfigurationBase, string> >(1024); //# Preorder counter int i = 0; //store the expended event step of a node to avoid multiple invocation of the make one move. Dictionary <string, List <KeyValuePair <ConfigurationBase, string> > > ExpendedNode = new Dictionary <string, List <KeyValuePair <ConfigurationBase, string> > >(1024); do { if (CancelRequested) { VerificationOutput.NoOfStates = DFSData.Count; // VisitedWithID.Count; return; } KeyValuePair <ConfigurationBase, string> pair = TaskStack.Peek(); ConfigurationBase config = pair.Key; string v = pair.Key.GetIDWithEvent() + Constants.SEPARATOR + pair.Value; 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 <KeyValuePair <ConfigurationBase, string> > list = ExpendedNode[v]; if (list.Count > 0) { //transverse all steps for (int k = list.Count - 1; k >= 0; k--) { KeyValuePair <ConfigurationBase, string> step = list[k]; //if the step is a unvisited step string tmp = step.Key.GetIDWithEvent() + Constants.SEPARATOR + step.Value; if (DFSData.GetContainsKey(tmp)[0] == VISITED_NOPREORDER) { if (done) { TaskStack.Push(step); done = false; list.RemoveAt(k); } } else { list.RemoveAt(k); } } } } else { IEnumerable <ConfigurationBase> list = config.MakeOneMove(); List <KeyValuePair <ConfigurationBase, string> > product = new List <KeyValuePair <ConfigurationBase, string> >(); foreach (ConfigurationBase step in list) { List <string> states = BA.MakeOneMove(pair.Value, step); for (int j = 0; j < states.Count; j++) { product.Add(new KeyValuePair <ConfigurationBase, string>(step, states[j])); } } //count the transitions visited VerificationOutput.Transitions += product.Count; for (int k = product.Count - 1; k >= 0; k--) { KeyValuePair <ConfigurationBase, string> step = product[k]; string tmp = step.Key.GetIDWithEvent() + Constants.SEPARATOR + step.Value; int[] data = DFSData.GetContainsKey(tmp); if (data != null) { outgoing.Add(tmp); if (data[0] == VISITED_NOPREORDER) { if (done) { TaskStack.Push(step); done = false; product.RemoveAt(k); } else { product[k] = step; } } else { product.RemoveAt(k); } } else { DFSData.Add(tmp, new int[] { VISITED_NOPREORDER, 0 }); OutgoingTransitionTable.Add(tmp, new List <string>(8)); outgoing.Add(tmp); if (done) { TaskStack.Push(step); done = false; product.RemoveAt(k); } else { product[k] = step; } } } ExpendedNode.Add(v, product); } if (done) { 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.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; TaskStack.Pop(); if (lowlinkV == preorderV) { StronglyConnectedComponets.Add(v); nodeData[0] = SCC_FOUND; //checking for buchi-fair bool BuchiFair = pair.Value.EndsWith(Constants.ACCEPT_STATE); if (stepStack.Count > 0) { KeyValuePair <ConfigurationBase, string> valuePair = stepStack.Peek(); string k = valuePair.Key.GetIDWithEvent() + Constants.SEPARATOR + valuePair.Value; while (stepStack.Count > 0 && DFSData.GetContainsKey(k)[0] > preorderV) { stepStack.Pop(); StronglyConnectedComponets.Add(k); DFSData.GetContainsKey(k)[0] = SCC_FOUND; if (!BuchiFair && valuePair.Value.EndsWith(Constants.ACCEPT_STATE)) { BuchiFair = true; } if (stepStack.Count > 0) { valuePair = stepStack.Peek(); k = valuePair.Key.GetIDWithEvent() + Constants.SEPARATOR + valuePair.Value; } } } if (BuchiFair && (config.IsDeadLock || StronglyConnectedComponets.Count > 1 || selfLoop)) { VerificationOutput.VerificationResult = VerificationResultType.INVALID; VerificationOutput.NoOfStates = DFSData.Count; while (TaskStack.Count > 0 && TaskStack.Peek().Key.Event != Constants.INITIAL_EVENT) { TaskStack.Pop(); } string startID = null; if (TaskStack.Count > 0) { startID = TaskStack.Peek().Key.GetIDWithEvent() + Constants.SEPARATOR + TaskStack.Peek().Value; } VerificationOutput.CounterExampleTrace = GetConcreteTrace(InitialStep, GetCounterExample(StronglyConnectedComponets, startID, OutgoingTransitionTable)); return; } foreach (string componet in StronglyConnectedComponets) { ExpendedNode.Remove(componet); } StronglyConnectedComponets.Clear(); } else { stepStack.Push(pair); } } } while (TaskStack.Count > 0); VerificationOutput.VerificationResult = VerificationResultType.VALID; VerificationOutput.NoOfStates = DFSData.Count; return; }