1a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka/* 2a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Copyright (C) 2013 The Android Open Source Project 3a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 4a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Licensed under the Apache License, Version 2.0 (the "License"); 5a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * you may not use this file except in compliance with the License. 6a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * You may obtain a copy of the License at 7a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 8a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * http://www.apache.org/licenses/LICENSE-2.0 9a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * 10a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * Unless required by applicable law or agreed to in writing, software 11a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * distributed under the License is distributed on an "AS IS" BASIS, 12a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * See the License for the specific language governing permissions and 14a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka * limitations under the License. 15a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka */ 16a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 17a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#ifndef LATINIME_TYPING_TRAVERSAL_H 18a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#define LATINIME_TYPING_TRAVERSAL_H 19a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 20cafab169cdb21244c82b99c09983c98066113d87Ken Wakasa#include <cstdint> 21a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 22a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#include "defines.h" 23b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/dicnode/dic_node.h" 24b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/dicnode/dic_node_vector.h" 2529432f843a8cd6ffb2be286104964592e80d77c9Ken Wakasa#include "suggest/core/layout/proximity_info_state.h" 267a06a792871c38517264fcb63b80a9c09bfe4766Keisuke Kuroynagi#include "suggest/core/layout/proximity_info_utils.h" 27b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/policy/traversal.h" 28b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/core/session/dic_traverse_session.h" 297d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard#include "suggest/core/suggest_options.h" 30b68e73448104714e8f12f89a1e00fb10b5fd14c4Ken Wakasa#include "suggest/policyimpl/typing/scoring_params.h" 31addea83bad5751308fef508d79c6989b8872f050Ken Wakasa#include "utils/char_utils.h" 32a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 33a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokanamespace latinime { 34a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataokaclass TypingTraversal : public Traversal { 35a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka public: 36a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka static const TypingTraversal *getInstance() { return &sInstance; } 37a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 38a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE int getMaxPointerCount() const { 39a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return MAX_POINTER_COUNT; 40a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 41a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 42a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool allowsErrorCorrections(const DicNode *const dicNode) const { 43a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return dicNode->getNormalizedSpatialDistance() 448da0c932925f605b9dd815387753dfab19beb873Tom Ouyang < ScoringParams::NORMALIZED_SPATIAL_DISTANCE_THRESHOLD_FOR_EDIT; 45a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 46a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 47a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool isOmission(const DicTraverseSession *const traverseSession, 48fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang const DicNode *const dicNode, const DicNode *const childDicNode, 49fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang const bool allowsErrorCorrections) const { 50a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (!CORRECT_OMISSION) { 51a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 52a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 53fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang // Note: Always consider intentional omissions (like apostrophes) since they are common. 54fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang const bool canConsiderOmission = 55fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang allowsErrorCorrections || childDicNode->canBeIntentionalOmission(); 56fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang if (!canConsiderOmission) { 57fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang return false; 58fd02ec10f0a0374096e88fa30a0e126d6ff11c72Tom Ouyang } 59a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int inputSize = traverseSession->getInputSize(); 60a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka // TODO: Don't refer to isCompletion? 61a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->isCompletion(inputSize)) { 62a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 63a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 64a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->canBeIntentionalOmission()) { 65a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return true; 66a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 67a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int point0Index = dicNode->getInputIndex(0); 68a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int currentBaseLowerCodePoint = 69464d3ba43257da34ab165da8ba0af11e928aae5cKen Wakasa CharUtils::toBaseLowerCase(childDicNode->getNodeCodePoint()); 70a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int typedBaseLowerCodePoint = 71464d3ba43257da34ab165da8ba0af11e928aae5cKen Wakasa CharUtils::toBaseLowerCase(traverseSession->getProximityInfoState(0) 72a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka ->getPrimaryCodePointAt(point0Index)); 73a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return (currentBaseLowerCodePoint != typedBaseLowerCodePoint); 74a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 75a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 76a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool isSpaceSubstitutionTerminal( 77a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const { 78252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka if (!CORRECT_NEW_WORD_SPACE_SUBSTITUTION) { 79a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 80a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 817d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard if (traverseSession->getSuggestOptions()->weightForLocale() 827d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard < ScoringParams::LOCALE_WEIGHT_THRESHOLD_FOR_SPACE_SUBSTITUTION) { 837d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // Space substitution is heavy, so we skip doing it if the weight for this language 847d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // is low because we anticipate the suggestions out of this dictionary are not for 857d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // the language the user intends to type in. 867d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard return false; 877d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard } 88a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (!canDoLookAheadCorrection(traverseSession, dicNode)) { 89a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 90a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 91a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int point0Index = dicNode->getInputIndex(0); 922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return dicNode->isTerminalDicNode() 93a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka && traverseSession->getProximityInfoState(0)-> 94a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka hasSpaceProximity(point0Index); 95a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 96a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 97a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool isSpaceOmissionTerminal( 98a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const { 99252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka if (!CORRECT_NEW_WORD_SPACE_OMISSION) { 100a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 101a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 1027d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard if (traverseSession->getSuggestOptions()->weightForLocale() 1037d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard < ScoringParams::LOCALE_WEIGHT_THRESHOLD_FOR_SPACE_OMISSION) { 1047d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // Space omission is heavy, so we skip doing it if the weight for this language 1057d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // is low because we anticipate the suggestions out of this dictionary are not for 1067d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard // the language the user intends to type in. 1077d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard return false; 1087d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard } 109a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int inputSize = traverseSession->getInputSize(); 110a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka // TODO: Don't refer to isCompletion? 111a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (dicNode->isCompletion(inputSize)) { 112a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 113a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 1142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (!dicNode->isTerminalDicNode()) { 115a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 116a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 117a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int16_t pointIndex = dicNode->getInputIndex(0); 118a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return pointIndex <= inputSize && !dicNode->isTotalInputSizeExceedingLimit() 1193e954347e3a7b381d7e94feb002e158f3bc69a32Jean Chalard && !dicNode->shouldBeFilteredBySafetyNetForBigram(); 120a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 121a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 122a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool shouldDepthLevelCache( 123a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession) const { 124a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int inputSize = traverseSession->getInputSize(); 125a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return traverseSession->isCacheBorderForTyping(inputSize); 126a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 127a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 128a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool shouldNodeLevelCache( 129a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const { 130a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 131a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 132a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 133a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool canDoLookAheadCorrection( 134a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const dicNode) const { 135a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const int inputSize = traverseSession->getInputSize(); 136a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return dicNode->canDoLookAheadCorrection(inputSize); 137a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 138a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 139a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE ProximityType getProximityType( 140a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const dicNode, 141a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicNode *const childDicNode) const { 142a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return traverseSession->getProximityInfoState(0)->getProximityType( 143a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka dicNode->getInputIndex(0), childDicNode->getNodeCodePoint(), 144a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka true /* checkProximityChars */); 145a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 146a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 147a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool needsToTraverseAllUserInput() const { 148a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return true; 149a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 150a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 151a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE float getMaxSpatialDistance() const { 152a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return ScoringParams::MAX_SPATIAL_DISTANCE; 153a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 154a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 155a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE int getDefaultExpandDicNodeSize() const { 156a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return DicNodeVector::DEFAULT_NODES_SIZE_FOR_OPTIMIZATION; 157a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 158a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 1597d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard AK_FORCE_INLINE int getMaxCacheSize(const int inputSize, const float weightForLocale) const { 1607d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard if (inputSize <= 1) { 1617d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard return ScoringParams::MAX_CACHE_DIC_NODE_SIZE_FOR_SINGLE_POINT; 1627d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard } 1637d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard if (weightForLocale < ScoringParams::LOCALE_WEIGHT_THRESHOLD_FOR_SMALL_CACHE_SIZE) { 1647d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard return ScoringParams::MAX_CACHE_DIC_NODE_SIZE_FOR_LOW_PROBABILITY_LOCALE; 1657d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard } 1667d5e1cb2650d74816767c085ad71d04d6e605559Jean Chalard return ScoringParams::MAX_CACHE_DIC_NODE_SIZE; 167a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 168a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 16963d33f42c8a310333544221345aed2bad64a2c0fKeisuke Kuroyanagi AK_FORCE_INLINE int getTerminalCacheSize() const { 17063d33f42c8a310333544221345aed2bad64a2c0fKeisuke Kuroyanagi return MAX_RESULTS; 17163d33f42c8a310333544221345aed2bad64a2c0fKeisuke Kuroyanagi } 17263d33f42c8a310333544221345aed2bad64a2c0fKeisuke Kuroyanagi 173a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka AK_FORCE_INLINE bool isPossibleOmissionChildNode( 174a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicTraverseSession *const traverseSession, const DicNode *const parentDicNode, 175a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const DicNode *const dicNode) const { 176a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka const ProximityType proximityType = 177a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka getProximityType(traverseSession, parentDicNode, dicNode); 1787a06a792871c38517264fcb63b80a9c09bfe4766Keisuke Kuroynagi if (!ProximityInfoUtils::isMatchOrProximityChar(proximityType)) { 179a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 180a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 181a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return true; 182a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 183a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 184c32356c2291a6de8adf21698e6467f30b5f2e31cKeisuke Kuroyanagi AK_FORCE_INLINE bool isGoodToTraverseNextWord(const DicNode *const dicNode, 185c32356c2291a6de8adf21698e6467f30b5f2e31cKeisuke Kuroyanagi const int probability) const { 186a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka if (probability < ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY) { 187a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return false; 188a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 18909858cbde49c086dd1d4d3050b57f0ea1774158bKeisuke Kuroynagi const bool shortCappedWord = dicNode->getNodeCodePointCount() 190b43ea5c3359259b042a6f58883c61a82acf34e82Keisuke Kuroyanagi < ScoringParams::THRESHOLD_SHORT_WORD_LENGTH && dicNode->isFirstCharUppercase(); 191a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka return !shortCappedWord 192a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka || probability >= ScoringParams::THRESHOLD_NEXT_WORD_PROBABILITY_FOR_CAPPED; 193a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka } 194a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 195a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka private: 196a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka DISALLOW_COPY_AND_ASSIGN(TypingTraversal); 197a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka static const bool CORRECT_OMISSION; 198252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka static const bool CORRECT_NEW_WORD_SPACE_SUBSTITUTION; 199252412d7eb4573f91588b06b0fe49ef9f0ac38acSatoshi Kataoka static const bool CORRECT_NEW_WORD_SPACE_OMISSION; 200a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka static const TypingTraversal sInstance; 201a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka 202a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka TypingTraversal() {} 203a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka ~TypingTraversal() {} 204a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka}; 205a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka} // namespace latinime 206a6a416519603d2e65416dd8f9507913b7e4fd0a0Satoshi Kataoka#endif // LATINIME_TYPING_TRAVERSAL_H 207