mtc_redundantcolors.cpp
Go to the documentation of this file.
1 /** @file mtc_redundantcolors.cpp
2 
3 Methods for removing redundant colors for the supervisor synthesis from MtcSystems
4 
5 */
6 
7 /* FAU Discrete Event Systems Library (libfaudes)
8 
9  Copyright (C) 2008 Matthias Singer
10  Copyright (C) 2006 Bernd Opitz
11  Exclusive copyright is granted to Klaus Schmidt
12 
13  This library is free software; you can redistribute it and/or
14  modify it under the terms of the GNU Lesser General Public
15  License as published by the Free Software Foundation; either
16  version 2.1 of the License, or (at your option) any later version.
17 
18  This library is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with this library; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
26 
27 
28 #include "mtc_redundantcolors.h"
29 
30 namespace faudes {
31 
32 // SearchScc(state,rCount,rGen, rNewStates,rSTACK,rStackStates,rDFN,rLOWLINK,rSccSet,rRoots)
33 void SearchScc(
34  const Idx state,
35  int& rCount, // why is this a ref?
36  const Generator& rGen,
37  StateSet& rNewStates,
38  std::stack<Idx>& rSTACK,
39  StateSet& rStackStates,
40  std::map<const Idx, int>& rDFN,
41  std::map<const Idx, int>& rLOWLINK,
42  std::set<StateSet>& rSccSet,
43  StateSet& rRoots)
44 {
45  FD_DF("SearchScc: -- search from state "<< state << "--");
46 
47  // mark state "old";
48  rNewStates.Erase(state);
49  // DFNUMBER[state] <- count;
50  rDFN[state]=rCount;
51  rCount++;
52  // LOWLINK[v] <- DFNUMBER[v];
53  rLOWLINK[state]=rDFN[state];
54  // push state on STACK;
55  rSTACK.push(state);
56  rStackStates.Insert(state);
57  //<<create set "L[state]" of successor states of state
58  StateSet SuccStates = StateSet();
59  TransSet::Iterator it = rGen.TransRelBegin(state);
60  TransSet::Iterator it_end = rGen.TransRelEnd(state);
61  for (; it != it_end; ++it) {
62  SuccStates.Insert(it->X2);
63  }
64  // for each vertex *sit on L[state] do
65  StateSet::Iterator sit = SuccStates.Begin();
66  StateSet::Iterator sit_end = SuccStates.End();
67  for (; sit != sit_end; ++sit)
68  {
69  // if *sit is marked "new" then
70  if(rNewStates.Exists(*sit))
71  {// begin
72  // SearchC(*sit);
73  SearchScc(*sit, rCount, rGen, rNewStates, rSTACK, rStackStates, rDFN, rLOWLINK, rSccSet, rRoots);
74  // LOWLINK[state] <- MIN(LOWLINK[state],LOWLINK[*sit]);
75  if(rLOWLINK[*sit]<rLOWLINK[state])
76  {
77  rLOWLINK[state]=rLOWLINK[*sit];
78  }
79  }//end
80  else
81  {
82  // if DFNUMBER[*sit]<DFNUMBER[state] and [*sit] is on STACK then
83  if((rDFN[*sit]<rDFN[state])&&(rStackStates.Exists(*sit)))
84  {
85  // LOWLINK[state]<-MIN(DFNUMBER[*sit],LOWLINK[state]);
86  if(rDFN[*sit]<rLOWLINK[state])
87  {
88  rLOWLINK[state]=rDFN[*sit];
89  }
90  }
91  }
92  }//end for
93  // if LOWLINK[state]=DFNUMBER[state] (i.e. state is root of a SCC) then
94  if(rLOWLINK[state]==rDFN[state])
95  {
96 
97  //create SCC
98  StateSet Scc;
99  Idx top;
100  // begin
101  // repeat
102  while(true)
103  {// begin
104  // pop x from top of STACK and print x;
105  top=rSTACK.top();
106  Scc.Insert(top);
107  rStackStates.Erase(top);
108  rSTACK.pop();
109  // until x=state;
110  if(top==state){
111  // print "end of SCC", insert SCC into SCCset;
112  rSccSet.insert(Scc);
113  rRoots.Insert(state);
114  break;
115  }
116  } //end while
117  } // end if
118 }
119 
120 // ComputeSCC(rGen,rSCCSet,rRoots)
121 bool ComputeSCC(const Generator& rGen, std::set<StateSet>& rSCCSet, StateSet& rRoots){
122  // helpers:
123  StateSet newStates = rGen.States();
124  int count = 1;
125  std::stack<Idx> stack;
126  StateSet stackStates;
127  std::map<const Idx,int> DFN;
128  std::map<const Idx, int> LOWLINK;
129  // Search for SCCs until the list of new states is empty
130  while(!newStates.Empty() ){
131  SearchScc(*newStates.Begin(), count, rGen, newStates, stack, stackStates, DFN, LOWLINK, rSCCSet, rRoots);
132  }
133  if(rSCCSet.empty() )
134  return false;
135  else
136  return true;
137 }
138 
139 // ColoredSCC(rGen,rColors,rColoredSCCs)
140 void ColoredSCC(MtcSystem& rGen, ColorSet& rColors, std::set<StateSet>& rColoredSCCs){
141  //helpers:
142  StateSet roots;
143  std::set<StateSet>::iterator stIt, stEndIt, tmpIt;
144  ColorSet currentColors;
145  StateSet::Iterator sIt, sEndIt;
146  // first find all SCCs
147  ComputeSCC(rGen, rColoredSCCs, roots);
148  // Erase the SCCS that do not have all colors in rColors
149  stIt = rColoredSCCs.begin();
150  stEndIt = rColoredSCCs.end();
151  // investigate each SCC
152  for( ; stIt != stEndIt; ){
153  currentColors.Clear();
154  sIt = stIt->Begin();
155  sEndIt = stIt->End();
156  // collect the colors from all states in the current SCC
157  for( ; sIt != sEndIt; sIt++){
158  currentColors = currentColors + rGen.Colors(*sIt);
159  }
160  // Remove the SCC if not all colors appear
161  if(currentColors != rColors){
162  tmpIt = stIt;
163  stIt++;
164  rColoredSCCs.erase(tmpIt);
165  continue;
166  }
167  stIt++;
168  }
169 }
170 
171 // CheckRedundantColor(rGen,redundantColor)
172 bool CheckRedundantColor(MtcSystem rGen, Idx redundantColor){
173  //helpers:
174  ColorSet remainingColors = rGen.Colors();
175  remainingColors.Erase(redundantColor);
176  std::set<StateSet> coloredSCCs;
177  std::set<StateSet>::const_iterator csIt, csEndIt;
178  // Remove all states with redundantColor from a copy of rGen
179  MtcSystem copyGen = rGen;
180  StateSet copyStates = copyGen.States();
181  TransSetX2EvX1 copyTransSet;
182  copyGen.TransRel(copyTransSet);
183  StateSet::Iterator stIt, stEndIt;
184  stIt = copyStates.Begin();
185  stEndIt = copyStates.End();
186  for( ; stIt!= stEndIt; stIt++){
187  // delete all states with the redundant color
188  StateSet criticalStates;
189  if( copyGen.ExistsColor(*stIt,redundantColor) ){
190  StateSet::Iterator crIt;
191  copyGen.DelState(*stIt);
192  criticalStates.Clear();
193  TraverseUncontrollableBackwards(copyGen.ControllableEvents(),copyTransSet,criticalStates, *stIt);
194  for(crIt = criticalStates.Begin(); crIt != criticalStates.End(); crIt++){
195  copyGen.DelState(*crIt);
196  }
197  }
198  }
199  // Fixed point iteration that alternately computes SCCs and removes states with outgoing uncontrollable
200  // transitions from SCCs
201  while(true){
202  coloredSCCs.clear();
203  // Determine the colored strongly connected components in the remaining generator copyGen
204  ColoredSCC(copyGen, remainingColors, coloredSCCs);
205  // if there are no colored SCCs, the color is redundant
206  if(coloredSCCs.empty() ){
207  return true;
208  }
209  // otherwise, the SCCs can be used to construct a strongly nonblocking and controllable subbehavior of rGen that is
210  // blocking w.r.t. the potentially redundant color (just remove all transitions that leave the SCCs in G)
211  else{
212  // go over all SCCs and remove states with outgoing uncontrollable transisions
213  bool done = true;
214  csIt = coloredSCCs.begin();
215  csEndIt = coloredSCCs.end();
216  // go over all states in the SCC
217  for( ; csIt != csEndIt; csIt++){
218  stIt = csIt->Begin();
219  stEndIt = csIt->End();
220  for( ; stIt != stEndIt; stIt++){
221  // check all transitions
222  TransSet::Iterator tIt, tEndIt;
223  tIt = copyGen.TransRelBegin(*stIt);
224  tEndIt = copyGen.TransRelEnd(*stIt);
225  for( ; tIt != tEndIt; tIt++){
226  if( (!copyGen.Controllable(tIt->Ev) && !csIt->Exists(tIt->X2) ) ){
227  done = false;
228  copyGen.DelState(*stIt);
229  break;
230  }
231  }
232  }
233  }
234  if(done == true)
235  return false;
236  }
237  }
238 }
239 
240 
241 // OptimalColorSet(rGen,rOptimalColors,rHighAlph)
242 void OptimalColorSet(const MtcSystem& rGen, ColorSet& rOptimalColors, EventSet& rHighAlph){
243  std::vector<Idx> colorVector;
244  ColorSet genColors = rGen.Colors();
245  ColorSet::Iterator cIt, cEndIt;
246  cIt = genColors.Begin();
247  cEndIt = genColors.End();
248  for( ; cIt != cEndIt; cIt++){
249  colorVector.push_back(*cIt);
250  }
251  Idx vectorSize = colorVector.size();
252  Idx optimalNumberStates, currentNumberStates, optimalNumberColors;
253  // the abstracted generator has at most as many states as the original generator with the overall alphabet
254  // as high-level alphabet and all colors
255  optimalNumberStates = rGen.Size();
256  EventSet optimalAlph, currentHighAlph;
257  optimalAlph = rGen.Alphabet();
258  rOptimalColors = rGen.Colors();
259  // check all colors for redundancy
260  for(Idx i = 1; i <= vectorSize; i++){
261  bool redundant = CheckRedundantColor(rGen, colorVector[i-1] );
262  // if the current color can be removed, check the next colors (note that this is only possible if
263  // there are additional colors
264  if(redundant == true){
265  MtcSystem reducedGen = rGen;
266  reducedGen.DelColor(colorVector[i-1] );
267  currentHighAlph = rHighAlph;
268  currentNumberStates = calcNaturalObserver(reducedGen, currentHighAlph);
269  // Set the optimal values if a smaller generator than before is achieved
270  if(currentNumberStates < optimalNumberStates){
271  optimalNumberStates = currentNumberStates;
272  optimalAlph = currentHighAlph;
273  rOptimalColors = reducedGen.Colors();
274  optimalNumberColors = rOptimalColors.Size();
275  }
276  // if the abstraction has the same size but less colors are needed
277  else if(currentNumberStates == optimalNumberStates && reducedGen.Colors().Size() < rOptimalColors.Size() ){
278  optimalAlph = currentHighAlph;
279  rOptimalColors = reducedGen.Colors();
280  optimalNumberColors = rOptimalColors.Size();
281  }
282  rec_OptimalColorSet(reducedGen, colorVector, i + 1, rOptimalColors, optimalNumberStates, optimalNumberColors, rHighAlph, optimalAlph);
283  }
284  }
285  rHighAlph = optimalAlph;
286 }
287 
288 // rec_OptimalColorSet(rGen,rColorVector,colorNumber,rOptimalColors,rOptimalNumberStates,rOptimalNumberColors,rHighAlph,rOptimalHighAlph)
289  void rec_OptimalColorSet(const MtcSystem& rGen, const std::vector<Idx>& rColorVector, Idx colorNumber, ColorSet& rOptimalColors,
290  Idx& rOptimalNumberStates, Idx& rOptimalNumberColors, const EventSet& rHighAlph, EventSet& rOptimalHighAlph){
291  Idx vectorSize = rColorVector.size();
292  EventSet currentHighAlph;
293  Idx currentNumberStates;
294  for(Idx i = colorNumber; i <= vectorSize; i++){
295  bool redundant = CheckRedundantColor(rGen, rColorVector[i-1] );
296  // if there are additional colors and the current color can be removed, check the next colors
297  if(redundant == true){
298  MtcSystem reducedGen = rGen;
299  reducedGen.DelColor(rColorVector[i-1] );
300  currentHighAlph = rHighAlph;
301  currentNumberStates = calcNaturalObserver(reducedGen, currentHighAlph);
302  // Set the optimal values if a smaller generator than before is achieved
303  if(currentNumberStates < rOptimalNumberStates){
304  rOptimalNumberStates = currentNumberStates;
305  rOptimalHighAlph = currentHighAlph;
306  rOptimalColors = reducedGen.Colors();
307  rOptimalNumberColors = rOptimalColors.Size();
308  }
309  // if the abstraction has the same size but less colors are needed
310  else if(currentNumberStates == rOptimalNumberStates && reducedGen.Colors().Size() < rOptimalColors.Size() ){
311  rOptimalHighAlph = currentHighAlph;
312  rOptimalColors = reducedGen.Colors();
313  rOptimalNumberColors = rOptimalColors.Size();
314  }
315  // if there are potential colors to be removed, call the recursive function
316  if(i < vectorSize){
317  rec_OptimalColorSet(reducedGen, rColorVector, colorNumber + 1, rOptimalColors, rOptimalNumberStates, rOptimalNumberColors, rHighAlph, rOptimalHighAlph);
318  }
319  }
320  }
321 }
322 
323 } // namespace faudes
#define FD_DF(message)
Debug: optional report on user functions.
Container for colors: this is a NameSet with its own static symboltable.
Definition: mtc_colorset.h:41
Set of indices.
Definition: cfl_indexset.h:78
Idx Insert(void)
Insert new index to set.
Set of indices with symbolic names.
Definition: cfl_nameset.h:69
virtual bool Erase(const Idx &rIndex)
Delete element by index.
Set of Transitions.
Definition: cfl_transset.h:242
TBaseSet< Transition, TransSort::X1EvX2 >::Iterator Iterator
Iterator on transition.
Definition: cfl_transset.h:269
const TaStateSet< StateAttr > & States(void) const
Return reference to state set.
const TaEventSet< EventAttr > & Alphabet(void) const
Return const reference to alphabet.
const ATransSet & TransRel(void) const
Return reference to transition relation.
EventSet ControllableEvents(void) const
Get EventSet with controllable events.
bool Controllable(Idx index) const
Is event controllable (by index)
Allows to create colored marking generators (CMGs) as the common five tupel consisting of alphabet,...
Definition: mtc_generator.h:53
bool ExistsColor(Idx colorIndex) const
Check if color exists in generator.
void Colors(ColorSet &rColors) const
Insert all colors used in the generator to a given ColorSet.
void DelColor(Idx stateIndex, const std::string &rColorName)
Remove color by name from an existing state specified by index.
Base class of all FAUDES generators.
TransSet::Iterator TransRelBegin(void) const
Iterator to Begin() of transition relation.
bool DelState(Idx index)
Delete a state from generator by index.
TransSet::Iterator TransRelEnd(void) const
Iterator to End() of transition relation.
Idx Size(void) const
Get generator size (number of states)
const StateSet & States(void) const
Return reference to state set.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
IndexSet StateSet
Definition: cfl_indexset.h:271
virtual void Clear(void)
Clear all set.
Definition: cfl_baseset.h:1902
Iterator End(void) const
Iterator to the end of set.
Definition: cfl_baseset.h:1896
Iterator Begin(void) const
Iterator to the begin of set.
Definition: cfl_baseset.h:1891
virtual bool Erase(const T &rElem)
Erase element by reference.
Definition: cfl_baseset.h:2019
Idx Size(void) const
Get Size of TBaseSet.
Definition: cfl_baseset.h:1819
void OptimalColorSet(const MtcSystem &rGen, ColorSet &rOptimalColors, EventSet &rHighAlph)
Compute an optimal subset of the colors that should be removed.
void ColoredSCC(MtcSystem &rGen, ColorSet &rColors, std::set< StateSet > &rColoredSCCs)
Compute all strongly connected components (SCCs) in a colored marking generator (CMG) that are marked...
bool ComputeSCC(const Generator &rGen, std::set< StateSet > &rSCCSet, StateSet &rRoots)
Computes the strongly connected components (SCCs) of an automaton.
bool CheckRedundantColor(MtcSystem rGen, Idx redundantColor)
Check if a color in a colored marking generator is redundant for the supervisor synthesis.
Int calcNaturalObserver(const Generator &rGen, EventSet &rHighAlph)
Lm(G)-observer computation by adding events to the high-level alphabet.
Methods for removing redundant colors for the supervisor synthesis from MtcSystems.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
void rec_OptimalColorSet(const MtcSystem &rGen, const std::vector< Idx > &rColorVector, Idx colorNumber, ColorSet &rOptimalColors, Idx &rOptimalNumberStates, Idx &rOptimalNumberColors, const EventSet &rHighAlph, EventSet &rOptimalHighAlph)
Recursively find an optimal set of colors to be removed.
void TraverseUncontrollableBackwards(const EventSet &rCAlph, TransSetX2EvX1 &rtransrel, StateSet &rCriticalStates, Idx current)
Helper function for IsControllable.
Definition: syn_supcon.cpp:847
void SearchScc(const Idx vState, int &vRcount, const Generator &rGen, const SccFilter &rFilter, StateSet &rTodo, std::stack< Idx > &rStack, StateSet &rStackStates, std::map< const Idx, int > &rDfn, std::map< const Idx, int > &rLowLnk, std::list< StateSet > &rSccList, StateSet &rRoots)
Search for strongly connected components (SCC).

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen