예제 #1
0
def test_type():
    assert variable.type('x1') == 'x'
    assert variable.type('event10') == 'event'
    assert variable.type('ref-ind2') == 'ref-ind'
    with pytest.raises(ValueError):
        variable.type('x')
    # and sort alias
    assert variable.sort('x1') == 'x'
예제 #2
0
def get_extractable(ep):
    ''' return a list of arg_id for entity arguments of ep '''
    # ignore CARG (constant arg) when extracting variables
    arg_ids = [x for x in ep.args if x.startswith('ARG')]
    return [
        arg_id for arg_id in arg_ids if variable.type(ep.args[arg_id]) == 'x'
    ]
예제 #3
0
def _prepare_variable_properties(m, semi):
    proplists = {}
    for var, varprops in m.variables.items():
        if varprops:
            proplists[var] = [
                varprops.get(key, val).upper()
                for key, val in semi.variables[variable.type(var)]]
    return proplists
예제 #4
0
def _match_properties(variables, semi):
    for var, propvals in variables.items():
        if not propvals:
            continue
        semiprops = semi.variables[variable.type(var)]
        assert len(semiprops) == len(propvals)
        assert all(semi.properties.subsumes(sp[1], pv)
                   for sp, pv in zip(semiprops, propvals))
        variables[var] = {sp[0]: pv for sp, pv in zip(semiprops, propvals)}
예제 #5
0
def _encode_variable(var, varprops):
    tokens = [var]
    if varprops.get(var):
        tokens.append('[')
        tokens.append(variable.type(var))
        for prop in sorted(varprops[var], key=property_priority):
            val = varprops[var][prop]
            tokens.append(prop + ':')
            tokens.append(val)
        tokens.append(']')
        del varprops[var]
    return ' '.join(tokens)
예제 #6
0
def _mrs_to_nodes(m, edges):
    nodes = []
    for ep in m.rels:
        properties, type = None, None
        if not ep.is_quantifier():
            iv = ep.iv
            properties = m.properties(iv)
            type = variable.type(iv)
        nodes.append(
            eds.Node(ep.id, ep.predicate, type, edges.get(ep.id, {}),
                     properties, ep.carg, ep.lnk, ep.surface, ep.base))
    return nodes
예제 #7
0
def _mrs_to_nodes(m, id_to_nid):
    nodes = []
    for ep in m.rels:
        node_id = id_to_nid[ep.id]
        properties, type = None, None
        if not ep.is_quantifier():
            iv = ep.iv
            properties = m.properties(iv)
            type = variable.type(iv)
        nodes.append(
            dmrs.Node(node_id, ep.predicate, type, properties, ep.carg, ep.lnk,
                      ep.surface, ep.base))
    return nodes
예제 #8
0
def _decode_rel(lexer, variables, semi):
    label, _, pred = lexer.expect_type(SYMBOL, COLON, SYMBOL)
    lnk = _decode_lnk(lexer)
    arglist, carg = _decode_arglist(lexer, variables)
    argtypes = [variable.type(arg) for arg in arglist]
    synopsis = semi.find_synopsis(pred, argtypes)
    args = {d[0]: v for d, v in zip(synopsis, arglist)}
    if carg:
        args[CONSTANT_ROLE] = carg
    return EP(
        pred,
        label,
        args=args,
        lnk=lnk,
        surface=None,
        base=None)
예제 #9
0
def has_neg_q(sem, index_ep):
    '''
    return
        True, list index of _no_q if ARG1 of index_ep is bound by _no_q
        False, 0 if ARG1 of index_ep is an x variable and is not bound by _no_q
        False, 1 if index_ep does not have an ARG of type x
    '''
    subj = index_ep.args.get('ARG1')
    if not subj:
        return False, 1
    if variable.type(subj) != 'x':
        return False, 1
    for i, ep in enumerate(sem.rels):
        if ep.args.get('ARG0') == subj:
            if ep.predicate == '_no_q':
                return True, i

    return False, 0
예제 #10
0
    def arguments(self, types=None, expressed=None):
        ivs = {ep.iv for ep in self.rels}
        args = {}

        for ep in self.rels:
            id = ep.id
            args[id] = []
            for role, value in ep.args.items():
                # only outgoing arguments
                if role in (INTRINSIC_ROLE, CONSTANT_ROLE):
                    continue
                # ignore undesired argument types
                if types is not None and variable.type(value) not in types:
                    continue
                # only include expressed/unexpressed if requested
                if expressed is not None and (value in ivs) != expressed:
                    continue
                args[id].append((role, value))

        return args
예제 #11
0
 def _var(v):
     d = {'type': variable.type(v)}
     if properties and mrs.variables.get(v):
         d['properties'] = dict(mrs.variables[v])
     return d
예제 #12
0
def find_predicate_modifiers(e, m, representatives=None):
    """
    Return an argument structure mapping for predicate-modifier edges.

    In EDS, predicate modifiers are edges that describe a relation
    between predications in the original MRS that is not evident on
    the regular and scopal arguments. In practice these are EPs that
    share a scope but do not select any other EPs within their scope,
    such as when quantifiers are modified ("nearly every...") or with
    relative clauses ("the chef whose soup spilled..."). These are
    almost the same as the MOD/EQ links of DMRS, except that predicate
    modifiers have more restrictions on their usage, mainly due to
    their using a standard role (`ARG1`) instead of an
    idiosyncratic one.

    Generally users won't call this function directly, but by calling
    :func:`from_mrs` with `predicate_modifiers=True`, but it is
    visible here in case users want to inspect its results separately
    from MRS-to-EDS conversion. Note that when calling it separately,
    *e* should use the same predication ids as *m* (by calling
    :func:`from_mrs` with `unique_ids=False`). Also, users may define
    their own function with the same signature and return type and use
    it in place of this one. See :func:`from_mrs` for details.

    Args:
        e: the EDS converted from *m* as by calling :func:`from_mrs`
            with `predicate_modifiers=False` and `unique_ids=False`,
            used to determine if parts of the graph are connected
        m: the source MRS
        representatives: the scope representatives; this argument is
            mainly to prevent :func:`delphin.scope.representatives`
            from being called twice on *m*
    Returns:
        A dictionary mapping source node identifiers to
        role-to-argument dictionaries of any additional
        predicate-modifier edges.
    Examples:
        >>> e = eds.from_mrs(m, predicate_modifiers=False)
        >>> print(eds.find_predicate_modifiers(e.argument_structure(), m)
        {'e5': {'ARG1': '_1'}}
    """
    if representatives is None:
        representatives = scope.representatives(m)
    role = eds.PREDICATE_MODIFIER_ROLE

    # find connected components so predicate modifiers only connect
    # separate components
    ids = {ep.id for ep in m.rels}
    edges = []
    for node in e.nodes:
        for _, tgt in node.edges.items():
            edges.append((node.id, tgt))
    components = util._connected_components(ids, edges)

    ccmap = {}
    for i, component in enumerate(components):
        for id in component:
            ccmap[id] = i

    addl = {}
    if len(components) > 1:
        for label, eps in representatives.items():
            if len(eps) > 1:
                first = eps[0]
                joined = set([ccmap[first.id]])
                for other in eps[1:]:
                    occ = ccmap[other.id]
                    type = variable.type(other.args.get(role, 'u0'))
                    needs_edge = occ not in joined
                    edge_available = type.lower() == 'u'
                    if needs_edge and edge_available:
                        addl.setdefault(other.id, {})[role] = first.id
                        joined.add(occ)
    return addl