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>