Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- mosesdecoder/COPYING +460 -0
- mosesdecoder/bjam +23 -0
- mosesdecoder/moses2/AlignmentInfoCollection.h +81 -0
- mosesdecoder/moses2/ArcLists.h +44 -0
- mosesdecoder/moses2/EstimatedScores.cpp +117 -0
- mosesdecoder/moses2/InputPathBase.h +32 -0
- mosesdecoder/moses2/InputType.h +86 -0
- mosesdecoder/moses2/Moses2Wrapper.cpp +70 -0
- mosesdecoder/moses2/Phrase.cpp +23 -0
- mosesdecoder/moses2/Scores.cpp +283 -0
- mosesdecoder/moses2/System.cpp +262 -0
- mosesdecoder/moses2/System.h +90 -0
- mosesdecoder/moses2/TargetPhrase.h +164 -0
- mosesdecoder/moses2/TrellisPaths.cpp +14 -0
- mosesdecoder/moses2/TypeDef.cpp +11 -0
- mosesdecoder/moses2/Word.h +63 -0
- mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.cpp +418 -0
- mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.h +87 -0
- mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.cpp +134 -0
- mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.h +75 -0
- mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.cpp +902 -0
- mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.h +82 -0
- mosesdecoder/phrase-extract/extract-ghkm/Jamfile +1 -0
- mosesdecoder/phrase-extract/extract-ghkm/Main.cpp +26 -0
- mosesdecoder/phrase-extract/extract-ghkm/Node.cpp +76 -0
- mosesdecoder/phrase-extract/extract-ghkm/Node.h +223 -0
- mosesdecoder/phrase-extract/extract-ghkm/Options.h +95 -0
- mosesdecoder/phrase-extract/extract-ghkm/Rule.cpp +44 -0
- mosesdecoder/phrase-extract/extract-ghkm/Rule.h +62 -0
- mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.cpp +203 -0
- mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.h +99 -0
- mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.cpp +235 -0
- mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.h +63 -0
- mosesdecoder/phrase-extract/extract-ghkm/Span.cpp +51 -0
- mosesdecoder/phrase-extract/extract-ghkm/Span.h +45 -0
- mosesdecoder/phrase-extract/extract-ghkm/StsgRule.cpp +97 -0
- mosesdecoder/phrase-extract/extract-ghkm/StsgRule.h +47 -0
- mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.cpp +98 -0
- mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.h +44 -0
- mosesdecoder/phrase-extract/extract-ghkm/Subgraph.cpp +206 -0
- mosesdecoder/phrase-extract/extract-ghkm/Subgraph.h +143 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentence.cpp +195 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentenceSyntax.h +46 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrase.cpp +67 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrases.cpp +104 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/Jamfile +2 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.cpp +74 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.h +66 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/Phrase.cpp +14 -0
- mosesdecoder/phrase-extract/extract-mixed-syntax/RulePhrase.cpp +50 -0
mosesdecoder/COPYING
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
GNU LESSER GENERAL PUBLIC LICENSE
|
| 3 |
+
Version 2.1, February 1999
|
| 4 |
+
|
| 5 |
+
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
| 6 |
+
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
| 7 |
+
Everyone is permitted to copy and distribute verbatim copies
|
| 8 |
+
of this license document, but changing it is not allowed.
|
| 9 |
+
|
| 10 |
+
[This is the first released version of the Lesser GPL. It also counts
|
| 11 |
+
as the successor of the GNU Library Public License, version 2, hence
|
| 12 |
+
the version number 2.1.]
|
| 13 |
+
|
| 14 |
+
Preamble
|
| 15 |
+
|
| 16 |
+
The licenses for most software are designed to take away your
|
| 17 |
+
freedom to share and change it. By contrast, the GNU General Public
|
| 18 |
+
Licenses are intended to guarantee your freedom to share and change
|
| 19 |
+
free software--to make sure the software is free for all its users.
|
| 20 |
+
|
| 21 |
+
This license, the Lesser General Public License, applies to some
|
| 22 |
+
specially designated software packages--typically libraries--of the
|
| 23 |
+
Free Software Foundation and other authors who decide to use it. You
|
| 24 |
+
can use it too, but we suggest you first think carefully about whether
|
| 25 |
+
this license or the ordinary General Public License is the better
|
| 26 |
+
strategy to use in any particular case, based on the explanations
|
| 27 |
+
below.
|
| 28 |
+
|
| 29 |
+
When we speak of free software, we are referring to freedom of use,
|
| 30 |
+
not price. Our General Public Licenses are designed to make sure that
|
| 31 |
+
you have the freedom to distribute copies of free software (and charge
|
| 32 |
+
for this service if you wish); that you receive source code or can get
|
| 33 |
+
it if you want it; that you can change the software and use pieces of
|
| 34 |
+
it in new free programs; and that you are informed that you can do
|
| 35 |
+
these things.
|
| 36 |
+
|
| 37 |
+
To protect your rights, we need to make restrictions that forbid
|
| 38 |
+
distributors to deny you these rights or to ask you to surrender these
|
| 39 |
+
rights. These restrictions translate to certain responsibilities for
|
| 40 |
+
you if you distribute copies of the library or if you modify it.
|
| 41 |
+
|
| 42 |
+
For example, if you distribute copies of the library, whether gratis
|
| 43 |
+
or for a fee, you must give the recipients all the rights that we gave
|
| 44 |
+
you. You must make sure that they, too, receive or can get the source
|
| 45 |
+
code. If you link other code with the library, you must provide
|
| 46 |
+
complete object files to the recipients, so that they can relink them
|
| 47 |
+
with the library after making changes to the library and recompiling
|
| 48 |
+
it. And you must show them these terms so they know their rights.
|
| 49 |
+
|
| 50 |
+
We protect your rights with a two-step method: (1) we copyright the
|
| 51 |
+
library, and (2) we offer you this license, which gives you legal
|
| 52 |
+
permission to copy, distribute and/or modify the library.
|
| 53 |
+
|
| 54 |
+
To protect each distributor, we want to make it very clear that
|
| 55 |
+
there is no warranty for the free library. Also, if the library is
|
| 56 |
+
modified by someone else and passed on, the recipients should know
|
| 57 |
+
that what they have is not the original version, so that the original
|
| 58 |
+
author's reputation will not be affected by problems that might be
|
| 59 |
+
introduced by others.
|
| 60 |
+
|
| 61 |
+
Finally, software patents pose a constant threat to the existence of
|
| 62 |
+
any free program. We wish to make sure that a company cannot
|
| 63 |
+
effectively restrict the users of a free program by obtaining a
|
| 64 |
+
restrictive license from a patent holder. Therefore, we insist that
|
| 65 |
+
any patent license obtained for a version of the library must be
|
| 66 |
+
consistent with the full freedom of use specified in this license.
|
| 67 |
+
|
| 68 |
+
Most GNU software, including some libraries, is covered by the
|
| 69 |
+
ordinary GNU General Public License. This license, the GNU Lesser
|
| 70 |
+
General Public License, applies to certain designated libraries, and
|
| 71 |
+
is quite different from the ordinary General Public License. We use
|
| 72 |
+
this license for certain libraries in order to permit linking those
|
| 73 |
+
libraries into non-free programs.
|
| 74 |
+
|
| 75 |
+
When a program is linked with a library, whether statically or using
|
| 76 |
+
a shared library, the combination of the two is legally speaking a
|
| 77 |
+
combined work, a derivative of the original library. The ordinary
|
| 78 |
+
General Public License therefore permits such linking only if the
|
| 79 |
+
entire combination fits its criteria of freedom. The Lesser General
|
| 80 |
+
Public License permits more lax criteria for linking other code with
|
| 81 |
+
the library.
|
| 82 |
+
|
| 83 |
+
We call this license the "Lesser" General Public License because it
|
| 84 |
+
does Less to protect the user's freedom than the ordinary General
|
| 85 |
+
Public License. It also provides other free software developers Less
|
| 86 |
+
of an advantage over competing non-free programs. These disadvantages
|
| 87 |
+
are the reason we use the ordinary General Public License for many
|
| 88 |
+
libraries. However, the Lesser license provides advantages in certain
|
| 89 |
+
special circumstances.
|
| 90 |
+
|
| 91 |
+
For example, on rare occasions, there may be a special need to
|
| 92 |
+
encourage the widest possible use of a certain library, so that it
|
| 93 |
+
becomes a de-facto standard. To achieve this, non-free programs must
|
| 94 |
+
be allowed to use the library. A more frequent case is that a free
|
| 95 |
+
library does the same job as widely used non-free libraries. In this
|
| 96 |
+
case, there is little to gain by limiting the free library to free
|
| 97 |
+
software only, so we use the Lesser General Public License.
|
| 98 |
+
|
| 99 |
+
In other cases, permission to use a particular library in non-free
|
| 100 |
+
programs enables a greater number of people to use a large body of
|
| 101 |
+
free software. For example, permission to use the GNU C Library in
|
| 102 |
+
non-free programs enables many more people to use the whole GNU
|
| 103 |
+
operating system, as well as its variant, the GNU/Linux operating
|
| 104 |
+
system.
|
| 105 |
+
|
| 106 |
+
Although the Lesser General Public License is Less protective of the
|
| 107 |
+
users' freedom, it does ensure that the user of a program that is
|
| 108 |
+
linked with the Library has the freedom and the wherewithal to run
|
| 109 |
+
that program using a modified version of the Library.
|
| 110 |
+
|
| 111 |
+
The precise terms and conditions for copying, distribution and
|
| 112 |
+
modification follow. Pay close attention to the difference between a
|
| 113 |
+
"work based on the library" and a "work that uses the library". The
|
| 114 |
+
former contains code derived from the library, whereas the latter must
|
| 115 |
+
be combined with the library in order to run.
|
| 116 |
+
|
| 117 |
+
GNU LESSER GENERAL PUBLIC LICENSE
|
| 118 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
| 119 |
+
|
| 120 |
+
0. This License Agreement applies to any software library or other
|
| 121 |
+
program which contains a notice placed by the copyright holder or
|
| 122 |
+
other authorized party saying it may be distributed under the terms of
|
| 123 |
+
this Lesser General Public License (also called "this License").
|
| 124 |
+
Each licensee is addressed as "you".
|
| 125 |
+
|
| 126 |
+
A "library" means a collection of software functions and/or data
|
| 127 |
+
prepared so as to be conveniently linked with application programs
|
| 128 |
+
(which use some of those functions and data) to form executables.
|
| 129 |
+
|
| 130 |
+
The "Library", below, refers to any such software library or work
|
| 131 |
+
which has been distributed under these terms. A "work based on the
|
| 132 |
+
Library" means either the Library or any derivative work under
|
| 133 |
+
copyright law: that is to say, a work containing the Library or a
|
| 134 |
+
portion of it, either verbatim or with modifications and/or translated
|
| 135 |
+
straightforwardly into another language. (Hereinafter, translation is
|
| 136 |
+
included without limitation in the term "modification".)
|
| 137 |
+
|
| 138 |
+
"Source code" for a work means the preferred form of the work for
|
| 139 |
+
making modifications to it. For a library, complete source code means
|
| 140 |
+
all the source code for all modules it contains, plus any associated
|
| 141 |
+
interface definition files, plus the scripts used to control
|
| 142 |
+
compilation and installation of the library.
|
| 143 |
+
|
| 144 |
+
Activities other than copying, distribution and modification are not
|
| 145 |
+
covered by this License; they are outside its scope. The act of
|
| 146 |
+
running a program using the Library is not restricted, and output from
|
| 147 |
+
such a program is covered only if its contents constitute a work based
|
| 148 |
+
on the Library (independent of the use of the Library in a tool for
|
| 149 |
+
writing it). Whether that is true depends on what the Library does
|
| 150 |
+
and what the program that uses the Library does.
|
| 151 |
+
|
| 152 |
+
1. You may copy and distribute verbatim copies of the Library's
|
| 153 |
+
complete source code as you receive it, in any medium, provided that
|
| 154 |
+
you conspicuously and appropriately publish on each copy an
|
| 155 |
+
appropriate copyright notice and disclaimer of warranty; keep intact
|
| 156 |
+
all the notices that refer to this License and to the absence of any
|
| 157 |
+
warranty; and distribute a copy of this License along with the
|
| 158 |
+
Library.
|
| 159 |
+
|
| 160 |
+
You may charge a fee for the physical act of transferring a copy,
|
| 161 |
+
and you may at your option offer warranty protection in exchange for a
|
| 162 |
+
fee.
|
| 163 |
+
|
| 164 |
+
2. You may modify your copy or copies of the Library or any portion
|
| 165 |
+
of it, thus forming a work based on the Library, and copy and
|
| 166 |
+
distribute such modifications or work under the terms of Section 1
|
| 167 |
+
above, provided that you also meet all of these conditions:
|
| 168 |
+
|
| 169 |
+
a) The modified work must itself be a software library.
|
| 170 |
+
|
| 171 |
+
b) You must cause the files modified to carry prominent notices
|
| 172 |
+
stating that you changed the files and the date of any change.
|
| 173 |
+
|
| 174 |
+
c) You must cause the whole of the work to be licensed at no
|
| 175 |
+
charge to all third parties under the terms of this License.
|
| 176 |
+
|
| 177 |
+
d) If a facility in the modified Library refers to a function or a
|
| 178 |
+
table of data to be supplied by an application program that uses
|
| 179 |
+
the facility, other than as an argument passed when the facility
|
| 180 |
+
is invoked, then you must make a good faith effort to ensure that,
|
| 181 |
+
in the event an application does not supply such function or
|
| 182 |
+
table, the facility still operates, and performs whatever part of
|
| 183 |
+
its purpose remains meaningful.
|
| 184 |
+
|
| 185 |
+
(For example, a function in a library to compute square roots has
|
| 186 |
+
a purpose that is entirely well-defined independent of the
|
| 187 |
+
application. Therefore, Subsection 2d requires that any
|
| 188 |
+
application-supplied function or table used by this function must
|
| 189 |
+
be optional: if the application does not supply it, the square
|
| 190 |
+
root function must still compute square roots.)
|
| 191 |
+
|
| 192 |
+
These requirements apply to the modified work as a whole. If
|
| 193 |
+
identifiable sections of that work are not derived from the Library,
|
| 194 |
+
and can be reasonably considered independent and separate works in
|
| 195 |
+
themselves, then this License, and its terms, do not apply to those
|
| 196 |
+
sections when you distribute them as separate works. But when you
|
| 197 |
+
distribute the same sections as part of a whole which is a work based
|
| 198 |
+
on the Library, the distribution of the whole must be on the terms of
|
| 199 |
+
this License, whose permissions for other licensees extend to the
|
| 200 |
+
entire whole, and thus to each and every part regardless of who wrote
|
| 201 |
+
it.
|
| 202 |
+
|
| 203 |
+
Thus, it is not the intent of this section to claim rights or contest
|
| 204 |
+
your rights to work written entirely by you; rather, the intent is to
|
| 205 |
+
exercise the right to control the distribution of derivative or
|
| 206 |
+
collective works based on the Library.
|
| 207 |
+
|
| 208 |
+
In addition, mere aggregation of another work not based on the Library
|
| 209 |
+
with the Library (or with a work based on the Library) on a volume of
|
| 210 |
+
a storage or distribution medium does not bring the other work under
|
| 211 |
+
the scope of this License.
|
| 212 |
+
|
| 213 |
+
3. You may opt to apply the terms of the ordinary GNU General Public
|
| 214 |
+
License instead of this License to a given copy of the Library. To do
|
| 215 |
+
this, you must alter all the notices that refer to this License, so
|
| 216 |
+
that they refer to the ordinary GNU General Public License, version 2,
|
| 217 |
+
instead of to this License. (If a newer version than version 2 of the
|
| 218 |
+
ordinary GNU General Public License has appeared, then you can specify
|
| 219 |
+
that version instead if you wish.) Do not make any other change in
|
| 220 |
+
these notices.
|
| 221 |
+
|
| 222 |
+
Once this change is made in a given copy, it is irreversible for
|
| 223 |
+
that copy, so the ordinary GNU General Public License applies to all
|
| 224 |
+
subsequent copies and derivative works made from that copy.
|
| 225 |
+
|
| 226 |
+
This option is useful when you wish to copy part of the code of
|
| 227 |
+
the Library into a program that is not a library.
|
| 228 |
+
|
| 229 |
+
4. You may copy and distribute the Library (or a portion or
|
| 230 |
+
derivative of it, under Section 2) in object code or executable form
|
| 231 |
+
under the terms of Sections 1 and 2 above provided that you accompany
|
| 232 |
+
it with the complete corresponding machine-readable source code, which
|
| 233 |
+
must be distributed under the terms of Sections 1 and 2 above on a
|
| 234 |
+
medium customarily used for software interchange.
|
| 235 |
+
|
| 236 |
+
If distribution of object code is made by offering access to copy
|
| 237 |
+
from a designated place, then offering equivalent access to copy the
|
| 238 |
+
source code from the same place satisfies the requirement to
|
| 239 |
+
distribute the source code, even though third parties are not
|
| 240 |
+
compelled to copy the source along with the object code.
|
| 241 |
+
|
| 242 |
+
5. A program that contains no derivative of any portion of the
|
| 243 |
+
Library, but is designed to work with the Library by being compiled or
|
| 244 |
+
linked with it, is called a "work that uses the Library". Such a
|
| 245 |
+
work, in isolation, is not a derivative work of the Library, and
|
| 246 |
+
therefore falls outside the scope of this License.
|
| 247 |
+
|
| 248 |
+
However, linking a "work that uses the Library" with the Library
|
| 249 |
+
creates an executable that is a derivative of the Library (because it
|
| 250 |
+
contains portions of the Library), rather than a "work that uses the
|
| 251 |
+
library". The executable is therefore covered by this License.
|
| 252 |
+
Section 6 states terms for distribution of such executables.
|
| 253 |
+
|
| 254 |
+
When a "work that uses the Library" uses material from a header file
|
| 255 |
+
that is part of the Library, the object code for the work may be a
|
| 256 |
+
derivative work of the Library even though the source code is not.
|
| 257 |
+
Whether this is true is especially significant if the work can be
|
| 258 |
+
linked without the Library, or if the work is itself a library. The
|
| 259 |
+
threshold for this to be true is not precisely defined by law.
|
| 260 |
+
|
| 261 |
+
If such an object file uses only numerical parameters, data
|
| 262 |
+
structure layouts and accessors, and small macros and small inline
|
| 263 |
+
functions (ten lines or less in length), then the use of the object
|
| 264 |
+
file is unrestricted, regardless of whether it is legally a derivative
|
| 265 |
+
work. (Executables containing this object code plus portions of the
|
| 266 |
+
Library will still fall under Section 6.)
|
| 267 |
+
|
| 268 |
+
Otherwise, if the work is a derivative of the Library, you may
|
| 269 |
+
distribute the object code for the work under the terms of Section 6.
|
| 270 |
+
Any executables containing that work also fall under Section 6,
|
| 271 |
+
whether or not they are linked directly with the Library itself.
|
| 272 |
+
|
| 273 |
+
6. As an exception to the Sections above, you may also combine or
|
| 274 |
+
link a "work that uses the Library" with the Library to produce a
|
| 275 |
+
work containing portions of the Library, and distribute that work
|
| 276 |
+
under terms of your choice, provided that the terms permit
|
| 277 |
+
modification of the work for the customer's own use and reverse
|
| 278 |
+
engineering for debugging such modifications.
|
| 279 |
+
|
| 280 |
+
You must give prominent notice with each copy of the work that the
|
| 281 |
+
Library is used in it and that the Library and its use are covered by
|
| 282 |
+
this License. You must supply a copy of this License. If the work
|
| 283 |
+
during execution displays copyright notices, you must include the
|
| 284 |
+
copyright notice for the Library among them, as well as a reference
|
| 285 |
+
directing the user to the copy of this License. Also, you must do one
|
| 286 |
+
of these things:
|
| 287 |
+
|
| 288 |
+
a) Accompany the work with the complete corresponding
|
| 289 |
+
machine-readable source code for the Library including whatever
|
| 290 |
+
changes were used in the work (which must be distributed under
|
| 291 |
+
Sections 1 and 2 above); and, if the work is an executable linked
|
| 292 |
+
with the Library, with the complete machine-readable "work that
|
| 293 |
+
uses the Library", as object code and/or source code, so that the
|
| 294 |
+
user can modify the Library and then relink to produce a modified
|
| 295 |
+
executable containing the modified Library. (It is understood
|
| 296 |
+
that the user who changes the contents of definitions files in the
|
| 297 |
+
Library will not necessarily be able to recompile the application
|
| 298 |
+
to use the modified definitions.)
|
| 299 |
+
|
| 300 |
+
b) Use a suitable shared library mechanism for linking with the
|
| 301 |
+
Library. A suitable mechanism is one that (1) uses at run time a
|
| 302 |
+
copy of the library already present on the user's computer system,
|
| 303 |
+
rather than copying library functions into the executable, and (2)
|
| 304 |
+
will operate properly with a modified version of the library, if
|
| 305 |
+
the user installs one, as long as the modified version is
|
| 306 |
+
interface-compatible with the version that the work was made with.
|
| 307 |
+
|
| 308 |
+
c) Accompany the work with a written offer, valid for at least
|
| 309 |
+
three years, to give the same user the materials specified in
|
| 310 |
+
Subsection 6a, above, for a charge no more than the cost of
|
| 311 |
+
performing this distribution.
|
| 312 |
+
|
| 313 |
+
d) If distribution of the work is made by offering access to copy
|
| 314 |
+
from a designated place, offer equivalent access to copy the above
|
| 315 |
+
specified materials from the same place.
|
| 316 |
+
|
| 317 |
+
e) Verify that the user has already received a copy of these
|
| 318 |
+
materials or that you have already sent this user a copy.
|
| 319 |
+
|
| 320 |
+
For an executable, the required form of the "work that uses the
|
| 321 |
+
Library" must include any data and utility programs needed for
|
| 322 |
+
reproducing the executable from it. However, as a special exception,
|
| 323 |
+
the materials to be distributed need not include anything that is
|
| 324 |
+
normally distributed (in either source or binary form) with the major
|
| 325 |
+
components (compiler, kernel, and so on) of the operating system on
|
| 326 |
+
which the executable runs, unless that component itself accompanies
|
| 327 |
+
the executable.
|
| 328 |
+
|
| 329 |
+
It may happen that this requirement contradicts the license
|
| 330 |
+
restrictions of other proprietary libraries that do not normally
|
| 331 |
+
accompany the operating system. Such a contradiction means you cannot
|
| 332 |
+
use both them and the Library together in an executable that you
|
| 333 |
+
distribute.
|
| 334 |
+
|
| 335 |
+
7. You may place library facilities that are a work based on the
|
| 336 |
+
Library side-by-side in a single library together with other library
|
| 337 |
+
facilities not covered by this License, and distribute such a combined
|
| 338 |
+
library, provided that the separate distribution of the work based on
|
| 339 |
+
the Library and of the other library facilities is otherwise
|
| 340 |
+
permitted, and provided that you do these two things:
|
| 341 |
+
|
| 342 |
+
a) Accompany the combined library with a copy of the same work
|
| 343 |
+
based on the Library, uncombined with any other library
|
| 344 |
+
facilities. This must be distributed under the terms of the
|
| 345 |
+
Sections above.
|
| 346 |
+
|
| 347 |
+
b) Give prominent notice with the combined library of the fact
|
| 348 |
+
that part of it is a work based on the Library, and explaining
|
| 349 |
+
where to find the accompanying uncombined form of the same work.
|
| 350 |
+
|
| 351 |
+
8. You may not copy, modify, sublicense, link with, or distribute
|
| 352 |
+
the Library except as expressly provided under this License. Any
|
| 353 |
+
attempt otherwise to copy, modify, sublicense, link with, or
|
| 354 |
+
distribute the Library is void, and will automatically terminate your
|
| 355 |
+
rights under this License. However, parties who have received copies,
|
| 356 |
+
or rights, from you under this License will not have their licenses
|
| 357 |
+
terminated so long as such parties remain in full compliance.
|
| 358 |
+
|
| 359 |
+
9. You are not required to accept this License, since you have not
|
| 360 |
+
signed it. However, nothing else grants you permission to modify or
|
| 361 |
+
distribute the Library or its derivative works. These actions are
|
| 362 |
+
prohibited by law if you do not accept this License. Therefore, by
|
| 363 |
+
modifying or distributing the Library (or any work based on the
|
| 364 |
+
Library), you indicate your acceptance of this License to do so, and
|
| 365 |
+
all its terms and conditions for copying, distributing or modifying
|
| 366 |
+
the Library or works based on it.
|
| 367 |
+
|
| 368 |
+
10. Each time you redistribute the Library (or any work based on the
|
| 369 |
+
Library), the recipient automatically receives a license from the
|
| 370 |
+
original licensor to copy, distribute, link with or modify the Library
|
| 371 |
+
subject to these terms and conditions. You may not impose any further
|
| 372 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
| 373 |
+
You are not responsible for enforcing compliance by third parties with
|
| 374 |
+
this License.
|
| 375 |
+
|
| 376 |
+
11. If, as a consequence of a court judgment or allegation of patent
|
| 377 |
+
infringement or for any other reason (not limited to patent issues),
|
| 378 |
+
conditions are imposed on you (whether by court order, agreement or
|
| 379 |
+
otherwise) that contradict the conditions of this License, they do not
|
| 380 |
+
excuse you from the conditions of this License. If you cannot
|
| 381 |
+
distribute so as to satisfy simultaneously your obligations under this
|
| 382 |
+
License and any other pertinent obligations, then as a consequence you
|
| 383 |
+
may not distribute the Library at all. For example, if a patent
|
| 384 |
+
license would not permit royalty-free redistribution of the Library by
|
| 385 |
+
all those who receive copies directly or indirectly through you, then
|
| 386 |
+
the only way you could satisfy both it and this License would be to
|
| 387 |
+
refrain entirely from distribution of the Library.
|
| 388 |
+
|
| 389 |
+
If any portion of this section is held invalid or unenforceable under
|
| 390 |
+
any particular circumstance, the balance of the section is intended to
|
| 391 |
+
apply, and the section as a whole is intended to apply in other
|
| 392 |
+
circumstances.
|
| 393 |
+
|
| 394 |
+
It is not the purpose of this section to induce you to infringe any
|
| 395 |
+
patents or other property right claims or to contest validity of any
|
| 396 |
+
such claims; this section has the sole purpose of protecting the
|
| 397 |
+
integrity of the free software distribution system which is
|
| 398 |
+
implemented by public license practices. Many people have made
|
| 399 |
+
generous contributions to the wide range of software distributed
|
| 400 |
+
through that system in reliance on consistent application of that
|
| 401 |
+
system; it is up to the author/donor to decide if he or she is willing
|
| 402 |
+
to distribute software through any other system and a licensee cannot
|
| 403 |
+
impose that choice.
|
| 404 |
+
|
| 405 |
+
This section is intended to make thoroughly clear what is believed to
|
| 406 |
+
be a consequence of the rest of this License.
|
| 407 |
+
|
| 408 |
+
12. If the distribution and/or use of the Library is restricted in
|
| 409 |
+
certain countries either by patents or by copyrighted interfaces, the
|
| 410 |
+
original copyright holder who places the Library under this License
|
| 411 |
+
may add an explicit geographical distribution limitation excluding those
|
| 412 |
+
countries, so that distribution is permitted only in or among
|
| 413 |
+
countries not thus excluded. In such case, this License incorporates
|
| 414 |
+
the limitation as if written in the body of this License.
|
| 415 |
+
|
| 416 |
+
13. The Free Software Foundation may publish revised and/or new
|
| 417 |
+
versions of the Lesser General Public License from time to time.
|
| 418 |
+
Such new versions will be similar in spirit to the present version,
|
| 419 |
+
but may differ in detail to address new problems or concerns.
|
| 420 |
+
|
| 421 |
+
Each version is given a distinguishing version number. If the Library
|
| 422 |
+
specifies a version number of this License which applies to it and
|
| 423 |
+
"any later version", you have the option of following the terms and
|
| 424 |
+
conditions either of that version or of any later version published by
|
| 425 |
+
the Free Software Foundation. If the Library does not specify a
|
| 426 |
+
license version number, you may choose any version ever published by
|
| 427 |
+
the Free Software Foundation.
|
| 428 |
+
|
| 429 |
+
14. If you wish to incorporate parts of the Library into other free
|
| 430 |
+
programs whose distribution conditions are incompatible with these,
|
| 431 |
+
write to the author to ask for permission. For software which is
|
| 432 |
+
copyrighted by the Free Software Foundation, write to the Free
|
| 433 |
+
Software Foundation; we sometimes make exceptions for this. Our
|
| 434 |
+
decision will be guided by the two goals of preserving the free status
|
| 435 |
+
of all derivatives of our free software and of promoting the sharing
|
| 436 |
+
and reuse of software generally.
|
| 437 |
+
|
| 438 |
+
NO WARRANTY
|
| 439 |
+
|
| 440 |
+
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
| 441 |
+
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
| 442 |
+
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
| 443 |
+
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
| 444 |
+
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
| 445 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| 446 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
| 447 |
+
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
| 448 |
+
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
| 449 |
+
|
| 450 |
+
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
| 451 |
+
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
| 452 |
+
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
| 453 |
+
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
| 454 |
+
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
| 455 |
+
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
| 456 |
+
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
| 457 |
+
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
| 458 |
+
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
| 459 |
+
DAMAGES.
|
| 460 |
+
|
mosesdecoder/bjam
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
set -e
|
| 3 |
+
top="$(dirname "$0")"
|
| 4 |
+
if
|
| 5 |
+
bjam="$(which bjam 2>/dev/null)" && #exists
|
| 6 |
+
[ ${#bjam} != 0 ] && #paranoia about which printing nothing then returning true
|
| 7 |
+
! grep UFIHGUFIHBDJKNCFZXAEVA "${bjam}" </dev/null >/dev/null && #bjam in path isn't this script
|
| 8 |
+
"${bjam}" --sanity-test 2>/dev/null |grep Sane >/dev/null && #The test in jam-files/sanity.jam passes
|
| 9 |
+
(cd "${top}/jam-files/fail" && ! "${bjam}") >/dev/null #Returns non-zero on failure
|
| 10 |
+
then
|
| 11 |
+
#Delegate to system bjam
|
| 12 |
+
exec "${bjam}" "$@"
|
| 13 |
+
fi
|
| 14 |
+
|
| 15 |
+
if [ ! -x "$top"/jam-files/bjam ] || "$top"/jam-files/bjam -v |grep 2011.4 >/dev/null; then
|
| 16 |
+
pushd "$top/jam-files/engine"
|
| 17 |
+
./build.sh
|
| 18 |
+
cp -f bin.*/bjam ../bjam
|
| 19 |
+
popd
|
| 20 |
+
fi
|
| 21 |
+
|
| 22 |
+
export BOOST_BUILD_PATH="$top"/jam-files/boost-build
|
| 23 |
+
exec "$top"/jam-files/bjam "$@"
|
mosesdecoder/moses2/AlignmentInfoCollection.h
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include "AlignmentInfo.h"
|
| 23 |
+
|
| 24 |
+
#include <set>
|
| 25 |
+
|
| 26 |
+
#ifdef WITH_THREADS
|
| 27 |
+
#include <boost/thread/shared_mutex.hpp>
|
| 28 |
+
#include <boost/thread/locks.hpp>
|
| 29 |
+
#endif
|
| 30 |
+
|
| 31 |
+
namespace Moses2
|
| 32 |
+
{
|
| 33 |
+
|
| 34 |
+
/** Singleton collection of all AlignmentInfo objects.
|
| 35 |
+
* Used as a cache of all alignment info to save space.
|
| 36 |
+
*/
|
| 37 |
+
class AlignmentInfoCollection
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
static AlignmentInfoCollection &Instance() {
|
| 41 |
+
return s_instance;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/** Returns a pointer to an AlignmentInfo object with the same source-target
|
| 45 |
+
* alignment pairs as given in the argument. If the collection already
|
| 46 |
+
* contains such an object then returns a pointer to it; otherwise a new
|
| 47 |
+
* one is inserted.
|
| 48 |
+
*/
|
| 49 |
+
private:
|
| 50 |
+
const AlignmentInfo* Add(AlignmentInfo const& ainfo);
|
| 51 |
+
|
| 52 |
+
public:
|
| 53 |
+
template<typename ALNREP>
|
| 54 |
+
AlignmentInfo const *
|
| 55 |
+
Add(ALNREP const & aln) {
|
| 56 |
+
return this->Add(AlignmentInfo(aln));
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
//! Returns a pointer to an empty AlignmentInfo object.
|
| 60 |
+
const AlignmentInfo &GetEmptyAlignmentInfo() const;
|
| 61 |
+
|
| 62 |
+
private:
|
| 63 |
+
typedef std::set<AlignmentInfo, AlignmentInfoOrderer> AlignmentInfoSet;
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
//! Only a single static variable should be created.
|
| 67 |
+
AlignmentInfoCollection();
|
| 68 |
+
~AlignmentInfoCollection();
|
| 69 |
+
|
| 70 |
+
static AlignmentInfoCollection s_instance;
|
| 71 |
+
|
| 72 |
+
#ifdef WITH_THREADS
|
| 73 |
+
//reader-writer lock
|
| 74 |
+
mutable boost::shared_mutex m_accessLock;
|
| 75 |
+
#endif
|
| 76 |
+
|
| 77 |
+
AlignmentInfoSet m_collection;
|
| 78 |
+
const AlignmentInfo *m_emptyAlignmentInfo;
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
+
}
|
mosesdecoder/moses2/ArcLists.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* ArcList.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 26 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#pragma once
|
| 8 |
+
#include <vector>
|
| 9 |
+
#include <unordered_map>
|
| 10 |
+
#include <unordered_set>
|
| 11 |
+
|
| 12 |
+
namespace Moses2
|
| 13 |
+
{
|
| 14 |
+
class System;
|
| 15 |
+
|
| 16 |
+
class HypothesisBase;
|
| 17 |
+
|
| 18 |
+
typedef std::vector<const HypothesisBase*> ArcList;
|
| 19 |
+
|
| 20 |
+
class ArcLists
|
| 21 |
+
{
|
| 22 |
+
public:
|
| 23 |
+
ArcLists();
|
| 24 |
+
virtual ~ArcLists();
|
| 25 |
+
|
| 26 |
+
void AddArc(bool added, const HypothesisBase *currHypo,
|
| 27 |
+
const HypothesisBase *otherHypo);
|
| 28 |
+
void Sort();
|
| 29 |
+
void Delete(const HypothesisBase *hypo);
|
| 30 |
+
|
| 31 |
+
const ArcList &GetArcList(const HypothesisBase *hypo) const;
|
| 32 |
+
|
| 33 |
+
std::string Debug(const System &system) const;
|
| 34 |
+
protected:
|
| 35 |
+
typedef std::unordered_map<const HypothesisBase*, ArcList*> Coll;
|
| 36 |
+
Coll m_coll;
|
| 37 |
+
|
| 38 |
+
ArcList &GetArcList(const HypothesisBase *hypo);
|
| 39 |
+
ArcList &GetAndDetachArcList(const HypothesisBase *hypo);
|
| 40 |
+
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
}
|
| 44 |
+
|
mosesdecoder/moses2/EstimatedScores.cpp
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// $Id$
|
| 2 |
+
// vim:tabstop=2
|
| 3 |
+
|
| 4 |
+
/***********************************************************************
|
| 5 |
+
Moses - factored phrase-based language decoder
|
| 6 |
+
Copyright (C) 2006 University of Edinburgh
|
| 7 |
+
|
| 8 |
+
This library is free software; you can redistribute it and/or
|
| 9 |
+
modify it under the terms of the GNU Lesser General Public
|
| 10 |
+
License as published by the Free Software Foundation; either
|
| 11 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 12 |
+
|
| 13 |
+
This library is distributed in the hope that it will be useful,
|
| 14 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 15 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 16 |
+
Lesser General Public License for more details.
|
| 17 |
+
|
| 18 |
+
You should have received a copy of the GNU Lesser General Public
|
| 19 |
+
License along with this library; if not, write to the Free Software
|
| 20 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 21 |
+
***********************************************************************/
|
| 22 |
+
|
| 23 |
+
#include <string>
|
| 24 |
+
#include <iostream>
|
| 25 |
+
#include "EstimatedScores.h"
|
| 26 |
+
|
| 27 |
+
using namespace std;
|
| 28 |
+
|
| 29 |
+
namespace Moses2
|
| 30 |
+
{
|
| 31 |
+
/**
|
| 32 |
+
* Calculate future score estimate for a given coverage bitmap
|
| 33 |
+
*
|
| 34 |
+
* /param bitmap coverage bitmap
|
| 35 |
+
*/
|
| 36 |
+
|
| 37 |
+
float EstimatedScores::CalcEstimatedScore(Bitmap const &bitmap) const
|
| 38 |
+
{
|
| 39 |
+
const size_t notInGap = numeric_limits<size_t>::max();
|
| 40 |
+
size_t startGap = notInGap;
|
| 41 |
+
float estimatedScore = 0.0f;
|
| 42 |
+
for (size_t currPos = 0; currPos < bitmap.GetSize(); currPos++) {
|
| 43 |
+
// start of a new gap?
|
| 44 |
+
if (bitmap.GetValue(currPos) == false && startGap == notInGap) {
|
| 45 |
+
startGap = currPos;
|
| 46 |
+
}
|
| 47 |
+
// end of a gap?
|
| 48 |
+
else if (bitmap.GetValue(currPos) == true && startGap != notInGap) {
|
| 49 |
+
estimatedScore += GetValue(startGap, currPos - 1);
|
| 50 |
+
startGap = notInGap;
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
// coverage ending with gap?
|
| 54 |
+
if (startGap != notInGap) {
|
| 55 |
+
estimatedScore += GetValue(startGap, bitmap.GetSize() - 1);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
return estimatedScore;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
/**
|
| 62 |
+
* Calculare future score estimate for a given coverage bitmap
|
| 63 |
+
* and an additional span that is also covered. This function is used
|
| 64 |
+
* to compute future score estimates for hypotheses that we may want
|
| 65 |
+
* build, but first want to check.
|
| 66 |
+
*
|
| 67 |
+
* Note: this function is implemented a bit more complex than
|
| 68 |
+
* the basic one (w/o additional phrase) for speed reasons,
|
| 69 |
+
* which is probably overkill.
|
| 70 |
+
*
|
| 71 |
+
* /param bitmap coverage bitmap
|
| 72 |
+
* /param startPos start of the span that is added to the coverage
|
| 73 |
+
* /param endPos end of the span that is added to the coverage
|
| 74 |
+
*/
|
| 75 |
+
|
| 76 |
+
float EstimatedScores::CalcEstimatedScore(Bitmap const &bitmap, size_t startPos,
|
| 77 |
+
size_t endPos) const
|
| 78 |
+
{
|
| 79 |
+
const size_t notInGap = numeric_limits<size_t>::max();
|
| 80 |
+
float estimatedScore = 0.0f;
|
| 81 |
+
size_t startGap = bitmap.GetFirstGapPos();
|
| 82 |
+
if (startGap == NOT_FOUND) return estimatedScore; // everything filled
|
| 83 |
+
|
| 84 |
+
// start loop at first gap
|
| 85 |
+
size_t startLoop = startGap + 1;
|
| 86 |
+
if (startPos == startGap) { // unless covered by phrase
|
| 87 |
+
startGap = notInGap;
|
| 88 |
+
startLoop = endPos + 1; // -> postpone start
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
size_t lastCovered = bitmap.GetLastPos();
|
| 92 |
+
if (endPos > lastCovered || lastCovered == NOT_FOUND) lastCovered = endPos;
|
| 93 |
+
|
| 94 |
+
for (size_t currPos = startLoop; currPos <= lastCovered; currPos++) {
|
| 95 |
+
// start of a new gap?
|
| 96 |
+
if (startGap == notInGap && bitmap.GetValue(currPos) == false
|
| 97 |
+
&& (currPos < startPos || currPos > endPos)) {
|
| 98 |
+
startGap = currPos;
|
| 99 |
+
}
|
| 100 |
+
// end of a gap?
|
| 101 |
+
else if (startGap != notInGap
|
| 102 |
+
&& (bitmap.GetValue(currPos) == true
|
| 103 |
+
|| (startPos <= currPos && currPos <= endPos))) {
|
| 104 |
+
estimatedScore += GetValue(startGap, currPos - 1);
|
| 105 |
+
startGap = notInGap;
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
// coverage ending with gap?
|
| 109 |
+
if (lastCovered != bitmap.GetSize() - 1) {
|
| 110 |
+
estimatedScore += GetValue(lastCovered + 1, bitmap.GetSize() - 1);
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
return estimatedScore;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
}
|
| 117 |
+
|
mosesdecoder/moses2/InputPathBase.h
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* InputPath.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
|
| 10 |
+
#include <iostream>
|
| 11 |
+
#include <vector>
|
| 12 |
+
#include "SubPhrase.h"
|
| 13 |
+
#include "legacy/Range.h"
|
| 14 |
+
|
| 15 |
+
namespace Moses2
|
| 16 |
+
{
|
| 17 |
+
|
| 18 |
+
class PhraseTable;
|
| 19 |
+
|
| 20 |
+
class InputPathBase
|
| 21 |
+
{
|
| 22 |
+
public:
|
| 23 |
+
const InputPathBase *prefixPath;
|
| 24 |
+
Range range;
|
| 25 |
+
|
| 26 |
+
InputPathBase(MemPool &pool, const Range &range,
|
| 27 |
+
size_t numPt, const InputPathBase *prefixPath);
|
| 28 |
+
|
| 29 |
+
};
|
| 30 |
+
|
| 31 |
+
}
|
| 32 |
+
|
mosesdecoder/moses2/InputType.h
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* InputType.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 14 Dec 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
|
| 10 |
+
#include "PhraseBased/ReorderingConstraint.h"
|
| 11 |
+
#include "TypeDef.h"
|
| 12 |
+
|
| 13 |
+
namespace Moses2
|
| 14 |
+
{
|
| 15 |
+
|
| 16 |
+
class InputType
|
| 17 |
+
{
|
| 18 |
+
public:
|
| 19 |
+
//////////////////////////////////////////////////////////////////////////////
|
| 20 |
+
class XMLOption
|
| 21 |
+
{
|
| 22 |
+
public:
|
| 23 |
+
size_t startPos, phraseSize;
|
| 24 |
+
|
| 25 |
+
SCORE prob;
|
| 26 |
+
|
| 27 |
+
XMLOption(MemPool &pool, const std::string &nodeName, size_t vStartPos);
|
| 28 |
+
|
| 29 |
+
const char *GetNodeName() const {
|
| 30 |
+
return m_nodeName;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
const char *GetTranslation() const {
|
| 34 |
+
return m_translation;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
const char *GetEntity() const {
|
| 38 |
+
return m_entity;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
void SetTranslation(MemPool &pool, const std::string &val);
|
| 42 |
+
void SetEntity(MemPool &pool, const std::string &val);
|
| 43 |
+
|
| 44 |
+
std::string Debug(const System &system) const;
|
| 45 |
+
public:
|
| 46 |
+
char *m_nodeName;
|
| 47 |
+
char *m_translation;
|
| 48 |
+
char *m_entity;
|
| 49 |
+
|
| 50 |
+
};
|
| 51 |
+
|
| 52 |
+
//////////////////////////////////////////////////////////////////////////////
|
| 53 |
+
|
| 54 |
+
InputType(MemPool &pool);
|
| 55 |
+
virtual ~InputType();
|
| 56 |
+
|
| 57 |
+
virtual void Init(const System &system, size_t size, int max_distortion);
|
| 58 |
+
|
| 59 |
+
ReorderingConstraint &GetReorderingConstraint() {
|
| 60 |
+
return m_reorderingConstraint;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
const ReorderingConstraint &GetReorderingConstraint() const {
|
| 64 |
+
return m_reorderingConstraint;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
const Vector<const XMLOption*> &GetXMLOptions() const {
|
| 68 |
+
return m_xmlOptions;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
void AddXMLOption(const System &system, const XMLOption *xmlOption);
|
| 72 |
+
|
| 73 |
+
//! Returns true if there were any XML tags parsed that at least partially covered the range passed
|
| 74 |
+
bool XmlOverlap(size_t startPos, size_t endPos) const;
|
| 75 |
+
|
| 76 |
+
virtual std::string Debug(const System &system) const;
|
| 77 |
+
|
| 78 |
+
protected:
|
| 79 |
+
ReorderingConstraint m_reorderingConstraint; /**< limits on reordering specified either by "-mp" switch or xml tags */
|
| 80 |
+
Vector<const XMLOption*> m_xmlOptions;
|
| 81 |
+
Vector<bool> m_xmlCoverageMap;
|
| 82 |
+
|
| 83 |
+
};
|
| 84 |
+
|
| 85 |
+
} /* namespace Moses2 */
|
| 86 |
+
|
mosesdecoder/moses2/Moses2Wrapper.cpp
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "Moses2Wrapper.h"
|
| 2 |
+
#include "System.h"
|
| 3 |
+
#include "legacy/Parameter.h"
|
| 4 |
+
#include "TranslationTask.h"
|
| 5 |
+
#include <string.h>
|
| 6 |
+
|
| 7 |
+
using namespace std;
|
| 8 |
+
namespace Moses2 {
|
| 9 |
+
//summary :: need to update the LM path at runtime with complete artifact path.
|
| 10 |
+
void Moses2Wrapper::UpdateLMPath(const std::string& filePath) {
|
| 11 |
+
|
| 12 |
+
char sep = '/';
|
| 13 |
+
|
| 14 |
+
#ifdef _WIN32
|
| 15 |
+
sep = '\\';
|
| 16 |
+
#endif
|
| 17 |
+
auto file = filePath.substr(filePath.find_last_of(sep) + 1);
|
| 18 |
+
auto path = filePath.substr(0, filePath.find_last_of(sep));
|
| 19 |
+
auto a = m_param->GetParam("feature");
|
| 20 |
+
std::vector<std::string> feature;
|
| 21 |
+
for (int i = 0; i < a->size(); i++) {
|
| 22 |
+
auto abc = Tokenize(a->at(i));
|
| 23 |
+
if (*abc.begin() == "KENLM") {
|
| 24 |
+
string s = "";
|
| 25 |
+
for (int k = 0; k < abc.size(); k++) {
|
| 26 |
+
if (abc.at(k).find("path=") != string::npos) {
|
| 27 |
+
auto lm = abc.at(k).substr(abc.at(k).find_last_of("=") + 1);
|
| 28 |
+
s = s + "path=" + path + sep + lm + " ";
|
| 29 |
+
}
|
| 30 |
+
else {
|
| 31 |
+
s = s + abc.at(k) + " ";
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
feature.push_back(s.erase(s.find_last_not_of(" \n\r\t") + 1));
|
| 35 |
+
}
|
| 36 |
+
else {
|
| 37 |
+
feature.push_back(a->at(i));
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
m_param->OverwriteParam("feature", feature);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
Moses2Wrapper::Moses2Wrapper(const std::string &filePath) {
|
| 44 |
+
m_param = new Parameter();
|
| 45 |
+
m_param->LoadParam(filePath);
|
| 46 |
+
UpdateLMPath(filePath);
|
| 47 |
+
m_system = new System(*m_param);
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
std::string Moses2Wrapper::Translate(const std::string &input , long id, bool nbest) {
|
| 51 |
+
TranslationTask task(*m_system, input, id);
|
| 52 |
+
return task.ReturnTranslation(nbest);
|
| 53 |
+
}
|
| 54 |
+
Moses2Wrapper::~Moses2Wrapper() {
|
| 55 |
+
delete m_param;
|
| 56 |
+
delete m_system;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
char* Moses2Wrapper::CopyString(const char* str) {
|
| 60 |
+
int32_t size = (int32_t)strlen(str);
|
| 61 |
+
char* obj = (char*)malloc(size + 1);
|
| 62 |
+
memcpy(obj, str, size);
|
| 63 |
+
obj[size] = '\0';
|
| 64 |
+
return obj;
|
| 65 |
+
}
|
| 66 |
+
void Moses2Wrapper::Free(void* ptr) {
|
| 67 |
+
free(ptr);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
}
|
mosesdecoder/moses2/Phrase.cpp
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* PhraseImpl.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include <boost/functional/hash.hpp>
|
| 8 |
+
#include "Phrase.h"
|
| 9 |
+
#include "Word.h"
|
| 10 |
+
#include "MemPool.h"
|
| 11 |
+
#include "Scores.h"
|
| 12 |
+
#include "System.h"
|
| 13 |
+
|
| 14 |
+
using namespace std;
|
| 15 |
+
|
| 16 |
+
namespace Moses2
|
| 17 |
+
{
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
} // namespace
|
| 23 |
+
|
mosesdecoder/moses2/Scores.cpp
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Scores.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#include <boost/foreach.hpp>
|
| 9 |
+
#include <vector>
|
| 10 |
+
#include <cstddef>
|
| 11 |
+
#include <stdio.h>
|
| 12 |
+
#include "Scores.h"
|
| 13 |
+
#include "Weights.h"
|
| 14 |
+
#include "System.h"
|
| 15 |
+
#include "FF/FeatureFunction.h"
|
| 16 |
+
#include "FF/FeatureFunctions.h"
|
| 17 |
+
#include "legacy/Util2.h"
|
| 18 |
+
|
| 19 |
+
using namespace std;
|
| 20 |
+
|
| 21 |
+
namespace Moses2
|
| 22 |
+
{
|
| 23 |
+
|
| 24 |
+
Scores::Scores(const System &system, MemPool &pool, size_t numScores) :
|
| 25 |
+
m_total(0)
|
| 26 |
+
{
|
| 27 |
+
if (system.options.nbest.nbest_size) {
|
| 28 |
+
m_scores = new (pool.Allocate<SCORE>(numScores)) SCORE[numScores];
|
| 29 |
+
Init<SCORE>(m_scores, numScores, 0);
|
| 30 |
+
} else {
|
| 31 |
+
m_scores = NULL;
|
| 32 |
+
}
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
Scores::Scores(const System &system, MemPool &pool, size_t numScores,
|
| 36 |
+
const Scores &origScores) :
|
| 37 |
+
m_total(origScores.m_total)
|
| 38 |
+
{
|
| 39 |
+
if (system.options.nbest.nbest_size) {
|
| 40 |
+
m_scores = new (pool.Allocate<SCORE>(numScores)) SCORE[numScores];
|
| 41 |
+
memcpy(m_scores, origScores.m_scores, sizeof(SCORE) * numScores);
|
| 42 |
+
} else {
|
| 43 |
+
m_scores = NULL;
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
Scores::~Scores()
|
| 48 |
+
{
|
| 49 |
+
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
const SCORE *Scores::GetScores(const FeatureFunction &featureFunction) const
|
| 53 |
+
{
|
| 54 |
+
assert(m_scores);
|
| 55 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 56 |
+
const SCORE &scores = m_scores[ffStartInd];
|
| 57 |
+
return &scores;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
void Scores::Reset(const System &system)
|
| 61 |
+
{
|
| 62 |
+
if (system.options.nbest.nbest_size) {
|
| 63 |
+
size_t numScores = system.featureFunctions.GetNumScores();
|
| 64 |
+
Init<SCORE>(m_scores, numScores, 0);
|
| 65 |
+
}
|
| 66 |
+
m_total = 0;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
void Scores::PlusEquals(const System &system,
|
| 70 |
+
const FeatureFunction &featureFunction, const SCORE &score)
|
| 71 |
+
{
|
| 72 |
+
assert(featureFunction.GetNumScores() == 1);
|
| 73 |
+
|
| 74 |
+
const Weights &weights = system.weights;
|
| 75 |
+
|
| 76 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 77 |
+
if (system.options.nbest.nbest_size) {
|
| 78 |
+
m_scores[ffStartInd] += score;
|
| 79 |
+
}
|
| 80 |
+
SCORE weight = weights[ffStartInd];
|
| 81 |
+
m_total += score * weight;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
void Scores::PlusEquals(const System &system,
|
| 85 |
+
const FeatureFunction &featureFunction, const SCORE &score, size_t offset)
|
| 86 |
+
{
|
| 87 |
+
assert(offset < featureFunction.GetNumScores());
|
| 88 |
+
|
| 89 |
+
const Weights &weights = system.weights;
|
| 90 |
+
|
| 91 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 92 |
+
if (system.options.nbest.nbest_size) {
|
| 93 |
+
m_scores[ffStartInd + offset] += score;
|
| 94 |
+
}
|
| 95 |
+
SCORE weight = weights[ffStartInd + offset];
|
| 96 |
+
m_total += score * weight;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
void Scores::PlusEquals(const System &system,
|
| 100 |
+
const FeatureFunction &featureFunction, const std::vector<SCORE> &scores)
|
| 101 |
+
{
|
| 102 |
+
assert(scores.size() == featureFunction.GetNumScores());
|
| 103 |
+
|
| 104 |
+
const Weights &weights = system.weights;
|
| 105 |
+
|
| 106 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 107 |
+
for (size_t i = 0; i < scores.size(); ++i) {
|
| 108 |
+
SCORE incrScore = scores[i];
|
| 109 |
+
if (system.options.nbest.nbest_size) {
|
| 110 |
+
m_scores[ffStartInd + i] += incrScore;
|
| 111 |
+
}
|
| 112 |
+
//cerr << "ffStartInd=" << ffStartInd << " " << i << endl;
|
| 113 |
+
SCORE weight = weights[ffStartInd + i];
|
| 114 |
+
m_total += incrScore * weight;
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
void Scores::PlusEquals(const System &system,
|
| 119 |
+
const FeatureFunction &featureFunction, SCORE scores[])
|
| 120 |
+
{
|
| 121 |
+
//assert(scores.size() == featureFunction.GetNumScores());
|
| 122 |
+
|
| 123 |
+
const Weights &weights = system.weights;
|
| 124 |
+
|
| 125 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 126 |
+
for (size_t i = 0; i < featureFunction.GetNumScores(); ++i) {
|
| 127 |
+
SCORE incrScore = scores[i];
|
| 128 |
+
if (system.options.nbest.nbest_size) {
|
| 129 |
+
m_scores[ffStartInd + i] += incrScore;
|
| 130 |
+
}
|
| 131 |
+
//cerr << "ffStartInd=" << ffStartInd << " " << i << endl;
|
| 132 |
+
SCORE weight = weights[ffStartInd + i];
|
| 133 |
+
m_total += incrScore * weight;
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
void Scores::PlusEquals(const System &system, const Scores &other)
|
| 138 |
+
{
|
| 139 |
+
size_t numScores = system.featureFunctions.GetNumScores();
|
| 140 |
+
if (system.options.nbest.nbest_size) {
|
| 141 |
+
for (size_t i = 0; i < numScores; ++i) {
|
| 142 |
+
m_scores[i] += other.m_scores[i];
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
m_total += other.m_total;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
void Scores::MinusEquals(const System &system, const Scores &other)
|
| 149 |
+
{
|
| 150 |
+
size_t numScores = system.featureFunctions.GetNumScores();
|
| 151 |
+
if (system.options.nbest.nbest_size) {
|
| 152 |
+
for (size_t i = 0; i < numScores; ++i) {
|
| 153 |
+
m_scores[i] -= other.m_scores[i];
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
m_total -= other.m_total;
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
void Scores::Assign(const System &system,
|
| 160 |
+
const FeatureFunction &featureFunction, const SCORE &score)
|
| 161 |
+
{
|
| 162 |
+
assert(featureFunction.GetNumScores() == 1);
|
| 163 |
+
|
| 164 |
+
const Weights &weights = system.weights;
|
| 165 |
+
|
| 166 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 167 |
+
|
| 168 |
+
if (system.options.nbest.nbest_size) {
|
| 169 |
+
assert(m_scores[ffStartInd] == 0);
|
| 170 |
+
m_scores[ffStartInd] = score;
|
| 171 |
+
}
|
| 172 |
+
SCORE weight = weights[ffStartInd];
|
| 173 |
+
m_total += score * weight;
|
| 174 |
+
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
void Scores::Assign(const System &system,
|
| 178 |
+
const FeatureFunction &featureFunction, const std::vector<SCORE> &scores)
|
| 179 |
+
{
|
| 180 |
+
assert(scores.size() == featureFunction.GetNumScores());
|
| 181 |
+
|
| 182 |
+
const Weights &weights = system.weights;
|
| 183 |
+
|
| 184 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 185 |
+
for (size_t i = 0; i < scores.size(); ++i) {
|
| 186 |
+
SCORE incrScore = scores[i];
|
| 187 |
+
|
| 188 |
+
if (system.options.nbest.nbest_size) {
|
| 189 |
+
assert(m_scores[ffStartInd + i] == 0);
|
| 190 |
+
m_scores[ffStartInd + i] = incrScore;
|
| 191 |
+
}
|
| 192 |
+
//cerr << "ffStartInd=" << ffStartInd << " " << i << endl;
|
| 193 |
+
SCORE weight = weights[ffStartInd + i];
|
| 194 |
+
m_total += incrScore * weight;
|
| 195 |
+
}
|
| 196 |
+
}
|
| 197 |
+
|
| 198 |
+
void Scores::CreateFromString(const std::string &str,
|
| 199 |
+
const FeatureFunction &featureFunction, const System &system,
|
| 200 |
+
bool transformScores)
|
| 201 |
+
{
|
| 202 |
+
vector<SCORE> scores = Tokenize<SCORE>(str);
|
| 203 |
+
if (transformScores) {
|
| 204 |
+
std::transform(scores.begin(), scores.end(), scores.begin(),
|
| 205 |
+
TransformScore);
|
| 206 |
+
std::transform(scores.begin(), scores.end(), scores.begin(), FloorScore);
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
/*
|
| 210 |
+
std::copy(scores.begin(),scores.end(),
|
| 211 |
+
std::ostream_iterator<SCORE>(cerr," "));
|
| 212 |
+
*/
|
| 213 |
+
|
| 214 |
+
PlusEquals(system, featureFunction, scores);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
std::string Scores::Debug(const System &system) const
|
| 218 |
+
{
|
| 219 |
+
stringstream out;
|
| 220 |
+
out << "total=" << m_total;
|
| 221 |
+
|
| 222 |
+
if (system.options.nbest.nbest_size) {
|
| 223 |
+
out << ", ";
|
| 224 |
+
BOOST_FOREACH(const FeatureFunction *ff, system.featureFunctions.GetFeatureFunctions()) {
|
| 225 |
+
out << ff->GetName() << "= ";
|
| 226 |
+
for (size_t i = ff->GetStartInd(); i < (ff->GetStartInd() + ff->GetNumScores()); ++i) {
|
| 227 |
+
out << m_scores[i] << " ";
|
| 228 |
+
}
|
| 229 |
+
}
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
return out.str();
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
void Scores::OutputBreakdown(std::ostream &out, const System &system) const
|
| 236 |
+
{
|
| 237 |
+
if (system.options.nbest.nbest_size) {
|
| 238 |
+
BOOST_FOREACH(const FeatureFunction *ff, system.featureFunctions.GetFeatureFunctions()) {
|
| 239 |
+
if (ff->IsTuneable()) {
|
| 240 |
+
out << ff->GetName() << "= ";
|
| 241 |
+
for (size_t i = ff->GetStartInd(); i < (ff->GetStartInd() + ff->GetNumScores()); ++i) {
|
| 242 |
+
out << m_scores[i] << " ";
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
}
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
// static functions to work out estimated scores
|
| 250 |
+
SCORE Scores::CalcWeightedScore(const System &system,
|
| 251 |
+
const FeatureFunction &featureFunction, SCORE scores[])
|
| 252 |
+
{
|
| 253 |
+
SCORE ret = 0;
|
| 254 |
+
|
| 255 |
+
const Weights &weights = system.weights;
|
| 256 |
+
|
| 257 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 258 |
+
for (size_t i = 0; i < featureFunction.GetNumScores(); ++i) {
|
| 259 |
+
SCORE incrScore = scores[i];
|
| 260 |
+
|
| 261 |
+
//cerr << "ffStartInd=" << ffStartInd << " " << i << endl;
|
| 262 |
+
SCORE weight = weights[ffStartInd + i];
|
| 263 |
+
ret += incrScore * weight;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
return ret;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
SCORE Scores::CalcWeightedScore(const System &system,
|
| 270 |
+
const FeatureFunction &featureFunction, SCORE score)
|
| 271 |
+
{
|
| 272 |
+
const Weights &weights = system.weights;
|
| 273 |
+
assert(featureFunction.GetNumScores() == 1);
|
| 274 |
+
|
| 275 |
+
size_t ffStartInd = featureFunction.GetStartInd();
|
| 276 |
+
SCORE weight = weights[ffStartInd];
|
| 277 |
+
SCORE ret = score * weight;
|
| 278 |
+
|
| 279 |
+
return ret;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
}
|
| 283 |
+
|
mosesdecoder/moses2/System.cpp
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* System.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include <string>
|
| 8 |
+
#include <iostream>
|
| 9 |
+
#include <boost/foreach.hpp>
|
| 10 |
+
#include <boost/thread.hpp>
|
| 11 |
+
#include <boost/thread/mutex.hpp>
|
| 12 |
+
#include "System.h"
|
| 13 |
+
#include "FF/FeatureFunction.h"
|
| 14 |
+
#include "TranslationModel/UnknownWordPenalty.h"
|
| 15 |
+
#include "legacy/Util2.h"
|
| 16 |
+
#include "util/exception.hh"
|
| 17 |
+
|
| 18 |
+
using namespace std;
|
| 19 |
+
|
| 20 |
+
namespace Moses2
|
| 21 |
+
{
|
| 22 |
+
#ifndef WIN32
|
| 23 |
+
thread_local MemPool System::m_managerPool;
|
| 24 |
+
thread_local MemPool System::m_systemPool;
|
| 25 |
+
thread_local Recycler<HypothesisBase*> System::m_hypoRecycler;
|
| 26 |
+
#endif // WIN32
|
| 27 |
+
|
| 28 |
+
System::System(const Parameter ¶msArg) :
|
| 29 |
+
params(paramsArg), featureFunctions(*this)
|
| 30 |
+
{
|
| 31 |
+
options.init(paramsArg);
|
| 32 |
+
IsPb();
|
| 33 |
+
|
| 34 |
+
bestCollector.reset(new OutputCollector());
|
| 35 |
+
|
| 36 |
+
params.SetParameter(cpuAffinityOffset, "cpu-affinity-offset", -1);
|
| 37 |
+
params.SetParameter(cpuAffinityOffsetIncr, "cpu-affinity-increment", 1);
|
| 38 |
+
|
| 39 |
+
const PARAM_VEC *section;
|
| 40 |
+
|
| 41 |
+
// output collectors
|
| 42 |
+
if (options.nbest.nbest_size && options.nbest.output_file_path != "-") {
|
| 43 |
+
nbestCollector.reset(new OutputCollector(options.nbest.output_file_path));
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
if (!options.output.detailed_transrep_filepath.empty()) {
|
| 47 |
+
detailedTranslationCollector.reset(new OutputCollector(options.output.detailed_transrep_filepath));
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
featureFunctions.Create();
|
| 51 |
+
LoadWeights();
|
| 52 |
+
|
| 53 |
+
if (params.GetParam("show-weights")) {
|
| 54 |
+
cerr << "Showing weights then exit" << endl;
|
| 55 |
+
featureFunctions.ShowWeights(weights);
|
| 56 |
+
//return;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
cerr << "START featureFunctions.Load()" << endl;
|
| 60 |
+
featureFunctions.Load();
|
| 61 |
+
cerr << "START LoadMappings()" << endl;
|
| 62 |
+
LoadMappings();
|
| 63 |
+
cerr << "END LoadMappings()" << endl;
|
| 64 |
+
LoadDecodeGraphBackoff();
|
| 65 |
+
cerr << "END LoadDecodeGraphBackoff()" << endl;
|
| 66 |
+
|
| 67 |
+
UTIL_THROW_IF2(options.input.xml_policy == XmlConstraint, "XmlConstraint not supported");
|
| 68 |
+
|
| 69 |
+
// max spans for scfg decoding
|
| 70 |
+
if (!isPb) {
|
| 71 |
+
section = params.GetParam("max-chart-span");
|
| 72 |
+
if (section && section->size()) {
|
| 73 |
+
maxChartSpans = Scan<size_t>(*section);
|
| 74 |
+
maxChartSpans.resize(mappings.size(), DEFAULT_MAX_CHART_SPAN);
|
| 75 |
+
|
| 76 |
+
/*
|
| 77 |
+
cerr << "maxChartSpans=" << maxChartSpans.size();
|
| 78 |
+
for (size_t i = 0; i < maxChartSpans.size(); ++i) {
|
| 79 |
+
cerr << " " << mappings[i]->GetName() << "=" << maxChartSpans[i];
|
| 80 |
+
}
|
| 81 |
+
cerr << endl;
|
| 82 |
+
*/
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
System::~System()
|
| 89 |
+
{
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
void System::LoadWeights()
|
| 93 |
+
{
|
| 94 |
+
weights.Init(featureFunctions);
|
| 95 |
+
|
| 96 |
+
//cerr << "Weights:" << endl;
|
| 97 |
+
typedef std::map<std::string, std::vector<float> > WeightMap;
|
| 98 |
+
const WeightMap &allWeights = params.GetAllWeights();
|
| 99 |
+
|
| 100 |
+
// check all weights are there for all FF
|
| 101 |
+
const std::vector<FeatureFunction*> &ffs = featureFunctions.GetFeatureFunctions();
|
| 102 |
+
BOOST_FOREACH(const FeatureFunction *ff, ffs) {
|
| 103 |
+
if (ff->IsTuneable()) {
|
| 104 |
+
const std::string &ffName = ff->GetName();
|
| 105 |
+
WeightMap::const_iterator iterWeight = allWeights.find(ffName);
|
| 106 |
+
UTIL_THROW_IF2(iterWeight == allWeights.end(), "Must specify weight for " << ffName);
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
// set weight
|
| 112 |
+
BOOST_FOREACH(const WeightMap::value_type &valPair, allWeights) {
|
| 113 |
+
const string &ffName = valPair.first;
|
| 114 |
+
const std::vector<float> &ffWeights = valPair.second;
|
| 115 |
+
/*
|
| 116 |
+
cerr << ffName << "=";
|
| 117 |
+
for (size_t i = 0; i < ffWeights.size(); ++i) {
|
| 118 |
+
cerr << ffWeights[i] << " ";
|
| 119 |
+
}
|
| 120 |
+
cerr << endl;
|
| 121 |
+
*/
|
| 122 |
+
weights.SetWeights(featureFunctions, ffName, ffWeights);
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
void System::LoadMappings()
|
| 127 |
+
{
|
| 128 |
+
const PARAM_VEC *vec = params.GetParam("mapping");
|
| 129 |
+
UTIL_THROW_IF2(vec == NULL, "Must have [mapping] section");
|
| 130 |
+
|
| 131 |
+
BOOST_FOREACH(const std::string &line, *vec) {
|
| 132 |
+
vector<string> toks = Tokenize(line);
|
| 133 |
+
assert( (toks.size() == 2 && toks[0] == "T") || (toks.size() == 3 && toks[1] == "T") );
|
| 134 |
+
|
| 135 |
+
size_t ptInd;
|
| 136 |
+
if (toks.size() == 2) {
|
| 137 |
+
ptInd = Scan<size_t>(toks[1]);
|
| 138 |
+
} else {
|
| 139 |
+
ptInd = Scan<size_t>(toks[2]);
|
| 140 |
+
}
|
| 141 |
+
const PhraseTable *pt = featureFunctions.GetPhraseTableExcludeUnknownWordPenalty(ptInd);
|
| 142 |
+
mappings.push_back(pt);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
// unk pt
|
| 146 |
+
const UnknownWordPenalty *unkWP = featureFunctions.GetUnknownWordPenalty();
|
| 147 |
+
if (unkWP) {
|
| 148 |
+
mappings.push_back(unkWP);
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
void System::LoadDecodeGraphBackoff()
|
| 153 |
+
{
|
| 154 |
+
const PARAM_VEC *vec = params.GetParam("decoding-graph-backoff");
|
| 155 |
+
|
| 156 |
+
for (size_t i = 0; i < mappings.size(); ++i) {
|
| 157 |
+
PhraseTable *pt = const_cast<PhraseTable*>(mappings[i]);
|
| 158 |
+
|
| 159 |
+
if (vec && vec->size() < i) {
|
| 160 |
+
pt->decodeGraphBackoff = Scan<int>((*vec)[i]);
|
| 161 |
+
} else if (pt == featureFunctions.GetUnknownWordPenalty()) {
|
| 162 |
+
pt->decodeGraphBackoff = 1;
|
| 163 |
+
} else {
|
| 164 |
+
pt->decodeGraphBackoff = 0;
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
void System::IsPb()
|
| 170 |
+
{
|
| 171 |
+
switch (options.search.algo) {
|
| 172 |
+
case Normal:
|
| 173 |
+
case NormalBatch:
|
| 174 |
+
case CubePruning:
|
| 175 |
+
case CubePruningPerMiniStack:
|
| 176 |
+
case CubePruningPerBitmap:
|
| 177 |
+
case CubePruningCardinalStack:
|
| 178 |
+
case CubePruningBitmapStack:
|
| 179 |
+
case CubePruningMiniStack:
|
| 180 |
+
isPb = true;
|
| 181 |
+
break;
|
| 182 |
+
case CYKPlus:
|
| 183 |
+
isPb = false;
|
| 184 |
+
break;
|
| 185 |
+
default:
|
| 186 |
+
throw std::runtime_error("Unknown search algorithm " + options.search.algo);
|
| 187 |
+
break;
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
FactorCollection& System::GetVocab() const
|
| 192 |
+
{
|
| 193 |
+
return m_vocab;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
//////////////////////////////////////////////////////
|
| 197 |
+
// thread local stuff
|
| 198 |
+
Batch& System::GetBatch(MemPool& pool) const
|
| 199 |
+
{
|
| 200 |
+
Batch* obj;
|
| 201 |
+
obj = m_batch.get();
|
| 202 |
+
if (obj == NULL) {
|
| 203 |
+
obj = new Batch(pool);
|
| 204 |
+
m_batch.reset(obj);
|
| 205 |
+
}
|
| 206 |
+
assert(obj);
|
| 207 |
+
return *obj;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
#ifdef WIN32
|
| 211 |
+
template<class C>
|
| 212 |
+
C& GetThreadSpecificObj(boost::thread_specific_ptr<C> &threadSpecificPtr)
|
| 213 |
+
{
|
| 214 |
+
C* obj;
|
| 215 |
+
obj = threadSpecificPtr.get();
|
| 216 |
+
if (obj == NULL) {
|
| 217 |
+
obj = new C();
|
| 218 |
+
threadSpecificPtr.reset(obj);
|
| 219 |
+
}
|
| 220 |
+
assert(obj);
|
| 221 |
+
return *obj;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
MemPool& System::GetManagerPool() const
|
| 225 |
+
{
|
| 226 |
+
MemPool &obj = GetThreadSpecificObj<MemPool>(m_managerPool);
|
| 227 |
+
return obj;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
MemPool& System::GetSystemPool() const
|
| 231 |
+
{
|
| 232 |
+
MemPool& obj = GetThreadSpecificObj<MemPool>(m_systemPool);
|
| 233 |
+
return obj;
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
Recycler<HypothesisBase*>& System::GetHypoRecycler() const
|
| 237 |
+
{
|
| 238 |
+
Recycler<HypothesisBase*>& obj = GetThreadSpecificObj<Recycler<HypothesisBase*> >(m_hypoRecycler);
|
| 239 |
+
return obj;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
#else
|
| 243 |
+
MemPool& System::GetManagerPool() const
|
| 244 |
+
{
|
| 245 |
+
return m_managerPool;
|
| 246 |
+
}
|
| 247 |
+
|
| 248 |
+
MemPool& System::GetSystemPool() const
|
| 249 |
+
{
|
| 250 |
+
return m_systemPool;
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
Recycler<HypothesisBase*>& System::GetHypoRecycler() const
|
| 254 |
+
{
|
| 255 |
+
return m_hypoRecycler;
|
| 256 |
+
}
|
| 257 |
+
|
| 258 |
+
#endif
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
}
|
| 262 |
+
|
mosesdecoder/moses2/System.h
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* System.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
#include <vector>
|
| 10 |
+
#include <deque>
|
| 11 |
+
#include <boost/thread/tss.hpp>
|
| 12 |
+
#include <boost/pool/object_pool.hpp>
|
| 13 |
+
#include <boost/shared_ptr.hpp>
|
| 14 |
+
#include "FF/FeatureFunctions.h"
|
| 15 |
+
#include "Weights.h"
|
| 16 |
+
#include "MemPool.h"
|
| 17 |
+
#include "Recycler.h"
|
| 18 |
+
#include "legacy/FactorCollection.h"
|
| 19 |
+
#include "legacy/Parameter.h"
|
| 20 |
+
#include "TypeDef.h"
|
| 21 |
+
#include "legacy/Bitmaps.h"
|
| 22 |
+
#include "legacy/OutputCollector.h"
|
| 23 |
+
#include "parameters/AllOptions.h"
|
| 24 |
+
|
| 25 |
+
namespace Moses2
|
| 26 |
+
{
|
| 27 |
+
namespace NSCubePruning
|
| 28 |
+
{
|
| 29 |
+
class Stack;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
class FeatureFunction;
|
| 33 |
+
class StatefulFeatureFunction;
|
| 34 |
+
class PhraseTable;
|
| 35 |
+
class HypothesisBase;
|
| 36 |
+
|
| 37 |
+
class System
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
const Parameter ¶ms;
|
| 41 |
+
AllOptions options;
|
| 42 |
+
FeatureFunctions featureFunctions;
|
| 43 |
+
Weights weights;
|
| 44 |
+
std::vector<const PhraseTable*> mappings;
|
| 45 |
+
|
| 46 |
+
std::vector<size_t> maxChartSpans;
|
| 47 |
+
bool isPb;
|
| 48 |
+
|
| 49 |
+
mutable boost::shared_ptr<OutputCollector> bestCollector, nbestCollector, detailedTranslationCollector;
|
| 50 |
+
|
| 51 |
+
// moses.ini params
|
| 52 |
+
int cpuAffinityOffset;
|
| 53 |
+
int cpuAffinityOffsetIncr;
|
| 54 |
+
|
| 55 |
+
System(const Parameter ¶msArg);
|
| 56 |
+
virtual ~System();
|
| 57 |
+
|
| 58 |
+
MemPool &GetSystemPool() const;
|
| 59 |
+
MemPool &GetManagerPool() const;
|
| 60 |
+
FactorCollection &GetVocab() const;
|
| 61 |
+
|
| 62 |
+
Recycler<HypothesisBase*> &GetHypoRecycler() const;
|
| 63 |
+
|
| 64 |
+
Batch &GetBatch(MemPool &pool) const;
|
| 65 |
+
|
| 66 |
+
protected:
|
| 67 |
+
mutable FactorCollection m_vocab;
|
| 68 |
+
|
| 69 |
+
mutable boost::thread_specific_ptr<Batch> m_batch;
|
| 70 |
+
|
| 71 |
+
#ifdef WIN32
|
| 72 |
+
mutable boost::thread_specific_ptr<MemPool> m_managerPool;
|
| 73 |
+
mutable boost::thread_specific_ptr<MemPool> m_systemPool;
|
| 74 |
+
mutable boost::thread_specific_ptr <Recycler<HypothesisBase*> > m_hypoRecycler;
|
| 75 |
+
#else
|
| 76 |
+
thread_local static MemPool m_managerPool;
|
| 77 |
+
thread_local static MemPool m_systemPool;
|
| 78 |
+
thread_local static Recycler<HypothesisBase*> m_hypoRecycler;
|
| 79 |
+
#endif
|
| 80 |
+
|
| 81 |
+
void LoadWeights();
|
| 82 |
+
void LoadMappings();
|
| 83 |
+
void LoadDecodeGraphBackoff();
|
| 84 |
+
|
| 85 |
+
void IsPb();
|
| 86 |
+
|
| 87 |
+
};
|
| 88 |
+
|
| 89 |
+
}
|
| 90 |
+
|
mosesdecoder/moses2/TargetPhrase.h
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* TargetPhrase.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 26 Apr 2016
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
#include <sstream>
|
| 10 |
+
#include "PhraseImplTemplate.h"
|
| 11 |
+
#include "System.h"
|
| 12 |
+
#include "Scores.h"
|
| 13 |
+
#include "AlignmentInfoCollection.h"
|
| 14 |
+
#include "TranslationModel/PhraseTable.h"
|
| 15 |
+
|
| 16 |
+
namespace Moses2
|
| 17 |
+
{
|
| 18 |
+
class AlignmentInfo;
|
| 19 |
+
|
| 20 |
+
template<typename WORD>
|
| 21 |
+
class TargetPhrase: public PhraseImplTemplate<WORD>
|
| 22 |
+
{
|
| 23 |
+
public:
|
| 24 |
+
typedef PhraseImplTemplate<WORD> Parent;
|
| 25 |
+
const PhraseTable &pt;
|
| 26 |
+
mutable void **ffData;
|
| 27 |
+
SCORE *scoreProperties;
|
| 28 |
+
|
| 29 |
+
TargetPhrase(MemPool &pool, const PhraseTable &pt, const System &system, size_t size)
|
| 30 |
+
: PhraseImplTemplate<WORD>(pool, size)
|
| 31 |
+
, pt(pt)
|
| 32 |
+
, scoreProperties(NULL)
|
| 33 |
+
, m_alignTerm(&AlignmentInfoCollection::Instance().GetEmptyAlignmentInfo()) {
|
| 34 |
+
m_scores = new (pool.Allocate<Scores>()) Scores(system, pool,
|
| 35 |
+
system.featureFunctions.GetNumScores());
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
Scores &GetScores() {
|
| 39 |
+
return *m_scores;
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
const Scores &GetScores() const {
|
| 43 |
+
return *m_scores;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
virtual SCORE GetScoreForPruning() const = 0;
|
| 47 |
+
|
| 48 |
+
SCORE *GetScoresProperty(int propertyInd) const {
|
| 49 |
+
return scoreProperties ? scoreProperties + propertyInd : NULL;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
const AlignmentInfo &GetAlignTerm() const {
|
| 53 |
+
return *m_alignTerm;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
void SetAlignTerm(const AlignmentInfo &alignInfo) {
|
| 57 |
+
m_alignTerm = &alignInfo;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
// ALNREP = alignment representation,
|
| 61 |
+
// see AlignmentInfo constructors for supported representations
|
| 62 |
+
template<typename ALNREP>
|
| 63 |
+
void
|
| 64 |
+
SetAlignTerm(const ALNREP &coll) {
|
| 65 |
+
m_alignTerm = AlignmentInfoCollection::Instance().Add(coll);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
virtual void SetAlignmentInfo(const std::string &alignString) {
|
| 69 |
+
AlignmentInfo::CollType alignTerm;
|
| 70 |
+
|
| 71 |
+
std::vector<std::string> toks = Tokenize(alignString);
|
| 72 |
+
for (size_t i = 0; i < toks.size(); ++i) {
|
| 73 |
+
std::vector<size_t> alignPair = Tokenize<size_t>(toks[i], "-");
|
| 74 |
+
UTIL_THROW_IF2(alignPair.size() != 2, "Wrong alignment format");
|
| 75 |
+
|
| 76 |
+
size_t sourcePos = alignPair[0];
|
| 77 |
+
size_t targetPos = alignPair[1];
|
| 78 |
+
|
| 79 |
+
alignTerm.insert(std::pair<size_t,size_t>(sourcePos, targetPos));
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
SetAlignTerm(alignTerm);
|
| 83 |
+
// cerr << "TargetPhrase::SetAlignmentInfo(const StringPiece &alignString) this:|" << *this << "|\n";
|
| 84 |
+
|
| 85 |
+
//cerr << "alignTerm=" << alignTerm.size() << endl;
|
| 86 |
+
//cerr << "alignNonTerm=" << alignNonTerm.size() << endl;
|
| 87 |
+
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
void OutputToStream(const System &system, const Phrase<WORD> &inputPhrase, std::ostream &out) const {
|
| 91 |
+
// get placeholders
|
| 92 |
+
FactorType placeholderFactor = system.options.input.placeholder_factor;
|
| 93 |
+
std::map<size_t, const Factor*> placeholders;
|
| 94 |
+
if (placeholderFactor != NOT_FOUND) {
|
| 95 |
+
// creates map of target position -> factor for placeholders
|
| 96 |
+
placeholders = GetPlaceholders(system, inputPhrase);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
size_t size = PhraseImplTemplate<WORD>::GetSize();
|
| 100 |
+
for (size_t i = 0; i < size; ++i) {
|
| 101 |
+
// output placeholder, if any
|
| 102 |
+
std::map<size_t, const Factor*>::const_iterator iter = placeholders.find(i);
|
| 103 |
+
if (iter == placeholders.end()) {
|
| 104 |
+
const WORD &word = (*this)[i];
|
| 105 |
+
word.OutputToStream(system, out);
|
| 106 |
+
} else {
|
| 107 |
+
const Factor *factor = iter->second;
|
| 108 |
+
out << *factor;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
out << " ";
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
std::map<size_t, const Factor*> GetPlaceholders(const System &system, const Phrase<WORD> &inputPhrase) const {
|
| 116 |
+
FactorType placeholderFactor = system.options.input.placeholder_factor;
|
| 117 |
+
std::map<size_t, const Factor*> ret;
|
| 118 |
+
//std::cerr << "inputPhrase=" << inputPhrase.Debug(system) << std::endl;
|
| 119 |
+
|
| 120 |
+
for (size_t sourcePos = 0; sourcePos < inputPhrase.GetSize(); ++sourcePos) {
|
| 121 |
+
const Factor *factor = inputPhrase[sourcePos][placeholderFactor];
|
| 122 |
+
if (factor) {
|
| 123 |
+
//std::cerr << "factor=" << *factor << std::endl;
|
| 124 |
+
//std::cerr << "tp=" << Debug(system) << std::endl;
|
| 125 |
+
std::set<size_t> targetPos = GetAlignTerm().GetAlignmentsForSource(sourcePos);
|
| 126 |
+
UTIL_THROW_IF2(targetPos.size() != 1,
|
| 127 |
+
"Placeholder should be aligned to 1, and only 1, word:" << targetPos.size() << "!=1");
|
| 128 |
+
ret[*targetPos.begin()] = factor;
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
return ret;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
virtual std::string Debug(const System &system) const {
|
| 136 |
+
std::stringstream out;
|
| 137 |
+
out << Phrase<WORD>::Debug(system);
|
| 138 |
+
out << " pt=" << pt.GetName() << " ";
|
| 139 |
+
out << " SCORES:" << GetScores().Debug(system);
|
| 140 |
+
out << " ALIGN-T:";
|
| 141 |
+
out << GetAlignTerm().Debug(system);
|
| 142 |
+
|
| 143 |
+
return out.str();
|
| 144 |
+
}
|
| 145 |
+
|
| 146 |
+
protected:
|
| 147 |
+
Scores *m_scores;
|
| 148 |
+
const AlignmentInfo *m_alignTerm;
|
| 149 |
+
};
|
| 150 |
+
|
| 151 |
+
///////////////////////////////////////////////////////////////////////
|
| 152 |
+
template<typename TP>
|
| 153 |
+
struct CompareScoreForPruning {
|
| 154 |
+
bool operator()(const TP *a, const TP *b) const {
|
| 155 |
+
return a->GetScoreForPruning() > b->GetScoreForPruning();
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
bool operator()(const TP &a, const TP &b) const {
|
| 159 |
+
return a.GetScoreForPruning() > b.GetScoreForPruning();
|
| 160 |
+
}
|
| 161 |
+
};
|
| 162 |
+
|
| 163 |
+
} /* namespace Moses2a */
|
| 164 |
+
|
mosesdecoder/moses2/TrellisPaths.cpp
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* TrellisPaths.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 16 Mar 2016
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include "TrellisPaths.h"
|
| 8 |
+
#include "legacy/Util2.h"
|
| 9 |
+
|
| 10 |
+
namespace Moses2
|
| 11 |
+
{
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
} /* namespace Moses2 */
|
mosesdecoder/moses2/TypeDef.cpp
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "TypeDef.h"
|
| 2 |
+
#include "util/exception.hh"
|
| 3 |
+
#include <typeinfo>
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
namespace Moses2
|
| 7 |
+
{
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
}
|
mosesdecoder/moses2/Word.h
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Word.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 23 Oct 2015
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
|
| 10 |
+
#include <iostream>
|
| 11 |
+
#include "TypeDef.h"
|
| 12 |
+
#include "legacy/Factor.h"
|
| 13 |
+
#include "legacy/FactorCollection.h"
|
| 14 |
+
|
| 15 |
+
namespace Moses2
|
| 16 |
+
{
|
| 17 |
+
|
| 18 |
+
class Word
|
| 19 |
+
{
|
| 20 |
+
public:
|
| 21 |
+
explicit Word();
|
| 22 |
+
Word(const Word ©);
|
| 23 |
+
|
| 24 |
+
virtual ~Word();
|
| 25 |
+
|
| 26 |
+
void CreateFromString(FactorCollection &vocab, const System &system,
|
| 27 |
+
const std::string &str);
|
| 28 |
+
|
| 29 |
+
virtual size_t hash() const;
|
| 30 |
+
virtual size_t hash(const std::vector<FactorType> &factors) const;
|
| 31 |
+
|
| 32 |
+
int Compare(const Word &compare) const;
|
| 33 |
+
|
| 34 |
+
virtual bool operator==(const Word &compare) const {
|
| 35 |
+
int cmp = Compare(compare);
|
| 36 |
+
return cmp == 0;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
virtual bool operator!=(const Word &compare) const {
|
| 40 |
+
return !((*this) == compare);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
virtual bool operator<(const Word &compare) const;
|
| 44 |
+
|
| 45 |
+
const Factor* operator[](size_t ind) const {
|
| 46 |
+
return m_factors[ind];
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
const Factor*& operator[](size_t ind) {
|
| 50 |
+
return m_factors[ind];
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
virtual void OutputToStream(const System &system, std::ostream &out) const;
|
| 54 |
+
virtual std::string Debug(const System &system) const;
|
| 55 |
+
|
| 56 |
+
std::string GetString(const FactorList &factorTypes) const;
|
| 57 |
+
protected:
|
| 58 |
+
const Factor *m_factors[MAX_NUM_FACTORS];
|
| 59 |
+
|
| 60 |
+
};
|
| 61 |
+
|
| 62 |
+
}
|
| 63 |
+
|
mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.cpp
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "AlignmentGraph.h"
|
| 21 |
+
|
| 22 |
+
#include <algorithm>
|
| 23 |
+
#include <cassert>
|
| 24 |
+
#include <cstdlib>
|
| 25 |
+
#include <memory>
|
| 26 |
+
#include <stack>
|
| 27 |
+
|
| 28 |
+
#include "SyntaxTree.h"
|
| 29 |
+
|
| 30 |
+
#include "ComposedRule.h"
|
| 31 |
+
#include "Node.h"
|
| 32 |
+
#include "Options.h"
|
| 33 |
+
#include "Subgraph.h"
|
| 34 |
+
|
| 35 |
+
namespace MosesTraining
|
| 36 |
+
{
|
| 37 |
+
namespace Syntax
|
| 38 |
+
{
|
| 39 |
+
namespace GHKM
|
| 40 |
+
{
|
| 41 |
+
|
| 42 |
+
AlignmentGraph::AlignmentGraph(const SyntaxTree *t,
|
| 43 |
+
const std::vector<std::string> &s,
|
| 44 |
+
const Alignment &a)
|
| 45 |
+
{
|
| 46 |
+
// Copy the parse tree nodes and add them to m_targetNodes.
|
| 47 |
+
m_root = CopyParseTree(t);
|
| 48 |
+
|
| 49 |
+
// Create a node for each source word.
|
| 50 |
+
m_sourceNodes.reserve(s.size());
|
| 51 |
+
for (std::vector<std::string>::const_iterator p(s.begin());
|
| 52 |
+
p != s.end(); ++p) {
|
| 53 |
+
m_sourceNodes.push_back(new Node(*p, SOURCE));
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// Connect source nodes to parse tree leaves according to the given word
|
| 57 |
+
// alignment.
|
| 58 |
+
std::vector<Node *> targetTreeLeaves;
|
| 59 |
+
GetTargetTreeLeaves(m_root, targetTreeLeaves);
|
| 60 |
+
for (Alignment::const_iterator p(a.begin()); p != a.end(); ++p) {
|
| 61 |
+
Node *src = m_sourceNodes[p->first];
|
| 62 |
+
Node *tgt = targetTreeLeaves[p->second];
|
| 63 |
+
src->AddParent(tgt);
|
| 64 |
+
tgt->AddChild(src);
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
// Attach unaligned source words (if any).
|
| 68 |
+
AttachUnalignedSourceWords();
|
| 69 |
+
|
| 70 |
+
// Populate node spans.
|
| 71 |
+
std::vector<Node *>::const_iterator p(m_sourceNodes.begin());
|
| 72 |
+
for (int i = 0; p != m_sourceNodes.end(); ++p, ++i) {
|
| 73 |
+
(*p)->PropagateIndex(i);
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
// Calculate complement spans.
|
| 77 |
+
CalcComplementSpans(m_root);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
AlignmentGraph::~AlignmentGraph()
|
| 81 |
+
{
|
| 82 |
+
for (std::vector<Node *>::iterator p(m_sourceNodes.begin());
|
| 83 |
+
p != m_sourceNodes.end(); ++p) {
|
| 84 |
+
delete *p;
|
| 85 |
+
}
|
| 86 |
+
for (std::vector<Node *>::iterator p(m_targetNodes.begin());
|
| 87 |
+
p != m_targetNodes.end(); ++p) {
|
| 88 |
+
delete *p;
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
Subgraph AlignmentGraph::ComputeMinimalFrontierGraphFragment(
|
| 93 |
+
Node *root,
|
| 94 |
+
const std::set<Node *> &frontierSet)
|
| 95 |
+
{
|
| 96 |
+
std::stack<Node *> expandableNodes;
|
| 97 |
+
std::set<const Node *> expandedNodes;
|
| 98 |
+
|
| 99 |
+
if (root->IsSink()) {
|
| 100 |
+
expandedNodes.insert(root);
|
| 101 |
+
} else {
|
| 102 |
+
expandableNodes.push(root);
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
while (!expandableNodes.empty()) {
|
| 106 |
+
Node *n = expandableNodes.top();
|
| 107 |
+
expandableNodes.pop();
|
| 108 |
+
|
| 109 |
+
const std::vector<Node *> &children = n->GetChildren();
|
| 110 |
+
|
| 111 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 112 |
+
p != children.end(); ++p) {
|
| 113 |
+
Node *child = *p;
|
| 114 |
+
if (child->IsSink()) {
|
| 115 |
+
expandedNodes.insert(child);
|
| 116 |
+
continue;
|
| 117 |
+
}
|
| 118 |
+
std::set<Node *>::const_iterator q = frontierSet.find(child);
|
| 119 |
+
if (q == frontierSet.end()) { //child is not from the frontier set
|
| 120 |
+
expandableNodes.push(child);
|
| 121 |
+
} else if (child->GetType() == TARGET) { // still need source word
|
| 122 |
+
expandableNodes.push(child);
|
| 123 |
+
} else {
|
| 124 |
+
expandedNodes.insert(child);
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
return Subgraph(root, expandedNodes);
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
void AlignmentGraph::ExtractMinimalRules(const Options &options)
|
| 133 |
+
{
|
| 134 |
+
// Determine which nodes are frontier nodes.
|
| 135 |
+
std::set<Node *> frontierSet;
|
| 136 |
+
ComputeFrontierSet(m_root, options, frontierSet);
|
| 137 |
+
|
| 138 |
+
// Form the minimal frontier graph fragment rooted at each frontier node.
|
| 139 |
+
std::vector<Subgraph> fragments;
|
| 140 |
+
fragments.reserve(frontierSet.size());
|
| 141 |
+
for (std::set<Node *>::iterator p(frontierSet.begin());
|
| 142 |
+
p != frontierSet.end(); ++p) {
|
| 143 |
+
Node *root = *p;
|
| 144 |
+
Subgraph fragment = ComputeMinimalFrontierGraphFragment(root, frontierSet);
|
| 145 |
+
assert(!fragment.IsTrivial());
|
| 146 |
+
// Can it form an SCFG rule?
|
| 147 |
+
// FIXME Does this exclude non-lexical unary rules?
|
| 148 |
+
if (root->GetType() == TREE && !root->GetSpan().empty()) {
|
| 149 |
+
root->AddRule(new Subgraph(fragment));
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
void AlignmentGraph::ExtractComposedRules(const Options &options)
|
| 155 |
+
{
|
| 156 |
+
ExtractComposedRules(m_root, options);
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
void AlignmentGraph::ExtractComposedRules(Node *node, const Options &options)
|
| 160 |
+
{
|
| 161 |
+
// Extract composed rules for all children first.
|
| 162 |
+
const std::vector<Node *> &children = node->GetChildren();
|
| 163 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 164 |
+
p != children.end(); ++p) {
|
| 165 |
+
ExtractComposedRules(*p, options);
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
// If there is no minimal rule for this node then there are no composed
|
| 169 |
+
// rules.
|
| 170 |
+
const std::vector<const Subgraph*> &rules = node->GetRules();
|
| 171 |
+
assert(rules.size() <= 1);
|
| 172 |
+
if (rules.empty()) {
|
| 173 |
+
return;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
// Construct an initial composition candidate from the minimal rule.
|
| 177 |
+
ComposedRule cr(*(rules[0]));
|
| 178 |
+
if (!cr.GetOpenAttachmentPoint()) {
|
| 179 |
+
// No composition possible.
|
| 180 |
+
return;
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
std::queue<ComposedRule> queue;
|
| 184 |
+
queue.push(cr);
|
| 185 |
+
while (!queue.empty()) {
|
| 186 |
+
ComposedRule cr = queue.front();
|
| 187 |
+
queue.pop();
|
| 188 |
+
const Node *attachmentPoint = cr.GetOpenAttachmentPoint();
|
| 189 |
+
assert(attachmentPoint);
|
| 190 |
+
assert(attachmentPoint != node);
|
| 191 |
+
// Create all possible rules by composing this node's minimal rule with the
|
| 192 |
+
// existing rules (both minimal and composed) rooted at the first open
|
| 193 |
+
// attachment point.
|
| 194 |
+
const std::vector<const Subgraph*> &rules = attachmentPoint->GetRules();
|
| 195 |
+
for (std::vector<const Subgraph*>::const_iterator p = rules.begin();
|
| 196 |
+
p != rules.end(); ++p) {
|
| 197 |
+
assert((*p)->GetRoot()->GetType() == TREE);
|
| 198 |
+
ComposedRule *cr2 = cr.AttemptComposition(**p, options);
|
| 199 |
+
if (cr2) {
|
| 200 |
+
node->AddRule(new Subgraph(cr2->CreateSubgraph()));
|
| 201 |
+
if (cr2->GetOpenAttachmentPoint()) {
|
| 202 |
+
queue.push(*cr2);
|
| 203 |
+
}
|
| 204 |
+
delete cr2;
|
| 205 |
+
}
|
| 206 |
+
}
|
| 207 |
+
// Done with this attachment point. Advance to the next, if any.
|
| 208 |
+
cr.CloseAttachmentPoint();
|
| 209 |
+
if (cr.GetOpenAttachmentPoint()) {
|
| 210 |
+
queue.push(cr);
|
| 211 |
+
}
|
| 212 |
+
}
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
Node *AlignmentGraph::CopyParseTree(const SyntaxTree *root)
|
| 216 |
+
{
|
| 217 |
+
NodeType nodeType = (root->IsLeaf()) ? TARGET : TREE;
|
| 218 |
+
|
| 219 |
+
std::auto_ptr<Node> n(new Node(root->value().label, nodeType));
|
| 220 |
+
|
| 221 |
+
if (nodeType == TREE) {
|
| 222 |
+
float score = 0.0f;
|
| 223 |
+
SyntaxNode::AttributeMap::const_iterator p =
|
| 224 |
+
root->value().attributes.find("pcfg");
|
| 225 |
+
if (p != root->value().attributes.end()) {
|
| 226 |
+
score = std::atof(p->second.c_str());
|
| 227 |
+
}
|
| 228 |
+
n->SetPcfgScore(score);
|
| 229 |
+
}
|
| 230 |
+
|
| 231 |
+
const std::vector<SyntaxTree *> &children = root->children();
|
| 232 |
+
std::vector<Node *> childNodes;
|
| 233 |
+
childNodes.reserve(children.size());
|
| 234 |
+
for (std::vector<SyntaxTree *>::const_iterator p(children.begin());
|
| 235 |
+
p != children.end(); ++p) {
|
| 236 |
+
Node *child = CopyParseTree(*p);
|
| 237 |
+
child->AddParent(n.get());
|
| 238 |
+
childNodes.push_back(child);
|
| 239 |
+
}
|
| 240 |
+
n->SetChildren(childNodes);
|
| 241 |
+
|
| 242 |
+
Node *p = n.release();
|
| 243 |
+
m_targetNodes.push_back(p);
|
| 244 |
+
return p;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
// Recursively constructs the set of frontier nodes for the tree (or subtree)
|
| 248 |
+
// rooted at the given node.
|
| 249 |
+
void AlignmentGraph::ComputeFrontierSet(Node *root,
|
| 250 |
+
const Options &options,
|
| 251 |
+
std::set<Node *> &frontierSet) const
|
| 252 |
+
{
|
| 253 |
+
// Non-tree nodes and unaligned target subtrees are not frontier nodes (and
|
| 254 |
+
// nor are their descendants). See the comment for the function
|
| 255 |
+
// AlignmentGraph::IsFrontierNode().
|
| 256 |
+
if (root->GetType() != TREE || root->GetSpan().empty()) {
|
| 257 |
+
return;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
if (IsFrontierNode(*root, options)) {
|
| 261 |
+
frontierSet.insert(root);
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
// Recursively check descendants.
|
| 265 |
+
const std::vector<Node *> &children = root->GetChildren();
|
| 266 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 267 |
+
p != children.end(); ++p) {
|
| 268 |
+
ComputeFrontierSet(*p, options, frontierSet);
|
| 269 |
+
}
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
// Determines whether the given node is a frontier node or not. The definition
|
| 273 |
+
// of a frontier node differs from Galley et al's (2004) in the following ways:
|
| 274 |
+
//
|
| 275 |
+
// 1. A node with an empty span is not a frontier node (this is to exclude
|
| 276 |
+
// unaligned target subtrees).
|
| 277 |
+
// 2. Target word nodes are not frontier nodes.
|
| 278 |
+
// 3. Source word nodes are not frontier nodes.
|
| 279 |
+
// 4. Unless the --AllowUnary option is used, a node is not a frontier node if
|
| 280 |
+
// it has the same span as its parent.
|
| 281 |
+
bool AlignmentGraph::IsFrontierNode(const Node &n, const Options &options) const
|
| 282 |
+
{
|
| 283 |
+
// Don't include word nodes or unaligned target subtrees.
|
| 284 |
+
if (n.GetType() != TREE || n.GetSpan().empty()) {
|
| 285 |
+
return false;
|
| 286 |
+
}
|
| 287 |
+
// This is the original GHKM definition of a frontier node.
|
| 288 |
+
if (SpansIntersect(n.GetComplementSpan(), Closure(n.GetSpan()))) {
|
| 289 |
+
return false;
|
| 290 |
+
}
|
| 291 |
+
// Unless unary rules are explicitly allowed, we use Chung et al's (2011)
|
| 292 |
+
// modified defintion of a frontier node to eliminate the production of
|
| 293 |
+
// non-lexical unary rules.
|
| 294 |
+
assert(n.GetParents().size() <= 1);
|
| 295 |
+
if (!options.allowUnary &&
|
| 296 |
+
!n.GetParents().empty() &&
|
| 297 |
+
n.GetParents()[0]->GetSpan() == n.GetSpan()) {
|
| 298 |
+
return false;
|
| 299 |
+
}
|
| 300 |
+
return true;
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
void AlignmentGraph::CalcComplementSpans(Node *root)
|
| 304 |
+
{
|
| 305 |
+
Span compSpan;
|
| 306 |
+
std::set<Node *> siblings;
|
| 307 |
+
|
| 308 |
+
const std::vector<Node *> &parents = root->GetParents();
|
| 309 |
+
for (std::vector<Node *>::const_iterator p(parents.begin());
|
| 310 |
+
p != parents.end(); ++p) {
|
| 311 |
+
const Span &parentCompSpan = (*p)->GetComplementSpan();
|
| 312 |
+
compSpan.insert(parentCompSpan.begin(), parentCompSpan.end());
|
| 313 |
+
const std::vector<Node *> &c = (*p)->GetChildren();
|
| 314 |
+
siblings.insert(c.begin(), c.end());
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
for (std::set<Node *>::iterator p(siblings.begin());
|
| 318 |
+
p != siblings.end(); ++p) {
|
| 319 |
+
if (*p == root) {
|
| 320 |
+
continue;
|
| 321 |
+
}
|
| 322 |
+
const Span &siblingSpan = (*p)->GetSpan();
|
| 323 |
+
compSpan.insert(siblingSpan.begin(), siblingSpan.end());
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
+
root->SetComplementSpan(compSpan);
|
| 327 |
+
|
| 328 |
+
const std::vector<Node *> &children = root->GetChildren();
|
| 329 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 330 |
+
p != children.end(); ++p) {
|
| 331 |
+
CalcComplementSpans(*p);
|
| 332 |
+
}
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
void AlignmentGraph::GetTargetTreeLeaves(Node *root,
|
| 336 |
+
std::vector<Node *> &leaves)
|
| 337 |
+
{
|
| 338 |
+
if (root->IsSink()) {
|
| 339 |
+
leaves.push_back(root);
|
| 340 |
+
} else {
|
| 341 |
+
const std::vector<Node *> &children = root->GetChildren();
|
| 342 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 343 |
+
p != children.end(); ++p) {
|
| 344 |
+
GetTargetTreeLeaves(*p, leaves);
|
| 345 |
+
}
|
| 346 |
+
}
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
void AlignmentGraph::AttachUnalignedSourceWords()
|
| 350 |
+
{
|
| 351 |
+
// Find the unaligned source words (if any).
|
| 352 |
+
std::set<int> unaligned;
|
| 353 |
+
for (size_t i = 0; i < m_sourceNodes.size(); ++i) {
|
| 354 |
+
const Node &sourceNode = (*m_sourceNodes[i]);
|
| 355 |
+
if (sourceNode.GetParents().empty()) {
|
| 356 |
+
unaligned.insert(i);
|
| 357 |
+
}
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
// Determine the attachment point for each one and attach it.
|
| 361 |
+
for (std::set<int>::iterator p = unaligned.begin();
|
| 362 |
+
p != unaligned.end(); ++p) {
|
| 363 |
+
int index = *p;
|
| 364 |
+
Node *attachmentPoint = DetermineAttachmentPoint(index);
|
| 365 |
+
Node *sourceNode = m_sourceNodes[index];
|
| 366 |
+
attachmentPoint->AddChild(sourceNode);
|
| 367 |
+
sourceNode->AddParent(attachmentPoint);
|
| 368 |
+
}
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
Node *AlignmentGraph::DetermineAttachmentPoint(int index)
|
| 372 |
+
{
|
| 373 |
+
// Find the nearest aligned neighbour to the left, if any.
|
| 374 |
+
int i = index;
|
| 375 |
+
while (--i >= 0) {
|
| 376 |
+
if (!m_sourceNodes[i]->GetParents().empty()) {
|
| 377 |
+
break;
|
| 378 |
+
}
|
| 379 |
+
}
|
| 380 |
+
// No aligned neighbours to the left, so attach to the root.
|
| 381 |
+
if (i == -1) {
|
| 382 |
+
return m_root;
|
| 383 |
+
}
|
| 384 |
+
// Find the nearest aligned neighbour to the right, if any.
|
| 385 |
+
size_t j = index;
|
| 386 |
+
while (++j < m_sourceNodes.size()) {
|
| 387 |
+
if (!m_sourceNodes[j]->GetParents().empty()) {
|
| 388 |
+
break;
|
| 389 |
+
}
|
| 390 |
+
}
|
| 391 |
+
// No aligned neighbours to the right, so attach to the root.
|
| 392 |
+
if (j == m_sourceNodes.size()) {
|
| 393 |
+
return m_root;
|
| 394 |
+
}
|
| 395 |
+
// Construct the set of target nodes that are aligned to the left and right
|
| 396 |
+
// neighbours.
|
| 397 |
+
const std::vector<Node *> &leftParents = m_sourceNodes[i]->GetParents();
|
| 398 |
+
assert(!leftParents.empty());
|
| 399 |
+
const std::vector<Node *> &rightParents = m_sourceNodes[j]->GetParents();
|
| 400 |
+
assert(!rightParents.empty());
|
| 401 |
+
std::set<Node *> targetSet;
|
| 402 |
+
targetSet.insert(leftParents.begin(), leftParents.end());
|
| 403 |
+
targetSet.insert(rightParents.begin(), rightParents.end());
|
| 404 |
+
// The attachment point is the lowest common ancestor of the target word
|
| 405 |
+
// nodes, unless the LCA is itself a target word, in which case the LCA
|
| 406 |
+
// is the parent. This is to avoid including introducing new word alignments.
|
| 407 |
+
// It assumes that the parse tree uses preterminals for parts of speech.
|
| 408 |
+
Node *lca = Node::LowestCommonAncestor(targetSet.begin(), targetSet.end());
|
| 409 |
+
if (lca->GetType() == TARGET) {
|
| 410 |
+
assert(lca->GetParents().size() == 1);
|
| 411 |
+
return lca->GetParents()[0];
|
| 412 |
+
}
|
| 413 |
+
return lca;
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
} // namespace GHKM
|
| 417 |
+
} // namespace Syntax
|
| 418 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.h
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
#ifndef EXTRACT_GHKM_ALIGNMENT_GRAPH_H_
|
| 22 |
+
#define EXTRACT_GHKM_ALIGNMENT_GRAPH_H_
|
| 23 |
+
|
| 24 |
+
#include <set>
|
| 25 |
+
#include <string>
|
| 26 |
+
#include <vector>
|
| 27 |
+
|
| 28 |
+
#include "SyntaxTree.h"
|
| 29 |
+
|
| 30 |
+
#include "Alignment.h"
|
| 31 |
+
#include "Options.h"
|
| 32 |
+
|
| 33 |
+
namespace MosesTraining
|
| 34 |
+
{
|
| 35 |
+
namespace Syntax
|
| 36 |
+
{
|
| 37 |
+
namespace GHKM
|
| 38 |
+
{
|
| 39 |
+
|
| 40 |
+
class Node;
|
| 41 |
+
class Subgraph;
|
| 42 |
+
|
| 43 |
+
class AlignmentGraph
|
| 44 |
+
{
|
| 45 |
+
public:
|
| 46 |
+
AlignmentGraph(const SyntaxTree *,
|
| 47 |
+
const std::vector<std::string> &,
|
| 48 |
+
const Alignment &);
|
| 49 |
+
|
| 50 |
+
~AlignmentGraph();
|
| 51 |
+
|
| 52 |
+
Node *GetRoot() {
|
| 53 |
+
return m_root;
|
| 54 |
+
}
|
| 55 |
+
const std::vector<Node *> &GetTargetNodes() {
|
| 56 |
+
return m_targetNodes;
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
void ExtractMinimalRules(const Options &);
|
| 60 |
+
void ExtractComposedRules(const Options &);
|
| 61 |
+
|
| 62 |
+
private:
|
| 63 |
+
// Disallow copying
|
| 64 |
+
AlignmentGraph(const AlignmentGraph &);
|
| 65 |
+
AlignmentGraph &operator=(const AlignmentGraph &);
|
| 66 |
+
|
| 67 |
+
Node *CopyParseTree(const SyntaxTree *);
|
| 68 |
+
void ComputeFrontierSet(Node *, const Options &, std::set<Node *> &) const;
|
| 69 |
+
bool IsFrontierNode(const Node &, const Options &) const;
|
| 70 |
+
void CalcComplementSpans(Node *);
|
| 71 |
+
void GetTargetTreeLeaves(Node *, std::vector<Node *> &);
|
| 72 |
+
void AttachUnalignedSourceWords();
|
| 73 |
+
Node *DetermineAttachmentPoint(int);
|
| 74 |
+
Subgraph ComputeMinimalFrontierGraphFragment(Node *,
|
| 75 |
+
const std::set<Node *> &);
|
| 76 |
+
void ExtractComposedRules(Node *, const Options &);
|
| 77 |
+
|
| 78 |
+
Node *m_root;
|
| 79 |
+
std::vector<Node *> m_sourceNodes;
|
| 80 |
+
std::vector<Node *> m_targetNodes;
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
} // namespace GHKM
|
| 84 |
+
} // namespace Syntax
|
| 85 |
+
} // namespace MosesTraining
|
| 86 |
+
|
| 87 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.cpp
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "ComposedRule.h"
|
| 21 |
+
|
| 22 |
+
#include <set>
|
| 23 |
+
#include <vector>
|
| 24 |
+
#include <queue>
|
| 25 |
+
|
| 26 |
+
#include "Node.h"
|
| 27 |
+
#include "Options.h"
|
| 28 |
+
#include "Subgraph.h"
|
| 29 |
+
|
| 30 |
+
namespace MosesTraining
|
| 31 |
+
{
|
| 32 |
+
namespace Syntax
|
| 33 |
+
{
|
| 34 |
+
namespace GHKM
|
| 35 |
+
{
|
| 36 |
+
|
| 37 |
+
ComposedRule::ComposedRule(const Subgraph &baseRule)
|
| 38 |
+
: m_baseRule(baseRule)
|
| 39 |
+
, m_depth(baseRule.GetDepth())
|
| 40 |
+
, m_size(baseRule.GetSize())
|
| 41 |
+
, m_nodeCount(baseRule.GetNodeCount())
|
| 42 |
+
{
|
| 43 |
+
const std::set<const Node *> &leaves = baseRule.GetLeaves();
|
| 44 |
+
for (std::set<const Node *>::const_iterator p = leaves.begin();
|
| 45 |
+
p != leaves.end(); ++p) {
|
| 46 |
+
if ((*p)->GetType() == TREE) {
|
| 47 |
+
m_openAttachmentPoints.push(*p);
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
ComposedRule::ComposedRule(const ComposedRule &other, const Subgraph &rule,
|
| 53 |
+
int depth)
|
| 54 |
+
: m_baseRule(other.m_baseRule)
|
| 55 |
+
, m_attachedRules(other.m_attachedRules)
|
| 56 |
+
, m_openAttachmentPoints(other.m_openAttachmentPoints)
|
| 57 |
+
, m_depth(depth)
|
| 58 |
+
, m_size(other.m_size+rule.GetSize())
|
| 59 |
+
, m_nodeCount(other.m_nodeCount+rule.GetNodeCount()-1)
|
| 60 |
+
{
|
| 61 |
+
m_attachedRules.push_back(&rule);
|
| 62 |
+
m_openAttachmentPoints.pop();
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
const Node *ComposedRule::GetOpenAttachmentPoint()
|
| 66 |
+
{
|
| 67 |
+
return m_openAttachmentPoints.empty() ? 0 : m_openAttachmentPoints.front();
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
void ComposedRule::CloseAttachmentPoint()
|
| 71 |
+
{
|
| 72 |
+
assert(!m_openAttachmentPoints.empty());
|
| 73 |
+
m_attachedRules.push_back(0);
|
| 74 |
+
m_openAttachmentPoints.pop();
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
ComposedRule *ComposedRule::AttemptComposition(const Subgraph &rule,
|
| 78 |
+
const Options &options) const
|
| 79 |
+
{
|
| 80 |
+
// The smallest possible rule fragment should be rooted at a tree node.
|
| 81 |
+
// Note that this differs from the original GHKM definition.
|
| 82 |
+
assert(rule.GetRoot()->GetType() == TREE);
|
| 83 |
+
|
| 84 |
+
// Check the node count of the proposed rule.
|
| 85 |
+
if (m_nodeCount+rule.GetNodeCount()-1 > options.maxNodes) {
|
| 86 |
+
return 0;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
// Check the size of the proposed rule.
|
| 90 |
+
if (m_size+rule.GetSize() > options.maxRuleSize) {
|
| 91 |
+
return 0;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
// Determine the depth of the proposed rule and test whether it exceeds the
|
| 95 |
+
// limit.
|
| 96 |
+
int attachmentPointDepth = 0;
|
| 97 |
+
const Node *n = rule.GetRoot();
|
| 98 |
+
while (n != m_baseRule.GetRoot()) {
|
| 99 |
+
assert(n->GetParents().size() == 1);
|
| 100 |
+
n = n->GetParents()[0];
|
| 101 |
+
++attachmentPointDepth;
|
| 102 |
+
}
|
| 103 |
+
int newDepth = std::max(m_depth, attachmentPointDepth+rule.GetDepth());
|
| 104 |
+
if (newDepth > options.maxRuleDepth) {
|
| 105 |
+
return 0;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
return new ComposedRule(*this, rule, newDepth);
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
Subgraph ComposedRule::CreateSubgraph()
|
| 112 |
+
{
|
| 113 |
+
std::set<const Node *> leaves;
|
| 114 |
+
const std::set<const Node *> &baseLeaves = m_baseRule.GetLeaves();
|
| 115 |
+
size_t i = 0;
|
| 116 |
+
for (std::set<const Node *>::const_iterator p = baseLeaves.begin();
|
| 117 |
+
p != baseLeaves.end(); ++p) {
|
| 118 |
+
const Node *baseLeaf = *p;
|
| 119 |
+
if (baseLeaf->GetType() == TREE && i < m_attachedRules.size()) {
|
| 120 |
+
const Subgraph *attachedRule = m_attachedRules[i++];
|
| 121 |
+
if (attachedRule) {
|
| 122 |
+
leaves.insert(attachedRule->GetLeaves().begin(),
|
| 123 |
+
attachedRule->GetLeaves().end());
|
| 124 |
+
continue;
|
| 125 |
+
}
|
| 126 |
+
}
|
| 127 |
+
leaves.insert(baseLeaf);
|
| 128 |
+
}
|
| 129 |
+
return Subgraph(m_baseRule.GetRoot(), leaves);
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
} // namespace GHKM
|
| 133 |
+
} // namespace Syntax
|
| 134 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.h
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
#ifndef EXTRACT_GHKM_COMPOSED_RULE_H_
|
| 22 |
+
#define EXTRACT_GHKM_COMPOSED_RULE_H_
|
| 23 |
+
|
| 24 |
+
#include <vector>
|
| 25 |
+
#include <queue>
|
| 26 |
+
|
| 27 |
+
#include "Subgraph.h"
|
| 28 |
+
|
| 29 |
+
namespace MosesTraining
|
| 30 |
+
{
|
| 31 |
+
namespace Syntax
|
| 32 |
+
{
|
| 33 |
+
namespace GHKM
|
| 34 |
+
{
|
| 35 |
+
|
| 36 |
+
class Node;
|
| 37 |
+
struct Options;
|
| 38 |
+
|
| 39 |
+
class ComposedRule
|
| 40 |
+
{
|
| 41 |
+
public:
|
| 42 |
+
// Form a 'trivial' ComposedRule from a single existing rule.
|
| 43 |
+
ComposedRule(const Subgraph &baseRule);
|
| 44 |
+
|
| 45 |
+
// Returns the first open attachment point if any exist or 0 otherwise.
|
| 46 |
+
const Node *GetOpenAttachmentPoint();
|
| 47 |
+
|
| 48 |
+
// Close the first open attachment point without attaching a rule.
|
| 49 |
+
void CloseAttachmentPoint();
|
| 50 |
+
|
| 51 |
+
// Attempts to produce a new composed rule by attaching a given rule at the
|
| 52 |
+
// first open attachment point. This will fail if the proposed rule violates
|
| 53 |
+
// the constraints set in the Options object, in which case the function
|
| 54 |
+
// returns 0.
|
| 55 |
+
ComposedRule *AttemptComposition(const Subgraph &, const Options &) const;
|
| 56 |
+
|
| 57 |
+
// Constructs a Subgraph object corresponding to the composed rule.
|
| 58 |
+
Subgraph CreateSubgraph();
|
| 59 |
+
|
| 60 |
+
private:
|
| 61 |
+
ComposedRule(const ComposedRule &, const Subgraph &, int);
|
| 62 |
+
|
| 63 |
+
const Subgraph &m_baseRule;
|
| 64 |
+
std::vector<const Subgraph *> m_attachedRules;
|
| 65 |
+
std::queue<const Node *> m_openAttachmentPoints;
|
| 66 |
+
int m_depth;
|
| 67 |
+
int m_size;
|
| 68 |
+
int m_nodeCount;
|
| 69 |
+
};
|
| 70 |
+
|
| 71 |
+
} // namespace GHKM
|
| 72 |
+
} // namespace Syntax
|
| 73 |
+
} // namespace MosesTraining
|
| 74 |
+
|
| 75 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.cpp
ADDED
|
@@ -0,0 +1,902 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "ExtractGHKM.h"
|
| 21 |
+
|
| 22 |
+
#include <cassert>
|
| 23 |
+
#include <cstdlib>
|
| 24 |
+
#include <fstream>
|
| 25 |
+
#include <iostream>
|
| 26 |
+
#include <iterator>
|
| 27 |
+
#include <string>
|
| 28 |
+
#include <sstream>
|
| 29 |
+
#include <vector>
|
| 30 |
+
|
| 31 |
+
#include <boost/program_options.hpp>
|
| 32 |
+
|
| 33 |
+
#include "syntax-common/exception.h"
|
| 34 |
+
#include "syntax-common/xml_tree_parser.h"
|
| 35 |
+
|
| 36 |
+
#include "InputFileStream.h"
|
| 37 |
+
#include "OutputFileStream.h"
|
| 38 |
+
#include "SyntaxNode.h"
|
| 39 |
+
#include "SyntaxNodeCollection.h"
|
| 40 |
+
#include "SyntaxTree.h"
|
| 41 |
+
#include "tables-core.h"
|
| 42 |
+
#include "XmlException.h"
|
| 43 |
+
#include "XmlTree.h"
|
| 44 |
+
|
| 45 |
+
#include "Alignment.h"
|
| 46 |
+
#include "AlignmentGraph.h"
|
| 47 |
+
#include "Node.h"
|
| 48 |
+
#include "Options.h"
|
| 49 |
+
#include "PhraseOrientation.h"
|
| 50 |
+
#include "ScfgRule.h"
|
| 51 |
+
#include "ScfgRuleWriter.h"
|
| 52 |
+
#include "Span.h"
|
| 53 |
+
#include "StsgRule.h"
|
| 54 |
+
#include "StsgRuleWriter.h"
|
| 55 |
+
|
| 56 |
+
namespace MosesTraining
|
| 57 |
+
{
|
| 58 |
+
namespace Syntax
|
| 59 |
+
{
|
| 60 |
+
namespace GHKM
|
| 61 |
+
{
|
| 62 |
+
|
| 63 |
+
int ExtractGHKM::Main(int argc, char *argv[])
|
| 64 |
+
{
|
| 65 |
+
using Moses::InputFileStream;
|
| 66 |
+
using Moses::OutputFileStream;
|
| 67 |
+
|
| 68 |
+
// Process command-line options.
|
| 69 |
+
Options options;
|
| 70 |
+
ProcessOptions(argc, argv, options);
|
| 71 |
+
|
| 72 |
+
// Open input files.
|
| 73 |
+
//
|
| 74 |
+
// The GHKM algorithm is neutral about whether the model is string-to-tree or
|
| 75 |
+
// tree-to-string. This implementation assumes the model to be
|
| 76 |
+
// string-to-tree, but if the -t2s option is given then the source and target
|
| 77 |
+
// input files are switched prior to extraction and then the source and
|
| 78 |
+
// target of the extracted rules are switched on output.
|
| 79 |
+
std::string effectiveTargetFile = options.t2s ? options.sourceFile
|
| 80 |
+
: options.targetFile;
|
| 81 |
+
std::string effectiveSourceFile = options.t2s ? options.targetFile
|
| 82 |
+
: options.sourceFile;
|
| 83 |
+
InputFileStream targetStream(effectiveTargetFile);
|
| 84 |
+
InputFileStream sourceStream(effectiveSourceFile);
|
| 85 |
+
InputFileStream alignmentStream(options.alignmentFile);
|
| 86 |
+
|
| 87 |
+
// Open output files.
|
| 88 |
+
OutputFileStream fwdExtractStream;
|
| 89 |
+
OutputFileStream invExtractStream;
|
| 90 |
+
OutputFileStream glueGrammarStream;
|
| 91 |
+
OutputFileStream targetUnknownWordStream;
|
| 92 |
+
OutputFileStream sourceUnknownWordStream;
|
| 93 |
+
OutputFileStream sourceLabelSetStream;
|
| 94 |
+
OutputFileStream unknownWordSoftMatchesStream;
|
| 95 |
+
|
| 96 |
+
std::string fwdFileName = options.extractFile;
|
| 97 |
+
std::string invFileName = options.extractFile + std::string(".inv");
|
| 98 |
+
if (options.gzOutput) {
|
| 99 |
+
fwdFileName += ".gz";
|
| 100 |
+
invFileName += ".gz";
|
| 101 |
+
}
|
| 102 |
+
OpenOutputFileOrDie(fwdFileName, fwdExtractStream);
|
| 103 |
+
OpenOutputFileOrDie(invFileName, invExtractStream);
|
| 104 |
+
|
| 105 |
+
if (!options.glueGrammarFile.empty()) {
|
| 106 |
+
OpenOutputFileOrDie(options.glueGrammarFile, glueGrammarStream);
|
| 107 |
+
}
|
| 108 |
+
if (!options.targetUnknownWordFile.empty()) {
|
| 109 |
+
OpenOutputFileOrDie(options.targetUnknownWordFile, targetUnknownWordStream);
|
| 110 |
+
}
|
| 111 |
+
if (!options.sourceUnknownWordFile.empty()) {
|
| 112 |
+
OpenOutputFileOrDie(options.sourceUnknownWordFile, sourceUnknownWordStream);
|
| 113 |
+
}
|
| 114 |
+
if (!options.sourceLabelSetFile.empty()) {
|
| 115 |
+
if (!options.sourceLabels) {
|
| 116 |
+
Error("SourceLabels should be active if SourceLabelSet is supposed to be written to a file");
|
| 117 |
+
}
|
| 118 |
+
OpenOutputFileOrDie(options.sourceLabelSetFile, sourceLabelSetStream); // note that this is not a global source label set if extraction is parallelized
|
| 119 |
+
}
|
| 120 |
+
if (!options.unknownWordSoftMatchesFile.empty()) {
|
| 121 |
+
OpenOutputFileOrDie(options.unknownWordSoftMatchesFile, unknownWordSoftMatchesStream);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
// Word count statistics for producing unknown word labels.
|
| 125 |
+
std::map<std::string, int> targetWordCount;
|
| 126 |
+
std::map<std::string, std::string> targetWordLabel;
|
| 127 |
+
|
| 128 |
+
// Word count statistics for producing unknown word labels: source side.
|
| 129 |
+
std::map<std::string, int> sourceWordCount;
|
| 130 |
+
std::map<std::string, std::string> sourceWordLabel;
|
| 131 |
+
|
| 132 |
+
std::string targetLine;
|
| 133 |
+
std::string sourceLine;
|
| 134 |
+
std::string alignmentLine;
|
| 135 |
+
Alignment alignment;
|
| 136 |
+
XmlTreeParser targetXmlTreeParser;
|
| 137 |
+
XmlTreeParser sourceXmlTreeParser;
|
| 138 |
+
ScfgRuleWriter scfgWriter(fwdExtractStream, invExtractStream, options);
|
| 139 |
+
StsgRuleWriter stsgWriter(fwdExtractStream, invExtractStream, options);
|
| 140 |
+
size_t lineNum = options.sentenceOffset;
|
| 141 |
+
while (true) {
|
| 142 |
+
std::getline(targetStream, targetLine);
|
| 143 |
+
std::getline(sourceStream, sourceLine);
|
| 144 |
+
std::getline(alignmentStream, alignmentLine);
|
| 145 |
+
|
| 146 |
+
if (targetStream.eof() && sourceStream.eof() && alignmentStream.eof()) {
|
| 147 |
+
break;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
if (targetStream.eof() || sourceStream.eof() || alignmentStream.eof()) {
|
| 151 |
+
Error("Files must contain same number of lines");
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
++lineNum;
|
| 155 |
+
|
| 156 |
+
// Parse target tree.
|
| 157 |
+
if (targetLine.size() == 0) {
|
| 158 |
+
std::cerr << "skipping line " << lineNum << " with empty target tree\n";
|
| 159 |
+
continue;
|
| 160 |
+
}
|
| 161 |
+
std::auto_ptr<SyntaxTree> targetParseTree;
|
| 162 |
+
try {
|
| 163 |
+
targetParseTree = targetXmlTreeParser.Parse(targetLine);
|
| 164 |
+
assert(targetParseTree.get());
|
| 165 |
+
} catch (const Exception &e) {
|
| 166 |
+
std::ostringstream oss;
|
| 167 |
+
oss << "Failed to parse target XML tree at line " << lineNum;
|
| 168 |
+
if (!e.msg().empty()) {
|
| 169 |
+
oss << ": " << e.msg();
|
| 170 |
+
}
|
| 171 |
+
Error(oss.str());
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
// Read source tokens (and parse tree if using source labels).
|
| 175 |
+
std::vector<std::string> sourceTokens;
|
| 176 |
+
std::auto_ptr<SyntaxTree> sourceParseTree;
|
| 177 |
+
if (!options.sourceLabels) {
|
| 178 |
+
sourceTokens = ReadTokens(sourceLine);
|
| 179 |
+
} else {
|
| 180 |
+
try {
|
| 181 |
+
sourceParseTree = sourceXmlTreeParser.Parse(sourceLine);
|
| 182 |
+
assert(sourceParseTree.get());
|
| 183 |
+
} catch (const Exception &e) {
|
| 184 |
+
std::ostringstream oss;
|
| 185 |
+
oss << "Failed to parse source XML tree at line " << lineNum;
|
| 186 |
+
if (!e.msg().empty()) {
|
| 187 |
+
oss << ": " << e.msg();
|
| 188 |
+
}
|
| 189 |
+
Error(oss.str());
|
| 190 |
+
}
|
| 191 |
+
sourceTokens = sourceXmlTreeParser.words();
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// Read word alignments.
|
| 195 |
+
try {
|
| 196 |
+
ReadAlignment(alignmentLine, alignment);
|
| 197 |
+
} catch (const Exception &e) {
|
| 198 |
+
std::ostringstream oss;
|
| 199 |
+
oss << "Failed to read alignment at line " << lineNum << ": ";
|
| 200 |
+
oss << e.msg();
|
| 201 |
+
Error(oss.str());
|
| 202 |
+
}
|
| 203 |
+
if (alignment.size() == 0) {
|
| 204 |
+
std::cerr << "skipping line " << lineNum << " without alignment points\n";
|
| 205 |
+
continue;
|
| 206 |
+
}
|
| 207 |
+
if (options.t2s) {
|
| 208 |
+
FlipAlignment(alignment);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
// Record word counts.
|
| 212 |
+
if (!options.targetUnknownWordFile.empty()) {
|
| 213 |
+
CollectWordLabelCounts(*targetParseTree, options, targetWordCount,
|
| 214 |
+
targetWordLabel);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
// Record word counts: source side.
|
| 218 |
+
if (options.sourceLabels && !options.sourceUnknownWordFile.empty()) {
|
| 219 |
+
CollectWordLabelCounts(*sourceParseTree, options, sourceWordCount,
|
| 220 |
+
sourceWordLabel);
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
// Form an alignment graph from the target tree, source words, and
|
| 224 |
+
// alignment.
|
| 225 |
+
AlignmentGraph graph(targetParseTree.get(), sourceTokens, alignment);
|
| 226 |
+
|
| 227 |
+
// Extract minimal rules, adding each rule to its root node's rule set.
|
| 228 |
+
graph.ExtractMinimalRules(options);
|
| 229 |
+
|
| 230 |
+
// Extract composed rules.
|
| 231 |
+
if (!options.minimal) {
|
| 232 |
+
graph.ExtractComposedRules(options);
|
| 233 |
+
}
|
| 234 |
+
|
| 235 |
+
// Initialize phrase orientation scoring object
|
| 236 |
+
PhraseOrientation phraseOrientation(sourceTokens.size(),
|
| 237 |
+
targetXmlTreeParser.words().size(), alignment);
|
| 238 |
+
|
| 239 |
+
// Write the rules, subject to scope pruning.
|
| 240 |
+
const std::vector<Node *> &targetNodes = graph.GetTargetNodes();
|
| 241 |
+
for (std::vector<Node *>::const_iterator p = targetNodes.begin();
|
| 242 |
+
p != targetNodes.end(); ++p) {
|
| 243 |
+
|
| 244 |
+
const std::vector<const Subgraph *> &rules = (*p)->GetRules();
|
| 245 |
+
|
| 246 |
+
PhraseOrientation::REO_CLASS l2rOrientation=PhraseOrientation::REO_CLASS_UNKNOWN, r2lOrientation=PhraseOrientation::REO_CLASS_UNKNOWN;
|
| 247 |
+
if (options.phraseOrientation && !rules.empty()) {
|
| 248 |
+
int sourceSpanBegin = *((*p)->GetSpan().begin());
|
| 249 |
+
int sourceSpanEnd = *((*p)->GetSpan().rbegin());
|
| 250 |
+
l2rOrientation = phraseOrientation.GetOrientationInfo(sourceSpanBegin,sourceSpanEnd,PhraseOrientation::REO_DIR_L2R);
|
| 251 |
+
r2lOrientation = phraseOrientation.GetOrientationInfo(sourceSpanBegin,sourceSpanEnd,PhraseOrientation::REO_DIR_R2L);
|
| 252 |
+
// std::cerr << "span " << sourceSpanBegin << " " << sourceSpanEnd << std::endl;
|
| 253 |
+
// std::cerr << "phraseOrientation " << phraseOrientation.GetOrientationInfo(sourceSpanBegin,sourceSpanEnd) << std::endl;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
for (std::vector<const Subgraph *>::const_iterator q = rules.begin();
|
| 257 |
+
q != rules.end(); ++q) {
|
| 258 |
+
// STSG output.
|
| 259 |
+
if (options.stsg) {
|
| 260 |
+
StsgRule rule(**q);
|
| 261 |
+
if (rule.Scope() <= options.maxScope) {
|
| 262 |
+
stsgWriter.Write(rule);
|
| 263 |
+
}
|
| 264 |
+
continue;
|
| 265 |
+
}
|
| 266 |
+
// SCFG output.
|
| 267 |
+
ScfgRule *r = 0;
|
| 268 |
+
if (options.sourceLabels) {
|
| 269 |
+
r = new ScfgRule(**q, &sourceXmlTreeParser.node_collection());
|
| 270 |
+
} else {
|
| 271 |
+
r = new ScfgRule(**q);
|
| 272 |
+
}
|
| 273 |
+
// TODO Can scope pruning be done earlier?
|
| 274 |
+
if (r->Scope() <= options.maxScope) {
|
| 275 |
+
scfgWriter.Write(*r,lineNum,false);
|
| 276 |
+
if (options.treeFragments) {
|
| 277 |
+
fwdExtractStream << " {{Tree ";
|
| 278 |
+
(*q)->PrintTree(fwdExtractStream);
|
| 279 |
+
fwdExtractStream << "}}";
|
| 280 |
+
}
|
| 281 |
+
if (options.partsOfSpeech) {
|
| 282 |
+
fwdExtractStream << " {{POS";
|
| 283 |
+
(*q)->PrintPartsOfSpeech(fwdExtractStream);
|
| 284 |
+
fwdExtractStream << "}}";
|
| 285 |
+
}
|
| 286 |
+
if (options.phraseOrientation) {
|
| 287 |
+
fwdExtractStream << " {{Orientation ";
|
| 288 |
+
phraseOrientation.WriteOrientation(fwdExtractStream,l2rOrientation);
|
| 289 |
+
fwdExtractStream << " ";
|
| 290 |
+
phraseOrientation.WriteOrientation(fwdExtractStream,r2lOrientation);
|
| 291 |
+
fwdExtractStream << "}}";
|
| 292 |
+
phraseOrientation.IncrementPriorCount(PhraseOrientation::REO_DIR_L2R,l2rOrientation,1);
|
| 293 |
+
phraseOrientation.IncrementPriorCount(PhraseOrientation::REO_DIR_R2L,r2lOrientation,1);
|
| 294 |
+
}
|
| 295 |
+
fwdExtractStream << std::endl;
|
| 296 |
+
invExtractStream << std::endl;
|
| 297 |
+
}
|
| 298 |
+
delete r;
|
| 299 |
+
}
|
| 300 |
+
}
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
if (options.phraseOrientation) {
|
| 304 |
+
std::string phraseOrientationPriorsFileName = options.extractFile + std::string(".phraseOrientationPriors");
|
| 305 |
+
OutputFileStream phraseOrientationPriorsStream;
|
| 306 |
+
OpenOutputFileOrDie(phraseOrientationPriorsFileName, phraseOrientationPriorsStream);
|
| 307 |
+
PhraseOrientation::WritePriorCounts(phraseOrientationPriorsStream);
|
| 308 |
+
}
|
| 309 |
+
|
| 310 |
+
std::map<std::string,size_t> sourceLabels;
|
| 311 |
+
if (options.sourceLabels && !options.sourceLabelSetFile.empty()) {
|
| 312 |
+
std::set<std::string> extendedLabelSet = sourceXmlTreeParser.label_set();
|
| 313 |
+
extendedLabelSet.insert("XLHS"); // non-matching label (left-hand side)
|
| 314 |
+
extendedLabelSet.insert("XRHS"); // non-matching label (right-hand side)
|
| 315 |
+
extendedLabelSet.insert("TOPLABEL"); // as used in the glue grammar
|
| 316 |
+
extendedLabelSet.insert("SOMELABEL"); // as used in the glue grammar
|
| 317 |
+
size_t index = 0;
|
| 318 |
+
for (std::set<std::string>::const_iterator iter=extendedLabelSet.begin();
|
| 319 |
+
iter!=extendedLabelSet.end(); ++iter, ++index) {
|
| 320 |
+
sourceLabels.insert(std::pair<std::string,size_t>(*iter,index));
|
| 321 |
+
}
|
| 322 |
+
WriteSourceLabelSet(sourceLabels, sourceLabelSetStream);
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
std::set<std::string> strippedTargetLabelSet;
|
| 326 |
+
std::map<std::string, int> strippedTargetTopLabelSet;
|
| 327 |
+
if (options.stripBitParLabels &&
|
| 328 |
+
(!options.glueGrammarFile.empty() || !options.unknownWordSoftMatchesFile.empty())) {
|
| 329 |
+
StripBitParLabels(targetXmlTreeParser.label_set(),
|
| 330 |
+
targetXmlTreeParser.top_label_set(),
|
| 331 |
+
strippedTargetLabelSet, strippedTargetTopLabelSet);
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
if (!options.glueGrammarFile.empty()) {
|
| 335 |
+
if (options.stripBitParLabels) {
|
| 336 |
+
WriteGlueGrammar(strippedTargetLabelSet, strippedTargetTopLabelSet, sourceLabels, options, glueGrammarStream);
|
| 337 |
+
} else {
|
| 338 |
+
WriteGlueGrammar(targetXmlTreeParser.label_set(),
|
| 339 |
+
targetXmlTreeParser.top_label_set(),
|
| 340 |
+
sourceLabels, options, glueGrammarStream);
|
| 341 |
+
}
|
| 342 |
+
}
|
| 343 |
+
|
| 344 |
+
if (!options.targetUnknownWordFile.empty()) {
|
| 345 |
+
WriteUnknownWordLabel(targetWordCount, targetWordLabel, options, targetUnknownWordStream);
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
if (options.sourceLabels && !options.sourceUnknownWordFile.empty()) {
|
| 349 |
+
WriteUnknownWordLabel(sourceWordCount, sourceWordLabel, options, sourceUnknownWordStream, true);
|
| 350 |
+
}
|
| 351 |
+
|
| 352 |
+
if (!options.unknownWordSoftMatchesFile.empty()) {
|
| 353 |
+
if (options.stripBitParLabels) {
|
| 354 |
+
WriteUnknownWordSoftMatches(strippedTargetLabelSet, unknownWordSoftMatchesStream);
|
| 355 |
+
} else {
|
| 356 |
+
WriteUnknownWordSoftMatches(targetXmlTreeParser.label_set(),
|
| 357 |
+
unknownWordSoftMatchesStream);
|
| 358 |
+
}
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
return 0;
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
void ExtractGHKM::ProcessOptions(int argc, char *argv[],
|
| 365 |
+
Options &options) const
|
| 366 |
+
{
|
| 367 |
+
namespace po = boost::program_options;
|
| 368 |
+
namespace cls = boost::program_options::command_line_style;
|
| 369 |
+
|
| 370 |
+
// Construct the 'top' of the usage message: the bit that comes before the
|
| 371 |
+
// options list.
|
| 372 |
+
std::ostringstream usageTop;
|
| 373 |
+
usageTop << "Usage: " << name()
|
| 374 |
+
<< " [OPTION]... TARGET SOURCE ALIGNMENT EXTRACT\n\n"
|
| 375 |
+
<< "SCFG rule extractor based on the GHKM algorithm described in\n"
|
| 376 |
+
<< "Galley et al. (2004).\n\n"
|
| 377 |
+
<< "Options";
|
| 378 |
+
|
| 379 |
+
// Construct the 'bottom' of the usage message.
|
| 380 |
+
std::ostringstream usageBottom;
|
| 381 |
+
usageBottom << "\nImplementation Notes:\n"
|
| 382 |
+
<< "\nThe parse tree is assumed to contain part-of-speech preterminal nodes.\n"
|
| 383 |
+
<< "\n"
|
| 384 |
+
<< "For the composed rule constraints: rule depth is the "
|
| 385 |
+
"maximum distance from the\nrule's root node to a sink "
|
| 386 |
+
"node, not counting preterminal expansions or word\n"
|
| 387 |
+
"alignments. Rule size is the measure defined in DeNeefe "
|
| 388 |
+
"et al (2007): the\nnumber of non-part-of-speech, non-leaf "
|
| 389 |
+
"constituent labels in the target tree.\nNode count is the "
|
| 390 |
+
"number of target tree nodes (excluding target words).\n"
|
| 391 |
+
<< "\n"
|
| 392 |
+
<< "Scope pruning (Hopkins and Langmead, 2010) is applied to both minimal and\ncomposed rules.\n"
|
| 393 |
+
<< "\n"
|
| 394 |
+
<< "Unaligned source words are attached to the tree using the "
|
| 395 |
+
"following heuristic:\nif there are aligned source words to "
|
| 396 |
+
"both the left and the right of an unaligned\nsource word "
|
| 397 |
+
"then it is attached to the lowest common ancestor of its "
|
| 398 |
+
"nearest\nsuch left and right neighbours. Otherwise, it is "
|
| 399 |
+
"attached to the root of the\nparse tree.\n"
|
| 400 |
+
<< "\n"
|
| 401 |
+
<< "Unless the --AllowUnary option is given, unary rules containing no lexical\nsource items are eliminated using the method described in Chung et al. (2011).\nThe parsing algorithm used in Moses is unable to handle such rules.\n"
|
| 402 |
+
<< "\n"
|
| 403 |
+
<< "References:\n"
|
| 404 |
+
<< "Galley, M., Hopkins, M., Knight, K., and Marcu, D. (2004)\n"
|
| 405 |
+
<< "\"What's in a Translation Rule?\", In Proceedings of HLT/NAACL 2004.\n"
|
| 406 |
+
<< "\n"
|
| 407 |
+
<< "DeNeefe, S., Knight, K., Wang, W., and Marcu, D. (2007)\n"
|
| 408 |
+
<< "\"What Can Syntax-Based MT Learn from Phrase-Based MT?\", In Proceedings of\nEMNLP-CoNLL 2007.\n"
|
| 409 |
+
<< "\n"
|
| 410 |
+
<< "Hopkins, M. and Langmead, G. (2010)\n"
|
| 411 |
+
<< "\"SCFG Decoding Without Binarization\", In Proceedings of EMNLP 2010.\n"
|
| 412 |
+
<< "\n"
|
| 413 |
+
<< "Chung, T. and Fang, L. and Gildea, D. (2011)\n"
|
| 414 |
+
<< "\"Issues Concerning Decoding with Synchronous Context-free Grammar\", In\nProceedings of ACL/HLT 2011.";
|
| 415 |
+
|
| 416 |
+
// Declare the command line options that are visible to the user.
|
| 417 |
+
po::options_description visible(usageTop.str());
|
| 418 |
+
visible.add_options()
|
| 419 |
+
//("help", "print this help message and exit")
|
| 420 |
+
("AllowUnary",
|
| 421 |
+
"allow fully non-lexical unary rules")
|
| 422 |
+
("ConditionOnTargetLHS",
|
| 423 |
+
"write target LHS instead of \"X\" as source LHS")
|
| 424 |
+
("GlueGrammar",
|
| 425 |
+
po::value(&options.glueGrammarFile),
|
| 426 |
+
"write glue grammar to named file")
|
| 427 |
+
("GZOutput",
|
| 428 |
+
"write gzipped extract files")
|
| 429 |
+
("IncludeSentenceId",
|
| 430 |
+
"include sentence ID")
|
| 431 |
+
("MaxNodes",
|
| 432 |
+
po::value(&options.maxNodes)->default_value(options.maxNodes),
|
| 433 |
+
"set maximum number of tree nodes for composed rules")
|
| 434 |
+
("MaxRuleDepth",
|
| 435 |
+
po::value(&options.maxRuleDepth)->default_value(options.maxRuleDepth),
|
| 436 |
+
"set maximum depth for composed rules")
|
| 437 |
+
("MaxRuleSize",
|
| 438 |
+
po::value(&options.maxRuleSize)->default_value(options.maxRuleSize),
|
| 439 |
+
"set maximum size for composed rules")
|
| 440 |
+
("MaxScope",
|
| 441 |
+
po::value(&options.maxScope)->default_value(options.maxScope),
|
| 442 |
+
"set maximum allowed scope")
|
| 443 |
+
("Minimal",
|
| 444 |
+
"extract minimal rules only")
|
| 445 |
+
("PartsOfSpeech",
|
| 446 |
+
"output parts-of-speech as property (preterminals from the parse tree)")
|
| 447 |
+
("PartsOfSpeechFactor",
|
| 448 |
+
"output parts-of-speech as factor (preterminals from the parse tree)")
|
| 449 |
+
("PCFG",
|
| 450 |
+
"include score based on PCFG scores in target corpus")
|
| 451 |
+
("PhraseOrientation",
|
| 452 |
+
"output phrase orientation information")
|
| 453 |
+
("StripBitParLabels",
|
| 454 |
+
"strip suffix starting with a hyphen symbol (\"-\") from non-terminal labels")
|
| 455 |
+
("STSG",
|
| 456 |
+
"output STSG rules (default is SCFG)")
|
| 457 |
+
("T2S",
|
| 458 |
+
"enable tree-to-string rule extraction (string-to-tree is assumed by default)")
|
| 459 |
+
("TreeFragments",
|
| 460 |
+
"output parse tree information")
|
| 461 |
+
("SourceLabels",
|
| 462 |
+
"output source syntax label information")
|
| 463 |
+
("SourceLabelSet",
|
| 464 |
+
po::value(&options.sourceLabelSetFile),
|
| 465 |
+
"write source syntax label set to named file")
|
| 466 |
+
("SentenceOffset",
|
| 467 |
+
po::value(&options.sentenceOffset)->default_value(options.sentenceOffset),
|
| 468 |
+
"set sentence number offset if processing split corpus")
|
| 469 |
+
("UnknownWordLabel",
|
| 470 |
+
po::value(&options.targetUnknownWordFile),
|
| 471 |
+
"write unknown word labels to named file")
|
| 472 |
+
("SourceUnknownWordLabel",
|
| 473 |
+
po::value(&options.sourceUnknownWordFile),
|
| 474 |
+
"write source syntax unknown word labels to named file")
|
| 475 |
+
("UnknownWordMinRelFreq",
|
| 476 |
+
po::value(&options.unknownWordMinRelFreq)->default_value(
|
| 477 |
+
options.unknownWordMinRelFreq),
|
| 478 |
+
"set minimum relative frequency for unknown word labels")
|
| 479 |
+
("UnknownWordSoftMatches",
|
| 480 |
+
po::value(&options.unknownWordSoftMatchesFile),
|
| 481 |
+
"write dummy value to unknown word label file, and mappings from dummy value to other labels to named file")
|
| 482 |
+
("UnknownWordUniform",
|
| 483 |
+
"write uniform weights to unknown word label file")
|
| 484 |
+
("UnpairedExtractFormat",
|
| 485 |
+
"do not pair non-terminals in extract files")
|
| 486 |
+
;
|
| 487 |
+
|
| 488 |
+
// Declare the command line options that are hidden from the user
|
| 489 |
+
// (these are used as positional options).
|
| 490 |
+
po::options_description hidden("Hidden options");
|
| 491 |
+
hidden.add_options()
|
| 492 |
+
("TargetFile",
|
| 493 |
+
po::value(&options.targetFile),
|
| 494 |
+
"target file")
|
| 495 |
+
("SourceFile",
|
| 496 |
+
po::value(&options.sourceFile),
|
| 497 |
+
"source file")
|
| 498 |
+
("AlignmentFile",
|
| 499 |
+
po::value(&options.alignmentFile),
|
| 500 |
+
"alignment file")
|
| 501 |
+
("ExtractFile",
|
| 502 |
+
po::value(&options.extractFile),
|
| 503 |
+
"extract file")
|
| 504 |
+
;
|
| 505 |
+
|
| 506 |
+
// Compose the full set of command-line options.
|
| 507 |
+
po::options_description cmdLineOptions;
|
| 508 |
+
cmdLineOptions.add(visible).add(hidden);
|
| 509 |
+
|
| 510 |
+
// Register the positional options.
|
| 511 |
+
po::positional_options_description p;
|
| 512 |
+
p.add("TargetFile", 1);
|
| 513 |
+
p.add("SourceFile", 1);
|
| 514 |
+
p.add("AlignmentFile", 1);
|
| 515 |
+
p.add("ExtractFile", 1);
|
| 516 |
+
|
| 517 |
+
// Process the command-line.
|
| 518 |
+
po::variables_map vm;
|
| 519 |
+
try {
|
| 520 |
+
po::store(po::command_line_parser(argc, argv).style(MosesOptionStyle()).
|
| 521 |
+
options(cmdLineOptions).positional(p).run(), vm);
|
| 522 |
+
po::notify(vm);
|
| 523 |
+
} catch (const std::exception &e) {
|
| 524 |
+
std::ostringstream msg;
|
| 525 |
+
msg << e.what() << "\n\n" << visible << usageBottom.str();
|
| 526 |
+
Error(msg.str());
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
if (vm.count("help")) {
|
| 530 |
+
std::cout << visible << usageBottom.str() << std::endl;
|
| 531 |
+
std::exit(0);
|
| 532 |
+
}
|
| 533 |
+
|
| 534 |
+
// Check all positional options were given.
|
| 535 |
+
if (!vm.count("TargetFile") ||
|
| 536 |
+
!vm.count("SourceFile") ||
|
| 537 |
+
!vm.count("AlignmentFile") ||
|
| 538 |
+
!vm.count("ExtractFile")) {
|
| 539 |
+
std::ostringstream msg;
|
| 540 |
+
std::cerr << visible << usageBottom.str() << std::endl;
|
| 541 |
+
std::exit(1);
|
| 542 |
+
}
|
| 543 |
+
|
| 544 |
+
// Process Boolean options.
|
| 545 |
+
if (vm.count("AllowUnary")) {
|
| 546 |
+
options.allowUnary = true;
|
| 547 |
+
}
|
| 548 |
+
if (vm.count("ConditionOnTargetLHS")) {
|
| 549 |
+
options.conditionOnTargetLhs = true;
|
| 550 |
+
}
|
| 551 |
+
if (vm.count("GZOutput")) {
|
| 552 |
+
options.gzOutput = true;
|
| 553 |
+
}
|
| 554 |
+
if (vm.count("IncludeSentenceId")) {
|
| 555 |
+
options.includeSentenceId = true;
|
| 556 |
+
}
|
| 557 |
+
if (vm.count("Minimal")) {
|
| 558 |
+
options.minimal = true;
|
| 559 |
+
}
|
| 560 |
+
if (vm.count("PartsOfSpeech")) {
|
| 561 |
+
options.partsOfSpeech = true;
|
| 562 |
+
}
|
| 563 |
+
if (vm.count("PartsOfSpeechFactor")) {
|
| 564 |
+
options.partsOfSpeechFactor = true;
|
| 565 |
+
}
|
| 566 |
+
if (vm.count("PCFG")) {
|
| 567 |
+
options.pcfg = true;
|
| 568 |
+
}
|
| 569 |
+
if (vm.count("PhraseOrientation")) {
|
| 570 |
+
options.phraseOrientation = true;
|
| 571 |
+
}
|
| 572 |
+
if (vm.count("StripBitParLabels")) {
|
| 573 |
+
options.stripBitParLabels = true;
|
| 574 |
+
}
|
| 575 |
+
if (vm.count("STSG")) {
|
| 576 |
+
options.stsg = true;
|
| 577 |
+
}
|
| 578 |
+
if (vm.count("T2S")) {
|
| 579 |
+
options.t2s = true;
|
| 580 |
+
}
|
| 581 |
+
if (vm.count("TreeFragments")) {
|
| 582 |
+
options.treeFragments = true;
|
| 583 |
+
}
|
| 584 |
+
if (vm.count("SourceLabels")) {
|
| 585 |
+
options.sourceLabels = true;
|
| 586 |
+
}
|
| 587 |
+
if (vm.count("UnknownWordUniform")) {
|
| 588 |
+
options.unknownWordUniform = true;
|
| 589 |
+
}
|
| 590 |
+
if (vm.count("UnpairedExtractFormat")) {
|
| 591 |
+
options.unpairedExtractFormat = true;
|
| 592 |
+
}
|
| 593 |
+
|
| 594 |
+
// Workaround for extract-parallel issue.
|
| 595 |
+
if (options.sentenceOffset > 0) {
|
| 596 |
+
options.targetUnknownWordFile.clear();
|
| 597 |
+
}
|
| 598 |
+
if (options.sentenceOffset > 0) {
|
| 599 |
+
options.sourceUnknownWordFile.clear();
|
| 600 |
+
options.unknownWordSoftMatchesFile.clear();
|
| 601 |
+
}
|
| 602 |
+
}
|
| 603 |
+
|
| 604 |
+
std::vector<std::string> ExtractGHKM::ReadTokens(const std::string &s) const
|
| 605 |
+
{
|
| 606 |
+
std::vector<std::string> tokens;
|
| 607 |
+
|
| 608 |
+
std::string whitespace = " \t";
|
| 609 |
+
|
| 610 |
+
std::string::size_type begin = s.find_first_not_of(whitespace);
|
| 611 |
+
assert(begin != std::string::npos);
|
| 612 |
+
while (true) {
|
| 613 |
+
std::string::size_type end = s.find_first_of(whitespace, begin);
|
| 614 |
+
std::string token;
|
| 615 |
+
if (end == std::string::npos) {
|
| 616 |
+
token = s.substr(begin);
|
| 617 |
+
} else {
|
| 618 |
+
token = s.substr(begin, end-begin);
|
| 619 |
+
}
|
| 620 |
+
tokens.push_back(token);
|
| 621 |
+
if (end == std::string::npos) {
|
| 622 |
+
break;
|
| 623 |
+
}
|
| 624 |
+
begin = s.find_first_not_of(whitespace, end);
|
| 625 |
+
if (begin == std::string::npos) {
|
| 626 |
+
break;
|
| 627 |
+
}
|
| 628 |
+
}
|
| 629 |
+
|
| 630 |
+
return tokens;
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
void ExtractGHKM::WriteGlueGrammar(
|
| 634 |
+
const std::set<std::string> &labelSet,
|
| 635 |
+
const std::map<std::string, int> &topLabelSet,
|
| 636 |
+
const std::map<std::string,size_t> &sourceLabels,
|
| 637 |
+
const Options &options,
|
| 638 |
+
std::ostream &out) const
|
| 639 |
+
{
|
| 640 |
+
// choose a top label that is not already a label
|
| 641 |
+
std::string topLabel = "QQQQQQ";
|
| 642 |
+
for(size_t i = 1; i <= topLabel.length(); i++) {
|
| 643 |
+
if (labelSet.find(topLabel.substr(0,i)) == labelSet.end() ) {
|
| 644 |
+
topLabel = topLabel.substr(0,i);
|
| 645 |
+
break;
|
| 646 |
+
}
|
| 647 |
+
}
|
| 648 |
+
|
| 649 |
+
const size_t sourceLabelGlueTop = 0;
|
| 650 |
+
const size_t sourceLabelGlueX = 1;
|
| 651 |
+
const size_t sourceLabelSentenceStart = 2;
|
| 652 |
+
const size_t sourceLabelSentenceEnd = 3;
|
| 653 |
+
// const size_t partOfSpeechSentenceStart = 0;
|
| 654 |
+
// const size_t partOfSpeechSentenceEnd = 1;
|
| 655 |
+
|
| 656 |
+
#ifndef BOS_
|
| 657 |
+
#define BOS_ "<s>" //Beginning of sentence symbol
|
| 658 |
+
#endif
|
| 659 |
+
#ifndef EOS_
|
| 660 |
+
#define EOS_ "</s>" //End of sentence symbol
|
| 661 |
+
#endif
|
| 662 |
+
|
| 663 |
+
std::string sentenceStartSource = BOS_;
|
| 664 |
+
std::string sentenceEndSource = EOS_;
|
| 665 |
+
std::string sentenceStartTarget = BOS_;
|
| 666 |
+
std::string sentenceEndTarget = EOS_;
|
| 667 |
+
if (options.partsOfSpeech) {
|
| 668 |
+
sentenceStartTarget = sentenceStartTarget + "|" + BOS_;
|
| 669 |
+
sentenceEndTarget = sentenceEndTarget + "|" + EOS_;
|
| 670 |
+
}
|
| 671 |
+
if (options.partsOfSpeechFactor) {
|
| 672 |
+
sentenceStartTarget = sentenceStartTarget + "|" + BOS_;
|
| 673 |
+
sentenceEndTarget = sentenceEndTarget + "|" + EOS_;
|
| 674 |
+
}
|
| 675 |
+
|
| 676 |
+
// basic rules
|
| 677 |
+
out << sentenceStartSource << " [X] ||| " << sentenceStartTarget << " [" << topLabel << "] ||| 1 ||| 0-0 ||| ||| |||";
|
| 678 |
+
if (options.treeFragments) {
|
| 679 |
+
out << " {{Tree [" << topLabel << " [SSTART <s>]]}}";
|
| 680 |
+
}
|
| 681 |
+
// if (options.partsOfSpeech) {
|
| 682 |
+
// out << " {{POS " << partOfSpeechSentenceStart << "}}";
|
| 683 |
+
// }
|
| 684 |
+
if (options.sourceLabels) {
|
| 685 |
+
out << " {{SourceLabels 2 1 " << sourceLabelSentenceStart << " 1 1 " << sourceLabelGlueTop << " 1}}";
|
| 686 |
+
}
|
| 687 |
+
if (options.phraseOrientation) {
|
| 688 |
+
out << " {{Orientation 1 1 0.5 0.5 1 1 0.5 0.5}}";
|
| 689 |
+
}
|
| 690 |
+
out << std::endl;
|
| 691 |
+
|
| 692 |
+
out << "[X][" << topLabel << "] " << sentenceEndSource << " [X] ||| [X][" << topLabel << "] " << sentenceEndTarget << " [" << topLabel << "] ||| 1 ||| 0-0 1-1 ||| ||| |||";
|
| 693 |
+
if (options.treeFragments) {
|
| 694 |
+
out << " {{Tree [" << topLabel << " [" << topLabel << "] [SEND </s>]]}}";
|
| 695 |
+
}
|
| 696 |
+
// if (options.partsOfSpeech) {
|
| 697 |
+
// out << " {{POS " << partOfSpeechSentenceEnd << "}}";
|
| 698 |
+
// }
|
| 699 |
+
if (options.sourceLabels) {
|
| 700 |
+
out << " {{SourceLabels 4 1 " << sourceLabelSentenceStart << " " << sourceLabelGlueTop << " " << sourceLabelSentenceEnd << " 1 1 " << sourceLabelGlueTop << " 1}}";
|
| 701 |
+
}
|
| 702 |
+
if (options.phraseOrientation) {
|
| 703 |
+
out << " {{Orientation 1 1 0.5 0.5 1 1 0.5 0.5}}";
|
| 704 |
+
}
|
| 705 |
+
out << std::endl;
|
| 706 |
+
|
| 707 |
+
// top rules
|
| 708 |
+
for (std::map<std::string, int>::const_iterator i = topLabelSet.begin();
|
| 709 |
+
i != topLabelSet.end(); ++i) {
|
| 710 |
+
out << sentenceStartSource << " [X][" << i->first << "] " << sentenceEndSource << " [X] ||| " << sentenceStartTarget << " [X][" << i->first << "] " << sentenceEndTarget << " [" << topLabel << "] ||| 1 ||| 0-0 1-1 2-2 ||| ||| |||";
|
| 711 |
+
if (options.treeFragments) {
|
| 712 |
+
out << " {{Tree [" << topLabel << " [SSTART <s>] [" << i->first << "] [SEND </s>]]}}";
|
| 713 |
+
}
|
| 714 |
+
// if (options.partsOfSpeech) {
|
| 715 |
+
// out << " {{POS " << partOfSpeechSentenceStart << " " << partOfSpeechSentenceEnd << "}}";
|
| 716 |
+
// }
|
| 717 |
+
if (options.sourceLabels) {
|
| 718 |
+
out << " {{SourceLabels 4 1 " << sourceLabelSentenceStart << " " << sourceLabelGlueX << " " << sourceLabelSentenceEnd << " 1 1 " << sourceLabelGlueTop << " 1}}";
|
| 719 |
+
}
|
| 720 |
+
if (options.phraseOrientation) {
|
| 721 |
+
out << " {{Orientation 1 1 0.5 0.5 1 1 0.5 0.5}}";
|
| 722 |
+
}
|
| 723 |
+
out << std::endl;
|
| 724 |
+
}
|
| 725 |
+
|
| 726 |
+
// glue rules
|
| 727 |
+
for(std::set<std::string>::const_iterator i = labelSet.begin();
|
| 728 |
+
i != labelSet.end(); i++ ) {
|
| 729 |
+
out << "[X][" << topLabel << "] [X][" << *i << "] [X] ||| [X][" << topLabel << "] [X][" << *i << "] [" << topLabel << "] ||| 2.718 ||| 0-0 1-1 ||| ||| |||";
|
| 730 |
+
if (options.treeFragments) {
|
| 731 |
+
out << " {{Tree [" << topLabel << " ["<< topLabel << "] [" << *i << "]]}}";
|
| 732 |
+
}
|
| 733 |
+
if (options.sourceLabels) {
|
| 734 |
+
out << " {{SourceLabels 3 1 " << sourceLabelGlueTop << " " << sourceLabelGlueX << " 1 1 " << sourceLabelGlueTop << " 1}}";
|
| 735 |
+
}
|
| 736 |
+
if (options.phraseOrientation) {
|
| 737 |
+
out << " {{Orientation 1 1 0.5 0.5 1 1 0.5 0.5}}";
|
| 738 |
+
}
|
| 739 |
+
out << std::endl;
|
| 740 |
+
}
|
| 741 |
+
|
| 742 |
+
// glue rule for unknown word...
|
| 743 |
+
out << "[X][" << topLabel << "] [X][X] [X] ||| [X][" << topLabel << "] [X][X] [" << topLabel << "] ||| 2.718 ||| 0-0 1-1 ||| ||| |||";
|
| 744 |
+
if (options.treeFragments) {
|
| 745 |
+
out << " {{Tree [" << topLabel << " [" << topLabel << "] [X]]}}";
|
| 746 |
+
}
|
| 747 |
+
if (options.sourceLabels) {
|
| 748 |
+
out << " {{SourceLabels 3 1 " << sourceLabelGlueTop << " " << sourceLabelGlueX << " 1 1 " << sourceLabelGlueTop << " 1}}";
|
| 749 |
+
}
|
| 750 |
+
if (options.phraseOrientation) {
|
| 751 |
+
out << " {{Orientation 1 1 0.5 0.5 1 1 0.5 0.5}}";
|
| 752 |
+
}
|
| 753 |
+
out << std::endl;
|
| 754 |
+
}
|
| 755 |
+
|
| 756 |
+
void ExtractGHKM::WriteSourceLabelSet(
|
| 757 |
+
const std::map<std::string,size_t> &sourceLabels,
|
| 758 |
+
std::ostream &out) const
|
| 759 |
+
{
|
| 760 |
+
out << sourceLabels.size() << std::endl;
|
| 761 |
+
for (std::map<std::string,size_t>::const_iterator iter=sourceLabels.begin();
|
| 762 |
+
iter!=sourceLabels.end(); ++iter) {
|
| 763 |
+
out << iter->first << " " << iter->second << std::endl;
|
| 764 |
+
}
|
| 765 |
+
}
|
| 766 |
+
|
| 767 |
+
void ExtractGHKM::CollectWordLabelCounts(
|
| 768 |
+
SyntaxTree &root,
|
| 769 |
+
const Options &options,
|
| 770 |
+
std::map<std::string, int> &wordCount,
|
| 771 |
+
std::map<std::string, std::string> &wordLabel)
|
| 772 |
+
{
|
| 773 |
+
for (SyntaxTree::ConstLeafIterator p(root);
|
| 774 |
+
p != SyntaxTree::ConstLeafIterator(); ++p) {
|
| 775 |
+
const SyntaxTree &leaf = *p;
|
| 776 |
+
const std::string &word = leaf.value().label;
|
| 777 |
+
const SyntaxTree *ancestor = leaf.parent();
|
| 778 |
+
// If unary rule elimination is enabled and this word is at the end of a
|
| 779 |
+
// chain of unary rewrites, e.g.
|
| 780 |
+
// PN-SB -> NE -> word
|
| 781 |
+
// then record the constituent label at the top of the chain instead of
|
| 782 |
+
// the part-of-speech label.
|
| 783 |
+
while (!options.allowUnary &&
|
| 784 |
+
ancestor->parent() &&
|
| 785 |
+
ancestor->parent()->children().size() == 1) {
|
| 786 |
+
ancestor = ancestor->parent();
|
| 787 |
+
}
|
| 788 |
+
const std::string &label = ancestor->value().label;
|
| 789 |
+
++wordCount[word];
|
| 790 |
+
wordLabel[word] = label;
|
| 791 |
+
}
|
| 792 |
+
}
|
| 793 |
+
|
| 794 |
+
std::vector<std::string> ExtractGHKM::ReadTokens(const SyntaxTree &root) const
|
| 795 |
+
{
|
| 796 |
+
std::vector<std::string> tokens;
|
| 797 |
+
for (SyntaxTree::ConstLeafIterator p(root);
|
| 798 |
+
p != SyntaxTree::ConstLeafIterator(); ++p) {
|
| 799 |
+
const SyntaxTree &leaf = *p;
|
| 800 |
+
const std::string &word = leaf.value().label;
|
| 801 |
+
tokens.push_back(word);
|
| 802 |
+
}
|
| 803 |
+
return tokens;
|
| 804 |
+
}
|
| 805 |
+
|
| 806 |
+
void ExtractGHKM::WriteUnknownWordLabel(
|
| 807 |
+
const std::map<std::string, int> &wordCount,
|
| 808 |
+
const std::map<std::string, std::string> &wordLabel,
|
| 809 |
+
const Options &options,
|
| 810 |
+
std::ostream &out,
|
| 811 |
+
bool writeCounts) const
|
| 812 |
+
{
|
| 813 |
+
if (!options.unknownWordSoftMatchesFile.empty()) {
|
| 814 |
+
out << "UNK 1" << std::endl;
|
| 815 |
+
return;
|
| 816 |
+
}
|
| 817 |
+
|
| 818 |
+
std::map<std::string, int> labelCount;
|
| 819 |
+
int total = 0;
|
| 820 |
+
for (std::map<std::string, int>::const_iterator p = wordCount.begin();
|
| 821 |
+
p != wordCount.end(); ++p) {
|
| 822 |
+
// Only consider singletons.
|
| 823 |
+
if (p->second == 1) {
|
| 824 |
+
std::map<std::string, std::string>::const_iterator q =
|
| 825 |
+
wordLabel.find(p->first);
|
| 826 |
+
assert(q != wordLabel.end());
|
| 827 |
+
if (options.stripBitParLabels) {
|
| 828 |
+
size_t pos = q->second.find('-');
|
| 829 |
+
if (pos == std::string::npos) {
|
| 830 |
+
++labelCount[q->second];
|
| 831 |
+
} else {
|
| 832 |
+
++labelCount[q->second.substr(0,pos)];
|
| 833 |
+
}
|
| 834 |
+
} else {
|
| 835 |
+
++labelCount[q->second];
|
| 836 |
+
}
|
| 837 |
+
++total;
|
| 838 |
+
}
|
| 839 |
+
}
|
| 840 |
+
if ( writeCounts ) {
|
| 841 |
+
for (std::map<std::string, int>::const_iterator p = labelCount.begin();
|
| 842 |
+
p != labelCount.end(); ++p) {
|
| 843 |
+
out << p->first << " " << p->second << std::endl;
|
| 844 |
+
}
|
| 845 |
+
} else {
|
| 846 |
+
for (std::map<std::string, int>::const_iterator p = labelCount.begin();
|
| 847 |
+
p != labelCount.end(); ++p) {
|
| 848 |
+
double ratio = static_cast<double>(p->second) / static_cast<double>(total);
|
| 849 |
+
if (ratio >= options.unknownWordMinRelFreq) {
|
| 850 |
+
float weight = options.unknownWordUniform ? 1.0f : ratio;
|
| 851 |
+
out << p->first << " " << weight << std::endl;
|
| 852 |
+
}
|
| 853 |
+
}
|
| 854 |
+
}
|
| 855 |
+
}
|
| 856 |
+
|
| 857 |
+
void ExtractGHKM::WriteUnknownWordSoftMatches(
|
| 858 |
+
const std::set<std::string> &labelSet,
|
| 859 |
+
std::ostream &out) const
|
| 860 |
+
{
|
| 861 |
+
for (std::set<std::string>::const_iterator p = labelSet.begin(); p != labelSet.end(); ++p) {
|
| 862 |
+
std::string label = *p;
|
| 863 |
+
out << "UNK " << label << std::endl;
|
| 864 |
+
}
|
| 865 |
+
}
|
| 866 |
+
|
| 867 |
+
void ExtractGHKM::StripBitParLabels(
|
| 868 |
+
const std::set<std::string> &labelSet,
|
| 869 |
+
const std::map<std::string, int> &topLabelSet,
|
| 870 |
+
std::set<std::string> &outLabelSet,
|
| 871 |
+
std::map<std::string, int> &outTopLabelSet) const
|
| 872 |
+
{
|
| 873 |
+
for (std::set<std::string>::const_iterator it=labelSet.begin();
|
| 874 |
+
it!=labelSet.end(); ++it) {
|
| 875 |
+
size_t pos = it->find('-');
|
| 876 |
+
if (pos == std::string::npos) {
|
| 877 |
+
outLabelSet.insert(*it);
|
| 878 |
+
} else {
|
| 879 |
+
outLabelSet.insert(it->substr(0,pos));
|
| 880 |
+
}
|
| 881 |
+
}
|
| 882 |
+
for (std::map<std::string,int>::const_iterator it=topLabelSet.begin();
|
| 883 |
+
it!=topLabelSet.end(); ++it) {
|
| 884 |
+
size_t pos = it->first.find('-');
|
| 885 |
+
std::string stripped;
|
| 886 |
+
if (pos == std::string::npos) {
|
| 887 |
+
stripped = it->first;
|
| 888 |
+
} else {
|
| 889 |
+
stripped = it->first.substr(0,pos);
|
| 890 |
+
}
|
| 891 |
+
std::map<std::string, int>::iterator found=outTopLabelSet.find(stripped);
|
| 892 |
+
if (found != outTopLabelSet.end()) {
|
| 893 |
+
found->second += it->second;
|
| 894 |
+
} else {
|
| 895 |
+
outTopLabelSet.insert(std::pair<std::string,int>(stripped,it->second));
|
| 896 |
+
}
|
| 897 |
+
}
|
| 898 |
+
}
|
| 899 |
+
|
| 900 |
+
} // namespace GHKM
|
| 901 |
+
} // namespace Syntax
|
| 902 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.h
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include <map>
|
| 23 |
+
#include <ostream>
|
| 24 |
+
#include <set>
|
| 25 |
+
#include <string>
|
| 26 |
+
#include <vector>
|
| 27 |
+
|
| 28 |
+
#include "OutputFileStream.h"
|
| 29 |
+
#include "SyntaxTree.h"
|
| 30 |
+
|
| 31 |
+
#include "syntax-common/tool.h"
|
| 32 |
+
|
| 33 |
+
namespace MosesTraining
|
| 34 |
+
{
|
| 35 |
+
namespace Syntax
|
| 36 |
+
{
|
| 37 |
+
namespace GHKM
|
| 38 |
+
{
|
| 39 |
+
|
| 40 |
+
struct Options;
|
| 41 |
+
|
| 42 |
+
class ExtractGHKM : public Tool
|
| 43 |
+
{
|
| 44 |
+
public:
|
| 45 |
+
ExtractGHKM() : Tool("extract-ghkm") {}
|
| 46 |
+
|
| 47 |
+
virtual int Main(int argc, char *argv[]);
|
| 48 |
+
|
| 49 |
+
private:
|
| 50 |
+
void RecordTreeLabels(const SyntaxTree &, std::set<std::string> &);
|
| 51 |
+
void CollectWordLabelCounts(SyntaxTree &,
|
| 52 |
+
const Options &,
|
| 53 |
+
std::map<std::string, int> &,
|
| 54 |
+
std::map<std::string, std::string> &);
|
| 55 |
+
void WriteUnknownWordLabel(const std::map<std::string, int> &,
|
| 56 |
+
const std::map<std::string, std::string> &,
|
| 57 |
+
const Options &,
|
| 58 |
+
std::ostream &,
|
| 59 |
+
bool writeCounts=false) const;
|
| 60 |
+
void WriteUnknownWordSoftMatches(const std::set<std::string> &,
|
| 61 |
+
std::ostream &) const;
|
| 62 |
+
void WriteGlueGrammar(const std::set<std::string> &,
|
| 63 |
+
const std::map<std::string, int> &,
|
| 64 |
+
const std::map<std::string,size_t> &,
|
| 65 |
+
const Options &,
|
| 66 |
+
std::ostream &) const;
|
| 67 |
+
void WriteSourceLabelSet(const std::map<std::string,size_t> &,
|
| 68 |
+
std::ostream &) const;
|
| 69 |
+
void StripBitParLabels(const std::set<std::string> &labelSet,
|
| 70 |
+
const std::map<std::string, int> &topLabelSet,
|
| 71 |
+
std::set<std::string> &outLabelSet,
|
| 72 |
+
std::map<std::string, int> &outTopLabelSet) const;
|
| 73 |
+
|
| 74 |
+
std::vector<std::string> ReadTokens(const std::string &) const;
|
| 75 |
+
std::vector<std::string> ReadTokens(const SyntaxTree &root) const;
|
| 76 |
+
|
| 77 |
+
void ProcessOptions(int, char *[], Options &) const;
|
| 78 |
+
};
|
| 79 |
+
|
| 80 |
+
} // namespace GHKM
|
| 81 |
+
} // namespace Syntax
|
| 82 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Jamfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
exe extract-ghkm : [ glob *.cpp ] ..//syntax-common ..//deps ../..//boost_iostreams ../..//boost_program_options ../..//z : <include>.. ;
|
mosesdecoder/phrase-extract/extract-ghkm/Main.cpp
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "ExtractGHKM.h"
|
| 21 |
+
|
| 22 |
+
int main(int argc, char *argv[])
|
| 23 |
+
{
|
| 24 |
+
MosesTraining::Syntax::GHKM::ExtractGHKM tool;
|
| 25 |
+
return tool.Main(argc, argv);
|
| 26 |
+
}
|
mosesdecoder/phrase-extract/extract-ghkm/Node.cpp
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "Node.h"
|
| 21 |
+
|
| 22 |
+
#include "Subgraph.h"
|
| 23 |
+
|
| 24 |
+
namespace MosesTraining
|
| 25 |
+
{
|
| 26 |
+
namespace Syntax
|
| 27 |
+
{
|
| 28 |
+
namespace GHKM
|
| 29 |
+
{
|
| 30 |
+
|
| 31 |
+
Node::~Node()
|
| 32 |
+
{
|
| 33 |
+
for (std::vector<const Subgraph*>::const_iterator p(m_rules.begin());
|
| 34 |
+
p != m_rules.end(); ++p) {
|
| 35 |
+
delete *p;
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
bool Node::IsPreterminal() const
|
| 40 |
+
{
|
| 41 |
+
return (m_type == TREE
|
| 42 |
+
&& m_children.size() == 1
|
| 43 |
+
&& m_children[0]->m_type == TARGET);
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
void Node::PropagateIndex(int index)
|
| 47 |
+
{
|
| 48 |
+
m_span.insert(index);
|
| 49 |
+
for (std::vector<Node *>::const_iterator p(m_parents.begin());
|
| 50 |
+
p != m_parents.end(); ++p) {
|
| 51 |
+
(*p)->PropagateIndex(index);
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
std::vector<std::string> Node::GetTargetWords() const
|
| 56 |
+
{
|
| 57 |
+
std::vector<std::string> targetWords;
|
| 58 |
+
GetTargetWords(targetWords);
|
| 59 |
+
return targetWords;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
void Node::GetTargetWords(std::vector<std::string> &targetWords) const
|
| 63 |
+
{
|
| 64 |
+
if (m_type == TARGET) {
|
| 65 |
+
targetWords.push_back(m_label);
|
| 66 |
+
} else {
|
| 67 |
+
for (std::vector<Node *>::const_iterator p(m_children.begin());
|
| 68 |
+
p != m_children.end(); ++p) {
|
| 69 |
+
(*p)->GetTargetWords(targetWords);
|
| 70 |
+
}
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
} // namespace GHKM
|
| 75 |
+
} // namespace Syntax
|
| 76 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Node.h
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
#ifndef EXTRACT_GHKM_NODE_H_
|
| 22 |
+
#define EXTRACT_GHKM_NODE_H_
|
| 23 |
+
|
| 24 |
+
#include <cassert>
|
| 25 |
+
#include <iterator>
|
| 26 |
+
#include <string>
|
| 27 |
+
#include <vector>
|
| 28 |
+
|
| 29 |
+
#include "Span.h"
|
| 30 |
+
|
| 31 |
+
namespace MosesTraining
|
| 32 |
+
{
|
| 33 |
+
namespace Syntax
|
| 34 |
+
{
|
| 35 |
+
namespace GHKM
|
| 36 |
+
{
|
| 37 |
+
|
| 38 |
+
class Subgraph;
|
| 39 |
+
|
| 40 |
+
enum NodeType { SOURCE, TARGET, TREE };
|
| 41 |
+
|
| 42 |
+
class Node
|
| 43 |
+
{
|
| 44 |
+
public:
|
| 45 |
+
Node(const std::string &label, NodeType type)
|
| 46 |
+
: m_label(label)
|
| 47 |
+
, m_type(type)
|
| 48 |
+
, m_pcfgScore(0.0f) {}
|
| 49 |
+
|
| 50 |
+
~Node();
|
| 51 |
+
|
| 52 |
+
const std::string &GetLabel() const {
|
| 53 |
+
return m_label;
|
| 54 |
+
}
|
| 55 |
+
NodeType GetType() const {
|
| 56 |
+
return m_type;
|
| 57 |
+
}
|
| 58 |
+
const std::vector<Node*> &GetChildren() const {
|
| 59 |
+
return m_children;
|
| 60 |
+
}
|
| 61 |
+
const std::vector<Node*> &GetParents() const {
|
| 62 |
+
return m_parents;
|
| 63 |
+
}
|
| 64 |
+
float GetPcfgScore() const {
|
| 65 |
+
return m_pcfgScore;
|
| 66 |
+
}
|
| 67 |
+
const Span &GetSpan() const {
|
| 68 |
+
return m_span;
|
| 69 |
+
}
|
| 70 |
+
const Span &GetComplementSpan() const {
|
| 71 |
+
return m_complementSpan;
|
| 72 |
+
}
|
| 73 |
+
const std::vector<const Subgraph*> &GetRules() const {
|
| 74 |
+
return m_rules;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
void SetChildren(const std::vector<Node*> &c) {
|
| 78 |
+
m_children = c;
|
| 79 |
+
}
|
| 80 |
+
void SetParents(const std::vector<Node*> &p) {
|
| 81 |
+
m_parents = p;
|
| 82 |
+
}
|
| 83 |
+
void SetPcfgScore(float s) {
|
| 84 |
+
m_pcfgScore = s;
|
| 85 |
+
}
|
| 86 |
+
void SetSpan(const Span &s) {
|
| 87 |
+
m_span = s;
|
| 88 |
+
}
|
| 89 |
+
void SetComplementSpan(const Span &cs) {
|
| 90 |
+
m_complementSpan = cs;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
void AddChild(Node *c) {
|
| 94 |
+
m_children.push_back(c);
|
| 95 |
+
}
|
| 96 |
+
void AddParent(Node *p) {
|
| 97 |
+
m_parents.push_back(p);
|
| 98 |
+
}
|
| 99 |
+
void AddRule(const Subgraph *s) {
|
| 100 |
+
m_rules.push_back(s);
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
bool IsSink() const {
|
| 104 |
+
return m_children.empty();
|
| 105 |
+
}
|
| 106 |
+
bool IsPreterminal() const;
|
| 107 |
+
|
| 108 |
+
void PropagateIndex(int);
|
| 109 |
+
|
| 110 |
+
std::vector<std::string> GetTargetWords() const;
|
| 111 |
+
|
| 112 |
+
// Gets the path from this node's parent to the root. This node is
|
| 113 |
+
// required to be part of the original parse tree (i.e. not a source word,
|
| 114 |
+
// which can have multiple parents).
|
| 115 |
+
template<typename OutputIterator>
|
| 116 |
+
void GetTreeAncestors(OutputIterator result, bool includeSelf=false);
|
| 117 |
+
|
| 118 |
+
// Returns the lowest common ancestor given a sequence of nodes belonging to
|
| 119 |
+
// the target tree.
|
| 120 |
+
template<typename InputIterator>
|
| 121 |
+
static Node *LowestCommonAncestor(InputIterator first, InputIterator last);
|
| 122 |
+
|
| 123 |
+
private:
|
| 124 |
+
// Disallow copying
|
| 125 |
+
Node(const Node &);
|
| 126 |
+
Node &operator=(const Node &);
|
| 127 |
+
|
| 128 |
+
void GetTargetWords(std::vector<std::string> &) const;
|
| 129 |
+
|
| 130 |
+
std::string m_label;
|
| 131 |
+
NodeType m_type;
|
| 132 |
+
std::vector<Node*> m_children;
|
| 133 |
+
std::vector<Node*> m_parents;
|
| 134 |
+
float m_pcfgScore;
|
| 135 |
+
Span m_span;
|
| 136 |
+
Span m_complementSpan;
|
| 137 |
+
std::vector<const Subgraph*> m_rules;
|
| 138 |
+
};
|
| 139 |
+
|
| 140 |
+
template<typename OutputIterator>
|
| 141 |
+
void Node::GetTreeAncestors(OutputIterator result, bool includeSelf)
|
| 142 |
+
{
|
| 143 |
+
// This function assumes the node is part of the parse tree.
|
| 144 |
+
assert(m_type == TARGET || m_type == TREE);
|
| 145 |
+
|
| 146 |
+
if (includeSelf) {
|
| 147 |
+
*result++ = this;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
Node *ancestor = !(m_parents.empty()) ? m_parents[0] : 0;
|
| 151 |
+
while (ancestor != 0) {
|
| 152 |
+
*result++ = ancestor;
|
| 153 |
+
ancestor = !(ancestor->m_parents.empty()) ? ancestor->m_parents[0] : 0;
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
template<typename InputIterator>
|
| 158 |
+
Node *Node::LowestCommonAncestor(InputIterator first, InputIterator last)
|
| 159 |
+
{
|
| 160 |
+
// Check for an empty sequence.
|
| 161 |
+
if (first == last) {
|
| 162 |
+
return 0;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
// Check for the case that the sequence contains only one distinct node.
|
| 166 |
+
// Also check that every node belongs to the target tree.
|
| 167 |
+
InputIterator p = first;
|
| 168 |
+
Node *lca = *p++;
|
| 169 |
+
for (; p != last; ++p) {
|
| 170 |
+
Node *node = *p;
|
| 171 |
+
assert(node->m_type != SOURCE);
|
| 172 |
+
if (node != lca) {
|
| 173 |
+
lca = 0;
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
if (lca) {
|
| 177 |
+
return lca;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
// Now construct an ancestor path for each node, from itself to the root.
|
| 181 |
+
size_t minPathLength = 0;
|
| 182 |
+
std::vector<std::vector<Node *> > paths;
|
| 183 |
+
for (p = first; p != last; ++p) {
|
| 184 |
+
paths.resize(paths.size()+1);
|
| 185 |
+
(*p)->GetTreeAncestors(std::back_inserter(paths.back()), true);
|
| 186 |
+
size_t pathLength = paths.back().size();
|
| 187 |
+
assert(pathLength > 0);
|
| 188 |
+
if (paths.size() == 1 || pathLength < minPathLength) {
|
| 189 |
+
minPathLength = pathLength;
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
// Search for the start of the longest common suffix by working forward from
|
| 194 |
+
// the the earliest possible starting point to the root.
|
| 195 |
+
for (size_t i = 0; i < minPathLength; ++i) {
|
| 196 |
+
bool match = true;
|
| 197 |
+
for (size_t j = 0; j < paths.size(); ++j) {
|
| 198 |
+
size_t index = paths[j].size() - minPathLength + i;
|
| 199 |
+
assert(index >= 0);
|
| 200 |
+
assert(index < paths[j].size());
|
| 201 |
+
if (j == 0) {
|
| 202 |
+
lca = paths[j][index];
|
| 203 |
+
assert(lca);
|
| 204 |
+
} else if (lca != paths[j][index]) {
|
| 205 |
+
match = false;
|
| 206 |
+
break;
|
| 207 |
+
}
|
| 208 |
+
}
|
| 209 |
+
if (match) {
|
| 210 |
+
return lca;
|
| 211 |
+
}
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
// A lowest common ancestor should have been found.
|
| 215 |
+
assert(false);
|
| 216 |
+
return 0;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
} // namespace GHKM
|
| 220 |
+
} // namespace Syntax
|
| 221 |
+
} // namespace MosesTraining
|
| 222 |
+
|
| 223 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/Options.h
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include <string>
|
| 23 |
+
|
| 24 |
+
namespace MosesTraining
|
| 25 |
+
{
|
| 26 |
+
namespace Syntax
|
| 27 |
+
{
|
| 28 |
+
namespace GHKM
|
| 29 |
+
{
|
| 30 |
+
|
| 31 |
+
struct Options {
|
| 32 |
+
public:
|
| 33 |
+
Options()
|
| 34 |
+
: allowUnary(false)
|
| 35 |
+
, conditionOnTargetLhs(false)
|
| 36 |
+
, gzOutput(false)
|
| 37 |
+
, includeSentenceId(false)
|
| 38 |
+
, maxNodes(15)
|
| 39 |
+
, maxRuleDepth(3)
|
| 40 |
+
, maxRuleSize(3)
|
| 41 |
+
, maxScope(3)
|
| 42 |
+
, minimal(false)
|
| 43 |
+
, partsOfSpeech(false)
|
| 44 |
+
, partsOfSpeechFactor(false)
|
| 45 |
+
, pcfg(false)
|
| 46 |
+
, phraseOrientation(false)
|
| 47 |
+
, sentenceOffset(0)
|
| 48 |
+
, sourceLabels(false)
|
| 49 |
+
, stripBitParLabels(false)
|
| 50 |
+
, stsg(false)
|
| 51 |
+
, t2s(false)
|
| 52 |
+
, treeFragments(false)
|
| 53 |
+
, unknownWordMinRelFreq(0.03f)
|
| 54 |
+
, unknownWordUniform(false)
|
| 55 |
+
, unpairedExtractFormat(false) {}
|
| 56 |
+
|
| 57 |
+
// Positional options
|
| 58 |
+
std::string targetFile;
|
| 59 |
+
std::string sourceFile;
|
| 60 |
+
std::string alignmentFile;
|
| 61 |
+
std::string extractFile;
|
| 62 |
+
|
| 63 |
+
// All other options
|
| 64 |
+
bool allowUnary;
|
| 65 |
+
bool conditionOnTargetLhs;
|
| 66 |
+
std::string glueGrammarFile;
|
| 67 |
+
bool gzOutput;
|
| 68 |
+
bool includeSentenceId;
|
| 69 |
+
int maxNodes;
|
| 70 |
+
int maxRuleDepth;
|
| 71 |
+
int maxRuleSize;
|
| 72 |
+
int maxScope;
|
| 73 |
+
bool minimal;
|
| 74 |
+
bool partsOfSpeech;
|
| 75 |
+
bool partsOfSpeechFactor;
|
| 76 |
+
bool pcfg;
|
| 77 |
+
bool phraseOrientation;
|
| 78 |
+
int sentenceOffset;
|
| 79 |
+
bool sourceLabels;
|
| 80 |
+
std::string sourceLabelSetFile;
|
| 81 |
+
std::string sourceUnknownWordFile;
|
| 82 |
+
bool stripBitParLabels;
|
| 83 |
+
bool stsg;
|
| 84 |
+
bool t2s;
|
| 85 |
+
std::string targetUnknownWordFile;
|
| 86 |
+
bool treeFragments;
|
| 87 |
+
float unknownWordMinRelFreq;
|
| 88 |
+
std::string unknownWordSoftMatchesFile;
|
| 89 |
+
bool unknownWordUniform;
|
| 90 |
+
bool unpairedExtractFormat;
|
| 91 |
+
};
|
| 92 |
+
|
| 93 |
+
} // namespace GHKM
|
| 94 |
+
} // namespace Syntax
|
| 95 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Rule.cpp
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "Rule.h"
|
| 2 |
+
|
| 3 |
+
#include "Node.h"
|
| 4 |
+
#include "Subgraph.h"
|
| 5 |
+
|
| 6 |
+
namespace MosesTraining
|
| 7 |
+
{
|
| 8 |
+
namespace Syntax
|
| 9 |
+
{
|
| 10 |
+
namespace GHKM
|
| 11 |
+
{
|
| 12 |
+
|
| 13 |
+
int Rule::Scope(const std::vector<Symbol> &symbols)
|
| 14 |
+
{
|
| 15 |
+
int scope = 0;
|
| 16 |
+
bool predIsNonTerm = false;
|
| 17 |
+
if (symbols[0].GetType() == NonTerminal) {
|
| 18 |
+
++scope;
|
| 19 |
+
predIsNonTerm = true;
|
| 20 |
+
}
|
| 21 |
+
for (std::size_t i = 1; i < symbols.size(); ++i) {
|
| 22 |
+
bool isNonTerm = symbols[i].GetType() == NonTerminal;
|
| 23 |
+
if (isNonTerm && predIsNonTerm) {
|
| 24 |
+
++scope;
|
| 25 |
+
}
|
| 26 |
+
predIsNonTerm = isNonTerm;
|
| 27 |
+
}
|
| 28 |
+
if (predIsNonTerm) {
|
| 29 |
+
++scope;
|
| 30 |
+
}
|
| 31 |
+
return scope;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
bool Rule::PartitionOrderComp(const Node *a, const Node *b)
|
| 35 |
+
{
|
| 36 |
+
const Span &aSpan = a->GetSpan();
|
| 37 |
+
const Span &bSpan = b->GetSpan();
|
| 38 |
+
assert(!aSpan.empty() && !bSpan.empty());
|
| 39 |
+
return *(aSpan.begin()) < *(bSpan.begin());
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
} // namespace GHKM
|
| 43 |
+
} // namespace Syntax
|
| 44 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Rule.h
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
#ifndef EXTRACT_GHKM_RULE_H_
|
| 3 |
+
#define EXTRACT_GHKM_RULE_H_
|
| 4 |
+
|
| 5 |
+
#include <string>
|
| 6 |
+
#include <vector>
|
| 7 |
+
|
| 8 |
+
#include "Alignment.h"
|
| 9 |
+
|
| 10 |
+
namespace MosesTraining
|
| 11 |
+
{
|
| 12 |
+
namespace Syntax
|
| 13 |
+
{
|
| 14 |
+
namespace GHKM
|
| 15 |
+
{
|
| 16 |
+
|
| 17 |
+
class Node;
|
| 18 |
+
|
| 19 |
+
enum SymbolType { Terminal, NonTerminal };
|
| 20 |
+
|
| 21 |
+
class Symbol
|
| 22 |
+
{
|
| 23 |
+
public:
|
| 24 |
+
Symbol(const std::string &v, SymbolType t) : m_value(v) , m_type(t) {}
|
| 25 |
+
|
| 26 |
+
const std::string &GetValue() const {
|
| 27 |
+
return m_value;
|
| 28 |
+
}
|
| 29 |
+
SymbolType GetType() const {
|
| 30 |
+
return m_type;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
private:
|
| 34 |
+
std::string m_value;
|
| 35 |
+
SymbolType m_type;
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
// Base class for ScfgRule and StsgRule.
|
| 39 |
+
class Rule
|
| 40 |
+
{
|
| 41 |
+
public:
|
| 42 |
+
virtual ~Rule() {}
|
| 43 |
+
|
| 44 |
+
const Alignment &GetAlignment() const {
|
| 45 |
+
return m_alignment;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
virtual int Scope() const = 0;
|
| 49 |
+
|
| 50 |
+
protected:
|
| 51 |
+
static bool PartitionOrderComp(const Node *, const Node *);
|
| 52 |
+
|
| 53 |
+
static int Scope(const std::vector<Symbol>&);
|
| 54 |
+
|
| 55 |
+
Alignment m_alignment;
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
} // namespace GHKM
|
| 59 |
+
} // namespace Syntax
|
| 60 |
+
} // namespace MosesTraining
|
| 61 |
+
|
| 62 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.cpp
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "ScfgRule.h"
|
| 21 |
+
|
| 22 |
+
#include <algorithm>
|
| 23 |
+
|
| 24 |
+
#include "Node.h"
|
| 25 |
+
#include "Subgraph.h"
|
| 26 |
+
#include "SyntaxNode.h"
|
| 27 |
+
#include "SyntaxNodeCollection.h"
|
| 28 |
+
|
| 29 |
+
namespace MosesTraining
|
| 30 |
+
{
|
| 31 |
+
namespace Syntax
|
| 32 |
+
{
|
| 33 |
+
namespace GHKM
|
| 34 |
+
{
|
| 35 |
+
|
| 36 |
+
ScfgRule::ScfgRule(const Subgraph &fragment,
|
| 37 |
+
const SyntaxNodeCollection *sourceNodeCollection)
|
| 38 |
+
: m_graphFragment(fragment)
|
| 39 |
+
, m_sourceLHS("X", NonTerminal)
|
| 40 |
+
, m_targetLHS(fragment.GetRoot()->GetLabel(), NonTerminal)
|
| 41 |
+
, m_pcfgScore(fragment.GetPcfgScore())
|
| 42 |
+
, m_hasSourceLabels(sourceNodeCollection)
|
| 43 |
+
{
|
| 44 |
+
|
| 45 |
+
// Source RHS
|
| 46 |
+
|
| 47 |
+
const std::set<const Node *> &leaves = fragment.GetLeaves();
|
| 48 |
+
|
| 49 |
+
std::vector<const Node *> sourceRHSNodes;
|
| 50 |
+
sourceRHSNodes.reserve(leaves.size());
|
| 51 |
+
for (std::set<const Node *>::const_iterator p(leaves.begin());
|
| 52 |
+
p != leaves.end(); ++p) {
|
| 53 |
+
const Node &leaf = **p;
|
| 54 |
+
if (!leaf.GetSpan().empty()) {
|
| 55 |
+
sourceRHSNodes.push_back(&leaf);
|
| 56 |
+
}
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
std::sort(sourceRHSNodes.begin(), sourceRHSNodes.end(), PartitionOrderComp);
|
| 60 |
+
|
| 61 |
+
// Build a mapping from target nodes to source-order indices, so that we
|
| 62 |
+
// can construct the Alignment object later.
|
| 63 |
+
std::map<const Node *, std::vector<int> > sourceOrder;
|
| 64 |
+
|
| 65 |
+
m_sourceRHS.reserve(sourceRHSNodes.size());
|
| 66 |
+
m_numberOfNonTerminals = 0;
|
| 67 |
+
int srcIndex = 0;
|
| 68 |
+
for (std::vector<const Node *>::const_iterator p(sourceRHSNodes.begin());
|
| 69 |
+
p != sourceRHSNodes.end(); ++p, ++srcIndex) {
|
| 70 |
+
const Node &sinkNode = **p;
|
| 71 |
+
if (sinkNode.GetType() == TREE) {
|
| 72 |
+
m_sourceRHS.push_back(Symbol("X", NonTerminal));
|
| 73 |
+
sourceOrder[&sinkNode].push_back(srcIndex);
|
| 74 |
+
++m_numberOfNonTerminals;
|
| 75 |
+
} else {
|
| 76 |
+
assert(sinkNode.GetType() == SOURCE);
|
| 77 |
+
m_sourceRHS.push_back(Symbol(sinkNode.GetLabel(), Terminal));
|
| 78 |
+
// Add all aligned target words to the sourceOrder map
|
| 79 |
+
const std::vector<Node *> &parents(sinkNode.GetParents());
|
| 80 |
+
for (std::vector<Node *>::const_iterator q(parents.begin());
|
| 81 |
+
q != parents.end(); ++q) {
|
| 82 |
+
if ((*q)->GetType() == TARGET) {
|
| 83 |
+
sourceOrder[*q].push_back(srcIndex);
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
if (sourceNodeCollection) {
|
| 88 |
+
// Source syntax label
|
| 89 |
+
PushSourceLabel(sourceNodeCollection,&sinkNode,"XRHS");
|
| 90 |
+
}
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
// Target RHS + alignment
|
| 94 |
+
|
| 95 |
+
std::vector<const Node *> targetLeaves;
|
| 96 |
+
fragment.GetTargetLeaves(targetLeaves);
|
| 97 |
+
|
| 98 |
+
m_alignment.reserve(targetLeaves.size()); // might be too much but that's OK
|
| 99 |
+
m_targetRHS.reserve(targetLeaves.size());
|
| 100 |
+
|
| 101 |
+
for (std::vector<const Node *>::const_iterator p(targetLeaves.begin());
|
| 102 |
+
p != targetLeaves.end(); ++p) {
|
| 103 |
+
const Node &leaf = **p;
|
| 104 |
+
if (leaf.GetSpan().empty()) {
|
| 105 |
+
// The node doesn't cover any source words, so we can only add
|
| 106 |
+
// terminals to the target RHS (not a non-terminal).
|
| 107 |
+
std::vector<std::string> targetWords(leaf.GetTargetWords());
|
| 108 |
+
for (std::vector<std::string>::const_iterator q(targetWords.begin());
|
| 109 |
+
q != targetWords.end(); ++q) {
|
| 110 |
+
m_targetRHS.push_back(Symbol(*q, Terminal));
|
| 111 |
+
}
|
| 112 |
+
} else if (leaf.GetType() == SOURCE) {
|
| 113 |
+
// Do nothing
|
| 114 |
+
} else {
|
| 115 |
+
SymbolType type = (leaf.GetType() == TREE) ? NonTerminal : Terminal;
|
| 116 |
+
m_targetRHS.push_back(Symbol(leaf.GetLabel(), type));
|
| 117 |
+
|
| 118 |
+
int tgtIndex = m_targetRHS.size()-1;
|
| 119 |
+
std::map<const Node *, std::vector<int> >::iterator q(sourceOrder.find(&leaf));
|
| 120 |
+
assert(q != sourceOrder.end());
|
| 121 |
+
std::vector<int> &sourceNodes = q->second;
|
| 122 |
+
for (std::vector<int>::iterator r(sourceNodes.begin());
|
| 123 |
+
r != sourceNodes.end(); ++r) {
|
| 124 |
+
int srcIndex = *r;
|
| 125 |
+
m_alignment.push_back(std::make_pair(srcIndex, tgtIndex));
|
| 126 |
+
}
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
if (sourceNodeCollection) {
|
| 131 |
+
// Source syntax label for root node (if sourceNodeCollection available)
|
| 132 |
+
PushSourceLabel(sourceNodeCollection,fragment.GetRoot(),"XLHS");
|
| 133 |
+
// All non-terminal spans (including the LHS) should have obtained a label
|
| 134 |
+
// (a source-side syntactic constituent label if the span matches, "XLHS" otherwise)
|
| 135 |
+
// assert(m_sourceLabels.size() == m_numberOfNonTerminals+1);
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
void ScfgRule::PushSourceLabel(const SyntaxNodeCollection *sourceNodeCollection,
|
| 140 |
+
const Node *node,
|
| 141 |
+
const std::string &nonMatchingLabel)
|
| 142 |
+
{
|
| 143 |
+
ContiguousSpan span = Closure(node->GetSpan());
|
| 144 |
+
if (sourceNodeCollection->HasNode(span.first,span.second)) { // does a source constituent match the span?
|
| 145 |
+
std::vector<SyntaxNode*> sourceLabels =
|
| 146 |
+
sourceNodeCollection->GetNodes(span.first,span.second);
|
| 147 |
+
if (!sourceLabels.empty()) {
|
| 148 |
+
// store the topmost matching label from the source syntax tree
|
| 149 |
+
m_sourceLabels.push_back(sourceLabels.back()->label);
|
| 150 |
+
}
|
| 151 |
+
} else {
|
| 152 |
+
// no matching source-side syntactic constituent: store nonMatchingLabel
|
| 153 |
+
m_sourceLabels.push_back(nonMatchingLabel);
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
// TODO: rather implement the method external to ScfgRule
|
| 158 |
+
void ScfgRule::UpdateSourceLabelCoocCounts(std::map< std::string, std::map<std::string,float>* > &coocCounts, float count) const
|
| 159 |
+
{
|
| 160 |
+
std::map<int, int> sourceToTargetNTMap;
|
| 161 |
+
std::map<int, int> targetToSourceNTMap;
|
| 162 |
+
|
| 163 |
+
for (Alignment::const_iterator p(m_alignment.begin());
|
| 164 |
+
p != m_alignment.end(); ++p) {
|
| 165 |
+
if ( m_sourceRHS[p->first].GetType() == NonTerminal ) {
|
| 166 |
+
assert(m_targetRHS[p->second].GetType() == NonTerminal);
|
| 167 |
+
sourceToTargetNTMap[p->first] = p->second;
|
| 168 |
+
}
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
size_t sourceIndex = 0;
|
| 172 |
+
size_t sourceNonTerminalIndex = 0;
|
| 173 |
+
for (std::vector<Symbol>::const_iterator p=m_sourceRHS.begin();
|
| 174 |
+
p != m_sourceRHS.end(); ++p, ++sourceIndex) {
|
| 175 |
+
if ( p->GetType() == NonTerminal ) {
|
| 176 |
+
const std::string &sourceLabel = m_sourceLabels[sourceNonTerminalIndex];
|
| 177 |
+
int targetIndex = sourceToTargetNTMap[sourceIndex];
|
| 178 |
+
const std::string &targetLabel = m_targetRHS[targetIndex].GetValue();
|
| 179 |
+
++sourceNonTerminalIndex;
|
| 180 |
+
|
| 181 |
+
std::map<std::string,float>* countMap = NULL;
|
| 182 |
+
std::map< std::string, std::map<std::string,float>* >::iterator iter = coocCounts.find(sourceLabel);
|
| 183 |
+
if ( iter == coocCounts.end() ) {
|
| 184 |
+
std::map<std::string,float> *newCountMap = new std::map<std::string,float>();
|
| 185 |
+
std::pair< std::map< std::string, std::map<std::string,float>* >::iterator, bool > inserted =
|
| 186 |
+
coocCounts.insert( std::pair< std::string, std::map<std::string,float>* >(sourceLabel, newCountMap) );
|
| 187 |
+
assert(inserted.second);
|
| 188 |
+
countMap = (inserted.first)->second;
|
| 189 |
+
} else {
|
| 190 |
+
countMap = iter->second;
|
| 191 |
+
}
|
| 192 |
+
std::pair< std::map<std::string,float>::iterator, bool > inserted =
|
| 193 |
+
countMap->insert( std::pair< std::string,float>(targetLabel, count) );
|
| 194 |
+
if ( !inserted.second ) {
|
| 195 |
+
(inserted.first)->second += count;
|
| 196 |
+
}
|
| 197 |
+
}
|
| 198 |
+
}
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
} // namespace GHKM
|
| 202 |
+
} // namespace Syntax
|
| 203 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.h
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include <string>
|
| 23 |
+
#include <vector>
|
| 24 |
+
#include <list>
|
| 25 |
+
#include <memory>
|
| 26 |
+
#include <iostream>
|
| 27 |
+
|
| 28 |
+
#include "Alignment.h"
|
| 29 |
+
#include "Rule.h"
|
| 30 |
+
#include "SyntaxNodeCollection.h"
|
| 31 |
+
|
| 32 |
+
namespace MosesTraining
|
| 33 |
+
{
|
| 34 |
+
namespace Syntax
|
| 35 |
+
{
|
| 36 |
+
namespace GHKM
|
| 37 |
+
{
|
| 38 |
+
|
| 39 |
+
class Node;
|
| 40 |
+
class Subgraph;
|
| 41 |
+
|
| 42 |
+
class ScfgRule : public Rule
|
| 43 |
+
{
|
| 44 |
+
public:
|
| 45 |
+
ScfgRule(const Subgraph &fragment,
|
| 46 |
+
const SyntaxNodeCollection *sourceNodeCollection = 0);
|
| 47 |
+
|
| 48 |
+
const Subgraph &GetGraphFragment() const {
|
| 49 |
+
return m_graphFragment;
|
| 50 |
+
}
|
| 51 |
+
const Symbol &GetSourceLHS() const {
|
| 52 |
+
return m_sourceLHS;
|
| 53 |
+
}
|
| 54 |
+
const Symbol &GetTargetLHS() const {
|
| 55 |
+
return m_targetLHS;
|
| 56 |
+
}
|
| 57 |
+
const std::vector<Symbol> &GetSourceRHS() const {
|
| 58 |
+
return m_sourceRHS;
|
| 59 |
+
}
|
| 60 |
+
const std::vector<Symbol> &GetTargetRHS() const {
|
| 61 |
+
return m_targetRHS;
|
| 62 |
+
}
|
| 63 |
+
float GetPcfgScore() const {
|
| 64 |
+
return m_pcfgScore;
|
| 65 |
+
}
|
| 66 |
+
bool HasSourceLabels() const {
|
| 67 |
+
return m_hasSourceLabels;
|
| 68 |
+
}
|
| 69 |
+
void PrintSourceLabels(std::ostream &out) const {
|
| 70 |
+
for (std::vector<std::string>::const_iterator it = m_sourceLabels.begin();
|
| 71 |
+
it != m_sourceLabels.end(); ++it) {
|
| 72 |
+
out << " " << (*it);
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
void UpdateSourceLabelCoocCounts(std::map< std::string, std::map<std::string,float>* > &coocCounts,
|
| 76 |
+
float count) const;
|
| 77 |
+
|
| 78 |
+
int Scope() const {
|
| 79 |
+
return Rule::Scope(m_sourceRHS);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
private:
|
| 83 |
+
void PushSourceLabel(const SyntaxNodeCollection *sourceNodeCollection,
|
| 84 |
+
const Node *node, const std::string &nonMatchingLabel);
|
| 85 |
+
|
| 86 |
+
const Subgraph& m_graphFragment;
|
| 87 |
+
Symbol m_sourceLHS;
|
| 88 |
+
Symbol m_targetLHS;
|
| 89 |
+
std::vector<Symbol> m_sourceRHS;
|
| 90 |
+
std::vector<Symbol> m_targetRHS;
|
| 91 |
+
float m_pcfgScore;
|
| 92 |
+
bool m_hasSourceLabels;
|
| 93 |
+
std::vector<std::string> m_sourceLabels;
|
| 94 |
+
unsigned m_numberOfNonTerminals;
|
| 95 |
+
};
|
| 96 |
+
|
| 97 |
+
} // namespace GHKM
|
| 98 |
+
} // namespace Syntax
|
| 99 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.cpp
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "ScfgRuleWriter.h"
|
| 21 |
+
|
| 22 |
+
#include <cassert>
|
| 23 |
+
#include <cmath>
|
| 24 |
+
#include <ostream>
|
| 25 |
+
#include <map>
|
| 26 |
+
#include <sstream>
|
| 27 |
+
#include <vector>
|
| 28 |
+
|
| 29 |
+
#include "Alignment.h"
|
| 30 |
+
#include "Options.h"
|
| 31 |
+
#include "ScfgRule.h"
|
| 32 |
+
|
| 33 |
+
namespace MosesTraining
|
| 34 |
+
{
|
| 35 |
+
namespace Syntax
|
| 36 |
+
{
|
| 37 |
+
namespace GHKM
|
| 38 |
+
{
|
| 39 |
+
|
| 40 |
+
void ScfgRuleWriter::Write(const ScfgRule &rule, size_t lineNum, bool printEndl)
|
| 41 |
+
{
|
| 42 |
+
std::ostringstream sourceSS;
|
| 43 |
+
std::ostringstream targetSS;
|
| 44 |
+
|
| 45 |
+
if (m_options.unpairedExtractFormat) {
|
| 46 |
+
WriteUnpairedFormat(rule, sourceSS, targetSS);
|
| 47 |
+
} else {
|
| 48 |
+
WriteStandardFormat(rule, sourceSS, targetSS);
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
// Write the rule to the forward and inverse extract files.
|
| 52 |
+
if (m_options.t2s) {
|
| 53 |
+
// If model is tree-to-string then flip the source and target.
|
| 54 |
+
m_fwd << targetSS.str() << " ||| " << sourceSS.str() << " |||";
|
| 55 |
+
m_inv << sourceSS.str() << " ||| " << targetSS.str() << " |||";
|
| 56 |
+
} else {
|
| 57 |
+
m_fwd << sourceSS.str() << " ||| " << targetSS.str() << " |||";
|
| 58 |
+
m_inv << targetSS.str() << " ||| " << sourceSS.str() << " |||";
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
const Alignment &alignment = rule.GetAlignment();
|
| 62 |
+
for (Alignment::const_iterator p = alignment.begin();
|
| 63 |
+
p != alignment.end(); ++p) {
|
| 64 |
+
if (m_options.t2s) {
|
| 65 |
+
// If model is tree-to-string then flip the source and target.
|
| 66 |
+
m_fwd << " " << p->second << "-" << p->first;
|
| 67 |
+
m_inv << " " << p->first << "-" << p->second;
|
| 68 |
+
} else {
|
| 69 |
+
m_fwd << " " << p->first << "-" << p->second;
|
| 70 |
+
m_inv << " " << p->second << "-" << p->first;
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
if (m_options.includeSentenceId) {
|
| 75 |
+
if (m_options.t2s) {
|
| 76 |
+
m_inv << " ||| " << lineNum;
|
| 77 |
+
} else {
|
| 78 |
+
m_fwd << " ||| " << lineNum;
|
| 79 |
+
}
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
// Write a count of 1.
|
| 83 |
+
m_fwd << " ||| 1";
|
| 84 |
+
m_inv << " ||| 1";
|
| 85 |
+
|
| 86 |
+
// Write the PCFG score (if requested).
|
| 87 |
+
if (m_options.pcfg) {
|
| 88 |
+
m_fwd << " ||| " << std::exp(rule.GetPcfgScore());
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
m_fwd << " |||";
|
| 92 |
+
|
| 93 |
+
if (m_options.sourceLabels && rule.HasSourceLabels()) {
|
| 94 |
+
m_fwd << " {{SourceLabels";
|
| 95 |
+
rule.PrintSourceLabels(m_fwd);
|
| 96 |
+
m_fwd << "}}";
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
if (printEndl) {
|
| 100 |
+
m_fwd << std::endl;
|
| 101 |
+
m_inv << std::endl;
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
void ScfgRuleWriter::WriteStandardFormat(const ScfgRule &rule,
|
| 106 |
+
std::ostream &sourceSS,
|
| 107 |
+
std::ostream &targetSS)
|
| 108 |
+
{
|
| 109 |
+
const std::vector<Symbol> &sourceRHS = rule.GetSourceRHS();
|
| 110 |
+
const std::vector<Symbol> &targetRHS = rule.GetTargetRHS();
|
| 111 |
+
|
| 112 |
+
std::map<int, int> sourceToTargetNTMap;
|
| 113 |
+
std::map<int, int> targetToSourceNTMap;
|
| 114 |
+
|
| 115 |
+
const Alignment &alignment = rule.GetAlignment();
|
| 116 |
+
|
| 117 |
+
for (Alignment::const_iterator p(alignment.begin());
|
| 118 |
+
p != alignment.end(); ++p) {
|
| 119 |
+
if (sourceRHS[p->first].GetType() == NonTerminal) {
|
| 120 |
+
assert(targetRHS[p->second].GetType() == NonTerminal);
|
| 121 |
+
sourceToTargetNTMap[p->first] = p->second;
|
| 122 |
+
targetToSourceNTMap[p->second] = p->first;
|
| 123 |
+
}
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
// If parts-of-speech as a factor requested: retrieve preterminals from graph fragment
|
| 127 |
+
std::vector<std::string> partsOfSpeech;
|
| 128 |
+
if (m_options.partsOfSpeechFactor) {
|
| 129 |
+
const Subgraph &graphFragment = rule.GetGraphFragment();
|
| 130 |
+
graphFragment.GetPartsOfSpeech(partsOfSpeech);
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
// Write the source side of the rule to sourceSS.
|
| 134 |
+
int i = 0;
|
| 135 |
+
for (std::vector<Symbol>::const_iterator p(sourceRHS.begin());
|
| 136 |
+
p != sourceRHS.end(); ++p, ++i) {
|
| 137 |
+
WriteSymbol(*p, sourceSS);
|
| 138 |
+
if (p->GetType() == NonTerminal) {
|
| 139 |
+
int targetIndex = sourceToTargetNTMap[i];
|
| 140 |
+
WriteSymbol(targetRHS[targetIndex], sourceSS);
|
| 141 |
+
}
|
| 142 |
+
sourceSS << " ";
|
| 143 |
+
}
|
| 144 |
+
if (m_options.conditionOnTargetLhs) {
|
| 145 |
+
WriteSymbol(rule.GetTargetLHS(), sourceSS);
|
| 146 |
+
} else {
|
| 147 |
+
WriteSymbol(rule.GetSourceLHS(), sourceSS);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
// Write the target side of the rule to targetSS.
|
| 151 |
+
i = 0;
|
| 152 |
+
int targetTerminalIndex = 0;
|
| 153 |
+
for (std::vector<Symbol>::const_iterator p(targetRHS.begin());
|
| 154 |
+
p != targetRHS.end(); ++p, ++i) {
|
| 155 |
+
if (p->GetType() == NonTerminal) {
|
| 156 |
+
int sourceIndex = targetToSourceNTMap[i];
|
| 157 |
+
WriteSymbol(sourceRHS[sourceIndex], targetSS);
|
| 158 |
+
}
|
| 159 |
+
WriteSymbol(*p, targetSS);
|
| 160 |
+
// If parts-of-speech as a factor requested: write part-of-speech
|
| 161 |
+
if (m_options.partsOfSpeechFactor && (p->GetType() != NonTerminal)) {
|
| 162 |
+
assert(targetTerminalIndex<partsOfSpeech.size());
|
| 163 |
+
targetSS << "|" << partsOfSpeech[targetTerminalIndex];
|
| 164 |
+
++targetTerminalIndex;
|
| 165 |
+
}
|
| 166 |
+
targetSS << " ";
|
| 167 |
+
}
|
| 168 |
+
WriteSymbol(rule.GetTargetLHS(), targetSS);
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
void ScfgRuleWriter::WriteUnpairedFormat(const ScfgRule &rule,
|
| 172 |
+
std::ostream &sourceSS,
|
| 173 |
+
std::ostream &targetSS)
|
| 174 |
+
{
|
| 175 |
+
const std::vector<Symbol> &sourceRHS = rule.GetSourceRHS();
|
| 176 |
+
const std::vector<Symbol> &targetRHS = rule.GetTargetRHS();
|
| 177 |
+
|
| 178 |
+
// If parts-of-speech as a factor requested: retrieve preterminals from graph fragment
|
| 179 |
+
std::vector<std::string> partsOfSpeech;
|
| 180 |
+
if (m_options.partsOfSpeechFactor) {
|
| 181 |
+
const Subgraph &graphFragment = rule.GetGraphFragment();
|
| 182 |
+
graphFragment.GetPartsOfSpeech(partsOfSpeech);
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
// Write the source side of the rule to sourceSS.
|
| 186 |
+
for (std::vector<Symbol>::const_iterator p(sourceRHS.begin());
|
| 187 |
+
p != sourceRHS.end(); ++p) {
|
| 188 |
+
WriteSymbol(*p, sourceSS);
|
| 189 |
+
sourceSS << " ";
|
| 190 |
+
}
|
| 191 |
+
if (m_options.conditionOnTargetLhs) {
|
| 192 |
+
WriteSymbol(rule.GetTargetLHS(), sourceSS);
|
| 193 |
+
} else {
|
| 194 |
+
WriteSymbol(rule.GetSourceLHS(), sourceSS);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
// Write the target side of the rule to targetSS.
|
| 198 |
+
int targetTerminalIndex = 0;
|
| 199 |
+
for (std::vector<Symbol>::const_iterator p(targetRHS.begin());
|
| 200 |
+
p != targetRHS.end(); ++p) {
|
| 201 |
+
WriteSymbol(*p, targetSS);
|
| 202 |
+
// If parts-of-speech as a factor requested: write part-of-speech
|
| 203 |
+
if (m_options.partsOfSpeechFactor && (p->GetType() != NonTerminal)) {
|
| 204 |
+
assert(targetTerminalIndex<partsOfSpeech.size());
|
| 205 |
+
targetSS << "|" << partsOfSpeech[targetTerminalIndex];
|
| 206 |
+
++targetTerminalIndex;
|
| 207 |
+
}
|
| 208 |
+
targetSS << " ";
|
| 209 |
+
}
|
| 210 |
+
WriteSymbol(rule.GetTargetLHS(), targetSS);
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
void ScfgRuleWriter::WriteSymbol(const Symbol &symbol, std::ostream &out)
|
| 214 |
+
{
|
| 215 |
+
if (symbol.GetType() == NonTerminal) {
|
| 216 |
+
out << "[";
|
| 217 |
+
if (m_options.stripBitParLabels) {
|
| 218 |
+
size_t pos = symbol.GetValue().find('-');
|
| 219 |
+
if (pos == std::string::npos) {
|
| 220 |
+
out << symbol.GetValue();
|
| 221 |
+
} else {
|
| 222 |
+
out << symbol.GetValue().substr(0,pos);
|
| 223 |
+
}
|
| 224 |
+
} else {
|
| 225 |
+
out << symbol.GetValue();
|
| 226 |
+
}
|
| 227 |
+
out << "]";
|
| 228 |
+
} else {
|
| 229 |
+
out << symbol.GetValue();
|
| 230 |
+
}
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
} // namespace GHKM
|
| 234 |
+
} // namespace Syntax
|
| 235 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.h
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include <ostream>
|
| 23 |
+
|
| 24 |
+
#include "Subgraph.h"
|
| 25 |
+
|
| 26 |
+
namespace MosesTraining
|
| 27 |
+
{
|
| 28 |
+
namespace Syntax
|
| 29 |
+
{
|
| 30 |
+
namespace GHKM
|
| 31 |
+
{
|
| 32 |
+
|
| 33 |
+
struct Options;
|
| 34 |
+
class ScfgRule;
|
| 35 |
+
class Symbol;
|
| 36 |
+
|
| 37 |
+
class ScfgRuleWriter
|
| 38 |
+
{
|
| 39 |
+
public:
|
| 40 |
+
ScfgRuleWriter(std::ostream &fwd, std::ostream &inv, const Options &options)
|
| 41 |
+
: m_fwd(fwd)
|
| 42 |
+
, m_inv(inv)
|
| 43 |
+
, m_options(options) {}
|
| 44 |
+
|
| 45 |
+
void Write(const ScfgRule &rule, size_t lineNum, bool printEndl=true);
|
| 46 |
+
|
| 47 |
+
private:
|
| 48 |
+
// Disallow copying
|
| 49 |
+
ScfgRuleWriter(const ScfgRuleWriter &);
|
| 50 |
+
ScfgRuleWriter &operator=(const ScfgRuleWriter &);
|
| 51 |
+
|
| 52 |
+
void WriteStandardFormat(const ScfgRule &, std::ostream &, std::ostream &);
|
| 53 |
+
void WriteUnpairedFormat(const ScfgRule &, std::ostream &, std::ostream &);
|
| 54 |
+
void WriteSymbol(const Symbol &, std::ostream &);
|
| 55 |
+
|
| 56 |
+
std::ostream &m_fwd;
|
| 57 |
+
std::ostream &m_inv;
|
| 58 |
+
const Options &m_options;
|
| 59 |
+
};
|
| 60 |
+
|
| 61 |
+
} // namespace GHKM
|
| 62 |
+
} // namespace Syntax
|
| 63 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Span.cpp
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "Span.h"
|
| 21 |
+
|
| 22 |
+
namespace MosesTraining
|
| 23 |
+
{
|
| 24 |
+
namespace Syntax
|
| 25 |
+
{
|
| 26 |
+
namespace GHKM
|
| 27 |
+
{
|
| 28 |
+
|
| 29 |
+
bool SpansIntersect(const Span &a, const ContiguousSpan &b)
|
| 30 |
+
{
|
| 31 |
+
for (Span::const_iterator p = a.begin(); p != a.end(); ++p) {
|
| 32 |
+
if (*p >= b.first && *p <= b.second) {
|
| 33 |
+
return true;
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
return false;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
ContiguousSpan Closure(const Span &s)
|
| 40 |
+
{
|
| 41 |
+
ContiguousSpan result(-1,-1);
|
| 42 |
+
if (!s.empty()) {
|
| 43 |
+
result.first = *(s.begin());
|
| 44 |
+
result.second = *(s.rbegin());
|
| 45 |
+
}
|
| 46 |
+
return result;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
} // namespace GHKM
|
| 50 |
+
} // namespace Syntax
|
| 51 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/Span.h
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
#ifndef EXTRACT_GHKM_SPAN_H_
|
| 22 |
+
#define EXTRACT_GHKM_SPAN_H_
|
| 23 |
+
|
| 24 |
+
#include <map>
|
| 25 |
+
#include <set>
|
| 26 |
+
|
| 27 |
+
namespace MosesTraining
|
| 28 |
+
{
|
| 29 |
+
namespace Syntax
|
| 30 |
+
{
|
| 31 |
+
namespace GHKM
|
| 32 |
+
{
|
| 33 |
+
|
| 34 |
+
typedef std::set<int> Span;
|
| 35 |
+
typedef std::pair<int, int> ContiguousSpan;
|
| 36 |
+
|
| 37 |
+
bool SpansIntersect(const Span &, const ContiguousSpan &);
|
| 38 |
+
|
| 39 |
+
ContiguousSpan Closure(const Span &);
|
| 40 |
+
|
| 41 |
+
} // namespace MosesTraining
|
| 42 |
+
} // namespace Syntax
|
| 43 |
+
} // namespace GHKM
|
| 44 |
+
|
| 45 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/StsgRule.cpp
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "StsgRule.h"
|
| 2 |
+
|
| 3 |
+
#include <algorithm>
|
| 4 |
+
|
| 5 |
+
#include "Node.h"
|
| 6 |
+
#include "Subgraph.h"
|
| 7 |
+
|
| 8 |
+
namespace MosesTraining
|
| 9 |
+
{
|
| 10 |
+
namespace Syntax
|
| 11 |
+
{
|
| 12 |
+
namespace GHKM
|
| 13 |
+
{
|
| 14 |
+
|
| 15 |
+
StsgRule::StsgRule(const Subgraph &fragment)
|
| 16 |
+
: m_targetSide(fragment, true)
|
| 17 |
+
{
|
| 18 |
+
// Source side
|
| 19 |
+
|
| 20 |
+
const std::set<const Node *> &sinkNodes = fragment.GetLeaves();
|
| 21 |
+
|
| 22 |
+
// Collect the subset of sink nodes that excludes target nodes with
|
| 23 |
+
// empty spans.
|
| 24 |
+
std::vector<const Node *> productiveSinks;
|
| 25 |
+
productiveSinks.reserve(sinkNodes.size());
|
| 26 |
+
for (std::set<const Node *>::const_iterator p = sinkNodes.begin();
|
| 27 |
+
p != sinkNodes.end(); ++p) {
|
| 28 |
+
const Node *sink = *p;
|
| 29 |
+
if (!sink->GetSpan().empty()) {
|
| 30 |
+
productiveSinks.push_back(sink);
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
// Sort them into the order defined by their spans.
|
| 35 |
+
std::sort(productiveSinks.begin(), productiveSinks.end(), PartitionOrderComp);
|
| 36 |
+
|
| 37 |
+
// Build a map from target nodes to source-order indices, so that we
|
| 38 |
+
// can construct the Alignment object later.
|
| 39 |
+
std::map<const Node *, std::vector<int> > sinkToSourceIndices;
|
| 40 |
+
std::map<const Node *, int> nonTermSinkToSourceIndex;
|
| 41 |
+
|
| 42 |
+
m_sourceSide.reserve(productiveSinks.size());
|
| 43 |
+
int srcIndex = 0;
|
| 44 |
+
int nonTermCount = 0;
|
| 45 |
+
for (std::vector<const Node *>::const_iterator p = productiveSinks.begin();
|
| 46 |
+
p != productiveSinks.end(); ++p, ++srcIndex) {
|
| 47 |
+
const Node &sink = **p;
|
| 48 |
+
if (sink.GetType() == TREE) {
|
| 49 |
+
m_sourceSide.push_back(Symbol("X", NonTerminal));
|
| 50 |
+
sinkToSourceIndices[&sink].push_back(srcIndex);
|
| 51 |
+
nonTermSinkToSourceIndex[&sink] = nonTermCount++;
|
| 52 |
+
} else {
|
| 53 |
+
assert(sink.GetType() == SOURCE);
|
| 54 |
+
m_sourceSide.push_back(Symbol(sink.GetLabel(), Terminal));
|
| 55 |
+
// Add all aligned target words to the sinkToSourceIndices map
|
| 56 |
+
const std::vector<Node *> &parents(sink.GetParents());
|
| 57 |
+
for (std::vector<Node *>::const_iterator q = parents.begin();
|
| 58 |
+
q != parents.end(); ++q) {
|
| 59 |
+
if ((*q)->GetType() == TARGET) {
|
| 60 |
+
sinkToSourceIndices[*q].push_back(srcIndex);
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
// Alignment
|
| 67 |
+
|
| 68 |
+
std::vector<const Node *> targetLeaves;
|
| 69 |
+
m_targetSide.GetTargetLeaves(targetLeaves);
|
| 70 |
+
|
| 71 |
+
m_alignment.reserve(targetLeaves.size());
|
| 72 |
+
m_nonTermAlignment.resize(nonTermCount);
|
| 73 |
+
|
| 74 |
+
for (int i = 0, j = 0; i < targetLeaves.size(); ++i) {
|
| 75 |
+
const Node *leaf = targetLeaves[i];
|
| 76 |
+
assert(leaf->GetType() != SOURCE);
|
| 77 |
+
if (leaf->GetSpan().empty()) {
|
| 78 |
+
continue;
|
| 79 |
+
}
|
| 80 |
+
std::map<const Node *, std::vector<int> >::iterator p =
|
| 81 |
+
sinkToSourceIndices.find(leaf);
|
| 82 |
+
assert(p != sinkToSourceIndices.end());
|
| 83 |
+
std::vector<int> &sourceNodes = p->second;
|
| 84 |
+
for (std::vector<int>::iterator r = sourceNodes.begin();
|
| 85 |
+
r != sourceNodes.end(); ++r) {
|
| 86 |
+
int srcIndex = *r;
|
| 87 |
+
m_alignment.push_back(std::make_pair(srcIndex, i));
|
| 88 |
+
}
|
| 89 |
+
if (leaf->GetType() == TREE) {
|
| 90 |
+
m_nonTermAlignment[nonTermSinkToSourceIndex[leaf]] = j++;
|
| 91 |
+
}
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
} // namespace GHKM
|
| 96 |
+
} // namespace Syntax
|
| 97 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/StsgRule.h
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
#ifndef EXTRACT_GHKM_STSG_RULE_H_
|
| 3 |
+
#define EXTRACT_GHKM_STSG_RULE_H_
|
| 4 |
+
|
| 5 |
+
#include <vector>
|
| 6 |
+
|
| 7 |
+
#include "Rule.h"
|
| 8 |
+
#include "Subgraph.h"
|
| 9 |
+
|
| 10 |
+
namespace MosesTraining
|
| 11 |
+
{
|
| 12 |
+
namespace Syntax
|
| 13 |
+
{
|
| 14 |
+
namespace GHKM
|
| 15 |
+
{
|
| 16 |
+
|
| 17 |
+
class Node;
|
| 18 |
+
|
| 19 |
+
class StsgRule : public Rule
|
| 20 |
+
{
|
| 21 |
+
public:
|
| 22 |
+
StsgRule(const Subgraph &fragment);
|
| 23 |
+
|
| 24 |
+
const std::vector<Symbol> &GetSourceSide() const {
|
| 25 |
+
return m_sourceSide;
|
| 26 |
+
}
|
| 27 |
+
const Subgraph &GetTargetSide() const {
|
| 28 |
+
return m_targetSide;
|
| 29 |
+
}
|
| 30 |
+
const std::vector<int> &GetNonTermAlignment() const {
|
| 31 |
+
return m_nonTermAlignment;
|
| 32 |
+
}
|
| 33 |
+
int Scope() const {
|
| 34 |
+
return Rule::Scope(m_sourceSide);
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
private:
|
| 38 |
+
std::vector<Symbol> m_sourceSide;
|
| 39 |
+
Subgraph m_targetSide;
|
| 40 |
+
std::vector<int> m_nonTermAlignment;
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
} // namespace GHKM
|
| 44 |
+
} // namespace Syntax
|
| 45 |
+
} // namespace MosesTraining
|
| 46 |
+
|
| 47 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.cpp
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "StsgRuleWriter.h"
|
| 2 |
+
|
| 3 |
+
#include <cassert>
|
| 4 |
+
#include <cmath>
|
| 5 |
+
#include <ostream>
|
| 6 |
+
#include <map>
|
| 7 |
+
#include <sstream>
|
| 8 |
+
#include <vector>
|
| 9 |
+
|
| 10 |
+
#include "Alignment.h"
|
| 11 |
+
#include "Options.h"
|
| 12 |
+
#include "StsgRule.h"
|
| 13 |
+
|
| 14 |
+
namespace MosesTraining
|
| 15 |
+
{
|
| 16 |
+
namespace Syntax
|
| 17 |
+
{
|
| 18 |
+
namespace GHKM
|
| 19 |
+
{
|
| 20 |
+
|
| 21 |
+
void StsgRuleWriter::Write(const StsgRule &rule)
|
| 22 |
+
{
|
| 23 |
+
std::ostringstream sourceSS;
|
| 24 |
+
std::ostringstream targetSS;
|
| 25 |
+
|
| 26 |
+
// Write the source side of the rule to sourceSS.
|
| 27 |
+
const std::vector<Symbol> &sourceSide = rule.GetSourceSide();
|
| 28 |
+
for (std::size_t i = 0; i < sourceSide.size(); ++i) {
|
| 29 |
+
const Symbol &symbol = sourceSide[i];
|
| 30 |
+
if (i > 0) {
|
| 31 |
+
sourceSS << " ";
|
| 32 |
+
}
|
| 33 |
+
if (symbol.GetType() == NonTerminal) {
|
| 34 |
+
sourceSS << "[X]";
|
| 35 |
+
} else {
|
| 36 |
+
sourceSS << symbol.GetValue();
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
// Write the target side of the rule to targetSS.
|
| 41 |
+
rule.GetTargetSide().PrintTree(targetSS);
|
| 42 |
+
|
| 43 |
+
// Write the rule to the forward and inverse extract files.
|
| 44 |
+
if (m_options.t2s) {
|
| 45 |
+
// If model is tree-to-string then flip the source and target.
|
| 46 |
+
m_fwd << targetSS.str() << " ||| " << sourceSS.str() << " |||";
|
| 47 |
+
m_inv << sourceSS.str() << " ||| " << targetSS.str() << " |||";
|
| 48 |
+
} else {
|
| 49 |
+
m_fwd << sourceSS.str() << " ||| " << targetSS.str() << " |||";
|
| 50 |
+
m_inv << targetSS.str() << " ||| " << sourceSS.str() << " |||";
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Write the non-terminal alignments.
|
| 54 |
+
const std::vector<int> &nonTermAlignment = rule.GetNonTermAlignment();
|
| 55 |
+
for (int srcIndex = 0; srcIndex < nonTermAlignment.size(); ++srcIndex) {
|
| 56 |
+
int tgtIndex = nonTermAlignment[srcIndex];
|
| 57 |
+
if (m_options.t2s) {
|
| 58 |
+
// If model is tree-to-string then flip the source and target.
|
| 59 |
+
m_fwd << " " << tgtIndex << "-" << srcIndex;
|
| 60 |
+
m_inv << " " << srcIndex << "-" << tgtIndex;
|
| 61 |
+
} else {
|
| 62 |
+
m_fwd << " " << srcIndex << "-" << tgtIndex;
|
| 63 |
+
m_inv << " " << tgtIndex << "-" << srcIndex;
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
m_fwd << " |||";
|
| 67 |
+
m_inv << " |||";
|
| 68 |
+
|
| 69 |
+
// Write the symbol alignments.
|
| 70 |
+
const Alignment &alignment = rule.GetAlignment();
|
| 71 |
+
for (Alignment::const_iterator p = alignment.begin();
|
| 72 |
+
p != alignment.end(); ++p) {
|
| 73 |
+
if (m_options.t2s) {
|
| 74 |
+
// If model is tree-to-string then flip the source and target.
|
| 75 |
+
m_fwd << " " << p->second << "-" << p->first;
|
| 76 |
+
m_inv << " " << p->first << "-" << p->second;
|
| 77 |
+
} else {
|
| 78 |
+
m_fwd << " " << p->first << "-" << p->second;
|
| 79 |
+
m_inv << " " << p->second << "-" << p->first;
|
| 80 |
+
}
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// Write a count of 1.
|
| 84 |
+
m_fwd << " ||| 1";
|
| 85 |
+
m_inv << " ||| 1";
|
| 86 |
+
|
| 87 |
+
// Write the PCFG score (if requested).
|
| 88 |
+
if (m_options.pcfg) {
|
| 89 |
+
m_fwd << " ||| " << std::exp(rule.GetTargetSide().GetPcfgScore());
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
m_fwd << std::endl;
|
| 93 |
+
m_inv << std::endl;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
} // namespace GHKM
|
| 97 |
+
} // namespace Syntax
|
| 98 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.h
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#pragma once
|
| 2 |
+
#ifndef EXTRACT_GHKM_STSG_RULE_WRITER_H_
|
| 3 |
+
#define EXTRACT_GHKM_STSG_RULE_WRITER_H_
|
| 4 |
+
|
| 5 |
+
#include <ostream>
|
| 6 |
+
|
| 7 |
+
#include "Subgraph.h"
|
| 8 |
+
|
| 9 |
+
namespace MosesTraining
|
| 10 |
+
{
|
| 11 |
+
namespace Syntax
|
| 12 |
+
{
|
| 13 |
+
namespace GHKM
|
| 14 |
+
{
|
| 15 |
+
|
| 16 |
+
struct Options;
|
| 17 |
+
class StsgRule;
|
| 18 |
+
class Symbol;
|
| 19 |
+
|
| 20 |
+
class StsgRuleWriter
|
| 21 |
+
{
|
| 22 |
+
public:
|
| 23 |
+
StsgRuleWriter(std::ostream &fwd, std::ostream &inv, const Options &options)
|
| 24 |
+
: m_fwd(fwd)
|
| 25 |
+
, m_inv(inv)
|
| 26 |
+
, m_options(options) {}
|
| 27 |
+
|
| 28 |
+
void Write(const StsgRule &rule);
|
| 29 |
+
|
| 30 |
+
private:
|
| 31 |
+
// Disallow copying
|
| 32 |
+
StsgRuleWriter(const StsgRuleWriter &);
|
| 33 |
+
StsgRuleWriter &operator=(const StsgRuleWriter &);
|
| 34 |
+
|
| 35 |
+
std::ostream &m_fwd;
|
| 36 |
+
std::ostream &m_inv;
|
| 37 |
+
const Options &m_options;
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
} // namespace GHKM
|
| 41 |
+
} // namespace Syntax
|
| 42 |
+
} // namespace MosesTraining
|
| 43 |
+
|
| 44 |
+
#endif
|
mosesdecoder/phrase-extract/extract-ghkm/Subgraph.cpp
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include <iostream>
|
| 21 |
+
|
| 22 |
+
#include "Node.h"
|
| 23 |
+
#include "Subgraph.h"
|
| 24 |
+
|
| 25 |
+
namespace MosesTraining
|
| 26 |
+
{
|
| 27 |
+
namespace Syntax
|
| 28 |
+
{
|
| 29 |
+
namespace GHKM
|
| 30 |
+
{
|
| 31 |
+
|
| 32 |
+
void Subgraph::GetTargetLeaves(std::vector<const Node *> &result) const
|
| 33 |
+
{
|
| 34 |
+
result.clear();
|
| 35 |
+
GetTargetLeaves(m_root, result);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
void Subgraph::GetTargetLeaves(const Node *root,
|
| 39 |
+
std::vector<const Node *> &result) const
|
| 40 |
+
{
|
| 41 |
+
if (root->GetType() == TARGET || m_leaves.find(root) != m_leaves.end()) {
|
| 42 |
+
result.push_back(root);
|
| 43 |
+
} else {
|
| 44 |
+
const std::vector<Node*> &children = root->GetChildren();
|
| 45 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 46 |
+
p != children.end(); ++p) {
|
| 47 |
+
GetTargetLeaves(*p, result);
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
int Subgraph::CountNodes(const Node *n) const
|
| 53 |
+
{
|
| 54 |
+
if (n->GetType() != TREE) {
|
| 55 |
+
return 0;
|
| 56 |
+
}
|
| 57 |
+
if (IsTrivial()) {
|
| 58 |
+
return 1;
|
| 59 |
+
}
|
| 60 |
+
int count = 1;
|
| 61 |
+
const std::vector<Node*> &children = n->GetChildren();
|
| 62 |
+
for (std::vector<Node *>::const_iterator p = children.begin();
|
| 63 |
+
p != children.end(); ++p) {
|
| 64 |
+
const Node *child = *p;
|
| 65 |
+
if (m_leaves.find(child) == m_leaves.end()) {
|
| 66 |
+
count += CountNodes(child);
|
| 67 |
+
} else if (child->GetType() == TREE) {
|
| 68 |
+
++count;
|
| 69 |
+
}
|
| 70 |
+
}
|
| 71 |
+
return count;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
int Subgraph::CalcSize(const Node *n) const
|
| 75 |
+
{
|
| 76 |
+
if (n->GetType() != TREE || n->IsPreterminal()) {
|
| 77 |
+
return 0;
|
| 78 |
+
}
|
| 79 |
+
if (IsTrivial()) {
|
| 80 |
+
return 1;
|
| 81 |
+
}
|
| 82 |
+
int count = 1;
|
| 83 |
+
const std::vector<Node*> &children = n->GetChildren();
|
| 84 |
+
for (std::vector<Node *>::const_iterator p = children.begin();
|
| 85 |
+
p != children.end(); ++p) {
|
| 86 |
+
if (m_leaves.find(*p) == m_leaves.end()) {
|
| 87 |
+
count += CalcSize(*p);
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
return count;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
int Subgraph::CalcDepth(const Node *n) const
|
| 94 |
+
{
|
| 95 |
+
if (n->GetType() != TREE || n->IsPreterminal() || m_leaves.empty()) {
|
| 96 |
+
return 0;
|
| 97 |
+
}
|
| 98 |
+
int maxChildDepth = 0;
|
| 99 |
+
const std::vector<Node*> &children = n->GetChildren();
|
| 100 |
+
for (std::vector<Node *>::const_iterator p = children.begin();
|
| 101 |
+
p != children.end(); ++p) {
|
| 102 |
+
if (m_leaves.find(*p) == m_leaves.end()) {
|
| 103 |
+
maxChildDepth = std::max(maxChildDepth, CalcDepth(*p));
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
return maxChildDepth + 1;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
float Subgraph::CalcPcfgScore() const
|
| 110 |
+
{
|
| 111 |
+
if (m_root->GetType() != TREE || m_leaves.empty()) {
|
| 112 |
+
return 0.0f;
|
| 113 |
+
}
|
| 114 |
+
float score = m_root->GetPcfgScore();
|
| 115 |
+
for (std::set<const Node *>::const_iterator p = m_leaves.begin();
|
| 116 |
+
p != m_leaves.end(); ++p) {
|
| 117 |
+
const Node *leaf = *p;
|
| 118 |
+
if (leaf->GetType() == TREE) {
|
| 119 |
+
score -= leaf->GetPcfgScore();
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
return score;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
void Subgraph::PrintTree(std::ostream &out) const
|
| 126 |
+
{
|
| 127 |
+
RecursivelyPrintTree(m_root,out);
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
void Subgraph::RecursivelyPrintTree(const Node *n, std::ostream &out) const
|
| 131 |
+
{
|
| 132 |
+
NodeType nodeType = n->GetType();
|
| 133 |
+
if (nodeType == TREE) {
|
| 134 |
+
out << "[" << n->GetLabel();
|
| 135 |
+
if (m_leaves.find(n) == m_leaves.end()) {
|
| 136 |
+
const std::vector<Node *> &children = n->GetChildren();
|
| 137 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 138 |
+
p != children.end(); ++p) {
|
| 139 |
+
Node *child = *p;
|
| 140 |
+
if (child->GetType() == SOURCE) {
|
| 141 |
+
// This is possible due to the heuristic for attaching unaligned
|
| 142 |
+
// source words.
|
| 143 |
+
continue;
|
| 144 |
+
}
|
| 145 |
+
out << " ";
|
| 146 |
+
RecursivelyPrintTree(child,out);
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
out << "]";
|
| 150 |
+
} else if (nodeType == TARGET) {
|
| 151 |
+
out << n->GetLabel();
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
void Subgraph::PrintPartsOfSpeech(std::ostream &out) const
|
| 156 |
+
{
|
| 157 |
+
RecursivelyPrintPartsOfSpeech(m_root,out);
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
void Subgraph::RecursivelyPrintPartsOfSpeech(const Node *n, std::ostream &out) const
|
| 161 |
+
{
|
| 162 |
+
NodeType nodeType = n->GetType();
|
| 163 |
+
if (nodeType == TREE) {
|
| 164 |
+
if (m_leaves.find(n) == m_leaves.end()) {
|
| 165 |
+
const std::vector<Node *> &children = n->GetChildren();
|
| 166 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 167 |
+
p != children.end(); ++p) {
|
| 168 |
+
Node *child = *p;
|
| 169 |
+
if (child->GetType() == TARGET) {
|
| 170 |
+
out << " " << n->GetLabel();
|
| 171 |
+
} else {
|
| 172 |
+
RecursivelyPrintPartsOfSpeech(child,out);
|
| 173 |
+
}
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
void Subgraph::GetPartsOfSpeech(std::vector<std::string> &out) const
|
| 180 |
+
{
|
| 181 |
+
out.clear();
|
| 182 |
+
RecursivelyGetPartsOfSpeech(m_root,out);
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
void Subgraph::RecursivelyGetPartsOfSpeech(const Node *n, std::vector<std::string> &out) const
|
| 186 |
+
{
|
| 187 |
+
NodeType nodeType = n->GetType();
|
| 188 |
+
if (nodeType == TREE) {
|
| 189 |
+
if (m_leaves.find(n) == m_leaves.end()) {
|
| 190 |
+
const std::vector<Node *> &children = n->GetChildren();
|
| 191 |
+
for (std::vector<Node *>::const_iterator p(children.begin());
|
| 192 |
+
p != children.end(); ++p) {
|
| 193 |
+
Node *child = *p;
|
| 194 |
+
if (child->GetType() == TARGET) {
|
| 195 |
+
out.push_back(n->GetLabel());
|
| 196 |
+
} else {
|
| 197 |
+
RecursivelyGetPartsOfSpeech(child,out);
|
| 198 |
+
}
|
| 199 |
+
}
|
| 200 |
+
}
|
| 201 |
+
}
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
} // namespace MosesTraining
|
| 205 |
+
} // namespace Syntax
|
| 206 |
+
} // namespace GHKM
|
mosesdecoder/phrase-extract/extract-ghkm/Subgraph.h
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/***********************************************************************
|
| 2 |
+
Moses - statistical machine translation system
|
| 3 |
+
Copyright (C) 2006-2011 University of Edinburgh
|
| 4 |
+
|
| 5 |
+
This library is free software; you can redistribute it and/or
|
| 6 |
+
modify it under the terms of the GNU Lesser General Public
|
| 7 |
+
License as published by the Free Software Foundation; either
|
| 8 |
+
version 2.1 of the License, or (at your option) any later version.
|
| 9 |
+
|
| 10 |
+
This library is distributed in the hope that it will be useful,
|
| 11 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 12 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| 13 |
+
Lesser General Public License for more details.
|
| 14 |
+
|
| 15 |
+
You should have received a copy of the GNU Lesser General Public
|
| 16 |
+
License along with this library; if not, write to the Free Software
|
| 17 |
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
| 18 |
+
***********************************************************************/
|
| 19 |
+
|
| 20 |
+
#pragma once
|
| 21 |
+
|
| 22 |
+
#include <set>
|
| 23 |
+
#include <vector>
|
| 24 |
+
|
| 25 |
+
#include "Node.h"
|
| 26 |
+
|
| 27 |
+
namespace MosesTraining
|
| 28 |
+
{
|
| 29 |
+
namespace Syntax
|
| 30 |
+
{
|
| 31 |
+
namespace GHKM
|
| 32 |
+
{
|
| 33 |
+
|
| 34 |
+
class Node;
|
| 35 |
+
|
| 36 |
+
class Subgraph
|
| 37 |
+
{
|
| 38 |
+
public:
|
| 39 |
+
Subgraph(const Node *root)
|
| 40 |
+
: m_root(root)
|
| 41 |
+
, m_depth(0)
|
| 42 |
+
, m_size(root->GetType() == TREE ? 1 : 0)
|
| 43 |
+
, m_nodeCount(1)
|
| 44 |
+
, m_pcfgScore(0.0f) {}
|
| 45 |
+
|
| 46 |
+
Subgraph(const Node *root, const std::set<const Node *> &leaves)
|
| 47 |
+
: m_root(root)
|
| 48 |
+
, m_leaves(leaves)
|
| 49 |
+
, m_depth(-1)
|
| 50 |
+
, m_size(-1)
|
| 51 |
+
, m_nodeCount(-1)
|
| 52 |
+
, m_pcfgScore(0.0f) {
|
| 53 |
+
m_depth = CalcDepth(m_root);
|
| 54 |
+
m_size = CalcSize(m_root);
|
| 55 |
+
m_nodeCount = CountNodes(m_root);
|
| 56 |
+
m_pcfgScore = CalcPcfgScore();
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
Subgraph(const Subgraph &other, bool targetOnly=false)
|
| 60 |
+
: m_root(other.m_root)
|
| 61 |
+
, m_leaves(other.m_leaves)
|
| 62 |
+
, m_depth(other.m_depth)
|
| 63 |
+
, m_size(other.m_size)
|
| 64 |
+
, m_nodeCount(other.m_nodeCount)
|
| 65 |
+
, m_pcfgScore(other.m_pcfgScore) {
|
| 66 |
+
if (targetOnly && m_root->GetType() != SOURCE) {
|
| 67 |
+
// Replace any source-word sink nodes with their parents (except for
|
| 68 |
+
// the special case where the parent is a non-word tree node -- see
|
| 69 |
+
// below).
|
| 70 |
+
std::set<const Node *> targetLeaves;
|
| 71 |
+
for (std::set<const Node *>::const_iterator p = m_leaves.begin();
|
| 72 |
+
p != m_leaves.end(); ++p) {
|
| 73 |
+
const Node *leaf = *p;
|
| 74 |
+
if (leaf->GetType() != SOURCE) {
|
| 75 |
+
targetLeaves.insert(leaf);
|
| 76 |
+
} else {
|
| 77 |
+
const std::vector<Node*> &parents = leaf->GetParents();
|
| 78 |
+
for (std::vector<Node*>::const_iterator q = parents.begin();
|
| 79 |
+
q != parents.end(); ++q) {
|
| 80 |
+
const Node *parent = *q;
|
| 81 |
+
// Only add parents that are words, not tree nodes since those
|
| 82 |
+
// are never sink nodes. (A source word can have a tree node as
|
| 83 |
+
// its parent due to the heuristic for handling unaligned source
|
| 84 |
+
// words).
|
| 85 |
+
if (parent->GetType() == TARGET) {
|
| 86 |
+
targetLeaves.insert(*q);
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
m_leaves.swap(targetLeaves);
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
const Node *GetRoot() const {
|
| 96 |
+
return m_root;
|
| 97 |
+
}
|
| 98 |
+
const std::set<const Node *> &GetLeaves() const {
|
| 99 |
+
return m_leaves;
|
| 100 |
+
}
|
| 101 |
+
int GetDepth() const {
|
| 102 |
+
return m_depth;
|
| 103 |
+
}
|
| 104 |
+
int GetSize() const {
|
| 105 |
+
return m_size;
|
| 106 |
+
}
|
| 107 |
+
int GetNodeCount() const {
|
| 108 |
+
return m_nodeCount;
|
| 109 |
+
}
|
| 110 |
+
float GetPcfgScore() const {
|
| 111 |
+
return m_pcfgScore;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
bool IsTrivial() const {
|
| 115 |
+
return m_leaves.empty();
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
void GetTargetLeaves(std::vector<const Node *> &) const;
|
| 119 |
+
void PrintTree(std::ostream &out) const;
|
| 120 |
+
void PrintPartsOfSpeech(std::ostream &out) const;
|
| 121 |
+
void GetPartsOfSpeech(std::vector<std::string> &out) const;
|
| 122 |
+
|
| 123 |
+
private:
|
| 124 |
+
void GetTargetLeaves(const Node *, std::vector<const Node *> &) const;
|
| 125 |
+
int CalcDepth(const Node *) const;
|
| 126 |
+
int CalcSize(const Node *) const;
|
| 127 |
+
float CalcPcfgScore() const;
|
| 128 |
+
int CountNodes(const Node *) const;
|
| 129 |
+
void RecursivelyPrintTree(const Node *n, std::ostream &out) const;
|
| 130 |
+
void RecursivelyPrintPartsOfSpeech(const Node *n, std::ostream &out) const;
|
| 131 |
+
void RecursivelyGetPartsOfSpeech(const Node *n, std::vector<std::string> &out) const;
|
| 132 |
+
|
| 133 |
+
const Node *m_root;
|
| 134 |
+
std::set<const Node *> m_leaves;
|
| 135 |
+
int m_depth;
|
| 136 |
+
int m_size;
|
| 137 |
+
int m_nodeCount;
|
| 138 |
+
float m_pcfgScore;
|
| 139 |
+
};
|
| 140 |
+
|
| 141 |
+
} // namespace GHKM
|
| 142 |
+
} // namespace Syntax
|
| 143 |
+
} // namespace MosesTraining
|
mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentence.cpp
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* AlignedSentence.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 18 Feb 2014
|
| 5 |
+
* Author: s0565741
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#include <sstream>
|
| 9 |
+
#include "moses/Util.h"
|
| 10 |
+
#include "AlignedSentence.h"
|
| 11 |
+
#include "Parameter.h"
|
| 12 |
+
|
| 13 |
+
using namespace std;
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
/////////////////////////////////////////////////////////////////////////////////
|
| 17 |
+
AlignedSentence::AlignedSentence(int lineNum,
|
| 18 |
+
const std::string &source,
|
| 19 |
+
const std::string &target,
|
| 20 |
+
const std::string &alignment)
|
| 21 |
+
:m_lineNum(lineNum)
|
| 22 |
+
{
|
| 23 |
+
PopulateWordVec(m_source, source);
|
| 24 |
+
PopulateWordVec(m_target, target);
|
| 25 |
+
PopulateAlignment(alignment);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
AlignedSentence::~AlignedSentence()
|
| 29 |
+
{
|
| 30 |
+
Moses::RemoveAllInColl(m_source);
|
| 31 |
+
Moses::RemoveAllInColl(m_target);
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
void AlignedSentence::PopulateWordVec(Phrase &vec, const std::string &line)
|
| 35 |
+
{
|
| 36 |
+
std::vector<string> toks;
|
| 37 |
+
Moses::Tokenize(toks, line);
|
| 38 |
+
|
| 39 |
+
vec.resize(toks.size());
|
| 40 |
+
for (size_t i = 0; i < vec.size(); ++i) {
|
| 41 |
+
const string &tok = toks[i];
|
| 42 |
+
Word *word = new Word(i, tok);
|
| 43 |
+
vec[i] = word;
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
void AlignedSentence::PopulateAlignment(const std::string &line)
|
| 48 |
+
{
|
| 49 |
+
vector<string> alignStr;
|
| 50 |
+
Moses::Tokenize(alignStr, line);
|
| 51 |
+
|
| 52 |
+
for (size_t i = 0; i < alignStr.size(); ++i) {
|
| 53 |
+
vector<int> alignPair;
|
| 54 |
+
Moses::Tokenize(alignPair, alignStr[i], "-");
|
| 55 |
+
assert(alignPair.size() == 2);
|
| 56 |
+
|
| 57 |
+
int sourcePos = alignPair[0];
|
| 58 |
+
int targetPos = alignPair[1];
|
| 59 |
+
|
| 60 |
+
if (sourcePos >= m_source.size()) {
|
| 61 |
+
cerr << "ERROR1:AlignedSentence=" << Debug() << endl;
|
| 62 |
+
cerr << "m_source=" << m_source.size() << endl;
|
| 63 |
+
abort();
|
| 64 |
+
}
|
| 65 |
+
assert(sourcePos < m_source.size());
|
| 66 |
+
assert(targetPos < m_target.size());
|
| 67 |
+
Word *sourceWord = m_source[sourcePos];
|
| 68 |
+
Word *targetWord = m_target[targetPos];
|
| 69 |
+
|
| 70 |
+
sourceWord->AddAlignment(targetWord);
|
| 71 |
+
targetWord->AddAlignment(sourceWord);
|
| 72 |
+
}
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
std::string AlignedSentence::Debug() const
|
| 76 |
+
{
|
| 77 |
+
stringstream out;
|
| 78 |
+
out << "m_lineNum:";
|
| 79 |
+
out << m_lineNum;
|
| 80 |
+
out << endl;
|
| 81 |
+
|
| 82 |
+
out << "m_source:";
|
| 83 |
+
out << m_source.Debug();
|
| 84 |
+
out << endl;
|
| 85 |
+
|
| 86 |
+
out << "m_target:";
|
| 87 |
+
out << m_target.Debug();
|
| 88 |
+
out << endl;
|
| 89 |
+
|
| 90 |
+
out << "consistent phrases:" << endl;
|
| 91 |
+
out << m_consistentPhrases.Debug();
|
| 92 |
+
out << endl;
|
| 93 |
+
|
| 94 |
+
return out.str();
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
std::vector<int> AlignedSentence::GetSourceAlignmentCount() const
|
| 98 |
+
{
|
| 99 |
+
vector<int> ret(m_source.size());
|
| 100 |
+
|
| 101 |
+
for (size_t i = 0; i < m_source.size(); ++i) {
|
| 102 |
+
const Word &word = *m_source[i];
|
| 103 |
+
ret[i] = word.GetAlignmentIndex().size();
|
| 104 |
+
}
|
| 105 |
+
return ret;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
void AlignedSentence::Create(const Parameter ¶ms)
|
| 109 |
+
{
|
| 110 |
+
CreateConsistentPhrases(params);
|
| 111 |
+
m_consistentPhrases.AddHieroNonTerms(params);
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
void AlignedSentence::CreateConsistentPhrases(const Parameter ¶ms)
|
| 115 |
+
{
|
| 116 |
+
int countT = m_target.size();
|
| 117 |
+
int countS = m_source.size();
|
| 118 |
+
|
| 119 |
+
m_consistentPhrases.Initialize(countS);
|
| 120 |
+
|
| 121 |
+
// check alignments for target phrase startT...endT
|
| 122 |
+
for(int lengthT=1;
|
| 123 |
+
lengthT <= params.maxSpan && lengthT <= countT;
|
| 124 |
+
lengthT++) {
|
| 125 |
+
for(int startT=0; startT < countT-(lengthT-1); startT++) {
|
| 126 |
+
|
| 127 |
+
// that's nice to have
|
| 128 |
+
int endT = startT + lengthT - 1;
|
| 129 |
+
|
| 130 |
+
// find find aligned source words
|
| 131 |
+
// first: find minimum and maximum source word
|
| 132 |
+
int minS = 9999;
|
| 133 |
+
int maxS = -1;
|
| 134 |
+
vector< int > usedS = GetSourceAlignmentCount();
|
| 135 |
+
for(int ti=startT; ti<=endT; ti++) {
|
| 136 |
+
const Word &word = *m_target[ti];
|
| 137 |
+
const std::set<int> &alignment = word.GetAlignmentIndex();
|
| 138 |
+
|
| 139 |
+
std::set<int>::const_iterator iterAlign;
|
| 140 |
+
for(iterAlign = alignment.begin(); iterAlign != alignment.end(); ++iterAlign) {
|
| 141 |
+
int si = *iterAlign;
|
| 142 |
+
if (si<minS) {
|
| 143 |
+
minS = si;
|
| 144 |
+
}
|
| 145 |
+
if (si>maxS) {
|
| 146 |
+
maxS = si;
|
| 147 |
+
}
|
| 148 |
+
usedS[ si ]--;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
|
| 152 |
+
// unaligned phrases are not allowed
|
| 153 |
+
if( maxS == -1 )
|
| 154 |
+
continue;
|
| 155 |
+
|
| 156 |
+
// source phrase has to be within limits
|
| 157 |
+
size_t width = maxS - minS + 1;
|
| 158 |
+
|
| 159 |
+
if( width < params.minSpan )
|
| 160 |
+
continue;
|
| 161 |
+
|
| 162 |
+
if( width > params.maxSpan )
|
| 163 |
+
continue;
|
| 164 |
+
|
| 165 |
+
// check if source words are aligned to out of bound target words
|
| 166 |
+
bool out_of_bounds = false;
|
| 167 |
+
for(int si=minS; si<=maxS && !out_of_bounds; si++)
|
| 168 |
+
if (usedS[si]>0) {
|
| 169 |
+
out_of_bounds = true;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
// if out of bound, you gotta go
|
| 173 |
+
if (out_of_bounds)
|
| 174 |
+
continue;
|
| 175 |
+
|
| 176 |
+
// done with all the checks, lets go over all consistent phrase pairs
|
| 177 |
+
// start point of source phrase may retreat over unaligned
|
| 178 |
+
for(int startS=minS;
|
| 179 |
+
(startS>=0 &&
|
| 180 |
+
startS>maxS - params.maxSpan && // within length limit
|
| 181 |
+
(startS==minS || m_source[startS]->GetAlignment().size()==0)); // unaligned
|
| 182 |
+
startS--) {
|
| 183 |
+
// end point of source phrase may advance over unaligned
|
| 184 |
+
for(int endS=maxS;
|
| 185 |
+
(endS<countS && endS<startS + params.maxSpan && // within length limit
|
| 186 |
+
(endS==maxS || m_source[endS]->GetAlignment().size()==0)); // unaligned
|
| 187 |
+
endS++) {
|
| 188 |
+
|
| 189 |
+
// take note that this is a valid phrase alignment
|
| 190 |
+
m_consistentPhrases.Add(startS, endS, startT, endT, params);
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
}
|
mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentenceSyntax.h
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* AlignedSentenceSyntax.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 26 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#pragma once
|
| 9 |
+
|
| 10 |
+
#include "AlignedSentence.h"
|
| 11 |
+
#include "SyntaxTree.h"
|
| 12 |
+
#include "pugixml.hpp"
|
| 13 |
+
|
| 14 |
+
class AlignedSentenceSyntax : public AlignedSentence
|
| 15 |
+
{
|
| 16 |
+
public:
|
| 17 |
+
AlignedSentenceSyntax(int lineNum,
|
| 18 |
+
const std::string &source,
|
| 19 |
+
const std::string &target,
|
| 20 |
+
const std::string &alignment);
|
| 21 |
+
virtual ~AlignedSentenceSyntax();
|
| 22 |
+
|
| 23 |
+
void Create(const Parameter ¶ms);
|
| 24 |
+
|
| 25 |
+
//virtual std::string Debug() const;
|
| 26 |
+
protected:
|
| 27 |
+
std::string m_sourceStr, m_targetStr, m_alignmentStr;
|
| 28 |
+
SyntaxTree m_sourceTree, m_targetTree;
|
| 29 |
+
|
| 30 |
+
void XMLParse(Phrase &output,
|
| 31 |
+
SyntaxTree &tree,
|
| 32 |
+
const std::string input,
|
| 33 |
+
const Parameter ¶ms);
|
| 34 |
+
void XMLParse(Phrase &output,
|
| 35 |
+
SyntaxTree &tree,
|
| 36 |
+
const pugi::xml_node &parentNode,
|
| 37 |
+
const Parameter ¶ms);
|
| 38 |
+
void CreateNonTerms();
|
| 39 |
+
void CreateNonTerms(ConsistentPhrase &cp,
|
| 40 |
+
const SyntaxTree::Labels &sourceLabels,
|
| 41 |
+
const SyntaxTree::Labels &targetLabels);
|
| 42 |
+
void Populate(bool isSyntax, int mixedSyntaxType, const Parameter ¶ms,
|
| 43 |
+
std::string line, Phrase &phrase, SyntaxTree &tree);
|
| 44 |
+
|
| 45 |
+
};
|
| 46 |
+
|
mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrase.cpp
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* ConsistentPhrase.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 20 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include <sstream>
|
| 8 |
+
#include "ConsistentPhrase.h"
|
| 9 |
+
#include "Word.h"
|
| 10 |
+
#include "NonTerm.h"
|
| 11 |
+
#include "Parameter.h"
|
| 12 |
+
|
| 13 |
+
using namespace std;
|
| 14 |
+
|
| 15 |
+
ConsistentPhrase::ConsistentPhrase(
|
| 16 |
+
int sourceStart, int sourceEnd,
|
| 17 |
+
int targetStart, int targetEnd,
|
| 18 |
+
const Parameter ¶ms)
|
| 19 |
+
:corners(4)
|
| 20 |
+
,m_hieroNonTerm(*this, params.hieroNonTerm, params.hieroNonTerm)
|
| 21 |
+
{
|
| 22 |
+
corners[0] = sourceStart;
|
| 23 |
+
corners[1] = sourceEnd;
|
| 24 |
+
corners[2] = targetStart;
|
| 25 |
+
corners[3] = targetEnd;
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
ConsistentPhrase::~ConsistentPhrase()
|
| 29 |
+
{
|
| 30 |
+
// TODO Auto-generated destructor stub
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
bool ConsistentPhrase::operator<(const ConsistentPhrase &other) const
|
| 34 |
+
{
|
| 35 |
+
return corners < other.corners;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
void ConsistentPhrase::AddNonTerms(const std::string &source,
|
| 39 |
+
const std::string &target)
|
| 40 |
+
{
|
| 41 |
+
m_nonTerms.push_back(NonTerm(*this, source, target));
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
bool ConsistentPhrase::TargetOverlap(const ConsistentPhrase &other) const
|
| 45 |
+
{
|
| 46 |
+
if ( other.corners[3] < corners[2] || other.corners[2] > corners[3])
|
| 47 |
+
return false;
|
| 48 |
+
|
| 49 |
+
return true;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
std::string ConsistentPhrase::Debug() const
|
| 53 |
+
{
|
| 54 |
+
stringstream out;
|
| 55 |
+
out << "[" << corners[0] << "-" << corners[1]
|
| 56 |
+
<< "][" << corners[2] << "-" << corners[3] << "]";
|
| 57 |
+
|
| 58 |
+
out << "NT:";
|
| 59 |
+
for (size_t i = 0; i < m_nonTerms.size(); ++i) {
|
| 60 |
+
const NonTerm &nonTerm = m_nonTerms[i];
|
| 61 |
+
out << nonTerm.GetLabel(Moses::Input) << ":" << nonTerm.GetLabel(Moses::Output);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
return out.str();
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
|
mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrases.cpp
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* ConsistentPhrases.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 20 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include <sstream>
|
| 8 |
+
#include <cassert>
|
| 9 |
+
#include "ConsistentPhrases.h"
|
| 10 |
+
#include "NonTerm.h"
|
| 11 |
+
#include "Parameter.h"
|
| 12 |
+
#include "moses/Util.h"
|
| 13 |
+
|
| 14 |
+
using namespace std;
|
| 15 |
+
|
| 16 |
+
ConsistentPhrases::ConsistentPhrases()
|
| 17 |
+
{
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
ConsistentPhrases::~ConsistentPhrases()
|
| 21 |
+
{
|
| 22 |
+
for (size_t start = 0; start < m_coll.size(); ++start) {
|
| 23 |
+
std::vector<Coll> &allSourceStart = m_coll[start];
|
| 24 |
+
|
| 25 |
+
for (size_t size = 0; size < allSourceStart.size(); ++size) {
|
| 26 |
+
Coll &coll = allSourceStart[size];
|
| 27 |
+
Moses::RemoveAllInColl(coll);
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
void ConsistentPhrases::Initialize(size_t size)
|
| 33 |
+
{
|
| 34 |
+
m_coll.resize(size);
|
| 35 |
+
|
| 36 |
+
for (size_t sourceStart = 0; sourceStart < size; ++sourceStart) {
|
| 37 |
+
std::vector<Coll> &allSourceStart = m_coll[sourceStart];
|
| 38 |
+
allSourceStart.resize(size - sourceStart);
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
void ConsistentPhrases::Add(int sourceStart, int sourceEnd,
|
| 43 |
+
int targetStart, int targetEnd,
|
| 44 |
+
const Parameter ¶ms)
|
| 45 |
+
{
|
| 46 |
+
Coll &coll = m_coll[sourceStart][sourceEnd - sourceStart];
|
| 47 |
+
ConsistentPhrase *cp = new ConsistentPhrase(sourceStart, sourceEnd,
|
| 48 |
+
targetStart, targetEnd,
|
| 49 |
+
params);
|
| 50 |
+
|
| 51 |
+
assert(coll.find(cp) == coll.end());
|
| 52 |
+
coll.insert(cp);
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
const ConsistentPhrases::Coll &ConsistentPhrases::GetColl(int sourceStart, int sourceEnd) const
|
| 56 |
+
{
|
| 57 |
+
const std::vector<Coll> &allSourceStart = m_coll[sourceStart];
|
| 58 |
+
const Coll &ret = allSourceStart[sourceEnd - sourceStart];
|
| 59 |
+
return ret;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
ConsistentPhrases::Coll &ConsistentPhrases::GetColl(int sourceStart, int sourceEnd)
|
| 63 |
+
{
|
| 64 |
+
std::vector<Coll> &allSourceStart = m_coll[sourceStart];
|
| 65 |
+
Coll &ret = allSourceStart[sourceEnd - sourceStart];
|
| 66 |
+
return ret;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
std::string ConsistentPhrases::Debug() const
|
| 70 |
+
{
|
| 71 |
+
std::stringstream out;
|
| 72 |
+
for (size_t start = 0; start < m_coll.size(); ++start) {
|
| 73 |
+
const std::vector<Coll> &allSourceStart = m_coll[start];
|
| 74 |
+
|
| 75 |
+
for (size_t size = 0; size < allSourceStart.size(); ++size) {
|
| 76 |
+
const Coll &coll = allSourceStart[size];
|
| 77 |
+
|
| 78 |
+
Coll::const_iterator iter;
|
| 79 |
+
for (iter = coll.begin(); iter != coll.end(); ++iter) {
|
| 80 |
+
const ConsistentPhrase &consistentPhrase = **iter;
|
| 81 |
+
out << consistentPhrase.Debug() << endl;
|
| 82 |
+
}
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
return out.str();
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
void ConsistentPhrases::AddHieroNonTerms(const Parameter ¶ms)
|
| 90 |
+
{
|
| 91 |
+
// add [X] labels everywhere
|
| 92 |
+
for (size_t i = 0; i < m_coll.size(); ++i) {
|
| 93 |
+
vector<Coll> &inner = m_coll[i];
|
| 94 |
+
for (size_t j = 0; j < inner.size(); ++j) {
|
| 95 |
+
ConsistentPhrases::Coll &coll = inner[j];
|
| 96 |
+
ConsistentPhrases::Coll::iterator iter;
|
| 97 |
+
for (iter = coll.begin(); iter != coll.end(); ++iter) {
|
| 98 |
+
ConsistentPhrase &cp = **iter;
|
| 99 |
+
cp.AddNonTerms(params.hieroNonTerm, params.hieroNonTerm);
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
|
mosesdecoder/phrase-extract/extract-mixed-syntax/Jamfile
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
exe extract-mixed-syntax : Main.cpp AlignedSentence.cpp AlignedSentenceSyntax.cpp ConsistentPhrase.cpp ConsistentPhrases.cpp NonTerm.cpp Parameter.cpp Phrase.cpp pugixml.cpp Rule.cpp RulePhrase.cpp Rules.cpp RuleSymbol.cpp SyntaxTree.cpp Word.cpp ..//deps ../..//z ../..//boost_iostreams ../..//boost_program_options ../../moses//moses : <include>.. ;
|
| 2 |
+
|
mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.cpp
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Parameter.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 17 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#include "Parameter.h"
|
| 8 |
+
#include "moses/Util.h"
|
| 9 |
+
#include "util/exception.hh"
|
| 10 |
+
|
| 11 |
+
using namespace std;
|
| 12 |
+
|
| 13 |
+
Parameter::Parameter()
|
| 14 |
+
:maxSpan(10)
|
| 15 |
+
,minSpan(0)
|
| 16 |
+
,maxNonTerm(2)
|
| 17 |
+
,maxHieroNonTerm(999)
|
| 18 |
+
,maxSymbolsTarget(999)
|
| 19 |
+
,maxSymbolsSource(5)
|
| 20 |
+
,minHoleSource(2)
|
| 21 |
+
,minHoleSourceSyntax(1)
|
| 22 |
+
,sentenceOffset(0)
|
| 23 |
+
,nonTermConsecSource(false)
|
| 24 |
+
,requireAlignedWord(true)
|
| 25 |
+
,fractionalCounting(true)
|
| 26 |
+
,gzOutput(false)
|
| 27 |
+
|
| 28 |
+
,hieroNonTerm("[X]")
|
| 29 |
+
,sourceSyntax(false)
|
| 30 |
+
,targetSyntax(false)
|
| 31 |
+
|
| 32 |
+
,mixedSyntaxType(0)
|
| 33 |
+
,multiLabel(0)
|
| 34 |
+
,nonTermConsecSourceMixed(true)
|
| 35 |
+
,hieroSourceLHS(false)
|
| 36 |
+
,maxSpanFreeNonTermSource(0)
|
| 37 |
+
,nieceTerminal(true)
|
| 38 |
+
,maxScope(UNDEFINED)
|
| 39 |
+
,minScope(0)
|
| 40 |
+
|
| 41 |
+
,spanLength(false)
|
| 42 |
+
,ruleLength(false)
|
| 43 |
+
,nonTermContext(false)
|
| 44 |
+
,nonTermContextTarget(false)
|
| 45 |
+
,nonTermContextFactor(0)
|
| 46 |
+
|
| 47 |
+
,numSourceFactors(1)
|
| 48 |
+
,numTargetFactors(1)
|
| 49 |
+
|
| 50 |
+
,nonTermConsecSourceMixedSyntax(1)
|
| 51 |
+
{}
|
| 52 |
+
|
| 53 |
+
Parameter::~Parameter()
|
| 54 |
+
{
|
| 55 |
+
// TODO Auto-generated destructor stub
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
void Parameter::SetScopeSpan(const std::string &str)
|
| 59 |
+
{
|
| 60 |
+
scopeSpanStr = str;
|
| 61 |
+
vector<string> toks1;
|
| 62 |
+
Moses::Tokenize(toks1, str, ":");
|
| 63 |
+
|
| 64 |
+
for (size_t i = 0; i < toks1.size(); ++i) {
|
| 65 |
+
const string &tok1 = toks1[i];
|
| 66 |
+
|
| 67 |
+
vector<int> toks2;
|
| 68 |
+
Moses::Tokenize<int>(toks2, tok1, ",");
|
| 69 |
+
UTIL_THROW_IF2(toks2.size() != 2, "Format is min,max:min,max... String is " << tok1);
|
| 70 |
+
|
| 71 |
+
std::pair<int,int> values(toks2[0], toks2[1]);
|
| 72 |
+
scopeSpan.push_back(values);
|
| 73 |
+
}
|
| 74 |
+
}
|
mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.h
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* Parameter.h
|
| 3 |
+
*
|
| 4 |
+
* Created on: 17 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
#pragma once
|
| 8 |
+
|
| 9 |
+
#include <string>
|
| 10 |
+
#include <limits>
|
| 11 |
+
#include <vector>
|
| 12 |
+
|
| 13 |
+
#define UNDEFINED std::numeric_limits<int>::max()
|
| 14 |
+
|
| 15 |
+
class Parameter
|
| 16 |
+
{
|
| 17 |
+
public:
|
| 18 |
+
Parameter();
|
| 19 |
+
virtual ~Parameter();
|
| 20 |
+
|
| 21 |
+
int maxSpan;
|
| 22 |
+
int minSpan;
|
| 23 |
+
int maxNonTerm;
|
| 24 |
+
int maxHieroNonTerm;
|
| 25 |
+
int maxSymbolsTarget;
|
| 26 |
+
int maxSymbolsSource;
|
| 27 |
+
int minHoleSource;
|
| 28 |
+
int minHoleSourceSyntax;
|
| 29 |
+
|
| 30 |
+
long sentenceOffset;
|
| 31 |
+
|
| 32 |
+
bool nonTermConsecSource;
|
| 33 |
+
bool requireAlignedWord;
|
| 34 |
+
bool fractionalCounting;
|
| 35 |
+
bool gzOutput;
|
| 36 |
+
|
| 37 |
+
std::string hieroNonTerm;
|
| 38 |
+
std::string gluePath;
|
| 39 |
+
|
| 40 |
+
bool sourceSyntax, targetSyntax;
|
| 41 |
+
|
| 42 |
+
int mixedSyntaxType, multiLabel;
|
| 43 |
+
bool nonTermConsecSourceMixed;
|
| 44 |
+
bool hieroSourceLHS;
|
| 45 |
+
int maxSpanFreeNonTermSource;
|
| 46 |
+
bool nieceTerminal;
|
| 47 |
+
int maxScope, minScope;
|
| 48 |
+
|
| 49 |
+
// properties
|
| 50 |
+
bool spanLength;
|
| 51 |
+
bool ruleLength;
|
| 52 |
+
bool nonTermContext;
|
| 53 |
+
bool nonTermContextTarget;
|
| 54 |
+
int nonTermContextFactor;
|
| 55 |
+
|
| 56 |
+
int numSourceFactors, numTargetFactors;
|
| 57 |
+
|
| 58 |
+
int nonTermConsecSourceMixedSyntax;
|
| 59 |
+
|
| 60 |
+
std::string scopeSpanStr;
|
| 61 |
+
std::vector<std::pair<int,int> > scopeSpan;
|
| 62 |
+
|
| 63 |
+
void SetScopeSpan(const std::string &str);
|
| 64 |
+
|
| 65 |
+
};
|
| 66 |
+
|
mosesdecoder/phrase-extract/extract-mixed-syntax/Phrase.cpp
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <sstream>
|
| 2 |
+
#include "Phrase.h"
|
| 3 |
+
|
| 4 |
+
std::string Phrase::Debug() const
|
| 5 |
+
{
|
| 6 |
+
std::stringstream out;
|
| 7 |
+
|
| 8 |
+
for (size_t i = 0; i < size(); ++i) {
|
| 9 |
+
Word &word = *at(i);
|
| 10 |
+
out << word.Debug() << " ";
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
return out.str();
|
| 14 |
+
}
|
mosesdecoder/phrase-extract/extract-mixed-syntax/RulePhrase.cpp
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/*
|
| 2 |
+
* RulePhrase.cpp
|
| 3 |
+
*
|
| 4 |
+
* Created on: 26 Feb 2014
|
| 5 |
+
* Author: hieu
|
| 6 |
+
*/
|
| 7 |
+
|
| 8 |
+
#include <sstream>
|
| 9 |
+
#include "RulePhrase.h"
|
| 10 |
+
#include "RuleSymbol.h"
|
| 11 |
+
|
| 12 |
+
using namespace std;
|
| 13 |
+
|
| 14 |
+
extern bool g_debug;
|
| 15 |
+
|
| 16 |
+
int RulePhrase::Compare(const RulePhrase &other) const
|
| 17 |
+
{
|
| 18 |
+
if (GetSize() != other.GetSize()) {
|
| 19 |
+
return GetSize() < other.GetSize() ? -1 : +1;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
for (size_t i = 0; i < m_coll.size(); ++i) {
|
| 23 |
+
const RuleSymbol &symbol = *m_coll[i];
|
| 24 |
+
const RuleSymbol &otherSymbol = *other.m_coll[i];
|
| 25 |
+
int compare = symbol.Compare(otherSymbol);
|
| 26 |
+
|
| 27 |
+
if (compare) {
|
| 28 |
+
return compare;
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
return 0;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
void RulePhrase::Output(std::ostream &out) const
|
| 36 |
+
{
|
| 37 |
+
for (size_t i = 0; i < m_coll.size(); ++i) {
|
| 38 |
+
const RuleSymbol &symbol = *m_coll[i];
|
| 39 |
+
symbol.Output(out);
|
| 40 |
+
out << " ";
|
| 41 |
+
}
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
std::string RulePhrase::Debug() const
|
| 45 |
+
{
|
| 46 |
+
std::stringstream out;
|
| 47 |
+
Output(out);
|
| 48 |
+
return out.str();
|
| 49 |
+
}
|
| 50 |
+
|