diff --git a/aarbology2/src/aarbology.cpp b/aarbology2/src/aarbology.cpp index 60460031e01c9076b3f7c8b65e740a3d01a06a7e..673a0a8d8e370702bd8847c3f2cc85dbc3b8dcb5 100644 --- a/aarbology2/src/aarbology.cpp +++ b/aarbology2/src/aarbology.cpp @@ -14,6 +14,7 @@ #include <container/Container.h> #include <arbology/exact/ExactSubtreeMatch.h> +#include <arbology/exact/ExactSubtreeMatchingAutomaton.h> int main(int argc, char* argv[]) { try { @@ -21,6 +22,7 @@ int main(int argc, char* argv[]) { std::vector<std::string> allowed; allowed.push_back("exactSubtreeMatch"); + allowed.push_back("exactSubtreeMatchingAutomaton"); TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", false, "exactSubtreeMatch", &allowedVals); @@ -38,6 +40,8 @@ int main(int argc, char* argv[]) { int needSubject = 0; if( algorithm.getValue() == "exactSubtreeMatch") { needPattern = needSubject = 1; + } else if( algorithm.getValue() == "exactSubtreeMatchingAutomaton") { + needPattern = 1; } else { } @@ -81,6 +85,11 @@ int main(int argc, char* argv[]) { std::set<unsigned> res = arbology::exact::ExactSubtreeMatch::match(subject, pattern); alib::XmlDataFactory::toStdout(res); return 0; + } else if( algorithm.getValue() == "exactSubtreeMatchingAutomaton") { + tree::Tree pattern = alib::XmlDataFactory::fromTokens<tree::Tree>(patternTokens.front()); + automaton::Automaton res = arbology::exact::ExactSubtreeMatchingAutomaton::construct(pattern); + alib::XmlDataFactory::toStdout(res); + return 0; } else { throw exception::AlibException( "Invalid algorithm" ); return 1; diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp index 38961e6c36b7d7cb015c85ffd84689a59d876858..71190dd71917acf9516a15d16d4e3cff07213f7d 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp @@ -8,6 +8,7 @@ #include "ExactSubtreeMatchingAutomaton.h" #include <exception/AlibException.h> #include <tree/ranked/PrefixRankedTree.h> +#include <tree/ranked/RankedTree.h> #include <deque> @@ -44,8 +45,29 @@ automaton::InputDrivenNPDA ExactSubtreeMatchingAutomaton::construct(const tree:: return res; } -void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::RankedTree&) const { - throw exception::AlibException("Unsupported tree type RankedTree"); +automaton::State constructRecursive(const tree::RankedNode & node, automaton::NFTA & res, int & nextState) { + std::vector<automaton::State> states; + states.reserve(node.getSymbol().getRank().getData()); + for(const auto & child : node.getChildren()) { + states.push_back(constructRecursive(*child, res, nextState)); + } + automaton::State state (nextState++); + res.addState(state); + res.addTransition(node.getSymbol(), states, state); + return state; +} + +automaton::NFTA ExactSubtreeMatchingAutomaton::construct(const tree::RankedTree & pattern) { + automaton::NFTA res; + res.setInputSymbols(pattern.getAlphabet()); + int nextState = 0; + res.addFinalState(constructRecursive(pattern.getRoot(), res, nextState)); + return res; +} + +void ExactSubtreeMatchingAutomaton::Visit(void* data, const tree::RankedTree& pattern) const { + automaton::Automaton* & out = *((automaton::Automaton**) data); + out = new automaton::Automaton(this->construct(pattern)); } void ExactSubtreeMatchingAutomaton::Visit(void* data, const tree::PrefixRankedTree& pattern) const { diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h index 3a0b4a1b7fe99bb24e6f548aa15793573b366f13..dbe3b1471e7d692ccd1283c93d1a36a426d3419e 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h @@ -10,6 +10,7 @@ #include <automaton/Automaton.h> #include <automaton/PDA/InputDrivenNPDA.h> +#include <automaton/TA/NFTA.h> #include <tree/Tree.h> namespace arbology { @@ -27,6 +28,7 @@ public: static automaton::Automaton construct(const tree::Tree& pattern); static automaton::InputDrivenNPDA construct(const tree::PrefixRankedTree& pattern); + static automaton::NFTA construct(const tree::RankedTree& pattern); private: void Visit(void*, const tree::RankedTree& pattern) const; void Visit(void*, const tree::RankedPattern& subject) const;