~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/contrib/analyzers/common/src/java/org/apache/lucene/analysis/br/BrazilianStemmer.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.analysis.br;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
/**
21
 
 * A stemmer for Brazilian Portuguese words.
22
 
 */
23
 
public class BrazilianStemmer {
24
 
 
25
 
        /**
26
 
         * Changed term
27
 
         */
28
 
        private   String TERM ;
29
 
        private   String CT ;
30
 
        private   String R1 ;
31
 
        private   String R2 ;
32
 
        private   String RV ;
33
 
 
34
 
 
35
 
        public BrazilianStemmer() {
36
 
        }
37
 
 
38
 
        /**
39
 
         * Stems the given term to an unique <tt>discriminator</tt>.
40
 
         *
41
 
         * @param term  The term that should be stemmed.
42
 
         * @return      Discriminator for <tt>term</tt>
43
 
         */
44
 
        protected String stem( String term ) {
45
 
    boolean altered = false ; // altered the term
46
 
 
47
 
    // creates CT
48
 
    createCT(term) ;
49
 
 
50
 
                if ( !isIndexable( CT ) ) {
51
 
                        return null;
52
 
                }
53
 
                if ( !isStemmable( CT ) ) {
54
 
                        return CT ;
55
 
                }
56
 
 
57
 
    R1 = getR1(CT) ;
58
 
    R2 = getR1(R1) ;
59
 
    RV = getRV(CT) ;
60
 
    TERM = term + ";" +CT ;
61
 
 
62
 
    altered = step1() ;
63
 
    if (!altered) {
64
 
      altered = step2() ;
65
 
    }
66
 
 
67
 
    if (altered) {
68
 
      step3();
69
 
    } else {
70
 
      step4();
71
 
    }
72
 
 
73
 
    step5() ;
74
 
 
75
 
    return CT ;
76
 
        }
77
 
 
78
 
        /**
79
 
         * Checks a term if it can be processed correctly.
80
 
         *
81
 
         * @return  true if, and only if, the given term consists in letters.
82
 
         */
83
 
        private boolean isStemmable( String term ) {
84
 
                for ( int c = 0; c < term.length(); c++ ) {
85
 
                        // Discard terms that contain non-letter characters.
86
 
                        if ( !Character.isLetter(term.charAt(c))) {
87
 
                                return false;
88
 
                        }
89
 
                }
90
 
                return true;
91
 
        }
92
 
 
93
 
        /**
94
 
         * Checks a term if it can be processed indexed.
95
 
         *
96
 
         * @return  true if it can be indexed
97
 
         */
98
 
        private boolean isIndexable( String term ) {
99
 
                return (term.length() < 30) && (term.length() > 2) ;
100
 
        }
101
 
 
102
 
        /**
103
 
         * See if string is 'a','e','i','o','u'
104
 
   *
105
 
   * @return true if is vowel
106
 
         */
107
 
        private boolean isVowel( char value ) {
108
 
    return (value == 'a') ||
109
 
           (value == 'e') ||
110
 
           (value == 'i') ||
111
 
           (value == 'o') ||
112
 
           (value == 'u') ;
113
 
  }
114
 
 
115
 
        /**
116
 
         * Gets R1
117
 
   *
118
 
   * R1 - is the region after the first non-vowel following a vowel,
119
 
   *      or is the null region at the end of the word if there is
120
 
   *      no such non-vowel.
121
 
   *
122
 
   * @return null or a string representing R1
123
 
         */
124
 
        private String getR1( String value ) {
125
 
    int     i;
126
 
    int     j;
127
 
 
128
 
    // be-safe !!!
129
 
    if (value == null) {
130
 
      return null ;
131
 
    }
132
 
 
133
 
    // find 1st vowel
134
 
    i = value.length()-1 ;
135
 
    for (j=0 ; j < i ; j++) {
136
 
      if (isVowel(value.charAt(j))) {
137
 
        break ;
138
 
      }
139
 
    }
140
 
 
141
 
    if (!(j < i)) {
142
 
      return null ;
143
 
    }
144
 
 
145
 
    // find 1st non-vowel
146
 
    for ( ; j < i ; j++) {
147
 
      if (!(isVowel(value.charAt(j)))) {
148
 
        break ;
149
 
      }
150
 
    }
151
 
 
152
 
    if (!(j < i)) {
153
 
      return null ;
154
 
    }
155
 
 
156
 
    return value.substring(j+1) ;
157
 
  }
158
 
 
159
 
        /**
160
 
         * Gets RV
161
 
   *
162
 
   * RV - IF the second letter is a consonant, RV is the region after
163
 
   *      the next following vowel,
164
 
   *
165
 
   *      OR if the first two letters are vowels, RV is the region
166
 
   *      after the next consonant,
167
 
   *
168
 
   *      AND otherwise (consonant-vowel case) RV is the region after
169
 
   *      the third letter.
170
 
   *
171
 
   *      BUT RV is the end of the word if this positions cannot be
172
 
   *      found.
173
 
   *
174
 
   * @return null or a string representing RV
175
 
         */
176
 
