lingo 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/.rspec +1 -0
  2. data/COPYING +663 -0
  3. data/ChangeLog +754 -0
  4. data/README +322 -0
  5. data/Rakefile +100 -0
  6. data/TODO +28 -0
  7. data/bin/lingo +5 -0
  8. data/bin/lingoctl +6 -0
  9. data/de.lang +121 -0
  10. data/de/lingo-abk.txt +74 -0
  11. data/de/lingo-dic.txt +56822 -0
  12. data/de/lingo-mul.txt +3209 -0
  13. data/de/lingo-syn.txt +14841 -0
  14. data/de/test_dic.txt +24 -0
  15. data/de/test_mul.txt +17 -0
  16. data/de/test_mul2.txt +2 -0
  17. data/de/test_singleword.txt +2 -0
  18. data/de/test_syn.txt +4 -0
  19. data/de/test_syn2.txt +1 -0
  20. data/de/user-dic.txt +10 -0
  21. data/en.lang +113 -0
  22. data/en/lingo-dic.txt +55434 -0
  23. data/en/lingo-mul.txt +456 -0
  24. data/en/user-dic.txt +5 -0
  25. data/info/Objekte.png +0 -0
  26. data/info/Typen.png +0 -0
  27. data/info/database.png +0 -0
  28. data/info/db_small.png +0 -0
  29. data/info/download.png +0 -0
  30. data/info/gpl-hdr.txt +27 -0
  31. data/info/kerze.png +0 -0
  32. data/info/language.png +0 -0
  33. data/info/lingo.png +0 -0
  34. data/info/logo.png +0 -0
  35. data/info/meeting.png +0 -0
  36. data/info/types.png +0 -0
  37. data/lib/lingo.rb +321 -0
  38. data/lib/lingo/attendee/abbreviator.rb +119 -0
  39. data/lib/lingo/attendee/debugger.rb +111 -0
  40. data/lib/lingo/attendee/decomposer.rb +101 -0
  41. data/lib/lingo/attendee/dehyphenizer.rb +167 -0
  42. data/lib/lingo/attendee/multiworder.rb +301 -0
  43. data/lib/lingo/attendee/noneword_filter.rb +103 -0
  44. data/lib/lingo/attendee/objectfilter.rb +86 -0
  45. data/lib/lingo/attendee/sequencer.rb +190 -0
  46. data/lib/lingo/attendee/synonymer.rb +105 -0
  47. data/lib/lingo/attendee/textreader.rb +237 -0
  48. data/lib/lingo/attendee/textwriter.rb +196 -0
  49. data/lib/lingo/attendee/tokenizer.rb +218 -0
  50. data/lib/lingo/attendee/variator.rb +185 -0
  51. data/lib/lingo/attendee/vector_filter.rb +158 -0
  52. data/lib/lingo/attendee/wordsearcher.rb +96 -0
  53. data/lib/lingo/attendees.rb +289 -0
  54. data/lib/lingo/cli.rb +62 -0
  55. data/lib/lingo/config.rb +104 -0
  56. data/lib/lingo/const.rb +131 -0
  57. data/lib/lingo/ctl.rb +173 -0
  58. data/lib/lingo/database.rb +587 -0
  59. data/lib/lingo/language.rb +530 -0
  60. data/lib/lingo/modules.rb +98 -0
  61. data/lib/lingo/types.rb +285 -0
  62. data/lib/lingo/utilities.rb +40 -0
  63. data/lib/lingo/version.rb +27 -0
  64. data/lingo-all.cfg +85 -0
  65. data/lingo-call.cfg +15 -0
  66. data/lingo.cfg +78 -0
  67. data/lingo.rb +3 -0
  68. data/lir.cfg +72 -0
  69. data/porter/stem.cfg +311 -0
  70. data/porter/stem.rb +150 -0
  71. data/spec/spec_helper.rb +0 -0
  72. data/test.cfg +79 -0
  73. data/test/attendee/ts_abbreviator.rb +35 -0
  74. data/test/attendee/ts_decomposer.rb +31 -0
  75. data/test/attendee/ts_multiworder.rb +390 -0
  76. data/test/attendee/ts_noneword_filter.rb +19 -0
  77. data/test/attendee/ts_objectfilter.rb +19 -0
  78. data/test/attendee/ts_sequencer.rb +43 -0
  79. data/test/attendee/ts_synonymer.rb +33 -0
  80. data/test/attendee/ts_textreader.rb +58 -0
  81. data/test/attendee/ts_textwriter.rb +98 -0
  82. data/test/attendee/ts_tokenizer.rb +32 -0
  83. data/test/attendee/ts_variator.rb +24 -0
  84. data/test/attendee/ts_vector_filter.rb +62 -0
  85. data/test/attendee/ts_wordsearcher.rb +119 -0
  86. data/test/lir.csv +3 -0
  87. data/test/lir.txt +12 -0
  88. data/test/lir2.txt +12 -0
  89. data/test/mul.txt +1 -0
  90. data/test/ref/artikel.mul +1 -0
  91. data/test/ref/artikel.non +159 -0
  92. data/test/ref/artikel.seq +270 -0
  93. data/test/ref/artikel.syn +16 -0
  94. data/test/ref/artikel.vec +928 -0
  95. data/test/ref/artikel.ven +928 -0
  96. data/test/ref/artikel.ver +928 -0
  97. data/test/ref/lir.csv +328 -0
  98. data/test/ref/lir.mul +1 -0
  99. data/test/ref/lir.non +274 -0
  100. data/test/ref/lir.seq +249 -0
  101. data/test/ref/lir.syn +94 -0
  102. data/test/test_helper.rb +113 -0
  103. data/test/ts_database.rb +269 -0
  104. data/test/ts_language.rb +396 -0
  105. data/txt/artikel-en.txt +157 -0
  106. data/txt/artikel.txt +170 -0
  107. data/txt/lir.txt +1317 -0
  108. metadata +211 -0
