Skip to content

Construct scope trees and fragments #241

@goodmami

Description

@goodmami

In the new delphin.scope module I had a function tree_fragments() which constructed the partial scope trees and allowed inspection of immediately lower scopes (lheqs) and indirectly lower scopes (qeqs) for each scope label. In the end I needed per-predicate granularity when looking at scopal descendants (rather than the descendants of the whole scope) for representative node selection, so I started finding other ways of doing this. With scope.descendants() I no longer need the UnderspecifiedScope class or the tree_fragments() function. They may still be useful in the future for enumerating scope readings (see #221) so I copy those bits of code here. Re-adding the same functionality to PyDelphin might not use the code directly; they are just copied for reference.

class UnderspecifiedScope(tuple):
    """
    Quantifier scope with underspecified constraints.

    This class serves as the nodes in the scope tree fragments used by
    MRS (and transformations of DMRS). It combines three data
    structures:

    * the ids of predications in the immediate scope

    * a mapping of labels to :class:`UnderspecifiedScope` objects for
      scopes directly under the current scope

    * a mapping of labels to :class:`UnderspecifiedScope` objects for
      scopes qeq from the current scope

    This class is not meant to be instantiated directly, but rather is
    used in the return value of functions such as
    :func:`tree_fragments`.

    Attributes:
        ids: ids of predications in the immediate scope
        lheqs: mapping of labels to underspecified scopes directly
            under the current scope
        qeqs: mapping of labels to underspecified scopes qeq from
            the current scope
    """

    __slots__ = ()

    def __new__(cls,
                ids: Container[Identifier],
                lheqs: UnderspecifiedFragments = None,
                qeqs: UnderspecifiedFragments = None):
        if lheqs is None:
            lheqs = {}
        if qeqs is None:
            qeqs = {}
        return super().__new__(cls, (set(ids), dict(lheqs), dict(qeqs)))

    ids = property(
        itemgetter(0), doc='set of ids of predicates in the immediate scope')
    lheqs = property(
        itemgetter(1), doc='directly lower scopes')
    qeqs = property(
        itemgetter(2), doc='indirectly lower scopes')

    def __repr__(self):
        return 'UnderspecifiedScope({!r}, {!r}, {!r})'.format(*self)

    def __contains__(self, id):
        return (id in self.ids
                or any(id in lower for lower in self.lheqs.values())
                or any(id in lower for lower in self.qeqs.values()))
def tree_fragments(x: ScopingSemanticStructure,
                   prune=True) -> UnderspecifiedFragments:
    """
    Return a mapping of scope labels to underspecified tree fragments.

    Each fragment is an :class:`UnderspecifiedScope` object.

    By default the top-level mapping only includes the fragments that
    are not specified as being under another scope. By setting the
    *prune* parameter to `False` all scope labels are included in the
    mapping, which may be helpful for applications needing direct
    access to lower scopes.

    Args:
        x: an MRS or DMRS
        prune: if `True` only include top-level scopes in the mapping
    """
    scopes = x.scopes()
    fragments = {x.top: UnderspecifiedScope([])}
    for label, ps in scopes.items():
        fragments[label] = UnderspecifiedScope(ps)

    nested = set()
    for src, sc_roleargs in x.scopal_arguments(scopes).items():
        for _, rel, label in sc_roleargs:
            if rel == LHEQ:
                fragments[src].lheqs[tgt] = fragments[tgt]
                nested.add(tgt)
            elif rel == QEQ:
                fragments[src].qeqs[tgt] = fragments[tgt]
                nested.add(tgt)

    if prune:
        for label in nested:
            del fragments[label]

    return fragments

Metadata

Metadata

Assignees

No one assigned

    Labels

    *mrsRelated to MRS, DMRS, EDS, etc.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions