def get_lexem(self, synobj): """ :param synobj: :return: """ # "MergeF" is a feature that is deleted upon Merged # used to keep track of whether or not an element has undergone first MErge # can distinguish an X (simple) from an XP (complex) # put elements with uFs right onto the stack features0 = list(LEXICON.get(synobj, LEXICON['root'])) if any((f in COUNTED_FEATURES for f in features0)): self.feature_counter += 1 if any((f in COUNTED_PHI_FEATURES for f in features0)): self.phi_counter += 1 features = [] for feat in features0: if feat in COUNTED_FEATURES: features.append(feat + str(self.feature_counter)) elif feat in COUNTED_PHI_FEATURES: features.append(feat + str(self.phi_counter)) else: features.append(feat) if synobj == 'C_Null': synobj = 'C' elif synobj == 'n_Expl': synobj = 'n' # Leave the actual feature parsing to feature constructor, called by Constituent # as it gets strings as features. return Constituent(label=synobj, features=features)
def dephase_and_transfer(self, merged): """Dephasing a) A verbal root remerges with the local v* (when present) and phasehood is transferred to the verbal root. :param merged: :return: merged """ # Find closest Root def find_closest_root(const): if any(x.name == "Root" for x in const.get_head_features()): return const # (jukka) We are looking for v:s but if we go into branches we hit into n:s. # let's try to not go into branches. another option would be to directly # demand 'v' in label #if const.part1: # found = find_closest_root(const.part1) # if found: # return found if const.part2: return find_closest_root(const.part2) return None current = find_closest_root(merged) if not current: return # Transfer the complement of v assert current.is_labeled() remerge = current transfer = remerge.part2 # Dephasing takes the head of the merged structure new_label = remerge.label + "+" + merged.label if merged.part1.label == merged.label: target = merged.part1.copy() target.label = new_label merged = Constituent(label=new_label, part1=target, part2=merged.part2) else: merged.label = new_label self.out("Dephase v", merged) if transfer: transfer.transfered = True self.out("Transfer", transfer) # Check to see if Remerge results in labeling return merged, transfer
def remerge_postponed(self, merged, remerge): shared_feats = merged.shared_features(remerge) if find(shared_feats, "Q", i=True): label = "Q" elif find(shared_feats, "Top", i=True): label = "Top" else: assert False merged = Constituent(label=label, part1=remerge, part2=merged) return merged
def merge(self, label_giver, part1, part2): """ Merge two objects with predefined label :param label_giver: so or None :param part1: so :param part2: so :return: merged """ if label_giver: label = label_giver.label else: label = '_' merged = Constituent(label=label, part1=part1, part2=part2) return merged
def remerge_if_can(self, merged, dephase=False): def list_builder(node, l): if node not in l: l.append(node) # Again it seems that anything deeper than spine is off-limits #if node.part1: # l = list_builder(node.part1, l) if node.part2: l = list_builder(node.part2, l) return l rstack = list_builder(merged, []) for current in list(rstack): if current.label != merged.label and "Phi" not in current.label: # any item with unlabeled features: for x in find(current.get_head_features(expanded=True), u=True): # if Current is already Merged to element that shares features with # phase head, then Remerge isn't possible # Find complement of Current # See if complement shares features with phase head for inner_current in rstack: if current == inner_current.part1: # shared_feats with complement shared_feats = merged.shared_features( inner_current.part2) elif current == inner_current.part2: # shared_feats with complement shared_feats = merged.shared_features( inner_current.part1) else: continue if shared_feats: remerge = None # input('skipping :' + str(shared_feats)) if not dephase: self.out( "merge", """ Remerge of "%s" blocked by Remerge Condition (shared features) """ % current.label) else: remerge = current merged = Constituent(label="_", part1=remerge, part2=merged) msg = "merge (due to uF) %s + %s" % (remerge.label, merged.label) self.announce_derivation_step(merged, msg) self.out("merge", msg) self.out("Label(Head)", merged) return merged, remerge return merged, None return merged, None
def dephase_deleted_c(self, merged): """ Dephase b) Deletion of C transfers phasehood to T. """ def find_next_head(con, target_l, parent_l): if con.label != target_l and parent_l == target_l: return con if con.part1: found_left = find_next_head(con.part1, target_l, con.label) if found_left: return found_left if con.part2: return find_next_head(con.part2, target_l, con.label) left = merged.part1 right = merged.part2 label = merged.label merged_feats = merged.get_head_features(expanded=True) spec = merged.part1 spec_feats = spec.get_head_features(expanded=True) if spec_feats != merged_feats and not find(spec_feats, "Delete"): input('Delete-delete') merged = Constituent(label=merged.label, part1=spec, part2=merged.part2.part2) # Core Head needs to be deleted else: merged = merged.part2 self.out("Dephase(DeleteC)", merged) target_label = merged.label # Transfer phasehood to T and transfer complement if merged.is_unlabeled() or "Phi" in target_label: target_label = merged.part2.label transfer = find_next_head(left, target_label, label) if not transfer: transfer = find_next_head(right, target_label, label) return transfer, merged
def can_pass_features(self, x, y): # If X has uPhi, then uPhi are passed down the tree until they are checked x_feats = x.get_head_features(expanded=True) # sharing is possible y_feats = y.get_head_features(no_sharing=True, expanded=True) # Which is head? current_label = '' x_head = find( x_feats, "Head") # find returns lists, so this returns [x_head] or [] y_head = find(y_feats, "Head") if x_head and y_head: print("Both are heads:", x_feats, y_feats) print("Figure out label") print("%%%%") sys.exit() elif x_head: current_label = x.label elif y_head: current_label = y.label if current_label: # we used to have "merged" here as parameter, now we have to cook one up for debug self.out("Label(Head)", Constituent(label=current_label, part1=x, part2=y)) complement = None inherit = None # First thing is to collect unvalued phis from either x or y. First try x, # if it has impressive amount of unvalued features, then it is the feature giver. # Then y. If neither has enough, scoot off. unvalued_phis = find(x_feats, u=True, phi=True) unvalued_phis += find(x_feats, "Case", u=False) if len(unvalued_phis) >= 3 or x.label in PHASE_HEADS: inherit = x complement = y if not inherit: unvalued_phis = find(y_feats, u=True, phi=True) unvalued_phis += find(y_feats, "Case", u=False) if len(unvalued_phis) >= 3: inherit = y complement = x return unvalued_phis, inherit, complement
def remerge(self, merged, remerge): merged = Constituent(label=merged.label, part1=remerge, part2=merged) return merged