00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "parallel.h"
00024
00025 namespace faudes {
00026
00027
00028 void Parallel(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00029
00030 std::map< std::pair<Idx,Idx>, Idx> rcmap;
00031
00032 vGenerator* pResGen = &rResGen;
00033 if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00034 pResGen= rResGen.NewP();
00035 }
00036
00037 Parallel(rGen1, rGen2, rcmap, *pResGen);
00038 if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled() && rResGen.StateNamesEnabled())
00039 SetComposedStateNames(rGen1, rGen2, rcmap, *pResGen);
00040 else
00041 pResGen->ClearStateNames();
00042
00043 if(pResGen != &rResGen) {
00044 rResGen = *pResGen;
00045 delete pResGen;
00046 }
00047 }
00048
00049
00050
00051 void Parallel(
00052 const vGenerator& rGen1, const vGenerator& rGen2,
00053 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00054 vGenerator& rResGen)
00055 {
00056 FD_DF("Parallel(" << &rGen1 << "," << &rGen2 << ")");
00057
00058 vGenerator* pResGen = &rResGen;
00059 if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00060 pResGen= rResGen.NewP();
00061 }
00062 pResGen->Clear();
00063 pResGen->Name(CollapsString(rGen1.Name()+"||"+rGen2.Name()));
00064
00065 EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00066 FD_DF("Parallel: shared events: " << sharedalphabet.ToString());
00067
00068
00069 EventSet::Iterator eit;
00070 for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00071 pResGen->InsEvent(*eit);
00072 }
00073 for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00074 pResGen->InsEvent(*eit);
00075 }
00076 FD_DF("Parallel: inserted indices in rResGen.alphabet( "
00077 << pResGen->AlphabetToString() << ")");
00078
00079
00080 std::stack< std::pair<Idx,Idx> > todo;
00081
00082 std::pair<Idx,Idx> currentstates, newstates;
00083
00084 Idx tmpstate;
00085 StateSet::Iterator lit1, lit2;
00086 TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00087 std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00088
00089
00090 FD_DF("Parallel: adding all combinations of initial states to todo:");
00091 for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00092 for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00093 currentstates = std::make_pair(*lit1, *lit2);
00094 todo.push(currentstates);
00095 rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00096 FD_DF("Parallel: (" << *lit1 << "|" << *lit2 << ") -> "
00097 << rReverseCompositionMap[currentstates]);
00098 }
00099 }
00100
00101
00102 FD_DF("Parallel: processing reachable states:");
00103 while (! todo.empty()) {
00104
00105 currentstates = todo.top();
00106 todo.pop();
00107 FD_DF("Parallel: processing (" << currentstates.first << "|"
00108 << currentstates.second << ") -> "
00109 << rReverseCompositionMap[currentstates]);
00110
00111
00112 tit1 = rGen1.TransRelBegin(currentstates.first);
00113 tit1_end = rGen1.TransRelEnd(currentstates.first);
00114 for (; tit1 != tit1_end; ++tit1) {
00115
00116 if (! sharedalphabet.Exists(tit1->Ev)) {
00117 FD_DF("Parallel: exists only in rGen1");
00118 newstates = std::make_pair(tit1->X2, currentstates.second);
00119
00120 rcit = rReverseCompositionMap.find(newstates);
00121 if (rcit == rReverseCompositionMap.end()) {
00122 todo.push(newstates);
00123 tmpstate = pResGen->InsState();
00124 rReverseCompositionMap[newstates] = tmpstate;
00125 FD_DF("Parallel: todo push: (" << newstates.first << "|"
00126 << newstates.second << ") -> "
00127 << rReverseCompositionMap[newstates]);
00128 }
00129 else {
00130 tmpstate = rcit->second;
00131 }
00132 pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev,
00133 tmpstate);
00134 FD_DF("Parallel: add transition to new generator: "
00135 << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-"
00136 << tmpstate);
00137 }
00138
00139 else {
00140 FD_DF("Parallel: common event");
00141
00142 tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00143 tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00144 for (; tit2 != tit2_end; ++tit2) {
00145 newstates = std::make_pair(tit1->X2, tit2->X2);
00146
00147 rcit = rReverseCompositionMap.find(newstates);
00148 if (rcit == rReverseCompositionMap.end()) {
00149 todo.push(newstates);
00150 tmpstate = pResGen->InsState();
00151 rReverseCompositionMap[newstates] = tmpstate;
00152 FD_DF("Parallel: todo push: (" << newstates.first << "|"
00153 << newstates.second << ") -> "
00154 << rReverseCompositionMap[newstates]);
00155 }
00156 else {
00157 tmpstate = rcit->second;
00158 }
00159 pResGen->SetTransition(rReverseCompositionMap[currentstates],
00160 tit1->Ev, tmpstate);
00161 FD_DF("Parallel: add transition to new generator: "
00162 << rReverseCompositionMap[currentstates] << "-"
00163 << tit1->Ev << "-" << tmpstate);
00164 }
00165 }
00166 }
00167
00168
00169 tit2 = rGen2.TransRelBegin(currentstates.second);
00170 tit2_end = rGen2.TransRelEnd(currentstates.second);
00171 for (; tit2 != tit2_end; ++tit2) {
00172 if (! sharedalphabet.Exists(tit2->Ev)) {
00173 FD_DF("Parallel: exists only in rGen2");
00174 newstates = std::make_pair(currentstates.first, tit2->X2);
00175
00176 rcit = rReverseCompositionMap.find(newstates);
00177 if (rcit == rReverseCompositionMap.end()) {
00178 todo.push(newstates);
00179 tmpstate = pResGen->InsState();
00180 rReverseCompositionMap[newstates] = tmpstate;
00181 FD_DF("Parallel: todo push: (" << newstates.first << "|"
00182 << newstates.second << ") -> "
00183 << rReverseCompositionMap[newstates]);
00184 }
00185 else {
00186 tmpstate = rcit->second;
00187 }
00188 pResGen->SetTransition(rReverseCompositionMap[currentstates],
00189 tit2->Ev, tmpstate);
00190 FD_DF("Parallel: add transition to new generator: "
00191 << rReverseCompositionMap[currentstates] << "-"
00192 << tit2->Ev << "-" << tmpstate);
00193 }
00194 }
00195 }
00196
00197
00198 for (lit1 = rGen1.MarkedStatesBegin();
00199 lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00200 for (lit2 = rGen2.MarkedStatesBegin();
00201 lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00202 currentstates = std::make_pair(*lit1, *lit2);
00203 rcit = rReverseCompositionMap.find(currentstates);
00204 if (rcit != rReverseCompositionMap.end()) {
00205 pResGen->SetMarkedState(rcit->second);
00206 }
00207 }
00208 }
00209 FD_DF("Parallel: set marked states at the end: "
00210 << pResGen->MarkedStatesToString());
00211
00212 if(pResGen != &rResGen) {
00213 rResGen = *pResGen;
00214 delete pResGen;
00215 }
00216 }
00217
00218
00219
00220 void SParallel(const vGenerator& rGen1, const vGenerator& rGen2, vGenerator& rResGen) {
00221 std::map< std::pair<Idx,Idx>, Idx> rcmap;
00222 SParallel(rGen1, rGen2, rcmap, rResGen);
00223 }
00224
00225
00226
00227 void SParallel(
00228 const vGenerator& rGen1, const vGenerator& rGen2,
00229 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00230 vGenerator& rResGen)
00231 {
00232 FD_DF("SParallel(" << &rGen1 << "," << &rGen2 << ")");
00233
00234 vGenerator* pResGen = &rResGen;
00235 if(&rResGen== &rGen1 || &rResGen== &rGen2) {
00236 pResGen= rResGen.NewP();
00237 }
00238 pResGen->Clear();
00239
00240 pResGen->InjectAlphabet(rGen1.Alphabet() * rGen2.Alphabet());
00241 FD_DF("SParallel: shared alphabet: "
00242 << (rGen1.Alphabet() * rGen2.Alphabet()).ToString());
00243
00244
00245 std::stack< std::pair<Idx,Idx> > todo;
00246
00247 std::pair<Idx,Idx> currentstates, newstates;
00248
00249 Idx tmpstate;
00250
00251 StateSet::Iterator lit1, lit2;
00252 TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00253 std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00254
00255
00256 FD_DF("SParallel: adding all combinations of initial states to todo:");
00257 for (lit1 = rGen1.InitStatesBegin();
00258 lit1 != rGen1.InitStatesEnd(); ++lit1) {
00259 for (lit2 = rGen2.InitStatesBegin();
00260 lit2 != rGen2.InitStatesEnd(); ++lit2) {
00261 currentstates = std::make_pair(*lit1, *lit2);
00262 todo.push(currentstates);
00263 rReverseCompositionMap[currentstates] = pResGen->InsInitState();
00264 FD_DF("SParallel: (" << *lit1 << "|" << *lit2 << ") -> "
00265 << rReverseCompositionMap[currentstates]);
00266 }
00267 }
00268
00269
00270 FD_DF("SParallel: processing reachable states:");
00271 while (! todo.empty()) {
00272
00273 currentstates = todo.top();
00274 todo.pop();
00275 FD_DF("SParallel: processing (" << currentstates.first << "|"
00276 << currentstates.second << ") -> " << rReverseCompositionMap[currentstates]);
00277
00278 tit1 = rGen1.TransRelBegin(currentstates.first);
00279 tit1_end = rGen1.TransRelEnd(currentstates.first);
00280 tit2 = rGen2.TransRelBegin(currentstates.second);
00281 tit2_end = rGen2.TransRelEnd(currentstates.second);
00282 while ((tit1 != tit1_end) && (tit2 != tit2_end)) {
00283
00284 if (tit1->Ev == tit2->Ev) {
00285 newstates = std::make_pair(tit1->X2, tit2->X2);
00286
00287 rcit = rReverseCompositionMap.find(newstates);
00288 if (rcit == rReverseCompositionMap.end()) {
00289 todo.push(newstates);
00290 tmpstate = pResGen->InsState();
00291 rReverseCompositionMap[newstates] = tmpstate;
00292 FD_DF("SParallel: todo push: (" << newstates.first << "|"
00293 << newstates.second << ") -> " << rReverseCompositionMap[newstates]);
00294 }
00295 else {
00296 tmpstate = rcit->second;
00297 }
00298 pResGen->SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, tmpstate);
00299 FD_DF("SParallel: add transition to new generator: "
00300 << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" << tmpstate);
00301 ++tit1;
00302 ++tit2;
00303 }
00304
00305 else if (tit1->Ev < tit2->Ev) {
00306 ++tit1;
00307 }
00308
00309 else if (tit1->Ev > tit2->Ev) {
00310 ++tit2;
00311 }
00312 }
00313 }
00314
00315
00316 for (lit1 = rGen1.MarkedStatesBegin();
00317 lit1 != rGen1.MarkedStatesEnd(); ++lit1) {
00318 for (lit2 = rGen2.MarkedStatesBegin();
00319 lit2 != rGen2.MarkedStatesEnd(); ++lit2) {
00320 currentstates = std::make_pair(*lit1, *lit2);
00321 rcit = rReverseCompositionMap.find(currentstates);
00322 if (rcit != rReverseCompositionMap.end()) {
00323 pResGen->SetMarkedState(rcit->second);
00324 }
00325 }
00326 }
00327 FD_DF("SParallel: set marked states at the end: "
00328 << pResGen->MarkedStatesToString());
00329
00330 if(pResGen != &rResGen) {
00331 rResGen = *pResGen;
00332 delete pResGen;
00333 }
00334 }
00335
00336
00337
00338
00339
00340 void SetComposedStateNames(
00341 const vGenerator& rGen1, const vGenerator& rGen2,
00342 std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap,
00343 vGenerator& rGen12)
00344 {
00345 std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00346 for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00347 Idx x1=rcit->first.first;
00348 Idx x2=rcit->first.second;
00349 Idx x12=rcit->second;
00350 if(!rGen12.ExistsState(x12)) continue;
00351 std::string name1= rGen1.StateName(x1);
00352 if(name1=="") name1=ToStringInteger(x1);
00353 std::string name2= rGen2.StateName(x2);
00354 if(name2=="") name1=ToStringInteger(x2);
00355 std::string name12= name1 + "|" + name2;
00356 name12=rGen12.UniqueStateName(name12);
00357 rGen12.StateName(x12,name12);
00358 }
00359 }
00360
00361
00362 }