Example #1
0
def make_pred(tbentry, stemtag, glosstag, predchoice, lextype):
    '''
    Construct pred value from toolbox entry according
    to the predchoice specified.
    '''
    # Figure out if we're doing a noun or a verb
    lex_cat = lextype.rstrip('0123456789')
    # FIXME: What should I actually be doing with these errors?
    if lex_cat == 'verb':
        rel = '_v_rel'
    elif lex_cat == 'noun':
        rel = '_n_rel'
    else:
        print("Error: lex cat isn't verb or noun.")
    # Construct stem
    if predchoice == 'stem':
        pred = TDLencode('_' + tbentry[stemtag] + rel)
    elif predchoice == 'gloss':
        if tbentry[glosstag]:
            pred = TDLencode('_' + tbentry[glosstag] + rel)
        else:
            pred = TDLencode('_' + tbentry[stemtag] + rel)
    elif predchoice == 'glossfw':
        if tbentry[glosstag]:
            pred = TDLencode('_' + tbentry[glosstag].split()[0] + rel)
        else:
            pred = TDLencode('_' + tbentry[stemtag] + rel)
    else:
        print("Error: bad predchoice.")

    return pred
Example #2
0
def add_auxiliaries_to_lexicon(userstypename, sem, aux, lexicon, trigger):
    for stem in aux.get('stem', []):
        orth = orth_encode(stem.get('orth'))
        id = stem.get('name')
        typedef = TDLencode(id) + ' := ' + userstypename + ' & \
                       [ STEM < "' + orth + '" > ].'
        lexicon.add(typedef)

        evid_present = False
        evid_value = None
        for feat in aux.get('feat', []):
            if feat.get('name') == 'evidential':
                evid_present = True
                evid_value = feat.get('value')
        if sem == 'add-pred' or evid_present:
            pred = 'ev_' + str(evid_value) + '_rel'
            if not evid_present:
                pred = stem.get('pred')
            typedef = TDLencode(id) + \
                ' := [ SYNSEM.LKEYS.KEYREL.PRED "' + pred + '" ].'
            lexicon.add(typedef, merge=True)
        else:
            tense = aspect = mood = evidential = ''

            for feat in aux.get('feat', []):
                if feat.get('name') == 'tense':
                    tense = feat.get('value')
                if feat.get('name') == 'aspect':
                    aspect = feat.get('value')
                if feat.get('name') == 'mood':
                    mood = feat.get('value')
                if feat.get('name') == 'evidential':
                    evidential = feat.get('value')

            grdef = TDLencode(id) + '_gr := arg0e_gtr & \
                    [ CONTEXT [ RELS.LIST < [ '

            if tense == '' and aspect == '' and mood == '':
                grdef += 'PRED "non_existing_rel" ] > ],'
            else:
                grdef += 'ARG0.E [ '
                if tense != '':
                    grdef += 'TENSE ' + tense + ','
                if aspect != '':
                    grdef += 'ASPECT ' + aspect + ','
                if mood != '':
                    grdef += 'MOOD ' + mood + ','

                grdef = grdef[:len(grdef) - 1] + ' ] ] > ], '

            grdef += 'FLAGS.TRIGGER "' + TDLencode(id) + '" ].'
            trigger.add(grdef)
Example #3
0
def customize_misc_lex(ch, lexicon, trigger):

  # Question particle
  if ch.get('q-part'):
    orth = ch.get('q-part-orth')
    orthstr = orth_encode(orth)
    typedef = \
      TDLencode(orth) + ' := qpart-lex-item & \
                   [ STEM < "' + orthstr + '" > ].'
    lexicon.add(typedef)
    grdef = TDLencode(orth) +'_gr := generator_rule & \
                   [ CONTEXT [ RELS <! [ ARG0.SF ques ] !> ], \
                     FLAGS.TRIGGER "' + TDLencode(orth) + '" ].'
    trigger.add(grdef)
