Blame view

semantics/phraseology_generator.py 15.2 KB
Tomasz Bartosiak authored
1
2
3
4
# -*- coding: utf-8 -*-

from dictionary.models import sort_arguments, sort_positions, sortatributes
from settings import MORFEUSZ2
Tomasz Bartosiak authored
5
from copy import deepcopy
Tomasz Bartosiak authored
6
Tomasz Bartosiak authored
7
def lexicalisation(argument, subj, base, negativity, reference=None):
Tomasz Bartosiak authored
8
9
    b = argument.type
    if b == 'fixed':
Tomasz Bartosiak authored
10
        return (get_words(sortatributes(argument)[-1]), [])
Tomasz Bartosiak authored
11
12
13
14
15
16
17
    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
Tomasz Bartosiak authored
18
        nps = get_nps(get_case(lexicalisation_parameters[0], subj, negativity), get_number(attributes[1], subj), get_words(attributes[2]), attributes[3])
Tomasz Bartosiak authored
19
        return (nps, get_verb(base, get_number(attributes[1], subj), subj))
Tomasz Bartosiak authored
20
    elif lexicalisation_type == 'prepnp': #prepnp(prep, case), number, nouns, atr
Tomasz Bartosiak authored
21
        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])
Tomasz Bartosiak authored
22
        return (prepnps, [])
Tomasz Bartosiak authored
23
    elif lexicalisation_type == 'adjp': # adjp(case), number, gender, degree, adjectives, atr
Tomasz Bartosiak authored
24
        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])
Tomasz Bartosiak authored
25
26
        return (adjps, get_verb(base, get_number(attributes[1], subj), subj))
    elif lexicalisation_type == 'prepadjp': #prepadjp(prep, case), number, gender, degree, adjectives, atr
Tomasz Bartosiak authored
27
        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])
Tomasz Bartosiak authored
28
        return (prepadjps, [])
Tomasz Bartosiak authored
29
30
31
    elif lexicalisation_type == 'infp':
        infps = get_infps(get_aspect(lexicalisation_parameters[0]), get_words(attributes[2]), attributes[4])
        return (infps, [])
Tomasz Bartosiak authored
32
33
34
    elif lexicalisation_type == 'advp': #advp(type), degree, adverb, atr
        advps = get_advps(get_degree(attributes[1]), get_words(attributes[2]), attributes[3])
        return (advps, [base])
Tomasz Bartosiak authored
35
36
37
    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))
Tomasz Bartosiak authored
38
39
40
    elif lexicalisation_type == 'prepnump': # prepnump(prep,case), num, noun, atr
        numps = 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 (numps, get_verb(base, 'pl', subj))
Tomasz Bartosiak authored
41
    else:
Tomasz Bartosiak authored
42
43
        return ([], [])
    return ([], [])
Tomasz Bartosiak authored
44
Tomasz Bartosiak authored
45
46
47
48
49
50
def is_subj(categories):
    for cat in categories:
        if cat.category == u'subj':
            return True
    return False
Tomasz Bartosiak authored
51
52
53
def get_preposition(attribute):
    return attribute.values.all()[0].parameter.type.name
Tomasz Bartosiak authored
54
55
56
def get_numerals(attribute):
    return get_words(attribute)
Tomasz Bartosiak authored
57
58
59
60
def get_words(attribute):
    words = [word.text[1:-1] for word in attribute.values.all()]
    return words
Tomasz Bartosiak authored
61
62
63
def get_aspect(attribute):
    return attribute.values.all()[0].parameter.type.name
Tomasz Bartosiak authored
64
def get_case(attribute, is_subj, negativity, reference=None):
Tomasz Bartosiak authored
65
66
    case = attribute.values.all()[0].parameter.type.name
    if case == u'str':
Tomasz Bartosiak authored
67
        if is_subj:
Tomasz Bartosiak authored
68
            case = [u'nom']
Tomasz Bartosiak authored
69
        elif negativity:
Tomasz Bartosiak authored
70
            case = [u'gen']
Tomasz Bartosiak authored
71
        else:
Tomasz Bartosiak authored
72
73
74
            case = [u'acc']
    elif case == u'part':
        case = [u'gen', u'acc']
Tomasz Bartosiak authored
75
76
    elif case == u'agr' and reference is not None:
        _, tag = reference
Tomasz Bartosiak authored
77
78
        base = tag.split(':')[0]
        if base == u'siebie':
Tomasz Bartosiak authored
79
            case = [tag.split(':')[1]]
Tomasz Bartosiak authored
80
        else:
