phraseology_generator.py
16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# -*- coding: utf-8 -*-
from dictionary.models import sort_arguments, sort_positions, sortatributes
from settings import MORFEUSZ2
from copy import deepcopy
def lexicalisation(argument, subj, base, negativity, reference=None):
b = argument.type
if b == 'fixed':
return (get_words(sortatributes(argument)[-1]), [], 1)
attributes = sortatributes(argument)
lexicalisation_type = attributes[0].values.all()[0].argument.type
lexicalisation_parameters = sortatributes(attributes[0].values.all()[0].argument)
if lexicalisation_type == 'xp': # xp(...)[np/prepnp], ...
lexicalisation_type = lexicalisation_parameters[0].values.all()[0].argument.type
lexicalisation_parameters = sortatributes(lexicalisation_parameters[0].values.all()[0].argument)
if lexicalisation_type == 'np': # np(case), number, nouns, atr
nps = get_nps(get_case(lexicalisation_parameters[0], subj, negativity), get_number(attributes[1], subj), get_words(attributes[2]), attributes[3])
if subj:
return (nps, get_verb(base, get_number(attributes[1], subj), subj), -1)
else:
return (nps, [], 1)
elif lexicalisation_type == 'prepnp': #prepnp(prep, case), number, nouns, atr
prepnps = get_prepnps(get_preposition(lexicalisation_parameters[0]), get_case(lexicalisation_parameters[1], subj, negativity), get_number(attributes[1], subj), get_words(attributes[2]), attributes[3])
return (prepnps, [], 1)
elif lexicalisation_type == 'adjp': # adjp(case), number, gender, degree, adjectives, atr
adjps = get_adjps(get_case(lexicalisation_parameters[0], subj, negativity, reference), get_number(attributes[1], subj, reference), get_gender(attributes[2], reference), get_degree(attributes[3]), get_words(attributes[4]), attributes[5])
if reference is None:
if lexicalisation_parameters[0].values.all()[0].parameter.type.name == u'agr':
if get_number(attributes[1], subj, reference) == u'pl':
return (adjps, get_plural(base), 0)
else:
return (adjps, [], 0)
else:
return (adjps, [], -1)
elif subj:
return (adjps, get_verb(base, get_number(attributes[1], subj), subj), -1)
else:
return (adjps, [], 1)
elif lexicalisation_type == 'prepadjp': #prepadjp(prep, case), number, gender, degree, adjectives, atr
prepadjps = get_prepadjps(get_preposition(lexicalisation_parameters[0]), get_case(lexicalisation_parameters[1], subj, False, reference), get_number(attributes[1], subj, reference), get_gender(attributes[2], reference), get_degree(attributes[3]), get_words(attributes[4]), attributes[5])
return (prepadjps, [], 1)
elif lexicalisation_type == 'infp':
infps = get_infps(get_aspect(lexicalisation_parameters[0]), get_words(attributes[2]), attributes[4])
return (infps, [], 1)
elif lexicalisation_type == 'advp': #advp(type), degree, adverb, atr
advps = get_advps(get_degree(attributes[1]), get_words(attributes[2]), attributes[3])
return (advps, [], -1)
elif lexicalisation_type == 'nump': # nump(case), num, noun, atr
numps = get_numps(get_case(lexicalisation_parameters[0], subj, negativity, reference), get_words(attributes[1]), get_words(attributes[2]), attributes[3])
return (numps, get_verb(base, 'pl', subj), -1)
elif lexicalisation_type == 'prepnump': # prepnump(prep,case), num, noun, atr
prepnumps = get_prepnumps(get_preposition(lexicalisation_parameters[0]), get_case(lexicalisation_parameters[1], subj, False, reference), get_words(attributes[1]), get_words(attributes[2]), attributes[3])
return (prepnumps, [], 1)
elif lexicalisation_type == 'qub': # qub, form, atr
qubs = get_qubs(get_words(attributes[1]), attributes[2])
return (qubs, [], -1)
else:
return ([], [], 0)
return ([], [], 0)
def is_subj(categories):
for cat in categories:
if cat.category == u'subj':
return True
return False
def get_preposition(attribute):
return attribute.values.all()[0].parameter.type.name
def get_numerals(attribute):
return get_words(attribute)
def get_words(attribute):
words = [word.text[1:-1] for word in attribute.values.all()]
return words
def get_aspect(attribute):
return attribute.values.all()[0].parameter.type.name
def get_case(attribute, is_subj, negativity, reference=None):
case = attribute.values.all()[0].parameter.type.name
if case == u'str':
if is_subj:
case = [u'nom']
elif negativity:
case = [u'gen']
else:
case = [u'acc']
elif case == u'part':
case = [u'gen', u'acc']
elif case == u'agr' and reference is not None:
_, tag = reference
base = tag.split(':')[0]
if base == u'siebie':
case = tag.split(':')[1].split('.')
else:
case = tag.split(':')[2].split('.')
elif case == u'agr' and reference is None:
case = [u'nom']
else:
case = [case]
return case
def get_number(attribute, is_subj, reference=None):
number = attribute.values.all()[0].parameter.type.name
if number == u'_':
if is_subj:
number = u'sg'
elif number == u'agr' and reference is not None:
_, tag = reference
base = tag.split(':')[0]
if base == u'siebie':
number = u'_'
else:
number = tag.split(':')[1]
elif number == u'agr' and reference is None:
number = u'sg'
return number
def get_gender(attribute, reference=None):
gender = attribute.values.all()[0].parameter.type.name
if gender == u'_':
gender = u'n'
elif gender == u'm':
gender = u'm1'
elif gender == u'agr' and reference is not None:
_, tag = reference
base = tag.split(':')[0]
if base == u'siebie':
gender = u'_'
else:
gender = tag.split(':')[3]
elif gender == u'agr' and reference is None:
gender = 'm1'
return gender
def get_degree(attribute):
degree = attribute.values.all()[0].parameter.type.name
if degree == u'_':
degree = u'pos'
return degree
def in_tag(what, tag):
if u':' + what + u':' in tag or u':' + what + u'.' in tag or u'.' + what + u'.' in tag or u'.' + what + u':' in tag or tag.endswith(u'.' + what) or tag.endswith(u':' + what):
return True
else:
return False
def get_nps(cases, number, nouns, atr):
result = []
for noun in nouns:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(noun)]
options_temp = []
for case in cases:
if case != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(case, tag):
filtered.append(option)
options_temp += filtered
else:
options_temp += filtered
options = options_temp
if number != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(number, tag):
filtered.append(option)
options = filtered
result += options
return dependents(atr, result)
def get_prepnps(prep, cases, number, nouns, _atr):
nps = get_nps(cases, number, nouns, _atr)
return [prep + ' ' + np for np in nps]
def get_infps(aspect, verbs, atr):
result = []
for verb in verbs:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(verb)]
filtered = []
for option in options:
(orth, tag) = option
if u'inf:' in tag:
filtered.append(option)
options = filtered
filtered = []
if aspect != u'_':
for option in options:
(orth, tag) = option
if in_tag(aspect, tag):
filtered.append(option)
options = filtered
result += options
return dependents(atr, result)
def get_adjps(cases, number, gender, degree, adjectives, atr):
result = []
for adjective in adjectives:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(adjective)]
filtered = []
for option in options:
(orth, tag) = option
if u'adj:' in tag:
filtered.append(option)
options = filtered
options_temp = []
for case in cases:
if case != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(case, tag):
filtered.append(option)
options_temp += filtered
else:
options_temp += options
options = options_temp
if number != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(number, tag):
filtered.append(option)
options = filtered
if gender != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(gender, tag):
filtered.append(option)
options = filtered
if degree != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(degree, tag):
filtered.append(option)
options = filtered
result += options
return dependents(atr, result)
def get_prepadjps(prep, case, number, gender, degree, adjectives, _atr):
adjps = get_adjps(case, number, gender, degree, adjectives, _atr)
return [prep + ' ' + adjp for adjp in adjps]
def get_advps(degree, adverbs, atr):
result = []
for adverb in adverbs:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(adverb)]
filtered = []
for option in options:
(orth, tag) = option
if tag.startswith(u'adv'):
filtered.append(option)
options = filtered
if ':' in tag and degree != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(degree, tag):
filtered.append(option)
options = filtered
result += options
return dependents(atr, result)
def get_qubs(qubs, atr):
result = []
for qub in qubs:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(qub)]
filtered = []
for option in options:
(orth, tag) = option
if tag.startswith(u'qub'):
filtered.append(option)
options = filtered
result += options
return dependents(atr, result)
def get_numps(cases, numerals, nouns, atr):
results = []
nums = []
for numeral in numerals:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(numeral)]
filtered = []
for option in options:
(orth, tag) = option
if tag.startswith(u'num:'):
filtered.append(option)
options = filtered
options_temp = []
for case in cases:
if case != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(case, tag):
filtered.append(option)
options_temp += filtered
else:
options_temp += options
nums = options_temp
if len(nums) == 0:
continue
for (num_orth, num_tag) in nums:
rec = num_tag.split(':')[4]
for noun in nouns:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(noun) if 'subst:' in tag]
filtered = []
for option in options:
(orth, tag) = option
if in_tag(u'pl', tag):
filtered.append(option)
options = filtered
if rec == 'rec':
c = ['gen']
elif rec == 'congr':
c = cases
else:
c = list(set(['gen'] + cases))
options_temp = []
for case in c:
if case != u'_':
filtered = []
for option in options:
(orth, tag) = option
if in_tag(case, tag):
filtered.append(option)
options_temp += filtered
else:
options_temp += options
options = options_temp
for (orth, tag) in options:
gender = tag.split(':')[3]
if in_tag(gender, num_tag):
results.append(num_orth + ' ' + orth)
return results #ignoring ambiguos atr for numps
def get_prepnumps(prep, cases, numerals, nouns, atr):
numps = get_numps(cases, numerals, nouns, atr)
return [prep + ' ' + nump for nump in numps]
def get_verb(inf, number, is_subj):
if not is_subj:
return None
else:
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(inf)]
filtered = []
for option in options:
(orth, tag) = option
if tag.startswith(u'fin') and in_tag(number, tag) and in_tag(u'ter', tag):
filtered.append(option)
options = filtered
return [orth for orth, _ in options]
def get_plural(noun):
options = [(orth, tag) for (orth, base, tag, _, _) in MORFEUSZ2.generate(noun)]
filtered = []
for option in options:
(orth, tag) = option
if in_tag(u'pl', tag) and in_tag(u'nom', tag):
filtered.append(option)
options = filtered
return [orth for orth, _ in options]
def dependents(atr, options):
if atr.selection_mode.name == u'ratr' or atr.selection_mode.name == u'ratr1':
result = []
for option in options:
result += phrase(option, atr.values.all())
return result
else:
return [orth for orth, _ in options]
def phrase(head, dependents):
modifiers = {'pre': [], 'post': []}
for dependent in dependents:
values = []
type = None
for argument in dependent.position.arguments.all():
if argument.type == u'fixed':
type = argument.type
elif argument.type == u'lex':
type = sortatributes(argument)[0].values.all()[0].argument.type
value, _, _ = lexicalisation(argument, False, '', False, head)
values += value
if type == u'adjp':
modifiers['pre'].append(values)
else:
modifiers['post'].append(values)
pre = []
for permutation in permutations(modifiers['pre']):
pre += cartesian(permutation)
pre = [' '.join(words) for words in pre]
pre = list(set(pre))
post = []
for permutation in permutations(modifiers['post']):
post += cartesian(permutation)
post = [' '.join(words) for words in post]
post = list(set(post))
orth, _ = head
result = []
if len(pre) == 0 and len(post) == 0:
result.append(orth)
for prefix in pre:
for suffix in post:
if prefix == '' and suffix == '':
if len(pre) == 1 and len(post) == 1:
result.append(orth)
elif prefix == '':
result.append(orth + ' ' + suffix)
elif suffix == '':
result.append(prefix + ' ' + orth)
else:
result.append(prefix + ' ' + orth + ' ' + suffix)
return result
def cartesian(llist):
if len(llist) == 0:
result = [[]]
else:
result = []
tail = cartesian(llist[1:])
for element in llist[0]:
tailcopy = deepcopy(tail)
for cart in tailcopy:
cart.insert(0, element)
result.append(cart)
result += tail
return result
def permutations(llist):
if len(llist) == 0:
result = [[]]
else:
result = []
perms = permutations(llist[1:])
for perm in perms:
for i in range(0, len(perm) + 1):
permcopy = deepcopy(perm)
permcopy.insert(i, llist[0])
result.append(permcopy)
return result