Skip to content

Commit 4ed3dc0

Browse files
committed
Allow reln == null to represent not having any requirements on the label of the edge to be deleted. Essentially, it deletes all the edges between the two nodes. Still need to test the gov / dep wildcard variants of those - they seem less useful when calling iterate(), though
1 parent 195e259 commit 4ed3dc0

File tree

3 files changed

+77
-16
lines changed

3 files changed

+77
-16
lines changed

src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/RemoveEdge.java

+46-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package edu.stanford.nlp.semgraph.semgrex.ssurgeon;
22

33
import java.io.StringWriter;
4+
import java.util.ArrayList;
5+
import java.util.List;
46

57
import edu.stanford.nlp.ling.IndexedWord;
68
import edu.stanford.nlp.semgraph.semgrex.SemgrexMatcher;
@@ -31,8 +33,10 @@ public RemoveEdge(GrammaticalRelation relation, String govName, String depName)
3133
public String toEditString() {
3234
StringWriter buf = new StringWriter();
3335
buf.write(LABEL); buf.write("\t");
34-
buf.write(Ssurgeon.RELN_ARG);buf.write(" ");
35-
buf.write(relation.toString()); buf.write("\t");
36+
if (relation != null) {
37+
buf.write(Ssurgeon.RELN_ARG);buf.write(" ");
38+
buf.write(relation.toString()); buf.write("\t");
39+
}
3640
buf.write(Ssurgeon.GOV_NODENAME_ARG);buf.write(" ");
3741
buf.write(govName); buf.write("\t");
3842
buf.write(Ssurgeon.DEP_NODENAME_ARG);buf.write(" ");
@@ -61,30 +65,57 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
6165
IndexedWord depNode = getNamedNode(depName, sm);
6266
boolean success = false;
6367

68+
List<SemanticGraphEdge> edgesToDelete = null;
6469
if (govNode != null && depNode != null) {
65-
SemanticGraphEdge edge = sg.getEdge(govNode, depNode, relation);
66-
while (edge != null) {
67-
if (!sg.removeEdge(edge)) {
68-
throw new IllegalStateException("Found an edge and tried to delete it, but somehow this didn't work! " + edge);
70+
if (relation == null) {
71+
edgesToDelete = new ArrayList<>(sg.getAllEdges(govNode, depNode));
72+
} else {
73+
SemanticGraphEdge edge = sg.getEdge(govNode, depNode, relation);
74+
while (edge != null) {
75+
if (!sg.removeEdge(edge)) {
76+
throw new IllegalStateException("Found an edge and tried to delete it, but somehow this didn't work! " + edge);
77+
}
78+
edge = sg.getEdge(govNode, depNode, relation);
79+
success = true;
6980
}
70-
edge = sg.getEdge(govNode, depNode, relation);
71-
success = true;
7281
}
7382
} else if (depNode != null && govWild) {
7483
// dep known, wildcard gov
75-
for (SemanticGraphEdge edge : sg.incomingEdgeIterable(depNode)) {
76-
if (edge.getRelation().equals(relation) && sg.containsEdge(edge) ) {
77-
success = success || sg.removeEdge(edge);
84+
if (relation == null) {
85+
edgesToDelete = new ArrayList<>();
86+
sg.incomingEdgeIterable(depNode).forEach(edgesToDelete::add);
87+
} else {
88+
edgesToDelete = new ArrayList<>();
89+
for (SemanticGraphEdge edge : sg.incomingEdgeIterable(depNode)) {
90+
if (edge.getRelation().equals(relation)) {
91+
edgesToDelete.add(edge);
92+
}
7893
}
7994
}
80-
} else if (govNode != null && depWild) {
95+
} else if (govNode != null && depWild) {
8196
// gov known, wildcard dep
82-
for (SemanticGraphEdge edge : sg.outgoingEdgeIterable(govNode)) {
83-
if (edge.getRelation().equals(relation) && sg.containsEdge(edge) ) {
84-
success = success || sg.removeEdge(edge);
97+
if (relation == null) {
98+
edgesToDelete = new ArrayList<>();
99+
sg.outgoingEdgeIterable(govNode).forEach(edgesToDelete::add);
100+
} else {
101+
edgesToDelete = new ArrayList<>();
102+
for (SemanticGraphEdge edge : sg.outgoingEdgeIterable(govNode)) {
103+
if (edge.getRelation().equals(relation)) {
104+
edgesToDelete.add(edge);
105+
}
106+
}
107+
}
108+
}
109+
110+
if (edgesToDelete != null) {
111+
for (SemanticGraphEdge edge : edgesToDelete) {
112+
if (!sg.removeEdge(edge)) {
113+
throw new IllegalStateException("Found an edge and tried to delete it, but somehow this didn't work! " + edge);
85114
}
115+
success = true;
86116
}
87117
}
118+
88119
// will be true if at least one edge was removed
89120
return success;
90121
}

src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/Ssurgeon.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,11 @@ public static SsurgeonEdit parseEditLine(String editLine) {
360360
} else if (command.equalsIgnoreCase(DeleteGraphFromNode.LABEL)) {
361361
retEdit = new DeleteGraphFromNode(argsBox.node);
362362
} else if (command.equalsIgnoreCase(RemoveEdge.LABEL)) {
363-
retEdit = new RemoveEdge(GrammaticalRelation.valueOf(argsBox.reln), argsBox.govNodeName, argsBox.dep);
363+
GrammaticalRelation reln = null;
364+
if (argsBox.reln != null) {
365+
reln = GrammaticalRelation.valueOf(argsBox.reln);
366+
}
367+
retEdit = new RemoveEdge(reln, argsBox.govNodeName, argsBox.dep);
364368
} else if (command.equalsIgnoreCase(RemoveNamedEdge.LABEL)) {
365369
retEdit = new RemoveNamedEdge(argsBox.edge);
366370
} else if (command.equalsIgnoreCase(SetRoots.LABEL)) {

test/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,32 @@ public void readXMLRemoveEdgeIterate() {
118118
}
119119

120120

121+
/**
122+
* Test that removing an edge given its endpoints and the dependency type will remove all matching edges
123+
*/
124+
@Test
125+
public void readXMLRemoveEdgeNoRelationIterate() {
126+
String doc = String.join(newline,
127+
"<ssurgeon-pattern-list>",
128+
" <ssurgeon-pattern>",
129+
" <uid>38</uid>",
130+
" <notes>Test removing an edge with no relation set</notes>",
131+
" <semgrex>" + XMLUtils.escapeXML("{word:B}=a1 > {word:E}=a2") + "</semgrex>",
132+
" <edit-list>removeEdge -gov a1 -dep a2</edit-list>",
133+
" </ssurgeon-pattern>",
134+
"</ssurgeon-pattern-list>");
135+
Ssurgeon inst = Ssurgeon.inst();
136+
List<SsurgeonPattern> patterns = inst.readFromString(doc);
137+
assertEquals(patterns.size(), 1);
138+
SsurgeonPattern pattern = patterns.get(0);
139+
140+
SemanticGraph sg = SemanticGraph.valueOf("[A-0 obj> [B-1 nsubj> E-4] obj> C-2 nsubj> [D-3 obj> E-4]]");
141+
SemanticGraph newSg = pattern.iterate(sg);
142+
SemanticGraph expected = SemanticGraph.valueOf("[A-0 obj> B-1 obj> C-2 nsubj> [D-3 obj> E-4]]");
143+
assertEquals(newSg, expected);
144+
}
145+
146+
121147
/**
122148
* Test that removing a named edge will remove all matching edges
123149
*/

0 commit comments

Comments
 (0)