Skip to content

Commit 232931d

Browse files
committed
Iterate through all the patterns in an Ssurgeon, even if one does (or doesn't) change the graph
Adds a test of the multi-pattern iterate
1 parent 9c3dfee commit 232931d

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,15 @@ public SemanticGraph iterate(SemanticGraph sg) {
185185
// We reset the named node map with each edit set, since these edits
186186
// should exist in a separate graph for each unique Semgrex match.
187187
nodeMap = Generics.newHashMap();
188+
boolean edited = false;
188189
for (SsurgeonEdit edit : editScript) {
189190
if (edit.evaluate(copied, matcher)) {
190-
matcher = semgrexPattern.matcher(copied);
191-
break;
191+
edited = true;
192192
}
193193
}
194+
if (edited) {
195+
matcher = semgrexPattern.matcher(copied);
196+
}
194197
}
195198
return copied;
196199
}

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

+50
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ public void readXMLRemoveNamedEdgeIterate() {
180180
/**
181181
* Check that cutting a graph with two nodes into two pieces, then
182182
* pruning any disjoint pieces, results in a graph with just the root
183+
* when done as a single operation
183184
*/
184185
@Test
185186
public void readXMLPruneNodesIterate() {
@@ -242,6 +243,55 @@ public void readXMLPruneNodesIterate() {
242243
assertEquals(pruneSG, expected);
243244
}
244245

246+
247+
/**
248+
* Check that cutting a graph with two nodes into two pieces, then
249+
* pruning any disjoint pieces, results in a graph with just the root,
250+
* this time done as one combined operation
251+
*/
252+
@Test
253+
public void readXMLTwoStepPruneIterate() {
254+
Ssurgeon inst = Ssurgeon.inst();
255+
256+
String xml = String.join(newline,
257+
"<ssurgeon-pattern-list>",
258+
" <ssurgeon-pattern>",
259+
" <uid>38</uid>",
260+
" <notes>Remove dep edges and prune</notes>",
261+
" <semgrex>" + XMLUtils.escapeXML("{}=a1 >dep {}=a2") + "</semgrex>",
262+
" <edit-list>removeEdge -gov a1 -dep a2 -reln dep</edit-list>",
263+
" <edit-list>delete -node a2</edit-list>",
264+
" </ssurgeon-pattern>",
265+
"</ssurgeon-pattern-list>");
266+
List<SsurgeonPattern> patterns = inst.readFromString(xml);
267+
assertEquals(1, patterns.size());
268+
SsurgeonPattern ssurgeon = patterns.get(0);
269+
assertEquals(2, ssurgeon.editScript.size());
270+
271+
// Test a two node only version
272+
SemanticGraph sg = SemanticGraph.valueOf("[A dep> B]");
273+
SemanticGraph cutSG = ssurgeon.iterate(sg);
274+
SemanticGraph expected = SemanticGraph.valueOf("[A]");
275+
assertEquals(1, cutSG.vertexSet().size());
276+
assertEquals(expected, cutSG);
277+
278+
// Test a chain cut at the start
279+
sg = SemanticGraph.valueOf("[A dep> [B obj> C]]");
280+
cutSG = ssurgeon.iterate(sg);
281+
assertEquals(expected, cutSG);
282+
283+
// Test the chain cut at the bottom
284+
sg = SemanticGraph.valueOf("[A obj> [B dep> C]]");
285+
cutSG = ssurgeon.iterate(sg);
286+
assertEquals(SemanticGraph.valueOf("[A obj> B]"), cutSG);
287+
288+
// Test a chain cut at the start
289+
// Only the root will be left at the end
290+
sg = SemanticGraph.valueOf("[A dep> B dep> C]");
291+
cutSG = ssurgeon.iterate(sg);
292+
assertEquals(expected, cutSG);
293+
}
294+
245295
/**
246296
* Test that if the root is removed by a prune operation,
247297
* the roots on the graph are reset

0 commit comments

Comments
 (0)