syn_supnorm.cpp
Go to the documentation of this file.
1 /** @file syn_supnorm.cpp Supremal normal sublanguage */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Bernd Opitz
6  Exclusive copyright is granted to Klaus Schmidt
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
21 
22 
23 #include "syn_supnorm.h"
24 #include "syn_supcon.h"
25 
26 /* turn on debugging for this file */
27 //#undef FD_DF
28 //#define FD_DF(a) FD_WARN(a);
29 
30 namespace faudes {
31 
32 
33 
34 
35 /*
36 ***************************************************************************************
37 ***************************************************************************************
38  Implementation
39 ***************************************************************************************
40 ***************************************************************************************
41 */
42 
43 
44 //void NormalityConsistencyCheck(rL,rOAlph,rK)
46  const Generator& rL,
47  const EventSet& rOAlph,
48  const Generator& rK) {
49 
50  FD_DF("NormalityConsistencyCheck(...)");
51 
52  if (!(rK.IsDeterministic())) {
53  std::stringstream errstr;
54  errstr << "Nondeterministic parameter rK.";
55  if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
56  throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
57  }
58  if (!(rL.IsDeterministic())) {
59  std::stringstream errstr;
60  errstr << "Nondeterministic parameter rL.";
61  if(!(rL.IsDeterministic())) errstr << "Nondeterministic parameter rL.";
62  throw Exception("NormalityConsistencyCheck", errstr.str(), 101);
63  }
64 
65  EventSet Kevents,Sigma;
66  Sigma=rL.Alphabet();
67  Kevents=rK.Alphabet();
68 
69  // observable events have to be subset of Sigma
70  if(!(rOAlph<=Sigma)) {
71  EventSet only_in_OAlph = rOAlph - Sigma;
72  std::stringstream errstr;
73  errstr << "Not all observable events are contained in Sigma: "
74  << only_in_OAlph.ToString() << ".";
75  throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
76  }
77 
78  // alphabets must match
79  if ( Sigma != Kevents) {
80  EventSet only_in_L = Sigma - Kevents;
81  EventSet only_in_K = Kevents - Sigma;
82  only_in_L.Name("Only_In_L");
83  only_in_L.Name("Only_In_K");
84  std::stringstream errstr;
85  errstr << "Alphabets of generators do not match.";
86  if(!only_in_L.Empty())
87  errstr << " " << only_in_L.ToString() << ".";
88  if(!only_in_K.Empty())
89  errstr << " " << only_in_K.ToString() << ".";
90  throw Exception("NormalityConsistencyCheck", errstr.str(), 100);
91  }
92 
93  // K must be subset of L
94  if (!LanguageInclusion(rK,rL)) {
95  std::stringstream errstr;
96  errstr << "K is not subset of L.";
97  throw Exception("NormalityConsistencyCheck", errstr.str(), 0);
98  }
99 }
100 
101 // IsNormal(rK,rL,rOAlph)
102 bool IsNormal(
103  const Generator& rL,
104  const EventSet& rOAlph,
105  const Generator& rK)
106 {
107  FD_DF("IsNormal(...)");
108 
109  // bail out on empty K
110  // note: this is required to survive the
111  // determinism test when rK has no states at all
112  if(IsEmptyLanguage(rK)) return true;
113 
114  // determinism required
115  NormalityConsistencyCheck(rL,rOAlph,rK);
116 
117  //extract overall alphabet:
118  EventSet Sigma;
119  Sigma=rL.Alphabet();
120 
121  //extract alphabet of rK:
122  EventSet Kevents;
123  Kevents=rK.Alphabet();
124 
125  //calculate p(K)
126  Generator Ktest1, Ktest2;
127  Ktest1.StateNamesEnabled(false);
128  Ktest2.StateNamesEnabled(false);
129  Project(rK,rOAlph,Ktest1);
130 
131  //calculate pinv(p(K))
132  InvProject(Ktest1, Sigma);
133 
134  //check normality: pinv(p(K)) intersect L = K?
135  LanguageIntersection(Ktest1,rL,Ktest2);
136  return LanguageInclusion(Ktest2,rK);
137 
138  // Remark: testing for LanguageEquality is not required, as inclusion
139  // in the reverse direction is always met (assuming K\subseteq L)
140 }
141 
142 
143 
144 // IsNormal rti wrapper
145 bool IsNormal(const System& rPlantGen, const Generator& rSupCandGen) {
146  return IsNormal(rPlantGen, rPlantGen.ObservableEvents(),rSupCandGen);
147 }
148 
149 
150 // ConcatenateFullLanguage(rGen)
152  FD_DF("ConcatenateFullLanguage(" << rGen.Name() << ")");
153 
154  // prepare result
155  rGen.Name("ConcatenateFullLanguage(" + rGen.Name() + ")");
156 
157  // treat trivial empty result in case of empty marked language
158  if(rGen.MarkedStatesSize()==0) {
159  rGen.Clear();
160  return;
161  }
162 
163  // helpers
164  EventSet alph=rGen.Alphabet();
165  StateSet StatesToClear;
166  TransSet TransToClear,TransToSet;
167  StateSet::Iterator sit;
168  TransSet::Iterator tit;
169  EventSet::Iterator evit;
170 
171  // clear all transitions in marked states
172  for (sit = rGen.MarkedStatesBegin(); sit != rGen.MarkedStatesEnd(); ++sit) {
173  for (tit = rGen.TransRelBegin(*sit); tit != rGen.TransRelEnd(*sit); ++tit) {
174  TransToClear.Insert(*tit);
175  }
176  }
177 
178  for (tit = TransToClear.Begin(); tit != TransToClear.End(); ++tit) {
179  rGen.ClrTransition(*tit);
180  }
181  TransToClear.Clear();
182  rGen.Accessible();
183 
184  // all marked states become eqivalent -> switch transitions leading to marked states to one remaining marked state
185  // and delete all the others; note: for this special purpose, this procedure is faster than running StateMin.
186  // if an init state is marked the effort is even less (as the result is Sigma* itself, see "else" below)
187  bool initmarked = !( (rGen.InitStates() * rGen.MarkedStates()).Empty() );
188  if (!initmarked) {
189  // define remaining marked state (there is one because of nonzero MarkedStatesSize)
190  sit = rGen.MarkedStatesBegin();
191  Idx marked = *sit;
192  // switch transitions to all other marked states if there are any
193  if(rGen.MarkedStatesSize()>1) {
194  // extract transitions sorted by target state X2
195  TransSetX2EvX1 trel;
196  rGen.TransRel(trel);
198 
199  // switch transitions to all other marked states to the one remaining marked state
200  ++sit;
201  for (; sit != rGen.MarkedStatesEnd(); ++sit) {
202  for (tit2 = trel.BeginByX2(*sit); tit2 != trel.EndByX2(*sit); ++tit2) {
203  // switch transition target to remaining marked state
204  TransToSet.Insert(tit2->X1,tit2->Ev,marked);
205  // note: original transitions are cleared later with clearing the corresp. marked states.
206  }
207  }
208 
209  // delete all but remaining marked state (note: by doing so, also corresp. transitions are cleared.)
210  sit = rGen.MarkedStatesBegin();
211  ++sit;
212  for (; sit != rGen.MarkedStatesEnd(); ++sit) {
213  StatesToClear.Insert(*sit);
214  }
215  for (sit=StatesToClear.Begin(); sit != StatesToClear.End(); ++sit) {
216  rGen.DelState(*sit);
217  }
218  StatesToClear.Clear();
219 
220  // insert switched transitions
221  for (tit = TransToSet.Begin(); tit != TransToSet.End(); ++tit) {
222  rGen.SetTransition(*tit);
223  }
224  TransToSet.Clear();
225  }
226 
227  // now concatenate Sigma* by selflooping marked state with all events
228  for (evit = alph.Begin(); evit != alph.End(); ++evit) {
229  rGen.SetTransition(marked,*evit,marked);
230  }
231 
232  }
233  // consider marked init state case
234  else {
235  FD_DF("ConcatenateFullLanguage(" << rGen.Name() << "): marked initial state");
236  // reduce to empty string language
237  rGen.ClearStates();
238  rGen.ClearTransRel();
239  Idx state=rGen.InsInitState();
240  rGen.SetMarkedState(state);
241  // now concatenate Sigma* by selflooping marked state with all events
242  for (evit = alph.Begin(); evit != alph.End(); ++evit) {
243  rGen.SetTransition(state,*evit,state);
244  }
245 
246  }
247 
248  return;
249 }
250 
251 
252 // SupNorm(rL,rOAlph,rK,rResult)
253 bool SupNorm(
254  const Generator& rL,
255  const EventSet& rOAlph,
256  const Generator& rK,
257  Generator& rResult)
258 {
259  FD_DF("SupNorm(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
260 
261  // exceprions
262  NormalityConsistencyCheck(rL,rOAlph,rK);
263 
264  //extract overall alphabet:
265  EventSet allevents;
266  allevents=rL.Alphabet();
267 
268  // involved operations from cfl_regular.h operate on the marked
269  // languages -> turn generated languages into marked langusges
270  Generator prL=rL;
271  prL.InjectMarkedStates(rL.States());
272  Generator prK=rK;
273  prK.InjectMarkedStates(prK.States());
274 
275  // calculate "L-K"
276  LanguageDifference(prL,prK,rResult);
277 
278  // calculate Pinv(P(L-K)):
279  Project(rResult,rOAlph,rResult);
280  FD_DF("SupNorm: sizeof p(L-K): "<< rResult.Size());
281  InvProject(rResult,allevents);
282  FD_DF("SupNorm: sizeof pinv(p(L-K)): "<< rResult.Size());
283 
284  //calculate remaining set difference -> supnorm(K)
285  LanguageDifference(prK,rResult,rResult);
286 
287  // cosmetics: remove blocking states
288  rResult.Trim();
289 
290  // done
291  rResult.Name("SupNorm("+rL.Name()+", "+rK.Name()+")");
292  return !( rResult.InitStatesEmpty() );
293 }
294 
295 // SupNormClosed(rL,rOAlph,rK,rResult)
297  const Generator& rL,
298  const EventSet& rOAlph,
299  const Generator& rK,
300  Generator& rResult)
301 {
302  FD_DF("SupNormClosed(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
303 
304  // involved operations from regular.h operate on the marked
305  // languages -> turn generated languages into marked langs
306  Generator prL=rL;
307  prL.InjectMarkedStates(prL.States());
308  Generator prK=rK;
309  prK.InjectMarkedStates(prK.States());
310 
311  // concitency check on closed languages
312  NormalityConsistencyCheck(prL,rOAlph,prK);
313 
314  //extract overall alphabet:
315  EventSet allevents;
316  allevents=rL.Alphabet();
317 
318  // calculate "L-K"
319  LanguageDifference(prL,prK,rResult);
320 
321  // calculate Pinv(P(L-K)):
322  Project(rResult,rOAlph,rResult);
323  FD_DF("SupNormClosed: sizeof p(L-K): "<< rResult.Size());
324  InvProject(rResult,allevents);
325  FD_DF("SupNormClosed: sizeof pinv(p(L-K)): "<< rResult.Size());
326 
327  //concatenate Pinv(P(L-K)) with Sigma*: this leads to closed result
328  ConcatenateFullLanguage(rResult); // special function for efficient concatenation of Sigma*.
329 
330  FD_DF("SupNormClosed: sizeof pinv(p(L-K))Sigma*: "<< rResult.Size());
331 
332  //calculate remaining set difference -> supnormClosed(K)
333  LanguageDifference(prK,rResult,rResult);
334 
335  // cosmetics: remove blocking states
336  rResult.Trim();
337 
338  // done
339  rResult.Name("SupNormClosed("+rL.Name()+", "+rK.Name()+")");
340 
341  FD_DF("SupNormClosed(" << rL.Name() << "," << rK.Name() << "," << rOAlph.Name() << ")");
342  return !( rResult.InitStatesEmpty() );
343 }
344 
345 
346 // SupConNormClosed(rL,rCAlph,rOAlph,rK,rResult)
348  const Generator& rL,
349  const EventSet& rCAlph,
350  const EventSet& rOAlph,
351  const Generator& rK,
352  Generator& rResult)
353 {
354  FD_DF("SupConNormClosed(" << rL.Name() << "," << rK.Name() << ")");
355  // determinism required
356  ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK);
357  // 0.: intersect K with L to match requirements of SupNormClosed
358  Generator K;
359  K.StateNamesEnabled(false);
360  Product(rL,rK,K);
361  // 1. normal and closed sublanguage (operates on / returns generated language)
362  Generator N;
363  N.StateNamesEnabled(false);
364  SupNormClosed(rL,rOAlph,K,N);
365  // 2. project to sigma_o (generated languages)
366  Generator N0,L0;
367  N0.StateNamesEnabled(false);
368  L0.StateNamesEnabled(false);
369  Project(N,rOAlph,N0);
370  Project(rL,rOAlph,L0);
371  // 3. supremal controllable sublanguage (generated languages)
372  EventSet sig_co = rCAlph * rOAlph;
373  Generator K0;
374  K0.StateNamesEnabled(false);
375  SupConClosed(L0,sig_co,N0,K0);
376  // 4. inverese project to sigma (on generated language)
377  InvProject(K0,rL.Alphabet());
378  // 5. intersect with L (generated languages)
379  LanguageIntersection(K0,rL,rResult);
380  // convenience: mark the generated language
381  rResult.InjectMarkedStates(rResult.States());
382 }
383 
384 
385 // SupConNormNB(rL,rCAlph,rOAlph,rK,rResult)
387  const Generator& rL,
388  const EventSet& rCAlph,
389  const EventSet& rOAlph,
390  const Generator& rK,
391  Generator& rResult)
392 {
393  FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << ")");
394  // determinism required
395  ControlProblemConsistencyCheck(rL,rCAlph,rOAlph,rK);
396  // initialize: K0
397  Generator K0;
398  K0.StateNamesEnabled(false);
399  Product(rL,rK,K0);
400  K0.Coaccessible();
401  // initialize: closure(rL)
402  Generator L=rL;
403  L.StateNamesEnabled(false);
404  L.Trim();
405  L.InjectMarkedStates(L.States());
406  // loop
407  Generator Ki=K0;
408  Ki.StateNamesEnabled(false);
409  while(1) {
410  FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): #" << Ki.Size() << " m#" << Ki.MarkedStatesSize());
411  // keep copy of recent
412  rResult=Ki;
413  // cheep closure (for coreachable generator)
414  Ki.InjectMarkedStates(Ki.States());
415  // synthesise closed
416  SupConNormClosed(L,rCAlph,rOAlph,Ki,Ki);
417  // restrict
418  Product(K0,Ki,Ki);
419  Ki.Coaccessible();
420  // test (sequence is decreasing anyway)
421  if(LanguageInclusion(rResult,Ki)) break;
422  }
423  FD_DF("SupConNormNB(" << rL.Name() << "," << rK.Name() << "): done");
424 }
425 
426 
427 // SupPrefixClosed(rK,rResult)
429  const Generator& rK,
430  Generator& rResult)
431 {
432 
433  FD_DF("SupPrefixClosed("<<rK.Name()<<")");
434 
435  // prepare Result:
436  rResult.Name("SupPrefixClosed("+rK.Name()+")");
437 
438  // check for marked initial state, empty result if not
439  if( (rK.InitStates() * rK.MarkedStates()).Empty() ) {
440  rResult.Clear();
441  return false;
442  }
443 
444  rResult.Assign(rK);
445 
446  // erase all transitions not leading to a marked state
447  // todo: Depth-first-search could be faster
448  TransSet::Iterator tit=rResult.TransRelBegin();
449  TransSet::Iterator tit_end=rResult.TransRelEnd();
450  while(tit!=tit_end) {
451  if(rResult.ExistsMarkedState(tit->X2)) { ++tit; continue;}
452  rResult.ClrTransition(tit++);
453  }
454 
455  // make reachable (cosmetic)
456  rResult.Trim();
457 
458  // as there is at least one marked init state, result is nonempty
459  return true;
460 }
461 
462 
463 // helper class
464 class SNOState {
465 public:
466  // minimal interface
467  SNOState() {};
468  SNOState(const Idx& rq, const Idx& rx, const bool& rz) :
469  q(rq), x(rx), z(rz) {};
470  std::string Str(void) { return ToStringInteger(q)+"|"+
472  // order
473  bool operator < (const SNOState& other) const {
474  if (q < other.q) return(true);
475  if (q > other.q) return(false);
476  if (x < other.x) return(true);
477  if (x > other.x) return(false);
478  if (z < other.z) return(true);
479  return(false);
480  }
481  // member variables
485 };
486 
487 
488 // SupConNormClosedUnchecked(rPlantGen, rCAlph, rObserverGen, rSupCandGen)
490  const Generator& rPlantGen, // aka G
491  const EventSet& rCAlph,
492  const EventSet& rOAlph,
493  Generator& rObserverGen, // aka Hobs
494  Generator& rSupCandGen // aka H
495 )
496 {
497  FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << ")");
498 
499  // bail out on L(G)=0 --> closed-lopp language inclusion trivialy satisfied
500  if(rPlantGen.InitStatesEmpty()) return;
501 
502  // debugging: compare result with Lin-Brandt fromula at end of function
503  // Generator K;
504  // SupConNormClosed(rPlantGen, rCAlph, rOAlph, rSupCandGen, K);
505 
506  // loop until fixpoint
507  while(true) {
508  FD_DF("SupConNormClosedUnchecked(" << &rSupCandGen << "," << &rPlantGen << "): until fixpoint #" << rSupCandGen.Size());
509 
510  // record size to break loop
511  Idx ssz = rSupCandGen.TransRelSize();
512  Idx osz = rObserverGen.TransRelSize();
513 
514  // bail out if L(H)-0 --> closed-loop language fixpoint
515  if(rSupCandGen.InitStatesEmpty()) break;
516 
517  // todo stack (state triplets)
518  std::stack<SNOState> todo;
519  // relevant H states
520  StateSet processed, critical;
521 
522  // various iterators
523  TransSet::Iterator titg, titg_end;
524  TransSet::Iterator tith, tith_end;
525  TransSet::Iterator titho, titho_end;
526 
527  // current and successsor state
528  SNOState current, successor;
529 
530  // push combined initial state on todo stack
531  FD_DF("SupNorm: todo push initial state");
532  current.q = *rPlantGen.InitStatesBegin();
533  current.x = *rSupCandGen.InitStatesBegin();
534  current.z = *rObserverGen.InitStatesBegin();
535  todo.push(current);
536 
537  // process todo stack
538  while(!todo.empty()) {
539  // allow for user interrupt, incl progress report
540  FD_WPC(1,2,"Normality(): iterating states");
541  // get top element from todo stack
542  current = todo.top();
543  todo.pop();
544  FD_DF("SupNorm: todo #" << todo.size() << " processed #" << processed.Size());
545  FD_DF("SupNorm: pop: (" << rPlantGen.SStr(current.q) << "|" << rSupCandGen.SStr(current.x) << ")");
546 
547  // break cycles
548  if(processed.Exists(current.x)) continue;
549  if(critical.Exists(current.x)) continue;
550 
551  // record processed
552  processed.Insert(current.x);
553 
554  // figure events disbabled by candidate H w.r.t plant G
555  EventSet disabled = rPlantGen.ActiveEventSet(current.q) - rSupCandGen.ActiveEventSet(current.x);
556 
557  // if an unobservabel event is disabled, current state becomes critical
558  if(!(disabled <= rCAlph)) {
559  critical.Insert(current.x);
560  continue;
561  }
562 
563  // disable respective transition in observer Hobs
564  titho = rObserverGen.TransRelBegin(current.z);
565  titho_end = rObserverGen.TransRelEnd(current.z);
566  while(titho!=titho_end) {
567  if(!disabled.Exists(titho->Ev)) { ++titho; continue; }
568  rObserverGen.ClrTransition(titho++);
569  }
570 
571  // find successor states to push on stack
572  titg = rPlantGen.TransRelBegin(current.q);
573  titg_end = rPlantGen.TransRelEnd(current.q);
574  tith = rSupCandGen.TransRelBegin(current.x);
575  tith_end = rSupCandGen.TransRelEnd(current.x);
576  titho = rObserverGen.TransRelBegin(current.z);
577  titho_end = rObserverGen.TransRelEnd(current.z);
578  while( (titg != titg_end) && (tith != tith_end) && (titho != titho_end) ) {
579  FD_DF("SupNorm: processing g-transition: " << rPlantGen.TStr(*titg));
580  FD_DF("SupNorm: processing h-transition: " << rSupCandGen.TStr(*tith));
581  // increment case A: process common events
582  if( (titg->Ev == tith->Ev) && (tith->Ev == titho->Ev) ) {
583  FD_DF("SupNorm: processing common event " << rPlantGen.EStr(titg->Ev));
584  // push successor
585  if(!processed.Exists(tith->X2)) {
586  successor.q=titg->X2;
587  successor.x=tith->X2;
588  successor.z=titho->X2;
589  todo.push(successor);
590  }
591  // increment
592  ++titg; ++tith; ++titho;
593  }
594  // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs)
595  else if (tith->Ev < titho->Ev) {
596  rSupCandGen.ClrTransition(tith++);
597  }
598  // increment case C: increment Hobs transitions for events disabled by H (for removed critical states))
599  else if (titho->Ev < tith->Ev) {
600  ++titho;
601  }
602  // increment case D: increment G transitions for events disabled by H
603  else if (titg->Ev < tith->Ev) {
604  ++titg;
605  }
606  // increment case E: increment Hobs transitions for events disabled by G
607  else {
608  ++titho;
609  }
610  } // end accessible states
611  // reasoning for leftovers:
612  // a) if tith==end then we dont need to restrict H by Hobs anymore
613  // b) if titg=end then (by L subseteq K) we have tith=end, and we argue as in a)
614  // c) if titho=end then we need to restrict H by Hobs ...
615  while( (tith != tith_end) ) {
616  // increment case B: increment H transitions for events disabled by Hobs (when we disabled events in Hobs)
617  rSupCandGen.ClrTransition(tith++);
618  }
619 
620  } // end: todo stack
621 
622  // remove critical
623  //rSupCandGen.DelStates((rSupCandGen.States()-processed) + critical);
624  rSupCandGen.DelStates(critical);
625 
626  // break on fixpoint
627  if(ssz != rSupCandGen.TransRelSize()) continue;
628  if(osz != rObserverGen.TransRelSize()) continue;
629  break;
630 
631  } //end: until fixpoint
632 
633  // cosmetic
634  rSupCandGen.Accessible();
635 
636  /*
637  // debugging: compare with Lin-Brandt formula
638  Generator Rpr = rSupCandGen;
639  MarkAllStates(Rpr);
640  if(!LanguageEquality(K,Rpr)) FD_WARN("SUPNORM ERROR??? Supremal?");
641  */
642 
643 }
644 
645 
646 
647 /** rti wrapper */
648 void SupNorm(
649  const System& rPlantGen,
650  const Generator& rSpecGen,
651  Generator& rResGen)
652 {
653  // prepare result
654  Generator* pResGen = &rResGen;
655  if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
656  pResGen= rResGen.New();
657  }
658  // execute
659  SupNorm(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
660  // copy all attributes of input alphabet
661  pResGen->EventAttributes(rPlantGen.Alphabet());
662  // copy result
663  if(pResGen != &rResGen) {
664  pResGen->Move(rResGen);
665  delete pResGen;
666  }
667 }
668 
669 /** rti wrapper */
671  const System& rPlantGen,
672  const Generator& rSpecGen,
673  Generator& rResGen)
674 {
675  // prepare result
676  Generator* pResGen = &rResGen;
677  if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
678  pResGen= rResGen.New();
679  }
680  // execute
681  SupNormClosed(rPlantGen,rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
682  // copy all attributes of input alphabet
683  pResGen->EventAttributes(rPlantGen.Alphabet());
684  // copy result
685  if(pResGen != &rResGen) {
686  pResGen->Move(rResGen);
687  delete pResGen;
688  }
689 }
690 
691 
692 /** rti wrapper */
694  const System& rPlantGen,
695  const Generator& rSpecGen,
696  Generator& rResGen)
697 {
698  // prepare result
699  Generator* pResGen = &rResGen;
700  if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
701  pResGen= rResGen.New();
702  }
703  // execute
704  SupConNormClosed(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
705  // copy all attributes of input alphabet
706  pResGen->EventAttributes(rPlantGen.Alphabet());
707  // copy result
708  if(pResGen != &rResGen) {
709  pResGen->Move(rResGen);
710  delete pResGen;
711  }
712 }
713 
714 /** rti wrapper */
716  const System& rPlantGen,
717  const Generator& rSpecGen,
718  Generator& rResGen)
719 {
720  FD_DF("SupConNormNB(" << rPlantGen.Name() << "," << rSpecGen.Name() << "): rti wrapper");
721  // prepare result
722  Generator* pResGen = &rResGen;
723  if(&rResGen== &rPlantGen || &rResGen== &rSpecGen) {
724  pResGen= rResGen.New();
725  }
726  // execute
727  SupConNormNB(rPlantGen,rPlantGen.ControllableEvents(),rPlantGen.ObservableEvents(),rSpecGen,*pResGen);
728  // copy all attributes of input alphabet
729  pResGen->EventAttributes(rPlantGen.Alphabet());
730  // copy result
731  if(pResGen != &rResGen) {
732  pResGen->Move(rResGen);
733  delete pResGen;
734  }
735 }
736 
737 } // end namespace

libFAUDES 2.28c --- 2016.09.30 --- c++ api documentaion by doxygen