Exemple #1
0
def _encode_eds(e, properties, lnk, show_status, indent):
    # do something predictable for empty EDS
    if len(e.nodes) == 0:
        return '{:\n}' if indent else '{:}'

    # determine if graph is connected
    g = {node.id: set() for node in e.nodes}
    for node in e.nodes:
        for target in node.edges.values():
            g[node.id].add(target)
            g[target].add(node.id)
    nidgrp = _bfs(g, start=e.top)

    status = ''
    if show_status and nidgrp != set(g):
        status = ' (fragmented)'
    delim = '\n' if indent else ' '
    connected = ' ' if indent else ''
    disconnected = '|' if show_status else ' '

    ed_list = []
    for node in e.nodes:
        membership = connected if node.id in nidgrp else disconnected
        ed_list.append(membership + _encode_node(node, properties, lnk))

    return '{{{top}{status}{delim}{ed_list}{enddelim}}}'.format(
        top=e.top + ':' if e.top is not None else ':',
        status=status,
        delim=delim,
        ed_list=delim.join(ed_list),
        enddelim='\n' if indent else '')
def is_connected(m: mrs.MRS) -> bool:
    """
    Return `True` if *m* is a fully-connected MRS.

    A connected MRS is one where, when viewed as a graph, all EPs are
    connected to each other via regular (non-scopal) arguments, scopal
    arguments (including qeqs), or label equalities.
    """
    ids = {ep.id for ep in m.rels}
    g: Dict[Identifier, Set[Identifier]] = {id: set() for id in ids}
    # first establish links from labels and intrinsic variables to EPs
    for ep in m.rels:
        id, lbl, iv = ep.id, ep.label, ep.iv
        g[id].update((lbl, iv))
        g.setdefault(lbl, set()).add(id)
        if iv:
            g.setdefault(iv, set()).add(id)
    # arguments may link EPs with IVs or labels (or qeq) as targets
    hcmap = {hc.hi: hc.lo for hc in m.hcons}
    for id, roleargs in m.arguments().items():
        for role, value in roleargs:
            value = hcmap.get(value, value)  # resolve qeq if any
            if value in g:
                g[id].add(value)
                g[value].add(id)
    return ids.issubset(util._bfs(g))
Exemple #3
0
def _serialize_eds(e, properties, pretty_print, show_status,
                   predicate_modifiers):
    if not isinstance(e, Eds):
        e = Eds.from_xmrs(e, predicate_modifiers=predicate_modifiers)
    # do something predictable for empty EDS
    if len(e.nodeids()) == 0:
        return '{:\n}' if pretty_print else '{:}'

    # determine if graph is connected
    g = {n: set() for n in e.nodeids()}
    for n in e.nodeids():
        for tgt in e.edges(n).values():
            g[n].add(tgt)
            g[tgt].add(n)
    nidgrp = _bfs(g, start=e.top)

    status = ''
    if show_status and nidgrp != set(e.nodeids()):
        status = ' (fragmented)'
    delim = '\n' if pretty_print else ' '
    connected = ' ' if pretty_print else ''
    disconnected = '|' if show_status else ' '

    return eds.format(
        top=e.top + ':' if e.top is not None else ':',
        flag=status,
        delim=delim,
        ed_list=delim.join(
            ed.format(
                membership=connected if n.nodeid in nidgrp else disconnected,
                id=n.nodeid,
                pred=n.pred.short_form(),
                lnk=str(n.lnk) if n.lnk else '',
                carg=carg.format(constant=n.carg) if n.carg else '',
                props=proplist.format(
                    varsort=n.cvarsort + ' ' if n.cvarsort else '',
                    proplist=', '.join(
                        '{} {}'.format(k, v)
                        for k, v in sorted(n.properties.items())
                    )
                ) if properties and n.sortinfo else '',
                dep_list=(', '.join(
                    '{} {}'.format(rargname, tgt)
                    for rargname, tgt in sorted(
                        e.edges(n.nodeid).items(),
                        key=lambda x: rargname_sortkey(x[0])
                    )
                )),
            )
            for n in e.nodes()
        ),
        enddelim='\n' if pretty_print else ''
    )