        private String getRV( String value ) {
177
 
    int     i;
178
 
    int     j;
179
 
 
180
 
    // be-safe !!!
181
 
    if (value == null) {
182
 
      return null ;
183
 
    }
184
 
 
185
 
    i = value.length()-1 ;
186
 
 
187
 
    // RV - IF the second letter is a consonant, RV is the region after
188
 
    //      the next following vowel,
189
 
    if ((i > 0) && !isVowel(value.charAt(1))) {
190
 
      // find 1st vowel
191
 
      for (j=2 ; j < i ; j++) {
192
 
        if (isVowel(value.charAt(j))) {
193
 
          break ;
194
 
        }
195
 
      }
196
 
 
197
 
      if (j < i) {
198
 
        return value.substring(j+1) ;
199
 
      }
200
 
    }
201
 
 
202
 
 
203
 
    // RV - OR if the first two letters are vowels, RV is the region
204
 
    //      after the next consonant,
205
 
    if ((i > 1) &&
206
 
        isVowel(value.charAt(0)) &&
207
 
        isVowel(value.charAt(1))) {
208
 
      // find 1st consoant
209
 
      for (j=2 ; j < i ; j++) {
210
 
        if (!isVowel(value.charAt(j))) {
211
 
          break ;
212
 
        }
213
 
      }
214
 
 
215
 
      if (j < i) {
216
 
        return value.substring(j+1) ;
217
 
      }
218
 
    }
219
 
 
220
 
    // RV - AND otherwise (consonant-vowel case) RV is the region after
221
 
    //      the third letter.
222
 
    if (i > 2) {
223
 
      return value.substring(3) ;
224
 
    }
225
 
 
226
 
    return null ;
227
 
  }
228
 
 
229
 
        /**
230
 
   * 1) Turn to lowercase
231
 
   * 2) Remove accents
232
 
   * 3) ã -> a ; õ -> o
233
 
   * 4) ç -> c
234
 
   *
235
 
   * @return null or a string transformed
236
 
         */
237
 
        private String changeTerm( String value ) {
238
 
    int     j;
239
 
    String  r = "" ;
240
 
 
241
 
    // be-safe !!!
242
 
    if (value == null) {
243
 
      return null ;
244
 
    }
245
 
 
246
 
    value = value.toLowerCase() ;
247
 
    for (j=0 ; j < value.length() ; j++) {
248
 
      if ((value.charAt(j) == 'á') ||
249
 
          (value.charAt(j) == 'â') ||
250
 
          (value.charAt(j) == 'ã')) {
251
 
        r= r + "a" ; continue ;
252
 
      }
253
 
      if ((value.charAt(j) == 'é') ||
254
 
          (value.charAt(j) == 'ê')) {
255
 
        r= r + "e" ; continue ;
256
 
      }
257
 
      if (value.charAt(j) == 'í') {
258
 
        r= r + "i" ; continue ;
259
 
      }
260
 
      if ((value.charAt(j) == 'ó') ||
261
 
          (value.charAt(j) == 'ô') ||
262
 
          (value.charAt(j) == 'õ')) {
263
 
        r= r + "o" ; continue ;
264
 
      }
265
 
      if ((value.charAt(j) == 'ú') ||
266
 
          (value.charAt(j) == 'ü')) {
267
 
        r= r + "u" ; continue ;
268
 
      }
269
 
      if (value.charAt(j) == 'ç') {
270
 
        r= r + "c" ; continue ;
271
 
      }
272
 
      if (value.charAt(j) == 'ñ') {
273
 
        r= r + "n" ; continue ;
274
 
      }
275
 
 
276
 
      r= r+ value.charAt(j) ;
277
 
    }
278
 
 
279
 
    return r ;
280
 
  }
281
 
 
282
 
        /**
283
 
   * Check if a string ends with a suffix
284
 
   *
285
 
   * @return true if the string ends with the specified suffix
286
 
         */
287
 
        private boolean suffix( String value, String suffix ) {
288
 
 
289
 
    // be-safe !!!
290
 
    if ((value == null) || (suffix == null)) {
291
 
      return false ;
292
 
    }
293
 
 
294
 
    if (suffix.length() > value.length()) {
295
 
      return false ;
296
 
    }
297
 
 
298
 
    return value.substring(value.length()-suffix.length()).equals(suffix);
299
 
  }
300
 
 
301
 
        /**
302
 
   * Replace a string suffix by another
303
 
   *
304
 
   * @return the replaced String
305
 
         */
306
 
        private String replaceSuffix( String value, String toReplace, String changeTo ) {
307
 
    String vvalue ;
308
 
 
309
 
    // be-safe !!!
310
 
    if ((value == null) ||
311
 
        (toReplace == null) ||
312
 
        (changeTo == null) ) {
313
 
      return value ;
314
 
    }
315
 
 
316
 
    vvalue = removeSuffix(value,toReplace) ;
317
 
 
318
 
    if (value.equals(vvalue)) {
319
 
      return value ;
320
 
    } else {
321
 
      return vvalue + changeTo ;
322
 
    }
323
 
  }
324
 
 
325
 
        /**
326
 
   * Remove a string suffix
327
 
   *
328
 
   * @return the String without the suffix
329
 
         */
330
 
