All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.nlp.semgraph.semgrex.GraphRelation Maven / Gradle / Ivy

Go to download

Stanford Parser processes raw text in English, Chinese, German, Arabic, and French, and extracts constituency parse trees.

The newest version!
package edu.stanford.nlp.semgraph.semgrex; 
import edu.stanford.nlp.util.logging.Redwood;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.trees.GrammaticalRelation;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.SemanticGraphEdge;
import edu.stanford.nlp.util.*;
import java.util.function.Predicate;

/**
 * An abstract base class for relations between graph nodes in semgrex. There
 * are two types of subclasses: static anonymous singleton instantiations for
 * relations that do not require arguments, and private subclasses for those
 * with arguments. All invocations should be made through the static factory
 * methods.
 * 

* If you want to add a new relation, you just have to fill in the definition of * satisfies() and searchNodeIterator(). Also be * careful to make the appropriate adjustments to * getRelation(). Finally, if you are using the SemgrexParser, you * need to add the new relation symbol to the list of tokens.

* * @author Chloe Kiddon */ abstract class GraphRelation implements Serializable { final String symbol; final Predicate type; final String rawType; final String name; //"<" | ">" | ">>" | "<<" | "<#" | ">#" | ":" | "@"> /** * Returns true iff this GraphRelation holds between * the given pair of nodes in the given semantic graph. */ abstract boolean satisfies(IndexedWord n1, IndexedWord n2, SemanticGraph sg); /** * For a given node and its root, returns an {@link Iterator} over the nodes * of the semantic graph that satisfy the relation. */ abstract Iterator searchNodeIterator(IndexedWord node, SemanticGraph sg); private GraphRelation(String symbol, String type, String name) { this.symbol = symbol; this.type = getPattern(type); this.rawType = type; this.name = name; } private GraphRelation(String symbol, String type) { this(symbol, type, null); } private GraphRelation(String symbol) { this(symbol, null); } @Override public String toString() { return symbol + ((rawType != null) ? rawType : "") + ((name != null) ? "=" + name : ""); } public Predicate getPattern(String relnType) { if ((relnType == null) || (relnType.equals(""))) { return Filters.acceptFilter(); } else if (relnType.matches("/.*/")) { return new RegexStringFilter(relnType.substring(1, relnType.length() - 1)); } else { // raw description return new ArrayStringFilter(ArrayStringFilter.Mode.EXACT, relnType); } } public String getName() { if (name == null || name == "") return null; return name; } // ALIGNMENT graph relation: "@" ============================================== static class ALIGNMENT extends GraphRelation { private Alignment alignment; private boolean hypToText; ALIGNMENT() { super("@", ""); hypToText = true; } void setAlignment(Alignment alignment, boolean hypToText, SearchNodeIterator itr) { this.alignment = alignment; this.hypToText = hypToText; //log.info("setting alignment"); itr.advance(); } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (alignment == null) return false; if (hypToText) return (alignment.getMap().get(l1)).equals(l2); else { return (alignment.getMap().get(l2)).equals(l1); } } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { boolean foundOnce = false; int nextNum; // not really initialized until alignment is set @Override public void initialize() { } @Override public void advance() { if (alignment == null) return; if (node.equals(IndexedWord.NO_WORD)) next = null; //log.info("node: " + node.word()); if (hypToText) { if (!foundOnce) { next = alignment.getMap().get(node); foundOnce = true; // if (next == null) log.info("no alignment"); else // log.info("other graph: " + next.word()); } else { next = null; //log.info("next: null"); } } else { int num = 0; for (Map.Entry pair : alignment.getMap().entrySet()) { if (pair.getValue().equals(node)) { if (nextNum == num) { next = pair.getKey(); nextNum++; //log.info("next: " + next.word()); return; } num++; } } //log.info("backwards, next: null"); next = null; } } }; } // Generated automatically by Eclipse private static final long serialVersionUID = -2936526066368043778L; }; // ROOT graph relation: "Root" ================================================ static final GraphRelation ROOT = new GraphRelation("", "") { @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { return l1 == l2; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { @Override void initialize() { next = node; } }; } // automatically generated by Eclipse private static final long serialVersionUID = 4710135995247390313L; }; static final GraphRelation ITERATOR = new GraphRelation(":", "") { @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { return true; } Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return sg.vertexSet().iterator(); } // automatically generated by Eclipse private static final long serialVersionUID = 5259713498453659251L; }; // ALIGNED_ROOT graph relation: "AlignRoot" =================================== static final GraphRelation ALIGNED_ROOT = new GraphRelation("AlignRoot", "") { @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { return l1 == l2; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { @Override void initialize() { next = node; } }; } // automatically generated by Eclipse private static final long serialVersionUID = -3088857488269777611L; }; // GOVERNOR graph relation: ">" =============================================== static private class GOVERNER extends GraphRelation { GOVERNER(String reln, String name) { super(">", reln, name); } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { List> deps = sg.childPairs(l1); for (Pair dep : deps) { if (this.type.test(dep.first().toString()) && dep.second().equals(l2)) { return true; } } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { Iterator iterator; @Override public void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } if (iterator == null) { iterator = sg.outgoingEdgeIterator(node); } while (iterator.hasNext()) { SemanticGraphEdge edge = iterator.next(); relation = edge.getRelation().toString(); if (!type.test(relation)) { continue; } this.next = edge.getTarget(); return; } this.next = null; } }; } // automatically generated by Eclipse private static final long serialVersionUID = -7003148918274183951L; }; // DEPENDENT graph relation: "<" =============================================== static private class DEPENDENT extends GraphRelation { DEPENDENT(String reln, String name) { super("<", reln, name); } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (l1.equals(IndexedWord.NO_WORD) || l2.equals(IndexedWord.NO_WORD) ) return false; List> govs = sg.parentPairs(l1); for (Pair gov : govs) { if (this.type.test(gov.first().toString()) && gov.second().equals(l2)) return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { int nextNum; // subtle bug warning here: if we use int nextNum=0; // instead, // we get the first daughter twice because the assignment occurs after // advance() has already been // called once by the constructor of SearchNodeIterator. @Override public void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } List> govs = sg.parentPairs(node); while (nextNum < govs.size() && !type.test(govs.get(nextNum).first().toString())) { nextNum++; } if (nextNum < govs.size()) { next = govs.get(nextNum).second(); relation = govs.get(nextNum).first().toString(); nextNum++; } else { next = null; } } }; } // automatically generated by Eclipse private static final long serialVersionUID = -5115389883698108694L; }; static private class LIMITED_GRANDPARENT extends GraphRelation { final int startDepth, endDepth; LIMITED_GRANDPARENT(String reln, String name, int startDepth, int endDepth) { super(startDepth + "," + endDepth + ">>", reln, name); this.startDepth = startDepth; this.endDepth = endDepth; } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (l1.equals(IndexedWord.NO_WORD) || l2.equals(IndexedWord.NO_WORD) ) return false; List> usedNodes = new ArrayList<>(); for (int i = 0; i <= endDepth; ++i) { usedNodes.add(Generics.newIdentityHashSet()); } return l1 != l2 && satisfyHelper(l1, l2, sg, 0, usedNodes); } private boolean satisfyHelper(IndexedWord parent, IndexedWord l2, SemanticGraph sg, int depth, List> usedNodes) { List> deps = sg.childPairs(parent); if (depth + 1 > endDepth) { return false; } if (depth + 1 >= startDepth) { for (Pair dep : deps) { if (this.type.test(dep.first().toString()) && dep.second().equals(l2)) return true; } } usedNodes.get(depth).add(parent); for (Pair dep : deps) { if ((usedNodes.size() < depth + 1 || !usedNodes.get(depth + 1).contains(dep.second())) && satisfyHelper(dep.second(), l2, sg, depth + 1, usedNodes)) return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { List>> searchStack; List> seenNodes; Set returnedNodes; int currentDepth; @Override public void initialize() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } searchStack = Generics.newArrayList(); for (int i = 0; i <= endDepth; ++i) { searchStack.add(new Stack<>()); } seenNodes = new ArrayList<>(); for (int i = 0; i <= endDepth; ++i) { seenNodes.add(Generics.newIdentityHashSet()); } returnedNodes = Generics.newIdentityHashSet(); currentDepth = 1; List> children = sg.childPairs(node); for (int i = children.size() - 1; i >= 0; i--) { searchStack.get(1).push(children.get(i)); } if (!searchStack.get(1).isEmpty()) { advance(); } } @Override void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } Pair nextPair; while (currentDepth <= endDepth) { Stack> thisStack = searchStack.get(currentDepth); Set thisSeen = seenNodes.get(currentDepth); Stack> nextStack; Set nextSeen; if (currentDepth < endDepth) { nextStack = searchStack.get(currentDepth + 1); nextSeen = seenNodes.get(currentDepth + 1); } else { nextStack = null; nextSeen = null; } while (!thisStack.isEmpty()) { nextPair = thisStack.pop(); if (thisSeen.contains(nextPair.second())) { continue; } thisSeen.add(nextPair.second()); List> children = sg.childPairs(nextPair.second()); for (int i = children.size() - 1; i >= 0; i--) { if (nextSeen != null && !nextSeen.contains(children.get(i).second())) nextStack.push(children.get(i)); } if (currentDepth >= startDepth && type.test(nextPair.first().toString()) && !returnedNodes.contains(nextPair.second())) { next = nextPair.second(); relation = nextPair.first().toString(); returnedNodes.add(nextPair.second()); return; } } // didn't see anything at this depth, move to the next depth ++currentDepth; } // oh well, fell through with no results next = null; } }; } // automatically generated by Eclipse private static final long serialVersionUID = 1L; }; /** * Factored out the common code from GRANDKID and GRANDPARENT *
* In general, the only differences are which ways to go on edges, * so that is gotten through abstract methods */ static private abstract class GRANDSOMETHING extends GraphRelation { GRANDSOMETHING(String symbol, String reln, String name) { super(symbol, reln, name); } abstract List> getNeighborPairs(SemanticGraph sg, IndexedWord node); abstract Iterator neighborIterator(SemanticGraph sg, IndexedWord search); abstract IndexedWord followEdge(SemanticGraphEdge edge); @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { return l1 != l2 && satisfyHelper(l1, l2, sg, Generics.newIdentityHashSet()); } private boolean satisfyHelper(IndexedWord node, IndexedWord l2, SemanticGraph sg, Set usedNodes) { List> govs = getNeighborPairs(sg, node); for (Pair gov : govs) { if (this.type.test(gov.first().toString()) && gov.second().equals(l2)) return true; } usedNodes.add(node); for (Pair gov : govs) { if (!usedNodes.contains(gov.second()) && satisfyHelper(gov.second(), l2, sg, usedNodes)) return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { Stack searchStack; Set searchedNodes; Set matchedNodes; Iterator neighborIterator; @Override public void initialize() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } neighborIterator = null; searchedNodes = Generics.newIdentityHashSet(); matchedNodes = Generics.newIdentityHashSet(); searchStack = Generics.newStack(); searchStack.push(node); advance(); } @Override void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } while (!searchStack.isEmpty()) { if (neighborIterator == null || !neighborIterator.hasNext()) { IndexedWord search = searchStack.pop(); neighborIterator = neighborIterator(sg, search); } while (neighborIterator.hasNext()) { SemanticGraphEdge edge = neighborIterator.next(); IndexedWord otherEnd = followEdge(edge); if (!searchedNodes.contains(otherEnd)) { searchStack.push(otherEnd); searchedNodes.add(otherEnd); } if (type.test(edge.getRelation().toString()) && !matchedNodes.contains(otherEnd)) { matchedNodes.add(otherEnd); next = otherEnd; relation = edge.getRelation().toString(); return; } } } // oh well, fell through with no results next = null; } }; } // automatically generated by Eclipse private static final long serialVersionUID = 1L; }; // GRANDPARENT graph relation: ">>" =========================================== static private class GRANDPARENT extends GRANDSOMETHING { GRANDPARENT(String reln, String name) { super(">>", reln, name); } @Override List> getNeighborPairs(SemanticGraph sg, IndexedWord node) { return sg.childPairs(node); } @Override Iterator neighborIterator(SemanticGraph sg, IndexedWord search) { return sg.outgoingEdgeIterator(search); } @Override IndexedWord followEdge(SemanticGraphEdge edge) { return edge.getTarget(); } // automatically generated by Eclipse private static final long serialVersionUID = 1L; } // GRANDKID graph relation: "<<" ============================================== static private class GRANDKID extends GRANDSOMETHING { GRANDKID(String reln, String name) { super("<<", reln, name); } @Override List> getNeighborPairs(SemanticGraph sg, IndexedWord node) { return sg.parentPairs(node); } @Override Iterator neighborIterator(SemanticGraph sg, IndexedWord search) { return sg.incomingEdgeIterator(search); } @Override IndexedWord followEdge(SemanticGraphEdge edge) { return edge.getSource(); } // automatically generated by copying some other serialVersionUID private static final long serialVersionUID = 1L; } static private class LIMITED_GRANDKID extends GraphRelation { final int startDepth, endDepth; LIMITED_GRANDKID(String reln, String name, int startDepth, int endDepth) { super(startDepth + "," + endDepth + "<<", reln, name); this.startDepth = startDepth; this.endDepth = endDepth; } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (l1.equals(IndexedWord.NO_WORD) || l2.equals(IndexedWord.NO_WORD) ) return false; List> usedNodes = new ArrayList<>(); for (int i = 0; i <= endDepth; ++i) { usedNodes.add(Generics.newIdentityHashSet()); } return l1 != l2 && satisfyHelper(l1, l2, sg, 0, usedNodes); } private boolean satisfyHelper(IndexedWord child, IndexedWord l2, SemanticGraph sg, int depth, List> usedNodes) { List> deps = sg.parentPairs(child); if (depth + 1 > endDepth) { return false; } if (depth + 1 >= startDepth) { for (Pair dep : deps) { if (this.type.test(dep.first().toString()) && dep.second().equals(l2)) return true; } } usedNodes.get(depth).add(child); for (Pair dep : deps) { if ((usedNodes.size() < depth + 1 || !usedNodes.get(depth + 1).contains(dep.second())) && satisfyHelper(dep.second(), l2, sg, depth + 1, usedNodes)) return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { List>> searchStack; List> seenNodes; Set returnedNodes; int currentDepth; @Override public void initialize() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } searchStack = Generics.newArrayList(); for (int i = 0; i <= endDepth; ++i) { searchStack.add(new Stack<>()); } seenNodes = new ArrayList<>(); for (int i = 0; i <= endDepth; ++i) { seenNodes.add(Generics.newIdentityHashSet()); } returnedNodes = Generics.newIdentityHashSet(); currentDepth = 1; List> parents = sg.parentPairs(node); for (int i = parents.size() - 1; i >= 0; i--) { searchStack.get(1).push(parents.get(i)); } if (!searchStack.get(1).isEmpty()) { advance(); } } @Override void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } Pair nextPair; while (currentDepth <= endDepth) { Stack> thisStack = searchStack.get(currentDepth); Set thisSeen = seenNodes.get(currentDepth); Stack> nextStack; Set nextSeen; if (currentDepth < endDepth) { nextStack = searchStack.get(currentDepth + 1); nextSeen = seenNodes.get(currentDepth + 1); } else { nextStack = null; nextSeen = null; } while (!thisStack.isEmpty()) { nextPair = thisStack.pop(); if (thisSeen.contains(nextPair.second())) { continue; } thisSeen.add(nextPair.second()); List> parents = sg.parentPairs(nextPair.second()); for (int i = parents.size() - 1; i >= 0; i--) { if (nextSeen != null && !nextSeen.contains(parents.get(i).second())) nextStack.push(parents.get(i)); } if (currentDepth >= startDepth && type.test(nextPair.first().toString()) && !returnedNodes.contains(nextPair.second())) { returnedNodes.add(nextPair.second()); next = nextPair.second(); relation = nextPair.first().toString(); return; } } // didn't see anything at this depth, move to the next depth ++currentDepth; } // oh well, fell through with no results next = null; } }; } // automatically generated by Eclipse private static final long serialVersionUID = 1L; }; static private class EQUALS extends GraphRelation { EQUALS(String reln, String name) { super("==", reln, name); } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (l1 == l2) { return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { boolean alreadyIterated; @Override public void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } if (alreadyIterated) { next = null; return; } alreadyIterated = true; next = node; return; } }; } } static private abstract class SIBLING_RELATION extends GraphRelation { private static final long serialVersionUID = 1L; SIBLING_RELATION(String symbol, String reln, String name) { super(symbol, reln, name); } abstract boolean satisfiesOrder(IndexedWord l1, IndexedWord l2); @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { IndexedWord parent = sg.getCommonAncestor(l1, l2); Set l1Parents = sg.getParents(l1); if (parent != null && l1Parents.contains(parent) && satisfiesOrder(l1, l2)) { return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { Iterator iterator; @Override public void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } if (iterator == null) { Set parents = sg.getParents(node); Set neighbors = Generics.newIdentityHashSet(); for (IndexedWord parent : parents) { neighbors.addAll(sg.getChildren(parent)); } iterator = neighbors.iterator(); } while (iterator.hasNext()) { IndexedWord word = iterator.next(); if ( ! satisfiesOrder(node, word)) { continue; } this.next = word; return; } this.next = null; } }; } } static private class RIGHT_IMMEDIATE_SIBLING extends SIBLING_RELATION { RIGHT_IMMEDIATE_SIBLING(String reln, String name) { super("$+", reln, name); } private static final long serialVersionUID = 1L; boolean satisfiesOrder(IndexedWord l1, IndexedWord l2) { return (l1.index() == (l2.index() - 1)); } } static private class LEFT_IMMEDIATE_SIBLING extends SIBLING_RELATION { LEFT_IMMEDIATE_SIBLING(String reln, String name) { super("$-", reln, name); } private static final long serialVersionUID = 1L; boolean satisfiesOrder(IndexedWord l1, IndexedWord l2) { return (l1.index() == (l2.index() + 1)); } } static private class RIGHT_SIBLING extends SIBLING_RELATION { RIGHT_SIBLING(String reln, String name) { super("$++", reln, name); } private static final long serialVersionUID = 1L; boolean satisfiesOrder(IndexedWord l1, IndexedWord l2) { return (l1.index() < l2.index()); } } static private class LEFT_SIBLING extends SIBLING_RELATION { LEFT_SIBLING(String reln, String name) { super("$--", reln, name); } private static final long serialVersionUID = 1L; boolean satisfiesOrder(IndexedWord l1, IndexedWord l2) { return (l1.index() > l2.index()); } } static private class ADJACENT_NODE extends GraphRelation { private static final long serialVersionUID = 1L; ADJACENT_NODE(String reln, String name) { super(".", reln, name); } @Override boolean satisfies(IndexedWord l1, IndexedWord l2, SemanticGraph sg) { if (l1.index() == (l2.index() - 1)) { return true; } return false; } @Override Iterator searchNodeIterator(final IndexedWord node, final SemanticGraph sg) { return new SearchNodeIterator() { Iterator iterator; @Override public void advance() { if (node.equals(IndexedWord.NO_WORD)) { next = null; return; } if (iterator == null) { iterator = sg.vertexSet().iterator(); } while (iterator.hasNext()) { IndexedWord word = iterator.next(); if (node.index() != (word.index() - 1)) { continue; } this.next = word; return; } this.next = null; } }; } } // ============================================================================ public static boolean isKnownRelation(String reln) { return (reln.equals(">") || reln.equals("<") || reln.equals(">>") || reln.equals("<<") || reln.equals("@") || reln.equals("==") || reln.equals("$+") || reln.equals("$++") || reln.equals("$-") || reln.equals("$--") || reln.equals(".")); } public static GraphRelation getRelation(String reln, String type, String name) throws ParseException { if (reln == null && type == null) return null; if (!isKnownRelation(reln)) { throw new ParseException("Unknown relation " + reln); } switch (reln) { case ">": return new GOVERNER(type, name); case "<": return new DEPENDENT(type, name); case ">>": return new GRANDPARENT(type, name); case "<<": return new GRANDKID(type, name); case "==": return new EQUALS(type, name); case "$+": return new RIGHT_IMMEDIATE_SIBLING(type, name); case "$-": return new LEFT_IMMEDIATE_SIBLING(type, name); case "$++": return new RIGHT_SIBLING(type, name); case "$--": return new LEFT_SIBLING(type, name); case ".": return new ADJACENT_NODE(type, name); case "@": return new ALIGNMENT(); default: //error throw new ParseException("Relation " + reln + " not handled by getRelation"); } } public static GraphRelation getRelation(String reln, String type, int num, String name) throws ParseException { if (reln == null && type == null) return null; if (reln.equals(">>")) return new LIMITED_GRANDPARENT(type, name, num, num); else if (reln.equals("<<")) return new LIMITED_GRANDKID(type, name, num, num); else if (isKnownRelation(reln)) throw new ParseException("Relation " + reln + " does not use numeric arguments"); else //error throw new ParseException("Unrecognized compound relation " + reln + " " + type); } public static GraphRelation getRelation(String reln, String type, int num, int num2, String name) throws ParseException { if (reln == null && type == null) return null; if (reln.equals(">>")) return new LIMITED_GRANDPARENT(type, name, num, num2); else if (reln.equals("<<")) return new LIMITED_GRANDKID(type, name, num, num2); else if (isKnownRelation(reln)) throw new ParseException("Relation " + reln + " does not use numeric arguments"); else //error throw new ParseException("Unrecognized compound relation " + reln + " " + type); } @Override public int hashCode() { return symbol.hashCode(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof GraphRelation)) { return false; } final GraphRelation relation = (GraphRelation) o; if (!symbol.equals(relation.symbol) || !type.equals(relation.type)) { return false; } return true; } /** * This abstract Iterator implements a NULL iterator, but by subclassing and * overriding advance and/or initialize, it is an efficient implementation. */ static abstract class SearchNodeIterator implements Iterator { public SearchNodeIterator() { initialize(); } /** * This is the next node to be returned by the iterator, or null if there * are no more items. */ IndexedWord next = null; /** * Current relation string for next; */ String relation = null; /** * This method must insure that next points to first item, or null if there * are no items. */ void initialize() { advance(); } /** * This method must insure that next points to next item, or null if there * are no more items. */ void advance() { next = null; } public boolean hasNext() { return next != null; } public IndexedWord next() { if (next == null) { return null; } IndexedWord ret = next; advance(); return ret; } String getReln() {return relation;} public void remove() { throw new UnsupportedOperationException("SearchNodeIterator does not support remove()."); } } // Automatically generated by Eclipse private static final long serialVersionUID = -9128973950911993056L; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy