|
1 | 1 | /* |
2 | | - * Copyright 2025 Apple Inc. All rights reserved. |
| 2 | + * Copyright 2025 Unicode Incorporated and others. All rights reserved. |
3 | 3 | */ |
4 | | -#include <inflection/grammar/synthesis/MlGrammarSynthesizer.hpp> |
5 | 4 |
|
| 5 | +#include <inflection/grammar/synthesis/MlGrammarSynthesizer.hpp> |
6 | 6 | #include <inflection/dialog/SemanticFeatureModel.hpp> |
7 | 7 | #include <inflection/grammar/synthesis/MlGrammarSynthesizer_NumberLookupFunction.hpp> |
8 | 8 | #include <inflection/grammar/synthesis/MlGrammarSynthesizer_GenderLookupFunction.hpp> |
9 | 9 | #include <inflection/grammar/synthesis/MlGrammarSynthesizer_CaseLookupFunction.hpp> |
10 | 10 | #include <inflection/grammar/synthesis/MlGrammarSynthesizer_MlDisplayFunction.hpp> |
11 | 11 | #include <inflection/grammar/synthesis/GrammemeConstants.hpp> |
| 12 | +#include <inflection/npc.hpp> |
| 13 | +#include <map> |
12 | 14 |
|
13 | 15 | namespace inflection::grammar::synthesis { |
14 | 16 |
|
| 17 | + static constexpr auto MOOD_SUBJUNCTIVE = u"subjunctive"; |
| 18 | + |
15 | 19 | void MlGrammarSynthesizer::addSemanticFeatures(::inflection::dialog::SemanticFeatureModel& featureModel) |
16 | 20 | { |
17 | | - featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::NUMBER, new MlGrammarSynthesizer_NumberLookupFunction()); |
18 | | - featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::GENDER, new MlGrammarSynthesizer_GenderLookupFunction()); |
19 | | - featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::CASE, new MlGrammarSynthesizer_CaseLookupFunction()); |
20 | | - |
| 21 | + featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::NUMBER, |
| 22 | + new MlGrammarSynthesizer_NumberLookupFunction()); |
| 23 | + featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::GENDER, |
| 24 | + new MlGrammarSynthesizer_GenderLookupFunction()); |
| 25 | + featureModel.putDefaultFeatureFunctionByName(GrammemeConstants::CASE, |
| 26 | + new MlGrammarSynthesizer_CaseLookupFunction()); |
| 27 | + |
21 | 28 | featureModel.setDefaultDisplayFunction(new MlGrammarSynthesizer_MlDisplayFunction(featureModel)); |
22 | 29 | } |
23 | 30 |
|
24 | | -} // namespace inflection::grammar::synthesis |
| 31 | +MlGrammarSynthesizer::Number MlGrammarSynthesizer::getNumber(const ::std::u16string* value) { |
| 32 | + if (!value) return Number::undefined; |
| 33 | + if (*value == GrammemeConstants::NUMBER_SINGULAR()) return Number::singular; |
| 34 | + if (*value == GrammemeConstants::NUMBER_PLURAL()) return Number::plural; |
| 35 | + return Number::undefined; |
| 36 | +} |
| 37 | + |
| 38 | +MlGrammarSynthesizer::Case MlGrammarSynthesizer::getCase(const ::std::u16string* value) { |
| 39 | + if (!value) return Case::undefined; |
| 40 | + if (*value == GrammemeConstants::CASE_NOMINATIVE()) return Case::nominative; |
| 41 | + if (*value == GrammemeConstants::CASE_ACCUSATIVE()) return Case::accusative; |
| 42 | + if (*value == GrammemeConstants::CASE_DATIVE()) return Case::dative; |
| 43 | + if (*value == GrammemeConstants::CASE_GENITIVE()) return Case::genitive; |
| 44 | + if (*value == GrammemeConstants::CASE_INSTRUMENTAL()) return Case::instrumental; |
| 45 | + if (*value == GrammemeConstants::CASE_LOCATIVE()) return Case::locative; |
| 46 | + return Case::undefined; |
| 47 | +} |
| 48 | + |
| 49 | +MlGrammarSynthesizer::Person MlGrammarSynthesizer::getPerson(const ::std::u16string* value) { |
| 50 | + if (!value) return Person::undefined; |
| 51 | + if (*value == GrammemeConstants::PERSON_FIRST()) return Person::first; |
| 52 | + if (*value == GrammemeConstants::PERSON_SECOND()) return Person::second; |
| 53 | + if (*value == GrammemeConstants::PERSON_THIRD()) return Person::third; |
| 54 | + return Person::undefined; |
| 55 | +} |
25 | 56 |
|
| 57 | +MlGrammarSynthesizer::Tense MlGrammarSynthesizer::getTense(const ::std::u16string* value) { |
| 58 | + if (!value) return Tense::undefined; |
| 59 | + if (*value == GrammemeConstants::TENSE_PAST()) return Tense::past; |
| 60 | + if (*value == GrammemeConstants::TENSE_PRESENT()) return Tense::present; |
| 61 | + if (*value == GrammemeConstants::TENSE_FUTURE()) return Tense::future; |
| 62 | + return Tense::undefined; |
| 63 | +} |
| 64 | + |
| 65 | +MlGrammarSynthesizer::Mood MlGrammarSynthesizer::getMood(const ::std::u16string* value) { |
| 66 | + if (!value) return Mood::undefined; |
| 67 | + if (*value == GrammemeConstants::MOOD_INDICATIVE()) return Mood::indicative; |
| 68 | + if (*value == GrammemeConstants::MOOD_IMPERATIVE()) return Mood::imperative; |
| 69 | + if (*value == MOOD_SUBJUNCTIVE) return Mood::subjunctive; |
| 70 | + return Mood::undefined; |
| 71 | +} |
| 72 | + |
| 73 | +MlGrammarSynthesizer::LookupKey MlGrammarSynthesizer::makeLookupKey(Number num, Case kase) { |
| 74 | + return (static_cast<LookupKey>(kase) & 0xFF) |
| 75 | + | ((static_cast<LookupKey>(num) & 0xFF) << 8); |
| 76 | +} |
| 77 | + |
| 78 | +MlGrammarSynthesizer::LookupKey MlGrammarSynthesizer::makeVerbLookupKey(Person person, Number num, Tense tense, Mood mood) { |
| 79 | + return (static_cast<LookupKey>(person) & 0xFF) |
| 80 | + | ((static_cast<LookupKey>(num) & 0xFF) << 8) |
| 81 | + | ((static_cast<LookupKey>(tense) & 0x0F) << 24) |
| 82 | + | ((static_cast<LookupKey>(mood) & 0x0F) << 28); |
| 83 | +} |
| 84 | + |
| 85 | +MlGrammarSynthesizer::Person MlGrammarSynthesizer::personFromConstraint(const ::std::u16string& val) { |
| 86 | + return getPerson(&val); |
| 87 | +} |
| 88 | + |
| 89 | +MlGrammarSynthesizer::Number MlGrammarSynthesizer::numberFromConstraint(const ::std::u16string& val) { |
| 90 | + return getNumber(&val); |
| 91 | +} |
| 92 | + |
| 93 | +MlGrammarSynthesizer::Case MlGrammarSynthesizer::caseFromConstraint(const ::std::u16string& val) { |
| 94 | + return getCase(&val); |
| 95 | +} |
| 96 | + |
| 97 | +MlGrammarSynthesizer::LookupKey MlGrammarSynthesizer::buildVerbSuffixKey(const std::vector<::std::u16string>& constraintValues) { |
| 98 | + Person person = Person::undefined; |
| 99 | + Number num = Number::undefined; |
| 100 | + Tense tense = Tense::undefined; |
| 101 | + Mood mood = Mood::undefined; |
| 102 | + |
| 103 | + for (const auto& val : constraintValues) { |
| 104 | + if (person == Person::undefined) person = personFromConstraint(val); |
| 105 | + if (num == Number::undefined) num = numberFromConstraint(val); |
| 106 | + if (tense == Tense::undefined) tense = getTense(&val); |
| 107 | + if (mood == Mood::undefined) mood = getMood(&val); |
| 108 | + } |
| 109 | + |
| 110 | + return makeVerbLookupKey(person, num, tense, mood); |
| 111 | +} |
| 112 | + |
| 113 | +const std::map<MlGrammarSynthesizer::LookupKey, ::std::u16string> MlGrammarSynthesizer::malayalamSuffixMap = { |
| 114 | + {makeLookupKey(Number::singular, Case::nominative), u""}, |
| 115 | + {makeLookupKey(Number::plural, Case::nominative), u"കൾ"}, |
| 116 | + {makeLookupKey(Number::singular, Case::genitive), u"യുടെ"}, |
| 117 | + {makeLookupKey(Number::plural, Case::genitive), u"കളുടെ"}, |
| 118 | + {makeLookupKey(Number::singular, Case::dative), u"ക്ക്"}, |
| 119 | + {makeLookupKey(Number::plural, Case::dative), u"കൾക്ക്"}, |
| 120 | +}; |
| 121 | + |
| 122 | +const std::map<MlGrammarSynthesizer::LookupKey, ::std::u16string> MlGrammarSynthesizer::malayalamVerbSuffixMap = { |
| 123 | + {makeVerbLookupKey(Person::first, Number::singular, Tense::past, Mood::indicative), u"ച്ചു"}, |
| 124 | + {makeVerbLookupKey(Person::first, Number::plural, Tense::past, Mood::indicative), u"ഞ്ഞു"}, |
| 125 | + {makeVerbLookupKey(Person::second, Number::singular, Tense::past, Mood::indicative), u"ച്ചു"}, |
| 126 | + {makeVerbLookupKey(Person::second, Number::plural, Tense::past, Mood::indicative), u"ന്നു"}, |
| 127 | + {makeVerbLookupKey(Person::third, Number::singular, Tense::past, Mood::indicative), u"ച്ചു"}, |
| 128 | + {makeVerbLookupKey(Person::third, Number::plural, Tense::past, Mood::indicative), u"ന്നു"}, |
| 129 | + |
| 130 | + {makeVerbLookupKey(Person::first, Number::singular, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 131 | + {makeVerbLookupKey(Person::first, Number::plural, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 132 | + {makeVerbLookupKey(Person::second, Number::singular, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 133 | + {makeVerbLookupKey(Person::second, Number::plural, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 134 | + {makeVerbLookupKey(Person::third, Number::singular, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 135 | + {makeVerbLookupKey(Person::third, Number::plural, Tense::present, Mood::indicative), u"ിക്കുന്നു"}, |
| 136 | + |
| 137 | + {makeVerbLookupKey(Person::first, Number::singular, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 138 | + {makeVerbLookupKey(Person::first, Number::plural, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 139 | + {makeVerbLookupKey(Person::second, Number::singular, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 140 | + {makeVerbLookupKey(Person::second, Number::plural, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 141 | + {makeVerbLookupKey(Person::third, Number::singular, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 142 | + {makeVerbLookupKey(Person::third, Number::plural, Tense::future, Mood::indicative), u" ചെയ്യും"}, |
| 143 | +}; |
| 144 | + |
| 145 | +const std::u16string& MlGrammarSynthesizer::getSuffix(LookupKey key) { |
| 146 | + static const std::u16string empty = u""; |
| 147 | + auto it = malayalamSuffixMap.find(key); |
| 148 | + return it != malayalamSuffixMap.end() ? it->second : empty; |
| 149 | +} |
| 150 | + |
| 151 | +const std::u16string& MlGrammarSynthesizer::getVerbSuffix(LookupKey key) { |
| 152 | + static const std::u16string empty = u""; |
| 153 | + auto it = malayalamVerbSuffixMap.find(key); |
| 154 | + return it != malayalamVerbSuffixMap.end() ? it->second : empty; |
| 155 | +} |
| 156 | + |
| 157 | +} // namespace inflection::grammar::synthesis |
0 commit comments