Merge "Use SuggestionResults to get suggestion."
This commit is contained in:
commit
618a949f9d
13 changed files with 128 additions and 175 deletions
|
@ -199,47 +199,30 @@ static void latinime_BinaryDictionary_getSuggestions(JNIEnv *env, jclass clazz,
|
||||||
ASSERT(false);
|
ASSERT(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int outputCodePoints[outputCodePointsLength];
|
|
||||||
int scores[scoresLength];
|
|
||||||
const jsize spaceIndicesLength = env->GetArrayLength(outSpaceIndicesArray);
|
|
||||||
int spaceIndices[spaceIndicesLength];
|
|
||||||
const jsize outputTypesLength = env->GetArrayLength(outTypesArray);
|
|
||||||
int outputTypes[outputTypesLength];
|
|
||||||
const jsize outputAutoCommitFirstWordConfidenceLength =
|
const jsize outputAutoCommitFirstWordConfidenceLength =
|
||||||
env->GetArrayLength(outAutoCommitFirstWordConfidenceArray);
|
env->GetArrayLength(outAutoCommitFirstWordConfidenceArray);
|
||||||
// We only use the first result, as obviously we will only ever autocommit the first one
|
|
||||||
ASSERT(outputAutoCommitFirstWordConfidenceLength == 1);
|
ASSERT(outputAutoCommitFirstWordConfidenceLength == 1);
|
||||||
int outputAutoCommitFirstWordConfidence[outputAutoCommitFirstWordConfidenceLength];
|
if (outputAutoCommitFirstWordConfidenceLength != 1) {
|
||||||
memset(outputCodePoints, 0, sizeof(outputCodePoints));
|
// We only use the first result, as obviously we will only ever autocommit the first one
|
||||||
memset(scores, 0, sizeof(scores));
|
AKLOGE("Invalid outputAutoCommitFirstWordConfidenceLength: %d",
|
||||||
memset(spaceIndices, 0, sizeof(spaceIndices));
|
outputAutoCommitFirstWordConfidenceLength);
|
||||||
memset(outputTypes, 0, sizeof(outputTypes));
|
ASSERT(false);
|
||||||
memset(outputAutoCommitFirstWordConfidence, 0, sizeof(outputAutoCommitFirstWordConfidence));
|
|
||||||
|
|
||||||
if (givenSuggestOptions.isGesture() || inputSize > 0) {
|
|
||||||
// TODO: Use SuggestionResults to return suggestions.
|
|
||||||
count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
|
|
||||||
times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
|
|
||||||
prevWordCodePointsLength, &givenSuggestOptions, outputCodePoints,
|
|
||||||
scores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
|
|
||||||
} else {
|
|
||||||
SuggestionResults suggestionResults(MAX_RESULTS);
|
|
||||||
dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
|
|
||||||
&suggestionResults);
|
|
||||||
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
|
|
||||||
outScoresArray, outSpaceIndicesArray, outTypesArray,
|
|
||||||
outAutoCommitFirstWordConfidenceArray);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy back the output values
|
SuggestionResults suggestionResults(MAX_RESULTS);
|
||||||
env->SetIntArrayRegion(outSuggestionCount, 0, 1 /* len */, &count);
|
if (givenSuggestOptions.isGesture() || inputSize > 0) {
|
||||||
env->SetIntArrayRegion(outCodePointsArray, 0, outputCodePointsLength, outputCodePoints);
|
// TODO: Use SuggestionResults to return suggestions.
|
||||||
env->SetIntArrayRegion(outScoresArray, 0, scoresLength, scores);
|
dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
|
||||||
env->SetIntArrayRegion(outSpaceIndicesArray, 0, spaceIndicesLength, spaceIndices);
|
times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
|
||||||
env->SetIntArrayRegion(outTypesArray, 0, outputTypesLength, outputTypes);
|
prevWordCodePointsLength, &givenSuggestOptions, &suggestionResults);
|
||||||
env->SetIntArrayRegion(outAutoCommitFirstWordConfidenceArray, 0,
|
} else {
|
||||||
outputAutoCommitFirstWordConfidenceLength, outputAutoCommitFirstWordConfidence);
|
dictionary->getPredictions(prevWordCodePoints, prevWordCodePointsLength,
|
||||||
|
&suggestionResults);
|
||||||
|
}
|
||||||
|
suggestionResults.outputSuggestions(env, outSuggestionCount, outCodePointsArray,
|
||||||
|
outScoresArray, outSpaceIndicesArray, outTypesArray,
|
||||||
|
outAutoCommitFirstWordConfidenceArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict,
|
static jint latinime_BinaryDictionary_getProbability(JNIEnv *env, jclass clazz, jlong dict,
|
||||||
|
|
|
@ -103,7 +103,8 @@ AK_FORCE_INLINE static int intArrayToCharArray(const int *const source, const in
|
||||||
#define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
|
#define AKLOGI(fmt, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##__VA_ARGS__)
|
||||||
#endif // defined(HOST_TOOL)
|
#endif // defined(HOST_TOOL)
|
||||||
|
|
||||||
#define DUMP_RESULT(words, frequencies) do { dumpResult(words, frequencies); } while (0)
|
#define DUMP_SUGGESTION(words, frequencies, index, score) \
|
||||||
|
do { dumpWordInfo(words, frequencies, index, score); } while (0)
|
||||||
#define DUMP_WORD(word, length) do { dumpWord(word, length); } while (0)
|
#define DUMP_WORD(word, length) do { dumpWord(word, length); } while (0)
|
||||||
#define INTS_TO_CHARS(input, length, output, outlength) do { \
|
#define INTS_TO_CHARS(input, length, output, outlength) do { \
|
||||||
intArrayToCharArray(input, length, output, outlength); } while (0)
|
intArrayToCharArray(input, length, output, outlength); } while (0)
|
||||||
|
@ -165,7 +166,7 @@ static inline void showStackTrace() {
|
||||||
#else // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
|
#else // defined(FLAG_DO_PROFILE) || defined(FLAG_DBG)
|
||||||
#define AKLOGE(fmt, ...)
|
#define AKLOGE(fmt, ...)
|
||||||
#define AKLOGI(fmt, ...)
|
#define AKLOGI(fmt, ...)
|
||||||
#define DUMP_RESULT(words, frequencies)
|
#define DUMP_SUGGESTION(words, frequencies, index, score)
|
||||||
#define DUMP_WORD(word, length)
|
#define DUMP_WORD(word, length)
|
||||||
#undef DO_ASSERT_TEST
|
#undef DO_ASSERT_TEST
|
||||||
#define ASSERT(success)
|
#define ASSERT(success)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "suggest/core/policy/dictionary_header_structure_policy.h"
|
#include "suggest/core/policy/dictionary_header_structure_policy.h"
|
||||||
|
#include "suggest/core/result/suggestion_results.h"
|
||||||
#include "suggest/core/session/dic_traverse_session.h"
|
#include "suggest/core/session/dic_traverse_session.h"
|
||||||
#include "suggest/core/suggest.h"
|
#include "suggest/core/suggest.h"
|
||||||
#include "suggest/core/suggest_options.h"
|
#include "suggest/core/suggest_options.h"
|
||||||
|
@ -43,34 +44,25 @@ Dictionary::Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::Structu
|
||||||
logDictionaryInfo(env);
|
logDictionaryInfo(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
void Dictionary::getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
||||||
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
||||||
int inputSize, int *prevWordCodePoints, int prevWordLength,
|
int inputSize, int *prevWordCodePoints, int prevWordLength,
|
||||||
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
|
const SuggestOptions *const suggestOptions,
|
||||||
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const {
|
SuggestionResults *const outSuggestionResults) const {
|
||||||
TimeKeeper::setCurrentTime();
|
TimeKeeper::setCurrentTime();
|
||||||
int result = 0;
|
DicTraverseSession::initSessionInstance(
|
||||||
|
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
||||||
if (suggestOptions->isGesture()) {
|
if (suggestOptions->isGesture()) {
|
||||||
DicTraverseSession::initSessionInstance(
|
mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
||||||
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
|
||||||
result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
|
||||||
ycoordinates, times, pointerIds, inputCodePoints, inputSize, outWords,
|
|
||||||
outputScores, spaceIndices, outputTypes, outputAutoCommitFirstWordConfidence);
|
|
||||||
if (DEBUG_DICT) {
|
|
||||||
DUMP_RESULT(outWords, outputScores);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
DicTraverseSession::initSessionInstance(
|
|
||||||
traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
|
|
||||||
result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
|
||||||
ycoordinates, times, pointerIds, inputCodePoints, inputSize,
|
ycoordinates, times, pointerIds, inputCodePoints, inputSize,
|
||||||
outWords, outputScores, spaceIndices, outputTypes,
|
outSuggestionResults);
|
||||||
outputAutoCommitFirstWordConfidence);
|
} else {
|
||||||
if (DEBUG_DICT) {
|
mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
|
||||||
DUMP_RESULT(outWords, outputScores);
|
ycoordinates, times, pointerIds, inputCodePoints, inputSize,
|
||||||
|
outSuggestionResults);
|
||||||
}
|
}
|
||||||
return result;
|
if (DEBUG_DICT) {
|
||||||
|
outSuggestionResults->dumpSuggestions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,11 @@ class Dictionary {
|
||||||
Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr
|
Dictionary(JNIEnv *env, DictionaryStructureWithBufferPolicy::StructurePolicyPtr
|
||||||
dictionaryStructureWithBufferPolicy);
|
dictionaryStructureWithBufferPolicy);
|
||||||
|
|
||||||
int getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
void getSuggestions(ProximityInfo *proximityInfo, DicTraverseSession *traverseSession,
|
||||||
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
|
||||||
int inputSize, int *prevWordCodePoints, int prevWordLength,
|
int inputSize, int *prevWordCodePoints, int prevWordLength,
|
||||||
const SuggestOptions *const suggestOptions, int *outWords, int *outputScores,
|
const SuggestOptions *const suggestOptions,
|
||||||
int *spaceIndices, int *outputTypes, int *outputAutoCommitFirstWordConfidence) const;
|
SuggestionResults *const outSuggestionResults) const;
|
||||||
|
|
||||||
void getPredictions(const int *word, int length,
|
void getPredictions(const int *word, int length,
|
||||||
SuggestionResults *const outSuggestionResults) const;
|
SuggestionResults *const outSuggestionResults) const;
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace latinime {
|
||||||
|
|
||||||
class DicNode;
|
class DicNode;
|
||||||
class DicTraverseSession;
|
class DicTraverseSession;
|
||||||
|
class SuggestionResults;
|
||||||
|
|
||||||
// This class basically tweaks suggestions and distances apart from CompoundDistance
|
// This class basically tweaks suggestions and distances apart from CompoundDistance
|
||||||
class Scoring {
|
class Scoring {
|
||||||
|
@ -30,11 +31,8 @@ class Scoring {
|
||||||
virtual int calculateFinalScore(const float compoundDistance, const int inputSize,
|
virtual int calculateFinalScore(const float compoundDistance, const int inputSize,
|
||||||
const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit,
|
const ErrorTypeUtils::ErrorType containedErrorTypes, const bool forceCommit,
|
||||||
const bool boostExactMatches) const = 0;
|
const bool boostExactMatches) const = 0;
|
||||||
virtual bool getMostProbableString(const DicTraverseSession *const traverseSession,
|
virtual void getMostProbableString(const DicTraverseSession *const traverseSession,
|
||||||
const int terminalSize, const float languageWeight, int *const outputCodePoints,
|
const float languageWeight, SuggestionResults *const outSuggestionResults) const = 0;
|
||||||
int *const type, int *const freq) const = 0;
|
|
||||||
virtual void safetyNetForMostProbableString(const int scoreCount,
|
|
||||||
const int maxScore, int *const outputCodePoints, int *const scores) const = 0;
|
|
||||||
virtual float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
|
virtual float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
|
||||||
DicNode *const terminals, const int size) const = 0;
|
DicNode *const terminals, const int size) const = 0;
|
||||||
virtual float getDoubleLetterDemotionDistanceCost(
|
virtual float getDoubleLetterDemotionDistanceCost(
|
||||||
|
|
|
@ -54,13 +54,23 @@ void SuggestionResults::outputSuggestions(JNIEnv *env, jintArray outSuggestionCo
|
||||||
|
|
||||||
void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount,
|
void SuggestionResults::addPrediction(const int *const codePoints, const int codePointCount,
|
||||||
const int probability) {
|
const int probability) {
|
||||||
if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH
|
if (probability == NOT_A_PROBABILITY) {
|
||||||
|| probability == NOT_A_PROBABILITY) {
|
|
||||||
// Invalid word.
|
// Invalid word.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Use probability as a score of the word.
|
addSuggestion(codePoints, codePointCount, probability, Dictionary::KIND_PREDICTION,
|
||||||
const int score = probability;
|
NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuggestionResults::addSuggestion(const int *const codePoints, const int codePointCount,
|
||||||
|
const int score, const int type, const int indexToPartialCommit,
|
||||||
|
const int autocimmitFirstWordConfindence) {
|
||||||
|
if (codePointCount <= 0 || codePointCount > MAX_WORD_LENGTH) {
|
||||||
|
// Invalid word.
|
||||||
|
AKLOGE("Invalid word is added to the suggestion results. codePointCount: %d",
|
||||||
|
codePointCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (getSuggestionCount() >= mMaxSuggestionCount) {
|
if (getSuggestionCount() >= mMaxSuggestionCount) {
|
||||||
const SuggestedWord &mWorstSuggestion = mSuggestedWords.top();
|
const SuggestedWord &mWorstSuggestion = mSuggestedWords.top();
|
||||||
if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore()
|
if (score > mWorstSuggestion.getScore() || (score == mWorstSuggestion.getScore()
|
||||||
|
@ -70,8 +80,31 @@ void SuggestionResults::addPrediction(const int *const codePoints, const int cod
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score,
|
mSuggestedWords.push(SuggestedWord(codePoints, codePointCount, score, type,
|
||||||
Dictionary::KIND_PREDICTION, NOT_AN_INDEX, NOT_A_FIRST_WORD_CONFIDENCE));
|
indexToPartialCommit, autocimmitFirstWordConfindence));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuggestionResults::getSortedScores(int *const outScores) const {
|
||||||
|
auto copyOfSuggestedWords = mSuggestedWords;
|
||||||
|
while (!copyOfSuggestedWords.empty()) {
|
||||||
|
const SuggestedWord &suggestedWord = copyOfSuggestedWords.top();
|
||||||
|
outScores[copyOfSuggestedWords.size() - 1] = suggestedWord.getScore();
|
||||||
|
copyOfSuggestedWords.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuggestionResults::dumpSuggestions() const {
|
||||||
|
std::vector<SuggestedWord> suggestedWords;
|
||||||
|
auto copyOfSuggestedWords = mSuggestedWords;
|
||||||
|
while (!copyOfSuggestedWords.empty()) {
|
||||||
|
suggestedWords.push_back(copyOfSuggestedWords.top());
|
||||||
|
copyOfSuggestedWords.pop();
|
||||||
|
}
|
||||||
|
int index = 0;
|
||||||
|
for (auto it = suggestedWords.rbegin(); it != suggestedWords.rend(); ++it) {
|
||||||
|
DUMP_SUGGESTION(it->getCodePoint(), it->getCodePointCount(), index, it->getScore());
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -35,8 +35,12 @@ class SuggestionResults {
|
||||||
void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray,
|
void outputSuggestions(JNIEnv *env, jintArray outSuggestionCount, jintArray outCodePointsArray,
|
||||||
jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray,
|
jintArray outScoresArray, jintArray outSpaceIndicesArray, jintArray outTypesArray,
|
||||||
jintArray outAutoCommitFirstWordConfidenceArray);
|
jintArray outAutoCommitFirstWordConfidenceArray);
|
||||||
|
|
||||||
void addPrediction(const int *const codePoints, const int codePointCount, const int score);
|
void addPrediction(const int *const codePoints, const int codePointCount, const int score);
|
||||||
|
void addSuggestion(const int *const codePoints, const int codePointCount,
|
||||||
|
const int score, const int type, const int indexToPartialCommit,
|
||||||
|
const int autocimmitFirstWordConfindence);
|
||||||
|
void getSortedScores(int *const outScores) const;
|
||||||
|
void dumpSuggestions() const;
|
||||||
|
|
||||||
int getSuggestionCount() const {
|
int getSuggestionCount() const {
|
||||||
return mSuggestedWords.size();
|
return mSuggestedWords.size();
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "suggest/core/dictionary/dictionary.h"
|
#include "suggest/core/dictionary/dictionary.h"
|
||||||
#include "suggest/core/dictionary/error_type_utils.h"
|
#include "suggest/core/dictionary/error_type_utils.h"
|
||||||
#include "suggest/core/policy/scoring.h"
|
#include "suggest/core/policy/scoring.h"
|
||||||
|
#include "suggest/core/result/suggestion_results.h"
|
||||||
#include "suggest/core/session/dic_traverse_session.h"
|
#include "suggest/core/session/dic_traverse_session.h"
|
||||||
|
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
@ -31,10 +32,9 @@ namespace latinime {
|
||||||
const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
|
|
||||||
// TODO: Split this method.
|
// TODO: Split this method.
|
||||||
/* static */ int SuggestionsOutputUtils::outputSuggestions(
|
/* static */ void SuggestionsOutputUtils::outputSuggestions(
|
||||||
const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
|
const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
|
||||||
int *outputScores, int *outputCodePoints, int *outputIndicesToPartialCommit,
|
SuggestionResults *const outSuggestionResults) {
|
||||||
int *outputTypes, int *outputAutoCommitFirstWordConfidence) {
|
|
||||||
#if DEBUG_EVALUATE_MOST_PROBABLE_STRING
|
#if DEBUG_EVALUATE_MOST_PROBABLE_STRING
|
||||||
const int terminalSize = 0;
|
const int terminalSize = 0;
|
||||||
#else
|
#else
|
||||||
|
@ -49,18 +49,6 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
|
|
||||||
const float languageWeight = scoringPolicy->getAdjustedLanguageWeight(
|
const float languageWeight = scoringPolicy->getAdjustedLanguageWeight(
|
||||||
traverseSession, terminals, terminalSize);
|
traverseSession, terminals, terminalSize);
|
||||||
|
|
||||||
int outputWordIndex = 0;
|
|
||||||
// Insert most probable word at index == 0 as long as there is one terminal at least
|
|
||||||
const bool hasMostProbableString =
|
|
||||||
scoringPolicy->getMostProbableString(traverseSession, terminalSize, languageWeight,
|
|
||||||
&outputCodePoints[0], &outputTypes[0], &outputScores[0]);
|
|
||||||
if (hasMostProbableString) {
|
|
||||||
outputIndicesToPartialCommit[outputWordIndex] = NOT_AN_INDEX;
|
|
||||||
++outputWordIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int maxScore = S_INT_MIN;
|
|
||||||
// Force autocorrection for obvious long multi-word suggestions when the top suggestion is
|
// Force autocorrection for obvious long multi-word suggestions when the top suggestion is
|
||||||
// a long multiple words suggestion.
|
// a long multiple words suggestion.
|
||||||
// TODO: Implement a smarter auto-commit method for handling multi-word suggestions.
|
// TODO: Implement a smarter auto-commit method for handling multi-word suggestions.
|
||||||
|
@ -75,16 +63,12 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
// TODO: have partial commit work even with multiple pointers.
|
// TODO: have partial commit work even with multiple pointers.
|
||||||
const bool outputSecondWordFirstLetterInputIndex =
|
const bool outputSecondWordFirstLetterInputIndex =
|
||||||
traverseSession->isOnlyOnePointerUsed(0 /* pointerId */);
|
traverseSession->isOnlyOnePointerUsed(0 /* pointerId */);
|
||||||
if (terminalSize > 0) {
|
|
||||||
// If we have no suggestions, don't write this
|
|
||||||
outputAutoCommitFirstWordConfidence[0] =
|
|
||||||
computeFirstWordConfidence(&terminals[0]);
|
|
||||||
}
|
|
||||||
const bool boostExactMatches = traverseSession->getDictionaryStructurePolicy()->
|
const bool boostExactMatches = traverseSession->getDictionaryStructurePolicy()->
|
||||||
getHeaderStructurePolicy()->shouldBoostExactMatches();
|
getHeaderStructurePolicy()->shouldBoostExactMatches();
|
||||||
|
|
||||||
|
int codePoints[MAX_WORD_LENGTH];
|
||||||
// Output suggestion results here
|
// Output suggestion results here
|
||||||
for (int terminalIndex = 0; terminalIndex < terminalSize && outputWordIndex < MAX_RESULTS;
|
for (int terminalIndex = 0; terminalIndex < terminalSize; ++terminalIndex) {
|
||||||
++terminalIndex) {
|
|
||||||
DicNode *terminalDicNode = &terminals[terminalIndex];
|
DicNode *terminalDicNode = &terminals[terminalIndex];
|
||||||
if (DEBUG_GEO_FULL) {
|
if (DEBUG_GEO_FULL) {
|
||||||
terminalDicNode->dump("OUT:");
|
terminalDicNode->dump("OUT:");
|
||||||
|
@ -118,25 +102,18 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
(forceCommitMultiWords && terminalDicNode->hasMultipleWords())
|
(forceCommitMultiWords && terminalDicNode->hasMultipleWords())
|
||||||
|| (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
|
|| (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
|
||||||
boostExactMatches);
|
boostExactMatches);
|
||||||
if (maxScore < finalScore && isValidWord) {
|
|
||||||
maxScore = finalScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't output invalid words. However, we still need to submit their shortcuts if any.
|
// Don't output invalid words. However, we still need to submit their shortcuts if any.
|
||||||
if (isValidWord) {
|
if (isValidWord) {
|
||||||
outputTypes[outputWordIndex] = Dictionary::KIND_CORRECTION | outputTypeFlags;
|
terminalDicNode->outputResult(codePoints);
|
||||||
outputScores[outputWordIndex] = finalScore;
|
const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?
|
||||||
if (outputSecondWordFirstLetterInputIndex) {
|
|
||||||
outputIndicesToPartialCommit[outputWordIndex] =
|
|
||||||
terminalDicNode->getSecondWordFirstInputIndex(
|
terminalDicNode->getSecondWordFirstInputIndex(
|
||||||
traverseSession->getProximityInfoState(0));
|
traverseSession->getProximityInfoState(0)) :
|
||||||
} else {
|
NOT_AN_INDEX;
|
||||||
outputIndicesToPartialCommit[outputWordIndex] = NOT_AN_INDEX;
|
outSuggestionResults->addSuggestion(codePoints,
|
||||||
}
|
terminalDicNode->getTotalNodeCodePointCount(),
|
||||||
// Populate the outputChars array with the suggested word.
|
finalScore, Dictionary::KIND_CORRECTION | outputTypeFlags,
|
||||||
const int startIndex = outputWordIndex * MAX_WORD_LENGTH;
|
indexToPartialCommit, computeFirstWordConfidence(terminalDicNode));
|
||||||
terminalDicNode->outputResult(&outputCodePoints[startIndex]);
|
|
||||||
++outputWordIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!terminalDicNode->hasMultipleWords()) {
|
if (!terminalDicNode->hasMultipleWords()) {
|
||||||
|
@ -152,28 +129,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
traverseSession->getInputSize(),
|
traverseSession->getInputSize(),
|
||||||
terminalDicNode->getContainedErrorTypes(),
|
terminalDicNode->getContainedErrorTypes(),
|
||||||
true /* forceCommit */, boostExactMatches) : finalScore;
|
true /* forceCommit */, boostExactMatches) : finalScore;
|
||||||
const int updatedOutputWordIndex = outputShortcuts(&shortcutIt,
|
outputShortcuts(&shortcutIt, shortcutBaseScore, sameAsTyped, outSuggestionResults);
|
||||||
outputWordIndex, shortcutBaseScore, outputCodePoints, outputScores, outputTypes,
|
|
||||||
sameAsTyped);
|
|
||||||
const int secondWordFirstInputIndex = terminalDicNode->getSecondWordFirstInputIndex(
|
|
||||||
traverseSession->getProximityInfoState(0));
|
|
||||||
for (int i = outputWordIndex; i < updatedOutputWordIndex; ++i) {
|
|
||||||
if (outputSecondWordFirstLetterInputIndex) {
|
|
||||||
outputIndicesToPartialCommit[i] = secondWordFirstInputIndex;
|
|
||||||
} else {
|
|
||||||
outputIndicesToPartialCommit[i] = NOT_AN_INDEX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outputWordIndex = updatedOutputWordIndex;
|
|
||||||
}
|
}
|
||||||
DicNode::managedDelete(terminalDicNode);
|
DicNode::managedDelete(terminalDicNode);
|
||||||
}
|
}
|
||||||
|
scoringPolicy->getMostProbableString(traverseSession, languageWeight, outSuggestionResults);
|
||||||
if (hasMostProbableString) {
|
|
||||||
scoringPolicy->safetyNetForMostProbableString(outputWordIndex, maxScore,
|
|
||||||
&outputCodePoints[0], outputScores);
|
|
||||||
}
|
|
||||||
return outputWordIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ int SuggestionsOutputUtils::computeFirstWordConfidence(
|
/* static */ int SuggestionsOutputUtils::computeFirstWordConfidence(
|
||||||
|
@ -228,12 +188,11 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
return distanceContribution + lengthContribution + spaceContribution;
|
return distanceContribution + lengthContribution + spaceContribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ int SuggestionsOutputUtils::outputShortcuts(
|
/* static */ void SuggestionsOutputUtils::outputShortcuts(
|
||||||
BinaryDictionaryShortcutIterator *const shortcutIt,
|
BinaryDictionaryShortcutIterator *const shortcutIt, const int finalScore,
|
||||||
int outputWordIndex, const int finalScore, int *const outputCodePoints,
|
const bool sameAsTyped, SuggestionResults *const outSuggestionResults) {
|
||||||
int *const outputScores, int *const outputTypes, const bool sameAsTyped) {
|
|
||||||
int shortcutTarget[MAX_WORD_LENGTH];
|
int shortcutTarget[MAX_WORD_LENGTH];
|
||||||
while (shortcutIt->hasNextShortcutTarget() && outputWordIndex < MAX_RESULTS) {
|
while (shortcutIt->hasNextShortcutTarget()) {
|
||||||
bool isWhilelist;
|
bool isWhilelist;
|
||||||
int shortcutTargetStringLength;
|
int shortcutTargetStringLength;
|
||||||
shortcutIt->nextShortcutTarget(MAX_WORD_LENGTH, shortcutTarget,
|
shortcutIt->nextShortcutTarget(MAX_WORD_LENGTH, shortcutTarget,
|
||||||
|
@ -250,15 +209,9 @@ const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
|
||||||
shortcutScore = std::max(S_INT_MIN + 1, shortcutScore) - 1;
|
shortcutScore = std::max(S_INT_MIN + 1, shortcutScore) - 1;
|
||||||
kind = Dictionary::KIND_SHORTCUT;
|
kind = Dictionary::KIND_SHORTCUT;
|
||||||
}
|
}
|
||||||
outputTypes[outputWordIndex] = kind;
|
outSuggestionResults->addSuggestion(shortcutTarget, shortcutTargetStringLength,
|
||||||
outputScores[outputWordIndex] = shortcutScore;
|
std::max(S_INT_MIN + 1, shortcutScore) - 1, kind, NOT_AN_INDEX,
|
||||||
outputScores[outputWordIndex] = std::max(S_INT_MIN + 1, shortcutScore) - 1;
|
NOT_A_FIRST_WORD_CONFIDENCE);
|
||||||
const int startIndex2 = outputWordIndex * MAX_WORD_LENGTH;
|
|
||||||
// Copy shortcut target code points to the output buffer.
|
|
||||||
memmove(&outputCodePoints[startIndex2], shortcutTarget,
|
|
||||||
shortcutTargetStringLength * sizeof(shortcutTarget[0]));
|
|
||||||
++outputWordIndex;
|
|
||||||
}
|
}
|
||||||
return outputWordIndex;
|
|
||||||
}
|
}
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
|
|
|
@ -25,16 +25,15 @@ class BinaryDictionaryShortcutIterator;
|
||||||
class DicNode;
|
class DicNode;
|
||||||
class DicTraverseSession;
|
class DicTraverseSession;
|
||||||
class Scoring;
|
class Scoring;
|
||||||
|
class SuggestionResults;
|
||||||
|
|
||||||
class SuggestionsOutputUtils {
|
class SuggestionsOutputUtils {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Outputs the final list of suggestions (i.e., terminal nodes).
|
* Outputs the final list of suggestions (i.e., terminal nodes).
|
||||||
*/
|
*/
|
||||||
static int outputSuggestions(const Scoring *const scoringPolicy,
|
static void outputSuggestions(const Scoring *const scoringPolicy,
|
||||||
DicTraverseSession *traverseSession, int *outputScores, int *outputCodePoints,
|
DicTraverseSession *traverseSession, SuggestionResults *const outSuggestionResults);
|
||||||
int *outputIndicesToPartialCommit, int *outputTypes,
|
|
||||||
int *outputAutoCommitFirstWordConfidence);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionsOutputUtils);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(SuggestionsOutputUtils);
|
||||||
|
@ -44,9 +43,9 @@ class SuggestionsOutputUtils {
|
||||||
|
|
||||||
static int computeFirstWordConfidence(const DicNode *const terminalDicNode);
|
static int computeFirstWordConfidence(const DicNode *const terminalDicNode);
|
||||||
|
|
||||||
static int outputShortcuts(BinaryDictionaryShortcutIterator *const shortcutIt,
|
static void outputShortcuts(BinaryDictionaryShortcutIterator *const shortcutIt,
|
||||||
int outputWordIndex, const int finalScore, int *const outputCodePoints,
|
const int finalScore, const bool sameAsTyped,
|
||||||
int *const outputScores, int *const outputTypes, const bool sameAsTyped);
|
SuggestionResults *const outSuggestionResults);
|
||||||
};
|
};
|
||||||
} // namespace latinime
|
} // namespace latinime
|
||||||
#endif // LATINIME_SUGGESTIONS_OUTPUT_UTILS
|
#endif // LATINIME_SUGGESTIONS_OUTPUT_UTILS
|
||||||
|
|
|
@ -42,10 +42,9 @@ const int Suggest::MIN_CONTINUOUS_SUGGESTION_INPUT_SIZE = 2;
|
||||||
* automatically activated for sequential calls that share the same starting input.
|
* automatically activated for sequential calls that share the same starting input.
|
||||||
* TODO: Stop detecting continuous suggestion. Start using traverseSession instead.
|
* TODO: Stop detecting continuous suggestion. Start using traverseSession instead.
|
||||||
*/
|
*/
|
||||||
int Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
|
void Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
|
||||||
int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints,
|
int *inputXs, int *inputYs, int *times, int *pointerIds, int *inputCodePoints,
|
||||||
int inputSize, int *outWords, int *outputScores, int *outputIndices,
|
int inputSize, SuggestionResults *const outSuggestionResults) const {
|
||||||
int *outputTypes, int *outputAutoCommitFirstWordConfidence) const {
|
|
||||||
PROF_OPEN;
|
PROF_OPEN;
|
||||||
PROF_START(0);
|
PROF_START(0);
|
||||||
const float maxSpatialDistance = TRAVERSAL->getMaxSpatialDistance();
|
const float maxSpatialDistance = TRAVERSAL->getMaxSpatialDistance();
|
||||||
|
@ -66,11 +65,9 @@ int Suggest::getSuggestions(ProximityInfo *pInfo, void *traverseSession,
|
||||||
}
|
}
|
||||||
PROF_END(1);
|
PROF_END(1);
|
||||||
PROF_START(2);
|
PROF_START(2);
|
||||||
const int size = SuggestionsOutputUtils::outputSuggestions(SCORING, tSession, outputScores,
|
SuggestionsOutputUtils::outputSuggestions(SCORING, tSession, outSuggestionResults);
|
||||||
outWords, outputIndices, outputTypes, outputAutoCommitFirstWordConfidence);
|
|
||||||
PROF_END(2);
|
PROF_END(2);
|
||||||
PROF_CLOSE;
|
PROF_CLOSE;
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,6 +36,7 @@ class DicNode;
|
||||||
class DicTraverseSession;
|
class DicTraverseSession;
|
||||||
class ProximityInfo;
|
class ProximityInfo;
|
||||||
class Scoring;
|
class Scoring;
|
||||||
|
class SuggestionResults;
|
||||||
class Traversal;
|
class Traversal;
|
||||||
class Weighting;
|
class Weighting;
|
||||||
|
|
||||||
|
@ -46,10 +47,9 @@ class Suggest : public SuggestInterface {
|
||||||
SCORING(suggestPolicy ? suggestPolicy->getScoring() : nullptr),
|
SCORING(suggestPolicy ? suggestPolicy->getScoring() : nullptr),
|
||||||
WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {}
|
WEIGHTING(suggestPolicy ? suggestPolicy->getWeighting() : nullptr) {}
|
||||||
AK_FORCE_INLINE virtual ~Suggest() {}
|
AK_FORCE_INLINE virtual ~Suggest() {}
|
||||||
int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
|
void getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs, int *inputYs,
|
||||||
int *times, int *pointerIds, int *inputCodePoints, int inputSize, int *outWords,
|
int *times, int *pointerIds, int *inputCodePoints, int inputSize,
|
||||||
int *outputScores, int *outputIndices, int *outputTypes,
|
SuggestionResults *const outSuggestionResults) const;
|
||||||
int *outputAutoCommitFirstWordConfidence) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(Suggest);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(Suggest);
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
namespace latinime {
|
namespace latinime {
|
||||||
|
|
||||||
class ProximityInfo;
|
class ProximityInfo;
|
||||||
|
class SuggestionResults;
|
||||||
|
|
||||||
class SuggestInterface {
|
class SuggestInterface {
|
||||||
public:
|
public:
|
||||||
virtual int getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs,
|
virtual void getSuggestions(ProximityInfo *pInfo, void *traverseSession, int *inputXs,
|
||||||
int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
|
int *inputYs, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
|
||||||
int *outWords, int *outputScores, int *outputIndices, int *outputTypes,
|
SuggestionResults *const suggestionResults) const = 0;
|
||||||
int *outputAutoCommitFirstWordConfidence) const = 0;
|
|
||||||
SuggestInterface() {}
|
SuggestInterface() {}
|
||||||
virtual ~SuggestInterface() {}
|
virtual ~SuggestInterface() {}
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -32,15 +32,8 @@ class TypingScoring : public Scoring {
|
||||||
public:
|
public:
|
||||||
static const TypingScoring *getInstance() { return &sInstance; }
|
static const TypingScoring *getInstance() { return &sInstance; }
|
||||||
|
|
||||||
AK_FORCE_INLINE bool getMostProbableString(const DicTraverseSession *const traverseSession,
|
AK_FORCE_INLINE void getMostProbableString(const DicTraverseSession *const traverseSession,
|
||||||
const int terminalSize, const float languageWeight, int *const outputCodePoints,
|
const float languageWeight, SuggestionResults *const outSuggestionResults) const {}
|
||||||
int *const type, int *const freq) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE void safetyNetForMostProbableString(const int scoreCount, const int maxScore,
|
|
||||||
int *const outputCodePoints, int *const scores) const {
|
|
||||||
}
|
|
||||||
|
|
||||||
AK_FORCE_INLINE float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
|
AK_FORCE_INLINE float getAdjustedLanguageWeight(DicTraverseSession *const traverseSession,
|
||||||
DicNode *const terminals, const int size) const {
|
DicNode *const terminals, const int size) const {
|
||||||
|
|
Loading…
Reference in a new issue