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'
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' ]
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
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)}
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)
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
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
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)
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
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
def _var(v): d = {'type': variable.type(v)} if properties and mrs.variables.get(v): d['properties'] = dict(mrs.variables[v]) return d
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