00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "project.h"
00024
00025 namespace faudes {
00026
00027
00028 void UniqueInit(vGenerator& rGen) {
00029 Idx inituni;
00030 StateSet::Iterator lit;
00031 TransSet::Iterator tit;
00032
00033 if (rGen.InitStatesSize() == 1) return;
00034
00035 if (rGen.StateNamesEnabled()) {
00036 std::string initname=rGen.UniqueStateName("InitUni");
00037 inituni = rGen.InsState(initname);
00038 }
00039 else {
00040 inituni = rGen.InsState();
00041 }
00042 FD_DF("UniqueInit: introducing new initial state: " << inituni);
00043
00044 FD_DF("UniqueInit: introduce outgoing transitions: ");
00045 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
00046 for (tit = rGen.TransRelBegin(*lit); tit != rGen.TransRelEnd(*lit); ++tit) {
00047 rGen.SetTransition(inituni, tit->Ev, tit->X2);
00048 FD_DF("UniqueInit: " << inituni << "-" << tit->Ev << "-" << tit->X2);
00049 }
00050 }
00051
00052 if ((! rGen.InitStatesEmpty()) || (! rGen.MarkedStatesEmpty())) {
00053 rGen.SetMarkedState(inituni);
00054 FD_DF("UniqueInit: set marked state: " << inituni);
00055 }
00056
00057 rGen.ClearInitStates();
00058
00059 rGen.SetInitState(inituni);
00060 }
00061
00062
00063 void Deterministic(const vGenerator& rGen, vGenerator& rResGen) {
00064
00065 std::vector<StateSet> power_states;
00066 std::vector<Idx> det_states;
00067 Deterministic(rGen, power_states, det_states, rResGen);
00068 }
00069
00070
00071
00072 void Deterministic(const vGenerator& rGen, std::map<Idx,StateSet>& rEntryStatesMap,
00073 vGenerator& rResGen) {
00074
00075 rEntryStatesMap.clear();
00076
00077 std::vector<StateSet> power_states;
00078 std::vector<Idx> det_states;
00079
00080 Deterministic(rGen, power_states, det_states, rResGen);
00081
00082 std::vector<StateSet>::size_type i;
00083 for (i = 0; i < power_states.size(); ++i) {
00084 rEntryStatesMap.insert(std::pair<Idx,StateSet>(
00085 det_states[i], power_states[i]));
00086 }
00087 }
00088
00089
00090 void Deterministic(const vGenerator& rGen, std::vector<StateSet>& rPowerStates,
00091 std::vector<Idx>& rDetStates, vGenerator& rResGen) {
00092
00093
00094
00095
00096
00097
00098
00099
00100 vGenerator* pResGen = &rResGen;
00101 if(&rResGen== &rGen) {
00102 pResGen= rResGen.NewP();
00103 }
00104
00105
00106 pResGen->Clear();
00107 rPowerStates.clear();
00108 rDetStates.clear();
00109
00110 pResGen->Name(CollapsString("Det(" + rGen.Name() + ")"));
00111
00112 FD_DF("Deterministic A " << rGen.Alphabet().ToString());
00113 pResGen->InjectAlphabet(rGen.Alphabet());
00114 FD_DF("Deterministic B");
00115
00116
00117 TransSetEvX1X2 trel_evx1x2;
00118 rGen.TransRel(trel_evx1x2);
00119 typedef std::multimap< Idx,std::vector<StateSet>::size_type > T_HASHMAP;
00120 T_HASHMAP hashmap;
00121 std::vector<StateSet>::size_type current_vecindex;
00122 std::pair< std::map<StateSet,Idx>::iterator,bool > result;
00123 TransSet::Iterator transrel_end = rGen.TransRelEnd();
00124 StateSet newset;
00125 StateSet::Iterator lit;
00126 const Idx max_idx = std::numeric_limits<Idx>::max();
00127
00128
00129 if (rGen.InitStatesEmpty()) {
00130 if(pResGen != &rResGen) {
00131 pResGen->Move(rResGen);
00132 delete pResGen;
00133 }
00134 return;
00135 }
00136
00137 Idx newstate = pResGen->InsInitState();
00138
00139 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
00140
00141 newset.Insert(*lit);
00142
00143 if (rGen.ExistsMarkedState(*lit)) {
00144 pResGen->SetMarkedState(newstate);
00145 FD_DF("Deterministic: setting as mstate: " << rGen.SStr(newstate));
00146 }
00147 }
00148 FD_DF("Deterministic: created subset of initial states {"
00149 << newset.ToString() << "} with deterministic state index "
00150 << rGen.SStr(newstate));
00151
00152 rPowerStates.push_back(newset);
00153 rDetStates.push_back(newstate);
00154 hashmap.insert(std::make_pair(newset.Signature(), (Idx)rPowerStates.size() - 1));
00155
00156
00157
00158 for (current_vecindex = 0; current_vecindex < rPowerStates.size();
00159 ++current_vecindex) {
00160 FD_DF("Deterministic: current power set: {"
00161 << rPowerStates[current_vecindex].ToString() << "} -> "
00162 << rDetStates[current_vecindex]);
00163
00164 std::vector<StateSet> newset_vec;
00165 std::vector<Idx> event_vec;
00166
00167
00168 FD_DF("Deterministic: starting multiway merge...");
00169 std::list<TransSet::Iterator> merge_iterators;
00170 std::vector<Transition> trans_vec;
00171
00172
00173 TransSet::Iterator tit;
00174 for (lit = rPowerStates[current_vecindex].Begin();
00175 lit != rPowerStates[current_vecindex].End(); ++lit) {
00176 tit = rGen.TransRelBegin(*lit);
00177 if (tit != rGen.TransRelEnd(*lit)) {
00178 merge_iterators.push_back(tit);
00179 FD_DF("Deterministic: added merge iterator: " << rGen.SStr(tit->X1)
00180 << "-" << rGen.EStr(tit->Ev) << "-" << rGen.SStr(tit->X2));
00181 }
00182 }
00183
00184
00185 while (! merge_iterators.empty()) {
00186 Idx currentevent = max_idx;
00187 std::list<TransSet::Iterator>::iterator i;
00188 std::list<TransSet::Iterator>::iterator currentit = merge_iterators.end();
00189 for (i = merge_iterators.begin(); i != merge_iterators.end(); ++i) {
00190 if ((*i)->Ev < currentevent) {
00191 currentevent = (*i)->Ev;
00192 currentit = i;
00193 }
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 Idx currentstate;
00205 while (currentit != merge_iterators.end()) {
00206 currentstate = (*currentit)->X1;
00207 TransSet::Iterator& j = *currentit;
00208 while (1) {
00209
00210 if (j == transrel_end) {
00211 std::list<TransSet::Iterator>::iterator tmpit = currentit;
00212 ++currentit;
00213 merge_iterators.erase(tmpit);
00214 break;
00215 }
00216
00217 else if (j->X1 == currentstate) {
00218
00219 if (j->Ev == currentevent) {
00220 trans_vec.push_back(*j);
00221 FD_DF("Deterine: adding transition to list: "
00222 << rGen.SStr(j->X1) << "-" << rGen.EStr(j->Ev) << "-"
00223 << rGen.SStr(j->X2));
00224 }
00225
00226 else {
00227 ++currentit;
00228 break;
00229 }
00230 }
00231
00232 else {
00233 std::list<TransSet::Iterator>::iterator tmpit = currentit;
00234 ++currentit;
00235 merge_iterators.erase(tmpit);
00236 break;
00237 }
00238 ++j;
00239 }
00240 }
00241 }
00242
00243
00244 FD_DF("Deterministic: partitioning the transition vector...");
00245 std::vector<Transition>::iterator tv_it;
00246 StateSet newset;
00247 Idx lastevent = 0;
00248 for (tv_it = trans_vec.begin(); tv_it != trans_vec.end(); ++tv_it) {
00249 if ((tv_it->Ev == lastevent) || (lastevent == 0)) {
00250 newset.Insert(tv_it->X2);
00251 lastevent = tv_it->Ev;
00252 }
00253 else {
00254 FD_DF("Deterministic: partition: {" << newset.ToString()
00255 << "} with event " << rGen.EStr(lastevent));
00256 newset_vec.push_back(newset);
00257 event_vec.push_back(lastevent);
00258 newset.Clear();
00259 newset.Insert(tv_it->X2);
00260 lastevent = tv_it->Ev;
00261 }
00262 }
00263 if (! newset.Empty()) {
00264 FD_DF("Deterministic: partition: {" << newset.ToString()
00265 << "} with event " << rGen.EStr(lastevent));
00266 newset_vec.push_back(newset);
00267 event_vec.push_back(lastevent);
00268 }
00269 FD_DF("Deterministic: partitioning the transition vector finished");
00270 FD_DF("Deterministic: multiway merge finished");
00271
00272
00273 std::vector<StateSet>::size_type nsv_index;
00274 for (nsv_index = 0; nsv_index < newset_vec.size(); ++nsv_index) {
00275 StateSet& currentset = newset_vec[nsv_index];
00276 Idx currentevent = event_vec[nsv_index];
00277 Idx tmp_x2 = 0;
00278 Idx sig = currentset.Signature();
00279
00280 std::pair<T_HASHMAP::iterator,T_HASHMAP::iterator> phit
00281 = hashmap.equal_range(sig);
00282 T_HASHMAP::iterator hit = phit.first;
00283 for (hit = phit.first; hit != phit.second; ++hit) {
00284
00285 if (currentset == rPowerStates[hit->second]) {
00286 tmp_x2 = rDetStates[hit->second];
00287 break;
00288 }
00289 }
00290
00291
00292 if (tmp_x2 == 0) {
00293
00294 tmp_x2 = pResGen->InsState();
00295
00296 rPowerStates.push_back(currentset);
00297 rDetStates.push_back(tmp_x2);
00298 hashmap.insert(std::make_pair(sig, (Idx)rPowerStates.size() - 1));
00299 FD_DF("Deterministic: added new state "
00300 << rGen.SStr(tmp_x2)
00301 << " for new subset {" << currentset.ToString() << "}");
00302
00303 for (lit = currentset.Begin(); lit != currentset.End(); ++lit) {
00304 if (rGen.ExistsMarkedState(*lit)) {
00305 pResGen->SetMarkedState(tmp_x2);
00306 break;
00307 }
00308 }
00309 }
00310
00311 pResGen->SetTransition(rDetStates[current_vecindex], currentevent, tmp_x2);
00312 }
00313 }
00314
00315 if (rGen.StateNamesEnabled() && pResGen->StateNamesEnabled()) {
00316 FD_DF("Deterministic: fixing names...");
00317
00318 std::vector<StateSet>::size_type i;
00319
00320 std::vector<Idx>::const_iterator dit;
00321 for (i = 0; i < rPowerStates.size(); ++i) {
00322
00323 std::string name = "{";
00324 for (lit = rPowerStates[i].Begin(); lit != rPowerStates[i].End(); ++lit) {
00325 if (rGen.StateName(*lit) != "") {
00326 name = name + rGen.StateName(*lit) + ",";
00327 }
00328 else {
00329 name = name + ToStringInteger(*lit) + ",";
00330 }
00331 }
00332 name.erase(name.length() - 1);
00333 name = name + "}";
00334 FD_DF("Deterministic: setting state name \"" << name << "\" for index "
00335 << rDetStates[i]);
00336 pResGen->StateName(rDetStates[i], name);
00337 }
00338 }
00339
00340
00341 if(pResGen != &rResGen) {
00342 pResGen->Move(rResGen);
00343 delete pResGen;
00344 }
00345
00346 }
00347
00348
00349
00350
00351 void ProjectNonDet(vGenerator& rGen, const EventSet& rProjectAlphabet) {
00352
00353
00354
00355 StateSet reach;
00356 std::stack<Idx> todo;
00357 StateSet done;
00358 Idx currentstate;
00359 StateSet::Iterator lit;
00360 TransSet::Iterator tit;
00361 TransSet::Iterator tit_end;
00362
00363
00364
00365 for (lit = rGen.InitStatesBegin(); lit != rGen.InitStatesEnd(); ++lit) {
00366 FD_DF("ProjectNonDet: todo add: " << rGen.SStr(*lit));
00367 todo.push(*lit);
00368 }
00369
00370
00371 while (! todo.empty()) {
00372 currentstate = todo.top();
00373 todo.pop();
00374 done.Insert(currentstate);
00375 FD_DF("ProjectNonDet: current state: " << rGen.SStr(currentstate));
00376
00377
00378 reach.Clear();
00379 LocalAccessibleReach(rGen, rProjectAlphabet, currentstate, reach);
00380 FD_DF("ProjectNonDet: local reach: " << reach.ToString());
00381
00382
00383
00384 tit = rGen.TransRelBegin(currentstate);
00385 tit_end = rGen.TransRelEnd(currentstate);
00386 while(tit != tit_end) {
00387 FD_DF("ProjectNonDet: current transition: " << rGen.SStr(tit->X1)
00388 << "-" << rGen.EStr(tit->Ev) << "-" << rGen.SStr(tit->X2));
00389 if (! rProjectAlphabet.Exists(tit->Ev)) {
00390 FD_DF("ProjectNonDet: deleting current transition");
00391 TransSet::Iterator tit_tmp = tit;
00392 ++tit;
00393 rGen.ClrTransition(tit_tmp);
00394 } else {
00395 ++tit;
00396 }
00397 }
00398
00399
00400 FD_DF("ProjectNonDet: relinking outgoing transitions...");
00401 for (lit = reach.Begin(); lit != reach.End(); ++lit) {
00402 tit = rGen.TransRelBegin(*lit);
00403 tit_end = rGen.TransRelEnd(*lit);
00404 for (; tit != tit_end; ++tit) {
00405 if (rProjectAlphabet.Exists(tit->Ev)) {
00406 FD_DF("ProjectNonDet: relinking transition: " << rGen.TStr(*tit) << " to " << rGen.SStr(currentstate));
00407 rGen.SetTransition(currentstate, tit->Ev, tit->X2);
00408 if (! done.Exists(tit->X2)) {
00409 FD_DF("ProjectNonDet: todo push: " << rGen.SStr(tit->X2));
00410 todo.push(tit->X2);
00411 }
00412 }
00413 }
00414
00415 if (rGen.ExistsMarkedState(*lit)) {
00416 FD_DF("ProjectNonDet: setting marked state " << rGen.SStr(currentstate));
00417 rGen.SetMarkedState(currentstate);
00418 }
00419 }
00420 }
00421
00422
00423 rGen.InjectAlphabet(rProjectAlphabet);
00424
00425
00426 rGen.Name(CollapsString("Pro(" + rGen.Name() + ")"));
00427 }
00428
00429
00430
00431
00432 void Project(const vGenerator& rGen, const EventSet& rProjectAlphabet, vGenerator& rResGen) {
00433 FD_DF("Project(...)");
00434
00435
00436 vGenerator* g1= rGen.NewP();
00437 *g1=rGen;
00438 g1->StateNamesEnabled(false);
00439
00440 ProjectNonDet(*g1, rProjectAlphabet);
00441
00442 vGenerator* g2 = rGen.NewP();
00443 g2->StateNamesEnabled(false);
00444 Deterministic(*g1, *g2);
00445 delete g1;
00446
00447 bool se= rResGen.StateNamesEnabled();
00448 rResGen.StateNamesEnabled(false);
00449 StateMin(*g2, rResGen);
00450 rResGen.StateNamesEnabled(se);
00451 delete g2;
00452
00453 rResGen.Name(CollapsString(rGen.Name()+" Project"));
00454 }
00455
00456
00457
00458
00459 void Project(const vGenerator& rGen, const EventSet& rProjectAlphabet,
00460 std::map<Idx,StateSet>& rEntryStatesMap, vGenerator& rResGen) {
00461 FD_DF("Project(...)");
00462
00463 std::map<Idx,StateSet> tmp_entrystatemap;
00464
00465 rGen.Copy(rResGen);
00466
00467 ProjectNonDet(rResGen, rProjectAlphabet);
00468
00469 Generator tmp;
00470 Deterministic(rResGen, tmp_entrystatemap, tmp);
00471
00472 std::vector<StateSet> subsets;
00473 std::vector<Idx> newindices;
00474
00475 StateMin(tmp, rResGen, subsets, newindices);
00476
00477 std::vector<StateSet>::size_type i;
00478 std::map<Idx,StateSet>::iterator esmit;
00479 StateSet::Iterator sit;
00480 for (i = 0; i < subsets.size(); ++i) {
00481 StateSet tmpstates;
00482 for (sit = subsets[i].Begin(); sit != subsets[i].End(); ++sit) {
00483 esmit = tmp_entrystatemap.find(*sit);
00484 #ifdef FAUDES_DEBUG_CHECKED
00485 if (esmit == tmp_entrystatemap.end()) {
00486 std::cerr << "algorithm error" << std::endl;
00487 abort();
00488 }
00489 #endif
00490
00491 tmpstates.InsertSet(esmit->second);
00492 }
00493
00494 rEntryStatesMap.insert(std::make_pair(newindices[i], tmpstates));
00495 }
00496 }
00497
00498
00499
00500 void InvProject(vGenerator& rGen, const EventSet& rProjectAlphabet) {
00501
00502 if(! (rProjectAlphabet >= (EventSet) rGen.Alphabet() ) ){
00503 std::stringstream errstr;
00504 errstr << "Input alphabet has to contain alphabet of generator \"" << rGen.Name() << "\"";
00505 throw Exception("InvProject(Generator,EventSet)", errstr.str(), 506);
00506 }
00507 EventSet newevents = rProjectAlphabet - rGen.Alphabet();
00508
00509 rGen.InsEvents(newevents);
00510 FD_DF("InvProject: adding events \"" << newevents.ToString()
00511 << "\" at every state");
00512 StateSet::Iterator lit;
00513 EventSet::Iterator eit;
00514 for (lit = rGen.StatesBegin(); lit != rGen.StatesEnd(); ++lit) {
00515 for (eit = newevents.Begin(); eit != newevents.End(); ++eit) {
00516 rGen.SetTransition(*lit, *eit, *lit);
00517 }
00518 }
00519 }
00520
00521
00522
00523 void CreateEntryStatesMap(const std::map<StateSet,Idx>& rRevEntryStatesMap,
00524 std::map<Idx,StateSet>& rEntryStatesMap) {
00525 std::map<StateSet,Idx>::const_iterator it;
00526 for (it = rRevEntryStatesMap.begin(); it != rRevEntryStatesMap.end(); ++it) {
00527 rEntryStatesMap.insert(std::make_pair(it->second, it->first));
00528 }
00529 }
00530
00531
00532
00533 }