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