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

InternalTree.h « FF « moses - github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 165355d061af47d985ee391f7e1168a6322f0c5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once

#include <iostream>
#include <string>
#include <map>
#include <vector>
#include "FFState.h"
#include "moses/Word.h"
#include "moses/StaticData.h"
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include "util/generator.hh"
#include "util/exception.hh"
#include "util/string_piece.hh"

namespace Moses
{

class InternalTree;
typedef boost::shared_ptr<InternalTree> TreePointer;

class InternalTree
{
  Word m_value;
  std::vector<TreePointer> m_children;
public:
  InternalTree(const std::string & line, size_t start, size_t len, const bool terminal);
  InternalTree(const std::string & line, const bool nonterminal = true);
  InternalTree(const InternalTree & tree):
    m_value(tree.m_value) {
    const std::vector<TreePointer> & children = tree.m_children;
    for (std::vector<TreePointer>::const_iterator it = children.begin(); it != children.end(); it++) {
      m_children.push_back(boost::make_shared<InternalTree>(**it));
    }
  }
  size_t AddSubTree(const std::string & line, size_t start);

  std::string GetString(bool start = true) const;
  void Combine(const std::vector<TreePointer> &previous);
  void Unbinarize();
  void GetUnbinarizedChildren(std::vector<TreePointer> &children) const;
  const Word & GetLabel() const {
    return m_value;
  }

  size_t GetLength() const {
    return m_children.size();
  }
  std::vector<TreePointer> & GetChildren() {
    return m_children;
  }

  bool IsTerminal() const {
    return !m_value.IsNonTerminal();
  }

  bool IsLeafNT() const {
    return (m_value.IsNonTerminal() && m_children.size() == 0);
  }

  // different methods to search a tree (either just direct children (FlatSearch) or all children (RecursiveSearch)) for constituents.
  // can be used for formulating syntax constraints.

  // if found, 'it' is iterator to first tree node that matches search string
  bool FlatSearch(const Word & label, std::vector<TreePointer>::const_iterator & it) const;
  bool RecursiveSearch(const Word & label, std::vector<TreePointer>::const_iterator & it) const;

  // if found, 'it' is iterator to first tree node that matches search string, and 'parent' to its parent node
  bool RecursiveSearch(const Word & label, std::vector<TreePointer>::const_iterator & it, InternalTree const* &parent) const;

  // Python-like generator that yields next nonterminal leaf on every call
  $generator(leafNT) {
    std::vector<TreePointer>::iterator it;
    InternalTree* tree;
    leafNT(InternalTree* root = 0): tree(root) {}
    $emit(std::vector<TreePointer>::iterator)
    for (it = tree->GetChildren().begin(); it !=tree->GetChildren().end(); ++it) {
      if (!(*it)->IsTerminal() && (*it)->GetLength() == 0) {
        $yield(it);
      } else if ((*it)->GetLength() > 0) {
        if ((*it).get()) { // normal pointer to same object that TreePointer points to
          $restart(tree = (*it).get());
        }
      }
    }
    $stop;
  };


  // Python-like generator that yields the parent of the next nonterminal leaf on every call
  $generator(leafNTParent) {
    std::vector<TreePointer>::iterator it;
    InternalTree* tree;
    leafNTParent(InternalTree* root = 0): tree(root) {}
    $emit(InternalTree*)
    for (it = tree->GetChildren().begin(); it !=tree->GetChildren().end(); ++it) {
      if (!(*it)->IsTerminal() && (*it)->GetLength() == 0) {
        $yield(tree);
      } else if ((*it)->GetLength() > 0) {
        if ((*it).get()) {
          $restart(tree = (*it).get());
        }
      }
    }
    $stop;
  };

  // Python-like generator that yields the next nonterminal leaf on every call, and also stores the path from the root of the tree to the nonterminal
  $generator(leafNTPath) {
    std::vector<TreePointer>::iterator it;
    InternalTree* tree;
    std::vector<InternalTree*> * path;
    leafNTPath(InternalTree* root = NULL, std::vector<InternalTree*> * orig = NULL): tree(root), path(orig) {}
    $emit(std::vector<TreePointer>::iterator)
    path->push_back(tree);
    for (it = tree->GetChildren().begin(); it !=tree->GetChildren().end(); ++it) {
      if (!(*it)->IsTerminal() && (*it)->GetLength() == 0) {
        path->push_back((*it).get());
        $yield(it);
        path->pop_back();
      } else if ((*it)->GetLength() > 0) {
        if ((*it).get()) {
          $restart(tree = (*it).get());
        }
      }
    }
    path->pop_back();
    $stop;
  };

};

class TreeState : public FFState
{
  TreePointer m_tree;
public:
  TreeState(TreePointer tree)
    :m_tree(tree) {
  }

  TreePointer GetTree() const {
    return m_tree;
  }

  virtual size_t hash() const {
    return 0;
  }
  virtual bool operator==(const FFState& other) const {
    return true;
  }

};

}