        private String removeSuffix( String value, String toRemove ) {
331
 
    // be-safe !!!
332
 
    if ((value == null) ||
333
 
        (toRemove == null) ||
334
 
        !suffix(value,toRemove) ) {
335
 
      return value ;
336
 
    }
337
 
 
338
 
    return value.substring(0,value.length()-toRemove.length()) ;
339
 
  }
340
 
 
341
 
        /**
342
 
   * See if a suffix is preceded by a String
343
 
   *
344
 
   * @return true if the suffix is preceded
345
 
         */
346
 
        private boolean suffixPreceded( String value, String suffix, String preceded ) {
347
 
    // be-safe !!!
348
 
    if ((value == null) ||
349
 
        (suffix == null) ||
350
 
        (preceded == null) ||
351
 
        !suffix(value,suffix) ) {
352
 
      return false ;
353
 
    }
354
 
 
355
 
    return suffix(removeSuffix(value,suffix),preceded) ;
356
 
  }
357
 
 
358
 
        /**
359
 
         * Creates CT (changed term) , substituting * 'ã' and 'õ' for 'a~' and 'o~'.
360
 
         */
361
 
        private void createCT( String term ) {
362
 
    CT = changeTerm(term) ;
363
 
 
364
 
    if (CT.length() < 2) return ;
365
 
 
366
 
    // if the first character is ... , remove it
367
 
    if ((CT.charAt(0) == '"')  ||
368
 
        (CT.charAt(0) == '\'') ||
369
 
        (CT.charAt(0) == '-')  ||
370
 
        (CT.charAt(0) == ',')  ||
371
 
        (CT.charAt(0) == ';')  ||
372
 
        (CT.charAt(0) == '.')  ||
373
 
        (CT.charAt(0) == '?')  ||
374
 
        (CT.charAt(0) == '!')
375
 
        ) {
376
 
        CT = CT.substring(1);
377
 
    }
378
 
 
379
 
    if (CT.length() < 2) return ;
380
 
 
381
 
    // if the last character is ... , remove it
382
 
    if ((CT.charAt(CT.length()-1) == '-') ||
383
 
        (CT.charAt(CT.length()-1) == ',') ||
384
 
        (CT.charAt(CT.length()-1) == ';') ||
385
 
        (CT.charAt(CT.length()-1) == '.') ||
386
 
        (CT.charAt(CT.length()-1) == '?') ||
387
 
        (CT.charAt(CT.length()-1) == '!') ||
388
 
        (CT.charAt(CT.length()-1) == '\'') ||
389
 
        (CT.charAt(CT.length()-1) == '"')
390
 
        ) {
391
 
        CT = CT.substring(0,CT.length()-1);
392
 
    }
393
 
  }
394
 
 
395
 
 
396
 
        /**
397
 
         * Standard suffix removal.
398
 
   * Search for the longest among the following suffixes, and perform
399
 
   * the following actions:
400
 
   *
401
 
   * @return false if no ending was removed
402
 
         */
403
 
