Q: Suppose I need to add a lexical rule which the user did not specify in the questionnaire (like a slightly modified copy of it, for example). Adding a rule once the choices have been read into the morphotactics hierarchy appears nightmarish.
A (thanks, @ebender!) : Several libraries are already doing this. For example, the argument optionality library and the direct inverse library.
Details:
customize.py has the following:
add_lexrules_methods = [case.add_lexrules,
argument_optionality.add_lexrules,
valence_change.add_lexrules,
direct_inverse.add_lexrules,
ADD YOURS --> wh_ques.add_lexrules]
to_cfv = morphotactics.customize_inflection(ch, add_lexrules_methods,
mylang, irules, lrules, lexicon)
Then simply write your method. You can model it on one of the existing ones, because that will show you how to properly access the objects:
def add_lexrules(choices):
'''
'''
for pc in morphotactics.all_position_classes(choices):
pc_key = pc.full_key
idx = pc['lrt'].next_iter_num() if 'lrt' in pc else 1
for lrt in pc.get('lrt', []):
overt = [f for f in lrt.get(
'feat', []) if f['name'] == 'overt-arg']
dropped = [f for f in lrt.get(
'feat', []) if f['name'] == 'dropped-arg']
need_lex_rule = need_no_drop_rule('obj-mark', choices) or \
need_no_drop_rule('subj-mark', choices)
# overt-arg morphs should be the index of the next available
if overt:
feat = overt[0]
# convert overt-arg features to OPT
if feat['value'] == 'not-permitted':
feat['name'] = 'OPT'
feat['value'] = 'plus'
# only create a lexical rule if necessary
if need_lex_rule:
key = pc.full_key + '_lrt' + str(idx)
name = get_name(pc) + '-no-drop'
choices[key + '_name'] = name
choices[key + '_feat1_name'] = 'OPT'
choices[key + '_feat1_value'] = 'minus'
choices[key + '_feat1_head'] = feat['head']
choices[key + '_lri1_inflecting'] = 'no'
choices[key + '_lri1_orth'] = ''
# dropped-arg morphs should be the index of the next available + 1
if dropped:
feat = dropped[0]
# convert dropped-arg features to OPT
if feat['value'] == 'not-permitted':
feat['name'] = 'OPT'
feat['value'] = 'minus'
# only create a lexical rule if necessary
if need_lex_rule:
key = pc.full_key + '_lrt' + str(idx + 1)
name = get_name(pc) + '-drop'
choices[key + '_name'] = name
choices[key + '_feat1_name'] = 'OPT'
choices[key + '_feat1_value'] = 'plus'
choices[key + '_feat1_head'] = feat['head']
choices[key + '_lri1_inflecting'] = 'no'
choices[key + '_lri1_orth'] = ''
Now your new rule will be properly integrated into the morphotactics graph.
As a side note, if you want to add rules to the choices that the user can then interact with or customize further (like a template), adjectives does this. I believe the code is in the web side, not the customization side.
1 Like