package edu.stanford.nlp.naturalli; import edu.stanford.nlp.util.Trilean; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; /** * The catalog of the seven Natural Logic relations. * Set-theoretically, if we assume A and B are two sets (e.g., denotations), * and D is the universe of discourse, * then the relations between A and B are defined as follows: * * <ul> * <li>Equivalence: A = B</li> * <li>Forward entailment: A \\subset B</li> * <li>Reverse entailment: A \\supset B</li> * <li>Negation: A \\intersect B = \\empty \\land A \\union B = D </li> * <li>Alternation: A \\intersect B = \\empty </li> * <li>Cover: A \\union B = D </li> * </ul> * * @author Gabor Angeli */ @SuppressWarnings("UnusedDeclaration") public enum NaturalLogicRelation { EQUIVALENT (0, true, false, true, false), FORWARD_ENTAILMENT (1, true, false, false, false), REVERSE_ENTAILMENT (2, false, false, true, false), NEGATION (3, false, true, false, true), ALTERNATION (4, false, true, false, false), COVER (5, false, false, false, true), INDEPENDENCE (6, false, false, false, false), ; /** * A fixed index for this relation, so that it can be serialized more efficiently. * DO NOT CHANGE THIS INDEX or you will break existing serialization, and probably a bunch of other stuff too. * Otherwise, the index is arbitrary. */ public final int fixedIndex; /** * Determines whether this relation maintains the truth of a fact in a true context. * So, if the premise is true, and this relation is applied, the conclusion remains true. */ public final boolean maintainsTruth; /** * Determines whether this relation negates the truth of a fact in a true context. * So, if the premise is true, and this relation is applied, the conclusion becomes false. */ public final boolean negatesTruth; /** * Determines whether this relation maintains the falsehood of a false fact. * So, if the premise is false, and this relation is applied, the conclusion remains false. */ public final boolean maintainsFalsehood; /** * Determines whether this relation negates the truth of a fact in a false context. * So, if the premise is false, and this relation is applied, the conclusion becomes true. */ public final boolean negatesFalsehood; NaturalLogicRelation(int fixedIndex, boolean maintainsTruth, boolean negatesTruth, boolean maintainsFalsehood, boolean negatesFalsehood) { this.fixedIndex = fixedIndex; this.maintainsTruth = maintainsTruth; this.negatesTruth = negatesTruth; this.maintainsFalsehood = maintainsFalsehood; this.negatesFalsehood = negatesFalsehood; } protected static NaturalLogicRelation byFixedIndex(int index) { switch (index) { case 0: return EQUIVALENT; case 1: return FORWARD_ENTAILMENT; case 2: return REVERSE_ENTAILMENT; case 3: return NEGATION; case 4: return ALTERNATION; case 5: return COVER; case 6: return INDEPENDENCE; default: throw new IllegalArgumentException("Unknown index for Natural Logic relation: " + index); } } /** * The MacCartney "join table" -- this determines the transitivity of entailment if we chain two relations together. * These should already be projected up through the sentence, so that the relations being joined are relations between * <i>sentences</i> rather than relations between <i>lexical items</i> (see {@link Polarity#projectLexicalRelation(NaturalLogicRelation)}, * set by {@link edu.stanford.nlp.naturalli.NaturalLogicAnnotator} using the {@link edu.stanford.nlp.naturalli.NaturalLogicAnnotations.PolarityAnnotation}). * @param other The relation to join this relation with. * @return The new joined relation. */ public NaturalLogicRelation join(NaturalLogicRelation other) { switch (this) { case EQUIVALENT: return other; case FORWARD_ENTAILMENT: switch (other) { case EQUIVALENT: case FORWARD_ENTAILMENT: return FORWARD_ENTAILMENT; case NEGATION: case ALTERNATION: return COVER; case REVERSE_ENTAILMENT: case COVER: case INDEPENDENCE: return INDEPENDENCE; } case REVERSE_ENTAILMENT: switch (other) { case EQUIVALENT: case REVERSE_ENTAILMENT: return REVERSE_ENTAILMENT; case NEGATION: case COVER: return COVER; case FORWARD_ENTAILMENT: case ALTERNATION: case INDEPENDENCE: return INDEPENDENCE; } case NEGATION: switch (other) { case EQUIVALENT: return NEGATION; case FORWARD_ENTAILMENT: return COVER; case REVERSE_ENTAILMENT: return ALTERNATION; case NEGATION: return EQUIVALENT; case ALTERNATION: return REVERSE_ENTAILMENT; case COVER: return FORWARD_ENTAILMENT; case INDEPENDENCE: return INDEPENDENCE; } case ALTERNATION: switch (other) { case EQUIVALENT: case REVERSE_ENTAILMENT: return ALTERNATION; case NEGATION: case COVER: return FORWARD_ENTAILMENT; case FORWARD_ENTAILMENT: case ALTERNATION: case INDEPENDENCE: return INDEPENDENCE; } case COVER: switch (other) { case EQUIVALENT: case FORWARD_ENTAILMENT: return COVER; case NEGATION: case ALTERNATION: return REVERSE_ENTAILMENT; case REVERSE_ENTAILMENT: case COVER: case INDEPENDENCE: return INDEPENDENCE; } case INDEPENDENCE: return INDEPENDENCE; } throw new IllegalStateException("[should be impossible]: Incomplete join table for " + this + " joined with " + other); } /** * Implements the finite state automata of composing the truth value of a sentence with a natural logic relation being * applied. * @param initialTruthValue The truth value of the premise (the original sentence). * @return The truth value of the consequent -- that is, the sentence once it's been modified with this relation. * A value of {@link Trilean#UNKNOWN} indicates that natural logic cannot either confirm or disprove the truth * of the consequent. */ public Trilean applyToTruthValue(boolean initialTruthValue) { if (initialTruthValue) { if (maintainsTruth) { return Trilean.TRUE; } else if (negatesTruth) { return Trilean.FALSE; } else { return Trilean.UNKNOWN; } } else { if (maintainsFalsehood) { return Trilean.FALSE; } else if (negatesFalsehood) { return Trilean.TRUE; } else { return Trilean.UNKNOWN; } } } private static final Map<String, NaturalLogicRelation> insertArcToNaturalLogicRelation = Collections.unmodifiableMap(new HashMap<String, NaturalLogicRelation>() {{ put("acomp", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("advcl", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("acl", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("advmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("agent", NaturalLogicRelation.INDEPENDENCE); // put("amod", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("appos", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("aux", NaturalLogicRelation.INDEPENDENCE); // he left -/-> he should leave put("auxpass", NaturalLogicRelation.INDEPENDENCE); // some cat adopts -/-> some cat got adopted put("ccomp", NaturalLogicRelation.REVERSE_ENTAILMENT); // interesting project here... "he said x" -> "x"? put("cc", NaturalLogicRelation.REVERSE_ENTAILMENT); // match dep_conj put("compound", NaturalLogicRelation.INDEPENDENCE); // put("name", NaturalLogicRelation.INDEPENDENCE); // put("mwe", NaturalLogicRelation.INDEPENDENCE); // put("conj:and\\/or", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("conj:and", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("conj:both", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("conj:but", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("conj:nor", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("conj:or", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("conj:plus", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("conj", NaturalLogicRelation.REVERSE_ENTAILMENT); // match dep_cc put("conj_x", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("cop", NaturalLogicRelation.INDEPENDENCE); // put("csubj", NaturalLogicRelation.INDEPENDENCE); // don't drop subjects. put("csubjpass", NaturalLogicRelation.INDEPENDENCE); // as above put("dep", NaturalLogicRelation.REVERSE_ENTAILMENT); // allow cutting these off, else we just miss a bunch of sentences put("det", NaturalLogicRelation.FORWARD_ENTAILMENT); // todo(gabor) better treatment of generics? put("discourse", NaturalLogicRelation.EQUIVALENT); // put("dobj", NaturalLogicRelation.REVERSE_ENTAILMENT); // but, "he studied NLP at Stanford" -> "he studied NLP" put("expl", NaturalLogicRelation.EQUIVALENT); // though we shouldn't see this... put("goeswith", NaturalLogicRelation.EQUIVALENT); // also shouldn't see this put("infmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // deprecated into vmod put("iobj", NaturalLogicRelation.REVERSE_ENTAILMENT); // she gave me a raise -> she gave a raise put("mark", NaturalLogicRelation.REVERSE_ENTAILMENT); // he says that you like to swim -> he says you like to swim put("mwe", NaturalLogicRelation.INDEPENDENCE); // shouldn't see this put("neg", NaturalLogicRelation.NEGATION); // put("nn", NaturalLogicRelation.INDEPENDENCE); // put("npadvmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // "9 months after his election, <main clause>" put("nsubj", NaturalLogicRelation.REVERSE_ENTAILMENT); // Note[gabor]: Only true for _duplicate_ nsubj relations. @see NaturalLogicWeights. put("nsubjpass", NaturalLogicRelation.INDEPENDENCE); // put("number", NaturalLogicRelation.INDEPENDENCE); // put("num", NaturalLogicRelation.INDEPENDENCE); // gets a bit too vague if we allow deleting this? "he served three terms" -?-> "he served terms" put("op", NaturalLogicRelation.INDEPENDENCE); // put("parataxis", NaturalLogicRelation.INDEPENDENCE); // or, reverse? put("partmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // deprecated into vmod put("pcomp", NaturalLogicRelation.INDEPENDENCE); // though, not so in collapsed dependencies put("pobj", NaturalLogicRelation.INDEPENDENCE); // must delete whole preposition put("possessive", NaturalLogicRelation.INDEPENDENCE); // see dep_poss put("poss", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("nmod:poss", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("preconj", NaturalLogicRelation.INDEPENDENCE); // forbidden to see this put("predet", NaturalLogicRelation.INDEPENDENCE); // forbidden to see this put("case", NaturalLogicRelation.INDEPENDENCE); // put("nmod:aboard", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:about", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:above", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:according_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:across_from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:across", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:after", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:against", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:ahead_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:along", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:alongside_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:alongside", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:along_with", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:amid", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:among", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:anti", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:apart_from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:around", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as_for", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as_from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:aside_from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as_per", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:as_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:at", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:away_from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:based_on", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:because_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:before", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:behind", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:below", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:beneath", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:beside", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:besides", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:between", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:beyond", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:but", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:by_means_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:by", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:depending_on", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:dep", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:despite", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:down", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:due_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:during", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:en", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:except_for", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:excepting", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:except", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:excluding", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:exclusive_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:followed_by", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:following", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:for", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:from", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:if", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_accordance_with", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_addition_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_case_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:including", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_front_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_lieu_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_place_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:inside_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:inside", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:in_spite_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:instead_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:into", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:irrespective_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:like", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:minus", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:near", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:near_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:next_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:off_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:off", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:on_account_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:on_behalf_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:on", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:on_top_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:onto", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:opposite", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:out_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:out", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:outside_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:outside", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:over", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:owing_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:past", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:per", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:plus", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:preliminary_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:preparatory_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:previous_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:prior_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:pursuant_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:regarding", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:regardless_of", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:round", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:save", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:since", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:subsequent_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:such_as", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:thanks_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:than", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:throughout", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:through", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:together_with", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:toward", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:towards", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:underneath", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:under", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:unlike", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:until", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:upon", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:up", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:versus", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:via", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:vs.", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:whether", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:within", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:without", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:with_regard_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:with_respect_to", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("nmod:with", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("prt", NaturalLogicRelation.INDEPENDENCE); // put("punct", NaturalLogicRelation.EQUIVALENT); // put("purpcl", NaturalLogicRelation.REVERSE_ENTAILMENT); // deprecated into advmod put("quantmod", NaturalLogicRelation.FORWARD_ENTAILMENT); // put("rcmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // "there are great tenors --rcmod--> who are modest" put("root", NaturalLogicRelation.INDEPENDENCE); // err.. never delete put("tmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("vmod", NaturalLogicRelation.REVERSE_ENTAILMENT); // put("xcomp", NaturalLogicRelation.REVERSE_ENTAILMENT); // }}); /** * Returns whether this is a known dependency arc. */ public static boolean knownDependencyArc(String dependencyLabel) { return insertArcToNaturalLogicRelation.containsKey(dependencyLabel.toLowerCase()); } /** * Returns the natural logic relation corresponding to the given dependency arc being inserted into a sentence. */ public static NaturalLogicRelation forDependencyInsertion(String dependencyLabel) { return forDependencyInsertion(dependencyLabel, true); } /** * Returns the natural logic relation corresponding to the given dependency arc being inserted into a sentence. * @param dependencyLabel The label we are checking the relation for. * @param isSubject Whether this is on the subject side of a relation (e.g., for CONJ_OR edges) */ public static NaturalLogicRelation forDependencyInsertion(String dependencyLabel, boolean isSubject) { return forDependencyInsertion(dependencyLabel, isSubject, Optional.empty()); } /** * Returns the natural logic relation corresponding to the given dependency arc being inserted into a sentence. * @param dependencyLabel The label we are checking the relation for. * @param isSubject Whether this is on the subject side of a relation (e.g., for CONJ_OR edges) * @param dependent The dependent word of the dependency label. */ public static NaturalLogicRelation forDependencyInsertion(String dependencyLabel, boolean isSubject, Optional<String> dependent) { if (!isSubject) { switch (dependencyLabel) { // 'or' in the object position behaves as and. case "conj:or": case "conj:nor": return forDependencyInsertion("conj:and", false); case "cc:preconj": if (dependent.isPresent() && "neither".equalsIgnoreCase(dependent.get())) { return INDEPENDENCE; } else { return REVERSE_ENTAILMENT; } } } NaturalLogicRelation rel = insertArcToNaturalLogicRelation.get(dependencyLabel.toLowerCase()); if (rel != null) { return rel; } else { // log.info("Unknown dependency arc for NaturalLogicRelation: " + dependencyLabel); if (dependencyLabel.startsWith("nmod:")) { return NaturalLogicRelation.REVERSE_ENTAILMENT; } else if (dependencyLabel.startsWith("conj")) { return NaturalLogicRelation.REVERSE_ENTAILMENT; } else if (dependencyLabel.startsWith("advcl")) { return NaturalLogicRelation.REVERSE_ENTAILMENT; } else { return NaturalLogicRelation.INDEPENDENCE; } } } private static NaturalLogicRelation insertionToDeletion(NaturalLogicRelation insertionRel) { switch (insertionRel) { case EQUIVALENT: return EQUIVALENT; case FORWARD_ENTAILMENT: return REVERSE_ENTAILMENT; case REVERSE_ENTAILMENT: return FORWARD_ENTAILMENT; case NEGATION: return NEGATION; case ALTERNATION: return COVER; case COVER: return ALTERNATION; case INDEPENDENCE: return INDEPENDENCE; default: throw new IllegalStateException("Unhandled natural logic relation: " + insertionRel); } } /** * Returns the natural logic relation corresponding to the given dependency arc being deleted from a sentence. */ public static NaturalLogicRelation forDependencyDeletion(String dependencyLabel) { return forDependencyDeletion(dependencyLabel, true); } /** * Returns the natural logic relation corresponding to the given dependency arc being deleted from a sentence. * @param dependencyLabel The label we are checking the relation for * @param isSubject Whether this is on the subject side of a relation (e.g., for CONJ_OR edges) */ public static NaturalLogicRelation forDependencyDeletion(String dependencyLabel, boolean isSubject) { NaturalLogicRelation rel = forDependencyInsertion(dependencyLabel, isSubject); return insertionToDeletion(rel); } /** * Returns the natural logic relation corresponding to the given dependency arc being deleted from a sentence. * @param dependencyLabel The label we are checking the relation for * @param isSubject Whether this is on the subject side of a relation (e.g., for CONJ_OR edges) * @param dependent The dependent word of the dependency label. */ public static NaturalLogicRelation forDependencyDeletion(String dependencyLabel, boolean isSubject, Optional<String> dependent) { NaturalLogicRelation rel = forDependencyInsertion(dependencyLabel, isSubject, dependent); return insertionToDeletion(rel); } }