Tizen 2.1 base
[platform/core/uifw/ise-engine-sunpinyin.git] / src / ime-core / imi_context.h
1 // -*- mode: c++ -*-
2 /*
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4  *
5  * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
6  *
7  * The contents of this file are subject to the terms of either the GNU Lesser
8  * General Public License Version 2.1 only ("LGPL") or the Common Development and
9  * Distribution License ("CDDL")(collectively, the "License"). You may not use this
10  * file except in compliance with the License. You can obtain a copy of the CDDL at
11  * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
12  * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
13  * specific language governing permissions and limitations under the License. When
14  * distributing the software, include this License Header Notice in each file and
15  * include the full text of the License in the License file as well as the
16  * following notice:
17  *
18  * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
19  * (CDDL)
20  * For Covered Software in this distribution, this License shall be governed by the
21  * laws of the State of California (excluding conflict-of-law provisions).
22  * Any litigation relating to this License shall be subject to the jurisdiction of
23  * the Federal Courts of the Northern District of California and the state courts
24  * of the State of California, with venue lying in Santa Clara County, California.
25  *
26  * Contributor(s):
27  *
28  * If you wish your version of this file to be governed by only the CDDL or only
29  * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
30  * include this software in this distribution under the [CDDL or LGPL Version 2.1]
31  * license." If you don't indicate a single choice of license, a recipient has the
32  * option to distribute your version of this file under either the CDDL or the LGPL
33  * Version 2.1, or to extend the choice of license to its licensees as provided
34  * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
35  * Version 2 license, then the option applies only if the new code is made subject
36  * to such option by the copyright holder.
37  */
38
39 #ifndef SUNPY_IMI_CONTEXT_H
40 #define SUNPY_IMI_CONTEXT_H
41
42 #include "portability.h"
43
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif
47
48 #if defined(DEBUG) && defined (HAVE_ASSET_H)
49 #include <assert.h>
50 #endif
51
52 #include <climits>
53 #include <map>
54 #include <vector>
55
56 #include "pinyin/pinyin_seg.h"
57 #include "imi_data.h"
58 #include "ic_history.h"
59 #include "userdict.h"
60 #include "lattice_states.h"
61 #include "imi_funcobjs.h"
62
63 /**
64  * TSentenceScore is only used for whole sentence score,
65  * the score from language model still using double.
66  */
67 typedef TLongExpFloat TSentenceScore;
68
69 class CLatticeFrame;
70 class CCandidate;
71 class CIMIContext;
72
73 typedef std::vector<CLatticeFrame>  CLattice;
74 typedef std::vector<CCandidate>     CCandidates;
75 typedef CCandidates::iterator CCandidatesIter;
76
77 union TCandiRank {
78 public:
79     bool operator<(const TCandiRank& b) const
80     { return m_all < b.m_all; };
81
82     TCandiRank() : m_all(0) {
83     }
84
85     TCandiRank(bool user, bool best, unsigned int len,
86                bool fromLattice, TSentenceScore score);
87
88     TCandiRank(bool user, bool best, unsigned int len,
89                bool fromLattice, unsigned score);
90
91 protected:
92     unsigned int m_all;
93 #if !defined(WORDS_BIGENDIAN)
94     struct TAnony {
95         unsigned m_cost   : 24;
96         unsigned m_lattice : 1;
97         unsigned m_best   : 1;
98         unsigned m_len    : 5;
99         unsigned m_user   : 1;
100     } anony;
101 #else
102     struct TAnony {
103         unsigned m_user   : 1;
104         unsigned m_len    : 5;
105         unsigned m_best   : 1;
106         unsigned m_lattice : 1;
107         unsigned m_cost   : 24;
108     } anony;
109 #endif
110 }; // TCandiRank
111
112 /**
113  * CCandidate represent basic information about a single candidate.
114  * Its start bone and finishing bone. It's content string. and its
115  * word id.
116  */
117 class CCandidate {
118     friend class CIMIContext;
119 public:
120     unsigned m_start;
121     unsigned m_end;
122     const TWCHAR       *m_cwstr;
123
124 public:
125     /** Give out the constructor for convinience */
126     CCandidate(unsigned start = 0,
127                unsigned end = 0,
128                TLexiconState* pLxst = NULL,
129                const TWCHAR* s = NULL,
130                unsigned int wid = 0)
131         : m_start(start), m_end(end), m_cwstr(s), m_wordId(wid),
132           m_pLexiconState(pLxst) {}
133
134 protected:
135     unsigned int m_wordId;
136     TLexiconState* m_pLexiconState;
137 }; // of CCandidate
138
139 class CLatticeFrame {
140     friend class CIMIContext;
141 public:
142     enum TYPE {
143         UNUSED                  = 0x0000,      // unused frame
144         TAIL                    = 0x0001,      // tail frame
145
146         CATE_SYLLABLE           = 0x0100,
147         SYLLABLE                = 0x0101,      // pinyin
148         SYLLABLE_SEP            = 0x0102,      // pinyin
149         INCOMPLETE_SYLLABLE     = 0x0104,      // incomplete syllable string
150
151         CATE_OTHER              = 0x0200,
152         ASCII                   = 0x0201,      // english string
153         PUNC                    = 0x0202,      // punctuation
154         SYMBOL                  = 0x0204,      // other symbol
155         DIGITAL                 = 0x0208,      // not implemeted here
156     }; // TYPE
157
158     enum BESTWORD_TYPE {
159         NO_BESTWORD             = 1 << 0,
160         BESTWORD                = 1 << 1,
161         USER_SELECTED           = 1 << 2,
162         IGNORED                 = 1 << 3,
163     }; // BESTWORD_TYPE
164
165     unsigned m_type;
166     unsigned m_bwType;
167     wstring m_wstr;
168
169     CLatticeFrame () : m_type(UNUSED), m_bwType(NO_BESTWORD) {}
170
171     bool isUnusedFrame() const
172     { return m_type == 0; }
173
174     bool isSyllableFrame() const
175     { return(m_type & CATE_SYLLABLE); }
176
177     bool isSyllableSepFrame() const
178     { return((m_type & SYLLABLE_SEP) > CATE_SYLLABLE); }
179
180     bool isTailFrame() const
181     { return(m_type == TAIL); }
182
183     void clear(){
184         m_type = UNUSED;
185         m_bwType = NO_BESTWORD;
186         m_lexiconStates.clear();
187         m_latticeStates.clear();
188         m_wstr.clear();
189         m_bestWords.clear();
190     }
191
192     void print(std::string prefix);
193
194 protected:
195     std::map<int, CCandidate>   m_bestWords;
196     CCandidate m_selWord;
197     CLexiconStates m_lexiconStates;
198     CLatticeStates m_latticeStates;
199 }; // CLatticeFrame
200
201 typedef std::vector<unsigned> TPath;
202
203 class CIMIContext
204 {
205 public:
206     CIMIContext ();
207     ~CIMIContext () { clear(); }
208
209     void clear();
210
211     void setCoreData(CIMIData *pCoreData);
212     void setUserDict(CUserDict *pUserDict) { m_pUserDict = pUserDict; }
213
214     void setHistoryMemory(CICHistory *phm) { m_pHistory = phm; }
215     CICHistory * getHistoryMemory() { return m_pHistory; }
216
217     void setHistoryPower(unsigned power)
218     { m_historyPower = power <= 10 ? power : 3; }
219
220     int getHistoryPower()
221     { return m_historyPower; }
222
223     void setFullSymbolForwarding(bool value = true) {
224         m_bFullSymbolForwarding = value;
225     }
226     bool getFullSymbolForwarding() { return m_bFullSymbolForwarding; }
227     void setGetFullSymbolOp(CGetFullSymbolOp *op) { m_pGetFullSymbolOp = op; }
228     CGetFullSymbolOp& fullSymbolOp() const { return *m_pGetFullSymbolOp; }
229
230     void setFullPunctForwarding(bool value = true) {
231         m_bFullPunctForwarding = value;
232     }
233     bool getFullPunctForwarding() { return m_bFullPunctForwarding; }
234     void setGetFullPunctOp(CGetFullPunctOp *op) { m_pGetFullPunctOp = op; }
235     CGetFullPunctOp& fullPuncOp() const { return *m_pGetFullPunctOp; }
236
237     void setNonCompleteSyllable(bool value = true) {
238         m_bNonCompleteSyllable = value;
239     }
240     bool getNonCompleteSyllable() { return m_bNonCompleteSyllable; }
241
242     void setCharsetLevel(unsigned l) { m_csLevel = l; }
243     unsigned getCharsetLevel() { return m_csLevel; }
244
245     void setDynamicCandidateOrder(bool value = true) {
246         m_bDynaCandiOrder = value;
247     }
248     bool getDynaCandiOrder() { return m_bDynaCandiOrder; }
249
250     CLattice& getLattice() { return m_lattice; }
251     bool buildLattice(IPySegmentor *segmentor, bool doSearch = true);
252     bool isEmpty() { return m_tailIdx <= 1; }
253     unsigned getLastFrIdx() { return m_tailIdx - 1; }
254
255     // omit next punctuation if the very next symbol is an punctuation
256     void omitNextPunct() { m_bOmitPunct = true; }
257
258     bool searchFrom(unsigned from = 1);
259
260     size_t getMaxBest() const { return m_maxBest; }
261     void setMaxBest(size_t maxBest) {
262         m_maxBest = maxBest;
263         for (int i = 0; i < MAX_LATTICE_LENGTH; i++) {
264             m_lattice[i].m_latticeStates.setMaxBest(m_maxBest);
265         }
266     }
267
268     size_t getMaxTailCandidateNum() const { return m_maxTailCandidateNum; }
269     void setMaxTailCandidateNum(size_t maxTailCandidateNum) {
270         m_maxTailCandidateNum = maxTailCandidateNum;
271     }
272
273     size_t getNBest() { return m_nBest; }
274     std::vector<TPath>& getPath(int rank) { return m_path; }
275     std::vector<TPath>& getSegPath(int rank) { return m_segPath; }
276
277     TPath& getBestPath() { return m_path[0]; }
278     TPath& getBestSegPath() {
279         if (m_segPath.empty()) {
280             static TPath emptyPath;
281             return emptyPath;
282         }
283         // CIMIContext would fail to backTrace the bestPathes when there are
284         // no latticeStates on frame e.g., 'yiden' in Quanpin mode, in this
285         // case, return the original segs
286         if (m_segPath[0].empty() && m_pPySegmentor) {
287             // only require the primary segments without the auxiliary ones
288             IPySegmentor::TSegmentVec& segments =
289                 m_pPySegmentor->getSegments(false);
290             IPySegmentor::TSegmentVec::const_iterator it = segments.begin();
291             IPySegmentor::TSegmentVec::const_iterator ite = segments.end();
292             m_segPath[0].push_back(0);
293             for (; it != ite; ++it)
294                 m_segPath[0].push_back(it->m_start + it->m_len);
295         }
296         return m_segPath[0];
297     }
298
299     std::vector<CCandidates> getBestSentenceTails(int rank, unsigned start,
300                                                   unsigned end = UINT_MAX);
301
302     unsigned getBestSentence(CCandidates& result, int rank,
303                              unsigned start = 0, unsigned end = UINT_MAX);
304     unsigned getBestSentence(wstring& result, int rank,
305                              unsigned start = 0, unsigned end = UINT_MAX);
306     unsigned getBestSentence(std::vector<unsigned>& result, int rank,
307                              unsigned start = 0, unsigned end = UINT_MAX);
308
309     unsigned getSelectedSentence(wstring& result,
310                                  unsigned start = 0, unsigned end = UINT_MAX);
311     unsigned getSelectedSentence(std::vector<unsigned>& result,
312                                  unsigned start = 0, unsigned end = UINT_MAX);
313
314     void getCandidates(unsigned frIdx, CCandidates& result);
315     unsigned cancelSelection(unsigned frIdx, bool doSearch = true);
316     void makeSelection(CCandidate &candi, bool doSearch = true);
317     void deleteCandidate(CCandidate &candi);
318     void deleteCandidateByWID(unsigned wid);
319     void selectSentence(int idx);
320
321     void memorize();
322     void removeFromHistoryCache(std::vector<unsigned>& wids);
323     void printLattice();
324
325     CUserDict* getUserDict() { return m_pUserDict; }
326
327 protected:
328     void _clearFrom(unsigned from);
329
330     bool _buildLattice(IPySegmentor::TSegmentVec &segments,
331                        unsigned rebuildFrom = 1, bool doSearch = true);
332     void _forwardSyllables(unsigned i, unsigned j,
333                            const IPySegmentor::TSegment& seg);
334     void _forwardSingleSyllable(unsigned i, unsigned j, TSyllable syllable,
335                                 const IPySegmentor::TSegment& seg,
336                                 bool fuzzy = false);
337     void _forwardSyllableSep(unsigned i, unsigned j);
338     void _forwardString(unsigned i, unsigned j,
339                         const std::vector<unsigned>& strbuf);
340     void _forwardPunctChar(unsigned i, unsigned j, unsigned ch);
341     void _forwardOrdinaryChar(unsigned i, unsigned j, unsigned ch);
342     void _forwardTail(unsigned i, unsigned j);
343
344     void _transferBetween(unsigned start, unsigned end, TLexiconState* plxst,
345                           unsigned wid, double ic = 1.0);
346     bool _backTracePaths(const std::vector<TLatticeState>& tail_states,
347                          int rank, TPath& path, TPath& segPath);
348     void _clearPaths();
349
350     const TWCHAR *_getWstr(unsigned wid);
351
352     void _saveUserDict();
353     void _saveHistoryCache();
354
355 protected:
356     CLattice m_lattice;
357     unsigned m_tailIdx;
358
359     size_t m_nBest;
360     size_t m_maxBest;
361     size_t m_maxTailCandidateNum;
362
363     std::vector<TPath> m_path;
364     std::vector<TPath> m_segPath;
365
366     CThreadSlm* m_pModel;
367     CPinyinTrie* m_pPinyinTrie;
368     CUserDict* m_pUserDict;
369     CICHistory* m_pHistory;
370     unsigned m_historyPower;
371
372     unsigned m_csLevel;
373
374     bool m_bFullSymbolForwarding;
375     bool m_bOmitPunct;
376     CGetFullSymbolOp  *m_pGetFullSymbolOp;
377
378     bool m_bFullPunctForwarding;
379     CGetFullPunctOp *m_pGetFullPunctOp;
380
381     IPySegmentor *m_pPySegmentor;
382
383     bool m_bNonCompleteSyllable;
384     bool m_bDynaCandiOrder;
385
386     unsigned m_candiStarts;
387     unsigned m_candiEnds;
388 }; // CIMIContext
389
390 #endif