package edu.stanford.nlp.trees;
import java.io.Serializable;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.ling.IndexedWord;
/**
* A <code>TypedDependency</code> is a relation between two words in a
* <code>GrammaticalStructure</code>. Each <code>TypedDependency</code>
* consists of a governor word, a dependent word, and a relation, which is
* normally an instance of {@link GrammaticalRelation
* <code>GrammaticalRelation</code>}.
*
* @author Bill MacCartney
*/
public class TypedDependency implements Comparable<TypedDependency>, Serializable {
private static final long serialVersionUID = -7690294213151279779L;
// TODO FIXME: these should all be final. That they are mutable is
// awful design. Awful. It means that underlying data structures
// can be mutated in ways you don't intend. For example, there was
// a time when you could call typedDependenciesCollapsed() and it
// would change the GrammaticalStructure because of the way that
// object mutated its TypedDependency objects.
private GrammaticalRelation reln;
private IndexedWord gov;
private IndexedWord dep;
private boolean extra; // = false; // to code whether the dependency preserves the tree structure or not
// cdm: todo: remove this field and use typing on reln? Expand implementation of SEMANTIC_DEPENDENT
public TypedDependency(GrammaticalRelation reln, IndexedWord gov, IndexedWord dep) {
this.reln = reln;
this.gov = gov;
this.dep = dep;
}
public TypedDependency(TypedDependency other) {
this.reln = other.reln;
this.gov = other.gov;
this.dep = other.dep;
this.extra = other.extra;
}
public GrammaticalRelation reln() {
return reln;
}
public void setGov(IndexedWord gov) {
this.gov = gov;
}
public void setDep(IndexedWord dep) {
this.dep = dep;
}
public IndexedWord gov() {
return gov;
}
public IndexedWord dep() {
return dep;
}
public boolean extra() {
return extra;
}
public void setReln(GrammaticalRelation reln) {
this.reln = reln;
}
public void setExtra() {
this.extra = true;
}
@SuppressWarnings({"RedundantIfStatement"})
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof TypedDependency)) {
return false;
}
final TypedDependency typedDep = (TypedDependency) o;
if (reln != null ? !reln.equals(typedDep.reln) : typedDep.reln != null) {
return false;
}
if (gov != null ? !gov.equals(typedDep.gov) : typedDep.gov != null) {
return false;
}
if (dep != null ? !dep.equals(typedDep.dep) : typedDep.dep != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = (reln != null ? reln.hashCode() : 17);
result = 29 * result + (gov != null ? gov.hashCode() : 0);
result = 29 * result + (dep != null ? dep.hashCode() : 0);
return result;
}
@Override
public String toString() {
return toString(CoreLabel.OutputFormat.VALUE_INDEX);
}
public String toString(CoreLabel.OutputFormat format) {
return reln + "(" + gov.toString(format) + ", " + dep.toString(format) + ")";
}
public int compareTo(TypedDependency tdArg) {
IndexedWord depArg = tdArg.dep();
IndexedWord depThis = this.dep();
int indexArg = depArg.index();
int indexThis = depThis.index();
if (indexThis > indexArg) {
return 1;
} else if (indexThis < indexArg) {
return -1;
}
// dependent indices are equal, check governor
int govIndexArg = tdArg.gov().index();
int govIndexThis = this.gov().index();
if (govIndexThis > govIndexArg) {
return 1;
} else if (govIndexThis < govIndexArg) {
return -1;
}
// dependent and governor indices equal, the relation decides
return this.reln().compareTo(tdArg.reln());
}
}