@@ -117,6 +117,122 @@ public void readXMLRemoveEdgeIterate() {
117117 assertEquals (newSg , expected );
118118 }
119119
120+ /**
121+ * Check that cutting a graph with two nodes into two pieces, then
122+ * pruning any disjoint pieces, results in a graph with just the root
123+ */
124+ @ Test
125+ public void readXMLPruneNodesIterate () {
126+ Ssurgeon inst = Ssurgeon .inst ();
127+
128+ String cut = String .join (newline ,
129+ "<ssurgeon-pattern-list>" ,
130+ " <ssurgeon-pattern>" ,
131+ " <uid>38</uid>" ,
132+ " <notes>Remove dep edges</notes>" ,
133+ " <semgrex>" + XMLUtils .escapeXML ("{}=a1 > {}=a2" ) + "</semgrex>" ,
134+ " <edit-list>removeEdge -gov a1 -dep a2 -reln dep</edit-list>" ,
135+ " </ssurgeon-pattern>" ,
136+ "</ssurgeon-pattern-list>" );
137+ List <SsurgeonPattern > patterns = inst .readFromString (cut );
138+ assertEquals (patterns .size (), 1 );
139+ SsurgeonPattern ssurgeonCut = patterns .get (0 );
140+
141+ String prune = String .join (newline ,
142+ "<ssurgeon-pattern-list>" ,
143+ " <ssurgeon-pattern>" ,
144+ " <uid>38</uid>" ,
145+ " <notes>This semgrex detects disjoint nodes</notes>" ,
146+ " <semgrex>" + XMLUtils .escapeXML ("{}=disjoint !== {$} !<< {$}" ) + "</semgrex>" ,
147+ " <edit-list>delete -node disjoint</edit-list>" ,
148+ " </ssurgeon-pattern>" ,
149+ "</ssurgeon-pattern-list>" );
150+ patterns = inst .readFromString (prune );
151+ assertEquals (patterns .size (), 1 );
152+ SsurgeonPattern ssurgeonPrune = patterns .get (0 );
153+
154+ // Test a two node only version
155+ SemanticGraph sg = SemanticGraph .valueOf ("[A dep> B]" );
156+ SemanticGraph cutSG = ssurgeonCut .iterate (sg );
157+ assertEquals (cutSG .vertexSet ().size (), 2 );
158+ SemanticGraph pruneSG = ssurgeonPrune .iterate (cutSG );
159+ SemanticGraph expected = SemanticGraph .valueOf ("[A]" );
160+ assertEquals (pruneSG , expected );
161+
162+ // Test a chain cut at the start
163+ sg = SemanticGraph .valueOf ("[A dep> [B obj> C]]" );
164+ cutSG = ssurgeonCut .iterate (sg );
165+ assertEquals (cutSG .vertexSet ().size (), 3 );
166+ pruneSG = ssurgeonPrune .iterate (cutSG );
167+ assertEquals (pruneSG , expected );
168+
169+ // Test the chain cut at the bottom
170+ sg = SemanticGraph .valueOf ("[A obj> [B dep> C]]" );
171+ cutSG = ssurgeonCut .iterate (sg );
172+ assertEquals (cutSG .vertexSet ().size (), 3 );
173+ pruneSG = ssurgeonPrune .iterate (cutSG );
174+ assertEquals (pruneSG , SemanticGraph .valueOf ("[A obj> B]" ));
175+
176+ // Test a chain cut at the start
177+ // Only the root will be left at the end
178+ sg = SemanticGraph .valueOf ("[A dep> B dep> C]" );
179+ cutSG = ssurgeonCut .iterate (sg );
180+ assertEquals (cutSG .vertexSet ().size (), 3 );
181+ pruneSG = ssurgeonPrune .iterate (cutSG );
182+ assertEquals (pruneSG , expected );
183+ }
184+
185+ /**
186+ * Test that if the root is removed by a prune operation,
187+ * the roots on the graph are reset
188+ */
189+ @ Test
190+ public void readXMLPruneNodesResetRoots () {
191+ Ssurgeon inst = Ssurgeon .inst ();
192+
193+ String cut = String .join (newline ,
194+ "<ssurgeon-pattern-list>" ,
195+ " <ssurgeon-pattern>" ,
196+ " <uid>38</uid>" ,
197+ " <notes>Remove any dep edges from the graph</notes>" ,
198+ " <semgrex>" + XMLUtils .escapeXML ("{}=a1 > {}=a2" ) + "</semgrex>" ,
199+ " <edit-list>removeEdge -gov a1 -dep a2 -reln dep</edit-list>" ,
200+ " </ssurgeon-pattern>" ,
201+ "</ssurgeon-pattern-list>" );
202+ List <SsurgeonPattern > patterns = inst .readFromString (cut );
203+ assertEquals (patterns .size (), 1 );
204+ SsurgeonPattern ssurgeonCut = patterns .get (0 );
205+
206+ String prune = String .join (newline ,
207+ "<ssurgeon-pattern-list>" ,
208+ " <ssurgeon-pattern>" ,
209+ " <uid>38</uid>" ,
210+ " <notes>This semgrex detects disjoint roots</notes>" ,
211+ " <semgrex>" + XMLUtils .escapeXML ("{$}=root : {} !== {}=root !>> {}=root" ) + "</semgrex>" ,
212+ " <edit-list>delete -node root</edit-list>" ,
213+ " </ssurgeon-pattern>" ,
214+ "</ssurgeon-pattern-list>" );
215+ patterns = inst .readFromString (prune );
216+ assertEquals (patterns .size (), 1 );
217+ SsurgeonPattern ssurgeonPrune = patterns .get (0 );
218+
219+ // Test a two node only version
220+ SemanticGraph sg = SemanticGraph .valueOf ("[A dep> B]" );
221+ SemanticGraph cutSG = ssurgeonCut .iterate (sg );
222+ assertEquals (2 , cutSG .vertexSet ().size ());
223+ SemanticGraph pruneSG = ssurgeonPrune .iterate (cutSG );
224+ // note that for now, the prune operation doesn't renumber nodes in any way
225+ SemanticGraph expected = SemanticGraph .valueOf ("[B-1]" );
226+ assertEquals (expected , pruneSG );
227+
228+ // Test the chain cut at the bottom
229+ sg = SemanticGraph .valueOf ("[A obj> [B dep> C]]" );
230+ cutSG = ssurgeonCut .iterate (sg );
231+ assertEquals (cutSG .vertexSet ().size (), 3 );
232+ pruneSG = ssurgeonPrune .iterate (cutSG );
233+ assertEquals (SemanticGraph .valueOf ("[C-2]" ), pruneSG );
234+ }
235+
120236 /**
121237 * Simple test of an Ssurgeon edit script. This instances a simple semantic graph,
122238 * a semgrex pattern, and then the resulting actions over the named nodes in the
0 commit comments