        private boolean step1() {
404
 
    if (CT == null) return false ;
405
 
 
406
 
    // suffix length = 7
407
 
    if (suffix(CT,"uciones") && suffix(R2,"uciones")) {
408
 
        CT = replaceSuffix(CT,"uciones","u") ; return true;
409
 
    }
410
 
 
411
 
    // suffix length = 6
412
 
    if (CT.length() >= 6) {
413
 
      if (suffix(CT,"imentos") && suffix(R2,"imentos")) {
414
 
          CT = removeSuffix(CT,"imentos") ; return true;
415
 
      }
416
 
      if (suffix(CT,"amentos") && suffix(R2,"amentos")) {
417
 
          CT = removeSuffix(CT,"amentos") ; return true;
418
 
      }
419
 
      if (suffix(CT,"adores") && suffix(R2,"adores")) {
420
 
          CT = removeSuffix(CT,"adores") ; return true;
421
 
      }
422
 
      if (suffix(CT,"adoras") && suffix(R2,"adoras")) {
423
 
          CT = removeSuffix(CT,"adoras") ; return true;
424
 
      }
425
 
      if (suffix(CT,"logias") && suffix(R2,"logias")) {
426
 
          replaceSuffix(CT,"logias","log") ; return true;
427
 
      }
428
 
      if (suffix(CT,"encias") && suffix(R2,"encias")) {
429
 
          CT = replaceSuffix(CT,"encias","ente") ; return true;
430
 
      }
431
 
      if (suffix(CT,"amente") && suffix(R1,"amente")) {
432
 
          CT = removeSuffix(CT,"amente") ; return true;
433
 
      }
434
 
      if (suffix(CT,"idades") && suffix(R2,"idades")) {
435
 
          CT = removeSuffix(CT,"idades") ; return true;
436
 
      }
437
 
    }
438
 
 
439
 
    // suffix length = 5
440
 
    if (CT.length() >= 5) {
441
 
      if (suffix(CT,"acoes") && suffix(R2,"acoes")) {
442
 
          CT = removeSuffix(CT,"acoes") ; return true;
443
 
      }
444
 
      if (suffix(CT,"imento") && suffix(R2,"imento")) {
445
 
          CT = removeSuffix(CT,"imento") ; return true;
446
 
      }
447
 
      if (suffix(CT,"amento") && suffix(R2,"amento")) {
448
 
          CT = removeSuffix(CT,"amento") ; return true;
449
 
      }
450
 
      if (suffix(CT,"adora") && suffix(R2,"adora")) {
451
 
          CT = removeSuffix(CT,"adora") ; return true;
452
 
      }
453
 
      if (suffix(CT,"ismos") && suffix(R2,"ismos")) {
454
 
          CT = removeSuffix(CT,"ismos") ; return true;
455
 
      }
456
 
      if (suffix(CT,"istas") && suffix(R2,"istas")) {
457
 
          CT = removeSuffix(CT,"istas") ; return true;
458
 
      }
459
 
      if (suffix(CT,"logia") && suffix(R2,"logia")) {
460
 
          CT = replaceSuffix(CT,"logia","log") ; return true;
461
 
      }
462
 
      if (suffix(CT,"ucion") && suffix(R2,"ucion")) {
463
 
          CT = replaceSuffix(CT,"ucion","u") ; return true;
464
 
      }
465
 
      if (suffix(CT,"encia") && suffix(R2,"encia")) {
466
 
          CT = replaceSuffix(CT,"encia","ente") ; return true;
467
 
      }
468
 
      if (suffix(CT,"mente") && suffix(R2,"mente")) {
469
 
          CT = removeSuffix(CT,"mente") ; return true;
470
 
      }
471
 
      if (suffix(CT,"idade") && suffix(R2,"idade")) {
472
 
          CT = removeSuffix(CT,"idade") ; return true;
473
 
      }
474
 
    }
475
 
 
476
 
    // suffix length = 4
477
 
    if (CT.length() >= 4) {
478
 
      if (suffix(CT,"acao") && suffix(R2,"acao")) {
479
 
          CT = removeSuffix(CT,"acao") ; return true;
480
 
      }
481
 
      if (suffix(CT,"ezas") && suffix(R2,"ezas")) {
482
 
          CT = removeSuffix(CT,"ezas") ; return true;
483
 
      }
484
 
      if (suffix(CT,"icos") && suffix(R2,"icos")) {
485
 
          CT = removeSuffix(CT,"icos") ; return true ;
486
 
      }
487
 
      if (suffix(CT,"icas") && suffix(R2,"icas")) {
488
 
          CT = removeSuffix(CT,"icas") ; return true ;
489
 
      }
490
 
      if (suffix(CT,"ismo") && suffix(R2,"ismo")) {
491
 
          CT = removeSuffix(CT,"ismo") ; return true ;
492
 
      }
493
 
      if (suffix(CT,"avel") && suffix(R2,"avel")) {
494
 
          CT = removeSuffix(CT,"avel") ; return true ;
495
 
      }
496
 
      if (suffix(CT,"ivel") && suffix(R2,"ivel")) {
497
 
          CT = removeSuffix(CT,"ivel") ; return true ;
498
 
      }
499
 
      if (suffix(CT,"ista") && suffix(R2,"ista")) {
500
 
          CT = removeSuffix(CT,"ista") ; return true ;
501
 
      }
502
 
      if (suffix(CT,"osos") && suffix(R2,"osos")) {
503
 
          CT = removeSuffix(CT,"osos") ; return true ;
504
 
      }
505
 
      if (suffix(CT,"osas") && suffix(R2,"osas")) {
506
 
          CT = removeSuffix(CT,"osas") ; return true ;
507
 
      }
508
 
      if (suffix(CT,"ador") && suffix(R2,"ador")) {
509
 
          CT = removeSuffix(CT,"ador") ; return true ;
510
 
      }
511
 
      if (suffix(CT,"ivas") && suffix(R2,"ivas")) {
512
 
          CT = removeSuffix(CT,"ivas") ; return true ;
513
 
      }
514
 
      if (suffix(CT,"ivos") && suffix(R2,"ivos")) {
515
 
          CT = removeSuffix(CT,"ivos") ; return true ;
516
 
      }
517
 
      if (suffix(CT,"iras") &&
518
 
          suffix(RV,"iras") &&
519
 
          suffixPreceded(CT,"iras","e")) {
520
 
          CT = replaceSuffix(CT,"iras","ir") ; return true ;
521
 
      }
522
 
    }
523
 
 
524
 
    // suffix length = 3
525
 
    if (CT.length() >= 3) {
526
 
      if (suffix(CT,"eza") && suffix(R2,"eza")) {
527
 
          CT = removeSuffix(CT,"eza") ; return true ;
528
 
      }
529
 
      if (suffix(CT,"ico") && suffix(R2,"ico")) {
530
 
          CT = removeSuffix(CT,"ico") ; return true ;
531
 
      }
532
 
      if (suffix(CT,"ica") && suffix(R2,"ica")) {
533
 
          CT = removeSuffix(CT,"ica") ; return true ;
534
 
      }
535
 
      if (suffix(CT,"oso") && suffix(R2,"oso")) {
536
 
          CT = removeSuffix(CT,"oso") ; return true ;
537
 
      }
538
 
      if (suffix(CT,"osa") && suffix(R2,"osa")) {
539
 
          CT = removeSuffix(CT,"osa") ; return true ;
540
 
      }
541
 
      if (suffix(CT,"iva") && suffix(R2,"iva")) {
542
 
          CT = removeSuffix(CT,"iva") ; return true ;
543
 
      }
544
 
      if (suffix(CT,"ivo") && suffix(R2,"ivo")) {
545
 
          CT = removeSuffix(CT,"ivo") ; return true ;
546
 
      }
547
 
      if (suffix(CT,"ira") &&
548
 
          suffix(RV,"ira") &&
549
 
          suffixPreceded(CT,"ira","e")) {
550
 
          CT = replaceSuffix(CT,"ira","ir") ; return true ;
551
 
      }
552
 
    }
553
 
 
554
 
    // no ending was removed by step1
555
 
    return false ;
556
 
  }
557
 
 
558
 
 
559
 
