op_mc.cpp

Go to the documentation of this file.
00001 /** @file op_mc.cpp 
00002 
00003 Method to verify mutual controllability for two given generators.
00004 A definition of mutual controllability is given in 
00005 S.-H. Lee and K. C. Wong, “Structural decentralised control of concurrent
00006 DES,” European Journal of Control, vol. 35, pp. 1125-1134,2002.
00007 */
00008 
00009 /* FAU Discrete Event Systems Library (libfaudes)
00010 
00011    Copyright (C) 2006  Bernd Opitz
00012    Exclusive copyright is granted to Klaus Schmidt
00013 
00014    This library is free software; you can redistribute it and/or
00015    modify it under the terms of the GNU Lesser General Public
00016    License as published by the Free Software Foundation; either
00017    version 2.1 of the License, or (at your option) any later version.
00018 
00019    This library is distributed in the hope that it will be useful,
00020    but WITHOUT ANY WARRANTY; without even the implied warranty of
00021    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022    Lesser General Public License for more details.
00023 
00024    You should have received a copy of the GNU Lesser General Public
00025    License along with this library; if not, write to the Free Software
00026    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00027 
00028 #include "op_mc.h"
00029 
00030 namespace faudes {
00031 
00032 bool IsMutuallyControllable(const System& rGen1, const System& rGen2) {
00033   OP_DF("IsMutuallyControllable(" << rGen1.Name() << ", "
00034       << rGen2.Name() << ")");
00035   // helpers:
00036   StateSet forbidden1;
00037   StateSet forbidden2;
00038   // Tha algorithm is implemented by the following function
00039   return IsMutuallyControllable(rGen1, rGen2, forbidden1, forbidden2);
00040 }
00041 
00042 
00043 bool IsMutuallyControllable(const System& rGen1, const System& rGen2,
00044     StateSet& rForbidden1, StateSet& rForbidden2) {
00045   OP_DF("IsMutuallyControllable(" << rGen1.Name() << ", "
00046       << rGen2.Name() << ", rForbidden1, rForbidden2)");
00047   // algorithm:
00048   // Compute the intersection of the generator alphabets
00049   const EventSet alph12 = rGen1.Alphabet() * rGen2.Alphabet();
00050   OP_DF("IsMutuallyControllable: shared events \"" << alph12.ToString() 
00051       << "\"");
00052   // check for shared events: if there are no shared events, mutual controllability is fulfilled anyway.
00053   if (alph12.Empty()) {
00054     OP_DF("IsMutuallyControllable: shared alphabet empty. "
00055         << "terminating successful");
00056     return true;
00057   }
00058   // check for shared uncontrollable events
00059   const EventSet ualph12 = rGen1.UncontrollableEvents() * rGen2.UncontrollableEvents();
00060   OP_DF("IsMutuallyControllable: shared uncontrollable events \""
00061       << ualph12.ToString() << "\"");
00062   // if there are no shared uncontrollable events, mutual controllability is fulfilled anyway.
00063   if (ualph12.Empty()) {
00064     OP_DF("IsMutuallyControllable: shared uncontrollable alphabet empty "
00065         << "terminating successful");
00066     return true;
00067   }
00068   // prepare results
00069   bool result1;
00070   bool result2;
00071   rForbidden1.Clear();
00072   rForbidden2.Clear();
00073   // The generator g will serve as the plant in the subsequent controllability evaluation
00074   System g = rGen1.NewCGen();
00075   // "plant": (P_21)^-1( P_12( L(G_2) )) is the language generated by g
00076   aProject(rGen2, alph12, g);
00077   InvProject(g, rGen1.Alphabet());
00078   // The set of controllable events for the controllability test is alphabet of rGen1 - the shared uncontrollable events
00079   // mutual controllability test of rGen2 w.r.t. rGen1.
00080   result1 = IsControllable(g,  (rGen1.Alphabet() - ualph12), rGen1, rForbidden1);
00081   // print uncontrollable states if result is negative
00082   if (result1 == false) {
00083     OP_DF("IsMutuallyControllable(" << rGen1.Name() << ", " << rGen2.Name() 
00084         << "): uncontrollable states: " << rForbidden1.ToString());
00085   }
00086   // "plant": (P_12)^-1( P_21( L(G_1) )) is the language generated by g
00087   aProject(rGen1, alph12, g);
00088   InvProject(g, rGen2.Alphabet());
00089   // The set of controllable events for the controllability test is alphabet of rGen2 - the shared uncontrollable events
00090   // mutual controllability test of rGen1 w.r.t. rGen2.
00091   result2 = IsControllable(g, (rGen2.Alphabet() - ualph12), rGen2, rForbidden2);
00092   // print uncontrollable states if result is negative
00093   if (result2 == false) {
00094     OP_DF("IsMutuallyControllable(" << rGen1.Name() << ", " << rGen2.Name() 
00095         << "): uncontrollable states: " << rForbidden2.ToString());
00096   }
00097   
00098   if (result1 && result2) {
00099     OP_DF("IsMutuallyControllable: fulfilled");
00100   }
00101   else {
00102     OP_DF("IsMutuallyControllable: failed");
00103   }
00104 
00105   return (result1 && result2);
00106 }
00107 
00108 // RTI wrapper
00109 void IsMutuallyControllable(const System& rGen1, const System& rGen2, bool& rRes) {
00110   rRes=IsMutuallyControllable(rGen1, rGen2);
00111 }
00112 
00113 } // namespace faudes
00114 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen