mtc_parallel.cppGo to the documentation of this file.00001 /** @file mtc_parallel.cpp 00002 00003 Methods for parallel composition of multitasking generators 00004 00005 */ 00006 00007 /* FAU Discrete Event Systems Library (libfaudes) 00008 00009 Copyright (C) 2008 Matthias Singer 00010 Copyright (C) 2007 Thomas Moor 00011 Exclusive copyright is granted to Klaus Schmidt 00012 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Lesser General Public 00015 License as published by the Free Software Foundation; either 00016 version 2.1 of the License, or (at your option) any later version. 00017 00018 This library is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00021 Lesser General Public License for more details. 00022 00023 You should have received a copy of the GNU Lesser General Public 00024 License along with this library; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00026 00027 00028 #include "mtc_parallel.h" 00029 00030 namespace faudes { 00031 00032 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2, MtcSystem& rResGen) { 00033 // inputs have to agree on controllability of shared events: 00034 #ifdef FAUDES_CHECKED 00035 EventSet inconsistent = (rGen1.ControllableEvents()*rGen2.UncontrollableEvents()) 00036 +(rGen1.UncontrollableEvents()*rGen2.ControllableEvents()); 00037 if(!inconsistent.Empty()) { 00038 std::stringstream errstr; 00039 errstr << "mtcParallel: inconsistent controllability flags"; 00040 throw Exception("mtcParallel::inconsistent controllability flags", errstr.str(), 500); 00041 } 00042 #endif 00043 // prepare result 00044 rResGen.Clear(); 00045 00046 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00047 00048 // make parallel composition of inputs 00049 mtcParallel(rGen1, rGen2, rcmap, rResGen); 00050 00051 // copy controllability of input alphabets (TODO: copy all event attributes as in a Parallel) 00052 rResGen.SetControllable(rGen1.ControllableEvents()); 00053 rResGen.SetControllable(rGen2.ControllableEvents()); 00054 } 00055 00056 00057 // Parallel(rGen1, rGen2, rReverseCompositionMap, res) 00058 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2, 00059 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 00060 MtcSystem& rResGen) { 00061 FD_DF("mtcParallel(" << &rGen1 << "," << &rGen2 << ")"); 00062 // prepare result 00063 rResGen.Clear(); 00064 rResGen.Name(rGen1.Name()+"||"+rGen2.Name()); 00065 // rGen1.events() \ rGen2.events() 00066 EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet(); 00067 FD_DF("mtcParallel: shared events: " << sharedalphabet.ToString()); 00068 00069 // create res alphabet 00070 EventSet::Iterator eit; 00071 for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) { 00072 rResGen.InsEvent(*eit); 00073 } 00074 for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) { 00075 rResGen.InsEvent(*eit); 00076 } 00077 FD_DF("mtcParallel: inserted indices in rResGen.alphabet( " 00078 << rResGen.AlphabetToString() << ")"); 00079 00080 // todo stack 00081 std::stack< std::pair<Idx,Idx> > todo; 00082 // actual pair, new pair 00083 std::pair<Idx,Idx> currentstates, newstates; 00084 // state 00085 Idx tmpstate; 00086 00087 StateSet::Iterator lit1, lit2; 00088 TransSet::Iterator tit1, tit1_end, tit2, tit2_end; 00089 std::map< std::pair<Idx,Idx>, Idx>::iterator rcit; 00090 00091 ColorSet colors1, colors2, composedSet; 00092 rGen1.Colors(colors1); 00093 rGen2.Colors(colors2); 00094 00095 // push all combinations of initial states on todo stack 00096 FD_DF("mtcParallel: adding all combinations of initial states to todo:"); 00097 for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) { 00098 for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) { 00099 currentstates = std::make_pair(*lit1, *lit2); 00100 todo.push(currentstates); 00101 tmpstate = rReverseCompositionMap[currentstates] = rResGen.InsInitState(); 00102 ComposedColorSet(rGen1, *lit1, colors1, rGen2, *lit2, colors2, composedSet); 00103 rResGen.InsColors(tmpstate, composedSet); 00104 FD_DF("mtcParallel: (" << *lit1 << "|" << *lit2 << ") -> " 00105 << rReverseCompositionMap[currentstates]); 00106 } 00107 } 00108 00109 // start algorithm 00110 FD_DF("mtcParallel: processing reachable states:"); 00111 while (! todo.empty()) { 00112 // get next reachable state from todo stack 00113 currentstates = todo.top(); 00114 todo.pop(); 00115 FD_DF("mtcParallel: processing (" << currentstates.first << "|" 00116 << currentstates.second << ") -> " 00117 << rReverseCompositionMap[currentstates]); 00118 // iterate over all rGen1 transitions 00119 // (includes execution of shared events) 00120 tit1 = rGen1.TransRelBegin(currentstates.first); 00121 tit1_end = rGen1.TransRelEnd(currentstates.first); 00122 for (; tit1 != tit1_end; ++tit1) { 00123 // if event not shared 00124 if (! sharedalphabet.Exists(tit1->Ev)) { 00125 FD_DF("mtcParallel: exists only in rGen1"); 00126 newstates = std::make_pair(tit1->X2, currentstates.second); 00127 // add to todo list if composition state is new 00128 rcit = rReverseCompositionMap.find(newstates); 00129 if (rcit == rReverseCompositionMap.end()) { 00130 todo.push(newstates); 00131 tmpstate = rResGen.InsState(); 00132 ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, currentstates.second, colors2, composedSet); 00133 rResGen.InsColors(tmpstate, composedSet); 00134 rReverseCompositionMap[newstates] = tmpstate; 00135 FD_DF("mtcParallel: todo push: (" << newstates.first << "|" 00136 << newstates.second << ") -> " 00137 << rReverseCompositionMap[newstates]); 00138 } 00139 else { 00140 tmpstate = rcit->second; 00141 } 00142 rResGen.SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 00143 tmpstate); 00144 FD_DF("mtcParallel: add transition to new generator: " 00145 << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 00146 << tmpstate); 00147 } 00148 // if shared event 00149 else { 00150 FD_DF("mtcParallel: common event"); 00151 // find shared transitions 00152 tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev); 00153 tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev); 00154 for (; tit2 != tit2_end; ++tit2) { 00155 newstates = std::make_pair(tit1->X2, tit2->X2); 00156 // add to todo list if composition state is new 00157 rcit = rReverseCompositionMap.find(newstates); 00158 if (rcit == rReverseCompositionMap.end()) { 00159 todo.push(newstates); 00160 tmpstate = rResGen.InsState(); 00161 ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, tit2->X2, colors2, composedSet); 00162 rResGen.InsColors(tmpstate, composedSet); 00163 rReverseCompositionMap[newstates] = tmpstate; 00164 FD_DF("mtcParallel: todo push: (" << newstates.first << "|" 00165 << newstates.second << ") -> " 00166 << rReverseCompositionMap[newstates]); 00167 } 00168 else { 00169 tmpstate = rcit->second; 00170 } 00171 rResGen.SetTransition(rReverseCompositionMap[currentstates], 00172 tit1->Ev, tmpstate); 00173 FD_DF("mtcParallel: add transition to new generator: " 00174 << rReverseCompositionMap[currentstates] << "-" 00175 << tit1->Ev << "-" << tmpstate); 00176 } 00177 } 00178 } 00179 // iterate over all rGen2 transitions 00180 // (without execution of shared events) 00181 tit2 = rGen2.TransRelBegin(currentstates.second); 00182 tit2_end = rGen2.TransRelEnd(currentstates.second); 00183 for (; tit2 != tit2_end; ++tit2) { 00184 if (! sharedalphabet.Exists(tit2->Ev)) { 00185 FD_DF("mtcParallel: exists only in rGen2"); 00186 newstates = std::make_pair(currentstates.first, tit2->X2); 00187 // add to todo list if composition state is new 00188 rcit = rReverseCompositionMap.find(newstates); 00189 if (rcit == rReverseCompositionMap.end()) { 00190 todo.push(newstates); 00191 tmpstate = rResGen.InsState(); 00192 ComposedColorSet(rGen1, currentstates.first, colors1, rGen2, tit2->X2, colors2, composedSet); 00193 rResGen.InsColors(tmpstate, composedSet); 00194 rReverseCompositionMap[newstates] = tmpstate; 00195 FD_DF("mtcParallel: todo push: (" << newstates.first << "|" 00196 << newstates.second << ") -> " 00197 << rReverseCompositionMap[newstates]); 00198 } 00199 else { 00200 tmpstate = rcit->second; 00201 } 00202 rResGen.SetTransition(rReverseCompositionMap[currentstates], 00203 tit2->Ev, tmpstate); 00204 FD_DF("mtcParallel: add transition to new generator: " 00205 << rReverseCompositionMap[currentstates] << "-" 00206 << tit2->Ev << "-" << tmpstate); 00207 } 00208 } 00209 } 00210 } 00211 00212 // compose colors 00213 void ComposedColorSet(const MtcSystem& rGen1, const Idx sidx1, ColorSet& rColors1, 00214 const MtcSystem& rGen2, const Idx sidx2, ColorSet& rColors2, 00215 ColorSet& composedSet) { 00216 00217 composedSet.Clear(); 00218 00219 AttributeColoredState attr1, attr2; 00220 ColorSet::Iterator cit; 00221 00222 #ifdef FAUDES_CHECKED 00223 try { 00224 attr1 = rGen1.States().Attribute(sidx1); 00225 } 00226 catch (faudes::Exception& exception){ 00227 std::stringstream errstr; 00228 errstr << "Index " << sidx1 << " not member of set" << std::endl; 00229 throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)", 00230 errstr.str(), 200); 00231 } 00232 try { 00233 attr2 = rGen2.States().Attribute(sidx2); 00234 } 00235 catch (faudes::Exception& exception){ 00236 std::stringstream errstr; 00237 errstr << "Index " << sidx2 << " not member of set" << std::endl; 00238 throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)", 00239 errstr.str(), 200); 00240 } 00241 #else 00242 attr1 = rGen1.States().Attribute(sidx1); 00243 attr2 = rGen2.States().Attribute(sidx2); 00244 #endif 00245 00246 if(!attr1.IsDefault()) { 00247 // iterate over colors in current state of generator 1 00248 for (cit = attr1.ColorsBegin(); cit != attr1.ColorsEnd(); cit++) { 00249 #ifdef FAUDES_CHECKED 00250 if (!rColors1.Exists(*cit)) 00251 throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)", 00252 "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors1", 201); 00253 #endif 00254 if(rColors2.Exists(*cit)) { 00255 // color also exists in second generator 00256 if(!attr2.IsDefault() && attr2.Colors().Exists(*cit)) { 00257 // current color exists in second generator's current state 00258 // -> insert into composedSet 00259 composedSet.Insert(*cit); 00260 } 00261 } 00262 else { 00263 // current color does not exist in generator 2 00264 // -> insert into composedSet 00265 composedSet.Insert(*cit); 00266 } 00267 } 00268 } 00269 00270 if(!attr2.IsDefault()) { 00271 // iterate over second generator's colors 00272 for (cit = attr2.ColorsBegin(); cit != attr2.ColorsEnd(); cit++) { 00273 #ifdef FAUDES_CHECKED 00274 if (!rColors2.Exists(*cit)) 00275 throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)", 00276 "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors2", 201); 00277 #endif 00278 if (!rColors1.Exists(*cit)) { 00279 // color does not exist in generator 1 00280 // -> insert into composedSet 00281 composedSet.Insert(*cit); 00282 } 00283 } 00284 } 00285 } 00286 00287 } // namespace faudes libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |