Adding lexical rules to the matrix without user spec

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