00001 #pragma once
00002
00003 namespace Moses
00004 {
00005 namespace Syntax
00006 {
00007 namespace T2S
00008 {
00009
00010 template<typename Callback>
00011 RuleMatcherSCFG<Callback>::RuleMatcherSCFG(const InputTree &inputTree,
00012 const RuleTrie &ruleTrie)
00013 : m_inputTree(inputTree)
00014 , m_ruleTrie(ruleTrie)
00015 {
00016 }
00017
00018 template<typename Callback>
00019 void RuleMatcherSCFG<Callback>::EnumerateHyperedges(const InputTree::Node &node,
00020 Callback &callback)
00021 {
00022 const int start = static_cast<int>(node.pvertex.span.GetStartPos());
00023 m_hyperedge.head = const_cast<PVertex*>(&node.pvertex);
00024 m_hyperedge.tail.clear();
00025 Match(node, m_ruleTrie.GetRootNode(), start, callback);
00026 }
00027
00028 template<typename Callback>
00029 void RuleMatcherSCFG<Callback>::Match(const InputTree::Node &inNode,
00030 const RuleTrie::Node &trieNode,
00031 int start, Callback &callback)
00032 {
00033
00034
00035 const std::vector<InputTree::Node*> &nodes = m_inputTree.nodesAtPos[start];
00036 for (std::vector<InputTree::Node*>::const_iterator p = nodes.begin();
00037 p != nodes.end(); ++p) {
00038 InputTree::Node &candidate = **p;
00039
00040 if (!IsDescendent(candidate, inNode)) {
00041 continue;
00042 }
00043
00044
00045 const RuleTrie::Node::SymbolMap *map = NULL;
00046 if (candidate.children.empty()) {
00047 map = &(trieNode.GetTerminalMap());
00048 } else {
00049 map = &(trieNode.GetNonTerminalMap());
00050 }
00051
00052 RuleTrie::Node::SymbolMap::const_iterator q =
00053 map->find(candidate.pvertex.symbol);
00054 if (q == map->end()) {
00055 continue;
00056 }
00057 const RuleTrie::Node &newTrieNode = q->second;
00058
00059 m_hyperedge.tail.push_back(&candidate.pvertex);
00060
00061 if (candidate.pvertex.span.GetEndPos() == inNode.pvertex.span.GetEndPos()) {
00062
00063 const Word &lhs = inNode.pvertex.symbol;
00064 TargetPhraseCollection::shared_ptr tpc =
00065 newTrieNode.GetTargetPhraseCollection(lhs);
00066 if (tpc) {
00067 m_hyperedge.label.translations = tpc;
00068 callback(m_hyperedge);
00069 }
00070 } else {
00071
00072 int newStart = candidate.pvertex.span.GetEndPos()+1;
00073 Match(inNode, newTrieNode, newStart, callback);
00074 }
00075 m_hyperedge.tail.pop_back();
00076 }
00077 }
00078
00079
00080 template<typename Callback>
00081 bool RuleMatcherSCFG<Callback>::IsDescendent(const InputTree::Node &x,
00082 const InputTree::Node &y)
00083 {
00084 const std::size_t xStart = x.pvertex.span.GetStartPos();
00085 const std::size_t yStart = y.pvertex.span.GetStartPos();
00086 const std::size_t xEnd = x.pvertex.span.GetEndPos();
00087 const std::size_t yEnd = y.pvertex.span.GetEndPos();
00088 if (xStart < yStart || xEnd > yEnd) {
00089 return false;
00090 }
00091 if (xStart > yStart || xEnd < yEnd) {
00092 return true;
00093 }
00094
00095 const InputTree::Node *z = &y;
00096 while (z->children.size() == 1) {
00097 z = z->children[0];
00098 if (z == &x) {
00099 return true;
00100 }
00101 }
00102 return false;
00103 }
00104
00105 }
00106 }
00107 }