/** * Copyright 2014, Emory University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.emory.clir.clearnlp.dependency; import java.util.List; import java.util.Set; import edu.emory.clir.clearnlp.constituent.CTLibEn; import edu.emory.clir.clearnlp.lexicon.propbank.PBLib; import edu.emory.clir.clearnlp.pos.POSLibEn; import edu.emory.clir.clearnlp.pos.POSTagEn; import edu.emory.clir.clearnlp.util.DSUtils; import edu.emory.clir.clearnlp.util.arc.SRLArc; import edu.emory.clir.clearnlp.util.lang.ENUtils; /** * @since 3.0.0 * @author Jinho D. Choi ({@code jinho.choi@emory.edu}) */ public class DEPLibEn implements DEPTagEn { private DEPLibEn() {} static public boolean isNoun(DEPNode node) { return POSLibEn.isNoun(node.getPOSTag()); } static public boolean isVerb(DEPNode node) { return POSLibEn.isVerb(node.getPOSTag()); } /** Enriches certain dependency labels into finer-grained labels. */ static public void enrichLabels(DEPTree tree) { Set<String> subj = DSUtils.toHashSet(DEP_CSUBJ, DEP_NSUBJ); List<DEPNode> list; for (DEPNode node : tree) { if (node.isLabel(DEP_ADVMOD) && ENUtils.isNegation(node.getWordForm())) node.setLabel(DEP_NEG); if (node.containsDependent(DEPLibEn.DEP_AUXPASS)) { for (DEPNode child : node.getDependentListByLabel(subj)) child.setLabel(child.getLabel()+DEPLibEn.DEP_PASS); } if ((list = node.getDependentListByLabel(DEPLibEn.DEP_DOBJ)).size() > 1) list.get(0).setLabel(DEPLibEn.DEP_IOBJ); } } static public void postLabel(DEPTree tree) { List<List<SRLArc>> argLists; int i, size = tree.size(); List<SRLArc> list; DEPNode node = tree.get(0); if (node.getSemanticHeadArcList() == null) return; argLists = tree.getArgumentList(); for (i=1; i<size; i++) { node = tree.get(i); list = argLists.get(i); if (node.isLabel(DEP_PREP)) { relinkPreposition(node); } else if (POSLibEn.isVerb(node.getPOSTag())) { labelReferentOfRelativeClause(node, list); } } } /** * Re-links PP to a verb predicate. * Called by {@link #postLabel(DEPTree)}. * @param prep the dependency label of this node is {@link DEPTagEn#DEP_PREP}. */ static private void relinkPreposition(DEPNode prep) { DEPNode head = prep.getHead(); if (head.isLabel(DEPLibEn.DEP_POBJ)) head = head.getHead(); if (isNoun(head) || head.isPOSTag(POSTagEn.POS_IN) || head.isPOSTag(POSTagEn.POS_RP)) { DEPNode gHead = head.getHead(); // verb predicate SRLArc sp; if (gHead != null && (sp = prep.getSemanticHeadArc(gHead)) != null) { if (head.getSemanticHeadArc(gHead) == null) { prep.removeSemanticHead(sp); head.addSemanticHead(gHead, sp.getLabel()); } } } } /** * Called by {@link #postLabel(DEPTree)}. * Add the argument label to the head of a referent. * @param verb the POS tag of this node is a verb. */ static private void labelReferentOfRelativeClause(DEPNode verb, List<SRLArc> argList) { DEPNode top = getHeightVerbInChain(verb); DEPNode head = top.getHead(); if (top.isLabel(DEP_RELCL) && !head.isArgumentOf(verb)) { for (SRLArc arc : argList) { if (PBLib.isReferentArgument(arc.getLabel()) && isReferentArgument(arc.getNode())) { head.addSemanticHead(verb, PBLib.getBaseLabel(arc.getLabel())); return; } } } } /** Called by {@link #labelReferentOfRelativeClause(DEPNode, List)}. */ static private boolean isReferentArgument(DEPNode node) { return node.getFirstDependentByLabel(DEP_POBJ) != null || node.isLemma("that") || node.isLemma("which"); } /** * @return get the highest verb in the chain. * @param verb the POS tag of this node is a verb. */ static public DEPNode getHeightVerbInChain(DEPNode verb) { while (isVerb(verb.getHead()) && (verb.isLabel(DEP_CONJ) || verb.isLabel(DEP_XCOMP))) verb = verb.getHead(); return verb; } /** * @param node the POS tag of this node is a noun. * @return the trimmed sequence of lemmas for the specific node. */ static public String getSubLemmasForNP(DEPNode node, String delim) { StringBuilder build = new StringBuilder(); boolean add = true; for (DEPNode dep : node.getDependentList()) { // insert the node's lemma at the right position. if (add && dep.getID() > node.getID()) { build.append(delim); build.append(node.getLemma()); add = false; } if (dep.isLabel(DEP_COMPOUND) || dep.isPOSTag(CTLibEn.POS_PRPS)) { build.append(delim); build.append(dep.getLemma()); } } if (add) { build.append(delim); build.append(node.getLemma()); } return build.substring(delim.length()); } /** * @param node the POS tag of this node is a preposition. * @return the trimmed sequence of lemmas for the specific node. */ static public String getSubLemmasForPP(DEPNode node, String delim) { StringBuilder build = new StringBuilder(); build.append(node.getLemma()); DEPNode pobj = node.getFirstDependentByLabel(DEP_POBJ); if (pobj != null) { build.append(delim); if (POSLibEn.isNoun(pobj.getPOSTag())) build.append(getSubLemmasForNP(pobj, delim)); else build.append(pobj.getLemma()); } return build.toString(); } }