        /**
560
 
         * Verb suffixes.
561
 
   *
562
 
   * Search for the longest among the following suffixes in RV,
563
 
   * and if found, delete.
564
 
   *
565
 
   * @return false if no ending was removed
566
 
        */
567
 
        private boolean step2() {
568
 
    if (RV == null) return false ;
569
 
 
570
 
    // suffix lenght = 7
571
 
    if (RV.length() >= 7) {
572
 
      if (suffix(RV,"issemos")) {
573
 
        CT = removeSuffix(CT,"issemos") ; return true;
574
 
      }
575
 
      if (suffix(RV,"essemos")) {
576
 
        CT = removeSuffix(CT,"essemos") ; return true;
577
 
      }
578
 
      if (suffix(RV,"assemos")) {
579
 
        CT = removeSuffix(CT,"assemos") ; return true;
580
 
      }
581
 
      if (suffix(RV,"ariamos")) {
582
 
        CT = removeSuffix(CT,"ariamos") ; return true;
583
 
      }
584
 
      if (suffix(RV,"eriamos")) {
585
 
        CT = removeSuffix(CT,"eriamos") ; return true;
586
 
      }
587
 
      if (suffix(RV,"iriamos")) {
588
 
        CT = removeSuffix(CT,"iriamos") ; return true;
589
 
      }
590
 
    }
591
 
 
592
 
    // suffix length = 6
593
 
    if (RV.length() >= 6) {
594
 
      if (suffix(RV,"iremos")) {
595
 
        CT = removeSuffix(CT,"iremos") ; return true;
596
 
      }
597
 
      if (suffix(RV,"eremos")) {
598
 
        CT = removeSuffix(CT,"eremos") ; return true;
599
 
      }
600
 
      if (suffix(RV,"aremos")) {
601
 
        CT = removeSuffix(CT,"aremos") ; return true;
602
 
      }
603
 
      if (suffix(RV,"avamos")) {
604
 
        CT = removeSuffix(CT,"avamos") ; return true;
605
 
      }
606
 
      if (suffix(RV,"iramos")) {
607
 
        CT = removeSuffix(CT,"iramos") ; return true;
608
 
      }
609
 
      if (suffix(RV,"eramos")) {
610
 
        CT = removeSuffix(CT,"eramos") ; return true;
611
 
      }
612
 
      if (suffix(RV,"aramos")) {
613
 
        CT = removeSuffix(CT,"aramos") ; return true;
614
 
      }
615
 
      if (suffix(RV,"asseis")) {
616
 
        CT = removeSuffix(CT,"asseis") ; return true;
617
 
      }
618
 
      if (suffix(RV,"esseis")) {
619
 
        CT = removeSuffix(CT,"esseis") ; return true;
620
 
      }
621
 
      if (suffix(RV,"isseis")) {
622
 
        CT = removeSuffix(CT,"isseis") ; return true;
623
 
      }
624
 
      if (suffix(RV,"arieis")) {
625
 
        CT = removeSuffix(CT,"arieis") ; return true;
626
 
      }
627
 
      if (suffix(RV,"erieis")) {
628
 
        CT = removeSuffix(CT,"erieis") ; return true;
629
 
      }
630
 
      if (suffix(RV,"irieis")) {
631
 
        CT = removeSuffix(CT,"irieis") ; return true;
632
 
      }
633
 
    }
634
 
 
635
 
 
636
 
    // suffix length = 5
637
 
    if (RV.length() >= 5) {
638
 
      if (suffix(RV,"irmos")) {
639
 
        CT = removeSuffix(CT,"irmos") ; return true;
640
 
      }
641
 
      if (suffix(RV,"iamos")) {
642
 
        CT = removeSuffix(CT,"iamos") ; return true;
643
 
      }
644
 
      if (suffix(RV,"armos")) {
645
 
        CT = removeSuffix(CT,"armos") ; return true;
646
 
      }
647
 
      if (suffix(RV,"ermos")) {
648
 
        CT = removeSuffix(CT,"ermos") ; return true;
649
 
      }
650
 
      if (suffix(RV,"areis")) {
651
 
        CT = removeSuffix(CT,"areis") ; return true;
652
 
      }
653
 
      if (suffix(RV,"ereis")) {
654
 
        CT = removeSuffix(CT,"ereis") ; return true;
655
 
      }
656
 
      if (suffix(RV,"ireis")) {
657
 
        CT = removeSuffix(CT,"ireis") ; return true;
658
 
      }
659
 
      if (suffix(RV,"asses")) {
660
 
        CT = removeSuffix(CT,"asses") ; return true;
661
 
      }
662
 
      if (suffix(RV,"esses")) {
663
 
        CT = removeSuffix(CT,"esses") ; return true;
664
 
      }
665
 
      if (suffix(RV,"isses")) {
666
 
        CT = removeSuffix(CT,"isses") ; return true;
667
 
      }
668
 
      if (suffix(RV,"astes")) {
669
 
        CT = removeSuffix(CT,"astes") ; return true;
670
 
      }
671
 
      if (suffix(RV,"assem")) {
672
 
        CT = removeSuffix(CT,"assem") ; return true;
673
 
      }
674
 
      if (suffix(RV,"essem")) {
675
 
        CT = removeSuffix(CT,"essem") ; return true;
676
 
      }
677
 
      if (suffix(RV,"issem")) {
678
 
        CT = removeSuffix(CT,"issem") ; return true;
679
 
      }
680
 
      if (suffix(RV,"ardes")) {
681
 
        CT = removeSuffix(CT,"ardes") ; return true;
682
 
      }
683
 
      if (suffix(RV,"erdes")) {
684
 
        CT = removeSuffix(CT,"erdes") ; return true;
685
 
      }
686
 
      if (suffix(RV,"irdes")) {
687
 
        CT = removeSuffix(CT,"irdes") ; return true;
688
 
      }
689
 
      if (suffix(RV,"ariam")) {
690
 
        CT = removeSuffix(CT,"ariam") ; return true;
691
 
      }
692
 
      if (suffix(RV,"eriam")) {
693
 
        CT = removeSuffix(CT,"eriam") ; return true;
694
 
      }
695
 
      if (suffix(RV,"iriam")) {
696
 
        CT = removeSuffix(CT,"iriam") ; return true;
697
 
      }
698
 
      if (suffix(RV,"arias")) {
699
 
        CT = removeSuffix(CT,"arias") ; return true;
700
 
      }
701
 
      if (suffix(RV,"erias")) {
702
 
        CT = removeSuffix(CT,"erias") ; return true;
703
 
      }
704
 
      if (suffix(RV,"irias")) {
705
 
        CT = removeSuffix(CT,"irias") ; return true;
706
 
      }
707
 
      if (suffix(RV,"estes")) {
708
 
        CT = removeSuffix(CT,"estes") ; return true;
709
 
      }
710
 
      if (suffix(RV,"istes")) {
711
 
        CT = removeSuffix(CT,"istes") ; return true;
712
 
      }
713
 
      if (suffix(RV,"areis")) {
714
 
        CT = removeSuffix(CT,"areis") ; return true;
715
 
      }
716
 
      if (suffix(RV,"aveis")) {
717
 
        CT = removeSuffix(CT,"aveis") ; return true;
718
 
      }
719
 
    }
720
 
 
721
 
    // suffix length = 4
722
 
    if (RV.length() >= 4) {
723
 
      if (suffix(RV,"aria")) {
724
 
        CT = removeSuffix(CT,"aria") ; return true;
725
 
      }
726
 
      if (suffix(RV,"eria")) {
727
 
        CT = removeSuffix(CT,"eria") ; return true;
728
 
      }
729
 
      if (suffix(RV,"iria")) {
730
 
        CT = removeSuffix(CT,"iria") ; return true;
731
 
      }
732
 
      if (suffix(RV,"asse")) {
733
 
        CT = removeSuffix(CT,"asse") ; return true;
734
 
      }
735
 
      if (suffix(RV,"esse")) {
736
 
        CT = removeSuffix(CT,"esse") ; return true;
737
 
      }
738
 
      if (suffix(RV,"isse")) {
739
 
        CT = removeSuffix(CT,"isse") ; return true;
740
 
      }
741
 
      if (suffix(RV,"aste")) {
742
 
        CT = removeSuffix(CT,"aste") ; return true;
743
 
      }
744
 
      if (suffix(RV,"este")) {
745
 
        CT = removeSuffix(CT,"este") ; return true;
746
 
      }
747
 
      if (suffix(RV,"iste")) {
748
 
        CT = removeSuffix(CT,"iste") ; return true;
749
 
      }
750
 
      if (suffix(RV,"arei")) {
751
 
        CT = removeSuffix(CT,"arei") ; return true;
752
 
      }
753
 
      if (suffix(RV,"erei")) {
754
 
        CT = removeSuffix(CT,"erei") ; return true;
755
 
      }
756
 
      if (suffix(RV,"irei")) {
757
 
        CT = removeSuffix(CT,"irei") ; return true;
758
 
      }
759
 
      if (suffix(RV,"aram")) {
760
 
        CT = removeSuffix(CT,"aram") ; return true;
761
 
      }
762
 
      if (suffix(RV,"eram")) {
763
 
        CT = removeSuffix(CT,"eram") ; return true;
764
 
      }
765
 
      if (suffix(RV,"iram")) {
766
 
        CT = removeSuffix(CT,"iram") ; return true;
767
 
      }
768
 
      if (suffix(RV,"avam")) {
769
 
        CT = removeSuffix(CT,"avam") ; return true;
770
 
      }
771
 
      if (suffix(RV,"arem")) {
772
 
        CT = removeSuffix(CT,"arem") ; return true;
773
 
      }
774
 
      if (suffix(RV,"erem")) {
775
 
        CT = removeSuffix(CT,"erem") ; return true;
776
 
      }
777
 
      if (suffix(RV,"irem")) {
778
 
        CT = removeSuffix(CT,"irem") ; return true;
779
 
      }
780
 
      if (suffix(RV,"ando")) {
781
 
        CT = removeSuffix(CT,"ando") ; return true;
782
 
      }
783
 
      if (suffix(RV,"endo")) {
784
 
        CT = removeSuffix(CT,"endo") ; return true;
785
 
      }
786
 
      if (suffix(RV,"indo")) {
787
 
        CT = removeSuffix(CT,"indo") ; return true;
788
 
      }
789
 
      if (suffix(RV,"arao")) {
790
 
        CT = removeSuffix(CT,"arao") ; return true;
791
 
      }
792
 
      if (suffix(RV,"erao")) {
793
 
        CT = removeSuffix(CT,"erao") ; return true;
794
 
      }
795
 
      if (suffix(RV,"irao")) {
796
 
        CT = removeSuffix(CT,"irao") ; return true;
797
 
      }
798
 
      if (suffix(RV,"adas")) {
799
 
        CT = removeSuffix(CT,"adas") ; return true;
800
 
      }
801
 
      if (suffix(RV,"idas")) {
802
 
        CT = removeSuffix(CT,"idas") ; return true;
803
 
      }
804
 
      if (suffix(RV,"aras")) {
805
 
        CT = removeSuffix(CT,"aras") ; return true;
806
 
      }
807
 
      if (suffix(RV,"eras")) {
808
 
        CT = removeSuffix(CT,"eras") ; return true;
809
 
      }
810
 
      if (suffix(RV,"iras")) {
811
 
        CT = removeSuffix(CT,"iras") ; return true;
812
 
      }
813
 
      if (suffix(RV,"avas")) {
814
 
        CT = removeSuffix(CT,"avas") ; return true;
815
 
      }
816
 
      if (suffix(RV,"ares")) {
817
 
        CT = removeSuffix(CT,"ares") ; return true;
818
 
      }
819
 
      if (suffix(RV,"eres")) {
820
 
        CT = removeSuffix(CT,"eres") ; return true;
821
 
      }
822
 
      if (suffix(RV,"ires")) {
823
 
        CT = removeSuffix(CT,"ires") ; return true;
824
 
      }
825
 
      if (suffix(RV,"ados")) {
826
 
        CT = removeSuffix(CT,"ados") ; return true;
827
 
      }
828
 
      if (suffix(RV,"idos")) {
829
 
        CT = removeSuffix(CT,"idos") ; return true;
830
 
      }
831
 
      if (suffix(RV,"amos")) {
832
 
        CT = removeSuffix(CT,"amos") ; return true;
833
 
      }
834
 
      if (suffix(RV,"emos")) {
835
 
        CT = removeSuffix(CT,"emos") ; return true;
836
 
      }
837
 
      if (suffix(RV,"imos")) {
838
 
        CT = removeSuffix(CT,"imos") ; return true;
839
 
      }
840
 
      if (suffix(RV,"iras")) {
841
 
        CT = removeSuffix(CT,"iras") ; return true;
842
 
      }
843
 
      if (suffix(RV,"ieis")) {
844
 
        CT = removeSuffix(CT,"ieis") ; return true;
845
 
      }
846
 
    }
847
 
 
848
 
    // suffix length = 3
849
 
    if (RV.length() >= 3) {
850
 
      if (suffix(RV,"ada")) {
851
 
        CT = removeSuffix(CT,"ada") ; return true;
852
 
      }
853
 
      if (suffix(RV,"ida")) {
854
 
        CT = removeSuffix(CT,"ida") ; return true;
855
 
      }
856
 
      if (suffix(RV,"ara")) {
857
 
        CT = removeSuffix(CT,"ara") ; return true;
858
 
      }
859
 
      if (suffix(RV,"era")) {
860
 
        CT = removeSuffix(CT,"era") ; return true;
861
 
      }
862
 
      if (suffix(RV,"ira")) {
863
 
        CT = removeSuffix(CT,"ava") ; return true;
864
 
      }
865
 
      if (suffix(RV,"iam")) {
866
 
        CT = removeSuffix(CT,"iam") ; return true;
867
 
      }
868
 
      if (suffix(RV,"ado")) {
869
 
        CT = removeSuffix(CT,"ado") ; return true;
870
 
      }
871
 
      if (suffix(RV,"ido")) {
872
 
        CT = removeSuffix(CT,"ido") ; return true;
873
 
      }
874
 
      if (suffix(RV,"ias")) {
875
 
        CT = removeSuffix(CT,"ias") ; return true;
876
 
      }
877
 
      if (suffix(RV,"ais")) {
878
 
        CT = removeSuffix(CT,"ais") ; return true;
879
 
      }
880
 
      if (suffix(RV,"eis")) {
881
 
        CT = removeSuffix(CT,"eis") ; return true;
882
 
      }
883
 
      if (suffix(RV,"ira")) {
884
 
        CT = removeSuffix(CT,"ira") ; return true;
885
 
      }
886
 
      if (suffix(RV,"ear")) {
887
 
        CT = removeSuffix(CT,"ear") ; return true;
888
 
      }
889
 
    }
890
 
 
891
 
    // suffix length = 2
892
 
    if (RV.length() >= 2) {
893
 
      if (suffix(RV,"ia")) {
894
 
        CT = removeSuffix(CT,"ia") ; return true;
895
 
      }
896
 
      if (suffix(RV,"ei")) {
897
 
        CT = removeSuffix(CT,"ei") ; return true;
898
 
      }
899
 
      if (suffix(RV,"am")) {
900
 
        CT = removeSuffix(CT,"am") ; return true;
901
 
      }
902
 
      if (suffix(RV,"em")) {
903
 
        CT = removeSuffix(CT,"em") ; return true;
904
 
      }
905
 
      if (suffix(RV,"ar")) {
906
 
        CT = removeSuffix(CT,"ar") ; return true;
907
 
      }
908
 
      if (suffix(RV,"er")) {
909
 
        CT = removeSuffix(CT,"er") ; return true;
910
 
      }
911
 
      if (suffix(RV,"ir")) {
912
 
        CT = removeSuffix(CT,"ir") ; return true;
913
 
      }
914
 
      if (suffix(RV,"as")) {
915
 
        CT = removeSuffix(CT,"as") ; return true;
916
 
      }
917
 
      if (suffix(RV,"es")) {
918
 
        CT = removeSuffix(CT,"es") ; return true;
919
 
      }
920
 
      if (suffix(RV,"is")) {
921
 
        CT = removeSuffix(CT,"is") ; return true;
922
 
      }
923
 
      if (suffix(RV,"eu")) {
924
 
        CT = removeSuffix(CT,"eu") ; return true;
925
 
      }
926
 
      if (suffix(RV,"iu")) {
927
 
        CT = removeSuffix(CT,"iu") ; return true;
928
 
      }
929
 
      if (suffix(RV,"iu")) {
930
 
        CT = removeSuffix(CT,"iu") ; return true;
931
 
      }
932
 
      if (suffix(RV,"ou")) {
933
 
        CT = removeSuffix(CT,"ou") ; return true;
934
 
      }
935
 
    }
936
 
 
937
 
    // no ending was removed by step2
938
 
    return false ;
939
 
  }
940
 
 
941
 
