diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp index 7bca842067476eb0742fef06b93e67192e04fb67..f5b7c51880ef8d1c4b01f97ab51d31c0f3e97da1 100644 --- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.cpp @@ -6,9 +6,17 @@ */ #include "ExactPatternMatchingAutomaton.h" +#include "SubtreeJumpTable.h" + #include <exception/AlibException.h> #include <tree/ranked/RankedTree.h> #include <tree/ranked/RankedPattern.h> +#include <tree/ranked/PrefixRankedTree.h> +#include <tree/ranked/PrefixRankedPattern.h> + +#include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/PDA/NPDA.h> +#include <automaton/TA/NFTA.h> #include <deque> @@ -20,6 +28,97 @@ automaton::Automaton ExactPatternMatchingAutomaton::construct ( const tree::Rank return getInstance().dispatch(pattern.getData()); } +automaton::InputDrivenNPDA ExactPatternMatchingAutomaton::construct(const tree::PrefixRankedTree& pattern) { + automaton::InputDrivenNPDA res(automaton::State(0), alphabet::symbolFrom('S')); + + for(const alphabet::RankedSymbol& symbol : pattern.getAlphabet()) { + res.addInputSymbol(alphabet::Symbol{symbol}); + res.setPushdownStoreOperation(alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('S')}, std::vector<alphabet::Symbol>{symbol.getRank().getData(), alphabet::symbolFrom('S')}); + } + + for(const alphabet::RankedSymbol& symbol : pattern.getAlphabet()) { + res.addTransition(automaton::State(0), alphabet::Symbol{symbol}, automaton::State(0)); + } + int i = 1; + for(const alphabet::RankedSymbol& symbol : pattern.getContent()) { + res.addState(automaton::State(i)); + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, automaton::State(i)); + i++; + } + res.addFinalState(automaton::State(i-1)); + return res; +} + +auto ExactPatternMatchingAutomatonPrefixRankedTree = ExactPatternMatchingAutomaton::RegistratorWrapper<automaton::InputDrivenNPDA, tree::PrefixRankedTree>(ExactPatternMatchingAutomaton::getInstance(), ExactPatternMatchingAutomaton::construct); + +std::vector<alphabet::Symbol> computeRHS(const tree::PrefixRankedPattern& pattern, const std::vector<int>& patternSubtreeJumpTable, int i) { + const std::vector<alphabet::RankedSymbol>& content = pattern.getContent(); + + unsigned rank = content[i].getRank().getData(); + i++; + + std::vector<alphabet::Symbol> res; + for(unsigned ranki = 0; ranki < rank; ranki++) { + if(content[i] == pattern.getSubtreeWildcard()) { + res.push_back(alphabet::symbolFrom('R')); + i++; + } else { + res.push_back(alphabet::symbolFrom('T')); + + i = patternSubtreeJumpTable[i]; + } + } + + return res; +} + +automaton::NPDA ExactPatternMatchingAutomaton::construct(const tree::PrefixRankedPattern& pattern) { + automaton::NPDA res(automaton::State(0), alphabet::symbolFrom('T')); + for(const alphabet::RankedSymbol& symbol : pattern.getAlphabet()) { + res.addInputSymbol(alphabet::Symbol{symbol}); + } + res.setStackAlphabet({alphabet::symbolFrom('T'), alphabet::symbolFrom('R')}); + + for(const alphabet::RankedSymbol& symbol : pattern.getAlphabet()) { + if(symbol == pattern.getSubtreeWildcard()) continue; + + res.addTransition(automaton::State(0), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('T')}, automaton::State(0), std::vector<alphabet::Symbol>{symbol.getRank().getData(), alphabet::symbolFrom('T')}); + } + + std::vector < int > patternSubtreeJumpTable = SubtreeJumpTable::compute ( pattern ); + + int i = 1; + for(const alphabet::RankedSymbol& symbol : pattern.getContent()) { + res.addState(automaton::State(i)); + if(symbol == pattern.getSubtreeWildcard()) { + for(const alphabet::RankedSymbol& symbol : pattern.getAlphabet()) { + if(symbol == pattern.getSubtreeWildcard()) continue; + + if(symbol.getRank().getData() == 0) { + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('T')}, automaton::State(i-1), std::vector<alphabet::Symbol>{}); + + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('R')}, automaton::State(i), std::vector<alphabet::Symbol>{}); + } else { + std::vector<alphabet::Symbol> push{symbol.getRank().getData(), alphabet::symbolFrom('T')}; + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('T')}, automaton::State(i-1), push); + + push[symbol.getRank().getData() - 1] = alphabet::symbolFrom('R'); + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('R')}, automaton::State(i-1), push); + } + } + + } else { + res.addTransition(automaton::State(i-1), alphabet::Symbol{symbol}, std::vector<alphabet::Symbol>{1, alphabet::symbolFrom('T')}, automaton::State(i), computeRHS(pattern, patternSubtreeJumpTable, i-1)); + } + i++; + } + + res.addFinalState(automaton::State(i-1)); + return res; +} + +auto ExactPatternMatchingAutomatonPrefixRankedPattern = ExactPatternMatchingAutomaton::RegistratorWrapper<automaton::NPDA, tree::PrefixRankedPattern>(ExactPatternMatchingAutomaton::getInstance(), ExactPatternMatchingAutomaton::construct); + automaton::State constructRecursiveTree(const tree::RankedNode & node, automaton::NFTA & res, int & nextState) { std::vector<automaton::State> states; states.reserve(node.getSymbol().getRank().getData()); diff --git a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h index 13a841b4a60e32588439415a56256bd3e91ab6b6..bf365fe36ae2127f585c4bd4abe953e26d469af2 100644 --- a/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactPatternMatchingAutomaton.h @@ -9,8 +9,7 @@ #define _EXACT_PATTERN_MATCHING_AUTOMATON_H__ #include <automaton/Automaton.h> -#include <automaton/PDA/InputDrivenNPDA.h> -#include <automaton/TA/NFTA.h> +#include <automaton/AutomatonFeatures.h> #include <tree/RankedTreeWrapper.h> #include <tree/TreeFeatures.h> #include <common/multipleDispatch.hpp> @@ -29,6 +28,8 @@ public: */ static automaton::Automaton construct ( const tree::RankedTreeWrapper & pattern ); + static automaton::NPDA construct(const tree::PrefixRankedPattern& pattern); + static automaton::InputDrivenNPDA construct(const tree::PrefixRankedTree& pattern); static automaton::NFTA construct(const tree::RankedTree& pattern); static automaton::NFTA construct(const tree::RankedPattern& pattern); diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp index 1636071f7469f6fd1cb6c298243d4057496b2d11..736ca7509506f263cb8ac7cb2a5b3a498ad6dd4d 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp @@ -10,6 +10,9 @@ #include <tree/ranked/PrefixRankedTree.h> #include <tree/ranked/RankedTree.h> +#include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/TA/NFTA.h> + #include <deque> namespace arbology { diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h index 715e1f3cfb7da88111382292e68cbca9ea10e09b..3082f7f5e17ae54fb5b8738168cfe61c4595ef1c 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h @@ -9,8 +9,7 @@ #define _EXACT_SUBTREE_MATCHING_AUTOMATON_H__ #include <automaton/Automaton.h> -#include <automaton/PDA/InputDrivenNPDA.h> -#include <automaton/TA/NFTA.h> +#include <automaton/AutomatonFeatures.h> #include <tree/Tree.h> #include <tree/TreeFeatures.h> #include <common/multipleDispatch.hpp>