00001 #include "PhraseBoundaryFeature.h"
00002
00003 #include "moses/Hypothesis.h"
00004 #include "moses/TranslationOption.h"
00005 #include "moses/InputPath.h"
00006 #include "util/string_stream.hh"
00007
00008 using namespace std;
00009
00010 namespace Moses
00011 {
00012
00013 size_t PhraseBoundaryState::hash() const
00014 {
00015 size_t ret = hash_value(*m_targetWord);
00016 boost::hash_combine(ret, hash_value(*m_sourceWord));
00017
00018 return ret;
00019 }
00020 bool PhraseBoundaryState::operator==(const FFState& other) const
00021 {
00022 const PhraseBoundaryState& rhs = static_cast<const PhraseBoundaryState&>(other);
00023 bool ret = *m_targetWord == *rhs.m_targetWord && *m_sourceWord == *rhs.m_sourceWord;
00024 return ret;
00025 }
00026
00028 PhraseBoundaryFeature::PhraseBoundaryFeature(const std::string &line)
00029 : StatefulFeatureFunction(0, line)
00030 {
00031 std::cerr << "Initializing source word deletion feature.." << std::endl;
00032 ReadParameters();
00033 }
00034
00035 void PhraseBoundaryFeature::SetParameter(const std::string& key, const std::string& value)
00036 {
00037 if (key == "source") {
00038 m_sourceFactors = Tokenize<FactorType>(value, ",");
00039 } else if (key == "target") {
00040 m_targetFactors = Tokenize<FactorType>(value, ",");
00041 } else {
00042 StatefulFeatureFunction::SetParameter(key, value);
00043 }
00044 }
00045
00046 const FFState* PhraseBoundaryFeature::EmptyHypothesisState(const InputType &) const
00047 {
00048 return new PhraseBoundaryState(NULL,NULL);
00049 }
00050
00051
00052 void PhraseBoundaryFeature::AddFeatures(
00053 const Word* leftWord, const Word* rightWord, const FactorList& factors, const string& side,
00054 ScoreComponentCollection* scores) const
00055 {
00056 for (size_t i = 0; i < factors.size(); ++i) {
00057 util::StringStream name;
00058 name << side << ":";
00059 name << factors[i];
00060 name << ":";
00061 if (leftWord) {
00062 name << leftWord->GetFactor(factors[i])->GetString();
00063 } else {
00064 name << BOS_;
00065 }
00066 name << ":";
00067 if (rightWord) {
00068 name << rightWord->GetFactor(factors[i])->GetString();
00069 } else {
00070 name << EOS_;
00071 }
00072 scores->PlusEquals(this,name.str(),1);
00073 }
00074
00075 }
00076
00077 FFState* PhraseBoundaryFeature::EvaluateWhenApplied
00078 (const Hypothesis& cur_hypo, const FFState* prev_state,
00079 ScoreComponentCollection* scores) const
00080 {
00081 const PhraseBoundaryState* pbState = static_cast<const PhraseBoundaryState*>(prev_state);
00082 const Phrase& targetPhrase = cur_hypo.GetCurrTargetPhrase();
00083 if (targetPhrase.GetSize() == 0) {
00084 return new PhraseBoundaryState(*pbState);
00085 }
00086 const Word* leftTargetWord = pbState->GetTargetWord();
00087 const Word* rightTargetWord = &(targetPhrase.GetWord(0));
00088 AddFeatures(leftTargetWord,rightTargetWord,m_targetFactors,"tgt",scores);
00089
00090 const Phrase& sourcePhrase = cur_hypo.GetTranslationOption().GetInputPath().GetPhrase();
00091 const Word* leftSourceWord = pbState->GetSourceWord();
00092 const Word* rightSourceWord = &(sourcePhrase.GetWord(0));
00093 AddFeatures(leftSourceWord,rightSourceWord,m_sourceFactors,"src",scores);
00094
00095 const Word* endSourceWord = &(sourcePhrase.GetWord(sourcePhrase.GetSize()-1));
00096 const Word* endTargetWord = &(targetPhrase.GetWord(targetPhrase.GetSize()-1));
00097
00098
00099 if (cur_hypo.IsSourceCompleted()) {
00100 AddFeatures(endSourceWord,NULL,m_sourceFactors,"src",scores);
00101 AddFeatures(endTargetWord,NULL,m_targetFactors,"tgt",scores);
00102 }
00103
00104 return new PhraseBoundaryState(endSourceWord,endTargetWord);
00105 }
00106
00107 bool PhraseBoundaryFeature::IsUseable(const FactorMask &mask) const
00108 {
00109 for (size_t i = 0; i < m_targetFactors.size(); ++i) {
00110 const FactorType &factor = m_targetFactors[i];
00111 if (!mask[factor]) {
00112 return false;
00113 }
00114 }
00115 return true;
00116 }
00117
00118 }