Exemple #4
0
def to_triples(d, properties=True, lnk=True):
    """
    Encode *d* as triples suitable for PENMAN serialization.
    """
    # determine if graph is connected
    g = {node.id: set() for node in d.nodes}
    for link in d.links:
        g[link.start].add(link.end)
        g[link.end].add(link.start)
    main_component = _bfs(g, start=d.top)
    complete = True

    idmap = {}
    quantifiers = {node.id for node in d.nodes if d.is_quantifier(node.id)}
    for i, node in enumerate(d.nodes, 1):
        if node.id in quantifiers:
            idmap[node.id] = 'q' + str(i)
        else:
            idmap[node.id] = '{}{}'.format(node.type or '_', i)
    # sort the nodes so the top node appears first
    nodes = sorted(d.nodes, key=lambda n: d.top != n.id)
    triples = []
    for node in nodes:
        if node.id in main_component:
            _id = idmap[node.id]
            triples.append((_id, ':instance', node.predicate))
            if lnk and node.lnk is not None:
                triples.append((_id, ':lnk', '"{}"'.format(str(node.lnk))))
            if node.carg is not None:
                triples.append((_id, ':carg', '"{}"'.format(node.carg)))
            if node.type:
                triples.append((_id, ':' + CVARSORT, node.type))
            if properties:
                for key in sorted(node.properties, key=property_priority):
                    value = node.properties[key]
                    triples.append((_id, ':' + key.lower(), value))
        else:
            complete = False

    # if d.top is not None:
    #     triples.append((None, 'top', d.top))
    for link in d.links:
        if link.start in main_component and link.end in main_component:
            start = idmap[link.start]
            end = idmap[link.end]
            relation = ':{}-{}'.format(link.role.upper(), link.post)
            triples.append((start, relation, end))

    if not complete:
        logger.warning('disconnected graph cannot be completely encoded: %r',
                       d)
    return triples
Exemple #5
0
    def is_connected(self):
        """
        Return `True` if the Xmrs represents a connected graph.

        Subgraphs can be connected through things like arguments,
        QEQs, and label equalities.
        """
        nids = set(self._nodeids)  # the nids left to find
        if len(nids) == 0:
            raise XmrsError('Cannot compute connectedness of an empty Xmrs.')
        # build a basic dict graph of relations
        edges = []
        # label connections
        for lbl in self.labels():
            lblset = self.labelset(lbl)
            edges.extend((x, y) for x in lblset for y in lblset if x != y)
        # argument connections
        _vars = self._vars
        for nid in nids:
            for rarg, tgt in self.args(nid).items():
                if tgt not in _vars:
                    continue
                if IVARG_ROLE in _vars[tgt]['refs']:
                    tgtnids = list(_vars[tgt]['refs'][IVARG_ROLE])
                elif tgt in self._hcons:
                    tgtnids = list(self.labelset(self.hcon(tgt)[2]))
                elif 'LBL' in _vars[tgt]['refs']:
                    tgtnids = list(_vars[tgt]['refs']['LBL'])
                else:
                    tgtnids = []
                # connections are bidirectional
                edges.extend((nid, t) for t in tgtnids if nid != t)
                edges.extend((t, nid) for t in tgtnids if nid != t)
        g = {nid: set() for nid in nids}
        for x, y in edges:
            g[x].add(y)
        connected_nids = _bfs(g)
        if connected_nids == nids:
            return True
        elif connected_nids.difference(nids):
            raise XmrsError('Possibly bogus nodeids: {}'.format(', '.join(
                connected_nids.difference(nids))))
        return False
Exemple #6
0
def to_triples(e, properties=True, lnk=True):
    """
    Encode the Eds as triples suitable for PENMAN serialization.
    """
    # determine if graph is connected
    g = {node.id: set() for node in e.nodes}
    for node in e.nodes:
        for target in node.edges.values():
            g[node.id].add(target)
            g[target].add(node.id)
    main_component = _bfs(g, start=e.top)
    complete = True

    triples = []
    # sort node ids just so top var is first
    nodes = sorted(e.nodes, key=lambda n: n.id != e.top)
    for node in nodes:
        nid = node.id
        if nid in main_component:
            triples.append((nid, ':instance', node.predicate))
            if lnk and node.lnk:
                triples.append((nid, ':lnk', '"{}"'.format(str(node.lnk))))
            if node.carg:
                triples.append((nid, ':carg', '"{}"'.format(node.carg)))
            if node.type is not None:
                triples.append((nid, ':type', node.type))
            if properties:
                for prop in sorted(node.properties, key=property_priority):
                    rel = ':' + prop.lower()
                    triples.append((nid, rel, node.properties[prop]))
            for role in sorted(node.edges, key=role_priority):
                triples.append((nid, ':' + role, node.edges[role]))
        else:
            complete = False

    if not complete:
        logger.warning(
            'disconnected graph cannot be completely encoded: %r', e)
    return triples