/// <summary> /// Clones this instance. /// </summary> /// <returns>StatesTuple.</returns> public StatesTuple Clone() { var c = new StatesTuple(MData.Length); for (var i = 0; i < MData.Length; ++i) { c.MData[i] = MData[i]; } return(c); }
public StatesTuple Clone() { var c = new StatesTuple(m_data.Length); for (var i = 0; i < m_data.Length; ++i) { c.m_data[i] = m_data[i]; } return(c); }
/// <summary> /// Builds the product. /// </summary> private void BuildProduct() { var numAutomata = _statesList.Count; var origin = new int[numAutomata]; var destination = new int[numAutomata]; _statesStack = new Stack <StatesTuple>(); var initialState = new StatesTuple(origin, _bits, _tupleSize); _statesStack.Push(initialState); _validStates = new Dictionary <StatesTuple, bool>(StatesTupleComparator.GetInstance()) { { initialState, false } }; while (_statesStack.Count > 0) { _statesStack.Pop().Get(origin, _bits, _maxSize); for (var e = 0; e < _eventsUnion.Length; ++e) { var nextEvent = false; for (var i = 0; i < numAutomata; ++i) { if (_adjacencyList[i].HasEvent(origin[i], e)) { destination[i] = _adjacencyList[i][origin[i], e]; } else { nextEvent = true; break; } } if (nextEvent) { continue; } var nextState = new StatesTuple(destination, _bits, _tupleSize); if (_validStates.ContainsKey(nextState)) { continue; } _statesStack.Push(nextState); _validStates.Add(nextState, false); } } Size = (ulong)_validStates.Count; }
/// <summary> /// Finds the supervisor. /// </summary> /// <param name="nPlant">The n plant.</param> /// <param name="nonBlocking">if set to <c>true</c> [non blocking].</param> private void FindSupervisor(int nPlant, bool nonBlocking) { _numberOfRunningThreads = 0; _statesStack = new Stack <StatesTuple>(); _removeBadStates = new Stack <bool>(); _validStates = new Dictionary <StatesTuple, bool>(StatesTupleComparator.GetInstance()); MakeReverseTransitions(); var initialIndex = new StatesTuple(new int[_statesList.Count], _bits, _tupleSize); _statesStack.Push(initialIndex); _removeBadStates.Push(false); var vThreads = new Task[NumberOfThreads - 1]; for (var i = 0; i < NumberOfThreads - 1; ++i) { vThreads[i] = Task.Factory.StartNew(() => FindStates(nPlant)); } FindStates(nPlant); for (var i = 0; i < NumberOfThreads - 1; ++i) { vThreads[i].Wait(); } foreach (var s in _validStates.Reverse()) { if (s.Value) { _validStates.Remove(s.Key); } } bool vNewBadStates; do { vNewBadStates = DepthFirstSearch(false, true); GC.Collect(); if (nonBlocking) { vNewBadStates |= RemoveBlockingStates(true); } } while (vNewBadStates); }
/// <summary> /// Removes the blocking states. /// </summary> /// <param name="checkForBadStates">if set to <c>true</c> [check for bad states].</param> /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns> private bool RemoveBlockingStates(bool checkForBadStates = false) { MakeReverseTransitions(); int n = _statesList.Count, i; _numberOfRunningThreads = 0; var threads = new Task[NumberOfThreads - 1]; var markedStates = new List <int> [n]; var pos = new int[n]; var statePos = new int[n]; pos[n - 1] = -1; _statesStack = new Stack <StatesTuple>(); var vNotCheckValidState = false; if (_validStates == null) { vNotCheckValidState = true; _validStates = new Dictionary <StatesTuple, bool>(StatesTupleComparator.GetInstance()); } for (i = 0; i < n; ++i) { markedStates[i] = _statesList[i].Where(st => st.IsMarked) .Select(st => Array.IndexOf(_statesList[i], st)).ToList(); } while (true) { for (i = n - 1; i >= 0; --i) { ++pos[i]; if (pos[i] < markedStates[i].Count()) { break; } pos[i] = 0; } if (i < 0) { break; } for (i = 0; i < n; ++i) { statePos[i] = markedStates[i][pos[i]]; } var tuple = new StatesTuple(statePos, _bits, _tupleSize); if (!_validStates.TryGetValue(tuple, out var vValue) && !vNotCheckValidState || vValue) { continue; } _validStates[tuple] = true; _statesStack.Push(tuple); } markedStates = null; Size = 0; for (i = 0; i < NumberOfThreads - 1; ++i) { threads[i] = Task.Factory.StartNew(() => InverseSearchThread(vNotCheckValidState)); } InverseSearchThread(vNotCheckValidState); for (i = 0; i < NumberOfThreads - 1; ++i) { threads[i].Wait(); } _statesStack = null; var v_newBadStates = false; var uncontrollableEventsCount = UncontrollableEvents.Count(); if (checkForBadStates) { var removedStates = new List <StatesTuple>(); foreach (var p in _validStates) { if (!p.Value) { removedStates.Add(p.Key); } } foreach (var p in removedStates) { v_newBadStates |= RemoveBadStates(p, uncontrollableEventsCount, true); } } _reverseTransitionsList = null; foreach (var p in _validStates.Reverse()) { if (!p.Value) { _validStates.Remove(p.Key); } else { _validStates[p.Key] = false; } } GC.Collect(); return(v_newBadStates); }
/// <summary> /// Controllabilities the and disabled events. /// </summary> /// <param name="plants">The plants.</param> /// <param name="getDisabledEvents">if set to <c>true</c> [get disabled events].</param> /// <returns>Tuple<Controllability, Dictionary<AbstractState, List<AbstractEvent>>>.</returns> /// <exception cref="Exception">Plant is invalid.</exception> public Tuple <Controllability, Dictionary <AbstractState, List <AbstractEvent> > > ControllabilityAndDisabledEvents( IEnumerable <DFA> plants, bool getDisabledEvents = true) { var G = ParallelComposition(plants, false); var nG = G._statesList.Count; var nS = _statesList.Count; var pos2 = new int[nS]; var evs = _eventsUnion.Union(G._eventsUnion).OrderBy(i => i.Controllability).ToArray(); var numUncontEvs = 0; var stackG = new Stack <int[]>(); var stackS = new Stack <int[]>(); var filteredStates = _validStates != null; var GfilteredStates = G._validStates != null; var evsMapG = new int[evs.Length]; var evsMapS = new int[evs.Length]; var GTuple = new StatesTuple(G._tupleSize); var STuple = new StatesTuple(_tupleSize); var controllable = UltraDES.Controllability.Controllable; var disabled = new Dictionary <AbstractState, List <AbstractEvent> >((int)Size); AbstractState currentState = null; if (!filteredStates) { _validStates = new Dictionary <StatesTuple, bool>((int)Size, StatesTupleComparator.GetInstance()); } for (var e = 0; e < evs.Length; ++e) { if (!evs[e].IsControllable) { ++numUncontEvs; } evsMapG[e] = Array.IndexOf(G._eventsUnion, evs[e]); evsMapS[e] = Array.IndexOf(_eventsUnion, evs[e]); } stackG.Push(new int[nG]); STuple.Set(pos2, _bits); if (!filteredStates || _validStates.ContainsKey(STuple)) { stackS.Push(pos2); if (filteredStates) { _validStates[STuple] = true; } else { _validStates.Add(new StatesTuple(pos2, _bits, _tupleSize), true); } } var stopSearch = false; while (stackS.Count > 0) { var pos1 = stackG.Pop(); pos2 = stackS.Pop(); if (getDisabledEvents) { currentState = ComposeState(pos2); disabled.Add(currentState, new List <AbstractEvent>()); } for (var e = 0; e < evs.Length; ++e) { var t = CheckState(G, nG, nS, pos1, pos2, evsMapG[e], evsMapS[e]); var GHasNext = t.Item1; var SHasNext = t.Item2; if (GHasNext && GfilteredStates) { GTuple.Set(t.Item3, G._bits); GHasNext = G._validStates.ContainsKey(GTuple); } if (SHasNext && filteredStates) { STuple.Set(t.Item4, _bits); SHasNext = _validStates.ContainsKey(STuple); } if (!GHasNext && SHasNext) { throw new Exception("Plant is invalid."); } if (GHasNext && !SHasNext) { if (e < numUncontEvs) { controllable = UltraDES.Controllability.Uncontrollable; if (!getDisabledEvents) { stopSearch = true; break; } } if (getDisabledEvents) { disabled[currentState].Add(evs[e]); } } else if (GHasNext && SHasNext) { if (filteredStates) { if (!_validStates[STuple]) { _validStates[STuple] = true; stackG.Push(t.Item3); stackS.Push(t.Item4); } } else { STuple.Set(t.Item4, _bits); if (!_validStates.ContainsKey(STuple)) { _validStates.Add(new StatesTuple(t.Item4, _bits, _tupleSize), true); stackG.Push(t.Item3); stackS.Push(t.Item4); } } } } if (stopSearch) { break; } } if (filteredStates) { foreach (var t in _validStates.Reverse()) { _validStates[t.Key] = false; } } else { _validStates = null; } return(new Tuple <Controllability, Dictionary <AbstractState, List <AbstractEvent> > >(controllable, disabled)); }