        /**
942
 
         * Delete suffix 'i' if in RV and preceded by 'c'
943
 
   *
944
 
        */
945
 
        private void step3() {
946
 
    if (RV == null) return ;
947
 
 
948
 
    if (suffix(RV,"i") && suffixPreceded(RV,"i","c")) {
949
 
      CT = removeSuffix(CT,"i") ;
950
 
    }
951
 
 
952
 
  }
953
 
 
954
 
        /**
955
 
         * Residual suffix
956
 
   *
957
 
   * If the word ends with one of the suffixes (os a i o á í ó)
958
 
   * in RV, delete it
959
 
   *
960
 
        */
961
 
        private void step4() {
962
 
    if (RV == null) return  ;
963
 
 
964
 
    if (suffix(RV,"os")) {
965
 
      CT = removeSuffix(CT,"os") ; return ;
966
 
    }
967
 
    if (suffix(RV,"a")) {
968
 
      CT = removeSuffix(CT,"a") ; return ;
969
 
    }
970
 
    if (suffix(RV,"i")) {
971
 
      CT = removeSuffix(CT,"i") ; return ;
972
 
    }
973
 
    if (suffix(RV,"o")) {
974
 
      CT = removeSuffix(CT,"o") ; return ;
975
 
    }
976
 
 
977
 
  }
978
 
 
979
 
