Exemple #1
0
    def add_hcons(self, hcons):
        """
        Incorporate the list of HandleConstraints given by *hcons*.
        """
        # (hi, relation, lo)
        _vars = self._vars
        _hcons = self._hcons
        for hc in hcons:
            try:
                if not isinstance(hc, HandleConstraint):
                    hc = HandleConstraint(*hc)
            except TypeError:
                raise XmrsError('Invalid HCONS data: {}'.format(repr(hc)))

            hi = hc.hi
            lo = hc.lo
            if hi in _hcons:
                raise XmrsError(
                    'Handle constraint already exists for hole %s.' % hi)
            _hcons[hi] = hc
            # the following should also ensure lo and hi are in _vars
            if 'hcrefs' not in _vars[lo]:
                _vars[lo]['hcrefs'] = []
            for role, refs in _vars[hi]['refs'].items():
                for nodeid in refs:
                    _vars[lo]['hcrefs'].append((nodeid, role, hi))
Exemple #2
0
 def add_eps(self, eps):
     """
     Incorporate the list of EPs given by *eps*.
     """
     # (nodeid, pred, label, args, lnk, surface, base)
     _nodeids, _eps, _vars = self._nodeids, self._eps, self._vars
     for ep in eps:
         try:
             if not isinstance(ep, ElementaryPredication):
                 ep = ElementaryPredication(*ep)
         except TypeError:
             raise XmrsError('Invalid EP data: {}'.format(repr(ep)))
         # eplen = len(ep)
         # if eplen < 3:
         #     raise XmrsError(
         #         'EPs must have length >= 3: (nodeid, pred, label, ...)'
         #     )
         nodeid, lbl = ep.nodeid, ep.label
         if nodeid in _eps:
             raise XmrsError('EP already exists in Xmrs: {} ({})'.format(
                 nodeid, ep[1]))
         _nodeids.append(nodeid)
         _eps[nodeid] = ep
         if lbl is not None:
             _vars[lbl]['refs']['LBL'].append(nodeid)
         for role, val in ep.args.items():
             # if the val is not in _vars, it might still be a
             # variable; check with var_re
             if val in _vars or var_re.match(val):
                 vardict = _vars[val]
                 vardict['refs'][role].append(nodeid)
Exemple #3
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 #4
0
    def validate(self):
        """
        Check that the Xmrs is well-formed.

        The Xmrs is analyzed and a list of problems is compiled. If
        any problems exist, an :exc:`XmrsError` is raised with the list
        joined as the error message. A well-formed Xmrs has the
        following properties:

        * All predications have an intrinsic variable
        * Every intrinsic variable belongs one predication and maybe
          one quantifier
        * Every predication has no more than one quantifier
        * All predications have a label
        * The graph of predications form a net (i.e. are connected).
          Connectivity can be established with variable arguments,
          QEQs, or label-equality.
        * The lo-handle for each QEQ must exist as the label of a
          predication
        """
        errors = []
        ivs, bvs = {}, {}
        _vars = self._vars
        _hcons = self._hcons
        labels = defaultdict(set)
        # ep_args = {}
        for ep in self.eps():
            nid, lbl, args, is_q = (ep.nodeid, ep.label, ep.args,
                                    ep.is_quantifier())
            if lbl is None:
                errors.append('EP ({}) is missing a label.'.format(nid))
            labels[lbl].add(nid)
            iv = args.get(IVARG_ROLE)
            if iv is None:
                errors.append(
                    'EP {nid} is missing an intrinsic variable.'.format(nid))
            if is_q:
                if iv in bvs:
                    errors.append('{} is the bound variable for more than '
                                  'one quantifier.'.format(iv))
                bvs[iv] = nid
            else:
                if iv in ivs:
                    errors.append('{} is the intrinsic variable for more '
                                  'than one EP.'.format(iv))
                ivs[iv] = nid
            # ep_args[nid] = args
        for hc in _hcons.values():
            if hc[2] not in labels:
                errors.append('Lo variable of HCONS ({} {} {}) is not the '
                              'label of any EP.'.format(*hc))
        if not self.is_connected():
            errors.append('Xmrs structure is not connected.')
        if errors:
            raise XmrsError('\n'.join(errors))
Exemple #5
0
 def add_icons(self, icons):
     """
     Incorporate the individual constraints given by *icons*.
     """
     _vars, _icons = self._vars, self._icons
     for ic in icons:
         try:
             if not isinstance(ic, IndividualConstraint):
                 ic = IndividualConstraint(*ic)
         except TypeError:
             raise XmrsError('Invalid ICONS data: {}'.format(repr(ic)))
         left = ic.left
         right = ic.right
         if left not in _icons:
             _icons[left] = []
         _icons[left].append(ic)
         # the following should also ensure left and right are in _vars
         if 'icrefs' not in _vars[right]:
             _vars[right]['icrefs'] = []
         _vars[right]['icrefs'].append(ic)
         _vars[left]  # just to instantiate if not done yet
Exemple #6
0
 def __init__(self, type, data):
     # class methods below use __new__ to instantiate data, so
     # don't do it here
     if type not in (Lnk.CHARSPAN, Lnk.CHARTSPAN, Lnk.TOKENS, Lnk.EDGE):
         raise XmrsError('Invalid Lnk type: {}'.format(type))