syn_functions.cppGo to the documentation of this file.00001 /** @file syn_functions.cpp Misc functions related to synthesis */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2010 Thomas Moor 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00020 00021 00022 //#define FAUDES_DEBUG_FUNCTION 00023 00024 #include "syn_functions.h" 00025 00026 00027 namespace faudes { 00028 00029 00030 00031 00032 /* 00033 *************************************************************************************** 00034 *************************************************************************************** 00035 Implementation 00036 *************************************************************************************** 00037 *************************************************************************************** 00038 */ 00039 00040 00041 00042 //IsRelativelyMarked(rGenPlant,rGenCand) 00043 bool IsRelativelyMarked(const Generator& rGenPlant, const Generator& rGenCand) { 00044 00045 // alphabets must match 00046 if ( rGenPlant.Alphabet() != rGenCand.Alphabet()) { 00047 std::stringstream errstr; 00048 errstr << "Alphabets of generators do not match."; 00049 throw Exception("IsRelativelyMarked", errstr.str(), 100); 00050 } 00051 00052 #ifdef FAUDES_CHECKED 00053 // generators are meant to be nonblocking 00054 if ( !IsNonblocking(rGenCand) || !IsNonblocking(rGenPlant)) { 00055 std::stringstream errstr; 00056 errstr << "Arguments are expected to be nonblocking."; 00057 throw Exception("IsRelativelyMarked", errstr.str(), 201); 00058 } 00059 #endif 00060 00061 #ifdef FAUDES_CHECKED 00062 // generators are meant to be deterministic 00063 if ( !IsDeterministic(rGenCand) || !IsDeterministic(rGenPlant)) { 00064 std::stringstream errstr; 00065 errstr << "Arguments are expected to be deterministic."; 00066 throw Exception("IsRelativelyMarked", errstr.str(), 202); 00067 } 00068 #endif 00069 00070 // perform composition 00071 std::map< std::pair<Idx,Idx> , Idx> revmap; 00072 Generator product; 00073 product.StateNamesEnabled(false); 00074 Product(rGenPlant,rGenCand,revmap,product); 00075 00076 // test all reachable states 00077 std::map< std::pair<Idx,Idx> , Idx>::iterator rit; 00078 for(rit=revmap.begin(); rit!=revmap.end(); ++rit) { 00079 // ok: not GPlant-marked state is not considered 00080 if(!rGenPlant.ExistsMarkedState(rit->first.first)) 00081 continue; 00082 // ok: GPlant-marked state also has GCand-mark 00083 if(rGenCand.ExistsMarkedState(rit->first.second)) 00084 continue; 00085 // failure: GPlant-marked state has no GCand-mark 00086 break; 00087 } 00088 00089 // ok if loop passed 00090 return rit==revmap.end(); 00091 00092 } 00093 00094 00095 00096 //IsRelativelyPrefixClosed(rGenPlant,rGenCand) 00097 bool IsRelativelyPrefixClosed(const Generator& rGenPlant, const Generator& rGenCand) { 00098 00099 FD_DF("IsRelativelyPrefixClosed(\"" << rGenPlant.Name() << "\", \"" << rGenCand.Name() << "\")"); 00100 00101 // alphabets must match 00102 if ( rGenPlant.Alphabet() != rGenCand.Alphabet()) { 00103 std::stringstream errstr; 00104 errstr << "Alphabets of generators do not match."; 00105 throw Exception("IsRelativelyPrefixClosed", errstr.str(), 100); 00106 } 00107 00108 #ifdef FAUDES_CHECKED 00109 // generators are meant to be nonblocking 00110 if ( !IsNonblocking(rGenCand) || !IsNonblocking(rGenPlant)) { 00111 std::stringstream errstr; 00112 errstr << "Arguments are expected to be nonblocking."; 00113 throw Exception("IsRelativelyPrefixClosed", errstr.str(), 201); 00114 } 00115 #endif 00116 00117 #ifdef FAUDES_CHECKED 00118 // generators are meant to be deterministic 00119 if ( !IsDeterministic(rGenCand) || !IsDeterministic(rGenPlant)) { 00120 std::stringstream errstr; 00121 errstr << "Arguments are expected to be deterministic."; 00122 throw Exception("IsRelativelyPrefixClosed", errstr.str(), 202); 00123 } 00124 #endif 00125 00126 // perform composition (variation from cfl_parallel.cpp) 00127 FD_DF("IsRelativelyPrefixClosed(..): perform product"); 00128 00129 // todo stack 00130 std::stack< std::pair<Idx,Idx> > todo; 00131 // current pair, new pair 00132 std::pair<Idx,Idx> currentstates, newstates; 00133 // accessible states 00134 std::set< std::pair<Idx,Idx> > productstates; 00135 // iterators 00136 StateSet::Iterator lit1, lit2; 00137 TransSet::Iterator tit1, tit1_end, tit2, tit2_end; 00138 std::set< std::pair<Idx,Idx> >::iterator rcit; 00139 // sense violation of L(GCand) <= L(GPlant) 00140 bool inclusion12=true; 00141 00142 // push all combinations of initial states on todo stack 00143 FD_DF("IsRelativelyPrefixClosed(..): perform product: adding all combinations of initial states to todo"); 00144 for (lit1 = rGenCand.InitStatesBegin(); 00145 lit1 != rGenCand.InitStatesEnd(); ++lit1) { 00146 for (lit2 = rGenPlant.InitStatesBegin(); 00147 lit2 != rGenPlant.InitStatesEnd(); ++lit2) { 00148 currentstates = std::make_pair(*lit1, *lit2); 00149 todo.push(currentstates); 00150 productstates.insert(currentstates); 00151 FD_DF("IsRelativelyPrefixClosed(..): perform product: (" << 00152 *lit1 << "|" << *lit2 << ")"); 00153 } 00154 } 00155 00156 // start algorithm 00157 FD_DF("IsRelativelyPrefixClosed(..): perform product: Product: processing reachable states:"); 00158 while (! todo.empty() && inclusion12) { 00159 // allow for user interrupt 00160 LoopCallback(); 00161 // get next reachable state from todo stack 00162 currentstates = todo.top(); 00163 todo.pop(); 00164 FD_DF("Processing (" << currentstates.first << "|" 00165 << currentstates.second << ")"); 00166 // iterate over all rGenCand transitions 00167 tit1 = rGenCand.TransRelBegin(currentstates.first); 00168 tit1_end = rGenCand.TransRelEnd(currentstates.first); 00169 tit2 = rGenPlant.TransRelBegin(currentstates.second); 00170 tit2_end = rGenPlant.TransRelEnd(currentstates.second); 00171 Idx curev1=0; 00172 bool resolved12=true; 00173 while((tit1 != tit1_end) && (tit2 != tit2_end)) { 00174 // sense new event 00175 if(tit1->Ev != curev1) { 00176 if(!resolved12) inclusion12=false; 00177 curev1=tit1->Ev; 00178 resolved12=false; 00179 } 00180 // shared event 00181 if(tit1->Ev == tit2->Ev) { 00182 resolved12=true; 00183 newstates = std::make_pair(tit1->X2, tit2->X2); 00184 // add to todo list if composition state is new 00185 rcit = productstates.find(newstates); 00186 if(rcit == productstates.end()) { 00187 todo.push(newstates); 00188 productstates.insert(newstates); 00189 FD_DF("Product: todo push: (" << newstates.first << "|" 00190 << newstates.second << ")"); 00191 } 00192 ++tit1; 00193 ++tit2; 00194 } 00195 // try resync tit1 00196 else if (tit1->Ev < tit2->Ev) { 00197 ++tit1; 00198 } 00199 // try resync tit2 00200 else if (tit1->Ev > tit2->Ev) { 00201 ++tit2; 00202 } 00203 } 00204 // last event was not resolved in the product 00205 if(!resolved12) inclusion12=false; 00206 } 00207 // report 00208 #ifdef FAUDES_DEBUG_FUNCTION 00209 FD_DF("IsRelativelyClosed(): Product: done"); 00210 if(!inclusion12) { 00211 FD_DF("IsRelativelyClosed(): Product: inclusion L(G1) <= L(G2) not satisfied"); 00212 } 00213 #endif 00214 00215 // bail out when inclusion condition is violated 00216 if(!inclusion12) return false; 00217 00218 // test all reachable states 00219 std::set< std::pair<Idx,Idx> >::iterator rit; 00220 for(rit=productstates.begin(); rit!=productstates.end(); ++rit) { 00221 // ok: state is GPlant-marked and GCand-marked 00222 if(rGenPlant.ExistsMarkedState(rit->second)) 00223 if(rGenCand.ExistsMarkedState(rit->first)) 00224 continue; 00225 // ok: state is neither GPlant-marked nor GCand-marked 00226 if(!rGenPlant.ExistsMarkedState(rit->second)) 00227 if(!rGenCand.ExistsMarkedState(rit->first)) 00228 continue; 00229 // failure: markin mismatch 00230 break; 00231 } 00232 00233 // ok if loop passed 00234 return rit==productstates.end(); 00235 00236 } 00237 00238 00239 // SupRelativelyPrefixClosed(rPlantGen, rCAlph, rSpecGen, rResGen) 00240 void SupRelativelyPrefixClosed( 00241 const Generator& rPlantGen, 00242 const Generator& rSpecGen, 00243 Generator& rResGen) 00244 { 00245 00246 // CONSISTENCY CHECK: alphabets must match 00247 if ( rPlantGen.Alphabet() != rSpecGen.Alphabet()) { 00248 EventSet only_in_plant = rPlantGen.Alphabet() - rSpecGen.Alphabet(); 00249 EventSet only_in_spec = rSpecGen.Alphabet() - rPlantGen.Alphabet(); 00250 only_in_plant.Name("Only_In_Plant"); 00251 only_in_spec.Name("Only_In_Specification"); 00252 std::stringstream errstr; 00253 errstr << "Alphabets of generators do not match."; 00254 if(!only_in_plant.Empty()) 00255 errstr << " " << only_in_plant.ToString() << "."; 00256 if(!only_in_spec.Empty()) 00257 errstr << " " << only_in_spec.ToString() << "."; 00258 throw Exception("SupCon/SupConNB", errstr.str(), 100); 00259 } 00260 00261 // CONSISTENCY CHECK: plant and spec must be deterministic 00262 bool plant_det = rPlantGen.IsDeterministic(); 00263 bool spec_det = rSpecGen.IsDeterministic(); 00264 if ((plant_det == false) && (spec_det == true)) { 00265 std::stringstream errstr; 00266 errstr << "Plant generator must be deterministic, " 00267 << "but is nondeterministic"; 00268 throw Exception("ControllableConsistencyCheck", errstr.str(), 201); 00269 } 00270 else if ((plant_det == true) && (spec_det == false)) { 00271 std::stringstream errstr; 00272 errstr << "Spec generator must be deterministic, " 00273 << "but is nondeterministic"; 00274 throw Exception("ControllableConsistencyCheck", errstr.str(), 203); 00275 } 00276 else if ((plant_det == false) && (spec_det == false)) { 00277 std::stringstream errstr; 00278 errstr << "Plant and spec generator must be deterministic, " 00279 << "but both are nondeterministic"; 00280 throw Exception("ControllableConsistencyCheck", errstr.str(), 204); 00281 } 00282 00283 // HELPERS: 00284 std::map< std::pair<Idx,Idx>, Idx> rcmap; 00285 00286 // ALGORITHM: 00287 SupRelativelyPrefixClosedUnchecked(rPlantGen, rSpecGen, rcmap, rResGen); 00288 } 00289 00290 00291 // SupRelativelyPrefixClosedUnchecked(rPlantGen, rSpecGen, rCompositionMap, rResGen) 00292 void SupRelativelyPrefixClosedUnchecked( 00293 const Generator& rPlantGen, 00294 const Generator& rSpecGen, 00295 std::map< std::pair<Idx,Idx>, Idx>& rCompositionMap, 00296 Generator& rResGen) 00297 { 00298 FD_DF("SupRelativelyPrefixClosed(" << &rPlantGen << "," << &rSpecGen << ")"); 00299 00300 // PREPARE RESULT: 00301 Generator* pResGen = &rResGen; 00302 if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) { 00303 pResGen= rResGen.New(); 00304 } 00305 pResGen->Clear(); 00306 pResGen->Name(CollapsString("SupRpcNB(("+rPlantGen.Name()+"),("+rSpecGen.Name()+"))")); 00307 pResGen->InjectAlphabet(rPlantGen.Alphabet()); 00308 00309 // ALGORITHM: 00310 StateSet pmarked; 00311 StateSet smarked; 00312 Product(rPlantGen, rSpecGen, rCompositionMap, pmarked, smarked, *pResGen); 00313 00314 // make resulting generator relatively prefix closed 00315 StateSet::Iterator six=pResGen->StatesBegin(); 00316 while(six!= pResGen->StatesEnd()) { 00317 Idx s=*(six++); 00318 if(!pmarked.Exists(s)) continue; 00319 if(smarked.Exists(s)) continue; 00320 pResGen->DelState(s); 00321 } 00322 pResGen->Trim(); 00323 00324 // copy result 00325 if(pResGen != &rResGen) { 00326 pResGen->Move(rResGen); 00327 delete pResGen; 00328 } 00329 00330 } 00331 00332 00333 // IsOmegaRelativelyMarked(rGenPlant,rGenCand) 00334 bool IsRelativelyOmegaMarked(const Generator& rGenPlant, const Generator& rGenCand) { 00335 00336 00337 FD_DF("IsRelativelyOmegaMarked(\"" << rGenPlant.Name() << "\", \"" << rGenCand.Name() << "\")"); 00338 00339 // alphabets must match 00340 if ( rGenPlant.Alphabet() != rGenCand.Alphabet()) { 00341 std::stringstream errstr; 00342 errstr << "Alphabets of generators do not match."; 00343 throw Exception("RelativelyOmegaMarked", errstr.str(), 100); 00344 } 00345 00346 #ifdef FAUDES_CHECKED 00347 // generators are meant to be nonblocking 00348 if ( !IsOmegaTrim(rGenCand) || !IsOmegaTrim(rGenPlant)) { 00349 std::stringstream errstr; 00350 errstr << "Arguments are expected to be nonblocking."; 00351 throw Exception("IsRelativelyOmegaMarked", errstr.str(), 201); 00352 } 00353 #endif 00354 00355 #ifdef FAUDES_CHECKED 00356 // generators are meant to be deterministic 00357 if ( !IsDeterministic(rGenCand) || !IsDeterministic(rGenPlant)) { 00358 std::stringstream errstr; 00359 errstr << "Arguments are expected to be deterministic."; 00360 throw Exception("IsRelativelyOmegaMarked", errstr.str(), 202); 00361 } 00362 #endif 00363 00364 00365 // perform composition 00366 std::map< std::pair<Idx,Idx> , Idx> revmap; 00367 Generator product; 00368 product.StateNamesEnabled(false); 00369 StateSet markCand; 00370 StateSet markPlant; 00371 Product(rGenPlant,rGenCand,revmap,markPlant,markCand,product); 00372 00373 // find all relevant SCCs 00374 SccFilter umfilter(SccFilter::FmIgnoreTrivial | SccFilter::FmStatesAvoid| SccFilter::FmStatesRequire, 00375 markCand,markPlant); 00376 std::list<StateSet> umsccs; 00377 StateSet umroots; 00378 ComputeScc(product,umfilter,umsccs,umroots); 00379 00380 // report 00381 std::list<StateSet>::iterator ssit=umsccs.begin(); 00382 for(;ssit!=umsccs.end(); ++ssit) { 00383 FD_DF("IsRelativelyOmegaMarked(): GPlant-marked scc without GCand-mark: " << ssit->ToString()); 00384 } 00385 00386 // result is true if no problematic SCCs exist 00387 return umsccs.size()==0; 00388 00389 00390 } 00391 00392 00393 00394 00395 // IsOmegaRelativelyClosed(rGenPlant,rGenCand) 00396 bool IsRelativelyOmegaClosed(const Generator& rGenPlant, const Generator& rGenCand) { 00397 00398 00399 FD_DF("IsRelativelyOmegaClosed(\"" << rGenPlant.Name() << "\", \"" << rGenCand.Name() << "\")"); 00400 00401 // alphabets must match 00402 if ( rGenPlant.Alphabet() != rGenCand.Alphabet()) { 00403 std::stringstream errstr; 00404 errstr << "Alphabets of generators do not match."; 00405 throw Exception("RelativelyOmegaClosed", errstr.str(), 100); 00406 } 00407 00408 #ifdef FAUDES_CHECKED 00409 // generators are meant to be nonblocking 00410 if( !IsOmegaTrim(rGenCand) ) { 00411 std::stringstream errstr; 00412 errstr << "Argument \"" << rGenCand.Name() << "\" is not omegatrim."; 00413 throw Exception("IsRelativelyOmegaClosed", errstr.str(), 201); 00414 } 00415 if( !IsOmegaTrim(rGenPlant) ) { 00416 std::stringstream errstr; 00417 errstr << "Argument \"" << rGenPlant.Name() << "\" is not omega-trim."; 00418 throw Exception("IsRelativelyOmegaClosed", errstr.str(), 201); 00419 } 00420 #endif 00421 00422 00423 // the trivial case: if B1 is empty it is relatively closed 00424 // (we must treat this case because empty generators are not regarded deterministic) 00425 if(rGenCand.Empty()) { 00426 FD_DF("IsRelativelyOmegaClosed(..): empty candidate: pass"); 00427 return true; 00428 } 00429 00430 // the trivial case: if B2 is empty but B1 is not empty, the test failed 00431 // (we must treat this case because empty generators are not regarded deterministic) 00432 if(rGenPlant.Empty()) { 00433 FD_DF("IsRelativelyOmegaClosed(..): non-empty candidate. empty plant: fail"); 00434 return false; 00435 } 00436 00437 #ifdef FAUDES_CHECKED 00438 // generators are meant to be deterministic 00439 if ( !IsDeterministic(rGenCand) || !IsDeterministic(rGenPlant)) { 00440 std::stringstream errstr; 00441 errstr << "Arguments are expected to be deterministic."; 00442 throw Exception("IsRelativelyOmegaClosed", errstr.str(), 202); 00443 } 00444 #endif 00445 00446 // doit 00447 return IsRelativelyOmegaClosedUnchecked(rGenPlant,rGenCand); 00448 } 00449 00450 00451 // IsOmegaRelativelyClosed(rGenPlant,rGenCand) 00452 bool IsRelativelyOmegaClosedUnchecked(const Generator& rGenPlant, const Generator& rGenCand) { 00453 00454 // perform composition (variant of cfl_parallel.cpp) 00455 std::map< std::pair<Idx,Idx> , Idx> revmap; 00456 Generator product; 00457 product.StateNamesEnabled(false); 00458 StateSet mark1; 00459 StateSet mark2; 00460 00461 // shared alphabet 00462 product.InjectAlphabet(rGenCand.Alphabet()); 00463 00464 // todo stack 00465 std::stack< std::pair<Idx,Idx> > todo; 00466 // current pair, new pair 00467 std::pair<Idx,Idx> currentstates, newstates; 00468 // state 00469 Idx tmpstate; 00470 // iterators 00471 StateSet::Iterator lit1, lit2; 00472 TransSet::Iterator tit1, tit1_end, tit2, tit2_end; 00473 std::map< std::pair<Idx,Idx>, Idx>::iterator rcit; 00474 // sense violation of L(G1) <= L(G2) 00475 bool inclusion12=true; 00476 00477 // push all combinations of initial states on todo stack 00478 FD_DF("IsRelativelyOmegaClosed(): Product composition A"); 00479 for (lit1 = rGenCand.InitStatesBegin(); 00480 lit1 != rGenCand.InitStatesEnd(); ++lit1) { 00481 for (lit2 = rGenPlant.InitStatesBegin(); 00482 lit2 != rGenPlant.InitStatesEnd(); ++lit2) { 00483 currentstates = std::make_pair(*lit1, *lit2); 00484 todo.push(currentstates); 00485 tmpstate = product.InsInitState(); 00486 revmap[currentstates] = tmpstate; 00487 FD_DF("IsRelativelyOmegaClosed(): Product composition A: (" << *lit1 << "|" << *lit2 << ") -> " 00488 << revmap[currentstates]); 00489 } 00490 } 00491 00492 // start algorithm 00493 while (! todo.empty() && inclusion12) { 00494 // allow for user interrupt 00495 LoopCallback(); 00496 // get next reachable state from todo stack 00497 currentstates = todo.top(); 00498 todo.pop(); 00499 FD_DF("IsRelativelyOmegaClosed(): Product composition B: (" << currentstates.first << "|" 00500 << currentstates.second << ") -> " << revmap[currentstates]); 00501 // iterate over all rGenCand transitions 00502 tit1 = rGenCand.TransRelBegin(currentstates.first); 00503 tit1_end = rGenCand.TransRelEnd(currentstates.first); 00504 tit2 = rGenPlant.TransRelBegin(currentstates.second); 00505 tit2_end = rGenPlant.TransRelEnd(currentstates.second); 00506 Idx curev1=0; 00507 bool resolved12=true; 00508 while((tit1 != tit1_end) && (tit2 != tit2_end)) { 00509 // sense new event 00510 if(tit1->Ev != curev1) { 00511 if(!resolved12) inclusion12=false; 00512 curev1=tit1->Ev; 00513 resolved12=false; 00514 } 00515 // shared event 00516 if (tit1->Ev == tit2->Ev) { 00517 resolved12=true; 00518 newstates = std::make_pair(tit1->X2, tit2->X2); 00519 // add to todo list if composition state is new 00520 rcit = revmap.find(newstates); 00521 if (rcit == revmap.end()) { 00522 todo.push(newstates); 00523 tmpstate = product.InsState(); 00524 revmap[newstates] = tmpstate; 00525 FD_DF("IsRelativelyOmegaClosed(): Product composition C: (" << newstates.first << "|" 00526 << newstates.second << ") -> " << revmap[newstates]); 00527 } 00528 else { 00529 tmpstate = rcit->second; 00530 } 00531 product.SetTransition(revmap[currentstates], tit1->Ev, tmpstate); 00532 ++tit1; 00533 ++tit2; 00534 } 00535 // try resync tit1 00536 else if (tit1->Ev < tit2->Ev) { 00537 ++tit1; 00538 } 00539 // try resync tit2 00540 else if (tit1->Ev > tit2->Ev) { 00541 ++tit2; 00542 } 00543 } 00544 // last event was not resolved in the product 00545 if(!resolved12) inclusion12=false; 00546 } 00547 // report 00548 #ifdef FAUDES_DEBUG_FUNCTION 00549 FD_DF("IsRelativelyOmegaClosed(): Product: done"); 00550 if(!inclusion12) { 00551 FD_DF("IsRelativelyOmegaClosed(): Product: inclusion L(G1) <= L(G2) not satisfied"); 00552 } 00553 #endif 00554 00555 // bail out 00556 if(!inclusion12) return false; 00557 00558 // retrieve marking from reverse composition map 00559 std::map< std::pair<Idx,Idx>, Idx>::iterator rit; 00560 for(rit=revmap.begin(); rit!=revmap.end(); ++rit){ 00561 if(rGenCand.ExistsMarkedState(rit->first.first)) mark1.Insert(rit->second); 00562 if(rGenPlant.ExistsMarkedState(rit->first.second)) mark2.Insert(rit->second); 00563 } 00564 00565 // find all relevant SCCs 1 00566 SccFilter umfilter12(SccFilter::FmIgnoreTrivial | SccFilter::FmStatesAvoid| SccFilter::FmStatesRequire, 00567 mark1,mark2); 00568 std::list<StateSet> umsccs12; 00569 StateSet umroots12; 00570 ComputeScc(product,umfilter12,umsccs12,umroots12); 00571 00572 // report 00573 std::list<StateSet>::iterator ssit=umsccs12.begin(); 00574 for(;ssit!=umsccs12.end(); ++ssit) { 00575 FD_DF("IsRelativelyOmegaClosed(): G2-marked scc without G1-mark: " << ssit->ToString()); 00576 } 00577 00578 // result is false if we found problematic SCCs to exist 00579 if(umsccs12.size()!=0) return false; 00580 00581 // find all relevant SCCs 2 00582 SccFilter umfilter21(SccFilter::FmIgnoreTrivial | SccFilter::FmStatesAvoid| SccFilter::FmStatesRequire, 00583 mark2,mark1); 00584 std::list<StateSet> umsccs21; 00585 StateSet umroots21; 00586 ComputeScc(product,umfilter21,umsccs21,umroots21); 00587 00588 // report 00589 ssit=umsccs21.begin(); 00590 for(;ssit!=umsccs21.end(); ++ssit) { 00591 FD_DF("IsRelativelyOmegaClosed(): G1-marked scc without G2-mark: " << ssit->ToString()); 00592 } 00593 00594 // result is false if we found problematic SCCs to exist 00595 if(umsccs21.size()!=0) return false; 00596 00597 // done, all tests passed 00598 FD_DF("IsRelativelyOmegaClosed(): pass"); 00599 return true; 00600 } 00601 00602 00603 00604 } // name space libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |