|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "ComposedRule.h" |
|
|
|
#include <set> |
|
#include <vector> |
|
#include <queue> |
|
|
|
#include "Node.h" |
|
#include "Options.h" |
|
#include "Subgraph.h" |
|
|
|
namespace MosesTraining |
|
{ |
|
namespace Syntax |
|
{ |
|
namespace GHKM |
|
{ |
|
|
|
ComposedRule::ComposedRule(const Subgraph &baseRule) |
|
: m_baseRule(baseRule) |
|
, m_depth(baseRule.GetDepth()) |
|
, m_size(baseRule.GetSize()) |
|
, m_nodeCount(baseRule.GetNodeCount()) |
|
{ |
|
const std::set<const Node *> &leaves = baseRule.GetLeaves(); |
|
for (std::set<const Node *>::const_iterator p = leaves.begin(); |
|
p != leaves.end(); ++p) { |
|
if ((*p)->GetType() == TREE) { |
|
m_openAttachmentPoints.push(*p); |
|
} |
|
} |
|
} |
|
|
|
ComposedRule::ComposedRule(const ComposedRule &other, const Subgraph &rule, |
|
int depth) |
|
: m_baseRule(other.m_baseRule) |
|
, m_attachedRules(other.m_attachedRules) |
|
, m_openAttachmentPoints(other.m_openAttachmentPoints) |
|
, m_depth(depth) |
|
, m_size(other.m_size+rule.GetSize()) |
|
, m_nodeCount(other.m_nodeCount+rule.GetNodeCount()-1) |
|
{ |
|
m_attachedRules.push_back(&rule); |
|
m_openAttachmentPoints.pop(); |
|
} |
|
|
|
const Node *ComposedRule::GetOpenAttachmentPoint() |
|
{ |
|
return m_openAttachmentPoints.empty() ? 0 : m_openAttachmentPoints.front(); |
|
} |
|
|
|
void ComposedRule::CloseAttachmentPoint() |
|
{ |
|
assert(!m_openAttachmentPoints.empty()); |
|
m_attachedRules.push_back(0); |
|
m_openAttachmentPoints.pop(); |
|
} |
|
|
|
ComposedRule *ComposedRule::AttemptComposition(const Subgraph &rule, |
|
const Options &options) const |
|
{ |
|
|
|
|
|
assert(rule.GetRoot()->GetType() == TREE); |
|
|
|
|
|
if (m_nodeCount+rule.GetNodeCount()-1 > options.maxNodes) { |
|
return 0; |
|
} |
|
|
|
|
|
if (m_size+rule.GetSize() > options.maxRuleSize) { |
|
return 0; |
|
} |
|
|
|
|
|
|
|
int attachmentPointDepth = 0; |
|
const Node *n = rule.GetRoot(); |
|
while (n != m_baseRule.GetRoot()) { |
|
assert(n->GetParents().size() == 1); |
|
n = n->GetParents()[0]; |
|
++attachmentPointDepth; |
|
} |
|
int newDepth = std::max(m_depth, attachmentPointDepth+rule.GetDepth()); |
|
if (newDepth > options.maxRuleDepth) { |
|
return 0; |
|
} |
|
|
|
return new ComposedRule(*this, rule, newDepth); |
|
} |
|
|
|
Subgraph ComposedRule::CreateSubgraph() |
|
{ |
|
std::set<const Node *> leaves; |
|
const std::set<const Node *> &baseLeaves = m_baseRule.GetLeaves(); |
|
size_t i = 0; |
|
for (std::set<const Node *>::const_iterator p = baseLeaves.begin(); |
|
p != baseLeaves.end(); ++p) { |
|
const Node *baseLeaf = *p; |
|
if (baseLeaf->GetType() == TREE && i < m_attachedRules.size()) { |
|
const Subgraph *attachedRule = m_attachedRules[i++]; |
|
if (attachedRule) { |
|
leaves.insert(attachedRule->GetLeaves().begin(), |
|
attachedRule->GetLeaves().end()); |
|
continue; |
|
} |
|
} |
|
leaves.insert(baseLeaf); |
|
} |
|
return Subgraph(m_baseRule.GetRoot(), leaves); |
|
} |
|
|
|
} |
|
} |
|
} |
|
|