~ubuntu-branches/ubuntu/quantal/sunpinyin/quantal

« back to all changes in this revision

Viewing changes to src/slm/slmseg/slmseg.cpp

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 
 * 
 
3
 *
4
4
 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
5
 
 * 
 
5
 *
6
6
 * The contents of this file are subject to the terms of either the GNU Lesser
7
7
 * General Public License Version 2.1 only ("LGPL") or the Common Development and
8
8
 * Distribution License ("CDDL")(collectively, the "License"). You may not use this
9
9
 * file except in compliance with the License. You can obtain a copy of the CDDL at
10
10
 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
11
 
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 
 
11
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
12
12
 * specific language governing permissions and limitations under the License. When
13
13
 * distributing the software, include this License Header Notice in each file and
14
14
 * include the full text of the License in the License file as well as the
15
15
 * following notice:
16
 
 * 
 
16
 *
17
17
 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
18
18
 * (CDDL)
19
19
 * For Covered Software in this distribution, this License shall be governed by the
21
21
 * Any litigation relating to this License shall be subject to the jurisdiction of
22
22
 * the Federal Courts of the Northern District of California and the state courts
23
23
 * of the State of California, with venue lying in Santa Clara County, California.
24
 
 * 
 
24
 *
25
25
 * Contributor(s):
26
 
 * 
 
26
 *
27
27
 * If you wish your version of this file to be governed by only the CDDL or only
28
28
 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
29
29
 * include this software in this distribution under the [CDDL or LGPL Version 2.1]
32
32
 * Version 2.1, or to extend the choice of license to its licensees as provided
33
33
 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
34
34
 * Version 2 license, then the option applies only if the new code is made subject
35
 
 * to such option by the copyright holder. 
 
35
 * to such option by the copyright holder.
36
36
 */
37
37
 
38
38
#ifdef HAVE_CONFIG_H
61
61
 
62
62
static struct option long_options[] =
63
63
{
64
 
    {"dict", 1, 0, 'd'},
65
 
    {"format", 1, 0, 'f'},
66
 
    {"show-id", 0, 0, 'i'},
67
 
    {"s-tok", 1, 0, 's'},
68
 
    {"model", 1, 0, 'm'},
69
 
    {0, 0, 0, 0}
 
64
    { "dict", 1, 0, 'd' },
 
65
    { "format", 1, 0, 'f' },
 
66
    { "show-id", 0, 0, 'i' },
 
67
    { "s-tok", 1, 0, 's' },
 
68
    { "model", 1, 0, 'm' },
 
69
    { 0, 0, 0, 0 }
70
70
};
71
71
 
