From e3ad22bfacfe674db9d7c3f93345e33e67c1181f Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 6 Dec 2016 09:24:13 +0100 Subject: [PATCH] template tree properties algorithms --- .../properties/ExactSubtreeRepeatsNaive.cpp | 93 ------------- .../properties/ExactSubtreeRepeatsNaive.h | 118 ++++++++++++++++- .../ReversedBadCharacterShiftTable.cpp | 112 ---------------- .../ReversedBadCharacterShiftTable.h | 125 +++++++++++++++++- 4 files changed, 233 insertions(+), 215 deletions(-) diff --git a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp index 9c14e08469..51ff2af299 100644 --- a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp +++ b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.cpp @@ -6,13 +6,6 @@ */ #include "ExactSubtreeRepeatsNaive.h" -#include "SubtreeJumpTable.h" - -#include <tree/ranked/RankedTree.h> -#include <tree/ranked/PrefixRankedTree.h> -#include <tree/ranked/PrefixRankedBarTree.h> -#include <tree/Tree.h> -#include <global/GlobalData.h> namespace tree { @@ -22,94 +15,8 @@ tree::Tree ExactSubtreeRepeatsNaive::repeats ( const tree::Tree & tree ) { return dispatch ( tree.getData ( ) ); } -std::tree < std::ranked_symbol < > > ExactSubtreeRepeatsNaive::repeats ( const std::tree < std::ranked_symbol < > > & node, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId ) { - std::vector < std::tree < std::ranked_symbol < > > > children; - std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( node.getData ( ), std::vector < std::ranked_symbol < > > ( ) ); - - for ( const std::tree < std::ranked_symbol < > > & child : node.getChildren() ) { - children.push_back ( repeats ( child, data, minId ) ); - childRepeatsKey.second.push_back ( children.back ( ).getData ( ) ); - } - - int & uniqueRepeatId = data[childRepeatsKey]; - - if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; - - return std::tree < std::ranked_symbol < > > ( std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), node.getData ( ).getRank ( ) ), std::move ( children ) ); -} - -tree::RankedTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::RankedTree < > & tree ) { - int minId = 1; - std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data; - - return tree::RankedTree < > ( repeats ( tree.getContent ( ), data, minId ) ); -} - auto ExactRepeatsNaiveRankedTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::RankedTree < >, tree::RankedTree < > > ( ExactSubtreeRepeatsNaive::repeats ); - -std::ranked_symbol < > ExactSubtreeRepeatsNaive::repeatsPrefixRanked ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ) { - int begin = index; - std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < > > ( ) ); - - res.push_back ( std::ranked_symbol < > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) ); - - index++; - - for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i ) - childRepeatsKey.second.push_back ( repeatsPrefixRanked ( symbols, res, data, minId, index ) ); - - int & uniqueRepeatId = data[childRepeatsKey]; - - if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; - - res[begin] = std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) ); - return res[begin]; -} - -tree::PrefixRankedTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedTree < > & tree ) { - int minId = 1; - int index = 0; - std::vector < std::ranked_symbol < > > res; - std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data; - - repeatsPrefixRanked ( tree.getContent ( ), res, data, minId, index ); - return tree::PrefixRankedTree < > ( res ); -} - auto ExactRepeatsNaivePrefixRankedTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::PrefixRankedTree < >, tree::PrefixRankedTree < > > ( ExactSubtreeRepeatsNaive::repeats ); - -std::ranked_symbol < > ExactSubtreeRepeatsNaive::repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ) { - int begin = index; - std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < > > ( ) ); - - res.push_back ( std::ranked_symbol < > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) ); - - index++; - - for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i ) - childRepeatsKey.second.push_back ( repeatsPrefixRankedBar ( symbols, res, data, minId, index ) ); - - int & uniqueRepeatId = data[childRepeatsKey]; - - if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; - - res[begin] = std::ranked_symbol < > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) ); - res.push_back ( symbols[index] ); - index++; - - return res[begin]; -} - -tree::PrefixRankedBarTree < > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedBarTree < > & tree ) { - int minId = 1; - int index = 0; - std::vector < std::ranked_symbol < > > res; - std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > data; - - repeatsPrefixRankedBar ( tree.getContent ( ), res, data, minId, index ); - return tree::PrefixRankedBarTree < > ( tree.getBars ( ), res ); -} - auto ExactRepeatsNaivePrefixRankedBarTree = ExactSubtreeRepeatsNaive::RegistratorWrapper < tree::PrefixRankedBarTree < >, tree::PrefixRankedBarTree < > > ( ExactSubtreeRepeatsNaive::repeats ); } /* namespace properties */ diff --git a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h index 2378926916..3f81f6e3da 100644 --- a/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h +++ b/alib2algo/src/tree/properties/ExactSubtreeRepeatsNaive.h @@ -17,6 +17,14 @@ #include <tree> #include <alphabet/RankedSymbol.h> +#include "SubtreeJumpTable.h" + +#include <tree/ranked/RankedTree.h> +#include <tree/ranked/PrefixRankedTree.h> +#include <tree/ranked/PrefixRankedBarTree.h> +#include <tree/Tree.h> +#include <global/GlobalData.h> + namespace tree { namespace properties { @@ -25,9 +33,14 @@ namespace properties { * Simple computation of subtree repeats */ class ExactSubtreeRepeatsNaive : public std::SingleDispatch < ExactSubtreeRepeatsNaive, tree::Tree, const tree::TreeBase & > { - static std::tree < std::ranked_symbol < > > repeats ( const std::tree < std::ranked_symbol < > > & node, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId ); - static std::ranked_symbol < > repeatsPrefixRanked ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ); - static std::ranked_symbol < > repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < > > & symbols, std::vector < std::ranked_symbol < > > & res, std::map < std::pair < std::ranked_symbol < >, std::vector < std::ranked_symbol < > > >, int > & data, int & minId, int & index ); + template < class SymbolType, class RankType > + static std::tree < std::ranked_symbol < SymbolType, RankType > > repeats ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId ); + + template < class SymbolType, class RankType > + static std::ranked_symbol < SymbolType, RankType > repeatsPrefixRanked ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ); + + template < class SymbolType, class RankType > + static std::ranked_symbol < SymbolType, RankType > repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ); public: /** @@ -40,12 +53,105 @@ public: * Compute a same shaped tree with nodes containing unique subtree ids. * @return Tree of repeats */ - static tree::RankedTree < > repeats ( const tree::RankedTree < > & tree ); - static tree::PrefixRankedTree < > repeats ( const tree::PrefixRankedTree < > & tree ); - static tree::PrefixRankedBarTree < > repeats ( const tree::PrefixRankedBarTree < > & tree ); + template < class SymbolType, class RankType > + static tree::RankedTree < SymbolType, RankType > repeats ( const tree::RankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class RankType > + static tree::PrefixRankedTree < SymbolType, RankType > repeats ( const tree::PrefixRankedTree < SymbolType, RankType > & tree ); + template < class SymbolType, class RankType > + static tree::PrefixRankedBarTree < SymbolType, RankType > repeats ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree ); }; +template < class SymbolType, class RankType > +std::tree < std::ranked_symbol < SymbolType, RankType > > ExactSubtreeRepeatsNaive::repeats ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & node, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId ) { + std::vector < std::tree < std::ranked_symbol < SymbolType, RankType > > > children; + std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( node.getData ( ), std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) ); + + for ( const std::tree < std::ranked_symbol < SymbolType, RankType > > & child : node.getChildren() ) { + children.push_back ( repeats ( child, data, minId ) ); + childRepeatsKey.second.push_back ( children.back ( ).getData ( ) ); + } + + int & uniqueRepeatId = data[childRepeatsKey]; + + if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; + + return std::tree < std::ranked_symbol < SymbolType, RankType > > ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), node.getData ( ).getRank ( ) ), std::move ( children ) ); +} + +template < class SymbolType, class RankType > +tree::RankedTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::RankedTree < SymbolType, RankType > & tree ) { + int minId = 1; + std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data; + + return tree::RankedTree < SymbolType, RankType > ( repeats ( tree.getContent ( ), data, minId ) ); +} + +template < class SymbolType, class RankType > +std::ranked_symbol < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeatsPrefixRanked ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ) { + int begin = index; + std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) ); + + res.push_back ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) ); + + index++; + + for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i ) + childRepeatsKey.second.push_back ( repeatsPrefixRanked ( symbols, res, data, minId, index ) ); + + int & uniqueRepeatId = data[childRepeatsKey]; + + if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; + + res[begin] = std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) ); + return res[begin]; +} + +template < class SymbolType, class RankType > +tree::PrefixRankedTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedTree < SymbolType, RankType > & tree ) { + int minId = 1; + int index = 0; + std::vector < std::ranked_symbol < SymbolType, RankType > > res; + std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data; + + repeatsPrefixRanked ( tree.getContent ( ), res, data, minId, index ); + return tree::PrefixRankedTree < SymbolType, RankType > ( res ); +} + +template < class SymbolType, class RankType > +std::ranked_symbol < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeatsPrefixRankedBar ( const std::vector < std::ranked_symbol < SymbolType, RankType > > & symbols, std::vector < std::ranked_symbol < SymbolType, RankType > > & res, std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > & data, int & minId, int & index ) { + int begin = index; + std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > > childRepeatsKey ( symbols[begin], std::vector < std::ranked_symbol < SymbolType, RankType > > ( ) ); + + res.push_back ( std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( 0 ), symbols[begin].getRank ( ) ) ); + + index++; + + for ( unsigned i = 0; i < ( unsigned ) symbols[begin].getRank ( ); ++i ) + childRepeatsKey.second.push_back ( repeatsPrefixRankedBar ( symbols, res, data, minId, index ) ); + + int & uniqueRepeatId = data[childRepeatsKey]; + + if ( uniqueRepeatId == 0 ) uniqueRepeatId = minId++; + + res[begin] = std::ranked_symbol < SymbolType, RankType > ( alphabet::symbolFrom ( uniqueRepeatId ), symbols[begin].getRank ( ) ); + res.push_back ( symbols[index] ); + index++; + + return res[begin]; +} + +template < class SymbolType, class RankType > +tree::PrefixRankedBarTree < SymbolType, RankType > ExactSubtreeRepeatsNaive::repeats ( const tree::PrefixRankedBarTree < SymbolType, RankType > & tree ) { + int minId = 1; + int index = 0; + std::vector < std::ranked_symbol < SymbolType, RankType > > res; + std::map < std::pair < std::ranked_symbol < SymbolType, RankType >, std::vector < std::ranked_symbol < SymbolType, RankType > > >, int > data; + + repeatsPrefixRankedBar ( tree.getContent ( ), res, data, minId, index ); + return tree::PrefixRankedBarTree < SymbolType, RankType > ( tree.getBars ( ), res ); +} + } /* namespace properties */ } /* namespace tree */ diff --git a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp index 25e5d2188e..dd9f293170 100644 --- a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp +++ b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.cpp @@ -7,11 +7,6 @@ #include "ReversedBadCharacterShiftTable.h" -#include <tree/ranked/PrefixRankedBarPattern.h> -#include <tree/ranked/PrefixRankedBarNonlinearPattern.h> -#include <tree/ranked/PrefixRankedPattern.h> -#include <tree/ranked/PrefixRankedNonlinearPattern.h> - namespace tree { namespace properties { @@ -20,116 +15,9 @@ std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs return dispatch ( pattern.getData ( ) ); } -std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < > & pattern ) { - return bcs ( tree::PrefixRankedBarNonlinearPattern < > ( pattern ) ); -} - auto ReversedBadCharacterShiftTablePrefixRankedBarPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedBarPattern < > > ( ReversedBadCharacterShiftTable::bcs ); - -std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < > & pattern ) { - const std::set < std::ranked_symbol < > > & alphabet = pattern.getAlphabet ( ); - - std::map < std::ranked_symbol < >, size_t > bcs; - - // initialisation of bcs table to the size of the pattern - for ( const std::ranked_symbol < > & symbol : alphabet ) { - if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue; - - bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) ); - } - - // find the distance between the beginning of the pattern and the index - // of the first symbol representing the variable's bar - unsigned firstSBarOffset = pattern.getContent ( ).size ( ) + 1; - - for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- ) - if ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) - firstSBarOffset = i; - - // limit the shift by occurrence of the last variable - - for ( const std::ranked_symbol < > & symbol : alphabet ) { - if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue; - - size_t tmp = firstSBarOffset; - - if ( pattern.getBars ( ).count ( symbol ) ) - // size of the smallest subtree containing given terminal depend - // on the arity of the terminal - tmp += ( size_t ) symbol.getRank ( ) * 2; - else if ( tmp >= 2 ) - // bar symbols match the variable bar which is one symbol after - // the last variable, conditioned because of the case S S| where - // the -1 would cause shift by 0 -- illegal - tmp -= 1; - - if ( bcs[symbol] > tmp ) - bcs[symbol] = tmp; - } - - // limit the shift by position of symbols within the pattern - for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned - if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue; - - size_t tmp = i; - - if ( bcs[pattern.getContent ( )[i]] > tmp ) - bcs[pattern.getContent ( )[i]] = tmp; - } - - return bcs; -} - auto ReversedBadCharacterShiftTablePrefixRankedBarNonlinearPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedBarNonlinearPattern < > > ( ReversedBadCharacterShiftTable::bcs ); - -std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedPattern < > & pattern ) { - return bcs ( tree::PrefixRankedNonlinearPattern < > ( pattern ) ); -} - auto ReversedBadCharacterShiftTablePrefixRankedPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedPattern < > > ( ReversedBadCharacterShiftTable::bcs ); - -std::map < std::ranked_symbol < >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < > & pattern ) { - const std::set < std::ranked_symbol < > > & alphabet = pattern.getAlphabet ( ); - - std::map < std::ranked_symbol < >, size_t > bcs; - - // initialisation of bcs table to the size of the pattern - for ( const std::ranked_symbol < > & symbol : alphabet ) { - if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue; - - bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) ); - } - - // find the distance between the beginning of the pattern and the index - // of the first symbol representing the variable's bar - unsigned firstSOffset = pattern.getContent ( ).size ( ) + 1; - - for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- ) - if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) - firstSOffset = i; - - if ( firstSOffset == 0 ) firstSOffset = 1; - - // limit the shift by occurrence of the last variable - for ( const std::ranked_symbol < > & symbol : alphabet ) { - if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue; - - if ( bcs[symbol] > firstSOffset ) - bcs[symbol] = firstSOffset; - } - - // limit the shift by position of symbols within the pattern - for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned - if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) continue; - size_t tmp = i; - - if ( bcs[pattern.getContent ( )[i]] > tmp ) - bcs[pattern.getContent ( )[i]] = tmp; - } - - return bcs; -} - auto ReversedBadCharacterShiftTablePrefixRankedNonlinearPattern = ReversedBadCharacterShiftTable::RegistratorWrapper < std::map < std::ranked_symbol < >, size_t >, tree::PrefixRankedNonlinearPattern < > > ( ReversedBadCharacterShiftTable::bcs ); } /* namespace properties */ diff --git a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h index 0eb08f2487..edfbab9a7e 100644 --- a/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h +++ b/alib2algo/src/tree/properties/ReversedBadCharacterShiftTable.h @@ -16,6 +16,11 @@ #include <set> #include <map> +#include <tree/ranked/PrefixRankedBarPattern.h> +#include <tree/ranked/PrefixRankedBarNonlinearPattern.h> +#include <tree/ranked/PrefixRankedPattern.h> +#include <tree/ranked/PrefixRankedNonlinearPattern.h> + namespace tree { namespace properties { @@ -32,13 +37,125 @@ public: */ static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::RankedTreeWrapper & pattern ); - static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedBarPattern < > & pattern ); - static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedBarNonlinearPattern < > & pattern ); - static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedPattern < > & pattern ); - static std::map < std::ranked_symbol < >, size_t > bcs ( const tree::PrefixRankedNonlinearPattern < > & pattern ); + template < class SymbolType, class RankType > + static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern ); + template < class SymbolType, class RankType > + static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > & pattern ); + template < class SymbolType, class RankType > + static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern ); + template < class SymbolType, class RankType > + static std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType, RankType > & pattern ); }; +template < class SymbolType, class RankType > +std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarPattern < SymbolType, RankType > & pattern ) { + return bcs ( tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > ( pattern ) ); +} + +template < class SymbolType, class RankType > +std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedBarNonlinearPattern < SymbolType, RankType > & pattern ) { + const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabet = pattern.getAlphabet ( ); + + std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs; + + // initialisation of bcs table to the size of the pattern + for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) { + if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue; + + bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) ); + } + + // find the distance between the beginning of the pattern and the index + // of the first symbol representing the variable's bar + unsigned firstSBarOffset = pattern.getContent ( ).size ( ) + 1; + + for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- ) + if ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) + firstSBarOffset = i; + + // limit the shift by occurrence of the last variable + + for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) { + if ( ( symbol == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( symbol ) ) || ( symbol == pattern.getVariablesBar ( ) ) ) continue; + + size_t tmp = firstSBarOffset; + + if ( pattern.getBars ( ).count ( symbol ) ) + // size of the smallest subtree containing given terminal depend + // on the arity of the terminal + tmp += ( size_t ) symbol.getRank ( ) * 2; + else if ( tmp >= 2 ) + // bar symbols match the variable bar which is one symbol after + // the last variable, conditioned because of the case S S| where + // the -1 would cause shift by 0 -- illegal + tmp -= 1; + + if ( bcs[symbol] > tmp ) + bcs[symbol] = tmp; + } + + // limit the shift by position of symbols within the pattern + for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned + if ( ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) ) || ( pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) || ( pattern.getContent ( )[i] == pattern.getVariablesBar ( ) ) ) continue; + + size_t tmp = i; + + if ( bcs[pattern.getContent ( )[i]] > tmp ) + bcs[pattern.getContent ( )[i]] = tmp; + } + + return bcs; +} + +template < class SymbolType, class RankType > +std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedPattern < SymbolType, RankType > & pattern ) { + return bcs ( tree::PrefixRankedNonlinearPattern < SymbolType, RankType > ( pattern ) ); +} + +template < class SymbolType, class RankType > +std::map < std::ranked_symbol < SymbolType, RankType >, size_t > ReversedBadCharacterShiftTable::bcs ( const tree::PrefixRankedNonlinearPattern < SymbolType, RankType > & pattern ) { + const std::set < std::ranked_symbol < SymbolType, RankType > > & alphabet = pattern.getAlphabet ( ); + + std::map < std::ranked_symbol < SymbolType, RankType >, size_t > bcs; + + // initialisation of bcs table to the size of the pattern + for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) { + if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue; + + bcs.insert ( std::make_pair ( symbol, pattern.getContent ( ).size ( ) ) ); + } + + // find the distance between the beginning of the pattern and the index + // of the first symbol representing the variable's bar + unsigned firstSOffset = pattern.getContent ( ).size ( ) + 1; + + for ( int i = ( int ) pattern.getContent ( ).size ( ) - 1; i >= 0; i-- ) + if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) + firstSOffset = i; + + if ( firstSOffset == 0 ) firstSOffset = 1; + + // limit the shift by occurrence of the last variable + for ( const std::ranked_symbol < SymbolType, RankType > & symbol : alphabet ) { + if ( symbol == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( symbol ) ) continue; + + if ( bcs[symbol] > firstSOffset ) + bcs[symbol] = firstSOffset; + } + + // limit the shift by position of symbols within the pattern + for ( unsigned i = pattern.getContent ( ).size ( ) - 1; i >= 1; i-- ) { // first symbol is not concerned + if ( pattern.getContent ( )[i] == pattern.getSubtreeWildcard ( ) || pattern.getNonlinearVariables ( ).count ( pattern.getContent ( )[i] ) ) continue; + size_t tmp = i; + + if ( bcs[pattern.getContent ( )[i]] > tmp ) + bcs[pattern.getContent ( )[i]] = tmp; + } + + return bcs; +} + } /* namespace properties */ } /* namespace tree */ -- GitLab