op_obserververification.cpp

Go to the documentation of this file.
00001 
00013 /* FAU Discrete Event Systems Library (libfaudes)
00014 
00015    Copyright (C) 2006  Bernd Opitz
00016    Exclusive copyright is granted to Klaus Schmidt
00017 
00018    This library is free software; you can redistribute it and/or
00019    modify it under the terms of the GNU Lesser General Public
00020    License as published by the Free Software Foundation; either
00021    version 2.1 of the License, or (at your option) any later version.
00022 
00023    This library is distributed in the hope that it will be useful,
00024    but WITHOUT ANY WARRANTY; without even the implied warranty of
00025    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026    Lesser General Public License for more details.
00027 
00028    You should have received a copy of the GNU Lesser General Public
00029    License along with this library; if not, write to the Free Software
00030    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00031 #include "op_obserververification.h"
00032 
00033 
00034 namespace faudes {
00035 
00036 bool IsObs(const Generator& rLowGen, const EventSet& rHighAlph){
00037   OP_DF("IsObs(" << rLowGen.Name() << "," << rHighAlph.Name() << ")");
00038   // Initialization of variables
00039   EventSet newHighAlph = rHighAlph;
00040   EventSet controllableEvents;
00041   map<Transition,Idx> mapChangedTrans;
00042   Generator genDyn(rLowGen);
00043   map<Transition,Transition> mapChangedTransReverse;
00044   vector<Idx> newPartitions;
00045   map<Idx,Idx> mapStateToPartition;
00046   map<Idx, EventSet> mapRelabeledEvents;
00047   bool observer;
00048   // One step of the observer algorithm: A dynamic system is computed that fulfills the one-step observer condition. 
00049   // if the result is equal to the original generator, then the natural projection on the high-level alphabet fulfills the observer property
00050   calculateDynamicSystemObs(rLowGen, newHighAlph, genDyn);
00051   Generator genPart;
00052   // compute coarsest quasi-congruence on the dynamic system
00053   calcBisimulation(genDyn, mapStateToPartition, genPart, newPartitions);
00054   // check if quotient automaton is deterministic and free of unobservable events
00055   // and relabel transitions in rLowGen if necessary. The high-level alphabet is modified accordingly
00056   Generator genObs(rLowGen);
00057   observer=relabel(genObs, controllableEvents, newHighAlph, newPartitions, mapStateToPartition, mapChangedTransReverse,  mapChangedTrans, mapRelabeledEvents);
00058   // return the result of the relabeling 
00059   return observer;
00060 
00061 }
00062 
00063 bool IsOCC(const cGenerator& rLowGen, const EventSet& rHighAlph){
00064   OP_DF("IsOCC(" << rLowGen.Name() << "," << rHighAlph.Name() << ")");
00065   EventSet controllableEvents = rLowGen.ControllableEvents();
00066   // call the function that implements the algorithm
00067   return IsOCC(rLowGen, controllableEvents, rHighAlph);
00068 }
00069 
00070 bool IsOCC(const Generator& rLowGen, const EventSet& rControllableEvents, const EventSet& rHighAlph){
00071   OP_DF("IsOCC(" << rLowGen.Name() << "," << rHighAlph.Name() << ")");
00072   //helpers:
00073   StateSet::Iterator stIt, stEndIt;
00074   stIt = rLowGen.StatesBegin();
00075   stEndIt = rLowGen.StatesEnd();
00076   TransSet::Iterator tIt, tEndIt;
00077   // iteration over all states of rLowGen. If there is an uncontrollable feasible high-level event, backward reachability is conducted to determine if OCC holds. 
00078   for( ; stIt != stEndIt; stIt++){
00079     tIt = rLowGen.TransRelBegin(*stIt);
00080     tEndIt = rLowGen.TransRelEnd(*stIt);
00081     for( ; tIt != tEndIt; tIt++){
00082       if(rHighAlph.Exists(tIt->Ev) && !rControllableEvents.Exists(tIt->Ev) ){
00083         // check if all local backward paths are uncontrollable
00084         bool uncontrollable = backwardVerificationOCC(rLowGen, rControllableEvents, rHighAlph, *stIt);
00085         // if not all paths are uncontrollable, OCC is violated
00086         if(uncontrollable == false)
00087           return false;
00088         // otherwise, go to the next state
00089         else
00090           break;
00091       }
00092     }
00093   }
00094   return true;
00095 }
00096 
00097 bool backwardVerificationOCC(const Generator& rLowGen, const EventSet& rControllableEvents, const EventSet& rHighAlph, Idx currentState){
00098   OP_DF("backwardVerificationOCC(" << rLowGen.Name() << "," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << currentState << ")");
00099   // reverse transition relation
00100   TransSetX2EvX1 tset_X2EvX1;
00101   rLowGen.TransRel(tset_X2EvX1);
00102   TransSetX2EvX1::Iterator tsIt, tsEndIt;
00103   // todo list
00104   std::stack<Idx> todo;
00105   // algorithm: the locally backwards reachable states from current staet are 
00106   // evaluated. If a controllable event is found, OCC is violated.
00107   StateSet doneStates;
00108   doneStates.Insert(currentState);
00109   todo.push(currentState);
00110   // the local reachability is evaluated until no new state is found
00111   while( !todo.empty() ){
00112     const Idx current = todo.top();
00113     todo.pop();
00114     tsIt = tset_X2EvX1.BeginByX2(current);
00115     tsEndIt = tset_X2EvX1.EndByX2(current);
00116     for(; tsIt != tsEndIt; tsIt++){
00117       // if the current transition is labeled with a high-level evnet
00118       // it is skipped
00119       if(rHighAlph.Exists(tsIt->Ev) )
00120         continue;
00121       // if the current transition is controllable, OCC is violated
00122       else if( rControllableEvents.Exists(tsIt->Ev) )
00123         return false;
00124       else if( !doneStates.Exists(tsIt->X1) ){
00125         todo.push(tsIt->X1);
00126         doneStates.Insert(tsIt->X1);
00127       }
00128     }
00129   }
00130   return true;
00131 }
00132 
00133 
00134 bool IsLCC(const cGenerator& rLowGen, const EventSet& rHighAlph){
00135   OP_DF("IsLCC(" << rLowGen.Name() << "," << rHighAlph.Name() << ")");
00136   EventSet controllableEvents = rLowGen.ControllableEvents();
00137   // call the function that implements the algorithm
00138   return IsLCC(rLowGen, controllableEvents, rHighAlph);
00139 }
00140 
00141 bool IsLCC(const Generator& rLowGen, const EventSet& rControllableEvents, const EventSet& rHighAlph){
00142   OP_DF("IsLCC(" << rLowGen.Name() << "," << rHighAlph.Name() << ")");
00143   // reverse transition relation
00144   TransSetX2EvX1 tset_X2EvX1;
00145   rLowGen.TransRel(tset_X2EvX1);
00146   //helpers:
00147   StateSet::Iterator stIt, stEndIt;
00148   stIt = rLowGen.StatesBegin();
00149   stEndIt = rLowGen.StatesEnd();
00150   TransSet::Iterator tIt, tEndIt;
00151   StateSet doneStates;
00152   map<Idx, bool> localStatesMap;
00153   map<Idx, bool>::const_iterator lsIt, lsEndIt;
00154   // iteration over all states of rLowGen. If there is an uncontrollable feasible high-level event, backward reachability is conducted to determine if LCC holds. 
00155   for( ; stIt != stEndIt; stIt++){
00156     tIt = rLowGen.TransRelBegin(*stIt);
00157     tEndIt = rLowGen.TransRelEnd(*stIt);
00158     for( ; tIt != tEndIt; tIt++){
00159       if(rHighAlph.Exists(tIt->Ev) && !rControllableEvents.Exists(tIt->Ev) ){
00160         doneStates.Clear();
00161         localStatesMap.clear();
00162         localStatesMap[*stIt] = false;
00163         doneStates.Insert(*stIt);
00164         // check if for all backward reachable states, a local uncontrollable backward paths exists
00165         backwardVerificationLCC(tset_X2EvX1, rControllableEvents, rHighAlph, *stIt, *stIt, false, localStatesMap, doneStates);
00166         // if for some state, all paths are controllable, LCC is violated
00167         lsIt = localStatesMap.begin();
00168         lsEndIt = localStatesMap.end();
00169         for( ; lsIt != lsEndIt; lsIt++){
00170           // if there is a state with only controllable paths, LCC is violated
00171           if(lsIt->second == true)
00172             return false;
00173         }
00174         // the evaluation for the current state is finished
00175         break;
00176       }
00177     }
00178   }
00179   return true;
00180 }
00181 
00182 
00183 void backwardVerificationLCC(const TransSetX2EvX1& rTransSetX2EvX1, const EventSet& rControllableEvents, const EventSet& rHighAlph, Idx exitState, Idx currentState, bool controllablePath, map<Idx, bool>& rLocalStatesMap, StateSet& rDoneStates){
00184   OP_DF("backwardVerificationLCC(rTransSetX2EvX1," << rControllableEvents.Name() << "," << rHighAlph.Name() << "," << exitState << "," << currentState << "," << controllablePath << ",rExitLocalStatesMap, rDoneStates)");
00185     // go along all backward transitions. Discard the goal state if it is reached via a high-level event or if it is in the rDoneStates and 
00186     // the controllability properties of the state do not change on the current path
00187     
00188   // helpers
00189   TransSetX2EvX1::Iterator tsIt, tsEndIt;
00190   tsIt = rTransSetX2EvX1.BeginByX2(currentState);
00191   tsEndIt = rTransSetX2EvX1.EndByX2(currentState);
00192   bool currentControllablePath;
00193   // we iterate over all backward transitions of the currentState to establish backward reachability
00194   for( ;tsIt != tsEndIt; tsIt++){
00195       // states reachable via a high-level event are not in the local backward reach and the controllability property of the current exitState does not change
00196     if( !rHighAlph.Exists(tsIt->Ev) && tsIt->X1 != exitState){
00197       // if the state has not been visited, yet, the controllability of the current path are set in the rExitLocalStatesMap
00198               if( !rDoneStates.Exists(tsIt->X1) ){
00199         rDoneStates.Insert(tsIt->X1);
00200         // the path is uncontrollable if the current transition has an uncontrollable event or the path was already uncontrollable
00201         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00202         rLocalStatesMap[tsIt->X1] = currentControllablePath;
00203         // as the state has not been visited, yet, it is subject to a new backward reachability
00204                     backwardVerificationLCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, currentControllablePath, rLocalStatesMap, rDoneStates);
00205       }
00206       else{ // for an existing state, the controllability value can change from controllable to uncontrollable (if 
00207         // a new uncontrollable path has been found). It is important to note, that the LCC condition implies that
00208         // if there is one uncontrollable path, then the state is flagged uncontrollable except for the case of the 
00209         // given exitState that is always uncontrollable
00210         currentControllablePath = rControllableEvents.Exists(tsIt->Ev) || controllablePath;
00211         if(rLocalStatesMap[tsIt->X1] != currentControllablePath && currentControllablePath == false){
00212           rLocalStatesMap[tsIt->X1] = false;
00213           // as the controllabiity attribute of the current state changed it is subject to a new backward reachability
00214                           backwardVerificationLCC(rTransSetX2EvX1, rControllableEvents, rHighAlph, exitState, tsIt->X1, false, rLocalStatesMap, rDoneStates);
00215         }
00216       }
00217     }
00218   }
00219 }
00220 
00221 }// namespace faudes

Generated on Fri May 9 11:26:47 2008 for libFAUDES 2.09b by  doxygen 1.4.4