/**
  * Returns any particle this <code>verb</code> may have
  *
  * @param verb
  * @param graph
  * @return
  */
 static IndexedWord getParticle(final IndexedWord verb, final SemanticGraph graph) {
   GrammaticalRelation reln =
       edu.stanford.nlp.trees.GrammaticalRelation.getRelation(
           edu.stanford.nlp.trees.EnglishGrammaticalRelations.PhrasalVerbParticleGRAnnotation
               .class);
   return graph.getChildWithReln(verb, reln);
 }
 static Boolean hasParticle(IndexedWord word, SemanticGraph graph) {
   GrammaticalRelation reln =
       edu.stanford.nlp.trees.GrammaticalRelation.getRelation(
           edu.stanford.nlp.trees.EnglishGrammaticalRelations.PhrasalVerbParticleGRAnnotation
               .class);
   return graph.hasChildWithReln(word, reln);
 }
 static boolean hasPrepMod(IndexedWord word, SemanticGraph graph) {
   GrammaticalRelation reln =
       edu.stanford.nlp.trees.GrammaticalRelation.getRelation(
           edu.stanford.nlp.trees.EnglishGrammaticalRelations.PrepositionalModifierGRAnnotation
               .class);
   return graph.hasChildWithReln(word, reln);
 }
 /**
  * This method decides whether a given <code>verb</code> has a passive subject or a passive
  * auxiliary.
  *
  * @param verb
  * @param graph
  * @return
  */
 static boolean isPassive(IndexedWord verb, SemanticGraph graph) {
   // Examples:
   // "Dole was defeated by Clinton" nsubjpass(defeated, Dole)
   GrammaticalRelation nsubjpass =
       GrammaticalRelation.getRelation(NominalPassiveSubjectGRAnnotation.class);
   // "That she lied was suspected by everyone" csubjpass(suspected, lied)
   GrammaticalRelation csubjpass =
       GrammaticalRelation.getRelation(ClausalPassiveSubjectGRAnnotation.class);
   // "Kennedy was killed" auxpass(killed, was)
   GrammaticalRelation auxrel =
       GrammaticalRelation.getRelation(EnglishGrammaticalRelations.AuxPassiveGRAnnotation.class);
   Boolean passive = false;
   passive = passive || graph.hasChildWithReln(verb, nsubjpass);
   passive = passive || graph.hasChildWithReln(verb, csubjpass);
   passive = passive || graph.hasChildWithReln(verb, auxrel);
   return passive;
 }
 /**
  * Decides whether this word has a direct object.
  *
  * @param word the word to analyse
  * @param graph the sentence to which this word belongs
  * @return TRUE, if a direct object is present for this verb
  */
 static boolean hasDirectObjectNP(IndexedWord word, SemanticGraph graph) {
   GrammaticalRelation reln =
       edu.stanford.nlp.trees.GrammaticalRelation.getRelation(
           edu.stanford.nlp.trees.EnglishGrammaticalRelations.DirectObjectGRAnnotation.class);
   if (graph.hasChildWithReln(word, reln)) {
     String pos = graph.getChildWithReln(word, reln).get(PartOfSpeechAnnotation.class);
     if (pos.equalsIgnoreCase("NN")) {
       return true;
     }
   }
   return false;
 }
 /**
  * A helper to add a single word to a given dependency tree
  *
  * @param toModify The tree to add the word to.
  * @param root The root of the tree where we should be adding the word.
  * @param rel The relation to add the word with.
  * @param coreLabel The word to add.
  */
 @SuppressWarnings("UnusedDeclaration")
 private static void addWord(
     SemanticGraph toModify, IndexedWord root, String rel, CoreLabel coreLabel) {
   IndexedWord dependent = new IndexedWord(coreLabel);
   toModify.addVertex(dependent);
   toModify.addEdge(
       root,
       dependent,
       GrammaticalRelation.valueOf(Language.English, rel),
       Double.NEGATIVE_INFINITY,
       false);
 }
 /**
  * Finds a direct object. ex: the chair in "move the chair"
  *
  * @param word
  * @param graph
  * @return
  */
 public static IndexedWord getDirectObject(IndexedWord word, SemanticGraph graph) {
   GrammaticalRelation reln =
       edu.stanford.nlp.trees.GrammaticalRelation.getRelation(
           edu.stanford.nlp.trees.EnglishGrammaticalRelations.DirectObjectGRAnnotation.class);
   return graph.getChildWithReln(word, reln);
 }
 /**
  * This method decides whether a given <code>word</code> has an agent. Ex: "The man has been
  * killed by the police"
  *
  * @param word
  * @param graph
  * @return
  */
 static boolean hasAgent(IndexedWord word, SemanticGraph graph) {
   // implement a check for agent(root, nounphrase)
   GrammaticalRelation agentrel = GrammaticalRelation.getRelation(AgentGRAnnotation.class);
   return graph.hasChildWithReln(word, agentrel);
 }
 static {
   for (GrammaticalRelation gr : ChineseGrammaticalRelations.values()) {
     shortNameToGRel.put(gr.getShortName(), gr);
   }
 }
 public static GrammaticalRelation valueOf(String s) {
   return GrammaticalRelation.valueOf(s, values());
 }
  /**
   * A helper to add an entire subtree to a given dependency tree.
   *
   * @param toModify The tree to add the subtree to.
   * @param root The root of the tree where we should be adding the subtree.
   * @param rel The relation to add the subtree with.
   * @param originalTree The orignal tree (i.e., {@link ClauseSplitterSearchProblem#tree}).
   * @param subject The root of the clause to add.
   * @param ignoredEdges The edges to ignore adding when adding this subtree.
   */
  private static void addSubtree(
      SemanticGraph toModify,
      IndexedWord root,
      String rel,
      SemanticGraph originalTree,
      IndexedWord subject,
      Collection<SemanticGraphEdge> ignoredEdges) {
    if (toModify.containsVertex(subject)) {
      return; // This subtree already exists.
    }
    Queue<IndexedWord> fringe = new LinkedList<>();
    Collection<IndexedWord> wordsToAdd = new ArrayList<>();
    Collection<SemanticGraphEdge> edgesToAdd = new ArrayList<>();
    // Search for subtree to add
    for (SemanticGraphEdge edge : originalTree.outgoingEdgeIterable(subject)) {
      if (!ignoredEdges.contains(edge)) {
        if (toModify.containsVertex(edge.getDependent())) {
          // Case: we're adding a subtree that's not disjoint from toModify. This is bad news.
          return;
        }
        edgesToAdd.add(edge);
        fringe.add(edge.getDependent());
      }
    }
    while (!fringe.isEmpty()) {
      IndexedWord node = fringe.poll();
      wordsToAdd.add(node);
      for (SemanticGraphEdge edge : originalTree.outgoingEdgeIterable(node)) {
        if (!ignoredEdges.contains(edge)) {
          if (toModify.containsVertex(edge.getDependent())) {
            // Case: we're adding a subtree that's not disjoint from toModify. This is bad news.
            return;
          }
          edgesToAdd.add(edge);
          fringe.add(edge.getDependent());
        }
      }
    }
    // Add subtree
    // (add subject)
    toModify.addVertex(subject);
    toModify.addEdge(
        root,
        subject,
        GrammaticalRelation.valueOf(Language.English, rel),
        Double.NEGATIVE_INFINITY,
        false);

    // (add nodes)
    wordsToAdd.forEach(toModify::addVertex);
    // (add edges)
    for (SemanticGraphEdge edge : edgesToAdd) {
      assert !toModify.incomingEdgeIterator(edge.getDependent()).hasNext();
      toModify.addEdge(
          edge.getGovernor(),
          edge.getDependent(),
          edge.getRelation(),
          edge.getWeight(),
          edge.isExtra());
    }
  }