        /**
980
 
         * If the word ends with one of ( e é ê) in RV,delete it,
981
 
   * and if preceded by 'gu' (or 'ci') with the 'u' (or 'i') in RV,
982
 
   * delete the 'u' (or 'i')
983
 
   *
984
 
   * Or if the word ends ç remove the cedilha
985
 
   *
986
 
        */
987
 
        private void step5() {
988
 
    if (RV == null) return  ;
989
 
 
990
 
    if (suffix(RV,"e")) {
991
 
      if (suffixPreceded(RV,"e","gu")) {
992
 
        CT = removeSuffix(CT,"e") ;
993
 
        CT = removeSuffix(CT,"u") ;
994
 
        return ;
995
 
      }
996
 
 
997
 
      if (suffixPreceded(RV,"e","ci")) {
998
 
        CT = removeSuffix(CT,"e") ;
999
 
        CT = removeSuffix(CT,"i") ;
1000
 
        return ;
1001
 
      }
1002
 
 
1003
 
      CT = removeSuffix(CT,"e") ; return ;
1004
 
    }
1005
 
  }
1006
 
 
1007
 
        /**
1008
 
         * For log and debug purpose
1009
 
         *
1010
 
         * @return  TERM, CT, RV, R1 and R2
1011
 
         */
1012
 
        public String log() {
1013
 
    return " (TERM = " + TERM + ")" +
1014
 
           " (CT = " + CT +")" +
1015
 
           " (RV = " + RV +")" +
1016
 
           " (R1 = " + R1 +")" +
1017
 
           " (R2 = " + R2 +")" ;
1018
 
        }
1019
 
 
1020
 
}
1021