72
72
static char* s_strDictFile = NULL;
82
82
ShowUsage()
83
83
{
84
84
    fprintf(stderr, "\nUsage:\n");
85
 
    fprintf(stderr, "slmseg -d dict_file [-f (text|bin)] [-i] [-s STOK_ID] [-m lm_file]\n\n");
 
85
    fprintf(
 
86
        stderr,
 
87
        "slmseg -d dict_file [-f (text|bin)] [-i] [-s STOK_ID] [-m lm_file]\n\n");
86
88
    fprintf(stderr, "  -f --format:\n");
87
 
    fprintf(stderr, "    Output Format, can be 'text' or 'bin'. default 'bin'\n");
88
 
    fprintf(stderr, "    Normally, in text mode, word text are output, while in binary mode,\n");
89
 
    fprintf(stderr, "    binary short integer of the word-ids are writed to stdout.\n");
 
89
    fprintf(stderr,
 
90
            "    Output Format, can be 'text' or 'bin'. default 'bin'\n");
 
91
    fprintf(
 
92
        stderr,
 
93
        "    Normally, in text mode, word text are output, while in binary mode,\n");
 
94
    fprintf(stderr,
 
95
            "    binary short integer of the word-ids are writed to stdout.\n");
90
96
    fprintf(stderr, "  -s --stok:\n");
91
97
    fprintf(stderr, "    Sentence token id. Default 10.\n");
92
 
    fprintf(stderr, "    It will be write to output in binary mode after every sentence.\n");
 
98
    fprintf(
 
99
        stderr,
 
100
        "    It will be write to output in binary mode after every sentence.\n");
93
101
    fprintf(stderr, "  -i --show-id:\n");
94
 
    fprintf(stderr, "    Show Id info. Under text output format mode, Attach id after known-words.\n");
 
102
    fprintf(
 
103
        stderr,
 
104
        "    Show Id info. Under text output format mode, Attach id after known-words.\n");
95
105
    fprintf(stderr, "                  Under binary mode, print id in text.\n");
96
106
    fprintf(stderr, "  -m --model:\n");
97
107
    fprintf(stderr, "    Language model file name");
98
108
    fprintf(stderr, "\n");
99
109
    fprintf(stderr, "Notes:\n");
100
 
    fprintf(stderr, "  Under binary mode, consecutive id of 0 are merged into one 0.\n");
101
 
    fprintf(stderr, "  Under text mode, no space are insert between unknown-words. \n");
 
110
    fprintf(stderr,
 
111
            "  Under binary mode, consecutive id of 0 are merged into one 0.\n");
 
112
    fprintf(stderr,
 
113
            "  Under text mode, no space are insert between unknown-words. \n");
102
114
    fprintf(stderr, "\n");
103
115
    fprintf(stderr, "\n");
104
116
    exit(1000);
108
120
getParameters(int argc, char* argv[])
109
121
{
110
122
    int c;
111
 
    while ((c=getopt_long(argc, argv, "d:if:s:m:", long_options, NULL)) != -1)
112
 
    {
 
123
    while ((c =
 
124
                getopt_long(argc, argv, "d:if:s:m:", long_options,
 
125
                            NULL)) != -1) {
113
126
        switch (c) {
114
127
        case 'd':
115
128
            s_strDictFile = strdup(optarg);
124
137
            s_iSTOKID = atoi(optarg);
125
138
            break;
126
139
        case 'm':
127
 
            s_strSlmFile  = strdup(optarg);
 
140
            s_strSlmFile = strdup(optarg);
128
141
            break;
129
142
        default:
130
143
            ShowUsage();
149
162
}
150
163
 
151
164
static void
152
 
output(int len, const TWCHAR* p, TSIMWordId idprev, TSIMWordId idcur, int& nWords)
 
165
output(int len,
 
166
       const TWCHAR* p,
 
167
       TSIMWordId idprev,
 
168
       TSIMWordId idcur,
 
169
       int& nWords)
153
170
{
154
171
    static char mbword[1024];
155
172
    static TWCHAR wcword[1024];
156
173
 
157
174
    bool bRealGap = (idcur != SIM_ID_NOT_WORD || idprev != SIM_ID_NOT_WORD);
158
175
    if (s_bTextOut) {
159
 
        for (int i=0; i < len; ++i, ++p)
 
176
        for (int i = 0; i < len; ++i, ++p)
160
177
            wcword[i] = *p;
161
178
        wcword[len] = 0;
162
179
        WCSTOMBS(mbword, wcword, sizeof(mbword));
182
199
}
183
200
 
184
201
struct TLatticeWord {
185
 
  int m_left;
186
 
  int m_right;
187
 
  int m_wordId;
 
202
    int m_left;
 
203
    int m_right;
 
204
    int m_wordId;
188
205
 
189
 
  TLatticeWord(int left=0, int right=0, int wid=0)
190
 
      : m_left(left), m_right(right), m_wordId(wid) { }
 
206
    TLatticeWord(int left = 0, int right = 0, int wid = 0)
 
207
        : m_left(left), m_right(right), m_wordId(wid)
 
208
    {
 
209
    }
191
210
};
192
211
 
193
212
typedef std::vector<TLatticeWord> TLatticeWordVec;
194
213
 
195
214
struct TLatticeStateValue {
196
 
  double                m_pr;
197
 
  TLatticeWord*         mp_btword;
198
 
  CThreadSlm::TState    m_btstate;
 
215
    double m_pr;
 
216
    TLatticeWord*         mp_btword;
 
217
    CThreadSlm::TState m_btstate;
199
218
 
200
 
  TLatticeStateValue(double pr=0.0, TLatticeWord* btword=NULL, CThreadSlm::TState btstate = CThreadSlm::TState())
201
 
      : m_pr(pr), mp_btword(btword), m_btstate(btstate) { }
 
219
    TLatticeStateValue(double pr = 0.0,
 
220
                       TLatticeWord* btword = NULL,
 
221
                       CThreadSlm::TState btstate = CThreadSlm::TState())
 
222
        : m_pr(pr), mp_btword(btword), m_btstate(btstate)
 
223
    {
 
224
    }
202
225
};
203
226
 
204
227
typedef std::map<CThreadSlm::TState, TLatticeStateValue> TLatticeColumnStates;
205
228
 
206
229
struct TLatticeColumn {
207
 
  TLatticeWordVec          m_wordstarting;
208
 
  TLatticeColumnStates     m_states;
 
230
    TLatticeWordVec m_wordstarting;
 
231
    TLatticeColumnStates m_states;
209
232
};
210
233
 
211
234
typedef std::vector<TLatticeColumn> CLattice;
212
235
 
213
 
inline void insertLatticeWord(CLattice& lattice, TLatticeWord word)
 
236
inline void
 
237
insertLatticeWord(CLattice& lattice, TLatticeWord word)
214
238
{
215
239
    lattice[word.m_left].m_wordstarting.push_back(word);
216
240
}
220
244
{
221
245
    const CSIMDict::TState* pstate;
222
246
 
223
 
    for (int i=1; (i<word_len) && *(p+i) != WCH_NULL; ++i) {
224
 
        int len = s_dict->matchLongest(s_dict->getRoot(), pstate, p+i);
225
 
        if (word_len < i+len)
226
 
            word_len = i+len;
 
247
    for (int i = 1; (i < word_len) && *(p + i) != WCH_NULL; ++i) {
 
248
        int len = s_dict->matchLongest(s_dict->getRoot(), pstate, p + i);
 
249
        if (word_len < i + len)
 
250
            word_len = i + len;
227
251
    }
228
252
 
229
253
    return word_len;
230
254
}
231
255
 
232
 
void fullSegBuildLattice(wstring& sntnc, int left, int len, CLattice& lattice)
 
256
void
 
257
fullSegBuildLattice(wstring& sntnc, int left, int len, CLattice& lattice)
233
258
{
234
 
    for (int right=left+len; left < right; ++left) {
 
259
    for (int right = left + len; left < right; ++left) {
235
260
        bool found = false;
236
261
 
237
 
        const TWCHAR* p = sntnc.c_str()+left;
 
262
        const TWCHAR* p = sntnc.c_str() + left;
238
263
        const CSIMDict::TState* pds = s_dict->getRoot();
239
 
        for (len = 0; left+len < right; ++len) {
 
264
        for (len = 0; left + len < right; ++len) {
240
265
            if ((pds = s_dict->step(pds, *p++)) == NULL)
241
266
                break;
242
267
            if (pds->word_id != SIM_ID_NOT_WORD) {
243
268
                found = true;
244
 
                insertLatticeWord(lattice, TLatticeWord(left, left+len+1, pds->word_id));
 
269
                insertLatticeWord(lattice,
 
270
                                  TLatticeWord(left, left + len + 1,
 
271
                                               pds->word_id));
245
272
            }
246
273
        }
247
274
        if (!found)
248
 
            insertLatticeWord(lattice, TLatticeWord(left, left+1, SIM_ID_NOT_WORD));
 
275
            insertLatticeWord(lattice,
 
276
                              TLatticeWord(left, left + 1, SIM_ID_NOT_WORD));
249
277
    }
250
278
}
251
279
 
252
280
/**
253
 
* Lattice head should have one state, with its TState using slm's root. its
254
 
* pr = 0 and its mp_btword == NULL;
255
 
* Lattice tail must contain no word, and it previous node contain only one word
256
 
* with its right = left+1, right == tail.
257
 
* The lattice should ensure the lattice path existing
258
 
*/
259
 
void buildLattice(wstring &sntnc, CLattice& lattice)
 
281
 * Lattice head should have one state, with its TState using slm's root. its
 
282
 * pr = 0 and its mp_btword == NULL;
 
283
 * Lattice tail must contain no word, and it previous node contain only one word
 
284
 * with its right = left+1, right == tail.
 
285
 * The lattice should ensure the lattice path existing
 
286
 */
 
287
void
 
288
buildLattice(wstring &sntnc, CLattice& lattice)
260
289
{
261
290
    lattice.clear();
262
 
    lattice.resize(sntnc.size()+2);
 
291
    lattice.resize(sntnc.size() + 2);
263
292
 
264
293
    unsigned int idcur = SIM_ID_NOT_WORD;
265
 
    lattice[0].m_states[CThreadSlm::TState()] = TLatticeStateValue(0.0, NULL, CThreadSlm::TState());
 
294
    lattice[0].m_states[CThreadSlm::TState()] = TLatticeStateValue(
 
295
        0.0,
 
296
        NULL,
 
297
        CThreadSlm::
 
298
        TState());
266
299
 
267
 
    for (int i=0, sz=sntnc.size(); i < sz; ) {
 
300
    for (int i = 0, sz = sntnc.size(); i < sz; ) {
268
301
        const CSIMDict::TState* pstate;
269
 
        const TWCHAR* p = sntnc.c_str()+i;
 
302
        const TWCHAR* p = sntnc.c_str() + i;
270
303
        int len = s_dict->matchLongest(s_dict->getRoot(), pstate, p);
271
304
        if (len <= 0) {
272
305
            idcur = SIM_ID_NOT_WORD;
277
310
        int ambilen = getAmbiLen(p, len);
278
311
 
279
312
        if (ambilen <= len) {
280
 
            insertLatticeWord(lattice, TLatticeWord(i, i+len, idcur));
 
313
            insertLatticeWord(lattice, TLatticeWord(i, i + len, idcur));
281
314
            i += len;
282
315
        } else {
283
316
            fullSegBuildLattice(sntnc, i, ambilen, lattice);
284
317
            i += ambilen;
285
318
        }
286
319
    }
287
 
    lattice[sntnc.size()].m_wordstarting.push_back(TLatticeWord(sntnc.size(), sntnc.size()+1, s_iSTOKID));
 
320
    lattice[sntnc.size()].m_wordstarting.push_back(TLatticeWord(sntnc.size(),
 
321
                                                                sntnc.size() +
 
322
                                                                1, s_iSTOKID));
288
323
}
289
324
 
290
 
void searchBest(CLattice& lattice)
 
325
void
 
326
searchBest(CLattice& lattice)
291
327
{
292
 
    for (int i=0, sz=lattice.size(); i < sz; ++i) {
 
328
    for (int i = 0, sz = lattice.size(); i < sz; ++i) {
293
329
        TLatticeColumnStates & states = lattice[i].m_states;
294
330
        TLatticeColumnStates::iterator itss = states.begin();
295
331
        TLatticeColumnStates::iterator itse = states.end();
315
351
    }
316
352
}
317
353
 
318
 
void getBestPath(CLattice& lattice, TLatticeWordVec& segResult)
 
354
void
 
355
getBestPath(CLattice& lattice, TLatticeWordVec& segResult)
319
356
{
320
357
    TLatticeColumnStates & states = lattice.back().m_states;
321
358
    TLatticeColumnStates::iterator its = states.begin();
360
397
    if (!s_bTextOut)
361
398
        output_stok(nWords);
362
399
 
363
 
    while (true){
 
400
    while (true) {
364
401
        if (ReadSentence(sntnc, iter, false) == false)
365
402
            break;
366
403
 
371
408
        TLatticeWordVec segResult;
372
409
        getBestPath(lattice, segResult);
373
410
 
374
 
        for (int i=0, sz=segResult.size(); i < sz; ++i) {
375
 
            const TWCHAR *p = sntnc.c_str()+segResult[i].m_left;
 
411
        for (int i = 0, sz = segResult.size(); i < sz; ++i) {
 
412
            const TWCHAR *p = sntnc.c_str() + segResult[i].m_left;
376
413
            int len = segResult[i].m_right - segResult[i].m_left;
377
414
            idcur = segResult[i].m_wordId;
378
415
 
424
461
        fprintf(stderr, "%d words, %d ambiguious. Done!\n", nWords, nAmbis);
425
462
        fflush(stderr);
426
463
    } else {
427
 
        for (int i=0; i < argc; ++i) {
 
464
        for (int i = 0; i < argc; ++i) {
428
465
            fprintf(stderr, "\nProcessing %s...", argv[i]); fflush(stderr);
429
466
            FILE *fp = fopen(argv[i], "r");
430
467
            if (fp != NULL) {
431
468
                processSingleFile(fp, nWords, nAmbis);
432
469
                fprintf(stderr, "@Offset %ld, %d words, %d ambiguious. Done!\n",
433
 
                                ftell(fp), nWords, nAmbis);
 
470
                        ftell(fp), nWords, nAmbis);
434
471
                fflush(stderr);
435
472
            } else {
436
473
                fprintf(stderr, "Can not Open!!!!!!!\n");