From 9490756c9b8337fc84097f56880470b09592cc7a Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 7 Sep 2017 18:57:53 +0200 Subject: [PATCH] templatize construction of (Nonlinear)TreePatternAutomaton --- aarbology2/src/aarbology.cpp | 10 +- .../ExactNonlinearTreePatternAutomaton.cpp | 117 +-------------- .../ExactNonlinearTreePatternAutomaton.h | 133 +++++++++++++++++- .../exact/ExactTreePatternAutomaton.cpp | 48 +------ .../exact/ExactTreePatternAutomaton.h | 55 +++++++- 5 files changed, 185 insertions(+), 178 deletions(-) diff --git a/aarbology2/src/aarbology.cpp b/aarbology2/src/aarbology.cpp index 58db9c350d..cb0daa0d30 100644 --- a/aarbology2/src/aarbology.cpp +++ b/aarbology2/src/aarbology.cpp @@ -229,8 +229,8 @@ int main ( int argc, char * argv[] ) { alib::XmlDataFactory::toStdout ( res ); } else if ( algorithm.getValue ( ) == "exactTreePatternAutomaton" ) { - tree::Tree subject = alib::XmlDataFactory::fromTokens ( std::move ( sax::FromXMLParserHelper::parseInput(true, subjectInput).front ( ) ) ); - DefaultSymbolType subtreeWildcard = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(subtreeWildcardInput) ); + tree::RankedTreeWrapper subject = alib::XmlDataFactory::fromTokens ( std::move ( sax::FromXMLParserHelper::parseInput(true, subjectInput).front ( ) ) ); + common::ranked_symbol < DefaultSymbolType, DefaultRankType > subtreeWildcard = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(subtreeWildcardInput) ); measurements::end ( ); measurements::start ( "Algorithm", measurements::Type::MAIN ); @@ -242,9 +242,9 @@ int main ( int argc, char * argv[] ) { alib::XmlDataFactory::toStdout ( res ); } else if ( algorithm.getValue ( ) == "exactNonlinearTreePatternAutomaton" ) { - tree::Tree subject = alib::XmlDataFactory::fromTokens ( std::move ( sax::FromXMLParserHelper::parseInput(true, subjectInput).front ( ) ) ); - DefaultSymbolType subtreeWildcard = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(subtreeWildcardInput) ); - ext::set < DefaultSymbolType > nonlinearVariables = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(nonlinearVariablesInput) ); + tree::RankedTreeWrapper subject = alib::XmlDataFactory::fromTokens ( std::move ( sax::FromXMLParserHelper::parseInput(true, subjectInput).front ( ) ) ); + common::ranked_symbol < DefaultSymbolType, DefaultRankType > subtreeWildcard = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(subtreeWildcardInput) ); + ext::set < common::ranked_symbol < DefaultSymbolType, DefaultRankType > > nonlinearVariables = alib::XmlDataFactory::fromTokens ( sax::FromXMLParserHelper::parseInput(nonlinearVariablesInput) ); measurements::end ( ); measurements::start ( "Algorithm", measurements::Type::MAIN ); diff --git a/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.cpp b/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.cpp index 1d5e295ed8..4430015eb4 100644 --- a/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.cpp @@ -6,130 +6,17 @@ */ #include "ExactNonlinearTreePatternAutomaton.h" -#include <tree/Tree.h> -#include <tree/ranked/PrefixRankedTree.h> -#include <automaton/Automaton.h> -#include <automaton/PDA/InputDrivenNPDA.h> - -#include <tree/properties/ExactSubtreeRepeatsNaive.h> - -#include <deque> -#include <alphabet/RankedSymbol.h> #include <registration/AlgoRegistration.hpp> namespace arbology { namespace exact { -automaton::Automaton ExactNonlinearTreePatternAutomaton::construct ( const tree::Tree & tree, const DefaultSymbolType & subtreeWildcard, const ext::set < DefaultSymbolType > & nonlinearVariables ) { +automaton::Automaton ExactNonlinearTreePatternAutomaton::construct ( const tree::RankedTreeWrapper & tree, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & subtreeWildcard, const ext::set < common::ranked_symbol < DefaultSymbolType, DefaultRankType > > & nonlinearVariables ) { return dispatch ( tree.getData ( ), subtreeWildcard, nonlinearVariables ); } -void ExactNonlinearTreePatternAutomaton::constructTail ( automaton::InputDrivenNPDA < > & res, const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const DefaultSymbolType & currentNonlinearVariable, const ext::set < DefaultSymbolType > & nonlinearVariables, unsigned subtreeId, ext::vector < common::ranked_symbol < > >::const_iterator rankedSymbolsIter, int i, ext::vector < common::ranked_symbol < unsigned, DefaultRankType > >::const_iterator subtreeRepeatsIter ) { - ext::deque < std::pair < size_t, int > > subtreeJumps; - ext::deque < unsigned > subtreeRepeatsStack; - - for (++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i; rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i ) { - DefaultSymbolType symbol ( alphabet::RankedSymbol < > { * rankedSymbolsIter } ); - subtreeJumps.push_back ( std::make_pair ( ( size_t ) rankedSymbolsIter->getRank ( ), i - 1 ) ); - subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) ); - - DefaultStateType currentState = DefaultStateType ( i, subtreeId ); - DefaultStateType previousState = DefaultStateType ( i - 1, subtreeId ); - - res.addState ( currentState ); - - res.addTransition ( previousState, symbol, currentState ); - - while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { - DefaultStateType jumpSource = DefaultStateType ( subtreeJumps.back ( ).second, subtreeId ); - res.addTransition ( jumpSource, subtreeWildcard, currentState ); - - for ( const DefaultSymbolType & nonlinearVariable : nonlinearVariables ) - if ( nonlinearVariable != currentNonlinearVariable || subtreeId == subtreeRepeatsStack.back ( ) ) - res.addTransition ( jumpSource, nonlinearVariable, currentState ); - - if ( subtreeJumps.size ( ) ) { - subtreeJumps.pop_back ( ); - subtreeRepeatsStack.pop_back ( ); - } - } - - if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; - } -} - -automaton::InputDrivenNPDA < > ExactNonlinearTreePatternAutomaton::constructInternal ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const DefaultSymbolType & currentNonlinearVariable, const ext::set < DefaultSymbolType > & nonlinearVariables ) { - DefaultSymbolType S = DefaultSymbolType ( 'S' ); - automaton::InputDrivenNPDA < > res ( DefaultStateType ( 0 ), S ); - - tree::PrefixRankedTree < unsigned, DefaultRankType > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( tree ); - - for ( const common::ranked_symbol < > & rankedSymbol : tree.getAlphabet ( ) ) { - DefaultSymbolType symbol ( alphabet::RankedSymbol < > { rankedSymbol } ); - res.addInputSymbol ( symbol ); - res.setPushdownStoreOperation ( symbol, ext::vector < DefaultSymbolType > ( 1, S ), ext::vector < DefaultSymbolType > ( ( size_t ) rankedSymbol.getRank ( ), S ) ); - } - - res.addInputSymbol ( subtreeWildcard ); - res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < DefaultSymbolType > ( 1, S ), ext::vector < DefaultSymbolType > { } ); - - for ( const DefaultSymbolType & nonlinearVariable : nonlinearVariables ) { - res.addInputSymbol ( nonlinearVariable ); - res.setPushdownStoreOperation ( nonlinearVariable, ext::vector < DefaultSymbolType > ( 1, S ), ext::vector < DefaultSymbolType > { } ); - } - - int i = 1; - ext::deque < std::pair < size_t, int > > subtreeJumps; - ext::deque < unsigned > subtreeRepeatsStack; - - ext::vector < common::ranked_symbol < > >::const_iterator rankedSymbolsIter; - ext::vector < common::ranked_symbol < unsigned, DefaultRankType > >::const_iterator subtreeRepeatsIter; - for ( rankedSymbolsIter = tree.getContent ( ).begin(), subtreeRepeatsIter = repeats.getContent ( ).begin ( ); rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++ i ) { - DefaultSymbolType symbol ( alphabet::RankedSymbol < > { * rankedSymbolsIter } ); - subtreeJumps.push_back ( std::make_pair ( ( size_t ) rankedSymbolsIter->getRank ( ), i - 1 ) ); - subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) ); - - DefaultStateType currentState = DefaultStateType ( i ); - DefaultStateType previousState = DefaultStateType ( i - 1 ); - - res.addState ( currentState ); - - res.addTransition ( previousState, symbol, currentState ); - res.addTransition ( res.getInitialState ( ), std::move ( symbol ), currentState ); - - while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { - DefaultStateType jumpSource = DefaultStateType ( subtreeJumps.back ( ).second ); - res.addTransition ( jumpSource, subtreeWildcard, currentState ); - - for ( const DefaultSymbolType & nonlinearVariable : nonlinearVariables ) - if ( nonlinearVariable != currentNonlinearVariable ) - res.addTransition ( jumpSource, nonlinearVariable, currentState ); - else { - unsigned subtreeId = subtreeRepeatsStack.back ( ); - DefaultStateType targetState = DefaultStateType ( i, subtreeId ); - - res.addState ( targetState ); - res.addTransition ( jumpSource, nonlinearVariable, targetState ); - - constructTail ( res, tree, subtreeWildcard, currentNonlinearVariable, nonlinearVariables, subtreeId, rankedSymbolsIter, i, subtreeRepeatsIter ); - } - - subtreeJumps.pop_back ( ); - subtreeRepeatsStack.pop_back ( ); - } - - if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; - } - - return res; -} - -automaton::InputDrivenNPDA < > ExactNonlinearTreePatternAutomaton::construct ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const ext::set < DefaultSymbolType > & nonlinearVariables ) { - return constructInternal ( tree, subtreeWildcard, * nonlinearVariables.begin ( ), nonlinearVariables ); -} - -auto ExactNonlinearTreePatternAutomatonPrefixRankedTree = registration::OverloadRegister < ExactNonlinearTreePatternAutomaton, automaton::InputDrivenNPDA < >, tree::PrefixRankedTree < > > ( ExactNonlinearTreePatternAutomaton::construct ); +auto ExactNonlinearTreePatternAutomatonPrefixRankedTree = registration::OverloadRegister < ExactNonlinearTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, ext::pair < unsigned, unsigned > >, tree::PrefixRankedTree < > > ( ExactNonlinearTreePatternAutomaton::construct ); } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.h b/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.h index 735a72e80f..92c81515d6 100644 --- a/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactNonlinearTreePatternAutomaton.h @@ -8,33 +8,152 @@ #ifndef _EXACT_NONLINEAR_TREE_PATTERN_AUTOMATON_H__ #define _EXACT_NONLINEAR_TREE_PATTERN_AUTOMATON_H__ -#include <automaton/AutomatonFeatures.h> -#include <tree/TreeFeatures.h> +#include <primitive/Unsigned.h> +#include <primitive/Character.h> +#include <container/ObjectsPair.h> + +#include <tree/RankedTreeWrapper.h> #include <core/multipleDispatch.hpp> #include <alphabet/Symbol.h> #include <alphabet/RankedSymbol.h> +#include <tree/ranked/PrefixRankedTree.h> +#include <automaton/Automaton.h> +#include <automaton/PDA/InputDrivenNPDA.h> + +#include <tree/properties/ExactSubtreeRepeatsNaive.h> + +#include <deque> #include <vector> namespace arbology { namespace exact { -class ExactNonlinearTreePatternAutomaton : public alib::SingleDispatch < ExactNonlinearTreePatternAutomaton, automaton::Automaton, const tree::TreeBase &, const DefaultSymbolType &, const ext::set < DefaultSymbolType > & > { - static automaton::InputDrivenNPDA < > constructInternal ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const DefaultSymbolType & currentNonlinearVariable, const ext::set < DefaultSymbolType > & nonlinearVariables ); +class ExactNonlinearTreePatternAutomaton : public alib::SingleDispatch < ExactNonlinearTreePatternAutomaton, automaton::Automaton, const tree::RankedTreeBase &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > &, const ext::set < common::ranked_symbol < DefaultSymbolType, DefaultRankType > > & > { + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > constructInternal ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables ); - static void constructTail ( automaton::InputDrivenNPDA < > & res, const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const DefaultSymbolType & currentNonlinearVariable, const ext::set < DefaultSymbolType > & nonlinearVariables, unsigned subtreeId, ext::vector < common::ranked_symbol < > >::const_iterator rankedSymbolsIter, int i, ext::vector < common::ranked_symbol < unsigned, DefaultRankType > >::const_iterator subtreeRepeatsIter ); + template < class SymbolType, class RankType > + static void constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables, unsigned subtreeId, typename ext::vector < common::ranked_symbol < SymbolType, RankType > >::const_iterator rankedSymbolsIter, int i, typename ext::vector < common::ranked_symbol < unsigned, RankType > >::const_iterator subtreeRepeatsIter ); public: /** * Performs conversion. * @return left regular grammar equivalent to source automaton. */ - static automaton::Automaton construct ( const tree::Tree & tree, const DefaultSymbolType & subtreeWildcard, const ext::set < DefaultSymbolType > & nonlinearVariables ); + static automaton::Automaton construct ( const tree::RankedTreeWrapper & tree, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & subtreeWildcard, const ext::set < common::ranked_symbol < DefaultSymbolType, DefaultRankType > > & nonlinearVariables ); - static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard, const ext::set < DefaultSymbolType > & nonlinearVariables ); + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables ); }; +template < class SymbolType, class RankType > +void ExactNonlinearTreePatternAutomaton::constructTail ( automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > & res, const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables, unsigned subtreeId, typename ext::vector < common::ranked_symbol < SymbolType, RankType > >::const_iterator rankedSymbolsIter, int i, typename ext::vector < common::ranked_symbol < unsigned, RankType > >::const_iterator subtreeRepeatsIter ) { + ext::deque < std::pair < size_t, int > > subtreeJumps; + ext::deque < unsigned > subtreeRepeatsStack; + + for (++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i; rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++i ) { + common::ranked_symbol < SymbolType, RankType > symbol = * rankedSymbolsIter; + subtreeJumps.push_back ( std::make_pair ( ( size_t ) symbol.getRank ( ), i - 1 ) ); + subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) ); + + ext::pair < unsigned, unsigned > currentState = ext::make_pair ( i, subtreeId + 1 ); + ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, subtreeId + 1 ); + + res.addState ( currentState ); + + res.addTransition ( previousState, std::move ( symbol ), currentState ); + + while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { + ext::pair < unsigned, unsigned > jumpSource = ext::make_pair ( subtreeJumps.back ( ).second, subtreeId + 1 ); + res.addTransition ( jumpSource, subtreeWildcard, currentState ); + + for ( const common::ranked_symbol < SymbolType, RankType > & nonlinearVariable : nonlinearVariables ) + if ( nonlinearVariable != currentNonlinearVariable || subtreeId == subtreeRepeatsStack.back ( ) ) + res.addTransition ( jumpSource, nonlinearVariable, currentState ); + + if ( subtreeJumps.size ( ) ) { + subtreeJumps.pop_back ( ); + subtreeRepeatsStack.pop_back ( ); + } + } + + if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; + } +} + +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > ExactNonlinearTreePatternAutomaton::constructInternal ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const common::ranked_symbol < SymbolType, RankType > & currentNonlinearVariable, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables ) { + char S = alphabet::SubtreeWildcardSymbol::instance < char > ( ); + automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > res ( ext::make_pair ( 0u, 0u ), S ); + + tree::PrefixRankedTree < unsigned, DefaultRankType > repeats = tree::properties::ExactSubtreeRepeatsNaive::repeats ( tree ); + + for ( const common::ranked_symbol < > & symbol : tree.getAlphabet ( ) ) { + res.addInputSymbol ( symbol ); + res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, S ), ext::vector < char > ( ( size_t ) symbol.getRank ( ), S ) ); + } + + res.addInputSymbol ( subtreeWildcard ); + res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > ( 1, S ), ext::vector < char > { } ); + + for ( const common::ranked_symbol < SymbolType, RankType > & nonlinearVariable : nonlinearVariables ) { + res.addInputSymbol ( nonlinearVariable ); + res.setPushdownStoreOperation ( nonlinearVariable, ext::vector < char > ( 1, S ), ext::vector < char > { } ); + } + + unsigned i = 1; + ext::deque < std::pair < size_t, int > > subtreeJumps; + ext::deque < unsigned > subtreeRepeatsStack; + + ext::vector < common::ranked_symbol < > >::const_iterator rankedSymbolsIter; + ext::vector < common::ranked_symbol < unsigned, DefaultRankType > >::const_iterator subtreeRepeatsIter; + for ( rankedSymbolsIter = tree.getContent ( ).begin(), subtreeRepeatsIter = repeats.getContent ( ).begin ( ); rankedSymbolsIter != tree.getContent ( ).end ( ); ++ rankedSymbolsIter, ++ subtreeRepeatsIter, ++ i ) { + common::ranked_symbol < SymbolType, RankType > symbol = * rankedSymbolsIter; + subtreeJumps.push_back ( std::make_pair ( ( size_t ) symbol.getRank ( ), i - 1 ) ); + subtreeRepeatsStack.push_back ( subtreeRepeatsIter->getSymbol ( ) ); + + ext::pair < unsigned, unsigned > currentState = ext::make_pair ( i, 0u ); + ext::pair < unsigned, unsigned > previousState = ext::make_pair ( i - 1, 0u ); + + res.addState ( currentState ); + + res.addTransition ( previousState, symbol, currentState ); + res.addTransition ( res.getInitialState ( ), std::move ( symbol ), currentState ); + + while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { + ext::pair < unsigned, unsigned > jumpSource = ext::make_pair ( subtreeJumps.back ( ).second, 0u ); + res.addTransition ( jumpSource, subtreeWildcard, currentState ); + + for ( const common::ranked_symbol < SymbolType, RankType > & nonlinearVariable : nonlinearVariables ) + if ( nonlinearVariable != currentNonlinearVariable ) + res.addTransition ( jumpSource, nonlinearVariable, currentState ); + else { + unsigned subtreeId = subtreeRepeatsStack.back ( ); + ext::pair < unsigned, unsigned > targetState = ext::make_pair ( i, subtreeId + 1 ); + + res.addState ( targetState ); + res.addTransition ( jumpSource, nonlinearVariable, targetState ); + + constructTail ( res, tree, subtreeWildcard, currentNonlinearVariable, nonlinearVariables, subtreeId, rankedSymbolsIter, i, subtreeRepeatsIter ); + } + + subtreeJumps.pop_back ( ); + subtreeRepeatsStack.pop_back ( ); + } + + if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; + } + + return res; +} + +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, ext::pair < unsigned, unsigned > > ExactNonlinearTreePatternAutomaton::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard, const ext::set < common::ranked_symbol < SymbolType, RankType > > & nonlinearVariables ) { + return constructInternal ( tree, subtreeWildcard, * nonlinearVariables.begin ( ), nonlinearVariables ); +} + } /* namespace exact */ } /* namespace arbology */ diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp index 0cf2e2d03c..cf84e4d631 100644 --- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.cpp @@ -6,61 +6,17 @@ */ #include "ExactTreePatternAutomaton.h" -#include <alphabet/SubtreeWildcardSymbol.h> -#include <tree/Tree.h> -#include <tree/ranked/PrefixRankedTree.h> -#include <automaton/Automaton.h> -#include <automaton/PDA/InputDrivenNPDA.h> - -#include <deque> #include <registration/AlgoRegistration.hpp> namespace arbology { namespace exact { -automaton::Automaton ExactTreePatternAutomaton::construct ( const tree::Tree & tree, const DefaultSymbolType & subtreeWildcard ) { +automaton::Automaton ExactTreePatternAutomaton::construct ( const tree::RankedTreeWrapper & tree, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & subtreeWildcard ) { return dispatch ( tree.getData ( ), subtreeWildcard ); } -automaton::InputDrivenNPDA < > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard ) { - DefaultSymbolType S = DefaultSymbolType ( 'S' ); - automaton::InputDrivenNPDA < > res ( DefaultStateType ( 0 ), S ); - - for ( const common::ranked_symbol < > & rankedSymbol : tree.getAlphabet ( ) ) { - DefaultSymbolType symbol ( alphabet::RankedSymbol < > { rankedSymbol } ); - res.addInputSymbol ( symbol ); - res.setPushdownStoreOperation ( symbol, ext::vector < DefaultSymbolType > ( 1, S ), ext::vector < DefaultSymbolType > ( ( size_t ) rankedSymbol.getRank ( ), S ) ); - } - - res.addInputSymbol ( subtreeWildcard ); - res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < DefaultSymbolType > ( 1, S ), ext::vector < DefaultSymbolType > { } ); - - int i = 1; - ext::deque < std::pair < size_t, int > > subtreeJumps; - - for ( const common::ranked_symbol < > & rankedSymbol : tree.getContent ( ) ) { - DefaultSymbolType symbol ( alphabet::RankedSymbol < > { rankedSymbol } ); - subtreeJumps.push_back ( std::make_pair ( ( size_t ) rankedSymbol.getRank ( ), i - 1 ) ); - - res.addState ( DefaultStateType ( i ) ); - res.addTransition ( DefaultStateType ( i - 1 ), symbol, DefaultStateType ( i ) ); - res.addTransition ( DefaultStateType ( 0 ), std::move ( symbol ), DefaultStateType ( i ) ); - - while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { - res.addTransition ( DefaultStateType ( subtreeJumps.back ( ).second ), subtreeWildcard, DefaultStateType ( i ) ); - subtreeJumps.pop_back ( ); - } - - if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; - - i++; - } - - return res; -} - -auto ExactTreePatternAutomatonPrefixRankedTree = registration::OverloadRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < >, tree::PrefixRankedTree < > > ( ExactTreePatternAutomaton::construct ); +auto ExactTreePatternAutomatonPrefixRankedTree = registration::OverloadRegister < ExactTreePatternAutomaton, automaton::InputDrivenNPDA < common::ranked_symbol < DefaultSymbolType, DefaultRankType >, char, unsigned >, tree::PrefixRankedTree < > > ( ExactTreePatternAutomaton::construct ); } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h index d0db79a74b..a0d413886b 100644 --- a/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactTreePatternAutomaton.h @@ -8,26 +8,71 @@ #ifndef _EXACT_TREE_PATTERN_AUTOMATON_H__ #define _EXACT_TREE_PATTERN_AUTOMATON_H__ -#include <automaton/AutomatonFeatures.h> -#include <tree/TreeFeatures.h> +#include <alphabet/SubtreeWildcardSymbol.h> +#include <tree/RankedTreeWrapper.h> +#include <tree/ranked/PrefixRankedTree.h> +#include <automaton/Automaton.h> +#include <automaton/PDA/InputDrivenNPDA.h> + +#include <deque> +#include <primitive/Character.h> +#include <primitive/Unsigned.h> + #include <core/multipleDispatch.hpp> namespace arbology { namespace exact { -class ExactTreePatternAutomaton : public alib::SingleDispatch < ExactTreePatternAutomaton, automaton::Automaton, const tree::TreeBase &, const DefaultSymbolType & > { +class ExactTreePatternAutomaton : public alib::SingleDispatch < ExactTreePatternAutomaton, automaton::Automaton, const tree::RankedTreeBase &, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & > { public: /** * Performs conversion. * @return left regular grammar equivalent to source automaton. */ - static automaton::Automaton construct ( const tree::Tree & tree, const DefaultSymbolType & subtreeWildcard ); + static automaton::Automaton construct ( const tree::RankedTreeWrapper & tree, const common::ranked_symbol < DefaultSymbolType, DefaultRankType > & subtreeWildcard ); - static automaton::InputDrivenNPDA < > construct ( const tree::PrefixRankedTree < > & tree, const DefaultSymbolType & subtreeWildcard ); + template < class SymbolType, class RankType > + static automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard ); }; +template < class SymbolType, class RankType > +automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > ExactTreePatternAutomaton::construct ( const tree::PrefixRankedTree < SymbolType, RankType > & tree, const common::ranked_symbol < SymbolType, RankType > & subtreeWildcard ) { + char S = alphabet::SubtreeWildcardSymbol::instance < char > ( ); + automaton::InputDrivenNPDA < common::ranked_symbol < SymbolType, RankType >, char, unsigned > res ( 0, S ); + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getAlphabet ( ) ) { + res.addInputSymbol ( symbol ); + res.setPushdownStoreOperation ( symbol, ext::vector < char > ( 1, S ), ext::vector < char > ( ( size_t ) symbol.getRank ( ), S ) ); + } + + res.addInputSymbol ( subtreeWildcard ); + res.setPushdownStoreOperation ( subtreeWildcard, ext::vector < char > ( 1, S ), ext::vector < char > { } ); + + unsigned i = 1; + ext::deque < std::pair < size_t, unsigned > > subtreeJumps; + + for ( const common::ranked_symbol < SymbolType, RankType > & symbol : tree.getContent ( ) ) { + subtreeJumps.push_back ( std::make_pair ( ( size_t ) symbol.getRank ( ), i - 1 ) ); + + res.addState ( i ); + res.addTransition ( i - 1, symbol, i ); + res.addTransition ( 0, std::move ( symbol ), i ); + + while ( subtreeJumps.size ( ) && subtreeJumps.back ( ).first == 0 ) { + res.addTransition ( subtreeJumps.back ( ).second, subtreeWildcard, i ); + subtreeJumps.pop_back ( ); + } + + if ( subtreeJumps.size ( ) ) subtreeJumps.back ( ).first--; + + i++; + } + + return res; +} + } /* namespace exact */ } /* namespace arbology */ -- GitLab