data/porter/stem.rb ADDED
@@ -0,0 +1,150 @@
1
+ # encoding: utf-8
2
+
3
+ require "yaml"
4
+ class String
5
+ def to_shadow
6
+ shadow = self.gsub(/[^aeiouy]/, 'c')
7
+ shadow.gsub!(/[aeiou]/, 'v')
8
+ shadow.gsub!(/cy/, 'cv')
9
+ shadow.gsub!(/y/, 'c')
10
+ shadow
11
+ end
12
+ end
13
+
14
+
15
+
16
+ # => condition nil oder eine evaluierbare regel
17
+ # => matchExp eine Regexp
18
+ # => replacement ist downcase
19
+ # => return new stem or nil, if rule didn't match
20
+ def checkSingleRule(word, condition, matchExp, replacement)
21
+
22
+ # => check for matching rule
23
+ return nil unless matchExp.match(word)
24
+
25
+ # => remember stem
26
+ stem = $1
27
+
28
+ # => check condition for rule
29
+ unless condition.nil?
30
+ evalCondition = condition.dup
31
+
32
+ stemShadow = stem.to_shadow
33
+
34
+ unless condition.index("m").nil?
35
+ m = stemShadow.squeeze.scan(/vc/).size
36
+ evalCondition.gsub!(/m/, m.to_s)
37
+ end
38
+
39
+ unless condition.index("*v*").nil?
40
+ evalCondition.gsub!(/\*v\*/, stemShadow.index("v").nil? ? "false" : "true")
41
+ end
42
+
43
+ unless condition.index("*d").nil?
44
+ evalCondition.gsub!(/\*d/, (stemShadow[-1..-1]=="c" && stem[-1]==stem[-2]) ? "true" : "false")
45
+ end
46
+
47
+ unless condition.index("*o").nil?
48
+ bool = /cvc$/.match(stemShadow) && "wxy".index(stemShadow[-1..-1]).nil?
49
+ evalCondition.gsub!(/\*o/, bool ? "true" : "false")
50
+ end
51
+
52
+ while /\*(\w)/.match(evalCondition)
53
+ char = $1
54
+ if char.downcase == char
55
+ abort "unbekannter Buchstabe %s in Regel: %" % [char, condition]
56
+ end
57
+
58
+ bool = (stem[-1..-1].upcase == char)
59
+ evalCondition.gsub!(Regexp.new(Regexp.escape("*#{char}")), bool ? "true" : "false")
60
+ end
61
+
62
+ evalCondition.gsub!(/and/, '&&')
63
+ evalCondition.gsub!(/or/, '||')
64
+ evalCondition.gsub!(/not/, '!')
65
+ evalCondition.gsub!(/=/, '==')
66
+ p evalCondition
67
+ return unless eval(evalCondition)
68
+ end
69
+
70
+ # => stem with replacement
71
+ if /^(-\d+)$/.match(replacement)
72
+ # => delete last characters from stem, if replacement looks like '-1' oder '-2'
73
+ stem[0...($1.to_i)]
74
+ else
75
+ # => append replacement to stem
76
+ stem + replacement
77
+ end
78
+
79
+ end
80
+
81
+ def checkAllRules(word, rules)
82
+ sequence = rules.keys.sort.reverse
83
+
84
+ actualRuleSet = sequence.pop.to_s
85
+
86
+ begin
87
+ label = nil
88
+
89
+ rules[actualRuleSet].each do |rule|
90
+ unless /^(\(.+\)){0,1}\s*(\S*)\s*->\s*(\S*?)\s*(?:goto\((\S+)\))*\s*$/.match(rule)
91
+ unless /^\s*goto\s*\(\s*(\S+)\s*\)$/.match(rule)
92
+ abort "ungültige Regel: %s" % rule
93
+ else
94
+ label = $1
95
+ break
96
+ end
97
+ end
98
+
99
+ condition, ending, replacement, label = $1, $2.downcase, $3.downcase, $4
100
+ p [rule, word, condition, ending, replacement, label ]
101
+ result = checkSingleRule(word, condition, Regexp.new("(.+)#{ending}$"), replacement)
102
+
103
+ unless result.nil?
104
+ p [word, actualRuleSet, rule]
105
+ word = result
106
+ break
107
+ end
108
+ end
109
+
110
+ if label.nil?
111
+ actualRuleSet = sequence.pop.to_s
112
+ else
113
+ while label != actualRuleSet && !actualRuleSet.nil?
114
+ actualRuleSet = sequence.pop.to_s
115
+ end
116
+ end
117
+ end until actualRuleSet.empty?
118
+
119
+ word
120
+ end
121
+
122
+ stemmerConfig = YAML::load_file("stem.cfg")
123
+
124
+ $rules = stemmerConfig["stemmer"]
125
+
126
+ word = $*[0]
127
+ p checkAllRules(word, $rules)
128
+
129
+ def test(word, stem)
130
+ result = checkAllRules(word, $rules)
131
+ if stem != result
132
+ warn "Falsches Wort %s, Stem %s, Result %s" % [word, stem, result]
133
+ else
134
+ warn "Korrekt: Wort %s, Stem %s" % [word, stem]
135
+ end
136
+ end
137
+
138
+
139
+ #test("caresses", "caress")
140
+ #test("ponies", "poni")
141
+ #test("ties", "ti")
142
+ #test("caress", "caress")
143
+ #test("cats", "cat")
144
+
145
+ #test("feed", "feed")
146
+ #?test("agreed", "agree")
147
+ #test("plastered", "plaster")
148
+ #test("bled", "bled")
149
+ #test("motoring", "motor")
150
+ #test("sing", "sing")
File without changes
data/test.cfg ADDED
@@ -0,0 +1,79 @@
1
+ #
2
+ # Lingo-Konfiguration für den Test mit einer Textdatei
3
+ #
4
+ ---
5
+ meeting:
6
+
7
+ attendees:
8
+
9
+ ########################################
10
+ # Text bereitstellen
11
+ #
12
+
13
+ # Angegebene Datei zeilenweise einlesen und verarbeiten
14
+ - textreader: { files: '$(files)' }
15
+
16
+
17
+ ########################################
18
+ # Inhalte verarbeiten
19
+ #
20
+
21
+ # Zeile in einzelnen Sinnbestandteile (Token) zerlegen
22
+ - tokenizer: { }
23
+
24
+ # Abkürzungen erkennen und auflösen
25
+ # - abbreviator: { source: 'sys-abk' }
26
+
27
+ # Verbleibende Token im Wörterbuch suchen
28
+ - wordsearcher: { source: 'sys-dic', mode: 'first' }
29
+
30
+ # Nicht erkannte Wörter auf Kompositum testen
31
+ - decomposer: { source: 'sys-dic' }
32
+
33
+ # Mehrwortgruppen im Strom erkennen
34
+ - multiworder: { stopper: 'PUNC,OTHR', source: 'sys-mul' }
35
+
36
+ # Wortsequenzen anhand von Regeln identifizieren
37
+ - sequencer: { stopper: 'PUNC,OTHR' }
38
+
39
+ # Relationierungen einfügen
40
+ - synonymer: { skip: '?,t', source: 'sys-syn', out: syn }
41
+
42
+
43
+ ########################################
44
+ # Datenstrom anzeigen
45
+ #
46
+ - debugger: { eval: 'true', ceval: 'cmd!="EOL"', prompt: 'lex:) ' }
47
+
48
+
49
+ ########################################
50
+ # Ergebnisse ausgeben
51
+ #
52
+
53
+ # Erstelle Datei mit Endung .non für nicht erkannte Wörter
54
+ - noneword_filter: { in: syn }
55
+ - textwriter: { ext: non, sep: "\n" }
56
+
57
+ # Erstelle Datei mit Endung .vec für erkannte Indexterme
58
+ - vector_filter: { in: syn, lexicals: '^[ksavem]$', sort: 'term_abs' }
59
+ - textwriter: { ext: vec, sep: "\n" }
60
+
61
+ # Erstelle Datei mit Endung .vec für erkannte Indexterme mit absoluter Häufigkeit
62
+ - vector_filter: { in: syn, lexicals: '^[ksavem]$' }
63
+ - textwriter: { ext: ven, sep: "\n" }
64
+
65
+ # Erstelle Datei mit Endung .vec für erkannte Indexterme mit relativer Häufigkeit
66
+ - vector_filter: { in: syn, lexicals: '^[ksavem]$', sort: 'term_rel' }
67
+ - textwriter: { ext: ver, sep: "\n" }
68
+
69
+ # Erstelle Datei mit Endung .mul für erkannte Mehrwortgruppen
70
+ - vector_filter: { in: syn, lexicals: m }
71
+ - textwriter: { ext: mul, sep: "\n" }
72
+
73
+ # Erstelle Datei mit Endung .seq für erkannte Wortsequenzen
74
+ - vector_filter: { in: syn, lexicals: q, sort: 'term_abs' }
75
+ - textwriter: { ext: seq, sep: "\n" }
76
+
77
+ # Erstelle Datei mit Endung .syn für erkannte Synonyme
78
+ - vector_filter: { in: syn, lexicals: y, sort: 'term_abs' }
79
+ - textwriter: { ext: syn, sep: "\n" }
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../test_helper'
4
+
5
+ ################################################################################
6
+ #
7
+ # Attendee Abbreviator
8
+ #
9
+ class TestAttendeeAbbreviator < AttendeeTestCase
10
+
11
+ def test_basic
12
+ @input = [
13
+ tk('z.b|ABRV'), tk('.|PUNC'),
14
+ tk('im|WORD'),
15
+ tk('14.|NUMS'),
16
+ tk('bzw|WORD'), tk('.|PUNC'),
17
+ tk('15.|NUMS'),
18
+ tk('Jh|WORD'), tk('.|PUNC'),
19
+ ai('EOL|')
20
+ ]
21
+ @expect = [
22
+ wd('z.b.|IDF', 'zum beispiel|w'),
23
+ tk('im|WORD'),
24
+ tk('14.|NUMS'),
25
+ wd('bzw.|IDF', 'beziehungsweise|w'),
26
+ tk('15.|NUMS'),
27
+ wd('Jh.|IDF', 'jahrhundert|s'),
28
+ ai('EOL|')
29
+ ]
30
+ meet({'source'=>'sys-abk'})
31
+ end
32
+
33
+ end
34
+ #
35
+ ################################################################################
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../test_helper'
4
+
5
+ ################################################################################
6
+ #
7
+ # Attendee Decomposer
8
+ #
9
+ class TestAttendeeDecomposer < AttendeeTestCase
10
+
11
+ def test_basic
12
+ @input = [
13
+ wd('Kleinseite|?'),
14
+ wd('Arrafat-Nachfolger|?'),
15
+ wd('Afganistan-Reisen|?'),
16
+ wd('Kompositumzerlegung|?'),
17
+ wd('Kompositumzerlegung|?')
18
+ ]
19
+ @expect = [
20
+ wd('Kleinseite|KOM', 'kleinseite|k', 'klein|a+', 'seite|s+'),
21
+ wd('Arrafat-Nachfolger|KOM', 'arrafat-nachfolger|k', 'nachfolger|s+', 'arrafat|x+'),
22
+ wd('Afganistan-Reisen|KOM', 'afganistan-reise|k', 'reise|s+', 'reisen|v+', 'afganistan|x+'),
23
+ wd('Kompositumzerlegung|KOM', 'kompositumzerlegung|k', 'kompositum|s+', 'zerlegung|s+'),
24
+ wd('Kompositumzerlegung|KOM', 'kompositumzerlegung|k', 'kompositum|s+', 'zerlegung|s+')
25
+ ]
26
+ meet({'source'=>'sys-dic'})
27
+ end
28
+
29
+ end
30
+ #
31
+ ################################################################################
@@ -0,0 +1,390 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../test_helper'
4
+
5
+ ################################################################################
6
+ #
7
+ # Attendee Multiworder
8
+ #
9
+ class TestAttendeeMultiworder < AttendeeTestCase
10
+
11
+ def test_basic
12
+ @input = [
13
+ ai('FILE|mul.txt'),
14
+ # John_F_._Kennedy
15
+ wd('John|IDF', 'john|e'), wd('F|?'), tk('.|PUNC'), wd('Kennedy|IDF', 'kennedy|e'),
16
+ # John_F_Kennedy
17
+ wd('John|IDF', 'john|e'), wd('F|?'), wd('Kennedy|IDF', 'kennedy|e'),
18
+ # John_F_Kennedy_.
19
+ wd('John|IDF', 'john|e'), wd('F|?'), wd('Kennedy|IDF', 'kennedy|e'), tk('.|PUNC'),
20
+ # a_priori
21
+ wd('a|?'), wd('priori|IDF', 'priori|w'),
22
+ # Ableitung_nicht_ganzzahliger_Ordnung
23
+ wd('Ableitung|IDF', 'ableitung|s'),
24
+ wd('nicht|IDF', 'nicht|w'),
25
+ wd('ganzzahliger|IDF', 'ganzzahlig|a'),
26
+ wd('Ordnung|IDF', 'ordnung|s'),
27
+ # Academic_learning_time_in_physical_education
28
+ wd('academic|?'), wd('learning|?'), wd('time|IDF', 'timen|v'),
29
+ wd('in|IDF', 'in|t'), wd('physical|?'), wd('education|?'),
30
+ # Satzende
31
+ tk('.|PUNC'),
32
+ ai('EOF|mul.txt')
33
+ ]
34
+ @expect = [
35
+ ai('FILE|mul.txt'),
36
+ # John_F_._Kennedy
37
+ wd('John F. Kennedy|MUL', 'john f. kennedy|m'),
38
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
39
+ # John_F_Kennedy
40
+ wd('John F Kennedy|MUL', 'john f. kennedy|m'),
41
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
42
+ # John_F_Kennedy_.
43
+ wd('John F Kennedy|MUL', 'john f. kennedy|m'),
44
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
45
+ tk('.|PUNC'),
46
+ # a_priori
47
+ wd('a priori|MUL', 'a priori|m'),
48
+ wd('a|MU?'), wd('priori|IDF', 'priori|w'),
49
+ # Ableitung_nicht_ganzzahliger_Ordnung
50
+ wd('Ableitung nicht ganzzahliger Ordnung|MUL', 'ableitung nicht ganzzahliger ordnung|m'),
51
+ wd('Ableitung|IDF', 'ableitung|s'),
52
+ wd('nicht|IDF', 'nicht|w'),
53
+ wd('ganzzahliger|IDF', 'ganzzahlig|a'),
54
+ wd('Ordnung|IDF', 'ordnung|s'),
55
+ # Academic_learning_time_in_physical_education
56
+ wd('academic learning time in physical education|MUL', 'academic learning time in physical education|m'),
57
+ wd('academic|MU?'), wd('learning|MU?'), wd('time|IDF', 'timen|v'),
58
+ wd('in|IDF', 'in|t'), wd('physical|MU?'), wd('education|MU?'),
59
+ # Satzende
60
+ tk('.|PUNC'),
61
+ ai('EOF|mul.txt')
62
+ ]
63
+ meet({'source'=>'tst-mul'})
64
+ end
65
+
66
+ def test_multiple_prefix
67
+ @input = [
68
+ ai('FILE|mul.txt'),
69
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
70
+ ai('EOF|mul.txt')
71
+ ]
72
+ @expect = [
73
+ ai('FILE|mul.txt'),
74
+ wd('Abelsches Schema|MUL', 'abelsches schema|m'),
75
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
76
+ ai('EOF|mul.txt')
77
+ ]
78
+ meet({'source'=>'tst-mul'})
79
+
80
+ @input = [
81
+ ai('FILE|mul.txt'),
82
+ wd('Tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
83
+ ai('EOF|mul.txt')
84
+ ]
85
+ @expect = [
86
+ ai('FILE|mul.txt'),
87
+ wd('Tolles abelsches Schema|MUL', 'tolles abelsches schema|m'),
88
+ wd('Tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
89
+ ai('EOF|mul.txt')
90
+ ]
91
+ meet({'source'=>'tst-mul'})
92
+
93
+ @input = [
94
+ ai('FILE|mul.txt'),
95
+ wd('Super|IDF', 'super|a'), wd('tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
96
+ ai('EOF|mul.txt')
97
+ ]
98
+ @expect = [
99
+ ai('FILE|mul.txt'),
100
+ wd('Super tolles abelsches Schema|MUL', 'super tolles abelsches schema|m'),
101
+ wd('Super|IDF', 'super|a'), wd('tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
102
+ ai('EOF|mul.txt')
103
+ ]
104
+ meet({'source'=>'tst-mul'})
105
+
106
+ @input = [
107
+ ai('FILE|mul.txt'),
108
+ wd('Extra|IDF', 'extra|a'), wd('super|IDF', 'super|a'), wd('tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
109
+ ai('EOF|mul.txt')
110
+ ]
111
+ @expect = [
112
+ ai('FILE|mul.txt'),
113
+ wd('Extra super tolles abelsches Schema|MUL', 'extra super tolles abelsches schema|m'),
114
+ wd('Extra|IDF', 'extra|a'), wd('super|IDF', 'super|a'), wd('tolles|IDF', 'toll|a'), wd('abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
115
+ ai('EOF|mul.txt')
116
+ ]
117
+ meet({'source'=>'tst-mul'})
118
+ end
119
+
120
+ def test_multiple_suffix
121
+ @input = [
122
+ ai('FILE|mul.txt'),
123
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
124
+ ai('EOF|mul.txt')
125
+ ]
126
+ @expect = [
127
+ ai('FILE|mul.txt'),
128
+ wd('Abelsches Schema|MUL', 'abelsches schema|m'),
129
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), tk('.|PUNC'),
130
+ ai('EOF|mul.txt')
131
+ ]
132
+ meet({'source'=>'tst-mul'})
133
+
134
+ @input = [
135
+ ai('FILE|mul.txt'),
136
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), tk('.|PUNC'),
137
+ ai('EOF|mul.txt')
138
+ ]
139
+ @expect = [
140
+ ai('FILE|mul.txt'),
141
+ wd('Abelsches Schema toll|MUL', 'abelsches schema toll|m'),
142
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), tk('.|PUNC'),
143
+ ai('EOF|mul.txt')
144
+ ]
145
+ meet({'source'=>'tst-mul'})
146
+
147
+ @input = [
148
+ ai('FILE|mul.txt'),
149
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), wd('super|IDF', 'super|a'), tk('.|PUNC'),
150
+ ai('EOF|mul.txt')
151
+ ]
152
+ @expect = [
153
+ ai('FILE|mul.txt'),
154
+ wd('Abelsches Schema toll super|MUL', 'abelsches schema toll super|m'),
155
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), wd('super|IDF', 'super|a'), tk('.|PUNC'),
156
+ ai('EOF|mul.txt')
157
+ ]
158
+ meet({'source'=>'tst-mul'})
159
+
160
+ @input = [
161
+ ai('FILE|mul.txt'),
162
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), wd('super|IDF', 'super|a'), wd('extra|IDF', 'extra|a'), tk('.|PUNC'),
163
+ ai('EOF|mul.txt')
164
+ ]
165
+ @expect = [
166
+ ai('FILE|mul.txt'),
167
+ wd('Abelsches Schema toll super extra|MUL', 'abelsches schema toll super extra|m'),
168
+ wd('Abelsches|IDF', 'abelsch|a'), wd('Schema|IDF', 'schema|s'), wd('toll|IDF', 'toll|a'), wd('super|IDF', 'super|a'), wd('extra|IDF', 'extra|a'), tk('.|PUNC'),
169
+ ai('EOF|mul.txt')
170
+ ]
171
+ meet({'source'=>'tst-mul'})
172
+ end
173
+
174
+ def test_ending_count
175
+ @input = [
176
+ ai('FILE|mul.txt'),
177
+ wd('John|IDF', 'john|e'), wd('F|?'), tk('.|PUNC'), wd('Kennedy|IDF', 'kennedy|e'),
178
+ wd('war|IDF', 'war|w'), wd('einmal|IDF', 'einmal|w'), wd('Präsident|IDF', 'präsident|s'), tk('.|PUNC'),
179
+ ai('EOF|mul.txt')
180
+ ]
181
+ @expect = [
182
+ ai('FILE|mul.txt'),
183
+ wd('John F. Kennedy|MUL', 'john f. kennedy|m'),
184
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
185
+ wd('war|IDF', 'war|w'), wd('einmal|IDF', 'einmal|w'), wd('Präsident|IDF', 'präsident|s'), tk('.|PUNC'),
186
+ ai('EOF|mul.txt')
187
+ ]
188
+ meet({'source'=>'tst-mul'})
189
+
190
+ #
191
+ @input.delete_at(-3)
192
+ @expect = [
193
+ ai('FILE|mul.txt'),
194
+ wd('John F. Kennedy|MUL', 'john f. kennedy|m'),
195
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
196
+ wd('war|IDF', 'war|w'), wd('einmal|IDF', 'einmal|w'), tk('.|PUNC'),
197
+ ai('EOF|mul.txt')
198
+ ]
199
+ meet({'source'=>'tst-mul'})
200
+
201
+ #
202
+ @input.delete_at(-3)
203
+ @expect = [
204
+ ai('FILE|mul.txt'),
205
+ wd('John F. Kennedy|MUL', 'john f. kennedy|m'),
206
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
207
+ wd('war|IDF', 'war|w'), tk('.|PUNC'),
208
+ ai('EOF|mul.txt')
209
+ ]
210
+ meet({'source'=>'tst-mul'})
211
+
212
+ #
213
+ @input.delete_at(-3)
214
+ @expect = [
215
+ ai('FILE|mul.txt'),
216
+ wd('John F. Kennedy|MUL', 'john f. kennedy|m'),
217
+ wd('John|IDF', 'john|e'), wd('F|MU?'), wd('Kennedy|IDF', 'kennedy|e'),
218
+ tk('.|PUNC'),
219
+ ai('EOF|mul.txt')
220
+ ]
221
+ meet({'source'=>'tst-mul'})
222
+ end
223
+
224
+ def test_two_sources_mode_first
225
+ # in keinen WB enthalten
226
+ @input = [
227
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
228
+ ]
229
+ @expect = [
230
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
231
+ ]
232
+ meet({'source'=>'tst-mul,tst-mu2', 'mode'=>'first'})
233
+
234
+ # im ersten WB enthalten
235
+ @input = [
236
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
237
+ ]
238
+ @expect = [
239
+ wd('abstrakten Kunst|MUL', 'abstrakte kunst|m'),
240
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
241
+ ]
242
+ meet({'source'=>'tst-mul,tst-mu2', 'mode'=>'first'})
243
+
244
+ # im zweiten WB enthalten
245
+ @input = [
246
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
247
+ ]
248
+ @expect = [
249
+ wd('traumatischer Angelegenheit|MUL', 'traumatische angelegenheit|m'),
250
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
251
+ ]
252
+ meet({'source'=>'tst-mul,tst-mu2', 'mode'=>'first'})
253
+
254
+ # in beiden WB enthalten
255
+ @input = [
256
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
257
+ ]
258
+ @expect = [
259
+ wd('azyklischen Bewegungen|MUL', 'chaotisches movement|m'),
260
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
261
+ ]
262
+ meet({'source'=>'tst-mul,tst-mu2', 'mode'=>'first'})
263
+ end
264
+
265
+ def test_two_sources_mode_first_flipped
266
+ # in keinen WB enthalten
267
+ @input = [
268
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
269
+ ]
270
+ @expect = [
271
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
272
+ ]
273
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'first'})
274
+
275
+ # im ersten WB enthalten
276
+ @input = [
277
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
278
+ ]
279
+ @expect = [
280
+ wd('abstrakten Kunst|MUL', 'abstrakte kunst|m'),
281
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
282
+ ]
283
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'first'})
284
+
285
+ # im zweiten WB enthalten
286
+ @input = [
287
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
288
+ ]
289
+ @expect = [
290
+ wd('traumatischer Angelegenheit|MUL', 'traumatische angelegenheit|m'),
291
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
292
+ ]
293
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'first'})
294
+
295
+ # in beiden WB enthalten
296
+ @input = [
297
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
298
+ ]
299
+ @expect = [
300
+ wd('azyklischen Bewegungen|MUL', 'azyklische bewegung|m'),
301
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
302
+ ]
303
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'first'})
304
+ end
305
+
306
+ def test_select_two_sources_mode_all
307
+ # in keinen WB enthalten
308
+ @input = [
309
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
310
+ ]
311
+ @expect = [
312
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
313
+ ]
314
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'all'})
315
+
316
+ # im ersten WB enthalten
317
+ @input = [
318
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
319
+ ]
320
+ @expect = [
321
+ wd('abstrakten Kunst|MUL', 'abstrakte kunst|m'),
322
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
323
+ ]
324
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'all'})
325
+
326
+ # im zweiten WB enthalten
327
+ @input = [
328
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
329
+ ]
330
+ @expect = [
331
+ wd('traumatischer Angelegenheit|MUL', 'traumatische angelegenheit|m'),
332
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
333
+ ]
334
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'all'})
335
+
336
+ # in beiden WB enthalten
337
+ @input = [
338
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
339
+ ]
340
+ @expect = [
341
+ wd('azyklischen Bewegungen|MUL', 'azyklische bewegung|m', 'chaotisches movement|m'),
342
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
343
+ ]
344
+ meet({'source'=>'tst-mu2,tst-mul', 'mode'=>'all'})
345
+ end
346
+
347
+ def test_select_two_sources_mode_def
348
+ # in keinen WB enthalten
349
+ @input = [
350
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
351
+ ]
352
+ @expect = [
353
+ wd('intelligente|IDF', 'intelligent|a'), wd('Indexierung|IDF', 'indexierung|s'), ai('EOF|mul.txt')
354
+ ]
355
+ meet({'source'=>'tst-mu2,tst-mul'})
356
+
357
+ # im ersten WB enthalten
358
+ @input = [
359
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
360
+ ]
361
+ @expect = [
362
+ wd('abstrakten Kunst|MUL', 'abstrakte kunst|m'),
363
+ wd('abstrakten|IDF', 'abstrakt|a'), wd('Kunst|IDF', 'kunst|s'), ai('EOF|mul.txt')
364
+ ]
365
+ meet({'source'=>'tst-mu2,tst-mul'})
366
+
367
+ # im zweiten WB enthalten
368
+ @input = [
369
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
370
+ ]
371
+ @expect = [
372
+ wd('traumatischer Angelegenheit|MUL', 'traumatische angelegenheit|m'),
373
+ wd('traumatischer|IDF', 'traumatisch|a'), wd('Angelegenheit|IDF', 'angelegenheit|s'), ai('EOF|mul.txt')
374
+ ]
375
+ meet({'source'=>'tst-mu2,tst-mul'})
376
+
377
+ # in beiden WB enthalten
378
+ @input = [
379
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
380
+ ]
381
+ @expect = [
382
+ wd('azyklischen Bewegungen|MUL', 'azyklische bewegung|m', 'chaotisches movement|m'),
383
+ wd('azyklischen|IDF', 'azyklisch|a'), wd('Bewegungen|IDF', 'bewegung|s'), ai('EOF|mul.txt')
384
+ ]
385
+ meet({'source'=>'tst-mu2,tst-mul'})
386
+ end
387
+
388
+ end
389
+ #
390
+ ################################################################################