diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0870594266feabc8d9f09b0c8438beb7d1224e26 --- /dev/null +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp @@ -0,0 +1,88 @@ +/* + * ExactSubtreeMatch.cpp + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#include "ExactSubtreeMatch.h" +#include <exception/AlibException.h> +#include <tree/ranked/RankedTree.h> +#include <tree/unranked/UnrankedTree.h> + +#include <deque> +#include <foreach> + +namespace arbology { + +namespace exact { + +std::set<unsigned> ExactSubtreeMatch::match(const tree::Tree& subject, const tree::Tree& pattern) { + std::set<unsigned> data; + Accept((void*) &data, subject.getData(), pattern.getData(), ExactSubtreeMatch::EXACT_SUBTREE_MATCH); + return data; +} + +bool ExactSubtreeMatch::matchHelper(const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern) { + if(subject.getSymbol() != pattern.getSymbol()) return false; + if(subject.getChildren().size() != pattern.getChildren().size()) return false; + for(const std::tuple<const tree::UnrankedNode*, const tree::UnrankedNode*>& childs : std::make_pair_foreach(subject.getChildren(), pattern.getChildren())) { + if(!matchHelper(*std::get<0>(childs), *std::get<1>(childs))) return false; + } + return true; +} + +bool ExactSubtreeMatch::matchHelper(const tree::RankedNode& subject, const tree::RankedNode& pattern) { + if(subject.getSymbol() != pattern.getSymbol()) return false; + // ranked symbols are the same test for number of children is not needed + for(const std::tuple<const tree::RankedNode*, const tree::RankedNode*>& childs : std::make_pair_foreach(subject.getChildren(), pattern.getChildren())) { + if(!matchHelper(*std::get<0>(childs), *std::get<1>(childs))) return false; + } + return true; +} + +void ExactSubtreeMatch::matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern) { + if(matchHelper(subject, pattern)) occ.insert(index); + index++; + for(const tree::UnrankedNode* child : subject.getChildren()) { + matchInternal(index, occ, *child, pattern); + } +} + +void ExactSubtreeMatch::matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::RankedNode& subject, const tree::RankedNode& pattern) { + if(matchHelper(subject, pattern)) occ.insert(index); + index++; + for(const tree::RankedNode* child : subject.getChildren()) { + matchInternal(index, occ, *child, pattern); + } +} + +std::set<unsigned> ExactSubtreeMatch::match(const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) { + unsigned i = 0; + std::set<unsigned> occ; + matchInternal(i, occ, subject.getRoot(), pattern.getRoot()); + return occ; +} + +std::set<unsigned> ExactSubtreeMatch::match(const tree::RankedTree& subject, const tree::RankedTree& pattern) { + unsigned i = 0; + std::set<unsigned> occ; + matchInternal(i, occ, subject.getRoot(), pattern.getRoot()); + return occ; +} + +void ExactSubtreeMatch::Visit(void* data, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const { + std::set<unsigned> & res = *((std::set<unsigned>*) data); + res = this->match(subject, pattern); +} + +void ExactSubtreeMatch::Visit(void* data, const tree::RankedTree& subject, const tree::RankedTree& pattern) const { + std::set<unsigned> & res = *((std::set<unsigned>*) data); + res = this->match(subject, pattern); +} + +const ExactSubtreeMatch ExactSubtreeMatch::EXACT_SUBTREE_MATCH; + +} /* namespace exact */ + +} /* namespace arbology */ diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h new file mode 100644 index 0000000000000000000000000000000000000000..bbfd582ee809257bd133a2a7f02dca778ff7e008 --- /dev/null +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h @@ -0,0 +1,50 @@ +/* + * ExactSubtreeMatch.h + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#ifndef _EXACT_SUBTREE_MATCH_H_ +#define _EXACT_SUBTREE_MATCH_H_ + +#include <tree/Tree.h> +#include <tree/ranked/RankedTree.h> +#include <tree/unranked/UnrankedTree.h> + +#include <set> + +namespace arbology { + +namespace exact { + +class ExactSubtreeMatch : public tree::VisitableTreeBase::const_promoting_visitor_type { +public: + ExactSubtreeMatch() {} + + /** + * Performs conversion. + * @return left regular grammar equivalent to source automaton. + */ + static std::set<unsigned> match(const tree::Tree& subject, const tree::Tree& pattern); + + static std::set<unsigned> match(const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern); + static std::set<unsigned> match(const tree::RankedTree& subject, const tree::RankedTree& pattern); +private: + static bool matchHelper(const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern); + static bool matchHelper(const tree::RankedNode& subject, const tree::RankedNode& pattern); + + static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::UnrankedNode& subject, const tree::UnrankedNode& pattern); + static void matchInternal(unsigned& index, std::set<unsigned>& occ, const tree::RankedNode& subject, const tree::RankedNode& pattern); + + void Visit(void*, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const; + void Visit(void*, const tree::RankedTree& subject, const tree::RankedTree& pattern) const; + + static const ExactSubtreeMatch EXACT_SUBTREE_MATCH; +}; + +} /* namespace exact */ + +} /* namespace arbology */ + +#endif /* _EXACT_SUBTREE_MATCH_H_ */ diff --git a/alib2algo/src/stringology/exact/ExactMatch.cpp b/alib2algo/src/stringology/exact/ExactFactorMatch.cpp similarity index 57% rename from alib2algo/src/stringology/exact/ExactMatch.cpp rename to alib2algo/src/stringology/exact/ExactFactorMatch.cpp index b68b7e1df56e8772440c32dee7a58cb6732a50c7..fe388a234ba7f2c4f6243972497ceedec7ccf5d6 100644 --- a/alib2algo/src/stringology/exact/ExactMatch.cpp +++ b/alib2algo/src/stringology/exact/ExactFactorMatch.cpp @@ -1,11 +1,11 @@ /* - * ExactMatch.cpp + * ExactFactorMatch.cpp * * Created on: 9. 2. 2014 * Author: Jan Travnicek */ -#include "ExactMatch.h" +#include "ExactFactorMatch.h" #include <exception/AlibException.h> #include <string/LinearString.h> @@ -15,13 +15,13 @@ namespace stringology { namespace exact { -std::set<unsigned> ExactMatch::match(const string::String& subject, const string::String& pattern) { +std::set<unsigned> ExactFactorMatch::match(const string::String& subject, const string::String& pattern) { std::set<unsigned> data; - Accept((void*) &data, subject.getData(), pattern.getData(), ExactMatch::EXACT_MATCH); + Accept((void*) &data, subject.getData(), pattern.getData(), ExactFactorMatch::EXACT_FACTOR_MATCH); return data; } -std::set<unsigned> ExactMatch::match(const string::LinearString& subject, const string::LinearString& pattern) { +std::set<unsigned> ExactFactorMatch::match(const string::LinearString& subject, const string::LinearString& pattern) { std::set<unsigned> occ; for(unsigned i = 0; i <= subject.getContent().size() - pattern.getContent().size(); i++) { unsigned j = 0; @@ -35,20 +35,20 @@ std::set<unsigned> ExactMatch::match(const string::LinearString& subject, const return occ; } -void ExactMatch::Visit(void*, const string::Epsilon&, const string::Epsilon&) const { +void ExactFactorMatch::Visit(void*, const string::Epsilon&, const string::Epsilon&) const { throw exception::AlibException("Unsupported string type Epsilon"); } -void ExactMatch::Visit(void* data, const string::LinearString& subject, const string::LinearString& pattern) const { +void ExactFactorMatch::Visit(void* data, const string::LinearString& subject, const string::LinearString& pattern) const { std::set<unsigned> & res = *((std::set<unsigned>*) data); res = this->match(subject, pattern); } -void ExactMatch::Visit(void*, const string::CyclicString&, const string::CyclicString&) const { +void ExactFactorMatch::Visit(void*, const string::CyclicString&, const string::CyclicString&) const { throw exception::AlibException("Unsupported string type CyclicString"); } -const ExactMatch ExactMatch::EXACT_MATCH; +const ExactFactorMatch ExactFactorMatch::EXACT_FACTOR_MATCH; } /* namespace exact */ diff --git a/alib2algo/src/stringology/exact/ExactMatch.h b/alib2algo/src/stringology/exact/ExactFactorMatch.h similarity index 82% rename from alib2algo/src/stringology/exact/ExactMatch.h rename to alib2algo/src/stringology/exact/ExactFactorMatch.h index faf97daecccfbc9f7d07a92035ef47e5832d6c3b..df9f5a12982323db87c97b2cdfd3ccf58f8d76b4 100644 --- a/alib2algo/src/stringology/exact/ExactMatch.h +++ b/alib2algo/src/stringology/exact/ExactFactorMatch.h @@ -1,5 +1,5 @@ /* - * ExactMatch.h + * ExactFactorMatch.h * * Created on: 9. 2. 2014 * Author: Jan Travnicek @@ -14,9 +14,9 @@ namespace stringology { namespace exact { -class ExactMatch : public string::VisitableStringBase::const_promoting_visitor_type { +class ExactFactorMatch : public string::VisitableStringBase::const_promoting_visitor_type { public: - ExactMatch() {} + ExactFactorMatch() {} /** * Performs conversion. @@ -30,7 +30,7 @@ private: void Visit(void*, const string::LinearString& subject, const string::LinearString& pattern) const; void Visit(void*, const string::CyclicString& subject, const string::CyclicString& pattern) const; - static const ExactMatch EXACT_MATCH; + static const ExactFactorMatch EXACT_FACTOR_MATCH; }; } /* namespace exact */ diff --git a/astringology2/src/astringology.cpp b/astringology2/src/astringology.cpp index c87d86ecbb201e8f5cf79190a3742a020dc0eb65..fee3b130ed7c3830cd6d2cde21aa9e151859ffe8 100644 --- a/astringology2/src/astringology.cpp +++ b/astringology2/src/astringology.cpp @@ -14,7 +14,7 @@ #include <automaton/Automaton.h> #include <container/Container.h> -#include <stringology/exact/ExactMatch.h> +#include <stringology/exact/ExactFactorMatch.h> #include <stringology/exact/BoyerMooreHorspool.h> #include <stringology/exact/ExactMatchingAutomaton.h> #include <stringology/exact/ExactFactorAutomaton.h> @@ -33,12 +33,12 @@ int main(int argc, char* argv[]) { allowed.push_back("exactSubsequenceAutomaton"); allowed.push_back("exactNondeterministicSubsequenceAutomaton"); allowed.push_back("exactMultiNondeterministicSubsequenceAutomaton"); - allowed.push_back("exactMatch"); + allowed.push_back("exactFactorMatch"); allowed.push_back("boyerMooreHorspool"); allowed.push_back("borderArray"); TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); - TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", false, "exactMatch", &allowedVals); + TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", false, "exactFactorMatch", &allowedVals); cmd.add(algorithm); TCLAP::MultiArg<std::string> subject( "s", "subject", "Subject string from file", false, "file"); @@ -51,7 +51,7 @@ int main(int argc, char* argv[]) { int needPattern = 0; int needSubject = 0; - if( algorithm.getValue() == "exactMatch") { + if( algorithm.getValue() == "exactFactorMatch") { needPattern = needSubject = 1; } else if( algorithm.getValue() == "boyerMooreHorspool") { needPattern = needSubject = 1; @@ -104,10 +104,10 @@ int main(int argc, char* argv[]) { patternTokens.emplace_back(std::move(tmp)); } - if( algorithm.getValue() == "exactMatch") { + if( algorithm.getValue() == "exactFactorMatch") { string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); string::String pattern = alib::XmlDataFactory::fromTokens<string::String>(patternTokens.front()); - std::set<unsigned> res = stringology::exact::ExactMatch::match(subject, pattern); + std::set<unsigned> res = stringology::exact::ExactFactorMatch::match(subject, pattern); alib::XmlDataFactory::toStdout(res); return 0; } else if( algorithm.getValue() == "boyerMooreHorspool") { diff --git a/tests.astringology.sh b/tests.astringology.sh index 57b62962fa9007ba15ffe380d98213de82b972ea..6c76981108b111169b64ee07e1aa07946a019bb2 100755 --- a/tests.astringology.sh +++ b/tests.astringology.sh @@ -134,7 +134,7 @@ function runTest { for SUBJECT_FILE in `ls $TESTS_DIR/astringology.test*.subject.xml`; do PATTERN_FILE=${SUBJECT_FILE%.subject.xml}.pattern.xml if [ -f ]; then - Occs=`./astringology2 -a exactMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s` + Occs=`./astringology2 -a exactFactorMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s` runTest2 "$Occs" "$2" "$SUBJECT_FILE" "$PATTERN_FILE" registerResult $? @@ -151,7 +151,7 @@ function runTest { cat <(generateSubject) > $SUBJECT_FILE cat <(generatePattern) > $PATTERN_FILE - Occs=`./astringology2 -a exactMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s` + Occs=`./astringology2 -a exactFactorMatch -s "$SUBJECT_FILE" -p "$PATTERN_FILE" | ./astat2 -p quantity -s` runTest2 "$Occs" "$2" "$SUBJECT_FILE" "$PATTERN_FILE" registerResult $?