syn_functions.cpp

Go 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