sleepyhead111 commited on
Commit
cd33cd3
·
verified ·
1 Parent(s): edace67

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. mosesdecoder/COPYING +460 -0
  2. mosesdecoder/bjam +23 -0
  3. mosesdecoder/moses2/AlignmentInfoCollection.h +81 -0
  4. mosesdecoder/moses2/ArcLists.h +44 -0
  5. mosesdecoder/moses2/EstimatedScores.cpp +117 -0
  6. mosesdecoder/moses2/InputPathBase.h +32 -0
  7. mosesdecoder/moses2/InputType.h +86 -0
  8. mosesdecoder/moses2/Moses2Wrapper.cpp +70 -0
  9. mosesdecoder/moses2/Phrase.cpp +23 -0
  10. mosesdecoder/moses2/Scores.cpp +283 -0
  11. mosesdecoder/moses2/System.cpp +262 -0
  12. mosesdecoder/moses2/System.h +90 -0
  13. mosesdecoder/moses2/TargetPhrase.h +164 -0
  14. mosesdecoder/moses2/TrellisPaths.cpp +14 -0
  15. mosesdecoder/moses2/TypeDef.cpp +11 -0
  16. mosesdecoder/moses2/Word.h +63 -0
  17. mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.cpp +418 -0
  18. mosesdecoder/phrase-extract/extract-ghkm/AlignmentGraph.h +87 -0
  19. mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.cpp +134 -0
  20. mosesdecoder/phrase-extract/extract-ghkm/ComposedRule.h +75 -0
  21. mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.cpp +902 -0
  22. mosesdecoder/phrase-extract/extract-ghkm/ExtractGHKM.h +82 -0
  23. mosesdecoder/phrase-extract/extract-ghkm/Jamfile +1 -0
  24. mosesdecoder/phrase-extract/extract-ghkm/Main.cpp +26 -0
  25. mosesdecoder/phrase-extract/extract-ghkm/Node.cpp +76 -0
  26. mosesdecoder/phrase-extract/extract-ghkm/Node.h +223 -0
  27. mosesdecoder/phrase-extract/extract-ghkm/Options.h +95 -0
  28. mosesdecoder/phrase-extract/extract-ghkm/Rule.cpp +44 -0
  29. mosesdecoder/phrase-extract/extract-ghkm/Rule.h +62 -0
  30. mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.cpp +203 -0
  31. mosesdecoder/phrase-extract/extract-ghkm/ScfgRule.h +99 -0
  32. mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.cpp +235 -0
  33. mosesdecoder/phrase-extract/extract-ghkm/ScfgRuleWriter.h +63 -0
  34. mosesdecoder/phrase-extract/extract-ghkm/Span.cpp +51 -0
  35. mosesdecoder/phrase-extract/extract-ghkm/Span.h +45 -0
  36. mosesdecoder/phrase-extract/extract-ghkm/StsgRule.cpp +97 -0
  37. mosesdecoder/phrase-extract/extract-ghkm/StsgRule.h +47 -0
  38. mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.cpp +98 -0
  39. mosesdecoder/phrase-extract/extract-ghkm/StsgRuleWriter.h +44 -0
  40. mosesdecoder/phrase-extract/extract-ghkm/Subgraph.cpp +206 -0
  41. mosesdecoder/phrase-extract/extract-ghkm/Subgraph.h +143 -0
  42. mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentence.cpp +195 -0
  43. mosesdecoder/phrase-extract/extract-mixed-syntax/AlignedSentenceSyntax.h +46 -0
  44. mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrase.cpp +67 -0
  45. mosesdecoder/phrase-extract/extract-mixed-syntax/ConsistentPhrases.cpp +104 -0
  46. mosesdecoder/phrase-extract/extract-mixed-syntax/Jamfile +2 -0
  47. mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.cpp +74 -0
  48. mosesdecoder/phrase-extract/extract-mixed-syntax/Parameter.h +66 -0
  49. mosesdecoder/phrase-extract/extract-mixed-syntax/Phrase.cpp +14 -0
  50. 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 &paramsArg) :
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 &params;
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 &paramsArg);
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 &copy);
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 &params)
109
+ {
110
+ CreateConsistentPhrases(params);
111
+ m_consistentPhrases.AddHieroNonTerms(params);
112
+ }
113
+
114
+ void AlignedSentence::CreateConsistentPhrases(const Parameter &params)
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 &params);
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 &params);
34
+ void XMLParse(Phrase &output,
35
+ SyntaxTree &tree,
36
+ const pugi::xml_node &parentNode,
37
+ const Parameter &params);
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 &params,
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 &params)
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 &params)
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 &params)
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
+