Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'moses/Syntax/T2S/RuleMatcherSCFG-inl.h')
-rw-r--r--moses/Syntax/T2S/RuleMatcherSCFG-inl.h107
1 files changed, 107 insertions, 0 deletions
diff --git a/moses/Syntax/T2S/RuleMatcherSCFG-inl.h b/moses/Syntax/T2S/RuleMatcherSCFG-inl.h
new file mode 100644
index 000000000..c1d8db63b
--- /dev/null
+++ b/moses/Syntax/T2S/RuleMatcherSCFG-inl.h
@@ -0,0 +1,107 @@
+#pragma once
+
+namespace Moses
+{
+namespace Syntax
+{
+namespace T2S
+{
+
+template<typename Callback>
+RuleMatcherSCFG<Callback>::RuleMatcherSCFG(const InputTree &inputTree,
+ const RuleTrie &ruleTrie)
+ : m_inputTree(inputTree)
+ , m_ruleTrie(ruleTrie)
+{
+}
+
+template<typename Callback>
+void RuleMatcherSCFG<Callback>::EnumerateHyperedges(const InputTree::Node &node,
+ Callback &callback)
+{
+ const int start = static_cast<int>(node.pvertex.span.GetStartPos());
+ m_hyperedge.head = const_cast<PVertex*>(&node.pvertex);
+ m_hyperedge.tail.clear();
+ Match(node, m_ruleTrie.GetRootNode(), start, callback);
+}
+
+template<typename Callback>
+void RuleMatcherSCFG<Callback>::Match(const InputTree::Node &inNode,
+ const RuleTrie::Node &trieNode,
+ int start, Callback &callback)
+{
+ // Try to extend the current hyperedge tail by adding a tree node that is a
+ // descendent of inNode and has a span starting at start.
+ const std::vector<InputTree::Node*> &nodes = m_inputTree.nodesAtPos[start];
+ for (std::vector<InputTree::Node*>::const_iterator p = nodes.begin();
+ p != nodes.end(); ++p) {
+ InputTree::Node &candidate = **p;
+ // Is candidate a descendent of inNode?
+ if (!IsDescendent(candidate, inNode)) {
+ continue;
+ }
+ // Get the appropriate SymbolMap (according to whether candidate is a
+ // terminal or non-terminal map) from the current rule trie node.
+ const RuleTrie::Node::SymbolMap *map = NULL;
+ if (candidate.children.empty()) {
+ map = &(trieNode.GetTerminalMap());
+ } else {
+ map = &(trieNode.GetNonTerminalMap());
+ }
+ // Test if the current rule prefix can be extended by candidate's symbol.
+ RuleTrie::Node::SymbolMap::const_iterator q =
+ map->find(candidate.pvertex.symbol);
+ if (q == map->end()) {
+ continue;
+ }
+ const RuleTrie::Node &newTrieNode = q->second;
+ // Add the candidate node to the tail.
+ m_hyperedge.tail.push_back(&candidate.pvertex);
+ // Have we now covered the full span of inNode?
+ if (candidate.pvertex.span.GetEndPos() == inNode.pvertex.span.GetEndPos()) {
+ // Check if the trie node has any rules with a LHS that match inNode.
+ const Word &lhs = inNode.pvertex.symbol;
+ const TargetPhraseCollection *tpc =
+ newTrieNode.GetTargetPhraseCollection(lhs);
+ if (tpc) {
+ m_hyperedge.label.translations = tpc;
+ callback(m_hyperedge);
+ }
+ } else {
+ // Recursive step.
+ int newStart = candidate.pvertex.span.GetEndPos()+1;
+ Match(inNode, newTrieNode, newStart, callback);
+ }
+ m_hyperedge.tail.pop_back();
+ }
+}
+
+// Return true iff x is a descendent of y; false otherwise.
+template<typename Callback>
+bool RuleMatcherSCFG<Callback>::IsDescendent(const InputTree::Node &x,
+ const InputTree::Node &y)
+{
+ const std::size_t xStart = x.pvertex.span.GetStartPos();
+ const std::size_t yStart = y.pvertex.span.GetStartPos();
+ const std::size_t xEnd = x.pvertex.span.GetEndPos();
+ const std::size_t yEnd = y.pvertex.span.GetEndPos();
+ if (xStart < yStart || xEnd > yEnd) {
+ return false;
+ }
+ if (xStart > yStart || xEnd < yEnd) {
+ return true;
+ }
+ // x and y both cover the same span.
+ const InputTree::Node *z = &y;
+ while (z->children.size() == 1) {
+ z = z->children[0];
+ if (z == &x) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace T2S
+} // namespace Syntax
+} // namespace Moses