00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <ctime>
00023 #include <iostream>
00024 #include <iterator>
00025 #include <fstream>
00026 #include <sstream>
00027 #include <algorithm>
00028 #include "Parameter.h"
00029 #include "Util.h"
00030 #include "InputFileStream.h"
00031 #include "UserMessage.h"
00032
00033 using namespace std;
00034
00035 namespace Moses
00036 {
00038 Parameter::Parameter()
00039 {
00040 AddParam("beam-threshold", "b", "threshold for threshold pruning");
00041 AddParam("config", "f", "location of the configuration file");
00042 AddParam("continue-partial-translation", "cpt", "start from nonempty hypothesis");
00043 AddParam("decoding-graph-backoff", "dpb", "only use subsequent decoding paths for unknown spans of given length");
00044 AddParam("drop-unknown", "du", "drop unknown words instead of copying them");
00045 AddParam("disable-discarding", "dd", "disable hypothesis discarding");
00046 AddParam("factor-delimiter", "fd", "specify a different factor delimiter than the default");
00047 AddParam("generation-file", "location and properties of the generation table");
00048 AddParam("global-lexical-file", "gl", "discriminatively trained global lexical translation model file");
00049 AddParam("input-factors", "list of factors in the input");
00050 AddParam("input-file", "i", "location of the input file to be translated");
00051 AddParam("inputtype", "text (0), confusion network (1), word lattice (2) (default = 0)");
00052 AddParam("labeled-n-best-list", "print out labels for each weight type in n-best list. default is true");
00053 AddParam("include-alignment-in-n-best", "include word alignment in the n-best list. default is false");
00054 AddParam("lmodel-file", "location and properties of the language models");
00055 AddParam("lmodel-dub", "dictionary upper bounds of language models");
00056 AddParam("lmodel-oov-feature", "add language model oov feature, one per model");
00057 AddParam("mapping", "description of decoding steps");
00058 AddParam("max-partial-trans-opt", "maximum number of partial translation options per input span (during mapping steps)");
00059 AddParam("max-trans-opt-per-coverage", "maximum number of translation options per input span (after applying mapping steps)");
00060 AddParam("max-phrase-length", "maximum phrase length (default 20)");
00061 AddParam("n-best-list", "file and size of n-best-list to be generated; specify - as the file in order to write to STDOUT");
00062 AddParam("lattice-samples", "generate samples from lattice, in same format as nbest list. Uses the file and size arguments, as in n-best-list");
00063 AddParam("n-best-factor", "factor to compute the maximum number of contenders (=factor*nbest-size). value 0 means infinity, i.e. no threshold. default is 0");
00064 AddParam("print-all-derivations", "to print all derivations in search graph");
00065 AddParam("output-factors", "list of factors in the output");
00066 AddParam("phrase-drop-allowed", "da", "if present, allow dropping of source words");
00067 AddParam("report-all-factors", "report all factors in output, not just first");
00068 AddParam("report-all-factors-in-n-best", "Report all factors in n-best-lists. Default is false");
00069 AddParam("report-segmentation", "t", "report phrase segmentation in the output");
00070 #ifdef HAVE_SYNLM
00071 AddParam("slmodel-file", "location of the syntactic language model file(s)");
00072 AddParam("weight-slm", "slm", "weight(s) for syntactic language model");
00073 AddParam("slmodel-factor", "factor to use with syntactic language model");
00074 AddParam("slmodel-beam", "beam width to use with syntactic language model's parser");
00075 #endif
00076 AddParam("stack", "s", "maximum stack size for histogram pruning");
00077 AddParam("stack-diversity", "sd", "minimum number of hypothesis of each coverage in stack (default 0)");
00078 AddParam("threads","th", "number of threads to use in decoding (defaults to single-threaded)");
00079 AddParam("translation-details", "T", "for each best hypothesis, report translation details to the given file");
00080 AddParam("ttable-file", "location and properties of the translation tables");
00081 AddParam("ttable-limit", "ttl", "maximum number of translation table entries per input phrase");
00082 AddParam("translation-option-threshold", "tot", "threshold for translation options relative to best for input phrase");
00083 AddParam("early-discarding-threshold", "edt", "threshold for constructing hypotheses based on estimate cost");
00084 AddParam("verbose", "v", "verbosity level of the logging");
00085 AddParam("weight-d", "d", "weight(s) for distortion (reordering components)");
00086 AddParam("weight-lr", "lr", "weight(s) for lexicalized reordering, if not included in weight-d");
00087 AddParam("weight-generation", "g", "weight(s) for generation components");
00088 AddParam("weight-i", "I", "weight(s) for word insertion - used for parameters from confusion network and lattice input links");
00089 AddParam("weight-l", "lm", "weight(s) for language models");
00090 AddParam("weight-lex", "lex", "weight for global lexical model");
00091 AddParam("weight-t", "tm", "weights for translation model components");
00092 AddParam("weight-w", "w", "weight for word penalty");
00093 AddParam("weight-u", "u", "weight for unknown word penalty");
00094 AddParam("weight-e", "e", "weight for word deletion");
00095 AddParam("output-factors", "list if factors in the output");
00096 AddParam("cache-path", "?");
00097 AddParam("distortion-limit", "dl", "distortion (reordering) limit in maximum number of words (0 = monotone, -1 = unlimited)");
00098 AddParam("monotone-at-punctuation", "mp", "do not reorder over punctuation");
00099 AddParam("distortion-file", "source factors (0 if table independent of source), target factors, location of the factorized/lexicalized reordering tables");
00100 AddParam("distortion", "configurations for each factorized/lexicalized reordering model.");
00101 AddParam("xml-input", "xi", "allows markup of input with desired translations and probabilities. values can be 'pass-through' (default), 'inclusive', 'exclusive', 'ignore'");
00102 AddParam("xml-brackets", "xb", "specify strings to be used as xml tags opening and closing, e.g. \"{{ }}\" (default \"< >\"). Avoid square brackets because of configuration file format. Valid only with text input mode" );
00103 AddParam("minimum-bayes-risk", "mbr", "use miminum Bayes risk to determine best translation");
00104 AddParam("lminimum-bayes-risk", "lmbr", "use lattice miminum Bayes risk to determine best translation");
00105 AddParam("consensus-decoding", "con", "use consensus decoding (De Nero et. al. 2009)");
00106 AddParam("mbr-size", "number of translation candidates considered in MBR decoding (default 200)");
00107 AddParam("mbr-scale", "scaling factor to convert log linear score probability in MBR decoding (default 1.0)");
00108 AddParam("lmbr-thetas", "theta(s) for lattice mbr calculation");
00109 AddParam("lmbr-pruning-factor", "average number of nodes/word wanted in pruned lattice");
00110 AddParam("lmbr-p", "unigram precision value for lattice mbr");
00111 AddParam("lmbr-r", "ngram precision decay value for lattice mbr");
00112 AddParam("lmbr-map-weight", "weight given to map solution when doing lattice MBR (default 0)");
00113 AddParam("lattice-hypo-set", "to use lattice as hypo set during lattice MBR");
00114 AddParam("clean-lm-cache", "clean language model caches after N translations (default N=1)");
00115 AddParam("use-persistent-cache", "cache translation options across sentences (default true)");
00116 AddParam("persistent-cache-size", "maximum size of cache for translation options (default 10,000 input phrases)");
00117 AddParam("recover-input-path", "r", "(conf net/word lattice only) - recover input path corresponding to the best translation");
00118 AddParam("output-word-graph", "owg", "Output stack info as word graph. Takes filename, 0=only hypos in stack, 1=stack + nbest hypos");
00119 AddParam("time-out", "seconds after which is interrupted (-1=no time-out, default is -1)");
00120 AddParam("output-search-graph", "osg", "Output connected hypotheses of search into specified filename");
00121 AddParam("output-search-graph-extended", "osgx", "Output connected hypotheses of search into specified filename, in extended format");
00122 AddParam("unpruned-search-graph", "usg", "When outputting chart search graph, do not exclude dead ends. Note: stack pruning may have eliminated some hypotheses");
00123 #ifdef HAVE_PROTOBUF
00124 AddParam("output-search-graph-pb", "pb", "Write phrase lattice to protocol buffer objects in the specified path.");
00125 #endif
00126 AddParam("cube-pruning-pop-limit", "cbp", "How many hypotheses should be popped for each stack. (default = 1000)");
00127 AddParam("cube-pruning-diversity", "cbd", "How many hypotheses should be created for each coverage. (default = 0)");
00128 AddParam("cube-pruning-lazy-scoring", "cbls", "Don't fully score a hypothesis until it is popped");
00129 AddParam("parsing-algorithm", "Which parsing algorithm to use. 0=CYK+, 1=scope-3. (default = 0)");
00130 AddParam("search-algorithm", "Which search algorithm to use. 0=normal stack, 1=cube pruning, 2=cube growing. (default = 0)");
00131 AddParam("constraint", "Location of the file with target sentences to produce constraining the search");
00132 AddParam("use-alignment-info", "Use word-to-word alignment: actually it is only used to output the word-to-word alignment. Word-to-word alignments are taken from the phrase table if any. Default is false.");
00133 AddParam("print-alignment-info", "Output word-to-word alignment into the log file. Word-to-word alignments are takne from the phrase table if any. Default is false");
00134 AddParam("print-alignment-info-in-n-best", "Include word-to-word alignment in the n-best list. Word-to-word alignments are takne from the phrase table if any. Default is false");
00135 AddParam("link-param-count", "Number of parameters on word links when using confusion networks or lattices (default = 1)");
00136 AddParam("description", "Source language, target language, description");
00137
00138 AddParam("max-chart-span", "maximum num. of source word chart rules can consume (default 10)");
00139 AddParam("non-terminals", "list of non-term symbols, space separated");
00140 AddParam("rule-limit", "a little like table limit. But for chart decoding rules. Default is DEFAULT_MAX_TRANS_OPT_SIZE");
00141 AddParam("source-label-overlap", "What happens if a span already has a label. 0=add more. 1=replace. 2=discard. Default is 0");
00142 AddParam("output-hypo-score", "Output the hypo score to stdout with the output string. For search error analysis. Default is false");
00143 AddParam("unknown-lhs", "file containing target lhs of unknown words. 1 per line: LHS prob");
00144 AddParam("translation-systems", "specify multiple translation systems, each consisting of an id, followed by a set of models ids, eg '0 T1 R1 L0'");
00145 AddParam("show-weights", "print feature weights and exit");
00146 AddParam("alignment-output-file", "print output word alignments into given file");
00147 AddParam("sort-word-alignment", "Sort word alignments for more consistent display. 0=no sort (default), 1=target order");
00148 AddParam("start-translation-id", "Id of 1st input. Default = 0");
00149 }
00150
00151 Parameter::~Parameter()
00152 {
00153 }
00154
00156 void Parameter::AddParam(const string ¶mName, const string &description)
00157 {
00158 m_valid[paramName] = true;
00159 m_description[paramName] = description;
00160 }
00161
00163 void Parameter::AddParam(const string ¶mName, const string &abbrevName, const string &description)
00164 {
00165 m_valid[paramName] = true;
00166 m_valid[abbrevName] = true;
00167 m_abbreviation[paramName] = abbrevName;
00168 m_description[paramName] = description;
00169 }
00170
00172 void Parameter::Explain()
00173 {
00174 cerr << "Usage:" << endl;
00175 for(PARAM_STRING::const_iterator iterParam = m_description.begin(); iterParam != m_description.end(); iterParam++) {
00176 const string paramName = iterParam->first;
00177 const string paramDescription = iterParam->second;
00178 cerr << "\t-" << paramName;
00179 PARAM_STRING::const_iterator iterAbbr = m_abbreviation.find( paramName );
00180 if ( iterAbbr != m_abbreviation.end() )
00181 cerr << " (" << iterAbbr->second << ")";
00182 cerr << ": " << paramDescription << endl;
00183 }
00184 }
00185
00189 bool Parameter::isOption(const char* token)
00190 {
00191 if (! token) return false;
00192 std::string tokenString(token);
00193 size_t length = tokenString.size();
00194 if (length > 0 && tokenString.substr(0,1) != "-") return false;
00195 if (length > 1 && tokenString.substr(1,1).find_first_not_of("0123456789") == 0) return true;
00196 return false;
00197 }
00198
00200 bool Parameter::LoadParam(const string &filePath)
00201 {
00202 const char *argv[] = {"executable", "-f", filePath.c_str() };
00203 return LoadParam(3, (char**) argv);
00204 }
00205
00207 bool Parameter::LoadParam(int argc, char* argv[])
00208 {
00209
00210 string configPath;
00211 if ( (configPath = FindParam("-f", argc, argv)) == ""
00212 && (configPath = FindParam("-config", argc, argv)) == "") {
00213 PrintCredit();
00214 Explain();
00215
00216 UserMessage::Add("No configuration file was specified. Use -config or -f");
00217 return false;
00218 } else {
00219 if (!ReadConfigFile(configPath)) {
00220 UserMessage::Add("Could not read "+configPath);
00221 return false;
00222 }
00223 }
00224
00225
00226 for(PARAM_STRING::const_iterator iterParam = m_description.begin(); iterParam != m_description.end(); iterParam++) {
00227 const string paramName = iterParam->first;
00228 OverwriteParam("-" + paramName, paramName, argc, argv);
00229 }
00230
00231
00232 for(PARAM_STRING::const_iterator iterParam = m_abbreviation.begin(); iterParam != m_abbreviation.end(); iterParam++) {
00233 const string paramName = iterParam->first;
00234 const string paramShortName = iterParam->second;
00235 OverwriteParam("-" + paramShortName, paramName, argc, argv);
00236 }
00237
00238
00239 int verbose = 1;
00240 if (m_setting.find("verbose") != m_setting.end() &&
00241 m_setting["verbose"].size() > 0)
00242 verbose = Scan<int>(m_setting["verbose"][0]);
00243 if (verbose >= 1) {
00244 TRACE_ERR( "Defined parameters (per moses.ini or switch):" << endl);
00245 for(PARAM_MAP::const_iterator iterParam = m_setting.begin() ; iterParam != m_setting.end(); iterParam++) {
00246 TRACE_ERR( "\t" << iterParam->first << ": ");
00247 for ( size_t i = 0; i < iterParam->second.size(); i++ )
00248 TRACE_ERR( iterParam->second[i] << " ");
00249 TRACE_ERR( endl);
00250 }
00251 }
00252
00253
00254 bool noErrorFlag = true;
00255 for (int i = 0 ; i < argc ; i++) {
00256 if (isOption(argv[i])) {
00257 string paramSwitch = (string) argv[i];
00258 string paramName = paramSwitch.substr(1);
00259 if (m_valid.find(paramName) == m_valid.end()) {
00260 UserMessage::Add("illegal switch: " + paramSwitch);
00261 noErrorFlag = false;
00262 }
00263 }
00264 }
00265
00266
00267 return Validate() && noErrorFlag;
00268 }
00269
00271 bool Parameter::Validate()
00272 {
00273 bool noErrorFlag = true;
00274
00275 PARAM_MAP::const_iterator iterParams;
00276 for (iterParams = m_setting.begin(); iterParams != m_setting.end(); ++iterParams) {
00277 const std::string &key = iterParams->first;
00278
00279 if (m_valid.find(key) == m_valid.end())
00280 {
00281 UserMessage::Add("Unknown parameter " + key);
00282 noErrorFlag = false;
00283 }
00284 }
00285
00286
00287
00288 if (m_setting["ttable-file"].size() == 0) {
00289 UserMessage::Add("No phrase translation table (ttable-file)");
00290 noErrorFlag = false;
00291 }
00292
00293 if (m_setting["lmodel-dub"].size() > 0) {
00294 if (m_setting["lmodel-file"].size() != m_setting["lmodel-dub"].size()) {
00295 stringstream errorMsg("");
00296 errorMsg << "Config and parameters specify "
00297 << static_cast<int>(m_setting["lmodel-file"].size())
00298 << " language model files (lmodel-file), but "
00299 << static_cast<int>(m_setting["lmodel-dub"].size())
00300 << " LM upperbounds (lmodel-dub)"
00301 << endl;
00302 UserMessage::Add(errorMsg.str());
00303 noErrorFlag = false;
00304 }
00305 }
00306
00307 if (m_setting["lmodel-file"].size() * (m_setting.find("lmodel-oov-feature") != m_setting.end() ? 2 : 1)
00308 != m_setting["weight-l"].size()) {
00309 stringstream errorMsg("");
00310 errorMsg << "Config and parameters specify "
00311 << static_cast<int>(m_setting["lmodel-file"].size())
00312 << " language model files (lmodel-file), but "
00313 << static_cast<int>(m_setting["weight-l"].size())
00314 << " weights (weight-l)";
00315 errorMsg << endl << "You might be giving '-lmodel-file TYPE FACTOR ORDER FILENAME' but you should be giving these four as a single argument, i.e. '-lmodel-file \"TYPE FACTOR ORDER FILENAME\"'";
00316 errorMsg << endl << "You should also remember that each language model requires 2 weights, if and only if lmodel-oov-feature is on.";
00317 UserMessage::Add(errorMsg.str());
00318 noErrorFlag = false;
00319 }
00320
00321
00322
00323
00324 if (noErrorFlag && m_setting["input-file"].size() == 1) {
00325 noErrorFlag = FileExists(m_setting["input-file"][0]);
00326 }
00327
00328 if (noErrorFlag) {
00329 std::vector<std::string> ext;
00330
00331 ext.push_back("");
00332 ext.push_back(".gz");
00333 noErrorFlag = FilesExist("generation-file", 3, ext);
00334 }
00335
00336 if (noErrorFlag) {
00337 std::vector<std::string> ext;
00338
00339 ext.push_back("");
00340 ext.push_back(".gz");
00341
00342 ext.push_back(".binlexr.idx");
00343 noErrorFlag = FilesExist("distortion-file", 3, ext);
00344 }
00345 return noErrorFlag;
00346 }
00347
00349 bool Parameter::FilesExist(const string ¶mName, int fieldNo, std::vector<std::string> const& extensions)
00350 {
00351 typedef std::vector<std::string> StringVec;
00352 StringVec::const_iterator iter;
00353
00354 PARAM_MAP::const_iterator iterParam = m_setting.find(paramName);
00355 if (iterParam == m_setting.end()) {
00356
00357 return true;
00358 }
00359 const StringVec &pathVec = (*iterParam).second;
00360 for (iter = pathVec.begin() ; iter != pathVec.end() ; ++iter) {
00361 StringVec vec = Tokenize(*iter);
00362
00363 size_t tokenizeIndex;
00364 if (fieldNo == -1)
00365 tokenizeIndex = vec.size() - 1;
00366 else
00367 tokenizeIndex = static_cast<size_t>(fieldNo);
00368
00369 if (tokenizeIndex >= vec.size()) {
00370 stringstream errorMsg("");
00371 errorMsg << "Expected at least " << (tokenizeIndex+1) << " tokens per entry in '"
00372 << paramName << "', but only found "
00373 << vec.size();
00374 UserMessage::Add(errorMsg.str());
00375 return false;
00376 }
00377 const string &pathStr = vec[tokenizeIndex];
00378
00379 bool fileFound=0;
00380 for(size_t i=0; i<extensions.size() && !fileFound; ++i) {
00381 fileFound|=FileExists(pathStr + extensions[i]);
00382 }
00383 if(!fileFound) {
00384 stringstream errorMsg("");
00385 errorMsg << "File " << pathStr << " does not exist";
00386 UserMessage::Add(errorMsg.str());
00387 return false;
00388 }
00389 }
00390 return true;
00391 }
00392
00394
00395
00396 string Parameter::FindParam(const string ¶mSwitch, int argc, char* argv[])
00397 {
00398 for (int i = 0 ; i < argc ; i++) {
00399 if (string(argv[i]) == paramSwitch) {
00400 if (i+1 < argc) {
00401 return argv[i+1];
00402 } else {
00403 stringstream errorMsg("");
00404 errorMsg << "Option " << paramSwitch << " requires a parameter!";
00405 UserMessage::Add(errorMsg.str());
00406
00407 }
00408 }
00409 }
00410 return "";
00411 }
00412
00418 void Parameter::OverwriteParam(const string ¶mSwitch, const string ¶mName, int argc, char* argv[])
00419 {
00420 int startPos = -1;
00421 for (int i = 0 ; i < argc ; i++) {
00422 if (string(argv[i]) == paramSwitch) {
00423 startPos = i+1;
00424 break;
00425 }
00426 }
00427 if (startPos < 0)
00428 return;
00429
00430 int index = 0;
00431 m_setting[paramName];
00432 while (startPos < argc && (!isOption(argv[startPos]))) {
00433 if (m_setting[paramName].size() > (size_t)index)
00434 m_setting[paramName][index] = argv[startPos];
00435 else
00436 m_setting[paramName].push_back(argv[startPos]);
00437 index++;
00438 startPos++;
00439 }
00440 }
00441
00442
00444 bool Parameter::ReadConfigFile(const string &filePath )
00445 {
00446 InputFileStream inFile(filePath);
00447 string line, paramName;
00448 while(getline(inFile, line)) {
00449
00450 size_t comPos = line.find_first_of("#");
00451 if (comPos != string::npos)
00452 line = line.substr(0, comPos);
00453
00454 line = Trim(line);
00455
00456 if (line.size() == 0) {
00457
00458 }
00459 else if (line[0]=='[') {
00460
00461 for (size_t currPos = 0 ; currPos < line.size() ; currPos++) {
00462 if (line[currPos] == ']') {
00463 paramName = line.substr(1, currPos - 1);
00464 break;
00465 }
00466 }
00467 } else {
00468
00469 m_setting[paramName].push_back(line);
00470 }
00471 }
00472 return true;
00473 }
00474
00475 struct Credit {
00476 string name, contact, currentPursuits, areaResponsibility;
00477 int sortId;
00478
00479 Credit(string name, string contact, string currentPursuits, string areaResponsibility) {
00480 this->name = name ;
00481 this->contact = contact ;
00482 this->currentPursuits = currentPursuits ;
00483 this->areaResponsibility = areaResponsibility;
00484 this->sortId = rand() % 1000;
00485 }
00486
00487 bool operator<(const Credit &other) const {
00488
00489
00490
00491
00492
00493
00494
00495
00496 return sortId < other.sortId;
00497 }
00498
00499 };
00500
00501 std::ostream& operator<<(std::ostream &os, const Credit &credit)
00502 {
00503 os << credit.name;
00504 if (credit.contact != "")
00505 os << "\t contact: " << credit.contact;
00506 if (credit.currentPursuits != "")
00507 os << " " << credit.currentPursuits;
00508 if (credit.areaResponsibility != "")
00509 os << " I'll answer question on: " << credit.areaResponsibility;
00510 return os;
00511 }
00512
00513 void Parameter::PrintCredit()
00514 {
00515 vector<Credit> everyone;
00516 srand ( time(NULL) );
00517
00518 everyone.push_back(Credit("Nicola Bertoldi"
00519 , "911"
00520 , ""
00521 , "scripts & other stuff"));
00522 everyone.push_back(Credit("Ondrej Bojar"
00523 , ""
00524 , "czech this out!"
00525 , ""));
00526 everyone.push_back(Credit("Chris Callison-Burch"
00527 , "anytime, anywhere"
00528 , "international playboy"
00529 , ""));
00530 everyone.push_back(Credit("Alexandra Constantin"
00531 , ""
00532 , "eu sunt varza"
00533 , ""));
00534 everyone.push_back(Credit("Brooke Cowan"
00535 , "brooke@csail.mit.edu"
00536 , "if you're going to san francisco, be sure to wear a flower in your hair"
00537 , ""));
00538 everyone.push_back(Credit("Chris Dyer"
00539 , "can't. i'll be out driving my mustang"
00540 , "driving my mustang"
00541 , ""));
00542 everyone.push_back(Credit("Marcello Federico"
00543 , "federico at itc at it"
00544 , "Researcher at ITC-irst, Trento, Italy"
00545 , "IRST language model"));
00546 everyone.push_back(Credit("Evan Herbst"
00547 , "Small college in upstate New York"
00548 , ""
00549 , ""));
00550 everyone.push_back(Credit("Philipp Koehn"
00551 , "only between 2 and 4am"
00552 , ""
00553 , "Nothing fazes this dude"));
00554 everyone.push_back(Credit("Christine Moran"
00555 , "weird building at MIT"
00556 , ""
00557 , ""));
00558 everyone.push_back(Credit("Wade Shen"
00559 , "via morse code"
00560 , "buying another laptop"
00561 , ""));
00562 everyone.push_back(Credit("Richard Zens"
00563 , "richard at aachen dot de"
00564 , ""
00565 , "ambiguous source input, confusion networks, confusing source code"));
00566 everyone.push_back(Credit("Hieu Hoang", "http://www.hoang.co.uk/hieu/"
00567 , "phd student at Edinburgh Uni. Original Moses developer"
00568 , "general queries/ flames on Moses."));
00569
00570 sort(everyone.begin(), everyone.end());
00571
00572
00573 cerr << "Moses - A beam search decoder for phrase-based statistical machine translation models" << endl
00574 << "Copyright (C) 2006 University of Edinburgh" << endl << endl
00575
00576 << "This library is free software; you can redistribute it and/or" << endl
00577 << "modify it under the terms of the GNU Lesser General Public" << endl
00578 << "License as published by the Free Software Foundation; either" << endl
00579 << "version 2.1 of the License, or (at your option) any later version." << endl << endl
00580
00581 << "This library is distributed in the hope that it will be useful," << endl
00582 << "but WITHOUT ANY WARRANTY; without even the implied warranty of" << endl
00583 << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU" << endl
00584 << "Lesser General Public License for more details." << endl << endl
00585
00586 << "You should have received a copy of the GNU Lesser General Public" << endl
00587 << "License along with this library; if not, write to the Free Software" << endl
00588 << "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA" << endl << endl
00589 << "***********************************************************************" << endl << endl
00590 << "Built on " << __DATE__ << " at " __TIME__ << endl << endl
00591 << "WHO'S FAULT IS THIS GODDAM SOFTWARE:" << endl;
00592
00593 ostream_iterator<Credit> out(cerr, "\n");
00594 copy(everyone.begin(), everyone.end(), out);
00595 cerr << endl << endl;
00596 }
00597
00598 }
00599
00600