00001
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <op_bisimulation.h>
00032
00033 namespace faudes {
00034
00035 void calcBisimulation(Generator& rGenOrig, map<Idx,Idx>& rMapStateToPartition, Generator& rGenPart, vector<Idx>& rNewPartitions)
00036 {
00037 OP_DF("calcBisimulation(" << rGenOrig.Name() << ", rMapStateToPartition, " << rGenPart.Name() << ", rNewPartitions)");
00038
00039 Bisimulation bisim = Bisimulation(rGenOrig);
00040
00041 bisim.partition(rMapStateToPartition, rGenPart, rNewPartitions);
00042 #ifdef OP_DF_PLOT
00043 cout << "The result of the partition refinement is:" << endl;
00044 bisim.writeW();
00045 bisim.writeRo();
00046 #endif
00047 OP_DF("calcBisimulation: leaving function");
00048 }
00049
00050
00051 void calcBisimulation(Generator& rGenOrig, map<Idx,Idx>& rMapStateToPartition, vector<Idx>& rNewPartitions)
00052 {
00053 OP_DF("calcBisimulation(" << rGenOrig.Name() << ", rMapStateToPartition, rNewPartitions)");
00054
00055 Bisimulation bisim = Bisimulation(rGenOrig);
00056
00057 bisim.partition(rMapStateToPartition, rNewPartitions);
00058 #ifdef FAUDES_DEBUG_FUNCTION
00059 cout << "The result of the partition refinement is:" << endl;
00060 bisim.writeW();
00061 bisim.writeRo();
00062 #endif
00063 OP_DF("calcBisimulation: leaving function");
00064 }
00065
00066
00067 Bisimulation::Bisimulation(Generator& g)
00068 {
00069 OP_DF("Bisimulation::Bisimulation(" << g.Name() << ")");
00070 gen = &g;
00071 gen->TransRel(tset_evx2x1);
00072 index=1;
00073
00074
00075 Partition universalPartition;
00076 universalPartition.index=index;
00077 universalPartition.pFather=NULL;
00078 universalPartition.pFirstChild=NULL;
00079 universalPartition.pSecondChild=NULL;
00080 universalPartition.pBrother=NULL;
00081 universalPartition.states = gen->States();
00082 universalPartition.numberOfStates = universalPartition.states.Size();
00083
00084
00085 W[index]=universalPartition;
00086
00087
00088 ro.push_back(&W[index]);
00089 roDividers.insert(&W[index]);
00090
00091 index++;
00092
00093 OP_DF("Bisimulation::Bisimulation: leaving function");
00094 }
00095
00096
00097 void Bisimulation::partitionSplitter(Partition& B)
00098 {
00099 OP_DF("Bisimulation::partitionSplitter(B)");
00100 OP_DF("Bisimulation::partitionSplitter: index of current coset is " << B.index);
00101
00102
00103
00104
00105
00106 Partition* pFather = B.pFather;
00107
00108
00109 Partition* pSmallerPart;
00110 Partition* pLargerPart;
00111
00112 if(B.numberOfStates <= B.pBrother->numberOfStates)
00113 {
00114 pSmallerPart = &B;
00115 pLargerPart = B.pBrother;
00116 }
00117 else
00118 {
00119 pSmallerPart = B.pBrother;
00120 pLargerPart = &B;
00121 }
00122
00123 OP_DF("Bisimulation::partitionSplitter: the chosen (smaller) coset for segmentation has the index: " << pSmallerPart->index);
00124 OP_DF("Bisimulation::partitionSplitter: the larger coset has the index: " << pLargerPart->index << "\n");
00125
00126
00127
00128
00129 EventSet::Iterator eIt;
00130 EventSet::Iterator eItBegin=gen->AlphabetBegin();
00131 EventSet::Iterator eItEnd=gen->AlphabetEnd();
00132
00133
00134 StateSet::Iterator sIt;
00135 StateSet::Iterator sItBegin;
00136 StateSet::Iterator sItEnd;
00137
00138
00139 TransSetEvX2X1::Iterator tIt;
00140 TransSetEvX2X1::Iterator tItBegin;
00141 TransSetEvX2X1::Iterator tItEnd;
00142
00143
00144 vector<Partition*>::iterator roIt;
00145
00146
00147 stack<vector<Partition*>::iterator> toDo;
00148
00149
00150
00151 for (eIt=eItBegin; eIt != eItEnd; ++eIt)
00152 {
00153
00154
00155 if(pFather->infoMap.find(*eIt) != pFather->infoMap.end() ){
00156 OP_DF("Bisimulation::partitionSplitter: partitioning for event " << gen->EventName(*eIt));
00157
00158
00159 pLargerPart->infoMap[*eIt]= pFather->infoMap.find(*eIt)->second;
00160
00161 pSmallerPart->infoMap[*eIt]=map<Idx,Idx>();
00162
00163 computeInfoMaps(*(pSmallerPart), pSmallerPart, pLargerPart, eIt);
00164
00165 map<Idx, map<Idx, Idx> >::iterator imIt = pSmallerPart->infoMap.find(*eIt);
00166 if(imIt == pSmallerPart->infoMap.end() )
00167 pSmallerPart->infoMap.erase(imIt);
00168 imIt = pLargerPart->infoMap.find(*eIt);
00169 if(imIt == pLargerPart->infoMap.end() )
00170 pLargerPart->infoMap.erase(imIt);
00171
00172 OP_DF("Bisimulation::partitionSplitter: computing predecessor cosets of parent coset with index " << pFather->index);
00173 Idx tempState;
00174
00175 for(roIt=ro.begin(); roIt!=ro.end(); roIt++)
00176 {
00177
00178 tempState = *((*roIt)->states.Begin());
00179 OP_DF("Bisimulation::partitionSplitter: checking candidate coset with index " << (*roIt)->index << " and its state " << gen->StateName(tempState) << " [" << tempState << "]");
00180
00181
00182 if(stateLeadsToPartition(tempState, *pFather, eIt))
00183 {
00184 toDo.push(roIt);
00185 OP_DF("Bisimulation::partitionSplitter: coset with index " << (*roIt)->index << " is predecessor for parent coset with index " << (*pFather).index << " and event = " << gen->EventName(*eIt) << " and was pushed on toDo-stack");
00186 }
00187 }
00188
00189
00190
00191 Idx index1,index2,index3;
00192 vector<Idx> removeSet;
00193 vector<Partition*> addSet;
00194
00195
00196 while(!toDo.empty())
00197 {
00198 roIt=toDo.top();
00199 toDo.pop();
00200 OP_DF("Bisimulation::partitionSplitter: current coset taken from todo-stack has index " << (*roIt)->index);
00201
00202 bool nonNull[3] = {0,0,0};
00203
00204
00205 Partition X1,X2,X3;
00206 index1=index;
00207 W[index1]=X1;
00208 W[index1].index=index1;
00209 index++;
00210 index2=index;
00211 W[index2]=X2;
00212 W[index2].index=index2;
00213 index++;
00214 index3=index;
00215 W[index3]=X3;
00216 W[index3].index=index3;
00217 index++;
00218
00219 sItBegin = (*roIt)->states.Begin();
00220 sItEnd = (*roIt)->states.End();
00221
00222
00223 map<Idx, map<Idx, Idx> >::const_iterator itMapFather = pFather->infoMap.find(*eIt);
00224
00225 map<Idx, map<Idx, Idx> >::const_iterator itMapSmallerPart = pSmallerPart->infoMap.find(*eIt);
00226
00227
00228
00229 for(sIt=sItBegin; sIt!=sItEnd; sIt++)
00230 {
00231 if(itMapSmallerPart == pSmallerPart->infoMap.end() ){
00232 W[index2].states.Insert(*sIt);
00233 nonNull[1]=true;
00234 }
00235 else if(itMapSmallerPart->second.find(*sIt)==itMapSmallerPart->second.end())
00236 {
00237 W[index2].states.Insert(*sIt);
00238 nonNull[1]=true;
00239 }
00240 else
00241 {
00242 if(itMapFather->second.find(*sIt)->second==itMapSmallerPart->second.find(*sIt)->second)
00243 {
00244 W[index1].states.Insert(*sIt);
00245 nonNull[0]=true;
00246 }
00247 if(itMapFather->second.find(*sIt)->second > itMapSmallerPart->second.find(*sIt)->second)
00248 {
00249 W[index3].states.Insert(*sIt);
00250 nonNull[2]=true;
00251 }
00252 }
00253 }
00254
00255
00256 switch(nonNull[0]+nonNull[1]*2+nonNull[2]*4)
00257 {
00258
00259 case 1:
00260 index=index-3;
00261 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has not been split ");
00262 break;
00263
00264 case 2:
00265 index=index-3;
00266 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has not been split ");
00267 break;
00268
00269 case 4:
00270 index=index-3;
00271 OP_DF("partition " << (*roIt)->index << " has not been split ");
00272 break;
00273
00274 case 3:
00275 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has been split into cosets X1 and X2");
00276
00277
00278 W.erase(W.find(index3));
00279
00280
00281 W[index2].pBrother=&W[index1];
00282 W[index2].pFather=*roIt;
00283 W[index2].pFirstChild=NULL;
00284 W[index2].pSecondChild=NULL;
00285 W[index2].numberOfStates=W[index2].states.Size();
00286 W[index1].pBrother=&W[index2];
00287 W[index1].pFather=*roIt;
00288 W[index1].pFirstChild=NULL;
00289 W[index1].pSecondChild=NULL;
00290 W[index1].numberOfStates=W[index1].states.Size();
00291 (*roIt)->pFirstChild=&W[index1];
00292 (*roIt)->pSecondChild=&W[index2];
00293
00294
00295 (*roIt)->states.Clear();
00296
00297
00298 if(roDividers.find(*roIt)!=roDividers.end())
00299 roDividers.erase(roDividers.find(*roIt));
00300
00301
00302 if((*roIt)->pFather!=NULL && (*roIt)->pFather != pFather)
00303 {
00304 if((*roIt)->pFather->pFirstChild->pFirstChild!=NULL && (*roIt)->pFather->pSecondChild->pSecondChild!=NULL)
00305 {
00306 (*roIt)->pFather->infoMap.clear();
00307 }
00308 }
00309
00310
00311 removeSet.push_back((*roIt)->index);
00312 addSet.push_back(&W[index1]);
00313 addSet.push_back(&W[index2]);
00314 roDividers.insert(&W[index1]);
00315 roDividers.insert(&W[index2]);
00316
00317 break;
00318 case 5:
00319 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has been split into cosets X1 and X3");
00320
00321
00322
00323 W.erase(W.find(index2));
00324 W[index3].pBrother=&W[index1];
00325 W[index3].pFather=*roIt;
00326 W[index3].pFirstChild=NULL;
00327 W[index3].pSecondChild=NULL;
00328 W[index3].numberOfStates=W[index3].states.Size();
00329 W[index1].pBrother=&W[index3];
00330 W[index1].pFather=*roIt;
00331 W[index1].pFirstChild=NULL;
00332 W[index1].pSecondChild=NULL;
00333 W[index1].numberOfStates=W[index1].states.Size();
00334 (*roIt)->pFirstChild=&W[index1];
00335 (*roIt)->pSecondChild=&W[index3];
00336
00337 (*roIt)->states.Clear();
00338 if(roDividers.find(*roIt)!=roDividers.end())
00339 roDividers.erase(roDividers.find(*roIt));
00340 if((*roIt)->pFather!=NULL && (*roIt)->pFather != pFather)
00341 {
00342 if((*roIt)->pFather->pFirstChild->pFirstChild!=NULL && (*roIt)->pFather->pSecondChild->pSecondChild!=NULL)
00343 (*roIt)->pFather->infoMap.clear();
00344 }
00345
00346 removeSet.push_back((*roIt)->index);
00347 addSet.push_back(&W[index1]);
00348 addSet.push_back(&W[index3]);
00349 roDividers.insert(&W[index1]);
00350 roDividers.insert(&W[index3]);
00351 break;
00352
00353 case 6:
00354 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has been split into cosets X2 and X3");
00355
00356
00357
00358 W.erase(W.find(index1));
00359 W[index3].pBrother=&W[index2];
00360 W[index3].pFather=*roIt;
00361 W[index3].pFirstChild=NULL;
00362 W[index3].pSecondChild=NULL;
00363 W[index3].numberOfStates=W[index3].states.Size();
00364 W[index2].pBrother=&W[index3];
00365 W[index2].pFather=*roIt;
00366 W[index2].pFirstChild=NULL;
00367 W[index2].pSecondChild=NULL;
00368 W[index2].numberOfStates=W[index2].states.Size();
00369 (*roIt)->pFirstChild=&W[index2];
00370 (*roIt)->pSecondChild=&W[index3];
00371
00372
00373 (*roIt)->states.Clear();
00374 if(roDividers.find(*roIt)!=roDividers.end())
00375 roDividers.erase(roDividers.find(*roIt));
00376 if((*roIt)->pFather!=NULL && (*roIt)->pFather != pFather)
00377 {
00378 if((*roIt)->pFather->pFirstChild->pFirstChild!=NULL && (*roIt)->pFather->pSecondChild->pSecondChild!=NULL)
00379 (*roIt)->pFather->infoMap.clear();
00380 }
00381
00382 removeSet.push_back((*roIt)->index);
00383 addSet.push_back(&W[index2]);
00384 addSet.push_back(&W[index3]);
00385 roDividers.insert(&W[index2]);
00386 roDividers.insert(&W[index3]);
00387
00388 break;
00389
00390 case 7:
00391
00392 OP_DF("Bisimulation::partitionSplitter: coset " << (*roIt)->index << " has been split into cosets X1, X2 and X3");
00393
00394
00395
00396 Partition X23;
00397 W[index]=X23;
00398 W[index].index=index;
00399 (*roIt)->pFirstChild=&W[index1];
00400 (*roIt)->pSecondChild=&W[index];
00401 W[index1].pFather=*roIt;
00402 W[index1].pBrother=&W[index];
00403 W[index1].pFirstChild=NULL;
00404 W[index1].pSecondChild=NULL;
00405 W[index1].numberOfStates=W[index1].states.Size();
00406 W[index].pBrother=&W[index1];
00407 W[index].pFather=*roIt;
00408 W[index].pFirstChild=&W[index2];
00409 W[index].pSecondChild=&W[index3];
00410 W[index2].pBrother=&W[index3];
00411 W[index2].pFather=&W[index];
00412 W[index2].pFirstChild=NULL;
00413 W[index2].pSecondChild=NULL;
00414 W[index2].numberOfStates=W[index2].states.Size();
00415 W[index3].pBrother=&W[index2];
00416 W[index3].pFather=&W[index];
00417 W[index3].pFirstChild=NULL;
00418 W[index3].pSecondChild=NULL;
00419 W[index3].numberOfStates=W[index3].states.Size();
00420 W[index].numberOfStates=W[index2].numberOfStates+W[index3].numberOfStates;
00421
00422 (*roIt)->states.Clear();
00423
00424 if(roDividers.find(*roIt)!=roDividers.end())
00425 roDividers.erase(roDividers.find(*roIt));
00426 if((*roIt)->pFather!=NULL && (*roIt)->pFather != pFather)
00427 {
00428 if((*roIt)->pFather->pFirstChild->pFirstChild!=NULL && (*roIt)->pFather->pSecondChild->pSecondChild!=NULL)
00429 (*roIt)->pFather->infoMap.clear();
00430 }
00431
00432 removeSet.push_back((*roIt)->index);
00433 addSet.push_back(&W[index1]);
00434 addSet.push_back(&W[index2]);
00435 addSet.push_back(&W[index3]);
00436 roDividers.insert(&W[index1]);
00437 roDividers.insert(&W[index2]);
00438 roDividers.insert(&W[index3]);
00439 index++;
00440
00441 break;
00442 }
00443
00444 }
00445
00446
00447 OP_DF("Bisimulation::partitionSplitter: deleting split cosets from ro");
00448 vector<Idx>::iterator remIt;
00449 for(remIt=removeSet.begin(); remIt != removeSet.end(); ++remIt)
00450 {
00451 vector<Partition*>::iterator delRoIt = ro.begin();
00452 vector<Partition*>::iterator delRoItEnd = ro.end();
00453 for(; delRoIt != delRoItEnd; ++delRoIt)
00454 {
00455 if((*delRoIt)->index == *remIt)
00456 {
00457 ro.erase(delRoIt);
00458 OP_DF("Bisimulation::partitionSplitter: coset "<< (*delRoIt)->index << " deleted from ro");
00459 break;
00460 }
00461 }
00462 }
00463 removeSet.clear();
00464
00465
00466 OP_DF("Bisimulation::partitionSplitter: inserting the new cosets into ro");
00467 vector<Partition*>::iterator addIt;
00468 for(addIt=addSet.begin(); addIt != addSet.end(); ++addIt)
00469 {
00470 ro.push_back(*addIt);
00471 OP_DF("Bisimulation::partitionSplitter: coset " << (*addIt)->index << " inserted into ro");
00472 }
00473 addSet.clear();
00474 }
00475 }
00476
00477
00478 pFather->infoMap.clear();
00479
00480
00481 pSmallerPart->nonSplitting=true;
00482 pLargerPart->nonSplitting=true;
00483
00484
00485 if(pSmallerPart->pFirstChild != NULL)
00486 pSmallerPart->states.Clear();
00487 if(pLargerPart->pFirstChild != NULL)
00488 pLargerPart->states.Clear();
00489
00490
00491 if(roDividers.find(pSmallerPart) != roDividers.end())
00492 roDividers.erase(pSmallerPart);
00493 if(roDividers.find(pLargerPart) != roDividers.end())
00494 roDividers.erase(pLargerPart);
00495
00496 OP_DF("Bisimulation::partitionSplitter: leaving function");
00497 }
00498
00499
00500 void Bisimulation::computeInfoMaps(Partition& node, Partition* pSmallerPart, Partition* pLargerPart, EventSet::Iterator eIt)
00501 {
00502 OP_DF("Bisimulation::computeInfoMaps(" << node.index << "," << pSmallerPart->index << "," << pLargerPart->index << "," << gen->EventName(*eIt) << ")");
00503
00504
00505 Idx tempState;
00506
00507 StateSet::Iterator sIt;
00508 StateSet::Iterator sItBegin;
00509 StateSet::Iterator sItEnd;
00510
00511 TransSetEvX2X1::Iterator tIt;
00512 TransSetEvX2X1::Iterator tItBegin;
00513 TransSetEvX2X1::Iterator tItEnd;
00514
00515 sItBegin=node.states.Begin();
00516 sItEnd=node.states.End();
00517 map<Idx, map<Idx,Idx> >::iterator imItLa, imItSm;
00518 imItLa = pLargerPart->infoMap.find(*eIt);
00519 imItSm = pSmallerPart->infoMap.find(*eIt);
00520 for(sIt=sItBegin; sIt!=sItEnd; sIt++)
00521 {
00522 tItBegin=tset_evx2x1.BeginByEvX2(*eIt,*sIt);
00523 tItEnd=tset_evx2x1.EndByEvX2(*eIt,*sIt);
00524
00525 for(tIt=tItBegin; tIt != tItEnd; ++tIt)
00526 {
00527 tempState=tIt->X1;
00528
00529 if(imItSm->second.find(tempState) == imItSm->second.end())
00530 {
00531 imItSm->second[tempState]=1;
00532 }
00533
00534 else
00535 {
00536 imItSm->second[tempState]++;
00537 }
00538 imItLa->second[tempState]--;
00539 if(imItLa->second[tempState]==0)
00540 imItLa->second.erase(tempState);
00541 }
00542 }
00543
00544 if(node.pFirstChild!=NULL){
00545 computeInfoMaps(*(node.pFirstChild), pSmallerPart, pLargerPart, eIt);
00546 }
00547 if(node.pSecondChild!=NULL){
00548 computeInfoMaps(*(node.pSecondChild),pSmallerPart, pLargerPart, eIt);
00549 }
00550
00551 OP_DF("Bisimulation::computeInfoMaps: leaving function");
00552 }
00553
00554
00555 bool Bisimulation::stateLeadsToPartition(Idx state, Partition& node, EventSet::Iterator eIt)
00556 {
00557 OP_DF("Bisimulation::stateLeadsToPartition(" << state << "," << node.index << "," << gen->EventName(*eIt) << ")");
00558
00559 bool found=false;
00560
00561 if(node.states.Exists(gen->TransRelBegin(state, *eIt)->X2) && gen->TransRelBegin(state, *eIt)->X1 == state && gen->TransRelBegin(state, *eIt)->Ev == *eIt)
00562 {
00563 found = true;
00564 }
00565
00566 if(found == false && node.pFirstChild!=NULL)
00567 {
00568 found=stateLeadsToPartition(state,*node.pFirstChild,eIt);
00569 }
00570
00571 if(found == false && node.pSecondChild!=NULL)
00572 {
00573 found=stateLeadsToPartition(state,*node.pSecondChild,eIt);
00574 }
00575
00576 OP_DF("Bisimulation::stateLeadsToPartition: leaving function");
00577 return found;
00578 }
00579
00580
00581 void Bisimulation::partitionClass(Partition& B)
00582 {
00583 OP_DF("Bisimulation::partitionClass(" << B.index << ")");
00584 OP_DF("Bisimulation::partitionClass: index of passed coset is " << B.index);
00585
00586
00587 EventSet::Iterator eIt;
00588 EventSet::Iterator eItBegin = gen->AlphabetBegin();
00589 EventSet::Iterator eItEnd = gen->AlphabetEnd();
00590
00591
00592 vector<Partition*>::iterator roIt;
00593
00594 vector<Partition*> addSet;
00595 vector<Partition*>::iterator addIt;
00596 vector<Idx> removeSet;
00597 vector<Idx>::iterator remIt;
00598
00599
00600 StateSet tb;
00601
00602 FD_DV("Bisimulation::partitionClass: loop over events " << gen->Alphabet().ToString());
00603
00604
00605 for (eIt=eItBegin; eIt!=eItEnd; ++eIt)
00606 {
00607 OP_DF("Bisimulation::partitionClass: partitioning for event " << gen->EventName(*eIt));
00608
00609 tb.Clear();
00610
00611 computeInfoMap(B, B, eIt, tb);
00612
00613 for(roIt = ro.begin(); roIt != ro.end(); ++roIt)
00614 {
00615 OP_DF("Bisimulation::partitionClass: candidate coset to be split has index " << (*roIt)->index);
00616
00617
00618 Partition intersection;
00619 W[index]=intersection;
00620 W[index].states=(*roIt)->states;
00621 W[index].states.SetIntersection(tb);
00622
00623 if(!W[index].states.Empty() && W[index].states.Size()!=(*roIt)->states.Size() )
00624 {
00625
00626 OP_DF("Bisimulation::partitionClass: current coset with index " << (*roIt)->index << " will be split");
00627
00628
00629 if(roDividers.find(*roIt)!=roDividers.end())
00630 {
00631 OP_DF("Bisimulation::partitionClass: candidate was in roDividers and will be deleted from it");
00632 roDividers.erase(roDividers.find(*roIt));
00633 }
00634
00635
00636 removeSet.push_back((*roIt)->index);
00637
00638
00639 W[index].index=index;
00640 W[index].pBrother=NULL;
00641 W[index].pFirstChild=NULL;
00642 W[index].pSecondChild=NULL;
00643 W[index].pFather=*roIt;
00644 W[index].numberOfStates=W[index].states.Size();
00645 (*roIt)->pFirstChild=&W[index];
00646
00647
00648 addSet.push_back(&W[index]);
00649 roDividers.insert(&W[index]);
00650 OP_DF("Bisimulation::partitionClass: the coset with index " << (&W[index])->index << " has been added to addSet and to roDividers");
00651
00652 index++;
00653
00654
00655 Partition diff;
00656 W[index]=diff;
00657 W[index].states = ((*roIt)->states) - W[index-1].states;
00658 W[index].index=index;
00659 W[index].pBrother=&W[index-1];
00660 W[index-1].pBrother=&W[index];
00661 W[index].pFirstChild=NULL;
00662 W[index].pSecondChild=NULL;
00663 W[index].pFather=*roIt;
00664 W[index].numberOfStates=W[index].states.Size();
00665 (*roIt)->pSecondChild=&W[index];
00666
00667
00668 addSet.push_back(&W[index]);
00669 roDividers.insert(&W[index]);
00670 OP_DF("Bisimulation::partitionClass: the coset with index " << (&W[index])->index << " has been added to addSet and to roDividers");
00671
00672 index++;
00673 OP_DF("Bisimulation::partitionClass: the candidate coset has been split");
00674
00675
00676 if((*roIt)->pFather!=NULL)
00677 {
00678 OP_DF("Bisimulation::partitionClass: split coset has parent coset with index " << (*roIt)->pFather->index);
00679 if((*roIt)->pFather->pFirstChild->pFirstChild!=NULL && (*roIt)->pFather->pSecondChild->pSecondChild!=NULL)
00680 {
00681 (*roIt)->pFather->infoMap.clear();
00682 OP_DF("Bisimulation::partitionClass: info map of parent coset deleted");
00683 }
00684 }
00685
00686
00687 (*roIt)->states.Clear();
00688 OP_DF("Bisimulation::partitionClass: states of split coset " << (*roIt)->index << " have been deleted");
00689 }
00690 else
00691 {
00692
00693 W.erase(index);
00694 }
00695 }
00696
00697
00698 OP_DF("Bisimulation::partitionClass: deleting split cosets from ro");
00699 for(remIt=removeSet.begin(); remIt!=removeSet.end();remIt++)
00700 {
00701 vector<Partition*>::iterator delRoIt = ro.begin();
00702 vector<Partition*>::iterator delRoItEnd = ro.end();
00703 for(; delRoIt!=delRoItEnd; ++delRoIt)
00704 {
00705 if((*delRoIt)->index==*remIt)
00706 {
00707 ro.erase(delRoIt);
00708 OP_DF("Bisimulation::partitionClass: coset " << (*delRoIt)->index << " was deleted from ro");
00709 break;
00710 }
00711 }
00712 }
00713 removeSet.clear();
00714
00715
00716 OP_DF("Bisimulation::partitionClass: inserting the new cosets into ro");
00717 for(addIt=addSet.begin();addIt!=addSet.end();addIt++)
00718 {
00719 ro.push_back(*addIt);
00720 OP_DF("Bisimulation::partitionClass: coset with index " << (*addIt)->index << " was inserted into ro");
00721 }
00722 addSet.clear();
00723
00724
00725 }
00726
00727
00728 B.nonSplitting = true;
00729
00730
00731 if(B.pFirstChild != NULL)
00732 B.states.Clear();
00733
00734
00735 roDividers.erase(&B);
00736
00737 OP_DF("Bisimulation::partitionClass: leaving function");
00738 }
00739
00740
00741 void Bisimulation::computeInfoMap(Partition& B, Partition& Bstates, EventSet::Iterator eIt, StateSet& tb)
00742 {
00743 OP_DF("Bisimulation::computeInfoMap(" << B.index << "," << Bstates.index << "," << gen->EventName(*eIt) << ", Stateset&)");
00744 OP_DF("Bisimulation::computeInfoMap: consider stateSet of coset " << Bstates.index);
00745
00746
00747 Idx temp;
00748
00749
00750 StateSet::Iterator sIt;
00751 StateSet::Iterator sItBegin = Bstates.states.Begin();
00752 StateSet::Iterator sItEnd = Bstates.states.End();
00753
00754
00755 TransSetEvX2X1::Iterator tIt;
00756 TransSetEvX2X1::Iterator tItBegin;
00757 TransSetEvX2X1::Iterator tItEnd;
00758 map<Idx, map<Idx, Idx> >::iterator imIt;
00759
00760 for(sIt=sItBegin; sIt != sItEnd; ++sIt)
00761 {
00762 tItBegin=tset_evx2x1.BeginByEvX2(*eIt,*sIt);
00763 tItEnd=tset_evx2x1.EndByEvX2(*eIt,*sIt);
00764
00765
00766 for(tIt=tItBegin; tIt != tItEnd; ++tIt)
00767 {
00768 imIt = B.infoMap.find(*eIt);
00769
00770 if(imIt == B.infoMap.end() )
00771 imIt = B.infoMap.insert(B.infoMap.begin(), make_pair(*eIt, map<Idx,Idx>() ) );
00772
00773 temp=tIt->X1;
00774 tb.Insert(temp);
00775
00776
00777 if(imIt->second.find(temp)==imIt->second.end())
00778 imIt->second[temp]=1;
00779 else
00780 imIt->second[temp]++;
00781 }
00782 }
00783
00784 if(Bstates.pFirstChild!=NULL)
00785 {
00786 computeInfoMap(B, *(Bstates.pFirstChild), eIt, tb);
00787 }
00788 if(Bstates.pSecondChild!=NULL)
00789 {
00790 computeInfoMap(B, *(Bstates.pSecondChild), eIt, tb);
00791 }
00792 OP_DF("Bisimulation::computeInfoMap: leaving function");
00793 }
00794
00795
00796 void Bisimulation::partition(map<Idx,Idx>& rMapStateToPartition, Generator& rGenPart, vector<Idx>& rNewPartitions)
00797 {
00798 OP_DF("Bisimulation::partition(rMapStateToPartition," << rGenPart.Name() << ", rNewPartitions)");
00799
00800
00801 set<Partition*>::iterator roDivIt;
00802 set<Partition*>::iterator roDivItEnd=roDividers.end();
00803 Partition* pFather;
00804 bool done=false;
00805
00806
00807 roDivIt=roDividers.begin();
00808
00809
00810
00811 while(done == false)
00812 {
00813
00814
00815 while(roDivIt != roDivItEnd && !roDividers.empty())
00816 {
00817 pFather=(*roDivIt)->pFather;
00818 if(pFather != NULL)
00819 {
00820 if(pFather->nonSplitting == true)
00821 {
00822 partitionSplitter(**roDivIt);
00823
00824
00825 roDivItEnd=roDividers.end();
00826 roDivIt=roDividers.begin();
00827 continue;
00828 }
00829 }
00830 roDivIt++;
00831 }
00832
00833
00834 if(!roDividers.empty())
00835 {
00836 roDivIt=roDividers.begin();
00837 partitionClass(**roDivIt);
00838
00839
00840 roDivItEnd=roDividers.end();
00841 roDivIt=roDividers.begin();
00842 }
00843 if(roDividers.empty())
00844 done=true;
00845 }
00846
00847
00848
00849 OP_DF("Bisimulation::partition: entering function: building generator from equivalence classes");
00850
00851 Idx newstate;
00852
00853 vector<Partition*>::const_iterator cRoIt = ro.begin();
00854 vector<Partition*>::const_iterator cRoItEnd = ro.end();
00855 StateSet::Iterator cSIt;
00856 StateSet::Iterator cSItEnd;
00857 for (; cRoIt != cRoItEnd; ++cRoIt)
00858 {
00859 std::ostringstream ostr;
00860 newstate = rGenPart.InsState();
00861
00862
00863 OP_DF("Bisimulation::partition: new state " << newstate << " for coset "
00864 << (*cRoIt)->index << " :"<< (*cRoIt)->states.ToString());
00865
00866
00867 rNewPartitions.push_back(newstate);
00868
00869 cSIt=(*cRoIt)->states.Begin();
00870 cSItEnd=(*cRoIt)->states.End();
00871
00872
00873 for (; cSIt != cSItEnd; ++cSIt)
00874 {
00875
00876
00877 rMapStateToPartition[*cSIt] = newstate;
00878
00879
00880 if (rGenPart.StateNamesEnabled())
00881 {
00882 if (gen->StateName(*cSIt) == "")
00883 {
00884 ostr << ToStringInteger(*cSIt) << ",";
00885 }
00886 else
00887 {
00888 ostr << gen->StateName(*cSIt) << ",";
00889 }
00890 }
00891
00892
00893 if (gen->ExistsInitState(*cSIt))
00894 {
00895 rGenPart.SetInitState(newstate);
00896 }
00897
00898 if (gen->ExistsMarkedState(*cSIt))
00899 {
00900 rGenPart.SetMarkedState(newstate);
00901 }
00902 }
00903
00904 if (rGenPart.StateNamesEnabled())
00905 {
00906 std::string statename = ostr.str();
00907 if(statename.length()>=1) statename.erase(statename.length()-1);
00908 statename = "{" + statename + "}";
00909 rGenPart.StateName(newstate, statename);
00910 OP_DF("Bisimulation::partition: new state " << statename);
00911 }
00912 }
00913
00914
00915 TransSet::Iterator tIt = gen->TransRelBegin();
00916 TransSet::Iterator tItEnd = gen->TransRelEnd();
00917 for (; tIt != tItEnd; ++tIt)
00918 {
00919 rGenPart.InsEvent(tIt->Ev);
00920 rGenPart.SetTransition(rMapStateToPartition[tIt->X1], tIt->Ev, rMapStateToPartition[tIt->X2]);
00921 OP_DF("Bisimulation::partition: adding transition: X1=" << rGenPart.TStr(*tIt) );
00922 }
00923 OP_DF("Bisimulation::partition: leaving function");
00924 }
00925
00926
00927 void Bisimulation::partition(map<Idx,Idx>& rMapStateToPartition, vector<Idx>& rNewPartitions)
00928 {
00929 OP_DF("Bisimulation::partition(rMapStateToPartition, rNewPartitions)");
00930
00931
00932 set<Partition*>::iterator roDivIt;
00933 set<Partition*>::iterator roDivItEnd=roDividers.end();
00934 Partition* pFather;
00935 bool done=false;
00936
00937 roDivIt=roDividers.begin();
00938
00939
00940 while(done==false)
00941 {
00942
00943
00944 while(roDivIt!=roDivItEnd && !roDividers.empty())
00945 {
00946 pFather=(*roDivIt)->pFather;
00947 if(pFather!=NULL)
00948 {
00949 if(pFather->nonSplitting == true)
00950 {
00951 partitionSplitter(**roDivIt);
00952
00953 roDivItEnd=roDividers.end();
00954 roDivIt=roDividers.begin();
00955 continue;
00956 }
00957 }
00958 roDivIt++;
00959 }
00960
00961
00962 if(!roDividers.empty())
00963 {
00964 roDivIt=roDividers.begin();
00965 partitionClass(**roDivIt);
00966
00967 roDivItEnd=roDividers.end();
00968 roDivIt=roDividers.begin();
00969 }
00970 if(roDividers.empty())
00971 done=true;
00972 }
00973
00974
00975
00976 OP_DF("Bisimulation::partition: writing vector rMapStateToPartition");
00977
00978 Idx newstate;
00979
00980 vector<Partition*>::const_iterator cRoIt = ro.begin();
00981 vector<Partition*>::const_iterator cRoItEnd = ro.end();
00982 StateSet::Iterator cSIt;
00983 StateSet::Iterator cSItEnd;
00984 for (; cRoIt != cRoItEnd; ++cRoIt)
00985 {
00986 Generator dummy;
00987 newstate = dummy.InsState();
00988 rNewPartitions.push_back(newstate);
00989 cSIt=(*cRoIt)->states.Begin();
00990 cSItEnd=(*cRoIt)->states.End();
00991 for ( ; cSIt!=cSItEnd; ++ cSIt)
00992 {
00993
00994 rMapStateToPartition[*cSIt] = newstate;
00995 }
00996 }
00997 OP_DF("Bisimulation::partition: leaving function");
00998 }
00999
01000
01001 void Bisimulation::writeW(void)
01002 {
01003 OP_DF("Bisimulation:writeW()");
01004 cout << "Plotting the W-tree:" << endl;
01005 writeNode(W.find(1)->second);
01006 }
01007
01008
01009 void Bisimulation::writeNode(Partition& node)
01010 {
01011 OP_DF("Bisimulation::writeNode(" << node.index << ")");
01012 cout << "Coset with index " << node.index << " has the following states:" << endl;
01013 node.states.Write();
01014 if(node.pFather!=NULL)
01015 cout << "Parent coset has index: " << node.pFather->index << endl;
01016 else
01017 cout << "Coset is the root of the tree" << endl;
01018 if(node.pBrother!=NULL)
01019 cout << "Coset has brother coset with index: " << node.pBrother->index << endl;
01020 else
01021 cout << "Coset has no brother" << endl;
01022 if(node.pFirstChild!=NULL && node.pSecondChild!=NULL)
01023 cout << "Child cosets have indices : " << node.pFirstChild->index << " and " << node.pSecondChild->index << endl;
01024 else
01025 cout << "Coset has no children" << endl;
01026 cout << "ro is stable with respect to this coset (1=yes; 0=no): " << node.nonSplitting << endl;
01027 cout << "Info-map of coset: " << endl;
01028 EventSet::Iterator eIt;
01029 for(eIt=gen->AlphabetBegin();eIt != gen->AlphabetEnd(); ++eIt)
01030 node.writeInfoMap(*eIt);
01031
01032 if(node.pFirstChild!=NULL)
01033 writeNode(*(node.pFirstChild));
01034 if(node.pSecondChild!=NULL)
01035 writeNode(*(node.pSecondChild));
01036 }
01037
01038
01039 void Bisimulation::writeRo(void)
01040 {
01041 OP_DF("Bisimulation::writeRo()");
01042 cout << "The Cosets with the following indices are in ro: " << endl;
01043 vector<Partition*>::iterator roIt;
01044 vector<Partition*>::iterator roItBegin =ro.begin();
01045 vector<Partition*>::iterator roItEnd = ro.end();
01046 for(roIt=roItBegin; roIt!=roItEnd; roIt++)
01047 cout << (*roIt)->index << endl;
01048 cout << endl;
01049 }
01050
01051 }