Example #4
0
def customize_head_comp_neg(mylang,ch,lexicon, hierarchies):
  # bipartite neg with negauxiliary which has a 'dummy' negcomp
  # add type for neg-adv

  # this analysis requires the neg-head-feature, if it's not on
  # simulate it here
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # negauxes with modified comps lists are 
  # generated by auxiliaries.py

  #TODO deal with v head

  # need to add type and instance for semantically empty neg-comp
  mylang.set_section('otherlex')
  mylang.add('''neg-comp-lex := norm-zero-arg &
                 [ SYNSEM.LOCAL [ CAT [ HEAD adv & [ NEGATED + ],
                                        VAL [ SUBJ < >,
                                              COMPS < > ] ],
                                  CONT [ RELS <! !>,
                                         HCONS <! !> ]]].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # add lexical instance
  if(ch.get('comp-neg-orth')):
    orth = ch.get('comp-neg-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-comp-lex &\
                [ STEM < \"'+ orthstr +'\" > ].')
Example #5
0
def customize_comp_neg(mylang, ch, lexicon, rules, lrules):
  # the neg-comp analyses require the neg-head-feature choice
  # simulate it here if it's not on 
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # first add lexical type
  mylang.set_section('otherlex')
  mylang.add('''neg-adv-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ] ].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # okay, now add the spelling and lexical instance
  if(ch.get('comp-neg-orth')):
    orth = ch.get('comp-neg-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-adv-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  # we need the lexical rule that adds these types to the comps lists
  # of the verbs that selecte them
  if ch.get('comp-neg-order') == 'before':
    mylang.add('''neg-comp-add-lex-rule := const-val-change-only-lex-rule &
               [ SYNSEM.LOCAL [ CAT.VAL [  SUBJ #subj,
                                           COMPS < canonical-synsem & 
                                                 [ LOCAL.CAT.HEAD [ NEGATED +,
                                MOD < [ LOCAL.CONT.HOOK #hook ] > ] ] 
                                                   . #comps > ] ],
                 DTR.SYNSEM.LOCAL [ CAT.VAL [ SUBJ #subj,
                                              COMPS #comps ],
                                        CONT.HOOK #hook ] ].
               ''')

  elif ch.get('comp-neg-order') == 'after':
    mylang.add('''neg-comp-add-lex-rule := const-val-change-only-lex-rule &
               [ SYNSEM.LOCAL.CAT.VAL [  SUBJ #subj,
                                         COMPS < #comps , canonical-synsem & 
                                             [ LOCAL.CAT.HEAD [ NEGATED +,
                                             MOD < [ LOCAL.CONT.HOOK #hook ] > ] ] > ],
                 DTR.SYNSEM.LOCAL [ CAT.VAL [ SUBJ #subj,
                                              COMPS.FIRST #comps ],
                                    CONT.HOOK #hook ] ].
               ''')

  lrules.add('neg-lex-rule := neg-comp-add-lex-rule.')
  # deal with type of selecting verb: auxiliary verb or any finite verb
  if(ch.get('comp-neg-head')=='aux'):
    mylang.add('neg-comp-add-lex-rule := [ DTR aux-lex ].')
  elif(ch.get('comp-neg-head')=='v'):
    mylang.add('''neg-comp-add-lex-rule := [ DTR verb-lex &
                [ SYNSEM.LOCAL.CAT.HEAD.FORM finite ] ].''')
Example #6
0
def customize_adv_neg(mylang, ch, lexicon, rules):
  # first add lexical type for negative adverb
  mylang.set_section('otherlex')
  mylang.add('''neg-adv-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD.MOD < [ LOCAL.CAT.HEAD verb ] > ]].''',
             'Type for negative adverbs.')

  mylang.add_comment('neg-adv-lex',
    '''This adverb should go through a specialized phrase structure rule
       included with this grammar.''')

  # now parameterize as pre/posthead, no value here means both orders
  # should work
  if ch.get('neg-order') == 'before':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
  elif ch.get('neg-order') == 'after':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')

  # constrain type of constituent modified by neg-adv
  if ch.get('neg-mod') == 's':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod') == 'vp':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod') == 'v':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

  mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')
    
  # add spelling for neg-adverb
  if(ch.get('neg-adv-orth')):
    orth = ch.get('neg-adv-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-adv-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  rules.add('adj-head-scop := adj-head-scop-phrase.')
  rules.add('head-adj-scop := head-adj-scop-phrase.',
          'Rule instances for head-modifier structures. Corresponding types\n' +
          'are defined in matrix.tdl.  The matrix customization script did\n' +
          'not need to add any further constraints, so no corresponding types\n' +
          'appear in ' + ch.get('language').lower() + '.tdl')
  mylang.add('+nvcdmo :+ [ MOD < > ].',
             'This grammar includes head-modifier rules.  To keep\n' +
             'out extraneous parses, constrain the value of MOD on\n' +
             'various subtypes of head.  This may need to be loosened later.\n' +
             'This constraint says that only adverbs, adjectives,\n' +
             'and adpositions can be modifiers.',
             section='addenda')
Example #7
0
def add_to_lexicon(morphtype, typename, type, lexicon):
    """
    add the subordinator or adverb to lexicon
    """
    orth = morphtype.get(type + 'orth')
    orthstr = orth_encode(orth)
    pred = morphtype.get(type + 'pred')
    name = TDLencode(morphtype.get(type + 'name'))
    lexicon.add(name + ' := ' + typename + ' &\
                      [ STEM < "' + orthstr + '" >,\
                   SYNSEM.LKEYS.KEYREL.PRED "' + pred + '"].')
Example #8
0
def customize_cops(mylang, ch, lexicon, hierarchies, trigger):

  if ch.get('cop',False):
    # Add PRD
    mylang.add('head :+ [ PRD bool ].', section='addenda')

    # Add copulas
    lexicon.add_literal(';;; Copulas')

    # Core definition
    mylang.add('''%s := basic-verb-lex-super & trans-first-arg-raising-lex-item-2 &
          [ SYNSEM.LOCAL [ CAT.VAL [ SUBJ < [ LOCAL [ CONT.HOOK.INDEX #xarg,
                                                      CAT [ VAL [ SPR < >,
                                                                  COMPS < > ],
                                                            HEAD noun ] ] ] >,
                                     COMPS < [ LOCAL.CAT [ HEAD.PRD +,
                                                           VAL [ SUBJ < >,
                                                                 COMPS < > ] ] ] >,
                                     SPR < >,
                                     SPEC < > ],
                           CONT.HOOK.XARG #xarg ] ].''' % LEXICAL_SUPERTYPES['cop'])

    # only works for adj right now, change in future
    comment = '''Copula type taking adjectival complements.\nNeed to define more for additional complement types.'''
    mylang.add('''adj-comp-copula-verb-lex := %s &
                  [ SYNSEM.LOCAL.CAT.VAL.COMPS.FIRST.LOCAL.CAT.HEAD adj ].''' % LEXICAL_SUPERTYPES['cop'],
               comment=comment)

    for cop in ch.get('cop', []):
      ctype = cop_id(cop)

      ## Calculate supertypes
      stypes = cop.get('supertypes').split(', ')
      stype_def = ''
      if '' in stypes: # Found root
        stype_def = 'adj-comp-copula-verb-lex & ' # Change for new complement types
      else:
        stype_names = [cop_id(ch[st]) for st in filter(None,stypes)]
        stype_def = " & ".join(stype_names) or ""
        if stype_def: stype_def += " & "

      features.customize_feature_values(mylang, ch, hierarchies, cop, ctype, 'cop')

      # Add the lexical types
      mylang.add(ctype + ' := ' + stype_def + '.')

      for stem in cop.get('stem'):
        orthstr = orth_encode(stem.get('orth'))
        name = stem.get('name')
        typedef = TDLencode(name) + ' := ' + ctype + ' & \
                        [ STEM < "' + orthstr + '" > ].'
        lexicon.add(typedef)
Example #9
0
def customize_determiners(mylang, ch, lexicon, hierarchies):

  # Lexical type for determiners, if the language has any:
  if ch.get('has-dets') == 'yes':
    comment = \
      ';;; Determiners\n' + \
      ';;; SPEC is non-empty, and already specified by basic-determiner-lex.'
    mylang.add_literal(comment)
    
    # LLD 2016-04-04 changed basic-zero-arg to norm-zero-arg
    typedef = \
      'determiner-lex := basic-determiner-lex & norm-zero-arg & \
          [ SYNSEM.LOCAL.CAT.VAL [ SPR < >, \
                                   COMPS < >, \
                                   SUBJ < > ]].'
    mylang.add(typedef)

    mylang.add('determiner-lex := non-mod-lex-item.')

  # Determiners
  if 'det' in ch:
    lexicon.add_literal(';;; Determiners')

  for det in ch.get('det',[]):
    stype = 'determiner-lex'
    dtype = det_id(det)

    mylang.add(dtype + ' := ' + stype + '.')

    has_inforstr_feat = False
    for feat in det.get('feat', []):
      if feat['name'] == "information-structure meaning":
        has_inforstr_feat = True
        mylang.add(dtype + ' := infostr-marking-determiner-lex.')
        break
    if not has_inforstr_feat:
      mylang.add(dtype + ' := no-icons-lex-item.')

    features.customize_feature_values(mylang, ch, hierarchies, det, dtype, 'det')

    for stem in det.get('stem',[]):
      orthstr = orth_encode(stem.get('orth'))
      pred = stem.get('pred')
      name = stem.get('name')
      typedef = \
        TDLencode(name) + ' := ' + dtype + ' & \
                    [ STEM < "' + orthstr + '" >, \
                      SYNSEM.LKEYS.KEYREL.PRED "' + pred + '" ].'
      lexicon.add(typedef)
Example #10
0
def add_complementizers_to_lexicon(lexicon, ch):
    lexicon.add_literal(';;; Complementizers')
    have_comp = False
    for comp_strategy in ch[COMPS]:
        id = comp_strategy.full_key
        stype = id + '-' + COMP_LEX_ITEM
        # TODO: Perhaps turn complementizers into full-blown
        # lexical items and then can call insert_ids() from lexical_items.py instead
        # This would need to be done via redesigning the questionnaire a little.
        for complementizer in comp_strategy[COMPLEMENTIZER]:
            orth = orth_encode(complementizer.get('orth'))
            name = TDLencode(complementizer.get('name'))
            typedef = name + ' := ' + stype + ' & \
                          [ STEM < "' + orth + '" > ].'
            lexicon.add(typedef)
            have_comp = True
    return have_comp
Example #11
0
def customize_infl_comp_neg(mylang,ch,lexicon):
  # neg affix on verb requires neg-adv with neg semantics 
  # neg-adv is a selected complement

  # this analysis requires the neg-head-feature, if it's not on
  # simulate it here
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')


  # add type for neg-adv
  mylang.set_section('otherlex')
  mylang.add('''neg-comp-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            SPEC < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ] ].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # add lexical instance
  if(ch.get('comp-neg-orth')):
    orth = ch.get('comp-neg-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-comp-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  # inflecting lexical rule must add neg-adv to comps list, 
  for vpc in ch['verb-pc']:
    for lrt in vpc['lrt']:
      for f in lrt['feat']:
        if 'negation' in f['name'] and f['value']=='plus':
          lrt['supertypes'] = ', '.join(lrt['supertypes'].split(', ') +\
                                        ['val-change-only-lex-rule']) 
          f['value']='d'
Example #12
0
def customize_coordination(mylang, ch, lexicon, rules, irules):
    """
    The main coordination customization routine
    """
    mylang.set_section('coord')

    for cs in ch.get('cs'):
        csnum = str(cs.iter_num())

        mark = cs.get('mark')
        pat = cs.get('pat')
        orth = cs.get('orth')
        orthstr = orth_encode(orth)
        order = cs.get('order')

        pre = ''
        suf = ''

        tn = TDLencode(orth)
        if (len(ch.get('cs')) > 1):
            tn += csnum

        if mark == 'word':
            lexicon.add(tn + ' := conj-lex &\
                  [ STEM < "' + orthstr + '" >,\
                    SYNSEM.LKEYS.KEYREL.PRED "_and_coord_rel",\
                    CFORM "' + csnum + '" ].')
            if pat == 'omni':
                lexicon.add(tn + '_nosem := nosem-conj-lex &\
                      [ STEM < "' + orthstr + '" >,\
                        CFORM "' + csnum + '" ].')

        if pat == 'a':
            top = 'apoly-'
            mid = ''
            bot = 'unary-'
            left = ''
        else:
            if pat == 'mono':
                top = 'monopoly-'
                mid = 'monopoly-'
                bot = ''
                left = ''
            elif pat == 'omni':
                top = 'omni-'
                mid = 'omni-'
                bot = 'omni-'
                left = 'omni-'
            elif pat == 'poly':
                top = 'apoly-'
                mid = ''
                bot = ''
                left = ''

            if mark == 'affix':
                bot = 'infl-'
                if order == 'before':
                    pre = orth
                else:
                    suf = orth
            else:
                if order == 'before':
                    bot += 'conj-first-'
                    if left:
                        left += 'conj-first-'
                else:
                    bot += 'conj-last-'
                    if left:
                        left += 'conj-last-'

        # EKN 02-13-2018 Add identification of possessive feats across
        # conjuncts
        poss = True if (ch.get('poss-strat') or ch.get('poss-pron'))\
            else False
        if poss:
            if top:
                customize_poss_feats(mylang, 'top')
            if mid:
                customize_poss_feats(mylang, 'mid')
            if bot:
                customize_poss_feats(mylang, 'bottom')

        # If this CS uses feature resolution, we will set up closest conjunct as a mixed strategy
        # (with additional rules and specifications).
        mixed_strategy = True if any([csap.get('pat').startswith('fr') for csap in cs.get('csap')]) \
            and any([csap.get('pat').startswith('dconj') for csap in cs.get('csap')]) \
            else False

        # make a list of the agreement rules for this coord strat
        if cs.get('csap'):
            agrrules = []
            for csap in cs.get(
                    'csap'):  # iterate through the agreement patterns used
                agrrules += customize_agreement_pattern(mylang, ch, csap, cs)
        # use an empty list if no agreement pattern is defined
        else:
            agrrules = [('', '')]

        # olzama 2020-04-28 Add adverb coordination if adverbs are present.
        # For now, I just hard coded Strategy 1 because I don't really know
        # how this library works. Adverbs are unlikely to require agreement though?
        if len(ch.get('adv')) > 0:
            mylang.add(
                'adv1-top-coord-rule := basic-adv-top-coord-rule & monopoly-top-coord-rule & \
                            [ SYNSEM.LOCAL.COORD-STRAT "1" ].')
            mylang.add(
                '''adv1-mid-coord-rule := basic-adv-mid-coord-rule & monopoly-mid-coord-rule &
                            [ SYNSEM.LOCAL.COORD-STRAT "1" ].''')
            mylang.add(
                '''adv1-bottom-coord-rule := conj-first-bottom-coord-rule & adv-bottom-coord-phrase &
                            [ SYNSEM.LOCAL.COORD-STRAT "1" ].''')
            rules.add('adv1-bottom-coord := adv1-bottom-coord-rule.')
            rules.add('adv1-mid-coord := adv1-mid-coord-rule.')
            rules.add('adv1-top-coord := adv1-top-coord-rule.')

        for pos in ('n', 'np', 'vp', 's'):
            # don't use noun-y agreement rules with VP or S
            agrrules = [('', '')] if pos in ('vp', 's') else agrrules
            # now write the rules
            if cs.get(pos):
                define_coord_strat(csnum, pos, top, mid, bot, left, pre, suf,
                                   mylang, rules, irules, agrrules,
                                   mixed_strategy)
Example #13
0
def customize_mod_mod_neg(mylang,ch,lexicon,rules):
  # need to create two modifiers, one sets neg-sat to minus, the other to
  # back to plus.

  # add neg-sat and decorate psrs
  # this analysis uses the neg-head-feature
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # add neg-sat to SYNSEM
  mylang.set_section('addenda')
  mylang.add('''synsem :+ [ NEG-SAT luk ].''')

  # verbs must start out NEG-SAT na-or-+
  mylang.add('''basic-verb-lex :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # decorate psrs to pass up NEG-SAT value
  mylang.add('''basic-head-comp-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 
  mylang.add('''basic-head-subj-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 

  # ammend root condition
  mylang.add('''clause :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # add neg1 mod (sets neg-sat to -, via its psr)
  mylang.set_section('otherlex')
  mylang.add('''neg1-adv-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            SPEC < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ] ].''',
             '''This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # add neg2 mod (sets neg-sat back to +, via its psr)
  mylang.add('''neg2-adv-lex := norm-zero-arg & 
                [ SYNSEM.LOCAL [ CAT [ VAL [ SPR < >,
                                             SPEC < >,
                                             COMPS < >,
                                             SUBJ < > ],
                                       HEAD adv & [ NEGATED +,
                                                    MOD < [ LOCAL.CAT.HEAD verb ] > ] ],
                                 CONT [ RELS <! !>,
                                        HCONS <! !> ] ] ].''')

  # create lexical instance for neg1
  if(ch.get('neg1-mod-orth')):
    orth = ch.get('neg1-mod-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg1-adv-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  # create lexical instance for neg2
  if(ch.get('neg2-mod-orth')):
    orth = ch.get('neg2-mod-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg2-adv-lex &\
                [ STEM < \"'+ orthstr +'\" > ].')

  # now parameterize as pre/posthead, no value here means both orders
  # should work, also add specialized modifier rules
  if ch.get('neg1-mod-order') == 'before':
    mylang.add('neg1-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
    mylang.add('''neg1-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT -,
                   HEAD-DTR.SYNSEM.NEG-SAT na-or-+,
                   NON-HEAD-DTR neg1-adv-lex ].''')
    rules.add('neg1-adj-head-scop := neg1-adj-head-scop-phrase.')
  elif ch.get('neg1-mod-order') == 'after':
    mylang.add('neg1-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')
    mylang.add('''neg1-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT -,
                 HEAD-DTR.SYNSEM.NEG-SAT na-or-+,
                 NON-HEAD-DTR neg1-adv-lex ].''')
    rules.add('neg1-head-adj-scop := neg1-head-adj-scop-phrase.')
  else:
    mylang.add('''neg1-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT -,
                   HEAD-DTR.SYNSEM.NEG-SAT na-or-+,
                   NON-HEAD-DTR neg1-adv-lex ].''')
    rules.add('neg1-adj-head-scop := neg1-adj-head-scop-phrase.')
    mylang.add('''neg1-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT -,
                 HEAD-DTR.SYNSEM.NEG-SAT na-or-+,
                 NON-HEAD-DTR neg1-adv-lex ].''')
    rules.add('neg1-head-adj-scop := neg1-head-adj-scop-phrase.')


  # constrain type of constituent modified by neg-adv
  if ch.get('neg1-mod') == 's':
    mylang.add('''neg1-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod1') == 'vp':
    mylang.add('''neg1-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg1-mod') == 'v':
    mylang.add('''neg1-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

    mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')

  # now parameterize as pre/posthead, no value here means both orders
  # should work, also add specialized modifier rules
  if ch.get('neg2-mod-order') == 'before':
    mylang.add('neg2-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
    mylang.add('''neg2-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg2-adv-lex ].''')
    rules.add('neg2-adj-head-scop := neg2-adj-head-scop-phrase.')
  elif ch.get('neg2-mod-order') == 'after':
    mylang.add('neg2-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')
    mylang.add('''neg2-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg2-adv-lex ].''')
    rules.add('neg2-head-adj-scop := neg2-head-adj-scop-phrase.')
  else:
    mylang.add('''neg2-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg2-adv-lex ].''')
    rules.add('neg2-adj-head-scop := neg2-adj-head-scop-phrase.')
    mylang.add('''neg2-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg2-adv-lex ].''')
    rules.add('neg2-head-adj-scop := neg2-head-adj-scop-phrase.')


  # constrain type of constituent modified by neg-adv
  if ch.get('neg2-mod') == 's':
    mylang.add('''neg2-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod2') == 'vp':
    mylang.add('''neg2-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg2-mod') == 'v':
    mylang.add('''neg2-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

    mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')
Example #14
0
def customize_comp_mod_neg(mylang,ch,lexicon,rules):
  # here we create a negation strategy with one selected complement,
  # which presumably carries the negative force 

  # this analysis uses the neg-head-feature
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # add neg-sat to SYNSEM
  mylang.set_section('addenda')
  mylang.add('''synsem :+ [ NEG-SAT luk ].''')

  # verbs must start out NEG-SAT na-or-+
  mylang.add('''basic-verb-lex :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # decorate psrs to pass up NEG-SAT value
  mylang.add('''basic-head-comp-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 
  mylang.add('''basic-head-subj-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 

  # ammend root condition
  mylang.add('''clause :+ [ SYNSEM.NEG-SAT na-or-+ ].''')


  # first introduce the lexical rule that introduces the negative complement
  # also needs to set NEG-SAT - on its target

  #TODO: parameterize this rule according to neg-comp before/after
  #      current system only supports before and ignores the choice!
  attach=''
  if ch.get('comp-neg-head-comp-mod') == 'v':
    attach='verb'
  else: attach='aux'

  next_n = ch['verb-pc'].next_iter_num() if 'verb-pc' in ch else 1
  ch['verb-pc%d_name' % next_n] = 'neg1'
  nvpc = ch['verb-pc'].get_last()
  nvpc['order'] = 'suffix' 
  nvpc['inputs'] = attach 
  nvpc['lrt1_feat1_name'] = 'negation'
  nvpc['lrt1_feat1_value'] = 'h'
  nvpc['lrt1_lri1_inflecting'] = 'no'
  nvpc['lrt1_supertypes'] = 'val-change-only-lex-rule'

  # create lexical type for neg-comp
  mylang.set_section('otherlex')
  mylang.add('''neg1-comp-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            SPEC < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ] ].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # create lexical instance for neg1
  if(ch.get('comp-neg-orth')):
    orth = ch.get('comp-neg-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg1-comp-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  # add lexical type for negadv "neg2"
  mylang.set_section('otherlex')
  mylang.add('''neg-adv-lex := norm-zero-arg &
                 [ SYNSEM.LOCAL [ CAT [ VAL [ SPR < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD adv & [ MOD < [ LOCAL.CAT.HEAD verb ] >,
                                             NEGATED + ] ],
                                  CONT [ RELS <! !>,
                                         HCONS <! !> ] ] ].''',
             'Type for negative adverbs.')

  mylang.add_comment('neg-adv-lex',
    '''This adverb should go through a specialized phrase structure rule
       included with this grammar.''')

  # now parameterize as pre/posthead, no value here means both orders
  # should work, also add specialized modifier rules
  if ch.get('neg-mod-order-comp-mod-neg') == 'before':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
  elif ch.get('neg-mod-order-comp-mod-neg') == 'after':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')
  else:
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')


  # constrain type of constituent modified by neg-adv
  if ch.get('neg-mod-comp-mod-neg') == 's':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-comp-mod-neg') == 'vp':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-comp-mod-neg') == 'v':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

  mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')
    
  # add spelling for neg-adverb
  if(ch.get('neg-mod-orth')):
    orth = ch.get('neg-mod-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-adv-lex &\
                [ STEM < \"'+ orthstr +'\" > ].')


  mylang.add('+nvcdmo :+ [ MOD < > ].',
             'This grammar includes head-modifier rules.  To keep\n' +
             'out extraneous parses, constrain the value of MOD on\n' +
             'various subtypes of head.  This may need to be loosened later.\n' +
             'This constraint says that only adverbs, adjectives,\n' +
             'and adpositions can be modifiers.',
             section='addenda')
Example #15
0
def customize_comp_comp_neg(mylang,ch,lexicon):
  # bipartite negation type with two negative complements,
  # presumably one is selected by an aux, the other by a v
  # 

  # this analysis uses the neg-head-feature
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # verbs need to be NEGATED - 'underlyingly'
  mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HEAD.NEGATED na-or-- ].')

  # add neg1 complement
  mylang.set_section('otherlex')
  mylang.add('''neg1-comp-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            SPEC < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ] ].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # add neg2 complement
  mylang.add('''neg2-comp-lex := norm-zero-arg &
                 [ SYNSEM.LOCAL [ CAT [ VAL [ SPR < >,
                                            SPEC < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ NEGATED +, 
                                             MOD < [ LOCAL.CAT.HEAD verb ] > ] ],
                                  CONT [ HCONS <! !>,
                                         RELS <! !> ]  ] ].''',
             '''Type for negative selected comps. 
                This type uses the MOD list to get scopal semantics.
                Constrain head-modifier rules to be [NEGATED -] if you don't
                want this type to act as a modifer.''')

  # add lexical instances
  if(ch.get('comp-neg1-orth')):
    orth = ch.get('comp-neg1-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg1-comp-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')

  if(ch.get('comp-neg2-orth')):
    orth = ch.get('comp-neg2-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg2-comp-lex &\
                [ STEM < \"'+ orthstr +'\" > ].')
                  
  # non-inflecting lexical rule must add neg-adv to comps list, 
  next_n = ch['verb-pc'].next_iter_num() if 'verb-pc' in ch else 1
  ch['verb-pc%d_name' % next_n] = 'neg1'
  nvpc = ch['verb-pc'].get_last()
  nvpc['order'] = 'suffix' 
  nvpc['inputs'] = 'aux'
  nvpc['lrt1_feat1_name'] = 'negation'
  nvpc['lrt1_feat1_value'] = 'f'
  nvpc['lrt1_lri1_inflecting'] = 'no'
  nvpc['lrt1_supertypes'] = 'val-change-only-lex-rule'

  # other non-inflecting lex rule adds other neg comp to other verbs
  # can go in same pc as above (the two rules should be exclusive)
  ch['verb-pc%d_name' % (next_n + 1)] = 'neg2'
  nvpc = ch['verb-pc'].get_last()
  nvpc['order'] = 'suffix' 
  nvpc['inputs'] = 'verb'
  nvpc['lrt1_feat1_name'] = 'negation'
  nvpc['lrt1_feat1_value'] = 'g'
  nvpc['lrt1_lri1_inflecting'] = 'no'
  nvpc['lrt1_supertypes'] = 'cat-change-only-lex-rule, same-hc-light-lex-rule, same-posthead-lex-rule, same-mc-lex-rule'

  # also need auxes to underlyingly select for [ NEGATED - ] types
  mylang.add('''aux-lex := [ SYNSEM.LOCAL.CAT.VAL.COMPS.FIRST.LOCAL.CAT.HEAD.NEGATED na-or-- ].''')
Example #16
0
def customize_head_mod_neg(mylang, ch, lexicon,rules):
  # basically just need to add NEG-SAT feature dependencies

  # this analysis uses the neg-head-feature
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # add neg-sat to SYNSEM
  mylang.set_section('addenda')
  mylang.add('''synsem :+ [ NEG-SAT luk ].''')

  # verbs must start out NEG-SAT na-or-+
  mylang.add('''basic-verb-lex :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # decorate psrs to pass up NEG-SAT value
  mylang.add('''basic-head-comp-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 
  mylang.add('''basic-head-subj-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 

  # ammend root condition
  mylang.add('''clause :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # neg-aux lexically introduces SYNSEM.NEG-SAT -
  # 

  # add type for neg-adv
  mylang.set_section('otherlex')
  mylang.add('''neg-adv-lex := norm-zero-arg &
                 [ SYNSEM.LOCAL [ CAT [ VAL [ SPR < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD adv & [ MOD < [ LOCAL.CAT.HEAD verb ] >,
                                             NEGATED + ] ],
                                  CONT [ RELS <! !>,
                                         HCONS <! !> ] ] ].''',
             'Type for negative adverbs.')

  mylang.add_comment('neg-adv-lex',
    '''This adverb should go through a specialized phrase structure rule
       included with this grammar.''')

  # now parameterize as pre/posthead, no value here means both orders
  # should work, also add specialized modifier rules
  if ch.get('neg-mod-order-head-mod-neg') == 'before':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
  elif ch.get('neg-mod-order-head-mod-neg') == 'after':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')
  else:
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')


  # constrain type of constituent modified by neg-adv
  if ch.get('neg-mod-head-mod-neg') == 's':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-head-mod-neg') == 'vp':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-head-mod-neg') == 'v':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

  mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')
    
  # add spelling for neg-adverb
  if(ch.get('neg-mod-orth')):
    orth = ch.get('neg-mod-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-adv-lex &\
                [ STEM < \"'+ orthstr +'\" > ].')


  mylang.add('+nvcdmo :+ [ MOD < > ].',
             'This grammar includes head-modifier rules.  To keep\n' +
             'out extraneous parses, constrain the value of MOD on\n' +
             'various subtypes of head.  This may need to be loosened later.\n' +
             'This constraint says that only adverbs, adjectives,\n' +
             'and adpositions can be modifiers.',
             section='addenda')
Example #17
0
def create_adverb_subordinator_lexical_subtypes(mylang, lexicon, trigger, cms):
    """
    Create the lexical subtype for the adverb subordinator with constraints for
    subordinator's position (before/after a vp/s), morphological constraints,
    and the SUBORDINATED feature. Then add each to lexicon.
    """
    lextype = []
    constraints = []
    pos = cms.get('position')
    subpos = cms.get('subposition')
    # add constraints for subordinator position
    if subpos == 'before':
        lextype.append('clause-init')
        constraints.append('SYNSEM.LOCAL.CAT.POSTHEAD -')
    elif subpos == 'after':
        lextype.append('clause-final')
        constraints.append('SYNSEM.LOCAL.CAT.POSTHEAD +')
    if pos == 'before':
        lextype.append('prehead')
    elif pos == 'after':
        lextype.append('posthead')
    # add morphological constraints
    lextype, constraints = add_morphological_constraints(
        lextype, constraints, cms, 'adverb')
    saved_constraints = constraints
    saved_lextype = lextype
    # each free adverb subordinator gets it's own lexical type with a special SUBORDINATED value so that the non-branching
    # rule can select it
    if cms.get('subordinator') == 'free':
        for adverb in cms.get('freemorph'):
            constraints = saved_constraints
            lextype = saved_lextype
            pred = adverb.get('pred')
            value = shortform_pred(pred)
            lextype = [value] + lextype
            constraints.append('SYNSEM.SUBORDINATED ' + value)
            # add constriants for the adverb's attaching to vp or s
            if cms.get('adverb-attach') == 's':
                if cms.get('shared-subj') == 'on':
                    constraints.append('SYNSEM.LOCAL [ CONT.HOOK.XARG #xarg,\
                                                       CAT.HEAD.MOD < [ LOCAL [ CONT.HOOK.XARG #xarg,\
                                                                              CAT.VAL [ SUBJ < unexpressed >,\
                                                                                        COMPS < > ]]] > ]'
                                       )
                else:
                    constraints.append(
                        'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ SUBJ < >, COMPS < > ]] >'
                    )
            elif cms.get('adverb-attach') == 'vp':
                constraints.append(
                    'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ SUBJ < [ ] >, COMPS < > ]] >'
                )
            if cms.get('adverb-attach') == 'both':
                constraints.append(
                    'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ COMPS < > ]] >'
                )
            type = build_type_name(lextype)
            type += '-adv-subord-lex-item'
            mylang.add(type + ' := adverb-subord-lex-item & [ ' +
                       constraints.pop() + ' ].')
            while constraints != []:
                mylang.add(type + ' := [ ' + constraints.pop() + ' ].')
            orth = adverb.get('orth')
            orthstr = orth_encode(orth)
            name = TDLencode(adverb.get('name'))
            lexicon.add(name + ' := ' + type + ' & [ STEM < "' + orthstr +
                        '" > ].')
            trigger_rule = TDLencode(orth) + '_gr := arg0e_gtr & \
                   [ CONTEXT [ RELS.LIST < [ PRED "' + TDLencode(
                pred) + '" ] > ], \
                     FLAGS.TRIGGER "' + TDLencode(orth) + '" ].'
            trigger.add(trigger_rule)

    # each adverb gets it's own lexical type with a special SUBORDINATED value so that the non-branching
    # rule can select it and so that the SUBPAIR feature can be added
    elif cms.get('subordinator') == 'pair':
        for adverb in cms.get('morphpair'):
            constraints = saved_constraints
            lextype = saved_lextype
            pred = adverb.get('subordpred')
            value = shortform_pred(pred)
            lextype = [value] + lextype
            constraints.append('SYNSEM.SUBORDINATED ' + value)
            constraints.append('SYNSEM.LOCAL.CAT.SUBPAIR ' + value)
            # add constriants for the adverb's attaching to vp or s
            if cms.get('adverb-attach') == 's':
                if cms.get('shared-subj') == 'on':
                    constraints.append('SYNSEM.LOCAL [ CONT.HOOK.XARG #xarg,\
                                                       CAT.HEAD.MOD < [ LOCAL [ CONT.HOOK.XARG #xarg,\
                                                                              CAT.VAL [ SUBJ < unexpressed >,\
                                                                                        COMPS < > ]]] > ]'
                                       )
                else:
                    constraints.append(
                        'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ SUBJ < >, COMPS < > ]] >'
                    )
            elif cms.get('adverb-attach') == 'vp':
                constraints.append(
                    'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ SUBJ < [ ] >, COMPS < > ]] >'
                )
            if cms.get('adverb-attach') == 'both':
                constraints.append(
                    'SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT.VAL [ COMPS < > ]] >'
                )
            type = build_type_name(lextype)
            type += '-adv-subord-lex-item'
            mylang.add(type + ' := adverb-subord-lex-item & [ ' +
                       constraints.pop() + ' ].')
            while constraints != []:
                mylang.add(type + ' := [ ' + constraints.pop() + ' ].')
            orth = adverb.get('subordorth')
            orthstr = orth_encode(orth)
            name = TDLencode(adverb.get('subordname'))
            lexicon.add(name + ' := ' + type + ' & [ STEM < "' + orthstr +
                        '" > ].')
Example #18
0
def customize_infl_mod_neg(mylang,ch,lexicon,rules):
  # neg affix on verb requires neg-adv with neg semantics 
  # neg-adv is a modifier 

  # this analysis requires the neg-head-feature, if it's not on
  # simulate it here
  if(ch.get('neg-head-feature')!='on'):
    mylang.add('head :+ [ NEGATED luk ].', section='addenda')

  # add neg-sat to SYNSEM
  mylang.set_section('addenda')
  mylang.add('''synsem :+ [ NEG-SAT luk ].''')

  # verbs must start out NEG-SAT na-or-+
  mylang.add('''basic-verb-lex :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # decorate psrs to pass up NEG-SAT value
  mylang.add('''basic-head-comp-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 
  mylang.add('''basic-head-subj-phrase :+ [ SYNSEM.NEG-SAT #ns,
                                            HEAD-DTR.SYNSEM.NEG-SAT #ns ].''') 

  # ammend root condition
  mylang.add('''clause :+ [ SYNSEM.NEG-SAT na-or-+ ].''')

  # inflecting lexical rule must add NEG-SAT - to verb, 
  for vpc in ch['verb-pc']:
    for lrt in vpc['lrt']:
      for f in lrt['feat']:
        if 'negation' in f['name'] and f['value']=='plus':
          f['value']='e'

  # add type for neg-adv
  mylang.set_section('otherlex')
  mylang.add('''neg-adv-lex := basic-scopal-adverb-lex &
                 [ SYNSEM.LOCAL.CAT [ VAL [ SPR < >,
                                            COMPS < >,
                                            SUBJ < > ],
                                      HEAD [ MOD < [ LOCAL.CAT.HEAD verb ] >,
                                             NEGATED + ]]].''',
             'Type for negative adverbs.')

  mylang.add_comment('neg-adv-lex',
    '''This adverb should go through a specialized phrase structure rule
       included with this grammar.''')

  # now parameterize as pre/posthead, no value here means both orders
  # should work, also add specialized modifier rules
  if ch.get('neg-mod-order-infl-mod-neg') == 'before':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD - ].')
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
  elif ch.get('neg-mod-order-infl-mod-neg') == 'after':
    mylang.add('neg-adv-lex := [ SYNSEM.LOCAL.CAT.POSTHEAD + ].')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')
  else:
    mylang.add('''neg-adj-head-scop-phrase := adj-head-scop-phrase &
                 [ SYNSEM.NEG-SAT +,
                   HEAD-DTR.SYNSEM.NEG-SAT -,
                   NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-adj-head-scop := neg-adj-head-scop-phrase.')
    mylang.add('''neg-head-adj-scop-phrase := head-adj-scop-phrase &
               [ SYNSEM.NEG-SAT +,
                 HEAD-DTR.SYNSEM.NEG-SAT -,
                 NON-HEAD-DTR neg-adv-lex ].''')
    rules.add('neg-head-adj-scop := neg-head-adj-scop-phrase.')


  # constrain type of constituent modified by neg-adv
  if ch.get('neg-mod-infl-mod-neg') == 's':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ null,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-infl-mod-neg') == 'vp':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LOCAL.CAT.VAL [ SUBJ cons,
                                                                                   COMPS null ]].''')
  elif ch.get('neg-mod-infl-mod-neg') == 'v':
    mylang.add('''neg-adv-lex := [ SYNSEM.LOCAL.CAT.HEAD.MOD.FIRST.LIGHT + ].''')

  mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].','''verb-lex is HC-LIGHT - to allow us to pick out\n
  lexical Vs for V-level attachment of negative adverbs.''')
    
  # add spelling for neg-adverb
  if(ch.get('neg-mod-orth')):
    orth = ch.get('neg-mod-orth')
    orthstr = orth_encode(orth)
    lexicon.add(TDLencode(orth) + ' := neg-adv-lex &\
                [ STEM < \"'+ orthstr +'\" >,\
                  SYNSEM.LKEYS.KEYREL.PRED \"neg_rel\" ].')


  mylang.add('+nvcdmo :+ [ MOD < > ].',
             'This grammar includes head-modifier rules.  To keep\n' +
             'out extraneous parses, constrain the value of MOD on\n' +
             'various subtypes of head.  This may need to be loosened later.\n' +
             'This constraint says that only adverbs, adjectives,\n' +
             'and adpositions can be modifiers.',
             section='addenda')
Example #19
0
def customize_case_adpositions(mylang, lexicon, trigger, ch):
    cases = case_names(ch)
    #features = ch.features()
    to_cfv = []

    if ch.has_adp_case():
        comment = \
          ';;; Case-marking adpositions\n' + \
          ';;; Case marking adpositions are constrained not to\n' + \
          ';;; be modifiers.'
        mylang.add_literal(comment)

        mylang.add('+np :+ [ CASE case ].', section='addenda')

        typedef = \
          'case-marking-adp-lex := basic-one-arg & raise-sem-lex-item & \
          [ SYNSEM.LOCAL.CAT [ HEAD adp & [ CASE #case, MOD < > ], \
                               VAL [ SPR < >, \
                                     SUBJ < >, \
                                     COMPS < #comps >, \
                                     SPEC < > ]], \
            ARG-ST < #comps & [ LOCAL.CAT [ HEAD noun & [ CASE #case ], \
                                            VAL.SPR < > ]] > ].'

        mylang.add(typedef)

        if ch.has_mixed_case():
            mylang.add('+np :+ [ CASE-MARKED bool ].', section='addenda')
            mylang.add('case-marking-adp-lex := \
         [ ARG-ST < [ LOCAL.CAT.HEAD.CASE-MARKED - ] > ].')

        # checking whether language has both prepositions and postpositions
        bidirectional = False
        adporders = []
        for adp in ch.get('adp', []):
            adp_order = adp.get('order')
            if not adp_order in adporders:
                adporders.append(adp_order)
        if len(adporders) == 2:
            bidirectional = True
            mylang.add('case-marking-prep-lex := case-marking-adp-lex & \
               [ SYNSEM.LOCAL.CAT.HEADFINAL - ].')
            mylang.add('case-marking-postp-lex := case-marking-adp-lex & \
               [ SYNSEM.LOCAL.CAT.HEADFINAL + ].')

        # Lexical entries
        lexicon.add_literal(';;; Case-marking adpositions')

        for adp in ch.get('adp', []):
            orth = orth_encode(adp.get('orth'))
            infix_tname = 'ad'
            if bidirectional:
                if adp.get('order') == 'before':
                    infix_tname = 'pre'
                elif adp.get('order') == 'after':
                    infix_tname = 'post'

            super_type = 'case-marking-' + infix_tname + 'p-lex'
            # figure out the abbreviation for the case this adp marks
            cn = ''
            abbr = ''
            for feat in adp.get('feat', []):
                if feat['name'] == 'case':
                    cn = feat['value']
                    break

            abbr = name_to_abbr(cn, cases)

            adp_type = TDLencode(abbr + '-marker')
            typedef = \
              adp_type + ' := ' + super_type + ' & \
                        [ STEM < "'                                          + orth + '" > ].'
            lexicon.add(typedef)

            has_inforstr_feat = False
            for feat in adp.get('feat', []):
                if feat['name'] == "information-structure meaning":
                    has_inforstr_feat = True
                    typedef = \
                    adp_type + ' := [ SYNSEM.LOCAL [ CAT.VAL.COMPS < [ LOCAL.CONT.HOOK.INDEX #target ] >, \
                                           CONT [ HOOK.ICONS-KEY #icons, \
                                                  ICONS <! info-str & #icons & [ IARG2 #target ] !> ] ] ] ].'

                    lexicon.add(typedef)
                    break
            if not has_inforstr_feat:
                typedef = \
                adp_type + ' := [ SYNSEM.LOCAL.CONT [ HOOK [ ICONS-KEY.IARG1 #clause, CLAUSE-KEY #clause ], ICONS <! !> ] ].'
                lexicon.add(typedef)

            if cn.strip() != '':
                customize_trigger_rules(adp_type, trigger)

            to_cfv += [(adp.full_key, adp_type, 'adp')]

    return to_cfv
Example #20
0
def customize_verbs(mylang, ch, lexicon, hierarchies):
  negmod = ch.get('neg-mod')
  negadv = ch.get('neg-adv')
  wo = ch.get('word-order')
  auxcomp = ch.get('aux-comp')
  auxorder = ch.get('aux-comp-order')
  # Do we need to constrain HC-LIGHT on verbs, to distinguish V from VP?
  hclight = (negadv == 'ind-adv' and negmod == 'v')
  hclightallverbs = False

  if ch.get('has-aux') == 'yes':
    vc = determine_vcluster(auxcomp, auxorder, wo, ch)
    if wo == 'vso' or wo == 'osv':
      wo = 'req-hcl-vp'
    if auxcomp == 'v' and hclight != True:
      hclight = True
      if wo != 'free' or vc == True:
        hclightallverbs = True
    if auxcomp == 'vp' and wo == 'req-hcl-vp':
      hclightallverbs = True
  else:
    vc = False

  if wo == 'req-hcl-vp':
    wo = ch.get('word-order')

  # Lexical types for verbs
  # I'm adding the constraint to associate XARG with the
  # first ARG-ST element here (so raising auxiliaries work),
  # but perhaps this belongs in matrix.tdl?  Or maybe this
  # is another module/parameter (like, the external argument
  # might not be the first one?

  mainorverbtype = main_or_verb(ch)
  # The variable mainorverbtype is a type name for lexical/main (non-aux) verbs.
  # Note that the use of 'main' instead of 'lexical' is strictly for
  # coding clarity
  # If there are auxiliaries, non-aux verbs are 'main-verb-lex', and 'verb-lex'
  # includes both aux and lexical/main verbs.
  # If there are no auxiliaries then 'verb-lex' covers all verbs

  # Neither mainverbs or auxs should start out as modifiers (for now)
  # Assigning constraint to verb-lex

  if ch.get('has-aux') == 'yes':
    mylang.add('head :+ [ AUX bool ].', section='addenda')
    #mainorverbtype = 'main-verb-lex'

    # we need to know whether the auxiliaries form a vcluster

    auxcomp = ch.get('aux-comp')
    wo = ch.get('word-order')
    auxorder = ch.get('aux-comp-order')
    vcluster = determine_vcluster(auxcomp, auxorder, wo, ch)

    typedef = \
      'verb-lex := non-mod-lex-item & \
                 [ SYNSEM.LOCAL.CAT.HEAD verb ].'
    mylang.add(typedef)
    typedef = \
      'main-verb-lex := verb-lex & basic-verb-lex & \
                      [ SYNSEM.LOCAL.CAT.HEAD.AUX - ].'
    mylang.add(typedef)
    typedef = \
      'aux-lex := verb-lex & \
                [ SYNSEM.LOCAL.CAT.HEAD.AUX + ].'
    mylang.add(typedef)
    if vcluster:
      mylang.add('main-verb-lex := [ SYNSEM.LOCAL.CAT.VC + ].')
      mylang.add('aux-lex := [ SYNSEM.LOCAL.CAT.VC - ].')
  else:
    #mainorverbtype = 'verb-lex'
    vcluster = False
    mylang.add('verb-lex := basic-verb-lex & non-mod-lex-item.')

  typedef = mainorverbtype + ' :=  \
       [ SYNSEM.LOCAL [ CAT.VAL [ SPR < >, \
                                  SPEC < >, \
                                  SUBJ < #subj > ], \
                        CONT.HOOK.XARG #xarg ], \
         ARG-ST < #subj & \
                  [ LOCAL [ CAT.VAL [ SPR < >, \
                                      COMPS < > ], \
                            CONT.HOOK.INDEX #xarg ] ], ... > ].'
  mylang.add(typedef)

  if hclightallverbs:
    mylang.add('verb-lex := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].')
  elif hclight:
    comment = \
      ';;; If there are aspects of the syntax which pick out\n' + \
      ';;; lexical Vs (transitive or intransitive) such as V-attachment\n' + \
      ';;; of adverbs or argument composition auxiliaries which take V\n' + \
      ';;; complements, we need to distinguish (intranstive) V and VP.\n' + \
      ';;; To do so, we make use of a feature LIGHT.  Phrases are\n' + \
      ';;; generally [LIGHT -] with the exception of head-complement\n' + \
      ';;; phrases, which take their value for LIGHT from the head\'s\n' + \
      ';;; HC-LIGHT feature.  To make this work for us here, constraint\n' + \
      ';;; HC-LIGHT on verbs to be -.'
#    mylang.add_literal(comment)
    mylang.add(mainorverbtype + ' := [ SYNSEM.LOCAL.CAT.HC-LIGHT - ].')

  # intransitive verb lexical type
  typedef = \
    'intransitive-verb-lex := ' + mainorverbtype + ' & intransitive-lex-item & \
       [ SYNSEM.LOCAL.CAT.VAL.COMPS < > ].'
  mylang.add(typedef)

  # transitive verb lexical type
  typedef = \
    'transitive-verb-lex := ' + mainorverbtype + ' & transitive-lex-item & \
       [ SYNSEM.LOCAL.CAT.VAL.COMPS < #comps >, \
         ARG-ST < [ ], \
                  #comps & \
                  [ LOCAL.CAT [ VAL [ SPR < >, \
                                      COMPS < > ] ] ] > ].'
  mylang.add(typedef)

  case.customize_verb_case(mylang, ch)

  # Add constraints to choices to create lex rules for bipartite stems
  customize_bipartite_stems(ch)

  # Lexical entries
  lexicon.add_literal(';;; Verbs')

  # Now create the lexical entries for all the defined verb types
  cases = case.case_names(ch)
  for verb in ch.get('verb',[]):
    stypes = verb.get('supertypes').split(', ')
    stype_names = [verb_id(ch[st]) for st in stypes if st != '']

    vtype = verb_id(verb)
    val = verb.get('valence')

    if not val == '':
      i = val.find(',')
      dir_inv = ''
      tivity = ''
      if i != -1:
        val = val[:i]
        dir_inv = 'dir-inv-'

      if val == 'trans':
        tivity = 'trans'
      elif val == 'intrans':
        tivity = 'intrans'
      elif val.find('-') != -1:
        c = val.split('-')
        a_case = case.canon_to_abbr(c[0], cases)
        o_case = case.canon_to_abbr(c[1], cases)
        tivity = a_case + '-' + o_case + '-trans'
      else:
        s_case = case.canon_to_abbr(val, cases)
        tivity = s_case + '-intrans'

      if not dir_inv == '' or not tivity == '':
        stype_names.append(dir_inv + tivity + 'itive-verb-lex')

    if len(stype_names) == 0:
      mylang.add(vtype + ' := verb-lex .')
    else:
      mylang.add(vtype + ' := ' + ' & '.join(stype_names) + '.')

    features.customize_feature_values(mylang, ch, hierarchies, verb, vtype, 'verb', None, cases)

    stems = verb.get('stem', [])
    stems.extend(verb.get('bistem', []))

    for stem in stems:
      orthstr = orth_encode(stem.get('orth'))
      pred = stem.get('pred')
      name = stem.get('name')
      typedef = \
        TDLencode(name) + ' := ' + vtype + ' & \
                    [ STEM < "' + orthstr + '" >, \
                      SYNSEM.LKEYS.KEYREL.PRED "' + pred + '" ].'
      lexicon.add(typedef)
Example #21
0
def customize_adjs(mylang, ch, lexicon, hierarchies, rules):

  # Add basic adjective definition
  if ch.get('adj',[]):
    mylang.add("adj-lex := basic-intersective-adjective-lex.")

  # Check which rules need to be added to rules.tdl
  adj_rules = {'adj_head': False, 'head_adj': False}
  # Check which types need to be added to mylanguage.tdl
  adj_type_base = ('pred_word', 'pred_lex', 'pred_only',
                   'attr_word', 'attr_lex', 'attr_only',
                   'stative_word', 'stative_lex', 'any_adj')
  # Convert into dictionary with False default values
  #adj_types = {item: False for item in adj_types}
  adj_types = dict()
  for item in adj_type_base:
    adj_types[item] = False

  # Lexical super types of different adjective types
  lst_map = {"both": "attr-adj-lex",
             "attr": "attr-only-adj-lex",
             "pred": "pred-only-adj-lex",
             "none": "adj-lex" }

  # Go through adjective position classes...
  for adj_pc in ch.get('adj-pc',[]):
    # check if any have "any adj" as input
    if not adj_types['any_adj'] and 'adj' in adj_pc.get('inputs',[]).split(', '):
      adj_types['any_adj'] = True
    # Additional checks for switching adjectives
    switching = adj_pc.get('switching',False)
    if switching:
      # For each switching adjective...
      for lrt in adj_pc.get('lrt',[]):
        # Check its mode to get lexical types to add
        if not (adj_types['pred_lex'] and adj_types['attr_lex']):
          adj_pc_mod = lrt.get('mod','')
          if adj_pc_mod:
            # TJT 12-05-14: "both" lexical rule types are predicative, too!
            if adj_pc_mod in ('pred','both'):
              adj_types['pred_lex'] = True
            # TJT 11-06-14: "both" lexical rule types are attributive
            elif adj_pc_mod in ('attr','both'):
              adj_types['attr_lex'] = True
        # Check modification direction to get rules to add
        if not (adj_rules['head_adj'] and adj_rules['adj_head']):
          lrt_modpos = lrt.get('modpos',False)
          if lrt_modpos:
            if lrt_modpos == 'before':
              adj_rules['head_adj'] = True
            elif lrt_modpos == 'after':
              adj_rules['adj_head'] = True
            elif lrt_modpos == 'either':
              adj_rules['head_adj'] = True
              adj_rules['adj_head'] = True
        # Check predicative behavoir to get rules to add
        if not adj_types['stative_lex']:
          # If not a copula complement
          if not lrt.get('predcop',False):
            adj_types['stative_lex'] = True

  # Add the lextypes to mylanguage.tdl
  for adj in ch.get('adj',[]):
    # Reset values
    lst, posthead, subj, pred, adj_constraints, modunique = '', '', '', '', '', ''
    root = False

    # Get all supertypes to check for redundant specifications
    all_supertypes, pathToRoot = get_all_supertypes(adj, ch)
    if not pathToRoot:
      raise ValueError("No path to the root was found for type %s." % adj.get('name','') +\
                       "Please try validating your choices and compiling again.")
    # Keep track of redundancies
    supertype_redundancies = defaultdict(lambda: False)

    ## Check pivots
    # Pivot on type of adjective
    mode = adj.get('mod',False)
    # TJT 2014-09-04: Commenting this out because one should be able
    # to define subtypes for purely morphological use
    #if not mode: continue
    # Pivot on modification direction
    modpos = adj.get('modpos',False)
    # Pivot on copula complementation
    predcop = adj.get('predcop',False)
    # Pivot on unique modification
    modunique = adj.get('modunique',False)

    # Optionally copula complement and adjectives that only agree
    # in only position must be unspecified at the lexical level
    if predcop == "opt":
      mode = "none"

    # Check for redundancies and collisions
    def_error = " ".join('''Collision found in supertype at %s!
                            Validate your choices file and try again.
                            Supertype: %s; Supertype Choice: %s
                            Type: %s; Type choice: %s'''.split()).strip()
    for supertype in all_supertypes:
      supertype_choice = ch.get(supertype,False)
      if supertype_choice:
        # Check mode
        if mode:
          supertype_mode = supertype_choice.get('mode',False)
          if supertype_mode:
            if supertype_mode == "both" and mode in ('attr', 'pred'):
              pass # attr and pred unify with both
            elif mode != supertype_mode:
              raise ValueError(def_error % (supertype, supertype_mode, adj.get('name',''), mode))
        # Check modpos
        if modpos:
          supertype_modpos = supertype_choice.get('modpos',False)
          if supertype_modpos:
            if modpos == supertype_modpos:
              supertype_redundancies['modpos'] = True
            elif supertype_modpos == 'either' and modpos in ('before', 'after'):
              pass # before and after unify with either
            else:
              raise ValueError(def_error % (supertype, supertype_modpos, adj.get('name',''), modpos))
        # Check modunique
        if modunique and supertype_choice.get('modunique',False):
          supertype_redundancies['modunique'] = True
        # Check predcop
        if predcop:
          supertype_predcop = supertype_choice.get('predcop',False)
          if supertype_predcop:
            if predcop == supertype_predcop:
              supertype_redundancies['predcop'] = True
            elif supertype_predcop == 'opt' and predcop in ('opt', 'obl'):
              pass
            else:
              raise ValueError(def_error % (supertype, supertype_predcop, adj.get('name',''), predcop))

    ## Calculate supertypes
    stypes = adj.get('supertypes').split(', ')
    stype_names = []
    if '' in stypes: # Found root
      root = True
    # Set up root supertypes
    if root:
      stype_names = [lst_map[mode]]
    # Set up defined supertypes
    else:
      stype_names = [adj_id(ch[st]) for st in stypes if st]
    	  # Add pred-only or attr-only types
      if mode == 'pred' and predcop != 'opt':
        stype_names.append("pred-only-adj-lex")
      elif mode == 'attr':
        stype_names.append("attr-only-adj-lex")
    # Format supertypes
    stype_def = " & ".join(stype_names) or ""
    if stype_def: stype_def += " & "
    # Add pred-only and attr-only types if applicable
    if mode in ('attr','pred'):
      adj_types["%s_only" % mode] = True # Add proper type to mylanguage.tdl

    # For attributive adjectives...
    if mode in ("both", "attr"):
      # Set up proper rule for mylanguage.tdl
      adj_types['attr_word'] = True
      # Pivot on direction of modification
      if not supertype_redundancies['modpos']:
        if modpos == 'after':
          posthead = 'POSTHEAD - '
          adj_rules['adj_head'] = True
        elif modpos == 'before':
          posthead = 'POSTHEAD + '
          adj_rules['head_adj'] = True
        elif modpos == "either":
          adj_rules['head_adj'] = True
          adj_rules['adj_head'] = True
      # Set up unique modification if necessary
      if modunique:
        if not supertype_redundancies['modunique']:
          modunique = 'MOD < [ MODIFIED notmod ] >'
        else: modunique = ''

    if not supertype_redundancies['predcop']:
      # For predicative adjectives...
      if mode in ('both', 'pred'):
        # Set up proper rule for mylanguage.tdl
        # Pivot on copula complement
        if predcop == 'obl':
          # Adjective only appears as copula complement
          pred = '+'
          subj = 'VAL.SUBJ < >'
          if mode == 'pred': adj_types['pred_word'] = True
        elif predcop == 'opt':
          # Switching between copula complement and inflection
          # See deffile.py for zero affixes added here
          adj_types['stative_lex'] = True
          adj_types['pred_lex'] = True
        elif predcop == 'imp':
          # Adjective only appears as stative predicate
          pred = '-'
          adj_types['stative_word'] = True
          adj_types['pred_word'] = True
          # Add additional supertype
          if root: stype_def += 'stative-pred-adj-lex & '

    # Calculate HEAD value
    head = ''
    if pred and modunique:
      head = "HEAD [ PRD %s, %s ]" % (pred, modunique)
    elif pred:
      head = "HEAD.PRD %s" % pred
    elif modunique:
      head = "HEAD." + modunique

    # Only output constraints if defined
    if posthead or pred or subj or modunique:
      adj_constraints = "\n  [ SYNSEM.LOCAL.CAT [" + "\n".join([posthead, subj, head]).strip(",\n") + '] ]'

    # Add lexical types to mylanguage.tdl
    atype = adj_id(adj)
    mylang.add(atype + ' := ' + lst + stype_def + adj_constraints + '.')

  ### Add the proper lexical types to mylanguage.tdl
  ## Add attributive adjective types
  if adj_types['attr_word']:
    mylang.add('''attr-adj-lex := adj-lex & intersective-mod-lex &
                    [ SYNSEM.LOCAL.CAT.HEAD.MOD < [ LOCAL.CAT [ HEAD noun,
                                                                VAL.SPR cons ] ] > ].''',
               comment='Basic attributive adjective definition')
  if adj_types['attr_lex']:
    mylang.add('''attr-adj-lex-rule := add-only-no-ccont-rule &
                    [ SYNSEM [ LOCAL [ CAT.HEAD.MOD < [ LOCAL intersective-mod &
                                                        [ CONT.HOOK.INDEX #xarg,
                                                          CAT [ HEAD noun,
                                                                VAL.SPR cons ] ] ] >,
                                       CONT.HOOK.XARG #xarg ] ] ].''',
               comment='Basic attributive adjective lexical rule definition',
               section='lexrules')

  ## Add attributive-only adjective types
  if adj_types['attr_only']:
    attr_only_map = {'attr_word':
                      {'type_name':'attr-only-adj-lex := attr-adj-lex & ',
                       'section':''},
                     'attr_lex':
                      {'type_name':'attr-only-adj-lex-rule := attr-adj-lex-rule & ',
                       'section':'lexrules'} }
    for sort in ('attr_word', 'attr_lex'):
      if adj_types[sort]:
        mylang.add('''%s [ SYNSEM.LOCAL.CAT [ HEAD.PRD -,
                                              VAL.SUBJ < > ] ].''' % \
                      attr_only_map[sort]['type_name'],
                      section=attr_only_map[sort]['section'])

  ## Add predicative-only adjective types
  if adj_types['pred_only']:
    if adj_types['pred_word']:
      mylang.add('''pred-only-adj-lex := adj-lex & no-mod-lex.''')
    if adj_types['pred_lex']:
      mylang.add('''pred-only-adj-lex-rule := add-only-no-ccont-rule & no-mod-lex.''')

  ## Add additional types
  # If there are stative predicates, add the proper rule and supertype
  pred_adj_map = {'stative_word':
                    {'supertype':'stative-pred-adj-lex := adj-lex &',
                     'comment':'Stative predicate adjective definition',
                     'section':''},
                  'stative_lex':
                    {'supertype':'stative-pred-lex-rule := add-only-no-ccont-rule & ',
                     'comment':'Stative predicate adjective lexical rule definition',
                     'section':'lexrules'}}
  pred_adj_definition = '''%s
    [ SYNSEM.LOCAL [ CAT.VAL.SUBJ < [ LOCAL [ CONT.HOOK.INDEX #xarg,
  		   		    	                       CAT [ VAL [ SPR < >,
                                                           COMPS < > ],
                                                    HEAD noun ] ] ] >,
                     CONT.HOOK.XARG #xarg ] ].'''
  for form in ("stative_word", "stative_lex"):
    if adj_types[form]:
      mylang.add(pred_adj_definition % pred_adj_map[form]['supertype'],
                 comment=pred_adj_map[form]['comment'],
                 section=pred_adj_map[form]['section'])

  # If adjective incorporation, add to mylanguage.tdl
  if ch.get("adj_incorp",False):
    mylang.add('''adj_incorporation-lex-rule := add-only-rule &
                    [ C-CONT [ RELS <! arg1-ev-relation &
                                       [ LBL #ltop,
		                                 ARG1 #index ] !>,
	                           HOOK #hook ],
                      DTR.SYNSEM.LOCAL [ CAT.HEAD noun,
  		                                 CONT.HOOK #hook &
    			                                   [ LTOP #ltop,
			                                         INDEX #index ] ] ].''',
            comment='Adjective Incorporation',
            section='lexrules')

  # Add the proper syntactic rules to rules.tdl
  if adj_rules['head_adj']: rules.add("head-adj-int := head-adj-int-phrase.")
  if adj_rules['adj_head']: rules.add("adj-head-int := adj-head-int-phrase.")

  # Add the lexical entries to lexicon.tdl
  lexicon.add_literal(';;; Adjectives')

  for adj in ch.get('adj',[]):
    atype = adj_id(adj)

    # Automatically generate feature values based on choices
    features.customize_feature_values(mylang, ch, hierarchies, adj, atype, 'adj')

    for stem in adj.get('stem', []):
      typedef = TDLencode(stem.get('name')) + ' := ' + atype + ' & \n \
                [ STEM < "' + orth_encode(stem.get('orth')) + '" >, \
                SYNSEM.LKEYS.KEYREL.PRED "' + stem.get('pred') + '" ].'
      lexicon.add(typedef)
Example #22
0
def customize_nouns(mylang, ch, lexicon, hierarchies):
  # Figure out which kinds of determiner-marking are in the language
  seen = {'obl':False, 'opt':False, 'imp':False}
  seenCount = 0

  for noun in ch.get('noun',[]):
    det = noun.get('det')
    if not det == '' and not seen[det]:
      seen[det] = True
      seenCount += 1

  singlentype = (seenCount == 1)

  # Playing fast and loose with the meaning of OPT on SPR.  Using
  # OPT - to mean obligatory (as usual), OPT + to mean impossible (that's
  # weird), and leaving OPT unspecified for truly optional.  Hoping
  # this will work at least for LSA111 lab.

  # ERB 2006-11-28 Update: To make that weird use of OPT work, the
  # head-spec rule has to require [OPT -] on its non-head daughter.
  # Adding that just in case we add the no-spr-noun-lex type.

  typedef = \
    'noun-lex := basic-noun-lex & basic-one-arg & no-hcons-lex-item & \
       [ SYNSEM.LOCAL [ CAT.VAL [ SPR < #spr & [ LOCAL.CAT.HEAD det ] >, \
                                  COMPS < >, \
                                  SUBJ < >, \
                                  SPEC < > ] ], \
         ARG-ST < #spr > ].'
  mylang.add(typedef)

  # Adding empty MOD on general definitiion for noun-lex
  mylang.add('noun-lex := non-mod-lex-item.')

  # singlentype means there's only one type of n in the hierarchy.
  if singlentype:
    if seen['obl']:
      typedef = 'noun-lex := [ SYNSEM.LOCAL.CAT.VAL.SPR < [ OPT - ] > ].'
      mylang.add(typedef)
    elif seen['imp']:
      typedef = 'noun-lex := [ SYNSEM.LOCAL.CAT.VAL.SPR < [ OPT + ] > ].'
      mylang.add(typedef)
  else:
    if seen['obl']:
      typedef = \
        'obl-spr-noun-lex := noun-lex & \
           [ SYNSEM.LOCAL.CAT.VAL.SPR < [ OPT - ] > ].'
      mylang.add(typedef)

    if seen['imp']:
      typedef = \
        'no-spr-noun-lex := noun-lex & \
           [ SYNSEM.LOCAL.CAT.VAL.SPR < [ OPT + ] > ].'
      mylang.add(typedef)

  if seen['imp'] and ch.get('has-dets') == 'yes':
    mylang.add(
      'head-spec-phrase := [ NON-HEAD-DTR.SYNSEM.OPT - ].',
      'Nouns which cannot take specifiers mark their SPR requirement\n' +
      'as OPT +.  Making the non-head daughter OPT - in this rule\n' +
      'keeps such nouns out.')

  if ch.get('case-marking') != 'none':
    if not ch.has_adp_case():
      mylang.add('noun :+ [ CASE case ].', section='addenda')

  # Add the lexical entries
  lexicon.add_literal(';;; Nouns')

  # make a hash of nountypes --> lists of children so that we
  # can stopdet on children
  children = defaultdict(dict)
  for noun in ch.get('noun',[]):
    for p in noun.get('supertypes').split(', '):
      children[p][noun.full_key] = 1

  # make and populate a dictionary of stopdets, to avoid vacuous det supertypes
  # have to follow inheritance paths downwards from any nonempty det values
  stopdets={}
  for noun in ch.get('noun',[]):
    # if det is nonempty, child nouns shouldn't inherit det
    det = noun.get('det')
    if det != '':
      if noun.full_key in children:
      # there are children to stopdet on
      # recursively look for children
        parents = [ noun.full_key ]
        while (True):
          next_parents = []
          for p in parents:
            if p in children:
              for c in children[p].keys():
                stopdets[c]=True
                if not c in next_parents:
                  next_parents.append(c)
          if len(next_parents) == 0:
            break
          else:
            parents = next_parents


  for noun in ch.get('noun',[]):
    ntype = noun_id(noun)
    det = noun.get('det')
    if noun.full_key in stopdets:
      det = ''

    stypes = noun.get('supertypes').split(', ')
    stype_names = [noun_id(ch[st]) for st in stypes if st != '']

    #if singlentype or det == 'opt':
    #  stype = 'noun-lex'
    if not singlentype:
      if det == 'obl':
        stype_names.append('obl-spr-noun-lex')
      elif det == 'imp':
        stype_names.append('no-spr-noun-lex')

    if len(stype_names) == 0:
      mylang.add(ntype + ' := noun-lex .')
    else:
      mylang.add(ntype + ' := ' + ' & '.join(stype_names) + '.')

    features.customize_feature_values(mylang, ch, hierarchies, noun, ntype, 'noun')

    for stem in noun.get('stem', []):
      orthstr = orth_encode(stem.get('orth'))
      pred = stem.get('pred')
      name = stem.get('name')
      typedef = TDLencode(name) + ' := ' + ntype + ' & \
                  [ STEM < "' + orthstr + '" >, \
                    SYNSEM.LKEYS.KEYREL.PRED "' + pred + '" ].'
      lexicon.add(typedef)
Example #23
0
def customize_case_adpositions(mylang, lexicon, trigger, ch, case_pos):
    cases = case_names(ch)
    # features = ch.features()
    to_cfv = []

    if ch.has_adp_case():
        comment = \
            ';;; Case-marking adpositions\n' + \
            ';;; Case marking adpositions are constrained not to\n' + \
            ';;; be modifiers.'
        mylang.add_literal(comment)
        case_pos.add('adp')
        #mylang.add('+np :+ [ CASE case ].', section='addenda')

        # EKN 2018-04-14 Case marking adps need to be marked as nonpossessive
        poss = True if ch.get('poss-strat') or ch.get('poss-pron') else False

        typedef = \
            'case-marking-adp-lex := non-local-none-lex-item & raise-sem-lex-item & \
                [ SYNSEM.LOCAL.CAT [ HEAD adp & [ CASE #case, MOD < > ], \
                                     VAL [ SPR < >, \
                                           SUBJ < >, \
                                           COMPS < #comps >, \
                                           SPEC < > ]], \
                  ARG-ST < #comps & [ LOCAL.CAT [ HEAD noun & [ CASE #case ], \
                                                  VAL.SPR < > ]] > ].'

        mylang.add(typedef)

        # EKN 03-02-2018 Add CASE real-case to comp of adp if possessives
        # implemented:
        if poss:
            mylang.add('case-marking-adp-lex := [ SYNSEM.LOCAL.CAT \
                           [ HEAD.POSSESSOR nonpossessive, \
                                  POSSESSUM nonpossessive ], \
                             ARG-ST < [ LOCAL.CAT.HEAD.CASE real-case ] > ].')

        if ch.has_mixed_case():
            mylang.add('+np :+ [ CASE-MARKED bool ].', section='addenda')
            mylang.add('case-marking-adp-lex := \
                 [ ARG-ST < [ LOCAL.CAT.HEAD.CASE-MARKED - ] > ].')

        # checking whether language has both prepositions and postpositions
        bidirectional = False
        adporders = []
        for adp in ch.get('adp', []):
            adp_order = adp.get('order')
            if adp_order not in adporders:
                adporders.append(adp_order)
        if len(adporders) == 2:
            bidirectional = True
            mylang.add('case-marking-prep-lex := case-marking-adp-lex & \
               [ SYNSEM.LOCAL.CAT.HEADFINAL - ].')
            mylang.add('case-marking-postp-lex := case-marking-adp-lex & \
               [ SYNSEM.LOCAL.CAT.HEADFINAL + ].')

        # Lexical entries
        lexicon.add_literal(';;; Case-marking adpositions')

        adp_type_names = []
        for adp in ch.get('adp', []):
            orth = orth_encode(adp.get('orth'))
            infix_tname = 'ad'
            if bidirectional:
                if adp.get('order') == 'before':
                    infix_tname = 'pre'
                elif adp.get('order') == 'after':
                    infix_tname = 'post'

            super_type = 'case-marking-' + infix_tname + 'p-lex'
            # figure out the abbreviation for the case this adp marks
            cn = ''
            abbr = ''
            for feat in adp.get('feat', []):
                if feat['name'] == 'case':
                    cn = feat['value']
                    break

            abbr = name_to_abbr(cn, cases)

            # the type name for the adp marker includes the orthography of the marker at the end
            # this serves to ensure each marker has its own lexical entry
            # and prevents them from being "merged" due to having identical names
            adp_type = TDLencode(abbr + '-marker_' + orth)
            adp_type_names.append(adp_type)

            typedef = \
                adp_type + ' := ' + super_type + ' & \
                        [ STEM < "'                                    + orth + '" > ].'
            lexicon.add(typedef)

            has_inforstr_feat = False
            for feat in adp.get('feat', []):
                if feat['name'] == "information-structure meaning":
                    has_inforstr_feat = True
                    typedef = adp_type + \
                        ' := [ SYNSEM.LOCAL \
                                [ CAT.VAL.COMPS < \
                                    [ LOCAL.CONT.HOOK.INDEX #target ] >, \
                                  CONT [ HOOK.ICONS-KEY #icons, \
                                         ICONS.LIST < info-str & \
                                         #icons & [ \
                                             IARG2 #target ] > ] ] ] ].'

                    lexicon.add(typedef)
                    break
            if not has_inforstr_feat:
                typedef = \
                    adp_type + ' := [ SYNSEM.LOCAL.CONT [ \
                                        HOOK [ ICONS-KEY.IARG1 #clause, \
                                               CLAUSE-KEY #clause ], \
                                        ICONS.LIST < > ] ].'

                lexicon.add(typedef)

            if cn.strip() != '':
                customize_trigger_rules(adp_type, trigger)

            to_cfv += [(adp.full_key, adp_type, 'adp')]
    return to_cfv
Example #24
0
def customize_coordination(mylang, ch, lexicon, rules, irules):
    """
  The main coordination customization routine
  """
    mylang.set_section('coord')

    for cs in ch.get('cs'):
        csnum = str(cs.iter_num())

        mark = cs.get('mark')
        pat = cs.get('pat')
        orth = cs.get('orth')
        orthstr = orth_encode(orth)
        order = cs.get('order')

        pre = ''
        suf = ''

        tn = TDLencode(orth)
        if (len(ch.get('cs')) > 1):
            tn += csnum

        if mark == 'word':
            lexicon.add(tn + ' := conj-lex &\
                  [ STEM < "' + orthstr + '" >,\
                    SYNSEM.LKEYS.KEYREL.PRED "_and_coord_rel",\
                    CFORM "' + csnum + '" ].')
            if pat == 'omni':
                lexicon.add(tn + '_nosem := nosem-conj-lex &\
                      [ STEM < "' + orthstr + '" >,\
                        CFORM "' + csnum + '" ].')

        if pat == 'a':
            top = 'apoly-'
            mid = ''
            bot = 'unary-'
            left = ''
        else:
            if pat == 'mono':
                top = 'monopoly-'
                mid = 'monopoly-'
                bot = ''
                left = ''
            elif pat == 'omni':
                top = 'omni-'
                mid = 'omni-'
                bot = 'omni-'
                left = 'omni-'
            elif pat == 'poly':
                top = 'apoly-'
                mid = ''
                bot = ''
                left = ''

            if mark == 'affix':
                bot = 'infl-'
                if order == 'before':
                    pre = orth
                else:
                    suf = orth
            else:
                if order == 'before':
                    bot += 'conj-first-'
                    if left:
                        left += 'conj-first-'
                else:
                    bot += 'conj-last-'
                    if left:
                        left += 'conj-last-'

        # hook this coord strat up to some agreement patterns, or not, if we have no info.
        if cs.get('csap'):
            agrrules = []
            for csap in cs.get('csap'):  # get the agreement patterns used
                agrrules += customize_agreement_pattern(
                    mylang, ch, csap)  # fetch the agreement rules
        else:
            agrrules = [('', '')]

        for pos in ('n', 'np', 'vp', 's'):
            agrrules = [('', '')] if pos in ('vp', 's') else agrrules
            if cs.get(pos):
                define_coord_strat(csnum, pos, top, mid, bot, left, pre, suf,
                                   mylang, rules, irules, agrrules)