Skip to content

Commit 499eb5b

Browse files
committedMar 5, 2025·
Move the Ssurgeon reindex operations from AddDep to SsurgeonUtils
1 parent dcee001 commit 499eb5b

File tree

5 files changed

+78
-76
lines changed

5 files changed

+78
-76
lines changed
 

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

+2-72
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
import java.io.StringWriter;
44
import java.util.*;
5-
import java.util.function.Function;
6-
import java.util.stream.Collectors;
75

86
import edu.stanford.nlp.ling.CoreLabel;
97
import edu.stanford.nlp.ling.IndexedWord;
108
import edu.stanford.nlp.semgraph.SemanticGraph;
11-
import edu.stanford.nlp.semgraph.SemanticGraphEdge;
129
import edu.stanford.nlp.semgraph.SemanticGraphUtils;
1310
import edu.stanford.nlp.semgraph.semgrex.SemgrexMatcher;
14-
import edu.stanford.nlp.trees.EnglishGrammaticalRelations;
1511
import edu.stanford.nlp.trees.GrammaticalRelation;
1612

1713
/**
@@ -90,72 +86,6 @@ public String toEditString() {
9086
return buf.toString();
9187
}
9288

93-
// TODO: make the updating of named nodes & edges faster,
94-
// possibly by building a cache from node/edge to name?
95-
public static void moveNode(SemanticGraph sg, SemgrexMatcher sm, IndexedWord word, int newIndex) {
96-
List<SemanticGraphEdge> outgoing = sg.outgoingEdgeList(word);
97-
List<SemanticGraphEdge> incoming = sg.incomingEdgeList(word);
98-
boolean isRoot = sg.isRoot(word);
99-
sg.removeVertex(word);
100-
101-
IndexedWord newWord = new IndexedWord(word.backingLabel());
102-
newWord.setIndex(newIndex);
103-
104-
// could be more expensive than necessary if we move multiple roots,
105-
// but the expectation is there is usually only the 1 root
106-
if (isRoot) {
107-
Set<IndexedWord> newRoots = new HashSet<>(sg.getRoots());
108-
newRoots.remove(word);
109-
newRoots.add(newWord);
110-
sg.setRoots(newRoots);
111-
}
112-
113-
for (String name : sm.getNodeNames()) {
114-
if (sm.getNode(name) == word) {
115-
sm.putNode(name, newWord);
116-
}
117-
}
118-
119-
for (SemanticGraphEdge oldEdge : outgoing) {
120-
SemanticGraphEdge newEdge = new SemanticGraphEdge(newWord, oldEdge.getTarget(), oldEdge.getRelation(), oldEdge.getWeight(), oldEdge.isExtra());
121-
122-
for (String name : sm.getEdgeNames()) {
123-
if (sm.getEdge(name) == oldEdge) {
124-
sm.putNamedEdge(name, newEdge);
125-
}
126-
}
127-
128-
sg.addEdge(newEdge);
129-
}
130-
131-
for (SemanticGraphEdge oldEdge : incoming) {
132-
SemanticGraphEdge newEdge = new SemanticGraphEdge(oldEdge.getSource(), newWord, oldEdge.getRelation(), oldEdge.getWeight(), oldEdge.isExtra());
133-
134-
for (String name : sm.getEdgeNames()) {
135-
if (sm.getEdge(name) == oldEdge) {
136-
sm.putNamedEdge(name, newEdge);
137-
}
138-
}
139-
140-
sg.addEdge(newEdge);
141-
}
142-
}
143-
144-
/**
145-
* reverse: operate in reverse order, highest index to first. You want true if moving indices up, false if moving indices down
146-
*/
147-
public static void moveNodes(SemanticGraph sg, SemgrexMatcher sm, Function<Integer, Boolean> shouldMove, Function<Integer, Integer> destination, boolean reverse) {
148-
// iterate first, then move, so that we don't screw up the graph while iterating
149-
List<IndexedWord> toMove = sg.vertexSet().stream().filter(x -> shouldMove.apply(x.index())).collect(Collectors.toList());
150-
Collections.sort(toMove);
151-
if (reverse) {
152-
Collections.reverse(toMove);
153-
}
154-
for (IndexedWord word : toMove) {
155-
moveNode(sg, sm, word, destination.apply(word.index()));
156-
}
157-
}
158-
15989
/**
16090
* TODO: bombproof if this gov, dep, and reln already exist.
16191
*/
@@ -210,8 +140,8 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
210140
if (position != null && !position.equals("+")) {
211141
// the payoff for tempIndex == maxIndex + 2:
212142
// everything will be moved one higher, unless it's the new node
213-
moveNodes(sg, sm, x -> (x >= newIndex && x != tempIndex), x -> x+1, true);
214-
moveNode(sg, sm, newNode, newIndex);
143+
SsurgeonUtils.moveNodes(sg, sm, x -> (x >= newIndex && x != tempIndex), x -> x+1, true);
144+
SsurgeonUtils.moveNode(sg, sm, newNode, newIndex);
215145
}
216146

217147
return true;

‎src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/DeleteLeaf.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
4444
boolean deletedNode = sg.removeVertex(tgtNode);
4545
// renumber the indices
4646
if (deletedNode) {
47-
AddDep.moveNodes(sg, sm, x -> (x >= deletedIndex), x -> x-1, false);
47+
SsurgeonUtils.moveNodes(sg, sm, x -> (x >= deletedIndex), x -> x-1, false);
4848
}
4949
return deletedEdge || deletedNode;
5050
}

