op_mc.cppGo 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 |