Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
RTEOptimizeFormalPart.hpp
Go to the documentation of this file.
1
6namespace rte {
7
8namespace simplify {
9
10template < class SymbolType >
12 ext::smart_ptr < FormalRTEElement < SymbolType > > optimized = optimizeInner ( element );
13
14 FormalRTEAlternation < SymbolType > * alternation = dynamic_cast<FormalRTEAlternation < SymbolType > *>( & element );
15 if( alternation ) {
16 FormalRTEAlternation < SymbolType > * alternationOptimized = dynamic_cast<FormalRTEAlternation < SymbolType > * > ( optimized.get ( ) );
17 if( alternationOptimized ) {
18 * alternation = std::move( * alternationOptimized );
19 } else {
20 * alternation = FormalRTEAlternation < SymbolType > { * optimized, FormalRTEEmpty < SymbolType > { } };
21 }
22 return;
23 }
24
25 FormalRTESubstitution < SymbolType > * concatenation = dynamic_cast<FormalRTESubstitution < SymbolType > *>( & element );
26 if( concatenation ) {
27 FormalRTESubstitution < SymbolType > * concatenationOptimized = dynamic_cast<FormalRTESubstitution < SymbolType > * > ( optimized.get ( ) );
28 if( concatenationOptimized ) {
29 * concatenation = std::move( * concatenationOptimized );
30 } else {
32 }
33 return;
34 }
35
36 FormalRTEIteration < SymbolType > * iteration = dynamic_cast<FormalRTEIteration < SymbolType > *>( & element );
37 if( iteration ) {
38 FormalRTEIteration < SymbolType > * iterationOptimized = dynamic_cast<FormalRTEIteration < SymbolType > *>( optimized.get ( ) );
39 if( iterationOptimized ) {
40 * iteration = std::move( * iterationOptimized );
41 } else {
42 * iteration = FormalRTEIteration < SymbolType > { optimized };
43 }
44 return;
45 }
46
47 // Nothing to optimize original element was FormalRTESymbol, FormalRTESymbolSubst, or FormalRTEEmpty
48}
49
50template < class SymbolType >
53
54 // optimize while you can
55 while( A1( elem ) || A2( elem ) || A3( elem ) || A4( elem ) /*|| A10( elem ) || V2( elem ) || V5( elem ) || V6( elem ) || X1( elem )*/
56 || A5( elem ) || A6( elem ) || A7( elem ) || A8( elem ) || A9( elem ) /*|| V8( elem ) //|| V9( elem )*/
57 || A11( elem ) || V1( elem ) /*|| V3( elem ) || V4( elem ) || V10( elem )*/ || S(elem) );
58
60}
61
62template < class SymbolType >
63bool RTEOptimize::S( FormalRTEElement < SymbolType > * & node ) {
64 bool optimized = false;
66 if( alternation ) {
67 ext::smart_ptr < FormalRTEElement < SymbolType > > tmp = optimizeInner ( alternation->getLeftElement ( ) );
68 if(* tmp != alternation->getLeftElement ( ) ) {
69 optimized = true;
70 alternation->setLeftElement ( * tmp );
71 }
72
73 tmp = optimizeInner ( alternation->getRightElement ( ) );
74 if(* tmp != alternation->getRightElement ( ) ) {
75 optimized = true;
76 alternation->setRightElement ( * tmp );
77 }
78
79 return optimized;
80 }
81
82 FormalRTESubstitution < SymbolType > * concatenation = dynamic_cast<FormalRTESubstitution < SymbolType >*>( node );
83 if( concatenation ) {
84 ext::smart_ptr < FormalRTEElement < SymbolType > > tmp = optimizeInner ( concatenation->getLeftElement() );
85 if(* tmp != concatenation->getLeftElement ( ) ) {
86 optimized = true;
87 concatenation->setLeftElement ( * tmp );
88 }
89
90 tmp = optimizeInner ( concatenation->getRightElement ( ));
91 if(* tmp != concatenation->getRightElement ( )) {
92 optimized = true;
93 concatenation->setRightElement ( * tmp );
94 }
95
96 return optimized;
97 }
98
99 FormalRTEIteration < SymbolType > * iteration = dynamic_cast<FormalRTEIteration < SymbolType >*>( node );
100 if( iteration ) {
101 ext::smart_ptr < FormalRTEElement < SymbolType > > tmp = optimizeInner ( iteration->getElement() );
102
103 if(* tmp != iteration->getElement ( ) ) {
104 optimized = true;
105 iteration->setElement ( * tmp );
106 }
107 return optimized;
108 }
109
110 return optimized;
111}
112
113
119template < class SymbolType >
120bool RTEOptimize::A1( FormalRTEElement < SymbolType > * & node ) {
121 FormalRTEAlternation < SymbolType > * n = dynamic_cast<FormalRTEAlternation < SymbolType > *>( node );
122 if( ! n ) return false;
123
124 if( dynamic_cast < FormalRTEAlternation < SymbolType > * > ( & n->getLeft ( ) ) ) {
125 FormalRTEAlternation < SymbolType > leftAlt ( std::move ( static_cast < FormalRTEAlternation < SymbolType > & > ( n->getLeft ( ) ) ) );
126
127 n->setLeft ( std::move ( leftAlt.getLeft ( ) ) );
128 leftAlt.setLeft ( std::move ( leftAlt.getRight ( ) ) );
129 leftAlt.setRight ( std::move ( n->getRight ( ) ) );
130 n->setRight ( std::move ( leftAlt ) );
131
132 return true;
133 }
134
135 return false;
136}
137
143template < class SymbolType >
144bool RTEOptimize::A2 ( FormalRTEElement < SymbolType > * & node ) {
145 FormalRTEAlternation < SymbolType > * n = dynamic_cast<FormalRTEAlternation < SymbolType > *>( node );
146 if( ! n ) return false;
147
148 if ( dynamic_cast < FormalRTEAlternation < SymbolType > * > ( & n->getRight ( ) ) ) {
149 FormalRTEAlternation < SymbolType > & rightAlt = static_cast < FormalRTEAlternation < SymbolType > & > ( n->getRight ( ) );
150
151 if ( n->getLeft ( ) > rightAlt.getLeft ( ) ) {
152 ext::ptr_value < FormalRTEElement < SymbolType > > tmp ( std::move ( n->getLeft ( ) ) );
153
154 n->setLeft ( std::move ( rightAlt.getLeft ( ) ) );
155 rightAlt.setLeft ( std::move ( tmp ) );
156 return true;
157 } else {
158 return false;
159 }
160 }
161
162 return false;
163}
164
170template < class SymbolType >
171bool RTEOptimize::A3 ( FormalRTEElement < SymbolType > * & node ) {
172 FormalRTEAlternation < SymbolType > * n = dynamic_cast < FormalRTEAlternation < SymbolType > * > ( node );
173 if( ! n ) return false;
174
175 // input can be \0 + \0, so at least one element must be preserved
176
177 if ( dynamic_cast < FormalRTEEmpty < SymbolType > * > ( & n->getRight ( ) ) ) {
178 node = std::move ( n->getLeft ( ) ).clone ( );
179 delete n;
180 return true;
181 }
182
183 if ( dynamic_cast < FormalRTEEmpty < SymbolType > * > ( & n->getLeft ( ) ) ) {
184 node = std::move ( n->getRight ( ) ).clone ( );
185 delete n;
186 return true;
187 }
188
189 return false;
190}
191
197template < class SymbolType >
198bool RTEOptimize::A4( FormalRTEElement < SymbolType > * & node ) {
199 /*
200 * two ways of implementing this opitimization:
201 * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts...
202 * - check every element against other ( O(n*n) )
203 *
204 * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2
205 */
206
207 FormalRTEAlternation < SymbolType > * n = dynamic_cast < FormalRTEAlternation < SymbolType > * > ( node );
208 if ( ! n ) return false;
209
210 if ( n->getLeftElement() == n->getRightElement() ) {
211 node = std::move ( n->getRight ( ) ).clone ( );
212 delete n;
213 return true;
214 }
215
216 return false;
217}
218
224template < class SymbolType >
225bool RTEOptimize::A5( FormalRTEElement < SymbolType > * & node ) {
226 FormalRTESubstitution < SymbolType > * n = dynamic_cast<FormalRTESubstitution < SymbolType > *>( node );
227 if( ! n ) return false;
228
229 FormalRTESubstitution < SymbolType > * leftNode = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & n->getLeft ( ) );
230 if( leftNode && n->getSubstitutionSymbol ( ) == leftNode->getSubstitutionSymbol ( ) ) {
231 FormalRTESubstitution < SymbolType > leftCon ( std::move ( * leftNode ) );
232
233 n->setLeft ( std::move ( leftCon.getLeft ( ) ) );
234 leftCon.setLeft ( std::move ( leftCon.getRight ( ) ) );
235 leftCon.setRight ( std::move ( n->getRight ( ) ) );
236 n->setRight ( std::move ( leftCon ) );
237
238 return true;
239 }
240
241 return false;
242}
243
249template < class SymbolType >
250bool RTEOptimize::A6( FormalRTEElement < SymbolType > * & node ) {
251 FormalRTESubstitution < SymbolType > * n = dynamic_cast<FormalRTESubstitution < SymbolType > *>( node );
252 if( ! n ) return false;
253
254 // input can be \e + \e, so at least one element must be preserved
255
256 if ( n->getSubstitutionSymbol ( ) == n->getLeft ( ) ) {
257 node = std::move ( n->getRight ( ) ).clone ( );
258 delete n;
259 return true;
260 }
261
262 if ( n->getSubstitutionSymbol ( ) == n->getRight ( ) ) {
263 node = std::move ( n->getRight ( ) ).clone ( );
264 delete n;
265 return true;
266 }
267
268
269 return false;
270}
271
277template < class SymbolType >
278bool RTEOptimize::A7( FormalRTEElement < SymbolType > * & node ) {
279 FormalRTESubstitution < SymbolType > * n = dynamic_cast<FormalRTESubstitution < SymbolType > *>( node );
280 if( ! n ) return false;
281
282 if ( /*dynamic_cast < FormalRTEEmpty < SymbolType > * > ( & n->getRight ( ) ) || */ dynamic_cast < FormalRTEEmpty < SymbolType > * > ( & n->getLeft ( ) ) ) {
283 delete n;
284 node = new FormalRTEEmpty < SymbolType > { };
285 return true;
286 }
287
288 return false;
289}
290
296template < class SymbolType >
297bool RTEOptimize::A8( FormalRTEElement < SymbolType > * & node ) {
298 FormalRTEAlternation < SymbolType > * n = dynamic_cast<FormalRTEAlternation < SymbolType > *>( node );
299 if( ! n ) return false;
300
301 FormalRTESubstitution < SymbolType > * left = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & n->getLeft ( ) );
302 FormalRTESubstitution < SymbolType > * right = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & n->getRight ( ) );
303 if ( left && right && left->getLeft ( ) == right->getLeft ( ) && left->getSubstitutionSymbol ( ) == right->getSubstitutionSymbol ( ) ) {
304 FormalRTEAlternation < SymbolType > alt { std::move ( left->getRight ( ) ), std::move ( right->getRight ( ) ) };
305
306 node = new FormalRTESubstitution < SymbolType > ( std::move ( left->getLeft ( ) ), std::move ( alt ), std::move ( left->getSubstitutionSymbol ( ) ) );
307 delete n;
308 return true;
309 }
310
311 return false;
312}
313
319template < class SymbolType >
320bool RTEOptimize::A9( FormalRTEElement < SymbolType > * & node ) {
321 FormalRTEAlternation < SymbolType > * n = dynamic_cast<FormalRTEAlternation < SymbolType > *>( node );
322 if( ! n ) return false;
323
324 FormalRTESubstitution < SymbolType > * left = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & n->getLeft ( ) );
325 FormalRTESubstitution < SymbolType > * right = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & n->getRight ( ) );
326 if ( left && right && left->getRight ( ) == right->getRight ( ) && left->getSubstitutionSymbol ( ) == right->getSubstitutionSymbol ( ) ) {
327 FormalRTEAlternation < SymbolType > alt { std::move ( left->getLeft ( ) ), std::move ( right->getLeft ( ) ) };
328
329 node = new FormalRTESubstitution < SymbolType > ( std::move ( alt ), std::move ( left->getRight ( ) ), std::move ( left->getSubstitutionSymbol ( ) ) );
330 delete n;
331 return true;
332 }
333
334 return false;
335}
336
342/*template < class SymbolType >
343bool RTEOptimize::A10( FormalRTEElement < SymbolType > * & n ) {*/
344 /*
345 * problem:
346 * - \e + x*x = x*
347 * - but if we do not have the eps, but we do have iteration, then \e \in h(iter), therefore \e in h(node).
348 */
349
350/* FormalRTEAlternation < SymbolType > * node = dynamic_cast<FormalRTEAlternation < SymbolType > * > ( n );
351 if ( ! node ) return false;
352
353 if ( dynamic_cast < FormalRTESymbolSubst < SymbolType > * > ( & node->getLeft ( ) ) ) {
354 FormalRTESubstitution < SymbolType > * rightCon = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & node->getRight ( ) );
355 if ( ! rightCon ) return false;
356
357 FormalRTEIteration < SymbolType > * rightLeftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & rightCon->getLeft ( ) );
358 if ( rightLeftIte ) {
359 if ( rightLeftIte->getElement ( ) == rightCon->getRightElement ( ) ) {
360 n = std::move ( rightCon->getLeft ( ) ).clone ( );
361 delete node;
362 return true;
363 }
364 }
365
366 FormalRTEIteration < SymbolType > * rightRightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & rightCon->getRight ( ) );
367 if ( rightRightIte ) {
368 if ( rightRightIte->getElement ( ) == rightCon->getLeftElement ( ) ) {
369 n = std::move ( rightCon->getRight ( ) ).clone ( );
370 delete node;
371 return true;
372 }
373 }
374 }
375
376 if ( dynamic_cast < FormalRTESymbolSubst < SymbolType > * > ( & node->getRight ( ) ) ) {
377 FormalRTESubstitution < SymbolType > * leftCon = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & node->getLeft ( ) );
378 if ( ! leftCon ) return false;
379
380 FormalRTEIteration < SymbolType > * leftLeftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & leftCon->getLeft ( ) );
381 if ( leftLeftIte ) {
382 if ( leftLeftIte->getElement ( ) == leftCon->getRightElement ( ) ) {
383 n = std::move ( leftCon->getLeft ( ) ).clone ( );
384 delete node;
385 return true;
386 }
387 }
388
389 FormalRTEIteration < SymbolType > * leftRightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & leftCon->getRight ( ) );
390 if ( leftRightIte ) {
391 if ( leftRightIte->getElement ( ) == leftCon->getLeftElement ( ) ) {
392 n = std::move ( leftCon->getRight ( ) ).clone ( );
393 delete node;
394 return true;
395 }
396 }
397 }
398
399 return false;
400}*/
401
407template < class SymbolType >
408bool RTEOptimize::A11( FormalRTEElement < SymbolType > * & node ) {
409 FormalRTEIteration < SymbolType > * n = dynamic_cast<FormalRTEIteration < SymbolType > *>( node );
410 if( ! n ) return false;
411
412 FormalRTEAlternation < SymbolType > * childAlt = dynamic_cast < FormalRTEAlternation < SymbolType > * > ( & n->getChild ( ) );
413 if ( childAlt ) {
414 if ( childAlt->getLeft ( ) == n->getSubstitutionSymbol ( ) ) {
415 n->setChild ( std::move ( childAlt->getRight ( ) ) );
416 return true;
417 }
418 if ( childAlt->getRight ( ) == n->getSubstitutionSymbol ( ) ) {
419 n->setChild ( std::move ( childAlt->getLeft ( ) ) );
420 return true;
421 }
422 }
423
424 return false;
425}
426
432template < class SymbolType >
433bool RTEOptimize::V1( FormalRTEElement < SymbolType > * & node ) {
434 FormalRTEIteration < SymbolType > * n = dynamic_cast<FormalRTEIteration < SymbolType > *>( node );
435 if( ! n ) return false;
436
437 if ( dynamic_cast < FormalRTEEmpty < SymbolType > * > ( & n->getChild ( ) ) ) {
438 delete std::exchange ( node, n->getSubstitutionSymbol ( ).clone ( ) );
439 return true;
440 }
441 return false;
442}
443
449/*template < class SymbolType >
450bool RTEOptimize::V2( FormalRTEElement < SymbolType > * & n ) {
451 FormalRTEAlternation < SymbolType > * node = dynamic_cast<FormalRTEAlternation < SymbolType > *>( n );
452 if( ! node ) return false;
453
454 FormalRTEIteration < SymbolType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & node->getLeft ( ) );
455 if ( leftIte ) {
456 if ( leftIte->getElement ( ) == node->getRightElement ( ) ) {
457 n = std::move ( node->getLeft ( ) ).clone ( );
458 delete node;
459 return true;
460 }
461 }
462
463 FormalRTEIteration < SymbolType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & node->getRight ( ) );
464 if ( rightIte ) {
465 if ( rightIte->getElement ( ) == node->getLeftElement ( ) ) {
466 n = std::move ( node->getRight ( ) ).clone ( );
467 delete node;
468 return true;
469 }
470 }
471
472 return false;
473}*/
474
480/*template < class SymbolType >
481bool RTEOptimize::V3( FormalRTEElement < SymbolType > * & n ) {
482 FormalRTEIteration < SymbolType > * node = dynamic_cast<FormalRTEIteration < SymbolType > *>( n );
483 if( ! node ) return false;
484
485 FormalRTEIteration < SymbolType > * childIter = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & node->getChild ( ) );
486 if( childIter ) {
487 node->setChild ( std::move ( childIter->getChild ( ) ) );
488 return true;
489 }
490
491 return false;
492}*/
493
499/*template < class SymbolType >
500bool RTEOptimize::V4( FormalRTEElement < SymbolType > * & n ) {
501 FormalRTEIteration < SymbolType > * node = dynamic_cast < FormalRTEIteration < SymbolType > *>( n );
502 if( ! node ) return false;
503
504 FormalRTESubstitution < SymbolType > * child = dynamic_cast < FormalRTESubstitution < SymbolType > * > ( & node->getChild ( ) );
505 if( ! child ) return false;
506
507 FormalRTEIteration < SymbolType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & child->getLeft ( ) );
508 if( ! leftIte ) return false;
509
510 FormalRTEIteration < SymbolType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & child->getRight ( ) );
511 if( ! rightIte ) return false;
512
513 node->setChild ( FormalRTEAlternation < SymbolType >( std::move ( leftIte->getElement ( ) ), std::move ( rightIte->getElement ( ) ) ) );
514
515 return true;
516}*/
517
523/*template < class SymbolType >
524bool RTEOptimize::V5( FormalRTEElement < SymbolType > * & *//* n *//*) {
525 return false; //TODO
526}*/
527
533/*template < class SymbolType >
534bool RTEOptimize::V6( FormalRTEElement < SymbolType > * & *//* n *//*) {
535 return false; //TODO
536}*/
537
543/*template < class SymbolType >
544bool RTEOptimize::V8( FormalRTEElement < SymbolType > * & *//* n *//*) {
545 return false; //TODO
546}*/
547
553/*template < class SymbolType >
554bool RTEOptimize::V9( FormalRTEElement < SymbolType > * & *//* n *//*) {
555 return false; //TODO
556}*/
557
563/*template < class SymbolType >
564bool RTEOptimize::V10( FormalRTEElement < SymbolType > * & n ) {
565 FormalRTEIteration < SymbolType > * node = dynamic_cast < FormalRTEIteration < SymbolType > *>( n );
566 if( ! node ) return false;
567
568 FormalRTEAlternation < SymbolType > * alt = dynamic_cast < FormalRTEAlternation < SymbolType > * > ( & node->getChild ( ) );
569 if( ! alt ) return false;
570
571 FormalRTEIteration < SymbolType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & alt->getLeft ( ) );
572 if( ! leftIte ) return false;
573
574 FormalRTEIteration < SymbolType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & alt->getRight ( ) );
575 if( ! rightIte ) return false;
576
577 alt->setLeft ( std::move ( leftIte->getChild ( ) ) );
578 alt->setRight ( std::move ( rightIte->getChild ( ) ) );
579
580 return true;
581}*/
582
588/*template < class SymbolType >
589bool RTEOptimize::X1( FormalRTEElement < SymbolType > * & n ) {
590 FormalRTEAlternation < SymbolType > * node = dynamic_cast<FormalRTEAlternation < SymbolType > *>( n );
591 if( ! node ) return false;
592
593 FormalRTEIteration < SymbolType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & node->getLeft ( ) );
594 if ( leftIte ) {
595 if ( dynamic_cast < FormalRTESymbolSubst < SymbolType > * > ( & node->getRight ( ) ) ) {
596 n = std::move ( node->getLeft ( ) ).clone ( );
597 delete node;
598 return true;
599 }
600 }
601
602 FormalRTEIteration < SymbolType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType > * > ( & node->getRight ( ) );
603 if ( rightIte ) {
604 if ( dynamic_cast < FormalRTESymbolSubst < SymbolType > * > ( & node->getLeft ( ) ) ) {
605 n = std::move ( node->getRight ( ) ).clone ( );
606 delete node;
607 return true;
608 }
609 }
610
611 return false;
612
613}*/
614
615} /* namespace simplify */
616
617} /* namespace rte */
Class representing wrapper of dynamically allocated object behaving like rvalue reference.
Definition: ptr_value.hpp:40
Managed pointer simulating value like behavior.
Definition: memory.hpp:233
T * get()
Getter of the raw managed pointer.
Definition: memory.hpp:367
Represents the alternation operator in the regular tree expression. The node must have exactly two ch...
Definition: FormalRTEAlternation.h:44
const FormalRTEElement< SymbolType > & getRightElement() const
Definition: FormalRTEAlternation.h:220
const FormalRTEElement< SymbolType > & getLeftElement() const
Definition: FormalRTEAlternation.h:215
void setLeftElement(FormalRTEElement< SymbolType > &&element)
Definition: FormalRTEAlternation.h:240
void setRightElement(FormalRTEElement< SymbolType > &&element)
Definition: FormalRTEAlternation.h:250
Definition: FormalRTEElement.h:54
Represents the empty expression in the regular tree expression. The node can't have any children.
Definition: FormalRTEEmpty.h:40
Represents the iteration operator in the regular tree expression. The node has exactly one child.
Definition: FormalRTEIteration.h:45
Represents the concatenation operator in the regular tree expression. The node must have exactly two ...
Definition: FormalRTESubstitution.h:44
Represents the substitution symbol in the regular tree expression. The node can't have any children.
Definition: FormalRTESymbolSubst.h:43
static rte::FormalRTE< SymbolType > optimize(const rte::FormalRTE< SymbolType > &rte)
Definition: Node.cpp:11
Definition: ToFTAGlushkov.h:22