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

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen