mittens 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/lib/mittens/version.rb +1 -1
  6. data/vendor/snowball/.github/workflows/ci.yml +43 -3
  7. data/vendor/snowball/.github/workflows/coverage.yml +8 -5
  8. data/vendor/snowball/GNUmakefile +46 -16
  9. data/vendor/snowball/NEWS +437 -13
  10. data/vendor/snowball/README.rst +4 -4
  11. data/vendor/snowball/algorithms/earlymodernenglish.sbl +301 -0
  12. data/vendor/snowball/algorithms/french.sbl +1 -1
  13. data/vendor/snowball/algorithms/ukrainian.sbl +1251 -0
  14. data/vendor/snowball/compiler/analyser.c +460 -156
  15. data/vendor/snowball/compiler/driver.c +41 -36
  16. data/vendor/snowball/compiler/generator.c +24 -1
  17. data/vendor/snowball/compiler/generator_ada.c +46 -45
  18. data/vendor/snowball/compiler/generator_c.c +1094 -187
  19. data/vendor/snowball/compiler/generator_csharp.c +34 -11
  20. data/vendor/snowball/compiler/generator_dart.c +39 -11
  21. data/vendor/snowball/compiler/generator_go.c +6 -6
  22. data/vendor/snowball/compiler/generator_java.c +29 -8
  23. data/vendor/snowball/compiler/generator_js.c +65 -38
  24. data/vendor/snowball/compiler/generator_pascal.c +69 -26
  25. data/vendor/snowball/compiler/generator_php.c +33 -12
  26. data/vendor/snowball/compiler/generator_python.c +23 -4
  27. data/vendor/snowball/compiler/generator_rust.c +37 -13
  28. data/vendor/snowball/compiler/generator_zig.c +6 -6
  29. data/vendor/snowball/compiler/header.h +85 -14
  30. data/vendor/snowball/compiler/space.c +67 -38
  31. data/vendor/snowball/compiler/tokeniser.c +28 -16
  32. data/vendor/snowball/csharp/Snowball/AssemblyInfo.cs +2 -2
  33. data/vendor/snowball/csharp/Snowball/Stemmer.cs +1 -4
  34. data/vendor/snowball/cxx/generate_algorithms.pl +5 -4
  35. data/vendor/snowball/cxx/{utilities.cxx → snowball_runtime.cxx} +1 -1
  36. data/vendor/snowball/cxx/stemmer.h +4 -0
  37. data/vendor/snowball/cxx/stemwords.cxx +36 -6
  38. data/vendor/snowball/dart/lib/src/snowball.dart +2 -2
  39. data/vendor/snowball/dart/pubspec.yaml +1 -1
  40. data/vendor/snowball/doc/libstemmer_c_README +3 -0
  41. data/vendor/snowball/doc/libstemmer_php_README +1 -1
  42. data/vendor/snowball/doc/libstemmer_python_README +8 -6
  43. data/vendor/snowball/examples/stemwords.c +4 -14
  44. data/vendor/snowball/go/env.go +16 -4
  45. data/vendor/snowball/include/libstemmer.h +0 -3
  46. data/vendor/snowball/java/org/tartarus/snowball/SnowballProgram.java +4 -4
  47. data/vendor/snowball/javascript/base-stemmer.js +27 -40
  48. data/vendor/snowball/javascript/stemwords.js +34 -10
  49. data/vendor/snowball/libstemmer/libstemmer_c.in +5 -5
  50. data/vendor/snowball/libstemmer/mkmodules.pl +5 -3
  51. data/vendor/snowball/libstemmer/modules.txt +4 -2
  52. data/vendor/snowball/pascal/SnowballProgram.pas +2 -2
  53. data/vendor/snowball/php/base-stemmer.php +2 -2
  54. data/vendor/snowball/python/setup.py +5 -1
  55. data/vendor/snowball/python/snowballstemmer/basestemmer.py +1 -2
  56. data/vendor/snowball/runtime/api.c +14 -3
  57. data/vendor/snowball/runtime/api.h +13 -9
  58. data/vendor/snowball/runtime/{utilities.c → snowball_runtime.c} +115 -181
  59. data/vendor/snowball/runtime/snowball_runtime.h +35 -24
  60. data/vendor/snowball/rust/src/snowball/snowball_env.rs +1 -1
  61. data/vendor/snowball/tests/compilertest +3 -3
  62. data/vendor/snowball/tests/runtime/among.sbl +96 -2
  63. data/vendor/snowball/tests/runtime/attachinsert.sbl +4 -0
  64. data/vendor/snowball/tests/runtime/debug.out +7 -0
  65. data/vendor/snowball/tests/runtime/debug.sbl +9 -0
  66. data/vendor/snowball/tests/runtime/integertests.sbl +22 -0
  67. data/vendor/snowball/tests/runtime/marklimit.sbl +30 -0
  68. data/vendor/snowball/tests/runtime/naming.sbl +20 -0
  69. data/vendor/snowball/tests/runtime/reverse.sbl +11 -0
  70. data/vendor/snowball/tests/stemtest.c +2 -5
  71. data/vendor/snowball/tests/syntax/aeslicefrom.sbl +7 -0
  72. data/vendor/snowball/tests/syntax/canon.sbl +14 -0
  73. data/vendor/snowball/tests/syntax/canon.syntax +36 -0
  74. data/vendor/snowball/tests/syntax/inline.syntax +4 -4
  75. data/vendor/snowball/tests/syntax/localvar.sbl +38 -0
  76. data/vendor/snowball/tests/syntax/localvar.stderr +3 -0
  77. data/vendor/snowball/tests/syntax/localvar.syntax +76 -0
  78. data/vendor/snowball/tests/syntax/unused.sbl +5 -1
  79. data/vendor/snowball/tests/syntax/unused.stderr +3 -1
  80. data/vendor/snowball/zig/env.zig +24 -4
  81. metadata +14 -4
@@ -0,0 +1,1251 @@
1
+ stringescapes {}
2
+
3
+ /* Ukrainian stemmer for Snowball
4
+ * Based on Ukrainian morphology analysis and dictionary research
5
+ *
6
+ * Primary source: "Словник мовних покручів" by Олекса Тихий (1964-1977)
7
+ * Additional analysis: Ukrainian morphology notes (internal)
8
+ *
9
+ * Key features:
10
+ * - Professional suffixes: -ар/-ник/-ач (каменяр, копач)
11
+ * - Verbal nouns: -ання/-яння/-іння (калякання, мурликання)
12
+ * - Rich diminutives: -еня/-атко (козеня, лисеня) + standard forms
13
+ * - Derivational: -ство/-ниця (козацтво, годувальниця)
14
+ * - Full noun/adjective/verb declension support
15
+ *
16
+ * Covers: nouns, adjectives, verbs, diminutives, verbal nouns, reflexives
17
+ */
18
+
19
+ stringdef a '{U+0430}'
20
+ stringdef b '{U+0431}'
21
+ stringdef v '{U+0432}'
22
+ stringdef h '{U+0433}' // г
23
+ stringdef g '{U+0491}' // ґ - Ukrainian specific
24
+ stringdef d '{U+0434}'
25
+ stringdef e '{U+0435}'
26
+ stringdef ie '{U+0454}' // є - Ukrainian specific
27
+ stringdef zh '{U+0436}'
28
+ stringdef z '{U+0437}'
29
+ stringdef y '{U+0438}' // и (not ы like in Russian)
30
+ stringdef i '{U+0456}' // і - Ukrainian specific
31
+ stringdef yi '{U+0457}' // ї - Ukrainian specific
32
+ stringdef i` '{U+0439}' // й
33
+ stringdef k '{U+043A}'
34
+ stringdef l '{U+043B}'
35
+ stringdef m '{U+043C}'
36
+ stringdef n '{U+043D}'
37
+ stringdef o '{U+043E}'
38
+ stringdef p '{U+043F}'
39
+ stringdef r '{U+0440}'
40
+ stringdef s '{U+0441}'
41
+ stringdef t '{U+0442}'
42
+ stringdef u '{U+0443}'
43
+ stringdef f '{U+0444}'
44
+ stringdef kh '{U+0445}'
45
+ stringdef ts '{U+0446}'
46
+ stringdef ch '{U+0447}'
47
+ stringdef sh '{U+0448}'
48
+ stringdef shch '{U+0449}'
49
+ stringdef ' '{U+044C}' // м'який знак (soft sign)
50
+ stringdef ap '{U+0027}' // apostrophe (п'ять, об'єкт)
51
+ stringdef iu '{U+044E}'
52
+ stringdef ia '{U+044F}'
53
+
54
+
55
+ routines ( mark_regions R2
56
+ perfective_gerund
57
+ reflexive_full
58
+ reflexive
59
+ adjective
60
+ verb
61
+ noun
62
+ professional
63
+ diminutive
64
+ diminutive_stem
65
+ verbal_noun
66
+ comparative
67
+ derivational
68
+ tidy_up
69
+ )
70
+
71
+ externals ( stem )
72
+
73
+ integers ( pV p2 )
74
+
75
+ booleans ( found_diminutive found_professional found_ia found_verb
76
+ found_la_noun found_ty_noun )
77
+
78
+ groupings ( v )
79
+
80
+ define v '{a}{e}{y}{i}{o}{u}{ie}{yi}{iu}{ia}'
81
+
82
+ define mark_regions as (
83
+ $pV = limit
84
+ $p2 = limit
85
+ do (
86
+ gopast v setmark pV gopast non-v
87
+ gopast v gopast non-v setmark p2
88
+ )
89
+ test (hop 3 do ($(pV < cursor) $pV = cursor))
90
+ )
91
+
92
+ backwardmode (
93
+
94
+ define R2 as $p2 <= cursor
95
+
96
+ define perfective_gerund as (
97
+ [substring] among (
98
+ // Perfective gerunds (дієприслівники доконаного виду)
99
+ // With {a}/{ia} prefix check
100
+ '{v}{sh}{y}'
101
+ '{v}{sh}{y}{s}{'}'
102
+ ('{a}' or '{ia}' delete)
103
+ // With {y} (и) - no prefix check needed (зробивши)
104
+ '{y}{v}{sh}{y}'
105
+ '{y}{v}{sh}{y}{s}{'}'
106
+ (delete)
107
+ // Present gerunds (дієприслівники недоконаного виду), removed
108
+ // with the thematic vowel so they meet the other verb forms:
109
+ // включаючи → включ (включати), виходячи → виход (виходити),
110
+ // розуміючи → розум (розуміти), кажучи → каж (кажуть)
111
+ '{a}{iu}{ch}{y}' '{ia}{iu}{ch}{y}' '{i}{iu}{ch}{y}'
112
+ '{u}{ch}{y}' '{ia}{ch}{y}' '{a}{ch}{y}'
113
+ (set found_verb delete)
114
+ // -уючи/-юючи → -ув/-юв, as the present tense of -увати verbs
115
+ // (використовуючи → використовув → використ)
116
+ '{u}{iu}{ch}{y}'
117
+ (set found_verb <- '{u}{v}')
118
+ '{iu}{iu}{ch}{y}'
119
+ (set found_verb <- '{iu}{v}')
120
+ )
121
+ )
122
+
123
+ // Present-tense reflexive endings: the whole ending goes and what is
124
+ // left is the verb root, so no further verb rule may run on it
125
+ // (залишається → залиш, not зал via -иш; називається → назив, not наз)
126
+ define reflexive_full as (
127
+ [substring] among (
128
+ '{a}{ie}{t}{'}{s}{ia}' // -ається (вважається, займається)
129
+ '{a}{iu}{t}{'}{s}{ia}' // -аються
130
+ '{ia}{ie}{t}{'}{s}{ia}' // -яється (розчиняється)
131
+ '{ia}{iu}{t}{'}{s}{ia}' // -яються
132
+ '{ie}{t}{'}{s}{ia}' // -ється (б'ється, дається)
133
+ '{e}{t}{'}{s}{ia}' // -еться (пишеться, береться, бореться)
134
+ '{y}{t}{'}{s}{ia}' // -иться (водиться, вводиться)
135
+ (delete)
136
+ // -ується/-уються → -ув: the stem meets the infinitive and past
137
+ // tense of -увати verbs (будується → будув = будувати)
138
+ '{u}{ie}{t}{'}{s}{ia}' '{u}{iu}{t}{'}{s}{ia}'
139
+ (<- '{u}{v}')
140
+ '{iu}{ie}{t}{'}{s}{ia}' '{iu}{iu}{t}{'}{s}{ia}'
141
+ (<- '{iu}{v}')
142
+ )
143
+ )
144
+
145
+ define reflexive as (
146
+ [substring] among (
147
+ // Reflexive endings that leave a verb form behind
148
+ '{t}{y}{s}{ia}' '{t}{y}{s}{'}' // -тися/-тись (infinitive reflexive)
149
+ '{l}{a}{s}{'}' // -лась (past fem reflexive)
150
+ '{v}{s}{ia}' '{v}{s}{'}' // -вся/-всь (past masc reflexive)
151
+ '{s}{ia}' '{s}{'}' // -ся/-сь (generic reflexive)
152
+ (delete)
153
+ )
154
+ )
155
+
156
+ define adjective as (
157
+ // Compound derivational+inflectional (R2-protected, split from standard endings
158
+ // so R2 failure falls through to standard adj rather than blocking it entirely)
159
+ (
160
+ [substring] among (
161
+ // -аційн- (інформаційний, організаційний)
162
+ '{a}{ts}{i}{i`}{n}{y}{m}{y}' // -аційними
163
+ '{a}{ts}{i}{i`}{n}{o}{h}{o}' // -аційного
164
+ '{a}{ts}{i}{i`}{n}{o}{m}{u}' // -аційному
165
+ '{a}{ts}{i}{i`}{n}{o}{iu}' // -аційною
166
+ '{a}{ts}{i}{i`}{n}{o}{yi}' // -аційної
167
+ '{a}{ts}{i}{i`}{n}{y}{kh}' // -аційних
168
+ '{a}{ts}{i}{i`}{n}{y}{m}' // -аційним
169
+ '{a}{ts}{i}{i`}{n}{y}{i`}' // -аційний
170
+ '{a}{ts}{i}{i`}{n}{i}{i`}' // -аційній
171
+ '{a}{ts}{i}{i`}{n}{a}' // -аційна
172
+ '{a}{ts}{i}{i`}{n}{e}' // -аційне
173
+ '{a}{ts}{i}{i`}{n}{i}' // -аційні
174
+ '{a}{ts}{i}{i`}{n}{o}' // -аційно (adverb)
175
+ '{a}{ts}{i}{i`}{n}{u}' // -аційну
176
+ '{a}{ts}{i}{i`}{n}{i}{s}{t}{'}' // -аційність
177
+ '{a}{ts}{i}{i`}{n}{o}{s}{t}{i}' // -аційності
178
+ '{a}{ts}{i}{i`}{n}{i}{s}{t}{iu}' // -аційністю
179
+
180
+ // -ічн-/-ичн- (лінгвістичний, історичний, логічний)
181
+ '{i}{ch}{n}{y}{m}{y}' // -ічними
182
+ '{i}{ch}{n}{o}{h}{o}' // -ічного
183
+ '{i}{ch}{n}{o}{m}{u}' // -ічному
184
+ '{i}{ch}{n}{o}{iu}' // -ічною
185
+ '{i}{ch}{n}{o}{yi}' // -ічної
186
+ '{i}{ch}{n}{y}{kh}' // -ічних
187
+ '{i}{ch}{n}{y}{m}' // -ічним
188
+ '{i}{ch}{n}{y}{i`}' // -ічний
189
+ '{i}{ch}{n}{i}{i`}' // -ічній
190
+ '{i}{ch}{n}{a}' // -ічна
191
+ '{i}{ch}{n}{e}' // -ічне
192
+ '{i}{ch}{n}{i}' // -ічні
193
+ '{i}{ch}{n}{o}' // -ічно (adverb)
194
+ '{i}{ch}{n}{u}' // -ічну
195
+ '{i}{ch}{n}{i}{s}{t}{'}' // -ічність
196
+ '{i}{ch}{n}{o}{s}{t}{i}' // -ічності
197
+ '{i}{ch}{n}{i}{s}{t}{iu}' // -ічністю
198
+ '{y}{ch}{n}{y}{m}{y}' // -ичними
199
+ '{y}{ch}{n}{o}{h}{o}' // -ичного
200
+ '{y}{ch}{n}{o}{m}{u}' // -ичному
201
+ '{y}{ch}{n}{o}{iu}' // -ичною
202
+ '{y}{ch}{n}{o}{yi}' // -ичної
203
+ '{y}{ch}{n}{y}{kh}' // -ичних
204
+ '{y}{ch}{n}{y}{m}' // -ичним
205
+ '{y}{ch}{n}{y}{i`}' // -ичний
206
+ '{y}{ch}{n}{i}{i`}' // -ичній
207
+ '{y}{ch}{n}{a}' // -ична
208
+ '{y}{ch}{n}{e}' // -ичне
209
+ '{y}{ch}{n}{i}' // -ичні
210
+ '{y}{ch}{n}{o}' // -ично (adverb)
211
+ '{y}{ch}{n}{u}' // -ичну
212
+ '{y}{ch}{n}{i}{s}{t}{'}' // -ичність
213
+ '{y}{ch}{n}{o}{s}{t}{i}' // -ичності
214
+ '{y}{ch}{n}{i}{s}{t}{iu}' // -ичністю
215
+ '{y}{ch}{n}{o}{s}{t}{e}{i`}' // -ичностей
216
+
217
+ // -ійн- (комерційний, традиційний)
218
+ '{i}{i`}{n}{y}{m}{y}' // -ійними
219
+ '{i}{i`}{n}{o}{h}{o}' // -ійного
220
+ '{i}{i`}{n}{o}{m}{u}' // -ійному
221
+ '{i}{i`}{n}{o}{iu}' // -ійною
222
+ '{i}{i`}{n}{o}{yi}' // -ійної
223
+ '{i}{i`}{n}{y}{kh}' // -ійних
224
+ '{i}{i`}{n}{y}{m}' // -ійним
225
+ '{i}{i`}{n}{y}{i`}' // -ійний
226
+ '{i}{i`}{n}{i}{i`}' // -ійній
227
+ '{i}{i`}{n}{a}' // -ійна
228
+ '{i}{i`}{n}{e}' // -ійне
229
+ '{i}{i`}{n}{i}' // -ійні
230
+ '{i}{i`}{n}{o}' // -ійно (adverb)
231
+ '{i}{i`}{n}{u}' // -ійну
232
+ '{i}{i`}{n}{i}{s}{t}{'}' // -ійність
233
+ '{i}{i`}{n}{o}{s}{t}{i}' // -ійності
234
+ '{i}{i`}{n}{i}{s}{t}{iu}' // -ійністю
235
+
236
+ // -уальн- (інтелектуальний, віртуальний, актуальний)
237
+ '{u}{a}{l}{'}{n}{y}{m}{y}' // -уальними
238
+ '{u}{a}{l}{'}{n}{o}{h}{o}' // -уального
239
+ '{u}{a}{l}{'}{n}{o}{m}{u}' // -уальному
240
+ '{u}{a}{l}{'}{n}{o}{iu}' // -уальною
241
+ '{u}{a}{l}{'}{n}{o}{yi}' // -уальної
242
+ '{u}{a}{l}{'}{n}{y}{kh}' // -уальних
243
+ '{u}{a}{l}{'}{n}{y}{m}' // -уальним
244
+ '{u}{a}{l}{'}{n}{y}{i`}' // -уальний
245
+ '{u}{a}{l}{'}{n}{i}{i`}' // -уальній
246
+ '{u}{a}{l}{'}{n}{a}' // -уальна
247
+ '{u}{a}{l}{'}{n}{e}' // -уальне
248
+ '{u}{a}{l}{'}{n}{i}' // -уальні
249
+ '{u}{a}{l}{'}{n}{o}' // -уально (adverb)
250
+ '{u}{a}{l}{'}{n}{u}' // -уальну
251
+ '{u}{a}{l}{'}{n}{i}{s}{t}{'}' // -уальність
252
+ '{u}{a}{l}{'}{n}{o}{s}{t}{i}' // -уальності
253
+ '{u}{a}{l}{'}{n}{i}{s}{t}{iu}' // -уальністю
254
+ '{u}{a}{l}{'}{n}{o}{s}{t}{e}{i`}' // -уальностей
255
+ // found_ia: a derivational suffix is gone, what is left is
256
+ // the root; professional must not strip -ар/-ник from it
257
+ // (деклараційний → деклар as декларація, not декл)
258
+ (R2 set found_ia delete)
259
+
260
+ // -аці- noun forms (інформація, організація — before verb -ію intercepts)
261
+ '{a}{ts}{i}{ia}{m}{y}' // -аціями
262
+ '{a}{ts}{i}{ia}{kh}' // -аціях
263
+ '{a}{ts}{i}{ia}{m}' // -аціям
264
+ '{a}{ts}{i}{ie}{iu}' // -аціє́ю (inst)
265
+ '{a}{ts}{i}{iu}' // -ацію
266
+ '{a}{ts}{i}{ia}' // -ація
267
+ '{a}{ts}{i}{yi}' // -ації (gen/dat/loc — ї=U+0457)
268
+ '{a}{ts}{i}{i`}' // -ацій (gen pl)
269
+ // other -ія nouns: the -і- stem marker goes with the ending
270
+ // (академія → академ = академічний, географія → географ)
271
+ '{i}{ia}{m}{y}' // -іями
272
+ '{i}{ia}{kh}' // -іях
273
+ '{i}{ia}{m}' // -іям
274
+ '{i}{ie}{iu}' // -ією (inst)
275
+ '{i}{ie}{m}' // -ієм (inst of -ій: критерієм, анатолієм)
276
+ '{i}{i`}' // -ій (nom of -ій nouns and gen pl of -ія: вікарій, італій)
277
+ '{i}{iu}' // -ію
278
+ '{i}{ia}' // -ія
279
+ '{i}{yi}' // -ії
280
+ '{i}{a}' // -іа (transliteration variant: вікімедіа)
281
+ // found_ia: the remaining stem is a noun root, so the
282
+ // professional pass must not strip -ар/-ник from it
283
+ // (Баварія → бавар as баварський, not бав)
284
+ (R2 set found_ia delete)
285
+ )
286
+ )
287
+ or
288
+ // Standard adj endings + participles (no R2 guard)
289
+ (
290
+ [substring] among (
291
+ // Participles (verbal adjectives)
292
+ '{o}{v}{a}{n}{y}{i`}' '{u}{v}{a}{n}{y}{i`}' // -ований/-уваний
293
+ '{o}{v}{a}{n}{a}' '{u}{v}{a}{n}{a}' // -ована/-увана
294
+ '{o}{v}{a}{n}{e}' '{u}{v}{a}{n}{e}' // -оване/-уване
295
+ '{o}{v}{a}{n}{i}' '{u}{v}{a}{n}{i}' // -овані/-увані
296
+ '{o}{v}{a}{n}{o}' '{u}{v}{a}{n}{o}' // -овано/-увано
297
+ '{u}{ch}{y}{i`}' '{iu}{ch}{y}{i`}' // -учий/-ючий
298
+ '{u}{ch}{a}' '{iu}{ch}{a}' // -уча/-юча
299
+ '{u}{ch}{e}' '{iu}{ch}{e}' // -уче/-юче
300
+ '{u}{ch}{i}' '{iu}{ch}{i}' // -учі/-ючі
301
+
302
+ '{i}{sh}{u}' // Comparative acc fem (старішу), kept from verb -у
303
+ '{yi}{m}{y}' '{i}{m}{y}' '{y}{m}{y}' // Instrumental plural
304
+ '{'}{o}{yi}' // Genitive singular fem (soft) e.g. синьої
305
+ '{'}{o}{h}{o}' // Genitive singular masc/neut (soft) e.g. синього
306
+ '{'}{o}{m}{u}' // Dative singular masc/neut (soft) e.g. синьому
307
+ '{'}{o}{iu}' // Instrumental singular fem (soft) e.g. синьою
308
+ '{o}{h}{o}' // Genitive singular masc/neut
309
+ '{o}{yi}' // Genitive singular fem
310
+ '{o}{m}{u}' // Dative singular masc/neut
311
+ '{o}{iu}' // Instrumental singular fem
312
+ '{yi}{kh}' '{i}{kh}' '{y}{kh}' // Genitive/Locative plural
313
+ '{yi}{m}' '{i}{m}' '{y}{m}' // Dative plural
314
+ '{i}{i`}' // Dative/Locative singular fem
315
+ '{y}{i`}' // Nominative singular masc
316
+ // -ія noun instrumental (before verb -ю intercepts)
317
+ '{ie}{iu}' // -єю (поліграфією→поліграфі)
318
+ (delete)
319
+ // Instrumental of nouns in -жа/-ча/-ша/-ща (площею, межею),
320
+ // before verb -ю intercepts; elsewhere -ею belongs to -ей/-ея
321
+ // nouns (музею, галерею) and is left to verb -ю
322
+ '{e}{iu}'
323
+ ( ('{zh}' or '{ch}' or '{sh}' or '{shch}') delete )
324
+ )
325
+ )
326
+ )
327
+
328
+ define verb as (
329
+ // -остей: gen pl of adj-derived abstract nouns. `not atlimit` keeps at
330
+ // least one char before the limit (pV), preventing волость regression
331
+ // (волостей→вол). Cursor counts bytes in UTF-8 but characters in wide
332
+ // mode, so a numeric cursor guard would stem inconsistently across
333
+ // encodings; `not atlimit` is encoding-portable.
334
+ // Fallback via -{i`} strips only -й → волосте, then noun strips -е → волост.
335
+ ( ['{o}{s}{t}{e}{i`}'] not atlimit delete )
336
+ or
337
+ ( [substring] among (
338
+ '{a}{t}{y}' '{i}{t}{y}' // Infinitive (читати→чит, робити→роб)
339
+ '{y}{t}{y}' // Infinitive (робити with и)
340
+ // -яти verbs (стояти, розчиняти → розчин): the я series
341
+ // mirrors the а series
342
+ '{ia}{v}' '{ia}{l}{a}' '{ia}{l}{y}' '{ia}{l}{o}'
343
+ '{ia}{ie}' '{ia}{iu}{t}{'}' '{ia}{ie}{m}{o}' '{ia}{ie}{t}{e}' '{ia}{ie}{sh}'
344
+ // Future (читатиме, робитимуть, сприятимуть), the persons
345
+ // that occur in the corpus
346
+ '{a}{t}{y}{m}{e}' '{a}{t}{y}{m}{u}{t}{'}' '{a}{t}{y}{m}{e}{m}{o}' '{a}{t}{y}{m}{u}'
347
+ '{y}{t}{y}{m}{e}' '{y}{t}{y}{m}{u}{t}{'}' '{y}{t}{y}{m}{u}'
348
+ '{i}{t}{y}{m}{e}'
349
+ '{ia}{t}{y}{m}{e}' '{ia}{t}{y}{m}{u}{t}{'}'
350
+ '{a}{iu}' // Present 1st sg (читаю)
351
+ // Note: -ію ({i}{iu}) removed — it falsely captures noun accusative
352
+ // of -ія words (поліграфію, демократію). Verb -ію (я дію) handled
353
+ // by -ю fallback below, giving ді instead of д (better grouping)
354
+ '{iu}{t}{'}' '{u}{t}{'}' // Present 3rd pl
355
+ '{a}{iu}{t}{'}' // Present 3rd pl variant
356
+ '{ie}{m}{o}' '{i}{m}{o}' // Present 1st pl
357
+ '{e}{m}{o}' '{y}{m}{o}' // Present 1st pl (живемо, робимо)
358
+ '{ie}{t}{e}' '{i}{t}{e}' // Present 2nd pl
359
+ '{e}{t}{e}' '{y}{t}{e}' // Present 2nd pl (живете, робите)
360
+ '{i`}{t}{e}' // Imperative pl variant
361
+ '{ie}{m}' // Present 1st pl short
362
+ // Note: -{y}{m} (-им) removed — adj standard ending '{y}{m}' (instr.sg/dat.pl)
363
+ // always fires first, so verb -им is unreachable
364
+ '{y}{t}{'}' '{yi}{t}{'}' // Present 3rd sg (робить, стоїть)
365
+ '{ie}{sh}' '{e}{sh}' '{y}{sh}' // Present 2nd sg (знаєш, живеш, робиш)
366
+ // Past tense with its thematic vowel, so the stem meets the
367
+ // infinitive (читала → чит = читати, робили → роб = робити)
368
+ '{y}{l}{a}' '{y}{l}{y}' '{y}{l}{o}'
369
+ '{i}{l}{a}' '{i}{l}{y}' '{i}{l}{o}'
370
+ // Present of -ати verbs with the thematic vowel (читає → чит)
371
+ '{a}{ie}' '{a}{ie}{m}{o}' '{a}{ie}{t}{e}' '{a}{ie}{sh}'
372
+ '{ie}' // Present 3rd sg/future
373
+ '{i`}' // Imperative sg
374
+ // found_ia: these are verb forms, so professional must
375
+ // not read the root as an agent noun (проникає → проник)
376
+ (set found_ia delete)
377
+ // Genitive plural -ей of consonant-stem nouns (дітей → діт,
378
+ // областей → област, цілей → ціл, коней → кон, грошей →
379
+ // грош): after т, ч, ш, щ, м, н, л the ending goes. After
380
+ // any other letter the е belongs to the stem of an -ей/-ея
381
+ // noun (трофей, трофею → трофе; ідея, ідей → іде) and only
382
+ // й goes, as for the imperative above. In a 5-letter word
383
+ // the letter sits outside pV and cannot be tested (atlimit):
384
+ // the ending goes, as дітей, цілей, коней, ролей, речей far
385
+ // outnumber музей, ліцей, хокей, which are listed as
386
+ // exceptions.
387
+ '{e}{i`}'
388
+ ( set found_ia
389
+ ( ( (atlimit or '{t}' or '{ch}' or '{sh}' or '{shch}'
390
+ or '{m}' or '{n}' or '{l}')
391
+ delete )
392
+ or (<- '{e}') ) )
393
+ // Past masc -ав/-ів/-ив: also the genitive plural of nouns
394
+ // (працівників), so professional may still follow
395
+ '{a}{v}' '{i}{v}' '{y}{v}'
396
+ (delete)
397
+ // Past -ала/-али/-ало, but not after a vowel: -іали/-еали/
398
+ // -уали are noun plurals (матеріали, ідеали, ритуали)
399
+ '{a}{l}{a}' '{a}{l}{y}' '{a}{l}{o}'
400
+ ( not v set found_ia delete )
401
+ // Infinitive -яти (стояти, розчиняти), but not after с, ц or
402
+ // an apostrophe: those are the numerals десяти, двадцяти,
403
+ // п'яти, дев'яти
404
+ '{ia}{t}{y}' '{ia}{t}{'}' // -яти, and 3rd pl -ять (стоять, болять)
405
+ ( not ('{s}' or '{ts}' or '{ap}') set found_ia delete )
406
+ // Present of -увати/-ювати verbs: -ує/-ують → -ув so the stem
407
+ // meets the infinitive and past tense (будує → будув = будував)
408
+ '{u}{ie}' '{u}{iu}{t}{'}' '{u}{ie}{m}{o}' '{u}{ie}{t}{e}' '{u}{ie}{sh}'
409
+ (<- '{u}{v}')
410
+ '{iu}{ie}' '{iu}{iu}{t}{'}' '{iu}{ie}{m}{o}' '{iu}{ie}{t}{e}' '{iu}{ie}{sh}'
411
+ (<- '{iu}{v}')
412
+ // Past masc -в (fallback): a vowel other than о precedes it
413
+ // (no verb ends in -ов or -ств, while Іванов, готов, товариств
414
+ // do). A vowel outside pV cannot be seen (став), so the
415
+ // ending is removed as before there.
416
+ '{v}'
417
+ ( not '{o}' (atlimit or v) delete )
418
+ // Present 1st sg -у (fallback), but not after -ств/-цтв: -ству
419
+ // and -цтву are the dative of -ство/-цтво nouns (товариству,
420
+ // мистецтву), left for noun.
421
+ '{u}'
422
+ ( not ('{s}{t}{v}' or '{ts}{t}{v}') delete )
423
+ // Past tense -ла/-ли/-ло, unless the letter before the
424
+ // ending marks a noun (found_la_noun, tested on the whole
425
+ // word in stem: школа, число, Павло, світло).
426
+ // Consonant-stem verbs keep the plain ending (могли,
427
+ // вийшло, принесла).
428
+ '{l}{a}' '{l}{y}' '{l}{o}'
429
+ ( not found_la_noun delete )
430
+ // Present 1st sg -ю (fallback), but not after -іст: -істю is
431
+ // the instrumental of -ість abstract nouns (активністю), which
432
+ // noun maps back to -ість so it stems like the nominative.
433
+ '{iu}'
434
+ ( not '{i}{s}{t}' delete )
435
+ // Infinitive -ти (fallback), unless the letter before the
436
+ // ending marks a noun plural (found_ty_noun, tested on the
437
+ // whole word in stem: документи, роботи, факти, карти).
438
+ // The guard lets noun -и run.
439
+ '{t}{y}'
440
+ ( not found_ty_noun delete )
441
+ )
442
+ )
443
+ )
444
+
445
+ define noun as (
446
+ // -ості: gen/dat/loc sg, nom/gen pl of adj-derived abstract nouns.
447
+ // `not atlimit` keeps at least one char before the limit (pV),
448
+ // preventing волості→вол; falls through to -{i} below → волост.
449
+ // Encoding-portable guard (cursor counts bytes in UTF-8 but chars in
450
+ // wide mode, so a numeric cursor test would stem inconsistently).
451
+ // Verb handles -остей (ends in -й), so the -{o}{s}{t}{e}{i`} entry
452
+ // here is removed (unreachable).
453
+ // -ість/-істю/-істі share the guard so the whole paradigm stems alike
454
+ // (кількість = кількості = кількістю → кільк, повість = повісті).
455
+ ( [substring] among (
456
+ '{o}{s}{t}{i}' // -ості
457
+ '{i}{s}{t}{'}' // -ість
458
+ '{i}{s}{t}{iu}' // -істю
459
+ '{i}{s}{t}{i}' // -істі (underived nouns: повісті)
460
+ (not atlimit delete)
461
+ )
462
+ )
463
+ or
464
+ ( [substring] among (
465
+ // -істю too close to pV for the rule above: restore the
466
+ // nominative so it stems like the -ість form, which keeps
467
+ // its ending there (радістю → радість → радіст).
468
+ '{i}{s}{t}{iu}' (<- '{i}{s}{t}{'}')
469
+
470
+ // Fleeting vowel: -ець → -ц (nominative → oblique stem)
471
+ // живописець→живописц (groups with живописця/цю/цем/ці)
472
+ '{e}{ts}{'}' (<- '{ts}')
473
+
474
+ // Collective/abstract nouns (specific, safe without R2)
475
+ '{s}{t}{v}{o}' // -ство (багатство→багат)
476
+ '{t}{v}{o}' // -тво (words in -цтво like козацтво match -ство above)
477
+ // oblique cases of -ство (авторства, суспільстві, мистецтвом)
478
+ '{s}{t}{v}{a}' '{s}{t}{v}{u}' '{s}{t}{v}{i}' '{s}{t}{v}{o}{m}'
479
+ '{s}{t}{v}{a}{m}' '{s}{t}{v}{a}{m}{y}' '{s}{t}{v}{a}{kh}'
480
+ '{s}{t}{v}' // gen pl (товариств)
481
+ (delete)
482
+ '{ts}{t}{v}' (<- '{ts}') // gen pl (мистецтв → мистец)
483
+ // oblique cases of -цтво keep the ц (козацтва → козац)
484
+ '{ts}{t}{v}{a}' (<- '{ts}') '{ts}{t}{v}{u}' (<- '{ts}')
485
+ '{ts}{t}{v}{i}' (<- '{ts}') '{ts}{t}{v}{o}{m}' (<- '{ts}')
486
+ '{ts}{t}{v}{a}{m}' (<- '{ts}')
487
+ '{ts}{t}{v}{a}{m}{y}' (<- '{ts}') '{ts}{t}{v}{a}{kh}' (<- '{ts}')
488
+
489
+ '{ia}{m}{y}' '{a}{m}{y}' // Instrumental plural
490
+ '{ia}{kh}' '{a}{kh}' // Locative plural
491
+ '{ia}{m}' '{a}{m}' // Dative plural
492
+ // Singular specific endings
493
+ '{o}{v}{i}' // -ові (братові→брат)
494
+ '{e}{v}{i}'
495
+ // Instrumental singular
496
+ '{e}{m}' '{o}{m}'
497
+
498
+ // Shorter endings
499
+ '{ia}' '{a}' '{i}' '{yi}' '{y}' '{e}' '{o}'
500
+ (delete)
501
+ )
502
+ )
503
+ )
504
+
505
+ define professional as (
506
+ [substring] among (
507
+ '{i}{v}{n}{y}{k}' '{a}{l}{'}{n}{y}{k}' '{e}{l}{'}{n}{y}{k}' // -івник, -альник, -ельник
508
+ '{ia}{r}' // -яр (каменяр, столяр)
509
+ '{n}{y}{k}' // -ник (generic agent)
510
+ '{a}{ch}' // -ач (копач)
511
+ (delete)
512
+ // -ар only after к (лікар, пекар, аптекар, друкар, бібліотекар):
513
+ // elsewhere it is part of the root (долар, товар, секретар,
514
+ // гектар, базар, календар, комар)
515
+ '{a}{r}'
516
+ ( '{k}' delete )
517
+ )
518
+ )
519
+
520
+ define diminutive as (
521
+ [substring] among (
522
+ // Double diminutives
523
+ '{o}{ch}{e}{ch}{o}{k}' '{o}{ch}{e}{ch}{k}{a}' '{o}{ch}{e}{ch}{k}{y}' '{o}{ch}{e}{ch}{k}{o}' '{o}{ch}{e}{ch}{k}{i}'
524
+
525
+ // Animal young (from dictionary analysis)
526
+ '{i}{t}{k}{o}' // -ітко (собаченітко → собачен)
527
+ '{ia}{t}{k}{o}' // -ятко (солов'ятко → солов, соколенятко → соколен)
528
+ '{a}{t}{k}{o}' // -атко (babies)
529
+
530
+ // Most diminutive forms
531
+ '{o}{ch}{o}{k}' '{o}{ch}{k}{a}' '{o}{ch}{k}{y}' '{o}{ch}{k}{o}' '{o}{ch}{k}{i}'
532
+ '{e}{ch}{o}{k}' '{e}{ch}{k}{a}' '{e}{ch}{k}{y}' '{e}{ch}{k}{o}' '{e}{ch}{k}{i}'
533
+ '{i}{ch}{o}{k}' '{i}{ch}{k}{a}' '{i}{ch}{k}{y}' '{i}{ch}{k}{o}' '{i}{ch}{k}{i}'
534
+
535
+ // Intensive diminutives
536
+ '{e}{s}{e}{n}{'}{k}{a}' '{e}{s}{e}{n}{'}{k}{y}' '{e}{s}{e}{n}{'}{k}{o}' '{e}{s}{e}{n}{'}{k}{i}' // -есеньк-
537
+ '{i}{s}{i}{n}{'}{k}{a}' '{i}{s}{i}{n}{'}{k}{y}' '{i}{s}{i}{n}{'}{k}{o}' '{i}{s}{i}{n}{'}{k}{i}' // -ісіньк-
538
+ '{iu}{s}{i}{n}{'}{k}{a}' '{iu}{s}{i}{n}{'}{k}{y}' '{iu}{s}{i}{n}{'}{k}{o}' '{iu}{s}{i}{n}{'}{k}{i}' // -юсіньк-
539
+ '{o}{n}{'}{k}{a}' '{o}{n}{'}{k}{y}' '{o}{n}{'}{k}{o}' '{o}{n}{'}{k}{i}' // -оньк-
540
+
541
+ // Regular -еньк-, -іньк- patterns
542
+ '{e}{n}{'}{k}{u}'
543
+ '{e}{n}{'}{k}{a}' '{e}{n}{'}{k}{y}' '{e}{n}{'}{k}{o}' '{e}{n}{'}{k}{i}'
544
+ '{i}{n}{'}{k}{a}' '{i}{n}{'}{k}{y}' '{i}{n}{'}{k}{o}' '{i}{n}{'}{k}{i}'
545
+
546
+ // -еня (козеня, лисеня) omitted: it is also the genitive of
547
+ // камінь, корінь, ступінь, промінь (каменя, кореня)
548
+
549
+ // -инка/-інка omitted: сторінка, картинка, тварина/тваринка,
550
+ // новинка are not diminutives of стор/карт/твар/нов, and
551
+ // дівчинка = дівчинку holds without it
552
+ // Note: -усь omitted — reflexive(-сь)+verb(-у) handles these (дідусь→дід, братусь→брат)
553
+ // -інь omitted: камінь, корінь, промінь, осінь are not diminutives
554
+ // -ень omitted: verbal_noun removes it first (gen pl рішень)
555
+ '{u}{n}{'}'
556
+ (delete)
557
+ // -ок: the о is fleeting, so only it goes and the stem meets the
558
+ // oblique forms (будинок → будинк = будинку, грибок = грибка).
559
+ // -ик/-ік are not fleeting (хлопчик = хлопчика) and are left alone.
560
+ '{o}{k}'
561
+ (<- '{k}')
562
+ )
563
+ )
564
+
565
+ define diminutive_stem as (
566
+ [substring] among (
567
+ '{e}{s}{e}{n}{'}{k}' // -есеньк
568
+ '{i}{s}{i}{n}{'}{k}' // -ісіньк
569
+ '{iu}{s}{i}{n}{'}{k}' // -юсіньк
570
+ '{e}{n}{'}{k}' // -еньк
571
+ '{o}{n}{'}{k}' // -оньк
572
+ '{i}{n}{'}{k}' // -іньк
573
+ // -ятк/-атк/-ітк intentionally excluded: they occur in stems like
574
+ // десятк(а), пам'ятк(а), початк(у), додатк(у), дітк(и);
575
+ // -ятко/-атко/-ітко are handled in diminutive above
576
+ (delete)
577
+ )
578
+ )
579
+
580
+ // Verbal nouns in -ння with all their cases (nom/gen -ння, dat -нню,
581
+ // loc -нні, inst -нням, pl -ннями/-ннях, gen pl -нь). found_verb: the
582
+ // verb root is left, so comparative and tidy_up must not read a final
583
+ // -іш as a comparative (вирішення → виріш = вирішити, not вир);
584
+ // found_ia keeps professional off it (проникання → проник, not про).
585
+ define verbal_noun as (
586
+ // -іння keeps the R2 guard: many -іння nouns are not deverbal
587
+ // (каміння, коріння, насіння, покоління)
588
+ ( setlimit tomark p2 for ([substring]) among (
589
+ '{i}{n}{n}{ia}' '{i}{n}{n}{iu}' '{i}{n}{n}{i}'
590
+ '{i}{n}{n}{ia}{m}' '{i}{n}{n}{ia}{m}{y}' '{i}{n}{n}{ia}{kh}'
591
+ '{i}{n}{'}' // gen pl (володінь, поколінь); камінь, корінь sit outside R2
592
+ (set found_ia set found_verb delete)
593
+ )
594
+ )
595
+ or
596
+ // -ання/-ення/-яння are deverbal, so pV is guard enough and short
597
+ // roots meet their verb (рішення = рішень = рішити → ріш, читання
598
+ // → чит). The plural of -нний adjectives (нечисленні, притаманні)
599
+ // shares the -нні form; the frequent ones are kept by exception.
600
+ ( [substring] among (
601
+ '{a}{n}{n}{ia}' '{ia}{n}{n}{ia}' '{e}{n}{n}{ia}'
602
+ '{a}{n}{n}{iu}' '{a}{n}{n}{i}' '{a}{n}{n}{ia}{m}' '{a}{n}{n}{ia}{m}{y}' '{a}{n}{n}{ia}{kh}'
603
+ '{ia}{n}{n}{iu}' '{ia}{n}{n}{i}' '{ia}{n}{n}{ia}{m}' '{ia}{n}{n}{ia}{m}{y}' '{ia}{n}{n}{ia}{kh}'
604
+ '{e}{n}{n}{iu}' '{e}{n}{n}{i}' '{e}{n}{n}{ia}{m}' '{e}{n}{n}{ia}{m}{y}' '{e}{n}{n}{ia}{kh}'
605
+ '{a}{n}{'}' '{e}{n}{'}' '{ia}{n}{'}' // gen pl: видань, рішень
606
+ (set found_ia set found_verb delete)
607
+ )
608
+ )
609
+ )
610
+
611
+ define derivational as (
612
+ setlimit tomark p2 for ([substring]) among (
613
+ // Abstract nouns reach this point without -ість (noun removes it
614
+ // in every case), so what is left is the adjective stem and the
615
+ // rules below treat it as such (національність → національн →
616
+ // націонал, промисловість → промислов → промисл).
617
+
618
+ // -ован left by noun on -ованість: the whole suffix goes so it
619
+ // meets the verb (організованість → організован → організ =
620
+ // організований)
621
+ '{o}{v}{a}{n}' // -ован
622
+
623
+ // Adjectival derivational
624
+ // -ьн: strip only the soft sign + н of -льн- adjectives so the
625
+ // stem matches the base noun and its -ізм/-іст derivatives
626
+ // (акварельний → акварел = акварель, соціальний → соціал = соціалізм)
627
+ '{'}{n}'
628
+ '{s}{'}{k}' // -ськ (український → україн)
629
+ '{z}{'}{k}' // -зьк
630
+ '{u}{v}{a}{t}' // -уват
631
+ '{i}{v}{n}' // -івн (пасічниківна → пасічник)
632
+ // -ув/-юв: the theme of -увати verbs, left by the infinitive,
633
+ // past tense, -ування and -увальний; the root then meets the
634
+ // participle and the -ація noun (адаптував, адаптування,
635
+ // адаптований, адаптація → адапт). R2 keeps short roots whole
636
+ // (будув, малюв).
637
+ '{u}{v}' '{iu}{v}'
638
+ '{o}{v}{u}{v}' // -овув (використовувати → використ = використання)
639
+ // -уван/-юван left by adjective endings on oblique forms of
640
+ // -уваний participles (виконуваним → виконуван → викон)
641
+ '{u}{v}{a}{n}' '{iu}{v}{a}{n}'
642
+ '{o}{v}' // -ов (дощовий → дощ after adj -ий)
643
+ '{ia}{n}' // -ян (кахляний → кахл after adj -ий)
644
+
645
+ // Other
646
+ '{i}{z}{m}' // -ізм
647
+ '{i}{s}{t}' // -іст
648
+ '{y}{shch}' // -ищ
649
+ (delete)
650
+ // -ельн after в: adjectives of -івля/-овля nouns (будівля →
651
+ // будівельний, торгівля → торговельний). The whole suffix goes so
652
+ // the stem matches the noun (будів, торгов); every в+ельн lexeme
653
+ // in the corpus follows this pattern. Elsewhere -ельн is -ель + ьн
654
+ // (акварельний, корабельний) and only ьн goes.
655
+ '{e}{l}{'}{n}'
656
+ ( ('{v}' delete) or (<- '{e}{l}') )
657
+ // -альн after -ув-/-юв-: deverbal adjectives of -увати verbs
658
+ // (лікувальний, рятувальний, обчислювальний). The whole suffix
659
+ // goes so the stem meets the verb and its -ування noun
660
+ // (лікув = лікувати, лікування). Elsewhere only ьн goes.
661
+ '{a}{l}{'}{n}'
662
+ ( (('{u}{v}' or '{iu}{v}') delete) or (<- '{a}{l}') )
663
+ // -ан after -ув-/-юв-, left by noun on abstract nouns of -уваний
664
+ // participles (засвоюваність → засвоюван → засвоюв = засвоювати).
665
+ // Elsewhere it stays (вихованість → вихован = вихована).
666
+ '{a}{n}'
667
+ ( ('{u}{v}' or '{iu}{v}') delete )
668
+ )
669
+ )
670
+
671
+ // Comparative -іш (сильніше, детальніше), removed before derivational so
672
+ // the remaining stem gets the same -ьн/-нн treatment as the positive form
673
+ // (детальніше → детальн → детал = детальна).
674
+ define comparative as (
675
+ ['{i}{sh}'] delete
676
+ )
677
+
678
+ define tidy_up as (
679
+ [substring] among (
680
+ // Comparative -іш uncovered by derivational (-іш-ов, -іш-ськ in
681
+ // surnames: Кулішова → куліш → кул)
682
+ '{i}{sh}'
683
+ (not found_verb delete
684
+ ['{n}'] '{n}' delete
685
+ )
686
+ // Consonant alternations in verbs
687
+ '{l}'
688
+ ('{b}' or '{p}' or '{v}' or '{m}' delete)
689
+ // Double consonants
690
+ '{n}'
691
+ ('{n}' delete)
692
+ // Soft sign cleanup
693
+ '{'}'
694
+ (delete)
695
+ )
696
+ )
697
+ )
698
+
699
+ define stem as (
700
+ // Strip най- prefix (superlative)
701
+ do (
702
+ ['{n}{a}{i`}'] not atlimit delete
703
+ )
704
+ // Exception: окремо is adverb (not verb -емо), stem as окрем
705
+ // to group with окремий/окрема/окремі (adj -ий/-а/-і → окрем)
706
+ ( test ('{o}{k}{r}{e}{m}{o}' atlimit)
707
+ backwards (['{o}'] delete)
708
+ )
709
+ or
710
+ // Word-level exceptions: prevent false root collisions from the -ості/-остей rule.
711
+ // вартість (value, root вартий=worth) vs варта (guard, different etymology):
712
+ // stripping -ості gives варт which collides with варта/вартовий paradigm.
713
+ // Map these forms to вартост, consistent with вартість→вартіст stem.
714
+ ( [substring] atlimit among (
715
+ '{v}{a}{r}{t}{o}{s}{t}{i}' (<- '{v}{a}{r}{t}{o}{s}{t}') // вартості
716
+ '{v}{a}{r}{t}{o}{s}{t}{e}{i`}' (<- '{v}{a}{r}{t}{o}{s}{t}') // вартостей
717
+ '{v}{a}{r}{t}{i}{s}{t}{'}' (<- '{v}{a}{r}{t}{o}{s}{t}') // вартість
718
+ '{v}{a}{r}{t}{i}{s}{t}{iu}' (<- '{v}{a}{r}{t}{o}{s}{t}') // вартістю
719
+ // совість (conscience) would meet сова (owl) after -ість removal
720
+ '{s}{o}{v}{i}{s}{t}{'}' (<- '{s}{o}{v}{i}{s}{t}') // совість
721
+ '{s}{o}{v}{i}{s}{t}{i}' (<- '{s}{o}{v}{i}{s}{t}') // совісті
722
+ '{s}{o}{v}{i}{s}{t}{iu}' (<- '{s}{o}{v}{i}{s}{t}') // совістю
723
+ // Fleeting-vowel and consonant alternations in the most frequent
724
+ // nouns, which no suffix rule can reach: рік/року/році, Київ/Києва,
725
+ // особа/осіб, люди/людей
726
+ '{r}{i}{k}' (<- '{r}{o}{k}') // рік
727
+ '{r}{o}{ts}{i}' (<- '{r}{o}{k}') // році
728
+ '{k}{y}{yi}{v}' (<- '{k}{y}{ie}{v}') // Київ
729
+ '{o}{s}{i}{b}' (<- '{o}{s}{o}{b}') // осіб
730
+ '{l}{iu}{d}{e}{i`}' (<- '{l}{iu}{d}') // людей
731
+ // могила (grave) would meet могти (can) once -ила is a verb ending
732
+ '{m}{o}{h}{y}{l}{a}' (<- '{m}{o}{h}{y}{l}') // могила
733
+ '{m}{o}{h}{y}{l}{y}' (<- '{m}{o}{h}{y}{l}') // могили
734
+ '{m}{o}{h}{y}{l}{u}' (<- '{m}{o}{h}{y}{l}') // могилу
735
+ '{m}{o}{h}{y}{l}{i}' (<- '{m}{o}{h}{y}{l}') // могилі
736
+ '{m}{o}{h}{y}{l}{o}{iu}' (<- '{m}{o}{h}{y}{l}') // могилою
737
+ // Names in -ило would lose -ило as a past tense (Кирило, Данило)
738
+ '{k}{y}{r}{y}{l}{o}' (<- '{k}{y}{r}{y}{l}') // Кирило
739
+ '{k}{y}{r}{y}{l}{a}' (<- '{k}{y}{r}{y}{l}') // Кирила
740
+ '{k}{y}{r}{y}{l}{u}' (<- '{k}{y}{r}{y}{l}') // Кирилу
741
+ '{k}{y}{r}{y}{l}{o}{m}' (<- '{k}{y}{r}{y}{l}') // Кирилом
742
+ '{d}{a}{n}{y}{l}{o}' (<- '{d}{a}{n}{y}{l}') // Данило
743
+ '{d}{a}{n}{y}{l}{a}' (<- '{d}{a}{n}{y}{l}') // Данила
744
+ '{d}{a}{n}{y}{l}{u}' (<- '{d}{a}{n}{y}{l}') // Данилу
745
+ '{d}{a}{n}{y}{l}{o}{m}' (<- '{d}{a}{n}{y}{l}') // Данилом
746
+ '{d}{a}{n}{y}{l}{i}' (<- '{d}{a}{n}{y}{l}') // Данилі
747
+ // Толстой keeps the Russian adjective ending -ой, which is not a
748
+ // Ukrainian ending (герой → геро must not lose its й)
749
+ '{t}{o}{l}{s}{t}{o}{i`}' (<- '{t}{o}{l}{s}{t}') // Толстой
750
+ // Adverbs in -ало are not a past tense
751
+ '{ch}{y}{m}{a}{l}{o}' (<- '{ch}{y}{m}{a}{l}{o}') // чимало
752
+ '{z}{a}{m}{a}{l}{o}' (<- '{z}{a}{m}{a}{l}') // замало
753
+ '{n}{e}{m}{a}{l}{o}' (<- '{n}{e}{m}{a}{l}') // немало
754
+ '{n}{e}{v}{d}{a}{l}{o}' (<- '{n}{e}{v}{d}{a}{l}') // невдало
755
+ '{d}{o}{s}{k}{o}{n}{a}{l}{o}' (<- '{d}{o}{s}{k}{o}{n}{a}{l}') // досконало
756
+ // The most frequent nouns in -ал whose genitive (animate) or plural
757
+ // looks like a past tense once -ала/-али is a verb ending
758
+ '{h}{e}{n}{e}{r}{a}{l}{a}' (<- '{h}{e}{n}{e}{r}{a}{l}') // генерала
759
+ '{h}{e}{n}{e}{r}{a}{l}{y}' (<- '{h}{e}{n}{e}{r}{a}{l}') // генерали
760
+ '{a}{d}{m}{i}{r}{a}{l}{a}' (<- '{a}{d}{m}{i}{r}{a}{l}') // адмірала
761
+ '{m}{a}{r}{sh}{a}{l}{a}' (<- '{m}{a}{r}{sh}{a}{l}') // маршала
762
+ '{k}{a}{r}{d}{y}{n}{a}{l}{a}' (<- '{k}{a}{r}{d}{y}{n}{a}{l}') // кардинала
763
+ '{f}{i}{n}{a}{l}{y}' (<- '{f}{i}{n}{a}{l}') // фінали
764
+ '{p}{i}{v}{f}{i}{n}{a}{l}{y}' (<- '{p}{i}{v}{f}{i}{n}{a}{l}') // півфінали
765
+ '{k}{a}{n}{a}{l}{y}' (<- '{k}{a}{n}{a}{l}') // канали
766
+ '{zh}{u}{r}{n}{a}{l}{y}' (<- '{zh}{u}{r}{n}{a}{l}') // журнали
767
+ '{s}{y}{h}{n}{a}{l}{y}' (<- '{s}{y}{h}{n}{a}{l}') // сигнали
768
+ '{m}{i}{n}{e}{r}{a}{l}{y}' (<- '{m}{i}{n}{e}{r}{a}{l}') // мінерали
769
+ '{k}{r}{y}{s}{t}{a}{l}{y}' (<- '{k}{r}{y}{s}{t}{a}{l}') // кристали
770
+ '{m}{e}{t}{a}{l}{y}' (<- '{m}{e}{t}{a}{l}') // метали
771
+ '{k}{v}{a}{r}{t}{a}{l}{y}' (<- '{k}{v}{a}{r}{t}{a}{l}') // квартали
772
+ // верства (layer) would lose -ства as the abstract-noun suffix
773
+ '{v}{e}{r}{s}{t}{v}{a}' (<- '{v}{e}{r}{s}{t}{v}') // верства
774
+ '{v}{e}{r}{s}{t}{v}{y}' (<- '{v}{e}{r}{s}{t}{v}') // верстви
775
+ '{v}{e}{r}{s}{t}{v}{u}' (<- '{v}{e}{r}{s}{t}{v}') // верству
776
+ '{v}{e}{r}{s}{t}{v}{i}' (<- '{v}{e}{r}{s}{t}{v}') // верстві
777
+ '{v}{e}{r}{s}{t}{v}{o}{iu}' (<- '{v}{e}{r}{s}{t}{v}') // верствою
778
+ '{v}{e}{r}{s}{t}{v}' (<- '{v}{e}{r}{s}{t}{v}') // верств
779
+ // Мельник (surname, and miller) would become мел via -ник and tidy_up
780
+ '{m}{e}{l}{'}{n}{y}{k}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельник
781
+ '{m}{e}{l}{'}{n}{y}{k}{a}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельника
782
+ '{m}{e}{l}{'}{n}{y}{k}{u}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельнику
783
+ '{m}{e}{l}{'}{n}{y}{k}{o}{m}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельником
784
+ '{m}{e}{l}{'}{n}{y}{k}{y}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельники
785
+ '{m}{e}{l}{'}{n}{y}{k}{i}{v}' (<- '{m}{e}{l}{'}{n}{y}{k}') // Мельників
786
+ // кристал: genitive кристала would be read as a past tense
787
+ '{k}{r}{y}{s}{t}{a}{l}{a}' (<- '{k}{r}{y}{s}{t}{a}{l}') // кристала
788
+ // матерія (matter) would meet матері (of мати, mother) after -ія
789
+ // removal; keep the -і stem it had before the -ія rule.
790
+ '{m}{a}{t}{e}{r}{i}{ia}' (<- '{m}{a}{t}{e}{r}{i}') // матерія
791
+ '{m}{a}{t}{e}{r}{i}{yi}' (<- '{m}{a}{t}{e}{r}{i}') // матерії
792
+ '{m}{a}{t}{e}{r}{i}{iu}' (<- '{m}{a}{t}{e}{r}{i}') // матерію
793
+ '{m}{a}{t}{e}{r}{i}{ie}{iu}' (<- '{m}{a}{t}{e}{r}{i}') // матерією
794
+ // досить (enough) is an adverb, not the 3rd person of a verb
795
+ '{d}{o}{s}{y}{t}{'}' (<- '{d}{o}{s}{y}{t}{'}') // досить
796
+ // The frequent infinitives in -кти and -рти, which the -ти guard
797
+ // otherwise reads as noun plurals (факти, карти)
798
+ '{v}{t}{e}{k}{t}{y}' (<- '{v}{t}{e}{k}') // втекти
799
+ '{u}{t}{e}{k}{t}{y}' (<- '{u}{t}{e}{k}') // утекти
800
+ '{p}{o}{m}{e}{r}{t}{y}' (<- '{p}{o}{m}{e}{r}') // померти
801
+ // The frequent past tenses in -рла/-рли/-рло, which the -ла guard
802
+ // otherwise reads as nouns (Карла, гирло)
803
+ '{p}{o}{m}{e}{r}{l}{a}' (<- '{p}{o}{m}{e}{r}') // померла
804
+ '{p}{o}{m}{e}{r}{l}{y}' (<- '{p}{o}{m}{e}{r}') // померли
805
+ '{p}{o}{m}{e}{r}{l}{o}' (<- '{p}{o}{m}{e}{r}') // померло
806
+ '{v}{y}{m}{e}{r}{l}{a}' (<- '{v}{y}{m}{e}{r}') // вимерла
807
+ '{v}{y}{m}{e}{r}{l}{y}' (<- '{v}{y}{m}{e}{r}') // вимерли
808
+ '{v}{d}{e}{r}{l}{y}{s}{ia}' (<- '{v}{d}{e}{r}') // вдерлися
809
+ // новела keeps its -ла: -вела is otherwise a past tense (привела)
810
+ '{n}{o}{v}{e}{l}{a}' (<- '{n}{o}{v}{e}{l}') // новела
811
+ '{n}{o}{v}{e}{l}{y}' (<- '{n}{o}{v}{e}{l}') // новели
812
+ // Nouns and names whose nominative ends in -ом, -им, -ям, -ам or
813
+ // -ем (and their dative in -ому), which the case-ending rules cut
814
+ // as if they were endings (альбом → альб, режим → реж, Вільям →
815
+ // віл): the most frequent ones keep the stem of their other forms
816
+ '{a}{l}{'}{b}{o}{m}' (<- '{a}{l}{'}{b}{o}{m}') // альбом
817
+ '{a}{l}{'}{b}{o}{m}{u}' (<- '{a}{l}{'}{b}{o}{m}') // альбому
818
+ '{m}{i}{n}{i}{a}{l}{'}{b}{o}{m}' (<- '{m}{i}{n}{i}{a}{l}{'}{b}{o}{m}') // мініальбом
819
+ '{m}{i}{n}{i}{a}{l}{'}{b}{o}{m}{u}' (<- '{m}{i}{n}{i}{a}{l}{'}{b}{o}{m}') // мініальбому
820
+ '{h}{e}{n}{o}{m}' (<- '{h}{e}{n}{o}{m}') // геном
821
+ '{h}{e}{n}{o}{m}{u}' (<- '{h}{e}{n}{o}{m}') // геному
822
+ '{d}{y}{p}{l}{o}{m}' (<- '{d}{y}{p}{l}{o}{m}') // диплом
823
+ '{p}{r}{y}{i`}{o}{m}' (<- '{p}{r}{y}{i`}{o}{m}') // прийом
824
+ '{p}{r}{y}{i`}{o}{m}{u}' (<- '{p}{r}{y}{i`}{o}{m}') // прийому
825
+ '{p}{i}{d}{i`}{o}{m}' (<- '{p}{i}{d}{i`}{o}{m}') // підйом
826
+ '{p}{i}{d}{i`}{o}{m}{u}' (<- '{p}{i}{d}{i`}{o}{m}') // підйому
827
+ '{s}{y}{n}{d}{r}{o}{m}' (<- '{s}{y}{n}{d}{r}{o}{m}') // синдром
828
+ '{s}{y}{n}{d}{r}{o}{m}{u}' (<- '{s}{y}{n}{d}{r}{o}{m}') // синдрому
829
+ '{a}{e}{r}{o}{d}{r}{o}{m}' (<- '{a}{e}{r}{o}{d}{r}{o}{m}') // аеродром
830
+ '{a}{e}{r}{o}{d}{r}{o}{m}{u}' (<- '{a}{e}{r}{o}{d}{r}{o}{m}') // аеродрому
831
+ '{sh}{o}{l}{o}{m}' (<- '{sh}{o}{l}{o}{m}') // шолом
832
+ '{a}{s}{t}{r}{o}{n}{o}{m}' (<- '{a}{s}{t}{r}{o}{n}{o}{m}') // астроном
833
+ '{a}{h}{r}{o}{n}{o}{m}' (<- '{a}{h}{r}{o}{n}{o}{m}') // агроном
834
+ '{r}{e}{zh}{y}{m}' (<- '{r}{e}{zh}{y}{m}') // режим
835
+ '{r}{e}{zh}{y}{m}{y}' (<- '{r}{e}{zh}{y}{m}') // режими
836
+ '{n}{a}{p}{r}{ia}{m}' (<- '{n}{a}{p}{r}{ia}{m}') // напрям
837
+ '{n}{a}{p}{r}{ia}{m}{y}' (<- '{n}{a}{p}{r}{ia}{m}') // напрями
838
+ '{i}{s}{l}{a}{m}' (<- '{i}{s}{l}{a}{m}') // іслам
839
+ '{m}{a}{d}{a}{m}' (<- '{m}{a}{d}{a}{m}') // мадам
840
+ '{v}{i}{l}{'}{ia}{m}' (<- '{v}{i}{l}{'}{ia}{m}') // Вільям
841
+ '{m}{a}{k}{s}{y}{m}' (<- '{m}{a}{k}{s}{y}{m}') // Максим
842
+ '{v}{a}{d}{y}{m}' (<- '{v}{a}{d}{y}{m}') // Вадим
843
+ '{a}{r}{t}{e}{m}' (<- '{a}{r}{t}{e}{m}') // Артем
844
+ '{ie}{r}{u}{s}{a}{l}{y}{m}' (<- '{ie}{r}{u}{s}{a}{l}{y}{m}') // Єрусалим
845
+ '{v}{ap}{ie}{t}{n}{a}{m}' (<- '{v}{ap}{ie}{t}{n}{a}{m}') // В'єтнам
846
+ '{a}{m}{s}{t}{e}{r}{d}{a}{m}' (<- '{a}{m}{s}{t}{e}{r}{d}{a}{m}') // Амстердам
847
+ // Noun plurals (and feminine genitives) in -ати/-ити/-іти, which
848
+ // the infinitive rules read as verbs (результати → результ,
849
+ // освіти → осв): no letter separates them from читати, робити,
850
+ // so the forms with at least 1000 occurrences take the stem of
851
+ // their singular
852
+ '{o}{s}{v}{i}{t}{y}' (<- '{o}{s}{v}{i}{t}') // освіти
853
+ '{r}{e}{z}{u}{l}{'}{t}{a}{t}{y}' (<- '{r}{e}{z}{u}{l}{'}{t}{a}{t}') // результати
854
+ '{v}{t}{r}{a}{t}{y}' (<- '{v}{t}{r}{a}{t}') // втрати
855
+ '{p}{a}{l}{a}{t}{y}' (<- '{p}{a}{l}{a}{t}') // палати
856
+ '{h}{a}{r}{m}{a}{t}{y}' (<- '{h}{a}{r}{m}{a}{t}') // гармати
857
+ '{d}{e}{p}{u}{t}{a}{t}{y}' (<- '{d}{e}{p}{u}{t}{a}{t}') // депутати
858
+ '{v}{y}{t}{r}{a}{t}{y}' (<- '{v}{y}{t}{r}{a}{t}') // витрати
859
+ '{s}{o}{l}{d}{a}{t}{y}' (<- '{s}{o}{l}{d}{a}{t}') // солдати
860
+ '{sh}{t}{a}{t}{y}' (<- '{sh}{t}{a}{t}') // штати
861
+ '{o}{r}{b}{i}{t}{y}' (<- '{o}{r}{b}{i}{t}') // орбіти
862
+ '{k}{i}{m}{n}{a}{t}{y}' (<- '{k}{i}{m}{n}{a}{t}') // кімнати
863
+ '{p}{r}{o}{s}{v}{i}{t}{y}' (<- '{p}{r}{o}{s}{v}{i}{t}') // просвіти
864
+ '{s}{t}{r}{a}{t}{y}' (<- '{s}{t}{r}{a}{t}') // страти
865
+ '{k}{o}{o}{r}{d}{y}{n}{a}{t}{y}' (<- '{k}{o}{o}{r}{d}{y}{n}{a}{t}') // координати
866
+ '{l}{a}{u}{r}{e}{a}{t}{y}' (<- '{l}{a}{u}{r}{e}{a}{t}') // лауреати
867
+ '{k}{a}{n}{d}{y}{d}{a}{t}{y}' (<- '{k}{a}{n}{d}{y}{d}{a}{t}') // кандидати
868
+ '{ch}{e}{m}{p}{i}{o}{n}{a}{t}{y}' (<- '{ch}{e}{m}{p}{i}{o}{n}{a}{t}') // чемпіонати
869
+ '{p}{l}{y}{t}{y}' (<- '{p}{l}{y}{t}') // плити
870
+ '{a}{p}{a}{r}{a}{t}{y}' (<- '{a}{p}{a}{r}{a}{t}') // апарати
871
+ '{p}{r}{e}{p}{a}{r}{a}{t}{y}' (<- '{p}{r}{e}{p}{a}{r}{a}{t}') // препарати
872
+ '{e}{l}{i}{t}{y}' (<- '{e}{l}{i}{t}') // еліти
873
+ '{z}{v}{i}{t}{y}' (<- '{z}{v}{i}{t}') // звіти
874
+ '{o}{p}{l}{a}{t}{y}' (<- '{o}{p}{l}{a}{t}') // оплати
875
+ '{s}{v}{i}{t}{y}' (<- '{s}{v}{i}{t}') // світи
876
+ '{s}{p}{l}{a}{t}{y}' (<- '{s}{p}{l}{a}{t}') // сплати
877
+ '{v}{y}{p}{l}{a}{t}{y}' (<- '{v}{y}{p}{l}{a}{t}') // виплати
878
+ '{e}{k}{s}{p}{o}{n}{a}{t}{y}' (<- '{e}{k}{s}{p}{o}{n}{a}{t}') // експонати
879
+ '{i}{s}{p}{y}{t}{y}' (<- '{i}{s}{p}{y}{t}') // іспити
880
+ '{ts}{y}{t}{a}{t}{y}' (<- '{ts}{y}{t}{a}{t}') // цитати
881
+ '{m}{a}{r}{h}{a}{r}{y}{t}{y}' (<- '{m}{a}{r}{h}{a}{r}{y}{t}') // Маргарити
882
+ '{h}{r}{a}{n}{a}{t}{y}' (<- '{h}{r}{a}{n}{a}{t}') // гранати
883
+ '{p}{o}{v}{i}{t}{y}' (<- '{p}{o}{v}{i}{t}') // повіти
884
+ '{z}{a}{p}{y}{t}{y}' (<- '{z}{a}{p}{y}{t}') // запити
885
+ '{d}{e}{m}{o}{k}{r}{a}{t}{y}' (<- '{d}{e}{m}{o}{k}{r}{a}{t}') // демократи
886
+ '{f}{o}{r}{m}{a}{t}{y}' (<- '{f}{o}{r}{m}{a}{t}') // формати
887
+ '{a}{h}{r}{e}{h}{a}{t}{y}' (<- '{a}{h}{r}{e}{h}{a}{t}') // агрегати
888
+ // Genitive plurals in -ей whose stem differs from the other forms:
889
+ // статей (стаття → статт) would meet стать; сімей (сім'я → сім')
890
+ // would meet the numeral сім
891
+ '{s}{t}{a}{t}{e}{i`}' (<- '{s}{t}{a}{t}{t}') // статей
892
+ '{s}{i}{m}{e}{i`}' (<- '{s}{i}{m}{ap}') // сімей
893
+ // Names and nouns in -ей after т, м, н, л, or too short for the
894
+ // letter to be tested, where -ей is otherwise the genitive plural
895
+ // ending: the е stays, as in their other forms (музею → музе)
896
+ '{m}{u}{z}{e}{i`}' (<- '{m}{u}{z}{e}') // музей
897
+ '{l}{i}{ts}{e}{i`}' (<- '{l}{i}{ts}{e}') // ліцей
898
+ '{kh}{o}{k}{e}{i`}' (<- '{kh}{o}{k}{e}') // хокей
899
+ '{ie}{v}{r}{e}{i`}' (<- '{ie}{v}{r}{e}') // єврей
900
+ '{i}{ie}{r}{e}{i`}' (<- '{i}{ie}{r}{e}') // ієрей
901
+ '{o}{r}{f}{e}{i`}' (<- '{o}{r}{f}{e}') // Орфей
902
+ '{t}{a}{d}{e}{i`}' (<- '{t}{a}{d}{e}') // Тадей
903
+ '{m}{a}{ts}{e}{i`}' (<- '{m}{a}{ts}{e}') // Мацей
904
+ '{p}{r}{o}{m}{e}{t}{e}{i`}' (<- '{p}{r}{o}{m}{e}{t}{e}') // Прометей
905
+ '{m}{a}{t}{e}{i`}' (<- '{m}{a}{t}{e}') // Матей
906
+ '{p}{t}{o}{l}{e}{m}{e}{i`}' (<- '{p}{t}{o}{l}{e}{m}{e}') // Птолемей
907
+ '{s}{i}{d}{n}{e}{i`}' (<- '{s}{i}{d}{n}{e}') // Сідней
908
+ '{d}{i}{s}{n}{e}{i`}' (<- '{d}{i}{s}{n}{e}') // Дісней
909
+ '{b}{r}{u}{n}{e}{i`}' (<- '{b}{r}{u}{n}{e}') // Бруней
910
+ '{e}{n}{e}{i`}' (<- '{e}{n}{e}') // Еней
911
+ '{i}{r}{y}{n}{e}{i`}' (<- '{i}{r}{y}{n}{e}') // Іриней
912
+ '{iu}{v}{i}{l}{e}{i`}' (<- '{iu}{v}{i}{l}{e}') // ювілей
913
+ '{p}{r}{y}{v}{i}{l}{e}{i`}' (<- '{p}{r}{y}{v}{i}{l}{e}') // привілей
914
+ '{k}{l}{e}{i`}' (<- '{k}{l}{e}') // клей
915
+ '{m}{a}{v}{z}{o}{l}{e}{i`}' (<- '{m}{a}{v}{z}{o}{l}{e}') // мавзолей
916
+ '{d}{y}{s}{p}{l}{e}{i`}' (<- '{d}{y}{s}{p}{l}{e}') // дисплей
917
+ '{h}{a}{l}{i}{l}{e}{i`}' (<- '{h}{a}{l}{i}{l}{e}') // Галілей
918
+ // Numerals in -яти whose с/апостроф sits outside pV, so the -яти
919
+ // guard cannot see it (десяти → десят as десять)
920
+ '{d}{e}{s}{ia}{t}{y}' (<- '{d}{e}{s}{ia}{t}') // десяти
921
+ '{d}{e}{s}{ia}{t}{'}' (<- '{d}{e}{s}{ia}{t}') // десять
922
+ // Months and other -ень/-інь nouns with a fleeting or alternating
923
+ // vowel: the nominative takes the stem of the oblique forms
924
+ // (березень/березня → березн, рівень/рівня → рівн, камінь/каменя → камен)
925
+ '{s}{i}{ch}{e}{n}{'}' (<- '{s}{i}{ch}{n}') // січень
926
+ '{b}{e}{r}{e}{z}{e}{n}{'}' (<- '{b}{e}{r}{e}{z}{n}') // березень
927
+ '{k}{v}{i}{t}{e}{n}{'}' (<- '{k}{v}{i}{t}{n}') // квітень
928
+ '{t}{r}{a}{v}{e}{n}{'}' (<- '{t}{r}{a}{v}{n}') // травень
929
+ '{ch}{e}{r}{v}{e}{n}{'}' (<- '{ch}{e}{r}{v}{n}') // червень
930
+ '{l}{y}{p}{e}{n}{'}' (<- '{l}{y}{p}{n}') // липень
931
+ '{s}{e}{r}{p}{e}{n}{'}' (<- '{s}{e}{r}{p}{n}') // серпень
932
+ '{v}{e}{r}{e}{s}{e}{n}{'}' (<- '{v}{e}{r}{e}{s}{n}') // вересень
933
+ '{zh}{o}{v}{t}{e}{n}{'}' (<- '{zh}{o}{v}{t}{n}') // жовтень
934
+ '{h}{r}{u}{d}{e}{n}{'}' (<- '{h}{r}{u}{d}{n}') // грудень
935
+ '{r}{i}{v}{e}{n}{'}' (<- '{r}{i}{v}{n}') // рівень
936
+ '{u}{ch}{e}{n}{'}' (<- '{u}{ch}{n}') // учень
937
+ '{s}{t}{u}{p}{i}{n}{'}' (<- '{s}{t}{u}{p}{e}{n}') // ступінь
938
+ '{p}{r}{o}{m}{i}{n}{'}' (<- '{p}{r}{o}{m}{e}{n}') // промінь
939
+ '{k}{a}{m}{i}{n}{'}' (<- '{k}{a}{m}{e}{n}') // камінь
940
+ '{k}{o}{r}{i}{n}{'}' (<- '{k}{o}{r}{e}{n}') // корінь
941
+ '{p}{ap}{ia}{t}{y}' (<- '{p}{ap}{ia}{t}') // п'яти
942
+ '{d}{e}{v}{ap}{ia}{t}{y}' (<- '{d}{e}{v}{ap}{ia}{t}') // дев'яти
943
+ // пророк keeps its о (not fleeting: пророка), unlike будинок/будинку
944
+ '{p}{r}{o}{r}{o}{k}' (<- '{p}{r}{o}{r}{o}{k}') // пророк
945
+ '{p}{r}{o}{r}{o}{k}{a}' (<- '{p}{r}{o}{r}{o}{k}') // пророка
946
+ '{p}{r}{o}{r}{o}{k}{u}' (<- '{p}{r}{o}{r}{o}{k}') // пророку
947
+ '{p}{r}{o}{r}{o}{k}{o}{m}' (<- '{p}{r}{o}{r}{o}{k}') // пророком
948
+ '{p}{r}{o}{r}{o}{k}{y}' (<- '{p}{r}{o}{r}{o}{k}') // пророки
949
+ '{p}{r}{o}{r}{o}{k}{i}{v}' (<- '{p}{r}{o}{r}{o}{k}') // пророків
950
+ // людина/люди and дитина/діти: singular and plural have different
951
+ // roots; the singular takes the stem of the plural
952
+ '{l}{iu}{d}{y}{n}{a}' (<- '{l}{iu}{d}') // людина
953
+ '{l}{iu}{d}{y}{n}{y}' (<- '{l}{iu}{d}') // людини
954
+ '{l}{iu}{d}{y}{n}{i}' (<- '{l}{iu}{d}') // людині
955
+ '{l}{iu}{d}{y}{n}{u}' (<- '{l}{iu}{d}') // людину
956
+ '{l}{iu}{d}{y}{n}{o}{iu}' (<- '{l}{iu}{d}') // людиною
957
+ '{d}{y}{t}{y}{n}{a}' (<- '{d}{i}{t}') // дитина
958
+ '{d}{y}{t}{y}{n}{y}' (<- '{d}{i}{t}') // дитини
959
+ '{d}{y}{t}{y}{n}{i}' (<- '{d}{i}{t}') // дитині
960
+ '{d}{y}{t}{y}{n}{u}' (<- '{d}{i}{t}') // дитину
961
+ '{d}{y}{t}{y}{n}{o}{iu}' (<- '{d}{i}{t}') // дитиною
962
+ // день: every form is too short for pV, so the whole paradigm is listed
963
+ '{d}{e}{n}{'}' (<- '{d}{n}') // день
964
+ '{d}{n}{ia}' (<- '{d}{n}') // дня
965
+ '{d}{n}{iu}' (<- '{d}{n}') // дню
966
+ '{d}{n}{e}{m}' (<- '{d}{n}') // днем
967
+ '{d}{n}{i}' (<- '{d}{n}') // дні
968
+ '{d}{n}{i}{v}' (<- '{d}{n}') // днів
969
+ '{d}{n}{ia}{m}' (<- '{d}{n}') // дням
970
+ '{d}{n}{ia}{m}{y}' (<- '{d}{n}') // днями
971
+ '{d}{n}{ia}{kh}' (<- '{d}{n}') // днях
972
+ // genitive plurals with a fleeting е (земля → земель, будівля → будівель)
973
+ '{z}{e}{m}{e}{l}{'}' (<- '{z}{e}{m}{l}') // земель
974
+ '{b}{u}{d}{i}{v}{e}{l}{'}' (<- '{b}{u}{d}{i}{v}') // будівель
975
+ // голова → голів (gen pl) would meet гол (goal)
976
+ '{h}{o}{l}{i}{v}' (<- '{h}{o}{l}{o}{v}') // голів
977
+ // євангеліє is the same noun as євангелія
978
+ '{ie}{v}{a}{n}{h}{e}{l}{i}{ie}' (<- '{ie}{v}{a}{n}{h}{e}{l}') // євангеліє
979
+ // осінь/осені: і/е alternation
980
+ '{o}{s}{i}{n}{'}' (<- '{o}{s}{e}{n}') // осінь
981
+ // Cities whose nominative -ів alternates with -ов/-ев/-ол
982
+ '{l}{'}{v}{i}{v}' (<- '{l}{'}{v}{o}{v}') // Львів
983
+ '{kh}{a}{r}{k}{i}{v}' (<- '{kh}{a}{r}{k}{o}{v}') // Харків
984
+ '{ch}{e}{r}{n}{i}{h}{i}{v}' (<- '{ch}{e}{r}{n}{i}{h}') // Чернігів (Чернігова → черніг via -ов)
985
+ '{m}{y}{k}{o}{l}{a}{yi}{v}' (<- '{m}{y}{k}{o}{l}{a}{ie}{v}') // Миколаїв
986
+ '{t}{e}{r}{n}{o}{p}{i}{l}{'}' (<- '{t}{e}{r}{n}{o}{p}{o}{l}') // Тернопіль
987
+ '{b}{o}{r}{y}{s}{p}{i}{l}{'}' (<- '{b}{o}{r}{y}{s}{p}{o}{l}') // Бориспіль
988
+ // Place names in -ань are not the genitive plural of a -ння noun
989
+ '{b}{e}{r}{e}{z}{a}{n}{'}' (<- '{b}{e}{r}{e}{z}{a}{n}') // Березань
990
+ '{a}{s}{t}{r}{a}{kh}{a}{n}{'}' (<- '{a}{s}{t}{r}{a}{kh}{a}{n}') // Астрахань
991
+ '{b}{o}{t}{o}{sh}{a}{n}{'}' (<- '{b}{o}{t}{o}{sh}{a}{n}') // Ботошань
992
+ // останній: its feminine and plural forms look like a -ння noun
993
+ '{o}{s}{t}{a}{n}{n}{ia}' (<- '{o}{s}{t}{a}{n}') // остання
994
+ '{o}{s}{t}{a}{n}{n}{iu}' (<- '{o}{s}{t}{a}{n}') // останню
995
+ '{o}{s}{t}{a}{n}{n}{i}' (<- '{o}{s}{t}{a}{n}') // останні
996
+ '{p}{i}{v}{d}{e}{n}{n}{i}' (<- '{p}{i}{v}{d}{e}{n}') // південні
997
+ '{shch}{o}{d}{e}{n}{n}{i}' (<- '{shch}{o}{d}{e}{n}') // щоденні
998
+ '{s}{v}{ia}{shch}{e}{n}{n}{i}' (<- '{s}{v}{ia}{shch}{e}{n}') // священні
999
+ '{d}{zh}{o}{v}{a}{n}{n}{i}' (<- '{d}{zh}{o}{v}{a}{n}') // Джованні
1000
+ '{l}{o}{z}{a}{n}{n}{i}' (<- '{l}{o}{z}{a}{n}') // Лозанні
1001
+ // Nouns in -ань that are not the genitive plural of a -ння noun
1002
+ '{v}{i}{d}{s}{t}{a}{n}{'}' (<- '{v}{i}{d}{s}{t}{a}{n}') // відстань
1003
+ '{v}{i}{d}{s}{t}{a}{n}{n}{iu}' (<- '{v}{i}{d}{s}{t}{a}{n}') // відстанню
1004
+ '{t}{a}{i`}{v}{a}{n}{'}' (<- '{t}{a}{i`}{v}{a}{n}') // Тайвань
1005
+ '{h}{a}{v}{a}{n}{'}' (<- '{h}{a}{v}{a}{n}') // гавань
1006
+ '{b}{r}{e}{t}{a}{n}{'}' (<- '{b}{r}{e}{t}{a}{n}') // Бретань
1007
+ '{k}{u}{b}{a}{n}{'}' (<- '{k}{u}{b}{a}{n}') // Кубань
1008
+ '{p}{r}{y}{s}{t}{a}{n}{'}' (<- '{p}{r}{y}{s}{t}{a}{n}') // пристань
1009
+ '{p}{o}{z}{n}{a}{n}{'}' (<- '{p}{o}{z}{n}{a}{n}') // Познань
1010
+ '{r}{ia}{z}{a}{n}{'}' (<- '{r}{ia}{z}{a}{n}') // Рязань
1011
+ '{iu}{n}{'}{n}{a}{n}{'}' (<- '{iu}{n}{'}{n}{a}{n}') // Юньнань
1012
+ '{kh}{a}{i`}{n}{a}{n}{'}' (<- '{kh}{a}{i`}{n}{a}{n}') // Хайнань
1013
+ '{h}{o}{r}{b}{a}{n}{'}' (<- '{h}{o}{r}{b}{a}{n}') // Горбань
1014
+ '{d}{o}{v}{h}{a}{n}{'}' (<- '{d}{o}{v}{h}{a}{n}') // Довгань
1015
+ // мішень (target) and домен (domain): -енню/-енні are not the
1016
+ // verbal-noun cases here
1017
+ '{m}{i}{sh}{e}{n}{'}' (<- '{m}{i}{sh}{e}{n}') // мішень
1018
+ '{m}{i}{sh}{e}{n}{n}{iu}' (<- '{m}{i}{sh}{e}{n}') // мішенню
1019
+ '{d}{o}{m}{e}{n}{n}{i}' (<- '{d}{o}{m}{e}{n}') // доменні
1020
+ // відання (jurisdiction) would become the preposition від
1021
+ '{v}{i}{d}{a}{n}{n}{ia}' (<- '{v}{i}{d}{a}{n}') // відання
1022
+ '{v}{i}{d}{a}{n}{n}{i}' (<- '{v}{i}{d}{a}{n}') // віданні
1023
+ // Plurals of -нний adjectives that look like the locative of a -ння noun
1024
+ '{p}{r}{y}{t}{a}{m}{a}{n}{n}{i}' (<- '{p}{r}{y}{t}{a}{m}{a}{n}') // притаманні
1025
+ '{n}{e}{ch}{y}{s}{l}{e}{n}{n}{i}' (<- '{n}{e}{ch}{y}{s}{l}{e}{n}') // нечисленні
1026
+ '{d}{o}{r}{o}{h}{o}{ts}{i}{n}{n}{i}' (<- '{d}{o}{r}{o}{h}{o}{ts}{i}{n}') // дорогоцінні
1027
+ '{n}{e}{s}{k}{i}{n}{ch}{e}{n}{n}{i}' (<- '{n}{e}{s}{k}{i}{n}{ch}{e}{n}') // нескінченні
1028
+ '{b}{a}{r}{a}{b}{a}{n}{n}{i}' (<- '{b}{a}{r}{a}{b}{a}{n}') // барабанні
1029
+ '{f}{o}{r}{t}{e}{p}{i}{a}{n}{n}{i}' (<- '{f}{o}{r}{t}{e}{p}{i}{a}{n}') // фортепіанні
1030
+ '{p}{o}{v}{n}{o}{ts}{i}{n}{n}{i}' (<- '{p}{o}{v}{n}{o}{ts}{i}{n}') // повноцінні
1031
+ // Locative singular of -ка/-га nouns with к→ц, г→з: the 43 forms
1032
+ // with at least 2000 occurrences (511k in all; віці alone 197k).
1033
+ // No rule can do this: -ці is also the plural of -ець (українці)
1034
+ // and -иці the plural of -иця (вулиці).
1035
+ '{v}{i}{ts}{i}' (<- '{v}{i}{k}') // віці
1036
+ '{o}{k}{r}{u}{z}{i}' (<- '{o}{k}{r}{u}{h}') // окрузі
1037
+ '{l}{i}{z}{i}' (<- '{l}{i}{h}') // лізі
1038
+ '{a}{m}{e}{r}{y}{ts}{i}' (<- '{a}{m}{e}{r}{y}{k}') // америці
1039
+ '{r}{i}{ch}{ts}{i}' (<- '{r}{i}{ch}{k}') // річці
1040
+ '{k}{n}{y}{z}{i}' (<- '{k}{n}{y}{h}') // книзі
1041
+ '{a}{f}{r}{y}{ts}{i}' (<- '{a}{f}{r}{y}{k}') // африці
1042
+ '{r}{e}{s}{p}{u}{b}{l}{i}{ts}{i}' (<- '{r}{e}{s}{p}{u}{b}{l}{i}{k}') // республіці
1043
+ '{s}{m}{u}{z}{i}' (<- '{s}{m}{u}{h}') // смузі
1044
+ '{b}{i}{b}{l}{i}{o}{t}{e}{ts}{i}' (<- '{b}{i}{b}{l}{i}{o}{t}{e}{k}') // бібліотеці
1045
+ '{p}{r}{y}{s}{ia}{z}{i}' (<- '{p}{r}{y}{s}{ia}{h}') // присязі
1046
+ '{d}{o}{r}{o}{z}{i}' (<- '{d}{o}{r}{o}{h}') // дорозі
1047
+ '{d}{i}{l}{ia}{n}{ts}{i}' (<- '{d}{i}{l}{ia}{n}{k}') // ділянці
1048
+ '{p}{r}{a}{k}{t}{y}{ts}{i}' (<- '{p}{r}{a}{k}{t}{y}{k}') // практиці
1049
+ '{f}{u}{t}{b}{o}{l}{ts}{i}' (<- '{f}{u}{t}{b}{o}{l}{k}') // футболці
1050
+ '{v}{a}{z}{i}' (<- '{v}{a}{h}') // вазі
1051
+ '{v}{y}{s}{t}{a}{v}{ts}{i}' (<- '{v}{y}{s}{t}{a}{v}{k}') // виставці
1052
+ '{m}{e}{k}{s}{y}{ts}{i}' (<- '{m}{e}{k}{s}{y}{k}') // мексиці
1053
+ '{p}{r}{a}{z}{i}' (<- '{p}{r}{a}{h}') // празі
1054
+ '{r}{o}{z}{r}{o}{b}{ts}{i}' (<- '{r}{o}{z}{r}{o}{b}{k}') // розробці
1055
+ '{z}{a}{t}{o}{ts}{i}' (<- '{z}{a}{t}{o}{k}') // затоці
1056
+ '{t}{o}{ch}{ts}{i}' (<- '{t}{o}{ch}{k}') // точці
1057
+ '{p}{o}{l}{i}{t}{y}{ts}{i}' (<- '{p}{o}{l}{i}{t}{y}{k}') // політиці
1058
+ '{m}{u}{z}{y}{ts}{i}' (<- '{m}{u}{z}{y}{k}') // музиці
1059
+ '{u}{v}{a}{z}{i}' (<- '{u}{v}{a}{h}') // увазі
1060
+ '{p}{i}{d}{h}{o}{t}{o}{v}{ts}{i}' (<- '{p}{i}{d}{h}{o}{t}{o}{v}{k}') // підготовці
1061
+ '{h}{o}{n}{ts}{i}' (<- '{h}{o}{n}{k}') // гонці
1062
+ '{t}{r}{i}{i`}{ts}{i}' (<- '{t}{r}{i}{i`}{k}') // трійці
1063
+ '{s}{t}{o}{r}{i}{n}{ts}{i}' (<- '{s}{t}{o}{r}{i}{n}{k}') // сторінці
1064
+ '{n}{a}{u}{ts}{i}' (<- '{n}{a}{u}{k}') // науці
1065
+ '{p}{i}{d}{t}{r}{y}{m}{ts}{i}' (<- '{p}{i}{d}{t}{r}{y}{m}{k}') // підтримці
1066
+ '{t}{e}{kh}{n}{i}{ts}{i}' (<- '{t}{e}{kh}{n}{i}{k}') // техніці
1067
+ '{n}{y}{z}{ts}{i}' (<- '{n}{y}{z}{k}') // низці
1068
+ '{k}{l}{a}{d}{ts}{i}' (<- '{k}{l}{a}{d}{k}') // кладці
1069
+ '{e}{k}{o}{n}{o}{m}{i}{ts}{i}' (<- '{e}{k}{o}{n}{o}{m}{i}{k}') // економіці
1070
+ '{s}{t}{r}{i}{ch}{ts}{i}' (<- '{s}{t}{r}{i}{ch}{k}') // стрічці
1071
+ '{r}{u}{ts}{i}' (<- '{r}{u}{k}') // руці
1072
+ '{z}{b}{i}{r}{ts}{i}' (<- '{z}{b}{i}{r}{k}') // збірці
1073
+ '{ch}{e}{r}{z}{i}' (<- '{ch}{e}{r}{h}') // черзі
1074
+ '{k}{r}{y}{t}{y}{ts}{i}' (<- '{k}{r}{y}{t}{y}{k}') // критиці
1075
+ '{f}{a}{b}{r}{y}{ts}{i}' (<- '{f}{a}{b}{r}{y}{k}') // фабриці
1076
+ '{o}{b}{k}{l}{a}{d}{y}{n}{ts}{i}' (<- '{o}{b}{k}{l}{a}{d}{y}{n}{k}') // обкладинці
1077
+ '{r}{y}{z}{i}' (<- '{r}{y}{h}') // ризі
1078
+ // Frequent adverbs, pronouns and particles whose stem would collide
1079
+ // with a content word (потім → пот, тому → том, біля → біл,
1080
+ // коли → кол, далі → дал, нічого → ніч). Listed last with no
1081
+ // command, so they are left unchanged.
1082
+ '{b}{i}{l}{ia}' // біля
1083
+ '{p}{r}{o}{t}{y}' // проти
1084
+ '{k}{o}{l}{y}' // коли
1085
+ '{d}{a}{l}{i}' // далі
1086
+ '{r}{a}{z}{o}{m}' // разом
1087
+ '{s}{a}{m}{e}' // саме
1088
+ '{m}{a}{l}{o}' // мало
1089
+ '{p}{o}{t}{i}{m}' // потім
1090
+ '{t}{o}{m}{u}' // тому
1091
+ '{l}{y}{sh}{e}' // лише
1092
+ '{d}{u}{zh}{e}' // дуже
1093
+ '{m}{a}{i`}{zh}{e}' // майже
1094
+ '{t}{o}{d}{i}' // тоді
1095
+ '{s}{e}{b}{e}' // себе
1096
+ '{z}{n}{o}{v}{u}' // знову
1097
+ '{z}{a}{m}{i}{s}{t}{'}' // замість
1098
+ '{p}{o}{k}{y}' // поки
1099
+ '{o}{k}{r}{i}{m}' // окрім
1100
+ '{k}{u}{d}{y}' // куди
1101
+ '{v}{e}{s}{'}' // весь
1102
+ '{u}{v}{e}{s}{'}' // увесь
1103
+ '{t}{r}{e}{b}{a}' // треба
1104
+ '{k}{o}{h}{o}' // кого
1105
+ '{k}{o}{m}{u}' // кому
1106
+ '{t}{e}{b}{e}' // тебе
1107
+ '{d}{e}{s}{'}' // десь
1108
+ '{l}{e}{d}{'}' // ледь
1109
+ '{t}{u}{d}{y}' // туди
1110
+ '{n}{i}{ch}{o}{h}{o}' // нічого
1111
+ '{i}{n}{a}{k}{sh}{e}' // інакше
1112
+ '{ch}{o}{m}{u}' // чому
1113
+ '{d}{o}{s}{i}' // досі
1114
+ '{z}{v}{i}{d}{k}{y}' // звідки
1115
+ '{z}{v}{i}{d}{s}{y}' // звідси
1116
+ '{z}{v}{i}{d}{t}{y}' // звідти
1117
+ '{shch}{o}{i`}{n}{o}' // щойно
1118
+ '{s}{p}{r}{a}{v}{d}{i}' // справді
1119
+ '{z}{a}{v}{zh}{d}{y}' // завжди
1120
+ '{s}{'}{o}{h}{o}{d}{n}{i}' // сьогодні
1121
+ '{z}{h}{o}{d}{o}{m}' // згодом
1122
+ '{i}{n}{o}{d}{i}' // іноді
1123
+ '{i}{n}{k}{o}{l}{y}' // інколи
1124
+ '{k}{o}{l}{y}{s}{'}' // колись
1125
+ '{v}{i}{d}{t}{o}{d}{i}' // відтоді
1126
+ '{d}{o}{t}{e}{p}{e}{r}' // дотепер
1127
+ // Nouns whose genitive plural or nominative would be read as a verb
1128
+ // form or hit an alternation rule: справ, держав (not past tense),
1129
+ // Сибір (Сибіру, not -бір/-бор), вплив, посів, архів, масив (the
1130
+ // -в of a 5-letter word goes as a past tense: почав, забив)
1131
+ '{s}{p}{r}{a}{v}' // справ
1132
+ '{d}{e}{r}{zh}{a}{v}' // держав
1133
+ '{s}{y}{b}{i}{r}' // Сибір
1134
+ '{v}{p}{l}{y}{v}' // вплив
1135
+ '{p}{o}{s}{i}{v}' // посів
1136
+ '{a}{r}{kh}{i}{v}' // архів
1137
+ '{m}{a}{s}{y}{v}' // масив
1138
+ )
1139
+ )
1140
+ or
1141
+ (
1142
+ // Vowel alternation in the closed last syllable of the most frequent
1143
+ // noun families: the nominative has і where every other form has о
1144
+ // (захід/заходу, вибір/вибору, ніч/ночі, стіл/столу). Applied to
1145
+ // the whole word before suffix removal, outside pV.
1146
+ do ( backwards (
1147
+ [substring] among (
1148
+ // (-від and -віз are left alone: досвід/досвіду and девіз keep
1149
+ // the і, and Девід, Давід are names)
1150
+ '{kh}{i}{d}' (<- '{kh}{o}{d}') // захід, дохід, схід, вихід, хід
1151
+ '{b}{i}{r}' (<- '{b}{o}{r}') // вибір, збір, набір, відбір
1152
+ '{r}{i}{s}{t}' (<- '{r}{o}{s}{t}') // зріст, приріст
1153
+ '{n}{i}{ch}' (<- '{n}{o}{ch}') // ніч, північ
1154
+ // The rest only as whole words: вологість, кисіль, Готфрід
1155
+ // end the same way and keep their і
1156
+ '{d}{i}{m}' (atlimit <- '{d}{o}{m}') // дім
1157
+ '{s}{t}{i}{l}' (atlimit <- '{s}{t}{o}{l}') // стіл
1158
+ '{p}{i}{ch}' (atlimit <- '{p}{e}{ch}') // піч
1159
+ '{s}{i}{l}{'}' (atlimit <- '{s}{o}{l}') // сіль
1160
+ '{k}{i}{n}{'}' (atlimit <- '{k}{o}{n}') // кінь
1161
+ '{h}{i}{s}{t}{'}' (atlimit <- '{h}{o}{s}{t}') // гість
1162
+ '{p}{l}{i}{d}' (atlimit <- '{p}{l}{o}{d}') // плід
1163
+ '{r}{i}{d}' (atlimit <- '{r}{o}{d}') // рід
1164
+ '{b}{i}{k}' (atlimit <- '{b}{o}{k}') // бік
1165
+ '{k}{i}{t}' (atlimit <- '{k}{o}{t}') // кіт
1166
+ '{r}{i}{h}' (atlimit <- '{r}{o}{h}') // ріг
1167
+ '{s}{i}{k}' (atlimit <- '{s}{o}{k}') // сік
1168
+ )
1169
+ ) )
1170
+ // Guards for the verb endings -ла/-ли/-ло and -ти, tested on the
1171
+ // whole word (after an optional -ся/-сь) so that the letter before
1172
+ // the ending is seen in 5-letter words too, where it sits outside
1173
+ // pV (школа → школ, число → числ, карти → карт, факти → факт).
1174
+ //
1175
+ // -ла/-ли/-ло is not a past tense after о (Микола, школа, апостоли,
1176
+ // навколо: nouns far outnumber verbs like виборола), after л, т, д,
1177
+ // в, й, б, п (Абдулла, світло, сідло, Павло, Михайло, срібло,
1178
+ // тепло: the verbs with these before the ending are rare, пливла,
1179
+ // ослабла), after р (Карла, гирло, горло: the frequent verbs
1180
+ // померла, вимерли are listed as exceptions), or after е unless
1181
+ // -вело (весело, ремесло are not verbs; призвело, привело are).
1182
+ // -ороли/-орола are the one verb family behind о (бороли,
1183
+ // виборола), so о only guards when not preceded by р;
1184
+ // стала/стали/стало are the past of стати, so т does not guard
1185
+ // the bare с.
1186
+ //
1187
+ // -ти is not an infinitive after н, е, о, іс, ис (документи,
1188
+ // портрети, роботи, спеціалісти, листи), nor after к, р, ш, ф, х,
1189
+ // п, б, в, л, м, т, ь, ю, є (пункти, карти, кошти, нафти, шахти,
1190
+ // рецепти, хребти, астронавти, Ялти, Мальти, валюти, дієти): the
1191
+ // infinitives in -кти and -рти (втекти, померти) are listed as
1192
+ // exceptions, the rest are rare (текти, стерти, гребти, пливти).
1193
+ unset found_la_noun
1194
+ unset found_ty_noun
1195
+ do ( backwards (
1196
+ // the same reflexive endings as the reflexive rule removes
1197
+ try ( among ( '{t}{y}{s}{ia}' '{t}{y}{s}{'}' '{l}{a}{s}{'}'
1198
+ '{v}{s}{ia}' '{v}{s}{'}' '{s}{ia}' '{s}{'}' ) )
1199
+ ( ( ( '{l}{a}' or '{l}{y}' or '{l}{o}' )
1200
+ ( ( '{o}' not '{r}' ) or '{l}' or ( '{t}' not ( '{s}' atlimit ) )
1201
+ or '{d}' or '{v}' or '{i`}' or '{b}' or '{p}' or '{r}'
1202
+ or ( '{e}' not '{v}' ) )
1203
+ set found_la_noun )
1204
+ or
1205
+ ( '{t}{y}'
1206
+ ( '{n}' or '{e}' or '{o}' or '{i}{s}' or '{y}{s}'
1207
+ or '{k}' or '{r}' or '{sh}' or '{f}' or '{kh}' or '{p}' or '{b}'
1208
+ or '{v}' or '{l}' or '{m}' or '{t}' or '{'}' or '{iu}' or '{ie}' )
1209
+ set found_ty_noun ) )
1210
+ ) )
1211
+ unset found_diminutive
1212
+ unset found_professional
1213
+ unset found_ia
1214
+ unset found_verb
1215
+ mark_regions // signals 'f' if input < 3 characters
1216
+ backwards setlimit tomark pV for (
1217
+ do (
1218
+ perfective_gerund or
1219
+ ( reflexive_full set found_verb ) or
1220
+ ( try ( reflexive set found_verb )
1221
+ ( verbal_noun or
1222
+ // do(): after a replacement (-ок <- к) the cursor sits
1223
+ // left of the new text; do() puts it back at the end so
1224
+ // the rules below see the whole word (залишок → залишк)
1225
+ ( do ( ( professional (set found_professional) )
1226
+ or ( diminutive (set found_diminutive) ) )
1227
+ // found_verb: a verb stem may end in -іш (вирішити →
1228
+ // виріш); comparative must leave it alone
1229
+ not found_professional ( adjective or (verb set found_verb) or noun )
1230
+ )
1231
+ )
1232
+ )
1233
+ )
1234
+ // Diminutive stems (after adjective endings removed)
1235
+ try ( diminutive_stem (set found_diminutive) )
1236
+
1237
+ // Professional suffixes (after noun declension removed)
1238
+ // Skip if diminutive already fired (prevents -ач removal on собач- from собаченітко)
1239
+ // Inside do(): a failing 'not' must not abort the steps below
1240
+ // (found_professional words still need derivational and tidy_up:
1241
+ // командувач → командув → команд, будильник → будил)
1242
+ do ( not found_diminutive not found_professional not found_ia professional )
1243
+
1244
+ do ( not found_verb comparative )
1245
+
1246
+ // Derivational suffixes (in R2 only)
1247
+ do derivational
1248
+ do tidy_up
1249
+ )
1250
+ )
1251
+ )