Tomasz Bartosiak authored
81
82
83
            case = [tag.split(':')[2]]
    else:
        case = [case]
Tomasz Bartosiak authored
84
85
    return case
Tomasz Bartosiak authored
86
def get_number(attribute, is_subj, reference=None):
Tomasz Bartosiak authored
87
    number = attribute.values.all()[0].parameter.type.name
Tomasz Bartosiak authored
88
89
90
    if number == u'_':
        if is_subj:
            number = u'sg'
Tomasz Bartosiak authored
91
92
    elif number == u'agr' and reference is not None:
        _, tag = reference
Tomasz Bartosiak authored
93
94
95
96
97
        base = tag.split(':')[0]
        if base == u'siebie':
            number = u'_'
        else:
            number = tag.split(':')[1]
Tomasz Bartosiak authored
98
99
    elif number == u'agr' and reference is None:
        number = u'sg'
Tomasz Bartosiak authored
100
101
    return number
Tomasz Bartosiak authored
102
def get_gender(attribute, reference=None):
Tomasz Bartosiak authored
103
104
105
    gender = attribute.values.all()[0].parameter.type.name
    if gender == u'_':
        gender = u'n'
Tomasz Bartosiak authored
106
    elif gender == u'm':
Tomasz Bartosiak authored
107
        gender = u'm1'
Tomasz Bartosiak authored
108
109
    elif gender == u'agr' and reference is not None:
        _, tag = reference
Tomasz Bartosiak authored
110
111
112
113
114
        base = tag.split(':')[0]
        if base == u'siebie':
            gender = u'_'
        else:
            gender = tag.split(':')[3]
Tomasz Bartosiak authored
115
116
    elif gender == u'agr' and reference is None:
        gender = 'm1'
Tomasz Bartosiak authored
117
118
119
120
121
122
123
124
    return gender

def get_degree(attribute):
    degree = attribute.values.all()[0].parameter.type.name
    if degree == u'_':
        degree = u'pos'
    return degree
Tomasz Bartosiak authored
125
def get_nps(cases, number, nouns, atr):
Tomasz Bartosiak authored
126
127
128
    result = []
    for noun in nouns:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(noun.encode('utf8'))]
Tomasz Bartosiak authored
129
130
131
132
133
134
        options_temp = []
        for case in cases:
            if case != u'_':
                filtered = []
                for option in options:
                    (orth, tag) = option
Tomasz Bartosiak authored
135
                    if u':' + case in tag or u'.' + case in tag:
Tomasz Bartosiak authored
136
137
138
139
140
                        filtered.append(option)
                options_temp += filtered
            else:
                options_temp += filtered
        options = options_temp
Tomasz Bartosiak authored
141
142
143
144
        if number != u'_':
            filtered = []
            for option in options:
                (orth, tag) = option
Tomasz Bartosiak authored
145
                if u':' + number + u':' in tag:
Tomasz Bartosiak authored
146
147
                    filtered.append(option)
            options = filtered
Tomasz Bartosiak authored
148
        result += options
Tomasz Bartosiak authored
149
    return dependents(atr, result)
Tomasz Bartosiak authored
150
Tomasz Bartosiak authored
151
152
def get_prepnps(prep, cases, number, nouns, _atr):
    nps = get_nps(cases, number, nouns, _atr)
Tomasz Bartosiak authored
153
154
    return [prep + ' ' + np for np in nps]
Tomasz Bartosiak authored
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
def get_infps(aspect, verbs, atr):
    result = []
    for verb in verbs:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(verb.encode('utf8'))]
        filtered = []
        for option in options:
            (orth, tag) = option
            if u'inf:' in tag:
                filtered.append(option)
        options = filtered
        if aspect != u'_':
            for option in options:
                (orth, tag) = option
                if u':' + aspect + u':' in tag:
                    filtered.append(option)
            options = filtered        
        result += options
    return dependents(atr, result)
Tomasz Bartosiak authored
174
def get_adjps(cases, number, gender, degree, adjectives, atr):
Tomasz Bartosiak authored
175
176
177
178
179
180
181
182
183
    result = []
    for adjective in adjectives:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(adjective.encode('utf8'))]
        filtered = []
        for option in options:
            (orth, tag) = option
            if u'adj:' in tag:
                filtered.append(option)
        options = filtered
Tomasz Bartosiak authored
184
185
186
187
188
189
190
191
192
193
194
195
        options_temp = []
        for case in cases:
            if case != u'_':
                filtered = []
                for option in options:
                    (orth, tag) = option
                    if u':' + case + u':' in tag:
                        filtered.append(option)
                options_temp += filtered
            else:
                options_temp += options
        options = options_temp
Tomasz Bartosiak authored
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
        if number != u'_':
            filtered = []
            for option in options:
                (orth, tag) = option
                if u':' + number + u':' in tag:
                    filtered.append(option)
            options = filtered
        if gender != u'_':
            filtered = []
            for option in options:
                (orth, tag) = option
                if u':' + gender + u':' in tag or  u'.' + gender + u':' in tag or  u':' + gender + u'.' in tag or  u'.' + gender + u'.' in tag:
                    filtered.append(option)
            options = filtered
        if degree != u'_':
            filtered = []
            for option in options:
                (orth, tag) = option
                if u':' + degree in tag:
                    filtered.append(option)
            options = filtered
        result += options
Tomasz Bartosiak authored
218
    return dependents(atr, result)
Tomasz Bartosiak authored
219
220
221
222
223

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]
Tomasz Bartosiak authored
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
def get_advps(degree, adverbs, atr):
    result = []
    for adverb in adverbs:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(adverb.encode('utf8'))]
        filtered = []
        for option in options:
            (orth, tag) = option
            if u'adv' in tag:
                filtered.append(option)
        options = filtered
        if ':' in tag and degree != u'_':
            filtered = []
            for option in options:
                (orth, tag) = option
                if u':' + degree in tag:
                    filtered.append(option)
            options = filtered
        result += options
    return dependents(atr, result)
Tomasz Bartosiak authored
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
def get_numps(cases, numerals, nouns, atr):
    results = []
    nums = []
    for numeral in numerals:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(numeral.encode('utf8'))]
        filtered = []
        for option in options:
            (orth, tag) = option
            if u'num:' 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 u':' + case + u':' in tag or ':' + case + '.' in tag or '.' + case + '.' in tag:
                        filtered.append(option)
                options_temp += filtered
            else:
                options_temp += options
        nums = options_temp
        if len(nums) == 0:
            return []
        for (num_orth, num_tag) in nums:
            rec = num_tag.split(':')[4]
            for noun in nouns:
                options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(noun.encode('utf8')) if 'subst:' in interp.getTag(MORFEUSZ2)]
                filtered = []
                for option in options:
                    (orth, tag) = option
                    if u':pl:' in tag:
                        filtered.append(option)
                options = filtered
                if rec == 'rec':
                    c = ['gen']
                else:
                    c = cases
                options_temp = []
                for case in c:
                    if case != u'_':
                        filtered = []
                        for option in options:
                            (orth, tag) = option
                            if u':' + case + u':' in tag or ':' + case + '.' in tag or '.' + case + '.' in tag:
                                filtered.append(option)
                        options_temp += filtered
                    else:
                        options_temp += options
                options = options_temp
                for (orth, tag) in options:
                    gender = tag.split(':')[3]
                    if u':' + gender + u':' in num_tag or ':' + gender + '.' in num_tag or '.' + gender + '.' in num_tag:
                        results.append(num_orth + ' ' + orth)

    return results #ignoring ambiguos atr for numps
Tomasz Bartosiak authored
302
303
304
305
def get_prepnumps(prep, cases, numerals, nouns, atr):
    numps = get_numps(cases, numerals, nouns, atr)
    return [prep + ' ' + nump for nump in numps]
Tomasz Bartosiak authored
306
Tomasz Bartosiak authored
307
308
309
310
311
312
313
314
def get_verb(inf, number, is_subj):
    if not is_subj:
        return None
    else:
        options = [(interp.orth, interp.getTag(MORFEUSZ2)) for interp in MORFEUSZ2.generate(inf.encode('utf8'))]
        filtered = []
        for option in options:
            (orth, tag) = option
Tomasz Bartosiak authored
315
            if u'fin:' in tag and u':' + number + ':' in tag and u':ter:' in tag:
Tomasz Bartosiak authored
316
317
318
                filtered.append(option)
        options = filtered
        return [orth for orth, _ in options]
Tomasz Bartosiak authored
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

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 == '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 = []
Tomasz Bartosiak authored
357
358
    if len(pre) == 0 and len(post) == 0:
        result.append(orth)
Tomasz Bartosiak authored
359
360
361
    for prefix in pre:
        for suffix in post:
            if prefix == '' and suffix == '':
Tomasz Bartosiak authored
362
                if len(pre) == 1 and len(post) == 1:
Tomasz Bartosiak authored
363
                    result.append(orth)
Tomasz Bartosiak authored
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
            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