From 069b2df9b9a54bee5161b68d15794affcee8917f Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Thu, 7 Apr 2016 17:18:24 +0200 Subject: [PATCH] naive nonlinear tree pattern matching --- .../src/arbology/exact/ExactPatternMatch.cpp | 57 +++++++++++++++++-- .../src/arbology/exact/ExactPatternMatch.h | 4 ++ .../src/arbology/exact/ExactSubtreeMatch.cpp | 4 +- alib2data/src/tree/TreeFeatures.h | 2 + 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/alib2algo/src/arbology/exact/ExactPatternMatch.cpp b/alib2algo/src/arbology/exact/ExactPatternMatch.cpp index 2d49e42933..5b5b0a7d40 100644 --- a/alib2algo/src/arbology/exact/ExactPatternMatch.cpp +++ b/alib2algo/src/arbology/exact/ExactPatternMatch.cpp @@ -9,6 +9,7 @@ #include <exception/AlibException.h> #include <tree/ranked/RankedTree.h> #include <tree/ranked/RankedPattern.h> +#include <tree/ranked/RankedNonlinearPattern.h> #include <tree/ranked/PrefixRankedTree.h> #include <tree/ranked/PrefixRankedPattern.h> #include <tree/ranked/PrefixRankedBarTree.h> @@ -16,6 +17,7 @@ #include <tree/unranked/UnrankedTree.h> #include <tree/unranked/UnrankedPattern.h> #include "SubtreeJumpTable.h" +#include "ExactSubtreeRepeatsNaive.h" #include <deque> #include <foreach> @@ -35,7 +37,7 @@ bool ExactPatternMatch::matchHelper ( const tree::UnrankedNode & subject, const 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 ( ) ) ) + for ( const std::tuple < const tree::UnrankedNode *, const tree::UnrankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), pattern.getChildren ( ) ) ) if ( !matchHelper ( * std::get < 0 > ( childs ), * std::get < 1 > ( childs ), subtreeVariable ) ) return false; return true; @@ -47,12 +49,32 @@ bool ExactPatternMatch::matchHelper ( const tree::RankedNode & subject, const tr 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 ( ) ) ) + for ( const std::tuple < const tree::RankedNode *, const tree::RankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), pattern.getChildren ( ) ) ) if ( !matchHelper ( * std::get < 0 > ( childs ), * std::get < 1 > ( childs ), subtreeVariable ) ) return false; return true; } +bool ExactPatternMatch::matchHelper ( const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable, const std::set < alphabet::RankedSymbol > & nonlinearVariables, const tree::RankedNode & repeats, std::map < alphabet::RankedSymbol, alphabet::Symbol > & variablesSetting ) { + if ( pattern.getSymbol ( ) == subtreeVariable ) return true; + + if ( nonlinearVariables.count ( pattern.getSymbol ( ) ) ) { + auto setting = variablesSetting.find ( pattern.getSymbol ( ) ); + + if ( ( setting != variablesSetting.end ( ) ) && ( repeats.getSymbol ( ).getSymbol ( ) != setting->second ) ) return false; + + if ( setting == variablesSetting.end ( ) ) variablesSetting.insert ( std::make_pair ( pattern.getSymbol ( ), repeats.getSymbol ( ).getSymbol ( ) ) ); + } + + 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 *, const tree::RankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), pattern.getChildren ( ), repeats.getChildren ( ) ) ) + if ( !matchHelper ( * std::get < 0 > ( childs ), * std::get < 1 > ( childs ), subtreeVariable, nonlinearVariables, * std::get < 2 > ( childs ), variablesSetting ) ) return false; + + return true; +} + void ExactPatternMatch::matchInternal ( unsigned & index, std::set < unsigned > & occ, const tree::UnrankedNode & subject, const tree::UnrankedNode & pattern, const alphabet::Symbol & subtreeVariable ) { if ( matchHelper ( subject, pattern, subtreeVariable ) ) occ.insert ( index ); @@ -71,6 +93,17 @@ void ExactPatternMatch::matchInternal ( unsigned & index, std::set < unsigned > matchInternal ( index, occ, * child, pattern, subtreeVariable ); } +void ExactPatternMatch::matchInternal ( unsigned & index, std::set < unsigned > & occ, const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable, const std::set < alphabet::RankedSymbol > & nonlinearVariables, const tree::RankedNode & repeats ) { + std::map < alphabet::RankedSymbol, alphabet::Symbol > variablesSetting; + + if ( matchHelper ( subject, pattern, subtreeVariable, nonlinearVariables, repeats, variablesSetting ) ) occ.insert ( index ); + + index++; + + for ( const std::tuple < const tree::RankedNode *, const tree::RankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), repeats.getChildren ( ) ) ) + matchInternal ( index, occ, * std::get < 0 > ( childs ), pattern, subtreeVariable, nonlinearVariables, * std::get < 1 > ( childs ) ); +} + std::set < unsigned > ExactPatternMatch::match ( const tree::UnrankedTree & subject, const tree::UnrankedPattern & pattern ) { unsigned i = 0; std::set < unsigned > occ; @@ -79,7 +112,7 @@ std::set < unsigned > ExactPatternMatch::match ( const tree::UnrankedTree & subj return occ; } -auto ExactPatternMatchUnrankedTree = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::UnrankedTree, tree::UnrankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); +auto ExactPatternMatchUnrankedPattern = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::UnrankedTree, tree::UnrankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); std::set < unsigned > ExactPatternMatch::match ( const tree::RankedTree & subject, const tree::RankedPattern & pattern ) { unsigned i = 0; @@ -89,7 +122,19 @@ std::set < unsigned > ExactPatternMatch::match ( const tree::RankedTree & subjec return occ; } -auto ExactPatternMatchRankedTree = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::RankedTree, tree::RankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); +auto ExactPatternMatchRankedPattern = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::RankedTree, tree::RankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); + +std::set < unsigned > ExactPatternMatch::match ( const tree::RankedTree & subject, const tree::RankedNonlinearPattern & pattern ) { + unsigned i = 0; + std::set < unsigned > occ; + + tree::RankedTree repeats = ExactSubtreeRepeatsNaive::repeats ( subject ); + + matchInternal ( i, occ, subject.getRoot ( ), pattern.getRoot ( ), pattern.getSubtreeWildcard ( ), pattern.getNonlinearVariables ( ), repeats.getRoot ( ) ); + return occ; +} + +auto ExactPatternMatchRankedNonlinearPattern = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::RankedTree, tree::RankedNonlinearPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); std::set < unsigned > ExactPatternMatch::match ( const tree::PrefixRankedTree & subject, const tree::PrefixRankedPattern & pattern ) { std::vector < int > subjectSubtreeJumpTable = SubtreeJumpTable::compute ( subject ); @@ -116,7 +161,7 @@ std::set < unsigned > ExactPatternMatch::match ( const tree::PrefixRankedTree & return occ; } -auto ExactPatternMatchPrefixRankedTree = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::PrefixRankedTree, tree::PrefixRankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); +auto ExactPatternMatchPrefixRankedPattern = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::PrefixRankedTree, tree::PrefixRankedPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); std::set < unsigned > ExactPatternMatch::match ( const tree::PrefixRankedBarTree & subject, const tree::PrefixRankedBarPattern & pattern ) { std::vector < int > subjectSubtreeJumpTable = SubtreeJumpTable::compute ( subject ); @@ -145,7 +190,7 @@ std::set < unsigned > ExactPatternMatch::match ( const tree::PrefixRankedBarTree return occ; } -auto ExactPatternMatchPrefixRankedBarTree = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::PrefixRankedBarTree, tree::PrefixRankedBarPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); +auto ExactPatternMatchPrefixRankedBarPattern = ExactPatternMatch::RegistratorWrapper < std::set < unsigned >, tree::PrefixRankedBarTree, tree::PrefixRankedBarPattern > ( ExactPatternMatch::getInstance ( ), ExactPatternMatch::match ); } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactPatternMatch.h b/alib2algo/src/arbology/exact/ExactPatternMatch.h index 4caec9421d..1bcc858438 100644 --- a/alib2algo/src/arbology/exact/ExactPatternMatch.h +++ b/alib2algo/src/arbology/exact/ExactPatternMatch.h @@ -14,6 +14,7 @@ #include <tree/unranked/UnrankedNode.h> #include <set> #include <core/multipleDispatch.hpp> +#include <alphabet/RankedSymbol.h> namespace arbology { @@ -29,15 +30,18 @@ public: static std::set < unsigned > match ( const tree::UnrankedTree & subject, const tree::UnrankedPattern & pattern ); static std::set < unsigned > match ( const tree::RankedTree & subject, const tree::RankedPattern & pattern ); + static std::set < unsigned > match ( const tree::RankedTree & subject, const tree::RankedNonlinearPattern & pattern ); static std::set < unsigned > match ( const tree::PrefixRankedTree & subject, const tree::PrefixRankedPattern & pattern ); static std::set < unsigned > match ( const tree::PrefixRankedBarTree & subject, const tree::PrefixRankedBarPattern & pattern ); private: static bool matchHelper ( const tree::UnrankedNode & subject, const tree::UnrankedNode & pattern, const alphabet::Symbol & subtreeVariable ); static bool matchHelper ( const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable ); + static bool matchHelper ( const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable, const std::set < alphabet::RankedSymbol > & nonlinearVariables, const tree::RankedNode & repeats, std::map < alphabet::RankedSymbol, alphabet::Symbol > & variablesSetting ); static void matchInternal ( unsigned & index, std::set < unsigned > & occ, const tree::UnrankedNode & subject, const tree::UnrankedNode & pattern, const alphabet::Symbol & subtreeVariable ); static void matchInternal ( unsigned & index, std::set < unsigned > & occ, const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable ); + static void matchInternal ( unsigned & index, std::set < unsigned > & occ, const tree::RankedNode & subject, const tree::RankedNode & pattern, const alphabet::RankedSymbol & subtreeVariable, const std::set < alphabet::RankedSymbol > & nonlinearVariables, const tree::RankedNode & subjectRepeats ); public: static ExactPatternMatch & getInstance ( ) { diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp index fd29de4a55..25768ec1b2 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp @@ -28,7 +28,7 @@ bool ExactSubtreeMatch::matchHelper ( const tree::UnrankedNode & subject, const 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 ( ) ) ) + for ( const std::tuple < const tree::UnrankedNode *, const tree::UnrankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), pattern.getChildren ( ) ) ) if ( !matchHelper ( * std::get < 0 > ( childs ), * std::get < 1 > ( childs ) ) ) return false; return true; @@ -38,7 +38,7 @@ bool ExactSubtreeMatch::matchHelper ( const tree::RankedNode & subject, const tr 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 ( ) ) ) + for ( const std::tuple < const tree::RankedNode *, const tree::RankedNode * > & childs : std::make_tuple_foreach ( subject.getChildren ( ), pattern.getChildren ( ) ) ) if ( !matchHelper ( * std::get < 0 > ( childs ), * std::get < 1 > ( childs ) ) ) return false; return true; diff --git a/alib2data/src/tree/TreeFeatures.h b/alib2data/src/tree/TreeFeatures.h index 60737ab718..4d8bd71280 100644 --- a/alib2data/src/tree/TreeFeatures.h +++ b/alib2data/src/tree/TreeFeatures.h @@ -28,12 +28,14 @@ class TreeBase; class RankedTree; class RankedPattern; +class RankedNonlinearPattern; class PrefixRankedTree; class PrefixRankedBarTree; class PrefixRankedPattern; class PrefixRankedBarPattern; class UnrankedTree; class UnrankedPattern; +class UnrankedNonlinearPattern; class RankedNode; class UnrankedNode; -- GitLab