‎src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/MergeNodes.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
161161
}
162162

163163
// reindex everyone
164-
AddDep.moveNodes(sg, sm, x -> (x >= dep.index()), x -> x-1, false);
164+
SsurgeonUtils.moveNodes(sg, sm, x -> (x >= dep.index()), x -> x-1, false);
165165

166166
return true;
167167
}

‎src/edu/stanford/nlp/semgraph/semgrex/ssurgeon/SplitWord.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ public boolean evaluate(SemanticGraph sg, SemgrexMatcher sm) {
137137

138138
// move all words down by nodeRegex.size() - 1
139139
// then move the original word down by headIndex
140-
AddDep.moveNodes(sg, sm, x -> (x > matchedIndex), x -> x+nodeRegex.size() - 1, true);
140+
SsurgeonUtils.moveNodes(sg, sm, x -> (x > matchedIndex), x -> x+nodeRegex.size() - 1, true);
141141
// the head node has its word replaced, and its index & links need
142142
// to be rearranged, but none of the links are added or removed
143143
if (headIndex > 0) {
144-
AddDep.moveNode(sg, sm, matchedNode, matchedIndex + headIndex);
144+
SsurgeonUtils.moveNode(sg, sm, matchedNode, matchedIndex + headIndex);
145145
}
146146
matchedNode = sm.getNode(node);
147147
matchedNode.setWord(words.get(headIndex));
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,81 @@
11
package edu.stanford.nlp.semgraph.semgrex.ssurgeon;
22

3+
import java.util.Collections;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Set;
7+
import java.util.function.Function;
8+
import java.util.stream.Collectors;
9+
310
import edu.stanford.nlp.ling.IndexedWord;
411
import edu.stanford.nlp.semgraph.SemanticGraph;
12+
import edu.stanford.nlp.semgraph.SemanticGraphEdge;
13+
import edu.stanford.nlp.semgraph.semgrex.SemgrexMatcher;
514

615
public class SsurgeonUtils {
16+
// TODO: make the updating of named nodes & edges faster,
17+
// possibly by building a cache from node/edge to name?
18+
public static void moveNode(SemanticGraph sg, SemgrexMatcher sm, IndexedWord word, int newIndex) {
19+
List<SemanticGraphEdge> outgoing = sg.outgoingEdgeList(word);
20+
List<SemanticGraphEdge> incoming = sg.incomingEdgeList(word);
21+
boolean isRoot = sg.isRoot(word);
22+
sg.removeVertex(word);
23+
24+
IndexedWord newWord = new IndexedWord(word.backingLabel());
25+
newWord.setIndex(newIndex);
26+
27+
// could be more expensive than necessary if we move multiple roots,
28+
// but the expectation is there is usually only the 1 root
29+
if (isRoot) {
30+
Set<IndexedWord> newRoots = new HashSet<>(sg.getRoots());
31+
newRoots.remove(word);
32+
newRoots.add(newWord);
33+
sg.setRoots(newRoots);
34+
}
35+
36+
for (String name : sm.getNodeNames()) {
37+
if (sm.getNode(name) == word) {
38+
sm.putNode(name, newWord);
39+
}
40+
}
41+
42+
for (SemanticGraphEdge oldEdge : outgoing) {
43+
SemanticGraphEdge newEdge = new SemanticGraphEdge(newWord, oldEdge.getTarget(), oldEdge.getRelation(), oldEdge.getWeight(), oldEdge.isExtra());
44+
45+
for (String name : sm.getEdgeNames()) {
46+
if (sm.getEdge(name) == oldEdge) {
47+
sm.putNamedEdge(name, newEdge);
48+
}
49+
}
50+
51+
sg.addEdge(newEdge);
52+
}
53+
54+
for (SemanticGraphEdge oldEdge : incoming) {
55+
SemanticGraphEdge newEdge = new SemanticGraphEdge(oldEdge.getSource(), newWord, oldEdge.getRelation(), oldEdge.getWeight(), oldEdge.isExtra());
56+
57+
for (String name : sm.getEdgeNames()) {
58+
if (sm.getEdge(name) == oldEdge) {
59+
sm.putNamedEdge(name, newEdge);
60+
}
61+
}
762

63+
sg.addEdge(newEdge);
64+
}
65+
}
866

67+
/**
68+
* reverse: operate in reverse order, highest index to first. You want true if moving indices up, false if moving indices down
69+
*/
70+
public static void moveNodes(SemanticGraph sg, SemgrexMatcher sm, Function<Integer, Boolean> shouldMove, Function<Integer, Integer> destination, boolean reverse) {
71+
// iterate first, then move, so that we don't screw up the graph while iterating
72+
List<IndexedWord> toMove = sg.vertexSet().stream().filter(x -> shouldMove.apply(x.index())).collect(Collectors.toList());
73+
Collections.sort(toMove);
74+
if (reverse) {
75+
Collections.reverse(toMove);
76+
}
77+
for (IndexedWord word : toMove) {
78+
moveNode(sg, sm, word, destination.apply(word.index()));
79+
}
80+
}
981
}

0 commit comments

Comments
 (0)
Please sign in to comment.