-
-
Notifications
You must be signed in to change notification settings - Fork 16
Inflection 77: Adding C and C++ API for stating source grammemes and tests for the same. #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| * @param value - The speakable string to convert to a concept | ||
| * @param intitialConstraints - The intitial constraints for the map. | ||
| */ | ||
| InflectableStringConcept(const SemanticFeatureModel* model, const SpeakableString& value, const std::map<SemanticFeature, ::std::u16string> intitialConstraints); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The map should be a const & for the API.
| * @param speakFeature The speakFeature from the SemanticFeatureModel that represents the SemanticFeature for the speak information for a SpeakableString. | ||
| * @param constraintMap The intitial constraint map. | ||
| */ | ||
| DisplayValue(const SpeakableString& value, const SemanticFeature& speakFeature, const ::std::map<SemanticFeature, ::std::u16string> constraintMap); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The map should be a const & for the API.
| DisplayValue::DisplayValue(const SpeakableString& value, const SemanticFeature& speakFeature) | ||
| : DisplayValue(value.getPrint(), {}) | ||
| DisplayValue::DisplayValue( | ||
| const SpeakableString& value, | ||
| const SemanticFeature& speakFeature, | ||
| const ::std::map<SemanticFeature, ::std::u16string> constraintMap) | ||
| : DisplayValue(value.getPrint(), constraintMap) | ||
| { | ||
| if (!value.speakEqualsPrint()) { | ||
| constraintMap.emplace(speakFeature, value.getSpeak()); | ||
| this->constraintMap.emplace(speakFeature, value.getSpeak()); | ||
| } | ||
| } | ||
|
|
||
| DisplayValue::DisplayValue( | ||
| const SpeakableString& value, | ||
| const SemanticFeature& speakFeature) | ||
| : DisplayValue(value.getPrint(), {}) | ||
| { | ||
| if (!value.speakEqualsPrint()) { | ||
| this->constraintMap.emplace(speakFeature, value.getSpeak()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please declare these functions in the same order as the header? It makes it easier to navigate.
Also the 2 argument constructor with the speakFeature can now call the new constructor with an empty map. Then the redundant if statement can be removed. It's best to keep the copy and paste code to a minimum to improve the maintenance.
| InflectableStringConcept::InflectableStringConcept(const SemanticFeatureModel* model, const SpeakableString& value) | ||
| InflectableStringConcept::InflectableStringConcept( | ||
| const SemanticFeatureModel* model, | ||
| const SpeakableString& value, | ||
| const ::std::map<SemanticFeature, ::std::u16string> intitialConstraints | ||
| ) | ||
| : super(model) | ||
| , value(value) | ||
| , defaultDisplayValue(value, *npc(super::getSpeakFeature()), intitialConstraints) | ||
| { | ||
| } | ||
|
|
||
| InflectableStringConcept::InflectableStringConcept( | ||
| const SemanticFeatureModel* model, | ||
| const SpeakableString& value | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please declare these functions in the same order as the header? It makes it easier to navigate.
Also the 2 argument constructor with the SpeakableString can now call the new constructor with an empty map. Then the copied code can be removed. It's best to keep the copy and paste code to a minimum to improve the maintenance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I would keep that in mind.
Being a fresher I wasn't aware.
|
@grhoten I have added the C API too can you please review and tell me the next steps. |
| * This is set to a failure when a failure has occurred during execution. | ||
| */ | ||
| INFLECTION_CAPI IDInflectableStringConcept* iinf_createWithConstraints(const IDSemanticFeatureModel* model, const IDSpeakableString* value, | ||
| const inflection::dialog::SemanticFeature* features, const char16_t** values, int32_t SemanticFeaturesLen, UErrorCode* status); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++ API is not allowed in C API. Please see ipron_createWithDefaults for how to pass in such values. That API also ensures that the 2 lengths are exactly the same.
For consistency with the PronounConcept API, it would be ideal if this was also named iinf_createWithDefaults to be consistent with the naming.
grhoten
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All new API need tests. The code should always be in a releasable state. Please add tests for these changes. The current code should be well over 90% line code coverage.
Please also state which issue is being fixed with these changes. That is best done with prefixing your commits and pull request summary with "Inflection-77".
| #include <inflection/dialog/SemanticFeatureConcept.h> | ||
| #include <inflection/dialog/SemanticFeatureModel.h> | ||
|
|
||
| #include <inflection/dialog/SemanticUtils.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This internal C++ header should not be used in public C API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will fix that
| if (pronounData->numValues() == 0) { | ||
| throw ::inflection::exception::IllegalArgumentException(u"Display data can not be empty."); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that this file needs to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup sure, I mistakenly added a line and forgot
|
@grhoten
|
|
@grhoten
|
static functions are not available outside of the file. It also compiles. So that implies that the changes are OK.
As long as there are a couple of tests, that should be sufficient to show the utility of the API.
I recommend including a test of iinf_createWithDefaults in InflectableStringConceptTest-c.cpp.
|
| <test><source definiteness="definite">cometa</source><initial gender="masculine"/><result number="singular" gender="masculine">el cometa</result></test> | ||
| <test><source definiteness="definite">cometa</source><initial gender="feminine"/><result number="singular" gender="feminine">la cometa</result></test> | ||
| <test><source definiteness="definite">QQQQ</source><initial gender="masculine" number="plural"/><result number="plural" gender="masculine">los QQQQ</result></test> | ||
| <test><source definiteness="definite">QQQQ</source><initial gender="feminine" number="plural"/><result number="plural" gender="masculine">las QQQQ</result></test> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests look reasonable.
| } | ||
| return new SpeakableString(result); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grhoten
Was this the expected behavior in this function? If not, could you please point out where I am going wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Within the DictionaryLookupFunction, you're only returning the grammeme value. This does not need to change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DictionaryLookupFunction::getFeatureValue likely needs to be updated to query the relevant values from displayValue. It should probably query DisplayValue::getFeatureValue or DisplayValue::getConstraintMap
Okay sure I wanted to know exactly what I need to do, based on your previous comment I came up with this commit, could you please tell what is expected to make the tests pass so that i could implement the same and further add tests in InfectableStringConceptTest-c.cpp as well to complete this task ?
…createWithDefaults as InflectableStringConceptTest-c#testCreateWithDefaults
|
Hello!! |
| auto initialConstraint = initialConstraintMap.find(feature); | ||
| if (initialConstraint != initialConstraintMap.end()) { | ||
| return new SpeakableString(initialConstraint->second); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes are confusing. Why are these changes needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More precisely, why is getFeatureValue being called here? Why is the feature name being checked for gender? What's special about gender or number? Why not grammatical case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto displayConstraint = displayConstraintMap.find(feature);
if (displayConstraint != displayConstraintMap.end()) {
auto numberFeature = npc(getModel())->getFeature(u"number");
if (feature.getName() == u"gender" && baseValue && numberFeature != nullptr
&& displayConstraintMap.find(*npc(numberFeature)) != displayConstraintMap.end()) {
return baseValue.release();
}
return new SpeakableString(displayConstraint->second);
} This is the test case which was failing before the changes:
<test>
<source definiteness="definite">cometa</source>
<initial gender="masculine"/>
<result gender="masculine" number="singular">el cometa</result>
</test>-
InflectableStringConcept::getFeatureValueasks the default display function for a renderedDisplayValue, so feature lookups reflect whatever the display layer injected (articles, inflections, etc.). Spanish determiners add bothgenderandnumberto that map, and the gender can contradict the lexeme default (la cometa). -
To avoid reporting the article’s guess as the noun’s gender, the code detects
feature == "gender"and, when the number constraint is present too, returns the lexeme’s base value instead of the display-layer value. English articles never set gender, and no language mutates case in this path yet (I am not sure though), so only the gender/number pair needs a guard today. -
InflectableStringConcept::getFeatureValueasks the default display function for a renderedDisplayValue, so feature lookups reflect whatever the display layer injected (articles, inflections, etc.). -
Spanish determiners add both
genderandnumberto that map, and the gender can contradict the lexeme default (la cometa).
To avoid reporting the article’s guess as the noun’s gender, the code detectsfeature == "gender"and, when the number constraint is present too, returns the lexeme’s base value instead of the display-layer value, as these conditions when satisfied point to the case when we have an article being inserted. -
Grammatical case isn’t treated specially because the Spanish article logic never synthesizes case information—so there’s no regression to guard against. If a language later injected case-altering determiners we’d need a similar safeguard, but today only the gender/number pair exhibits the mismatch.
|
@grhoten instead to get the include path automatically. |

@grhoten
Issue #77
Could you please review this so that I could move forward for C API and XML parsing too.