Skip to content

Commit 5a0c2d5

Browse files
committed
Update the SemgrexMatcher's nodes. Still should do edges
1 parent 0240694 commit 5a0c2d5

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

src/edu/stanford/nlp/semgraph/semgrex/SemgrexMatcher.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,11 @@ public boolean findNextMatchingNode() {
199199
public IndexedWord getNode(String name) {
200200
return namesToNodes.get(name);
201201
}
202-
202+
203+
public IndexedWord putNode(String name, IndexedWord node) {
204+
return namesToNodes.put(name, node);
205+
}
206+
203207
public String getRelnString(String name) {
204208
return namesToRelations.get(name);
205209
}

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,8 @@ public String toEditString() {
9999
return buf.toString();
100100
}
101101

102-
// TODO: update the SemgrexMatcher
103-
// currently the Ssurgeon will not be able to proceed after this edit
104-
// since all of the node and edge pointers will be rewritten
105-
public static void moveNode(SemanticGraph sg, IndexedWord word, int newIndex) {
102+
// TODO: update the SemgrexMatcher's edges as well
103+
public static void moveNode(SemanticGraph sg, SemgrexMatcher sm, IndexedWord word, int newIndex) {
106104
List<SemanticGraphEdge> outgoing = sg.outgoingEdgeList(word);
107105
List<SemanticGraphEdge> incoming = sg.incomingEdgeList(word);
108106
boolean isRoot = sg.isRoot(word);
@@ -120,6 +118,12 @@ public static void moveNode(SemanticGraph sg, IndexedWord word, int newIndex) {
120118
sg.setRoots(newRoots);
121119
}
122120

121+
for (String name : sm.getNodeNames()) {
122+
if (sm.getNode(name) == word) {
123+
sm.putNode(name, newWord);
124+
}
125+
}
126+
123127
for (SemanticGraphEdge oldEdge : outgoing) {
124128
SemanticGraphEdge newEdge = new SemanticGraphEdge(newWord, oldEdge.getTarget(), oldEdge.getRelation(), oldEdge.getWeight(), oldEdge.isExtra());
125129
sg.addEdge(newEdge);
@@ -131,13 +135,13 @@ public static void moveNode(SemanticGraph sg, IndexedWord word, int newIndex) {
131135
}
132136
}
133137

134-
public static void moveNodes(SemanticGraph sg, Function<Integer, Boolean> shouldMove, Function<Integer, Integer> destination) {
138+
public static void moveNodes(SemanticGraph sg, SemgrexMatcher sm, Function<Integer, Boolean> shouldMove, Function<Integer, Integer> destination) {
135139
// iterate first, then move, so that we don't screw up the graph while iterating
136140
List<IndexedWord> toMove = sg.vertexSet().stream().filter(x -> shouldMove.apply(x.index())).collect(Collectors.toList());
137141
Collections.sort(toMove);
138142
Collections.reverse(toMove);
139143
for (IndexedWord word : toMove) {
140-
moveNode(sg, word, destination.apply(word.index()));
144+
moveNode(sg, sm, word, destination.apply(word.index()));
141145
}
142146
}
143147

@@ -195,8 +199,8 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
195199
if (position != null && !position.equals("+")) {
196200
// the payoff for tempIndex == maxIndex + 2:
197201
// everything will be moved one higher, unless it's the new node
198-
moveNodes(sg, x -> (x >= newIndex && x != tempIndex), x -> x+1);
199-
moveNode(sg, newNode, newIndex);
202+
moveNodes(sg, sm, x -> (x >= newIndex && x != tempIndex), x -> x+1);
203+
moveNode(sg, sm, newNode, newIndex);
200204
}
201205

202206
return true;

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,46 @@ public void readXMLAddDepBrokenAnnotation() {
775775
}
776776
}
777777

778+
/**
779+
* The AddDep should update the matches in the SemgrexMatcher.
780+
* If that isn't done correctly, then moving the words first
781+
* and then trying to update the word that was moved
782+
* would not work
783+
*/
784+
@Test
785+
public void readXMLCheckSMNodes() {
786+
Ssurgeon inst = Ssurgeon.inst();
787+
788+
// use "dep" as the dependency so as to be language-agnostic in this test
789+
String add = String.join(newline,
790+
"<ssurgeon-pattern-list>",
791+
" <ssurgeon-pattern>",
792+
" <uid>38</uid>",
793+
" <notes>Add a word before antennae using the position</notes>",
794+
// have to bomb-proof the pattern
795+
" <semgrex>" + XMLUtils.escapeXML("{word:antenna}=antennae !> {word:blue}") + "</semgrex>",
796+
" <edit-list>addDep -gov antennae -reln dep -word blue -position -antennae</edit-list>",
797+
" <edit-list>editNode -node antennae -word antennae</edit-list>",
798+
" </ssurgeon-pattern>",
799+
"</ssurgeon-pattern-list>");
800+
List<SsurgeonPattern> patterns = inst.readFromString(add);
801+
assertEquals(patterns.size(), 1);
802+
SsurgeonPattern addSsurgeon = patterns.get(0);
803+
804+
SemanticGraph sg = SemanticGraph.valueOf("[has-2 nsubj> Jennifer-1 obj> antenna-3]");
805+
IndexedWord blueVertex = sg.getNodeByIndexSafe(4);
806+
assertNull(blueVertex);
807+
SemanticGraph newSG = addSsurgeon.iterate(sg);
808+
SemanticGraph expected = SemanticGraph.valueOf("[has-2 nsubj> Jennifer-1 obj> [antennae-4 dep> blue-3]]");
809+
assertEquals(expected, newSG);
810+
// the Ssurgeon we just created should not put a tag on the word
811+
// but it SHOULD put blue immediately before antennae
812+
blueVertex = newSG.getNodeByIndexSafe(3);
813+
assertNotNull(blueVertex);
814+
assertNull(blueVertex.tag());
815+
assertEquals("blue", blueVertex.value());
816+
}
817+
778818
/**
779819
* Test that types which can't be converted from String
780820
* are detected when making an AddDep

0 commit comments

Comments
 (0)