package edu.stanford.nlp.semgraph.semgrex.ssurgeon;
import java.io.StringWriter;
import java.util.*;
import edu.stanford.nlp.ling.IndexedWord;
import edu.stanford.nlp.semgraph.semgrex.SemgrexMatcher;
import edu.stanford.nlp.semgraph.SemanticGraph;
import edu.stanford.nlp.semgraph.SemanticGraphEdge;
import edu.stanford.nlp.util.Generics;
/**
* This destroys the subgraph starting from the given node. Use this when
* the SemanticGraph has been cut and separated into two separate graphs,
* and you wish to destroy one of them.
*
* @author yeh1
*
*/
public class DeleteGraphFromNode extends SsurgeonEdit {
public static final String LABEL = "delete";
String destroyNodeName;
public DeleteGraphFromNode(String destroyNodeName) {
this.destroyNodeName = destroyNodeName;
}
public static DeleteGraphFromNode fromArgs(String args) {
return new DeleteGraphFromNode(args.trim());
}
@Override
public String toEditString() {
StringWriter buf = new StringWriter();
buf.write(LABEL); buf.write("\t");
buf.write(Ssurgeon.NODENAME_ARG);buf.write(" ");
buf.write(destroyNodeName);
return buf.toString();
}
protected static void crawl(IndexedWord vertex, SemanticGraph sg, Set<IndexedWord> seenVerts) {
seenVerts.add(vertex);
for (SemanticGraphEdge edge : sg.incomingEdgeIterable(vertex)) {
IndexedWord gov = edge.getGovernor();
if (!seenVerts.contains(gov)) {
crawl(gov, sg, seenVerts);
}
}
for (SemanticGraphEdge edge : sg.outgoingEdgeIterable(vertex)) {
IndexedWord dep = edge.getDependent();
if (!seenVerts.contains(dep)) {
crawl(dep, sg, seenVerts);
}
}
}
protected static Set<IndexedWord> crawl(IndexedWord vertex, SemanticGraph sg) {
Set<IndexedWord> seen = Generics.newHashSet();
crawl(vertex, sg, seen);
return seen;
}
@Override
public void evaluate(SemanticGraph sg, SemgrexMatcher sm) {
IndexedWord seedNode = getNamedNode(destroyNodeName, sm);
// TODO: do not execute if seedNode if not in graph (or just error?)
if (sg.containsVertex(seedNode)) {
Set<IndexedWord> nodesToDestroy = crawl(seedNode, sg);
for (IndexedWord node : nodesToDestroy) {
sg.removeVertex(node);
}
// After destroy nodes, need to reset the roots, since it's possible a root node
// was destroyed.
sg.resetRoots();
}
}
}