From 232931dd8dfddf59121de7f79dcc2ef13a403048 Mon Sep 17 00:00:00 2001 From: John Bauer Date: Thu, 19 Jan 2023 19:01:57 -0800 Subject: [PATCH] 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 --- .../semgrex/ssurgeon/SsurgeonPattern.java | 7 ++- .../semgrex/ssurgeon/SsurgeonTest.java | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonPattern.java b/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonPattern.java index 1304f01a16..55aa8e578d 100644 --- a/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonPattern.java +++ b/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonPattern.java @@ -185,12 +185,15 @@ public SemanticGraph iterate(SemanticGraph sg) { // We reset the named node map with each edit set, since these edits // should exist in a separate graph for each unique Semgrex match. nodeMap = Generics.newHashMap(); + boolean edited = false; for (SsurgeonEdit edit : editScript) { if (edit.evaluate(copied, matcher)) { - matcher = semgrexPattern.matcher(copied); - break; + edited = true; } } + if (edited) { + matcher = semgrexPattern.matcher(copied); + } } return copied; } diff --git a/test/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonTest.java b/test/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonTest.java index 16e11daa13..16c9563365 100644 --- a/test/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonTest.java +++ b/test/src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SsurgeonTest.java @@ -180,6 +180,7 @@ public void readXMLRemoveNamedEdgeIterate() { /** * Check that cutting a graph with two nodes into two pieces, then * pruning any disjoint pieces, results in a graph with just the root + * when done as a single operation */ @Test public void readXMLPruneNodesIterate() { @@ -242,6 +243,55 @@ public void readXMLPruneNodesIterate() { assertEquals(pruneSG, expected); } + + /** + * Check that cutting a graph with two nodes into two pieces, then + * pruning any disjoint pieces, results in a graph with just the root, + * this time done as one combined operation + */ + @Test + public void readXMLTwoStepPruneIterate() { + Ssurgeon inst = Ssurgeon.inst(); + + String xml = String.join(newline, + "", + " ", + " 38", + " Remove dep edges and prune", + " " + XMLUtils.escapeXML("{}=a1 >dep {}=a2") + "", + " removeEdge -gov a1 -dep a2 -reln dep", + " delete -node a2", + " ", + ""); + List patterns = inst.readFromString(xml); + assertEquals(1, patterns.size()); + SsurgeonPattern ssurgeon = patterns.get(0); + assertEquals(2, ssurgeon.editScript.size()); + + // Test a two node only version + SemanticGraph sg = SemanticGraph.valueOf("[A dep> B]"); + SemanticGraph cutSG = ssurgeon.iterate(sg); + SemanticGraph expected = SemanticGraph.valueOf("[A]"); + assertEquals(1, cutSG.vertexSet().size()); + assertEquals(expected, cutSG); + + // Test a chain cut at the start + sg = SemanticGraph.valueOf("[A dep> [B obj> C]]"); + cutSG = ssurgeon.iterate(sg); + assertEquals(expected, cutSG); + + // Test the chain cut at the bottom + sg = SemanticGraph.valueOf("[A obj> [B dep> C]]"); + cutSG = ssurgeon.iterate(sg); + assertEquals(SemanticGraph.valueOf("[A obj> B]"), cutSG); + + // Test a chain cut at the start + // Only the root will be left at the end + sg = SemanticGraph.valueOf("[A dep> B dep> C]"); + cutSG = ssurgeon.iterate(sg); + assertEquals(expected, cutSG); + } + /** * Test that if the root is removed by a prune operation, * the roots on the graph are reset