From cbdf1502f07ff52c1d082dc82c09784fc3120dc0 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 16 Apr 2019 09:03:24 +0200 Subject: [PATCH] add basic rte optimize functionality --- alib2algo/src/rte/simplify/RTEOptimize.cpp | 23 + alib2algo/src/rte/simplify/RTEOptimize.h | 101 +++ .../rte/simplify/RTEOptimizeFormalPart.hpp | 620 ++++++++++++++++++ 3 files changed, 744 insertions(+) create mode 100644 alib2algo/src/rte/simplify/RTEOptimize.cpp create mode 100644 alib2algo/src/rte/simplify/RTEOptimize.h create mode 100644 alib2algo/src/rte/simplify/RTEOptimizeFormalPart.hpp diff --git a/alib2algo/src/rte/simplify/RTEOptimize.cpp b/alib2algo/src/rte/simplify/RTEOptimize.cpp new file mode 100644 index 0000000000..4fcd6de81b --- /dev/null +++ b/alib2algo/src/rte/simplify/RTEOptimize.cpp @@ -0,0 +1,23 @@ +/* + * RTEOptimize.cpp + * + * Created on: 1. 4. 2019 + * Author: Jan Travnicek + */ + +#include "RTEOptimize.h" +#include <registration/AlgoRegistration.hpp> + +namespace rte { + +namespace simplify { + +auto RTEOptimizeFormalRTE = registration::AbstractRegister < RTEOptimize, FormalRTE < >, const FormalRTE < > & > ( RTEOptimize::optimize, "rte" ).setDocumentation ( +"Implements a rte simplification algorithm that is transforming the regular expression to be smaller.\n\ +\n\ +@param rte the simplified rte\n\ +@return the simlified rte" ); + +} /* namespace rte */ + +} /* namespace simplify */ diff --git a/alib2algo/src/rte/simplify/RTEOptimize.h b/alib2algo/src/rte/simplify/RTEOptimize.h new file mode 100644 index 0000000000..0b411f88b8 --- /dev/null +++ b/alib2algo/src/rte/simplify/RTEOptimize.h @@ -0,0 +1,101 @@ +/* + * RTEOptimize.h + * + * Created on: 1. 4. 2019 + * Author: Jan Travnicek + */ + +#ifndef _RTE_OPTIMIZE_H__ +#define _RTE_OPTIMIZE_H__ + +#include <alib/algorithm> +#include <alib/iterator> + +#include <rte/formal/FormalRTE.h> +#include <rte/formal/FormalRTEElements.h> + +#include <exception/CommonException.h> + +namespace rte { + +namespace simplify { + +class RTEOptimize { +public: + + template < class SymbolType, class RankType > + static rte::FormalRTE < SymbolType, RankType > optimize( const rte::FormalRTE < SymbolType, RankType > & rte ); + template < class SymbolType, class RankType > + static rte::FormalRTEStructure < SymbolType, RankType > optimize( const rte::FormalRTEStructure < SymbolType, RankType > & rte ); + template < class SymbolType, class RankType > + static void optimize( rte::FormalRTEElement < SymbolType, RankType > & rte ); +private: + template < class SymbolType, class RankType > + static ext::smart_ptr < rte::FormalRTEElement < SymbolType, RankType > > optimizeInner( const rte::FormalRTEElement < SymbolType, RankType > & node ); + + template < class SymbolType, class RankType > + static bool S( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A1( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A2( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A3( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A4( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A5( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A6( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A7( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A8( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool A9( rte::FormalRTEElement < SymbolType, RankType > * & node ); +/* template < class SymbolType, class RankType > + static bool A10( rte::FormalRTEElement < SymbolType, RankType > * & node );*/ + template < class SymbolType, class RankType > + static bool A11( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V1( rte::FormalRTEElement < SymbolType, RankType > * & node ); +/* template < class SymbolType, class RankType > + static bool V2( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V3( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V4( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V5( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V6( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V8( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V9( rte::FormalRTEElement < SymbolType, RankType > * & node ); + template < class SymbolType, class RankType > + static bool V10( rte::FormalRTEElement < SymbolType, RankType > * & node );*/ + + template < class SymbolType, class RankType > + static bool X1( rte::FormalRTEElement < SymbolType, RankType > * & node ); +}; + +template < class SymbolType, class RankType > +FormalRTE < SymbolType, RankType > RTEOptimize::optimize( const FormalRTE < SymbolType, RankType > & rte ) { + return rte::FormalRTE < SymbolType, RankType > ( RTEOptimize::optimize ( rte.getRTE ( ) ) ); +} + +template < class SymbolType, class RankType > +FormalRTEStructure < SymbolType, RankType > RTEOptimize::optimize( const FormalRTEStructure < SymbolType, RankType > & rte ) { + ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > optimized = optimizeInner( rte.getStructure ( ) ); + + return rte::FormalRTEStructure < SymbolType, RankType > ( * optimized ); +} + +} /* namespace simplify */ + +} /* namespace rte */ + +#include "RTEOptimizeFormalPart.hpp" + +#endif /* _RTE_OPTIMIZE_H__ */ diff --git a/alib2algo/src/rte/simplify/RTEOptimizeFormalPart.hpp b/alib2algo/src/rte/simplify/RTEOptimizeFormalPart.hpp new file mode 100644 index 0000000000..d2a8304727 --- /dev/null +++ b/alib2algo/src/rte/simplify/RTEOptimizeFormalPart.hpp @@ -0,0 +1,620 @@ +/* + * RTEOptimize.cpp + * + * Created on: 1. 4. 2019 + * Author: Jan Travnicek + */ + +namespace rte { + +namespace simplify { + +template < class SymbolType, class RankType > +void RTEOptimize::optimize( FormalRTEElement < SymbolType, RankType > & element ) { + ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > optimized = optimizeInner ( element ); + + FormalRTEAlternation < SymbolType, RankType > * alternation = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( & element ); + if( alternation ) { + FormalRTEAlternation < SymbolType, RankType > * alternationOptimized = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > * > ( optimized.get ( ) ); + if( alternationOptimized ) { + * alternation = std::move( * alternationOptimized ); + } else { + * alternation = FormalRTEAlternation < SymbolType, RankType > { * optimized, FormalRTEEmpty < SymbolType, RankType > { } }; + } + return; + } + + FormalRTESubstitution < SymbolType, RankType > * concatenation = dynamic_cast<FormalRTESubstitution < SymbolType, RankType > *>( & element ); + if( concatenation ) { + FormalRTESubstitution < SymbolType, RankType > * concatenationOptimized = dynamic_cast<FormalRTESubstitution < SymbolType, RankType > * > ( optimized.get ( ) ); + if( concatenationOptimized ) { + * concatenation = std::move( * concatenationOptimized ); + } else { + * concatenation = FormalRTESubstitution < SymbolType, RankType > { * optimized, FormalRTESymbolSubst < SymbolType, RankType > { } }; + } + return; + } + + FormalRTEIteration < SymbolType, RankType > * iteration = dynamic_cast<FormalRTEIteration < SymbolType, RankType > *>( & element ); + if( iteration ) { + FormalRTEIteration < SymbolType, RankType > * iterationOptimized = dynamic_cast<FormalRTEIteration < SymbolType, RankType > *>( optimized.get ( ) ); + if( iterationOptimized ) { + * iteration = std::move( * iterationOptimized ); + } else { + * iteration = FormalRTEIteration < SymbolType, RankType > { optimized }; + } + return; + } + + // Nothing to optimize original element was FormalRTESymbol, FormalRTESymbolSubst, or FormalRTEEmpty + return; +} + +template < class SymbolType, class RankType > +ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > RTEOptimize::optimizeInner( const FormalRTEElement < SymbolType, RankType > & node ) { + FormalRTEElement < SymbolType, RankType > * elem = node.clone(); + + // optimize while you can + while( A1( elem ) || A2( elem ) || A3( elem ) || A4( elem ) /*|| A10( elem ) || V2( elem ) || V5( elem ) || V6( elem ) || X1( elem )*/ + || A5( elem ) || A6( elem ) || A7( elem ) || A8( elem ) || A9( elem ) /*|| V8( elem ) //|| V9( elem )*/ + || A11( elem ) || V1( elem ) /*|| V3( elem ) || V4( elem ) || V10( elem )*/ || S(elem) ); + + return ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > ( elem ); +} + +template < class SymbolType, class RankType > +bool RTEOptimize::S( FormalRTEElement < SymbolType, RankType > * & node ) { + bool optimized = false; + FormalRTEAlternation < SymbolType, RankType > * alternation = dynamic_cast<FormalRTEAlternation < SymbolType, RankType >*>( node ); + if( alternation ) { + ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > tmp = optimizeInner ( alternation->getLeftElement ( ) ); + if(* tmp != alternation->getLeftElement ( ) ) { + optimized = true; + alternation->setLeftElement ( * tmp ); + } + + tmp = optimizeInner ( alternation->getRightElement ( ) ); + if(* tmp != alternation->getRightElement ( ) ) { + optimized = true; + alternation->setRightElement ( * tmp ); + } + + return optimized; + } + + FormalRTESubstitution < SymbolType, RankType > * concatenation = dynamic_cast<FormalRTESubstitution < SymbolType, RankType >*>( node ); + if( concatenation ) { + ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > tmp = optimizeInner ( concatenation->getLeftElement() ); + if(* tmp != concatenation->getLeftElement ( ) ) { + optimized = true; + concatenation->setLeftElement ( * tmp ); + } + + tmp = optimizeInner ( concatenation->getRightElement ( )); + if(* tmp != concatenation->getRightElement ( )) { + optimized = true; + concatenation->setRightElement ( * tmp ); + } + + return optimized; + } + + FormalRTEIteration < SymbolType, RankType > * iteration = dynamic_cast<FormalRTEIteration < SymbolType, RankType >*>( node ); + if( iteration ) { + ext::smart_ptr < FormalRTEElement < SymbolType, RankType > > tmp = optimizeInner ( iteration->getElement() ); + + if(* tmp != iteration->getElement ( ) ) { + optimized = true; + iteration->setElement ( * tmp ); + } + return optimized; + } + + return optimized; +} + + +/** + * optimization A1: ( x + y ) + z = x + ( y + z ) + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A1( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + if( dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( & node->getLeft ( ) ) ) { + FormalRTEAlternation < SymbolType, RankType > leftAlt ( std::move ( static_cast < FormalRTEAlternation < SymbolType, RankType > & > ( node->getLeft ( ) ) ) ); + + node->setLeft ( std::move ( leftAlt.getLeft ( ) ) ); + leftAlt.setLeft ( std::move ( leftAlt.getRight ( ) ) ); + leftAlt.setRight ( std::move ( node->getRight ( ) ) ); + node->setRight ( std::move ( leftAlt ) ); + + return true; + } + + return false; +} + +/** + * optimization A2: x + y = y + x (sort) + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A2 ( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + if ( dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( & node->getRight ( ) ) ) { + FormalRTEAlternation < SymbolType, RankType > & rightAlt = static_cast < FormalRTEAlternation < SymbolType, RankType > & > ( node->getRight ( ) ); + + if ( node->getLeft ( ) > rightAlt.getLeft ( ) ) { + ext::ptr_value < FormalRTEElement < SymbolType, RankType > > tmp ( std::move ( node->getLeft ( ) ) ); + + node->setLeft ( std::move ( rightAlt.getLeft ( ) ) ); + rightAlt.setLeft ( std::move ( tmp ) ); + return true; + } else { + return false; + } + } + + return false; +} + +/** + * optimization A3: x + \0 = x + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A3 ( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( n ); + if( ! node ) return false; + + // input can be \0 + \0, so at least one element must be preserved + + if ( dynamic_cast < FormalRTEEmpty < SymbolType, RankType > * > ( & node->getRight ( ) ) ) { + n = std::move ( node->getLeft ( ) ).clone ( ); + delete node; + return true; + } + + if ( dynamic_cast < FormalRTEEmpty < SymbolType, RankType > * > ( & node->getLeft ( ) ) ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + + return false; +} + +/** + * optimization A4: x + x = x + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A4( FormalRTEElement < SymbolType, RankType > * & n ) { + /* + * two ways of implementing this opitimization: + * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts... + * - check every element against other ( O(n*n) ) + * + * As we always sort in optimization, we can use the first version, but A4 must be __always__ called __after__ A2 + */ + + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( n ); + if ( ! node ) return false; + + if ( node->getLeftElement() == node->getRightElement() ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + + return false; +} + +/** + * optimization A5: x.(y.z) = (x.y).z = x.y.z + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A5( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTESubstitution < SymbolType, RankType > * node = dynamic_cast<FormalRTESubstitution < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTESubstitution < SymbolType, RankType > * leftNode = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getLeft ( ) ); + if( leftNode && node->getSubstitutionSymbol ( ) == leftNode->getSubstitutionSymbol ( ) ) { + FormalRTESubstitution < SymbolType, RankType > leftCon ( std::move ( * leftNode ) ); + + node->setLeft ( std::move ( leftCon.getLeft ( ) ) ); + leftCon.setLeft ( std::move ( leftCon.getRight ( ) ) ); + leftCon.setRight ( std::move ( node->getRight ( ) ) ); + node->setRight ( std::move ( leftCon ) ); + + return true; + } + + return false; +} + +/** + * optimization A6: \e.x = x.\e = x + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A6( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTESubstitution < SymbolType, RankType > * node = dynamic_cast<FormalRTESubstitution < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + // input can be \e + \e, so at least one element must be preserved + + if ( node->getSubstitutionSymbol ( ) == node->getLeft ( ) ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + + if ( node->getSubstitutionSymbol ( ) == node->getRight ( ) ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + + + return false; +} + +/** + * optimization A7: \0.x = x.\0 = \0 + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A7( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTESubstitution < SymbolType, RankType > * node = dynamic_cast<FormalRTESubstitution < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + if ( /*dynamic_cast < FormalRTEEmpty < SymbolType, RankType > * > ( & node->getRight ( ) ) || */ dynamic_cast < FormalRTEEmpty < SymbolType, RankType > * > ( & node->getLeft ( ) ) ) { + delete node; + n = new FormalRTEEmpty < SymbolType, RankType > { }; + return true; + } + + return false; +} + +/** + * optimization A8: x.(y+z) = x.y + x.z + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A8( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTESubstitution < SymbolType, RankType > * left = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getLeft ( ) ); + FormalRTESubstitution < SymbolType, RankType > * right = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getRight ( ) ); + if ( left && right && left->getLeft ( ) == right->getLeft ( ) && left->getSubstitutionSymbol ( ) == right->getSubstitutionSymbol ( ) ) { + FormalRTEAlternation < SymbolType, RankType > alt { std::move ( left->getRight ( ) ), std::move ( right->getRight ( ) ) }; + + n = new FormalRTESubstitution < SymbolType, RankType > ( std::move ( left->getLeft ( ) ), std::move ( alt ), std::move ( left->getSubstitutionSymbol ( ) ) ); + delete node; + return true; + } + + return false; +} + +/** + * optimization A9: (x+y).z = x.z + y.z + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A9( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTESubstitution < SymbolType, RankType > * left = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getLeft ( ) ); + FormalRTESubstitution < SymbolType, RankType > * right = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getRight ( ) ); + if ( left && right && left->getRight ( ) == right->getRight ( ) && left->getSubstitutionSymbol ( ) == right->getSubstitutionSymbol ( ) ) { + FormalRTEAlternation < SymbolType, RankType > alt { std::move ( left->getLeft ( ) ), std::move ( right->getLeft ( ) ) }; + + n = new FormalRTESubstitution < SymbolType, RankType > ( std::move ( alt ), std::move ( left->getRight ( ) ), std::move ( left->getSubstitutionSymbol ( ) ) ); + delete node; + return true; + } + + return false; +} + +/** + * optimization A10: x* = \e + x*x + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::A10( FormalRTEElement < SymbolType, RankType > * & n ) {*/ + /* + * problem: + * - \e + x*x = x* + * - but if we do not have the eps, but we do have iteration, then \e \in h(iter), therefore \e in h(node). + */ + +/* FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > * > ( n ); + if ( ! node ) return false; + + if ( dynamic_cast < FormalRTESymbolSubst < SymbolType, RankType > * > ( & node->getLeft ( ) ) ) { + FormalRTESubstitution < SymbolType, RankType > * rightCon = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getRight ( ) ); + if ( ! rightCon ) return false; + + FormalRTEIteration < SymbolType, RankType > * rightLeftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & rightCon->getLeft ( ) ); + if ( rightLeftIte ) { + if ( rightLeftIte->getElement ( ) == rightCon->getRightElement ( ) ) { + n = std::move ( rightCon->getLeft ( ) ).clone ( ); + delete node; + return true; + } + } + + FormalRTEIteration < SymbolType, RankType > * rightRightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & rightCon->getRight ( ) ); + if ( rightRightIte ) { + if ( rightRightIte->getElement ( ) == rightCon->getLeftElement ( ) ) { + n = std::move ( rightCon->getRight ( ) ).clone ( ); + delete node; + return true; + } + } + } + + if ( dynamic_cast < FormalRTESymbolSubst < SymbolType, RankType > * > ( & node->getRight ( ) ) ) { + FormalRTESubstitution < SymbolType, RankType > * leftCon = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getLeft ( ) ); + if ( ! leftCon ) return false; + + FormalRTEIteration < SymbolType, RankType > * leftLeftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & leftCon->getLeft ( ) ); + if ( leftLeftIte ) { + if ( leftLeftIte->getElement ( ) == leftCon->getRightElement ( ) ) { + n = std::move ( leftCon->getLeft ( ) ).clone ( ); + delete node; + return true; + } + } + + FormalRTEIteration < SymbolType, RankType > * leftRightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & leftCon->getRight ( ) ); + if ( leftRightIte ) { + if ( leftRightIte->getElement ( ) == leftCon->getLeftElement ( ) ) { + n = std::move ( leftCon->getRight ( ) ).clone ( ); + delete node; + return true; + } + } + } + + return false; +}*/ + +/** + * optimization A11: x* = (\e + x)* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::A11( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEIteration < SymbolType, RankType > * node = dynamic_cast<FormalRTEIteration < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTEAlternation < SymbolType, RankType > * childAlt = dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( & node->getChild ( ) ); + if ( childAlt ) { + if ( childAlt->getLeft ( ) == node->getSubstitutionSymbol ( ) ) { + node->setChild ( std::move ( childAlt->getRight ( ) ) ); + return true; + } + if ( childAlt->getRight ( ) == node->getSubstitutionSymbol ( ) ) { + node->setChild ( std::move ( childAlt->getLeft ( ) ) ); + return true; + } + } + + return false; +} + +/** + * optimization V1: \0* = \e + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +template < class SymbolType, class RankType > +bool RTEOptimize::V1( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEIteration < SymbolType, RankType > * node = dynamic_cast<FormalRTEIteration < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + if ( dynamic_cast < FormalRTEEmpty < SymbolType, RankType > * > ( & node->getChild ( ) ) ) { + delete std::exchange ( n, node->getSubstitutionSymbol ( ).clone ( ) ); + return true; + } + return false; +} + +/** + * optimization V2: x* + x = x* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V2( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTEIteration < SymbolType, RankType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & node->getLeft ( ) ); + if ( leftIte ) { + if ( leftIte->getElement ( ) == node->getRightElement ( ) ) { + n = std::move ( node->getLeft ( ) ).clone ( ); + delete node; + return true; + } + } + + FormalRTEIteration < SymbolType, RankType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & node->getRight ( ) ); + if ( rightIte ) { + if ( rightIte->getElement ( ) == node->getLeftElement ( ) ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + } + + return false; +}*/ + +/** + * optimization V3: x** = x* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V3( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEIteration < SymbolType, RankType > * node = dynamic_cast<FormalRTEIteration < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTEIteration < SymbolType, RankType > * childIter = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & node->getChild ( ) ); + if( childIter ) { + node->setChild ( std::move ( childIter->getChild ( ) ) ); + return true; + } + + return false; +}*/ + +/** + * optimization V4: (x+y)* = (x*y*)* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V4( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEIteration < SymbolType, RankType > * node = dynamic_cast < FormalRTEIteration < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTESubstitution < SymbolType, RankType > * child = dynamic_cast < FormalRTESubstitution < SymbolType, RankType > * > ( & node->getChild ( ) ); + if( ! child ) return false; + + FormalRTEIteration < SymbolType, RankType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & child->getLeft ( ) ); + if( ! leftIte ) return false; + + FormalRTEIteration < SymbolType, RankType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & child->getRight ( ) ); + if( ! rightIte ) return false; + + node->setChild ( FormalRTEAlternation < SymbolType, RankType >( std::move ( leftIte->getElement ( ) ), std::move ( rightIte->getElement ( ) ) ) ); + + return true; +}*/ + +/** + * optimization V5: x*y = y + x*xy + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V5( FormalRTEElement < SymbolType, RankType > * & *//* n *//*) { + return false; //TODO +}*/ + +/** + * optimization V6: x*y = y + xx*y + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V6( FormalRTEElement < SymbolType, RankType > * & *//* n *//*) { + return false; //TODO +}*/ + +/** + * optimization V8: \e in h(x) => xx*=x* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V8( FormalRTEElement < SymbolType, RankType > * & *//* n *//*) { + return false; //TODO +}*/ + +/** + * optimization V9: (xy)*x = x(yx)* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V9( FormalRTEElement < SymbolType, RankType > * & *//* n *//*) { + return false; //TODO +}*/ + +/** + * optimization V10: (x+y)* = (x*+y*)* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::V10( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEIteration < SymbolType, RankType > * node = dynamic_cast < FormalRTEIteration < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTEAlternation < SymbolType, RankType > * alt = dynamic_cast < FormalRTEAlternation < SymbolType, RankType > * > ( & node->getChild ( ) ); + if( ! alt ) return false; + + FormalRTEIteration < SymbolType, RankType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & alt->getLeft ( ) ); + if( ! leftIte ) return false; + + FormalRTEIteration < SymbolType, RankType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & alt->getRight ( ) ); + if( ! rightIte ) return false; + + alt->setLeft ( std::move ( leftIte->getChild ( ) ) ); + alt->setRight ( std::move ( rightIte->getChild ( ) ) ); + + return true; +}*/ + +/** + * optimization X1: a* + \e = a* + * @param node FormalRTEElement < SymbolType, RankType > node + * @return bool true if optimization applied else false + */ +/*template < class SymbolType, class RankType > +bool RTEOptimize::X1( FormalRTEElement < SymbolType, RankType > * & n ) { + FormalRTEAlternation < SymbolType, RankType > * node = dynamic_cast<FormalRTEAlternation < SymbolType, RankType > *>( n ); + if( ! node ) return false; + + FormalRTEIteration < SymbolType, RankType > * leftIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & node->getLeft ( ) ); + if ( leftIte ) { + if ( dynamic_cast < FormalRTESymbolSubst < SymbolType, RankType > * > ( & node->getRight ( ) ) ) { + n = std::move ( node->getLeft ( ) ).clone ( ); + delete node; + return true; + } + } + + FormalRTEIteration < SymbolType, RankType > * rightIte = dynamic_cast < FormalRTEIteration < SymbolType, RankType > * > ( & node->getRight ( ) ); + if ( rightIte ) { + if ( dynamic_cast < FormalRTESymbolSubst < SymbolType, RankType > * > ( & node->getLeft ( ) ) ) { + n = std::move ( node->getRight ( ) ).clone ( ); + delete node; + return true; + } + } + + return false; + +}*/ + +} /* namespace simplify */ + +} /* namespace rte */ -- GitLab