| OLD | NEW |
| (Empty) | |
| 1 /* |
| 2 * Copyright (C) 2013 The Android Open Source Project |
| 3 * |
| 4 * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 * you may not use this file except in compliance with the License. |
| 6 * You may obtain a copy of the License at |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. |
| 15 */ |
| 16 |
| 17 #ifndef LATINIME_TYPING_TRAVERSAL_H |
| 18 #define LATINIME_TYPING_TRAVERSAL_H |
| 19 |
| 20 #include <cstdint> |
| 21 |
| 22 #include "third_party/prediction/defines.h" |
| 23 #include "third_party/prediction/suggest/core/dicnode/dic_node.h" |
| 24 #include "third_party/prediction/suggest/core/dicnode/dic_node_vector.h" |
| 25 #include "third_party/prediction/suggest/core/layout/proximity_info_state.h" |
| 26 #include "third_party/prediction/suggest/core/layout/proximity_info_utils.h" |
| 27 #include "third_party/prediction/suggest/core/policy/traversal.h" |
| 28 #include "third_party/prediction/suggest/core/session/dic_traverse_session.h" |
| 29 #include "third_party/prediction/suggest/policyimpl/typing/scoring_params.h" |
| 30 #include "third_party/prediction/utils/char_utils.h" |
| 31 |
| 32 namespace latinime { |
| 33 class TypingTraversal : public Traversal { |
| 34 public: |
| 35 static const TypingTraversal* getInstance() { return &sInstance; } |
| 36 |
| 37 AK_FORCE_INLINE int getMaxPointerCount() const { return MAX_POINTER_COUNT; } |
| 38 |
| 39 AK_FORCE_INLINE bool allowsErrorCorrections( |
| 40 const DicNode* const dicNode) const { |
| 41 return dicNode->getNormalizedSpatialDistance() < |
| 42 ScoringParams::NORMALIZED_SPATIAL_DISTANCE_THRESHOLD_FOR_EDIT; |
| 43 } |
| 44 |
| 45 AK_FORCE_INLINE bool isOmission( |
| 46 const DicTraverseSession* const traverseSession, |
| 47 const DicNode* const dicNode, |
| 48 const DicNode* const childDicNode, |
| 49 const bool allowsErrorCorrections) const { |
| 50 if (!CORRECT_OMISSION) { |
| 51 return false; |
| 52 } |
| 53 // Note: Always consider intentional omissions (like apostrophes) since they |
| 54 // are common. |
| 55 const bool canConsiderOmission = |
| 56 allowsErrorCorrections || childDicNode->canBeIntentionalOmission(); |
| 57 if (!canConsiderOmission) { |
| 58 return false; |
| 59 } |
| 60 const int inputSize = traverseSession->getInputSize(); |
| 61 // TODO: Don't refer to isCompletion? |
| 62 if (dicNode->isCompletion(inputSize)) { |
| 63 return false; |
| 64 } |
| 65 if (dicNode->canBeIntentionalOmission()) { |
| 66 return true; |
| 67 } |
| 68 const int point0Index = dicNode->getInputIndex(0); |
| 69 const int currentBaseLowerCodePoint = |
| 70 CharUtils::toBaseLowerCase(childDicNode->getNodeCodePoint()); |
| 71 const int typedBaseLowerCodePoint = |
| 72 CharUtils::toBaseLowerCase(traverseSession->getProximityInfoState(0) |
| 73 ->getPrimaryCodePointAt(point0Index)); |
| 74 return (currentBaseLowerCodePoint != typedBaseLowerCodePoint); |
| 75 } |
| 76 |
| 77 AK_FORCE_INLINE bool isSpaceSubstitutionTerminal( |
| 78 const DicTraverseSession* const traverseSession, |
| 79 const DicNode* const dicNode) const { |
| 80 if (!CORRECT_NEW_WORD_SPACE_SUBSTITUTION) { |
| 81 return false; |
| 82 } |
| 83 if (!canDoLookAheadCorrection(traverseSession, dicNode)) { |
| 84 return false; |
| 85 } |
| 86 const int point0Index = dicNode->getInputIndex(0); |
| 87 return dicNode->isTerminalDicNode() && |
| 88 traverseSession->getProximityInfoState(0) |
| 89 ->hasSpaceProximity(point0Index); |
| 90 } |
| 91 |
| 92 AK_FORCE_INLINE bool isSpaceOmissionTerminal( |
| 93 const DicTraverseSession* const traverseSession, |
| 94 const DicNode* const dicNode) const { |
| 95 if (!CORRECT_NEW_WORD_SPACE_OMISSION) { |
| 96 return false; |
| 97 } |
| 98 const int inputSize = traverseSession->getInputSize(); |
| 99 // TODO: Don't refer to isCompletion? |
| 100 if (dicNode->isCompletion(inputSize)) { |
| 101 return false; |
| 102 } |
| 103 if (!dicNode->isTerminalDicNode()) { |
| 104 return false; |
| 105 } |
| 106 const int16_t pointIndex = dicNode->getInputIndex(0); |
| 107 return pointIndex <= inputSize && |
| 108 !dicNode->isTotalInputSizeExceedingLimit() && |
| 109 !dicNode->shouldBeFilteredBySafetyNetForBigram(); |
| 110 } |
| 111 |
| 112 AK_FORCE_INLINE bool shouldDepthLevelCache( |
| 113 const DicTraverseSession* const traverseSession) const { |
| 114 const int inputSize = traverseSession->getInputSize(); |
| 115 return traverseSession->isCacheBorderForTyping(inputSize); |
| 116 } |
| 117 |
| 118 AK_FORCE_INLINE bool shouldNodeLevelCache( |
| 119 const DicTraverseSession* const traverseSession, |
| 120 const DicNode* const dicNode) const { |
| 121 return false; |
| 122 } |
| 123 |
| 124 AK_FORCE_INLINE bool canDoLookAheadCorrection( |
| 125 const DicTraverseSession* const traverseSession, |
| 126 const DicNode* const dicNode) const { |
| 127 const int inputSize = traverseSession->getInputSize(); |
| 128 return dicNode->canDoLookAheadCorrection(inputSize); |
| 129 } |
| 130 |
| 131 AK_FORCE_INLINE ProximityType |
| 132 getProximityType(const DicTraverseSession* const traverseSession, |
| 133 const DicNode* const dicNode, |
| 134 const DicNode* const childDicNode) const { |
| 135 return traverseSession->getProximityInfoState(0)->getProximityType( |
| 136 dicNode->getInputIndex(0), childDicNode->getNodeCodePoint(), |
| 137 true /* checkProximityChars */); |
| 138 } |
| 139 |
| 140 AK_FORCE_INLINE bool needsToTraverseAllUserInput() const { return true; } |
| 141 |
| 142 AK_FORCE_INLINE float getMaxSpatialDistance() const { |
| 143 return ScoringParams::MAX_SPATIAL_DISTANCE; |
| 144 } |
| 145 |
| 146 AK_FORCE_INLINE int getDefaultExpandDicNodeSize() const { |
| 147 return DicNodeVector::DEFAULT_NODES_SIZE_FOR_OPTIMIZATION; |
| 148 } |
| 149 |
| 150 AK_FORCE_INLINE int getMaxCacheSize(const int inputSize) const { |
| 151 return (inputSize <= 1) |
| 152 ? ScoringParams::MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT |
| 153 : ScoringParams::MAX_CACHE_DIC_NODE_SIZE; |
| 154 } |
| 155 |
| 156 AK_FORCE_INLINE int getTerminalCacheSize() const { return MAX_RESULTS; } |
| 157 |
| 158 AK_FORCE_INLINE bool isPossibleOmissionChildNode( |
| 159 const DicTraverseSession* const traverseSession, |
| 160 const DicNode* const parentDicNode, |
| 161 const DicNode* const dicNode) const { |
| 162 const ProximityType proximityType = |
| 163 getProximityType(traverseSession, parentDicNode, dicNode); |
| 164 if (!ProximityInfoUtils::isMatchOrProximityChar(proximityType)) { |
| 165 return false; |
| 166 } |
| 167 return true; |
| 168 } |
| 169 |
| 170 AK_FORCE_INLINE bool isGoodToTraverseNextWord( |
| 171 const DicNode* const dicNode) const { |
| 172 const int probability = dicNode->getProbability(); |
| 173 if (probability < ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY) { |
| 174 return false; |
| 175 } |
| 176 const bool shortCappedWord = |
| 177 dicNode->getNodeCodePointCount() < |
| 178 ScoringParams::THRESHOLD_SHORT_WORD_LENGTH && |
| 179 dicNode->isFirstCharUppercase(); |
| 180 return !shortCappedWord || |
| 181 probability >= |
| 182 ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED; |
| 183 } |
| 184 |
| 185 private: |
| 186 DISALLOW_COPY_AND_ASSIGN(TypingTraversal); |
| 187 static const bool CORRECT_OMISSION; |
| 188 static const bool CORRECT_NEW_WORD_SPACE_SUBSTITUTION; |
| 189 static const bool CORRECT_NEW_WORD_SPACE_OMISSION; |
| 190 static const TypingTraversal sInstance; |
| 191 |
| 192 TypingTraversal() {} |
| 193 ~TypingTraversal() {} |
| 194 }; |
| 195 } // namespace latinime |
| 196 #endif // LATINIME_TYPING_TRAVERSAL_H |
| OLD | NEW |