package edu.stanford.nlp.naturalli; /** * A silly little class to denote a quantifier scope. * * @author Gabor Angeli */ public class OperatorSpec { public final Operator instance; public final int quantifierBegin; public final int quantifierEnd; public final int quantifierHead; public final int subjectBegin; public final int subjectEnd; public final int objectBegin; public final int objectEnd; public OperatorSpec( Operator instance, int quantifierBegin, int quantifierEnd, int subjectBegin, int subjectEnd, int objectBegin, int objectEnd) { this.instance = instance; this.quantifierBegin = quantifierBegin; this.quantifierEnd = quantifierEnd; this.quantifierHead = quantifierEnd - 1; this.subjectBegin = subjectBegin; this.subjectEnd = subjectEnd; this.objectBegin = objectBegin; this.objectEnd = objectEnd; } protected OperatorSpec( Operator instance, int quantifierBegin, int quantifierEnd, int subjectBegin, int subjectEnd, int objectBegin, int objectEnd, int sentenceLength) { this(instance, Math.max(0, Math.min(sentenceLength - 1, quantifierBegin)), Math.max(0, Math.min(sentenceLength, quantifierEnd)), Math.max(0, Math.min(sentenceLength - 1, subjectBegin)), Math.max(0, Math.min(sentenceLength, subjectEnd)), Math.max(0, objectBegin == sentenceLength ? sentenceLength : Math.min(sentenceLength - 1, objectBegin)), Math.max(0, Math.min(sentenceLength, objectEnd))); } /** * If true, this is an explicit quantifier, such as "all" or "some." * The other option is for this to be an implicit quantification, for instance with proper names: * * <code> * "Felix is a cat" -> \forall x, Felix(x) \rightarrow cat(x). * </code> */ public boolean isExplicit() { return instance != Operator.IMPLICIT_NAMED_ENTITY; } public boolean isBinary() { return objectEnd > objectBegin; } public int quantifierLength() { return quantifierEnd - quantifierBegin; } /** {@inheritDoc} */ @Override public String toString() { return "QuantifierScope{" + "subjectBegin=" + subjectBegin + ", subjectEnd=" + subjectEnd + ", objectBegin=" + objectBegin + ", objectEnd=" + objectEnd + '}'; } public static OperatorSpec merge(OperatorSpec x, OperatorSpec y) { assert (x.quantifierBegin == y.quantifierBegin); assert (x.quantifierEnd == y.quantifierEnd); assert (x.instance == y.instance); return new OperatorSpec( x.instance, Math.min(x.quantifierBegin, y.quantifierBegin), Math.min(x.quantifierEnd, y.quantifierEnd), Math.min(x.subjectBegin, y.subjectBegin), Math.max(x.subjectEnd, y.subjectEnd), Math.min(x.objectBegin, y.objectBegin), Math.max(x.objectEnd, y.objectEnd)); } @SuppressWarnings("RedundantIfStatement") @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof OperatorSpec)) return false; OperatorSpec that = (OperatorSpec) o; if (objectBegin != that.objectBegin) return false; if (objectEnd != that.objectEnd) return false; if (quantifierBegin != that.quantifierBegin) return false; if (quantifierEnd != that.quantifierEnd) return false; if (quantifierHead != that.quantifierHead) return false; if (subjectBegin != that.subjectBegin) return false; if (subjectEnd != that.subjectEnd) return false; if (instance != that.instance) return false; return true; } @Override public int hashCode() { int result = instance != null ? instance.hashCode() : 0; result = 31 * result + quantifierBegin; result = 31 * result + quantifierEnd; result = 31 * result + quantifierHead; result = 31 * result + subjectBegin; result = 31 * result + subjectEnd; result = 31 * result + objectBegin; result = 31 * result + objectEnd; return result; } }