libFAUDES

Sections

Index

tp_tparallel.h

Go to the documentation of this file.
00001 /** @file tp_tparallel.h  Parallel composition for timed automata */
00002 
00003 /* Timeplugin for FAU Discrete Event Systems Library (libfaudes)
00004 
00005    Copyright (C) 2007  Thomas Moor
00006    Exclusive copyright is granted to Klaus Schmidt
00007 
00008 */
00009 
00010 
00011 // TODO: this code needs testing!
00012 // TODO: use cparallel for contr. attribs
00013 
00014 #ifndef FAUDES_TP_TPARALLEL_H
00015 #define FAUDES_TP_TPARALLEL_H
00016 
00017 #include "tp_tgenerator.h"
00018 
00019 namespace faudes {
00020 
00021 
00022 // convenience defs for template functions
00023 #define TEMP template < \
00024   class GlobalAttr1, class StateAttr1, class EventAttr1, class TransAttr1, \
00025   class GlobalAttr2, class StateAttr2, class EventAttr2, class TransAttr2, \
00026   class GlobalAttrR, class StateAttrR, class EventAttrR, class TransAttrR >
00027 
00028 #define TGEN1 TtGenerator<GlobalAttr1,StateAttr1,EventAttr1,TransAttr1>
00029 #define TGEN2 TtGenerator<GlobalAttr2,StateAttr2,EventAttr2,TransAttr2>
00030 #define TGENR TtGenerator<GlobalAttrR,StateAttrR,EventAttrR,TransAttrR>
00031 
00032 
00033 /**
00034  * Parallel composition of timed generators. 
00035  * Arguments rGen1 and rGen2 are assumed to have disjoind clocksets.
00036  * This implementation considers accessible states only. 
00037  *
00038  * Technically, this function is a template, but timed attribute interfaces
00039  * are assumed.
00040  *
00041  * @param rGen1
00042  *   First generator
00043  * @param rGen2
00044  *   Second generator
00045  * @param rResGen
00046  *   Reference to resulting parallel composition generator
00047  *
00048  * @ingroup TimedPlugin
00049  */
00050 TEMP void TParallel(const TGEN1& rGen1, const TGEN2& rGen2, TGENR& rResGen);
00051 
00052 
00053 /**
00054  * Parallel composition of timed generators. 
00055  * Arguments rGen1 and rGen2 are assumed to have disjoind clocksets.
00056  * This implementation considers accessible states only. 
00057  *
00058  * Technically, this function is a template, but timed attribute interfaces
00059  * are assumed.  This version fills given reverse composition map with indices. 
00060  *
00061  * @param rGen1
00062  *   First generator
00063  * @param rGen2
00064  *   Second generator
00065  * @param rReverseCompositionMap
00066  *   Reverse composition map (map< pair<Idx,Idx>, Idx>)
00067  * @param rResGen
00068  *   Reference to resulting parallel composition generator
00069  *
00070  * @ingroup TimedPlugin
00071  * @ingroup TimedPlugin
00072  */
00073 TEMP void TParallel(
00074     const TGEN1& rGen1, const TGEN2& rGen2,
00075     std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00076     TGENR& rResGen);
00077 
00078 
00079 
00080 /*
00081  **************************************************************************************
00082  **************************************************************************************
00083  implementation
00084  **************************************************************************************
00085  **************************************************************************************
00086  */
00087 
00088 
00089 // TParallel(rGen1, rGen2, res)
00090 TEMP void TParallel(const TGEN1& rGen1, const TGEN2& rGen2, TGENR& rResGen) {
00091   // prepare result:
00092   rResGen.Clear();
00093   // helpers:
00094   std::map< std::pair<Idx,Idx>, Idx> rcmap;
00095   TParallel(rGen1, rGen2, rcmap, rResGen);
00096   if (rGen1.StateNamesEnabled() && rGen2.StateNamesEnabled()) 
00097     SetComposedStateNames(rGen1, rGen2, rcmap, rResGen); 
00098 }
00099  
00100 
00101 // TParallel(rGen1, rGen2, rReverseCompositionMap, res)
00102 TEMP void TParallel(
00103   const TGEN1& rGen1, const TGEN2& rGen2, 
00104   std::map< std::pair<Idx,Idx>, Idx>& rReverseCompositionMap, 
00105   TGENR& rResGen)
00106 {
00107   FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << ")");
00108   // todo: exception for non-disjoint clocksets
00109   // call untimed parallel composition
00110   Parallel( rGen1, rGen2, rReverseCompositionMap, rResGen);
00111   // 1. union clockset
00112   ClockSet clocks12;
00113   clocks12.InsertSet(rGen1.Clocks());
00114   clocks12.InsertSet(rGen2.Clocks());
00115   FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): clocks:" << clocks12.ToString());
00116   FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): clocks:" << rGen1.Clocks().ToString());
00117   rResGen.InjectClocks(clocks12);
00118   // 2. intersect invariants
00119   std::map< std::pair<Idx,Idx>, Idx>::const_iterator rcit;
00120   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) {
00121     Idx x1=rcit->first.first;
00122     Idx x2=rcit->first.second;
00123     Idx x12=rcit->second;
00124     if(!rResGen.ExistsState(x12)) continue;
00125     TimeConstraint invariant12;
00126     invariant12 << rGen1.Invariant(x1);
00127     invariant12 <<  rGen2.Invariant(x2);
00128     FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): invariant " << x1 << "|" << x2 
00129        << " :" << invariant12.ToString());
00130     rResGen.Invariant(x12,invariant12);
00131   }
00132   // 3. set up composition map (todo: avoid this)
00133   std::map< Idx, std::pair<Idx,Idx> > compositionmap; 
00134   for(rcit=rReverseCompositionMap.begin(); rcit!=rReverseCompositionMap.end(); rcit++) 
00135     compositionmap[rcit->second]=rcit->first;
00136   // 4. resets and guards
00137   TransSet::Iterator tit;
00138   for(tit=rResGen.TransRelBegin(); tit!=rResGen.TransRelEnd(); tit++) {
00139     // hypothesis: unconstraint guard, no resets
00140     TimeConstraint guard;
00141     ClockSet resets;
00142     // if event is in Gen1, intersect with gurad of Gen1
00143     if(rGen1.ExistsEvent(tit->Ev)) {
00144        Transition t1;
00145        t1.X1=compositionmap[tit->X1].first;
00146        t1.Ev=tit->Ev;
00147        t1.X2=compositionmap[tit->X2].first;
00148        FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): guard/resets in Gen1 for " << t1.Str());  
00149        guard.Insert(rGen1.Guard(t1));
00150        resets.InsertSet(rGen1.Resets(t1));
00151     }
00152     // if event is in Gen2, intersect with gurad of Gen2
00153     if(rGen2.ExistsEvent(tit->Ev)) {
00154        Transition t2;
00155        t2.X1=compositionmap[tit->X1].second;
00156        t2.Ev=tit->Ev;
00157        t2.X2=compositionmap[tit->X2].second;
00158        FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): guard/resets in Gen2 for " << t2.Str());  
00159        guard.Insert(rGen2.Guard(t2));
00160        resets.InsertSet(rGen2.Resets(t2));
00161     }
00162     FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): guard " << tit->Str()  
00163        << " :" << guard.ToString());
00164     rResGen.Guard(*tit,guard);
00165     FD_DF("TParallel(" << &rGen1 << "," << &rGen2 << "): resets " << tit->Str()  
00166        << " :" << resets.ToString());
00167     rResGen.Resets(*tit,resets);
00168   }
00169   FD_DF("TParallel: done ");
00170 }
00171 
00172 
00173 
00174 
00175 #undef TEMP
00176 #undef GEN1
00177 #undef GEN2
00178 #undef GENR
00179 
00180 
00181 } // namespace faudes
00182 
00183 #endif 
00184 

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3