mtc_parallel.cpp

Go to the documentation of this file.
00001 /** @file mtc_parallel.cpp
00002 
00003 Methods for parallel composition of multitasking generators
00004 
00005 */
00006 
00007 /* FAU Discrete Event Systems Library (libfaudes)
00008 
00009    Copyright (C) 2008  Matthias Singer
00010    Copyright (C) 2007  Thomas Moor
00011    Exclusive copyright is granted to Klaus Schmidt
00012 
00013    This library is free software; you can redistribute it and/or
00014    modify it under the terms of the GNU Lesser General Public
00015    License as published by the Free Software Foundation; either
00016    version 2.1 of the License, or (at your option) any later version.
00017 
00018    This library is distributed in the hope that it will be useful,
00019    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021    Lesser General Public License for more details.
00022 
00023    You should have received a copy of the GNU Lesser General Public
00024    License along with this library; if not, write to the Free Software
00025    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00026 
00027 
00028 #include "mtc_parallel.h"
00029 
00030 namespace faudes {
00031 
00032 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2, MtcSystem& rResGen) {
00033   // inputs have to agree on controllability of shared events:
00034 #ifdef FAUDES_CHECKED
00035   EventSet inconsistent = (rGen1.ControllableEvents()*rGen2.UncontrollableEvents())
00036       +(rGen1.UncontrollableEvents()*rGen2.ControllableEvents());
00037   if(!inconsistent.Empty()) {
00038     std::stringstream errstr;
00039     errstr << "mtcParallel: inconsistent controllability flags";
00040     throw Exception("mtcParallel::inconsistent controllability flags", errstr.str(), 500);
00041   }
00042 #endif
00043   // prepare result
00044   rResGen.Clear();
00045 
00046   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00047 
00048   // make parallel composition of inputs
00049   mtcParallel(rGen1, rGen2, rcmap, rResGen);
00050 
00051   // copy controllability of input alphabets (TODO: copy all event attributes as in a Parallel)
00052   rResGen.SetControllable(rGen1.ControllableEvents());
00053   rResGen.SetControllable(rGen2.ControllableEvents());
00054 }
00055 
00056 
00057 // Parallel(rGen1, rGen2, rReverseCompositionMap, res)
00058 void mtcParallel(const MtcSystem& rGen1, const MtcSystem& rGen2,
00059     std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00060     MtcSystem& rResGen) {
00061   FD_DF("mtcParallel(" << &rGen1 << "," << &rGen2 << ")");
00062   // prepare result
00063   rResGen.Clear();
00064   rResGen.Name(rGen1.Name()+"||"+rGen2.Name());
00065   // rGen1.events() \ rGen2.events()
00066   EventSet sharedalphabet = rGen1.Alphabet() * rGen2.Alphabet();
00067   FD_DF("mtcParallel: shared events: " << sharedalphabet.ToString());
00068 
00069   // create res alphabet
00070   EventSet::Iterator eit;
00071   for (eit = rGen1.AlphabetBegin(); eit != rGen1.AlphabetEnd(); ++eit) {
00072     rResGen.InsEvent(*eit);
00073   }
00074   for (eit = rGen2.AlphabetBegin(); eit != rGen2.AlphabetEnd(); ++eit) {
00075     rResGen.InsEvent(*eit);
00076   }
00077   FD_DF("mtcParallel: inserted indices in rResGen.alphabet( "
00078       << rResGen.AlphabetToString() << ")");
00079 
00080   // todo stack
00081   std::stack< std::pair<Idx,Idx> > todo;
00082   // actual pair, new pair
00083   std::pair<Idx,Idx> currentstates, newstates;
00084   // state
00085   Idx tmpstate;
00086 
00087   StateSet::Iterator lit1, lit2;
00088   TransSet::Iterator tit1, tit1_end, tit2, tit2_end;
00089   std::map< std::pair<Idx,Idx>, Idx>::iterator rcit;
00090 
00091   ColorSet colors1, colors2, composedSet;
00092   rGen1.Colors(colors1);
00093   rGen2.Colors(colors2);
00094 
00095   // push all combinations of initial states on todo stack
00096   FD_DF("mtcParallel: adding all combinations of initial states to todo:");
00097   for (lit1 = rGen1.InitStatesBegin(); lit1 != rGen1.InitStatesEnd(); ++lit1) {
00098     for (lit2 = rGen2.InitStatesBegin(); lit2 != rGen2.InitStatesEnd(); ++lit2) {
00099       currentstates = std::make_pair(*lit1, *lit2);
00100       todo.push(currentstates);
00101       tmpstate = rReverseCompositionMap[currentstates] = rResGen.InsInitState();
00102       ComposedColorSet(rGen1, *lit1, colors1, rGen2, *lit2, colors2, composedSet);
00103       rResGen.InsColors(tmpstate, composedSet);
00104       FD_DF("mtcParallel:   (" << *lit1 << "|" << *lit2 << ") -> " 
00105           << rReverseCompositionMap[currentstates]);
00106     }
00107   }
00108 
00109   // start algorithm
00110   FD_DF("mtcParallel: processing reachable states:");
00111   while (! todo.empty()) {
00112     // get next reachable state from todo stack
00113     currentstates = todo.top();
00114     todo.pop();
00115     FD_DF("mtcParallel: processing (" << currentstates.first << "|" 
00116         << currentstates.second << ") -> " 
00117         << rReverseCompositionMap[currentstates]);
00118     // iterate over all rGen1 transitions 
00119     // (includes execution of shared events)
00120     tit1 = rGen1.TransRelBegin(currentstates.first);
00121     tit1_end = rGen1.TransRelEnd(currentstates.first);
00122     for (; tit1 != tit1_end; ++tit1) {
00123       // if event not shared
00124       if (! sharedalphabet.Exists(tit1->Ev)) {
00125         FD_DF("mtcParallel:   exists only in rGen1");
00126         newstates = std::make_pair(tit1->X2, currentstates.second);
00127         // add to todo list if composition state is new
00128         rcit = rReverseCompositionMap.find(newstates);
00129         if (rcit == rReverseCompositionMap.end()) {
00130           todo.push(newstates);
00131           tmpstate = rResGen.InsState();
00132           ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, currentstates.second, colors2, composedSet);
00133           rResGen.InsColors(tmpstate, composedSet);
00134           rReverseCompositionMap[newstates] = tmpstate;
00135           FD_DF("mtcParallel:   todo push: (" << newstates.first << "|" 
00136               << newstates.second << ") -> " 
00137               << rReverseCompositionMap[newstates]);
00138         }
00139         else {
00140           tmpstate = rcit->second;
00141         }
00142         rResGen.SetTransition(rReverseCompositionMap[currentstates], tit1->Ev, 
00143             tmpstate);
00144         FD_DF("mtcParallel:   add transition to new generator: " 
00145             << rReverseCompositionMap[currentstates] << "-" << tit1->Ev << "-" 
00146             << tmpstate);
00147       }
00148       // if shared event
00149       else {
00150         FD_DF("mtcParallel:   common event");
00151         // find shared transitions
00152         tit2 = rGen2.TransRelBegin(currentstates.second, tit1->Ev);
00153         tit2_end = rGen2.TransRelEnd(currentstates.second, tit1->Ev);
00154         for (; tit2 != tit2_end; ++tit2) {
00155           newstates = std::make_pair(tit1->X2, tit2->X2);
00156           // add to todo list if composition state is new
00157           rcit = rReverseCompositionMap.find(newstates);
00158           if (rcit == rReverseCompositionMap.end()) {
00159             todo.push(newstates);
00160             tmpstate = rResGen.InsState();
00161             ComposedColorSet(rGen1, tit1->X2, colors1, rGen2, tit2->X2, colors2, composedSet);
00162             rResGen.InsColors(tmpstate, composedSet);
00163             rReverseCompositionMap[newstates] = tmpstate;
00164             FD_DF("mtcParallel:   todo push: (" << newstates.first << "|" 
00165                 << newstates.second << ") -> " 
00166                 << rReverseCompositionMap[newstates]);
00167           }
00168           else {
00169             tmpstate = rcit->second;
00170           }
00171           rResGen.SetTransition(rReverseCompositionMap[currentstates], 
00172               tit1->Ev, tmpstate);
00173           FD_DF("mtcParallel:   add transition to new generator: " 
00174               << rReverseCompositionMap[currentstates] << "-" 
00175               << tit1->Ev << "-" << tmpstate);
00176         }
00177       }
00178     }
00179     // iterate over all rGen2 transitions 
00180     // (without execution of shared events)
00181     tit2 = rGen2.TransRelBegin(currentstates.second);
00182     tit2_end = rGen2.TransRelEnd(currentstates.second);
00183     for (; tit2 != tit2_end; ++tit2) {
00184       if (! sharedalphabet.Exists(tit2->Ev)) {
00185         FD_DF("mtcParallel:   exists only in rGen2");
00186         newstates = std::make_pair(currentstates.first, tit2->X2);
00187         // add to todo list if composition state is new
00188         rcit = rReverseCompositionMap.find(newstates);
00189         if (rcit == rReverseCompositionMap.end()) {
00190           todo.push(newstates);
00191           tmpstate = rResGen.InsState();
00192           ComposedColorSet(rGen1, currentstates.first, colors1, rGen2, tit2->X2, colors2, composedSet);
00193           rResGen.InsColors(tmpstate, composedSet);
00194           rReverseCompositionMap[newstates] = tmpstate;
00195           FD_DF("mtcParallel:   todo push: (" << newstates.first << "|" 
00196               << newstates.second << ") -> " 
00197               << rReverseCompositionMap[newstates]);
00198         }
00199         else {
00200           tmpstate = rcit->second;
00201         }
00202         rResGen.SetTransition(rReverseCompositionMap[currentstates], 
00203             tit2->Ev, tmpstate);
00204         FD_DF("mtcParallel:   add transition to new generator: " 
00205             << rReverseCompositionMap[currentstates] << "-" 
00206             << tit2->Ev << "-" << tmpstate);
00207       }
00208     }
00209   }
00210 }
00211 
00212   // compose colors
00213 void ComposedColorSet(const MtcSystem& rGen1, const Idx sidx1, ColorSet& rColors1,
00214                       const MtcSystem& rGen2, const Idx sidx2, ColorSet& rColors2,
00215                       ColorSet& composedSet) {
00216 
00217   composedSet.Clear();
00218 
00219   AttributeColoredState attr1, attr2;
00220   ColorSet::Iterator cit;
00221 
00222 #ifdef FAUDES_CHECKED
00223   try {
00224     attr1 = rGen1.States().Attribute(sidx1);
00225   }
00226   catch (faudes::Exception& exception){
00227     std::stringstream errstr;
00228     errstr << "Index " << sidx1 << " not member of set" << std::endl;
00229     throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)",
00230       errstr.str(), 200);
00231   }
00232   try {
00233     attr2 = rGen2.States().Attribute(sidx2);
00234   }
00235   catch (faudes::Exception& exception){
00236     std::stringstream errstr;
00237     errstr << "Index " << sidx2 << " not member of set" << std::endl;
00238     throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, composedSet)",
00239       errstr.str(), 200);
00240   }
00241 #else
00242   attr1 = rGen1.States().Attribute(sidx1);
00243   attr2 = rGen2.States().Attribute(sidx2);
00244 #endif
00245 
00246   if(!attr1.IsDefault()) {
00247     // iterate over colors in current state of generator 1
00248     for (cit = attr1.ColorsBegin(); cit != attr1.ColorsEnd(); cit++) {
00249 #ifdef FAUDES_CHECKED
00250       if (!rColors1.Exists(*cit))
00251         throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)",
00252           "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors1", 201);
00253 #endif
00254       if(rColors2.Exists(*cit)) {
00255         // color also exists in second generator
00256         if(!attr2.IsDefault() && attr2.Colors().Exists(*cit)) {
00257           // current color exists in second generator's current state
00258           // -> insert into composedSet
00259           composedSet.Insert(*cit);
00260         }
00261       }
00262       else {
00263         // current color does not exist in generator 2
00264         // -> insert into composedSet
00265         composedSet.Insert(*cit);
00266       }
00267     }
00268   }
00269 
00270   if(!attr2.IsDefault()) {
00271     // iterate over second generator's colors
00272     for (cit = attr2.ColorsBegin(); cit != attr2.ColorsEnd(); cit++) {
00273 #ifdef FAUDES_CHECKED
00274       if (!rColors2.Exists(*cit))
00275         throw Exception("mtcparallel: ComposedColorSet(rGen1, sidx1, rColors1, rGen2, sidx2, rColors2, rGenRes, sidxRes)",
00276           "Color index \""+ToStringInteger(*cit)+"\" not found in generator's color set rColors2", 201);
00277 #endif
00278       if (!rColors1.Exists(*cit)) {
00279         // color does not exist in generator 1
00280         // -> insert into composedSet
00281         composedSet.Insert(*cit);
00282       }
00283     }
00284   }
00285 }
00286 
00287 } // namespace faudes

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