Skip to content

Commit c31c834

Browse files
AngledLuffaclaude
andcommitted
Put a fronted WHADVP back in the predicate of an empty copula
"How are you?" and "I know where he is" came out with the copula as the head and the wh-adverb as advmod. EWT and GUM make the wh-adverb the head of its copular clause when the copula has no other predicate, as in "How was your trip", "When is the wedding?" or "asked how the food was". As for a fronted WHADJP, move the WHADVP to the copula, relabeled as an ADVP, when the copula has nothing after it. In a main clause question with no VP, where the SQ is just the copula and the subject, the adverb goes after the subject, the same shape as "Is the trouble over?". The adverb is then the head of the clause, with the copula as cop: Where is the station? Where head, is cop, station nsubj When will the meeting be? When head, will aux, be cop I know where he is ccomp(know, where), is cop A WHADVP is usually an adjunct, so the move needs a copula with nothing at all after it: "Where are you going?", "Why is he here?" and "when it was late" are unchanged. The relation rules tell a where or when complement, as in "I know where he is", from an adjunct, as in "stay where we are" or "put your money where your mouth is", by the WHADVP at the start of the SBAR. The move takes that away, so it is limited to the clauses whose relation does not depend on it: the complement of a verb which takes a wh-clause, the object of a preposition, as in "back to where she was", a clause with how, and a main clause question. The adjunct clauses are unchanged. A WRB at the end of the ADVP it is moved as is its head, so "know just where it was" has where as the head, with just as advmod. The PTB sometimes writes "how terrific" or "how useful" as a WHADVP, and there the adjective is still the head. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FFFrVzJ9BaKtDx4UPVveJx
1 parent 99ea6e6 commit c31c834

4 files changed

Lines changed: 124 additions & 4 deletions

File tree

‎src/edu/stanford/nlp/trees/CoordinationTransformer.java‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ public Tree transformTree(Tree t) {
127127
debugLine("After moveWHADJPToCopula: ", t);
128128
}
129129

130+
t = moveWHADVPToCopula(t);
131+
if (VERBOSE) {
132+
debugLine("After moveWHADVPToCopula: ", t);
133+
}
134+
130135
if (performMWETransformation) {
131136
t = MWETransform(t);
132137
if (VERBOSE) {
@@ -242,6 +247,56 @@ public static Tree moveWHADJPToCopula(Tree t) {
242247
return Tsurgeon.processPattern(moveWHADJPTregex, moveWHADJPTsurgeon, t);
243248
}
244249

250+
// A fronted WHADVP whose clause has a copula with no predicate, as in
251+
// "I know where he is", "How was your trip?" or "When will the
252+
// meeting be?" Unlike a WHADJP, a WHADVP is usually an adjunct, so
253+
// the copula must have nothing else after it, not even an adverb or a
254+
// PP, as in "why is he here" or "where is he from".
255+
private static final String WHADVP_EMPTY_COPULA =
256+
"(WHADVP=wh $+ (S|SQ <+(VP|S|SQ) (VP=vp < (/^VB/=cop < " + EnglishPatterns.copularWordRegex + ") !< NP|ADJP|ADVP|PRT|PP|VP|UCP|S|SBAR|WHADJP)))";
257+
258+
// The relation rules tell a where or when complement, as in "I know
259+
// where he is", from an adjunct, as in "stay where we are" or "put
260+
// your money where your mouth is", by the WHADVP at the start of the
261+
// SBAR. The move takes that away, so it is limited to the places
262+
// where the relation of the clause does not depend on it: the
263+
// complement of a verb which takes a wh-clause, the object of a
264+
// preposition, a clause with how, and a main clause question.
265+
private static final TregexPattern moveWHADVPTregex =
266+
TregexPattern.compile("SBAR [ > (VP < (/^V/ < " + EnglishPatterns.ccompVerbRegex + ") < (/^V/ < " + EnglishPatterns.ccompObjVerbRegex + ")) | " +
267+
"!$-- NP > (VP < (/^V/ < " + EnglishPatterns.ccompVerbRegex + ")) | > PP | " +
268+
"!$-- NP <, (WHADVP < (WRB < /^(?i:how)$/)) ] < " + WHADVP_EMPTY_COPULA);
269+
270+
private static final TregexPattern moveWHADVPQuestionTregex =
271+
TregexPattern.compile("SBARQ < " + WHADVP_EMPTY_COPULA);
272+
273+
private static final TsurgeonPattern moveWHADVPTsurgeon =
274+
Tsurgeon.parseOperation("[move wh $- cop] [relabel wh ADVP]");
275+
276+
// The same in a main clause question with no VP, where the SQ is just
277+
// the copula and the subject, as in "Where is the station?" The
278+
// adverb goes after the subject, as in "Is the station here?"
279+
private static final TregexPattern moveWHADVPSQTregex =
280+
TregexPattern.compile("SBARQ < (WHADVP=wh $+ (SQ=sq <, (/^VB/ < " + EnglishPatterns.copularWordRegex + ") <- NP !<3 __))");
281+
282+
private static final TsurgeonPattern moveWHADVPSQTsurgeon =
283+
Tsurgeon.parseOperation("[move wh >-1 sq] [relabel wh ADVP]");
284+
285+
/**
286+
* Puts a fronted wh-adverb back in the predicate position of a copula
287+
* which has no predicate, as in "I know where he is" or "Where is the
288+
* station?" After the move, the adverb is the head of the copular
289+
* clause, with the copula as cop, as in UD.
290+
*/
291+
public static Tree moveWHADVPToCopula(Tree t) {
292+
if (t == null) {
293+
return null;
294+
}
295+
t = Tsurgeon.processPattern(moveWHADVPTregex, moveWHADVPTsurgeon, t);
296+
t = Tsurgeon.processPattern(moveWHADVPQuestionTregex, moveWHADVPTsurgeon, t);
297+
return Tsurgeon.processPattern(moveWHADVPSQTregex, moveWHADVPSQTsurgeon, t);
298+
}
299+
245300
/** The basic category of a label, without function tags such as -TMP */
246301
private static String category(Tree t) {
247302
String label = t.value();

‎src/edu/stanford/nlp/trees/UniversalEnglishGrammaticalRelations.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ private UniversalEnglishGrammaticalRelations() {}
177177

178178
/** An adverb which the head finder can make the predicate of a copula */
179179
private static final String COPULAR_ADVERB =
180-
"(/^(?:ADVP|PRT)/ < (/^(?:RB|RP|IN|NN|JJ)/ < " + UniversalSemanticHeadFinder.COPULAR_ADVERB_REGEX + "))";
180+
"(/^(?:ADVP|PRT)/ < (/^(?:RB|RP|IN|NN|JJ|WRB)/ < " + UniversalSemanticHeadFinder.COPULAR_ADVERB_REGEX + "))";
181181

182182
/**
183183
* The "copula" grammatical relation. A copula is the relation between

‎src/edu/stanford/nlp/trees/UniversalSemanticHeadFinder.java‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,15 +304,17 @@ protected int postOperationFix(int headIdx, Tree[] daughterTrees) {
304304

305305
/**
306306
* Adverbs of place and direction which can be the predicate of a
307-
* copula, as in "he is here" or "the game is over". Other adverbs
307+
* copula, as in "he is here" or "the game is over", and wh-adverbs
308+
* moved back after a copula, as in "I know where he is". Other adverbs
308309
* after a copula, as in "the goal is simply to win", are modifiers.
309310
* "ago" is left out, since "it was a year ago" is most often an
310311
* ellipsis, as in "higher than it was a year ago".
311312
*/
312313
static final String COPULAR_ADVERB_REGEX = "/^(?i:here|there|everywhere|anywhere|somewhere|nowhere|elsewhere|" +
313314
"above|below|ahead|behind|around|away|back|close|near|nearby|down|up|uphill|downhill|upstairs|downstairs|" +
314315
"in|inside|indoors|out|outside|outdoors|off|on|over|through|together|home|abroad|overseas|aboard|along|apart|aside|" +
315-
"east|west|north|south|forward|far|farther|further|underway)$/";
316+
"east|west|north|south|forward|far|farther|further|underway|" +
317+
"where|how|when|why|wherever|whenever)$/";
316318

317319
/**
318320
* A predicate adverb followed by a measure phrase or a degree adverb,
@@ -338,7 +340,7 @@ protected int postOperationFix(int headIdx, Tree[] daughterTrees) {
338340

339341
/** An ADVP or PRT which is the predicate of a copula with no other predicate */
340342
static final TregexPattern copularAdverbTregex =
341-
TregexPattern.compile("/^(?:ADVP|PRT)/ < (/^(?:RB|RP|IN|NN|JJ)/ < " + COPULAR_ADVERB_REGEX + ")");
343+
TregexPattern.compile("/^(?:ADVP|PRT)/ < (/^(?:RB|RP|IN|NN|JJ|WRB)/ < " + COPULAR_ADVERB_REGEX + ")");
342344

343345
/**
344346
* We use this to avoid making a -TMP or -ADV the head of a copular phrase.
@@ -385,6 +387,14 @@ protected Tree determineNonTrivialHead(Tree t, Tree parent) {
385387
if (matcher.matchesAt(t)) {
386388
return matcher.getNode("head");
387389
}
390+
// a wh-adverb moved back after a copula is the head of its ADVP
391+
// when it comes last, as in "know just where it was". In "how
392+
// terrific they are" or "how useful it is", the head is the
393+
// adjective, as for any other ADVP
394+
Tree lastKid = t.lastChild();
395+
if (lastKid.value().equals("WRB")) {
396+
return lastKid;
397+
}
388398
}
389399

390400
if (motherCat.equals("CONJP")) {

‎test/src/edu/stanford/nlp/trees/UniversalEnglishGrammaticalStructureTest.java‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,61 @@ public static Collection<Object[]> testCases() {
722722
"root(ROOT-0, investigating-4)\n" +
723723
"det(causes-6, the-5)\n" +
724724
"obj(investigating-4, causes-6)\n"},
725+
// a fronted wh-adverb is the predicate of an empty copula
726+
{TestType.BASIC,
727+
"(ROOT (SBARQ (WHADVP (WRB Where)) (SQ (VBZ is) (NP (DT the) (NN station))) (. ?)))",
728+
"root(ROOT-0, Where-1)\n" +
729+
"cop(Where-1, is-2)\n" +
730+
"det(station-4, the-3)\n" +
731+
"nsubj(Where-1, station-4)\n"},
732+
{TestType.BASIC,
733+
"(ROOT (S (NP (PRP I)) (VP (VBP know) (SBAR (WHADVP (WRB where)) (S (NP (PRP he)) (VP (VBZ is))))) (. .)))",
734+
"nsubj(know-2, I-1)\n" +
735+
"root(ROOT-0, know-2)\n" +
736+
"ccomp(know-2, where-3)\n" +
737+
"nsubj(where-3, he-4)\n" +
738+
"cop(where-3, is-5)\n"},
739+
{TestType.BASIC,
740+
"(ROOT (S (NP (PRP We)) (VP (VBD knew) (SBAR (WHADVP (RB just) (WRB where)) (S (NP (PRP it)) (VP (VBD was))))) (. .)))",
741+
"nsubj(knew-2, We-1)\n" +
742+
"root(ROOT-0, knew-2)\n" +
743+
"advmod(where-4, just-3)\n" +
744+
"ccomp(knew-2, where-4)\n" +
745+
"nsubj(where-4, it-5)\n" +
746+
"cop(where-4, was-6)\n"},
747+
// how with an adjective in a WHADVP has the adjective as the head
748+
{TestType.BASIC,
749+
"(ROOT (S (NP (PRP We)) (VP (VBP know) (SBAR (WHADVP (WRB how) (JJ useful)) (S (NP (PRP it)) (VP (VBZ is))))) (. .)))",
750+
"nsubj(know-2, We-1)\n" +
751+
"root(ROOT-0, know-2)\n" +
752+
"advmod(useful-4, how-3)\n" +
753+
"ccomp(know-2, useful-4)\n" +
754+
"nsubj(useful-4, it-5)\n" +
755+
"cop(useful-4, is-6)\n"},
756+
// an adjunct where clause keeps the copula as its head
757+
{TestType.BASIC,
758+
"(ROOT (S (NP (NNS Rates)) (VP (MD will) (VP (VB stay) (SBAR (WHADVP (WRB where)) (S (NP (PRP they)) (VP (VBP are)))))) (. .)))",
759+
"nsubj(stay-3, Rates-1)\n" +
760+
"aux(stay-3, will-2)\n" +
761+
"root(ROOT-0, stay-3)\n" +
762+
"advmod(are-6, where-4)\n" +
763+
"nsubj(are-6, they-5)\n" +
764+
"advcl(stay-3, are-6)\n"},
765+
// a wh-adverb with a verb or another predicate stays an adjunct
766+
{TestType.BASIC,
767+
"(ROOT (SBARQ (WHADVP (WRB Where)) (SQ (VBP are) (NP (PRP you)) (VP (VBG going))) (. ?)))",
768+
"advmod(going-4, Where-1)\n" +
769+
"aux(going-4, are-2)\n" +
770+
"nsubj(going-4, you-3)\n" +
771+
"root(ROOT-0, going-4)\n"},
772+
{TestType.BASIC,
773+
"(ROOT (S (NP (PRP I)) (VP (VBP know) (SBAR (WHADVP (WRB when)) (S (NP (PRP it)) (VP (VBD was) (ADJP (JJ late)))))) (. .)))",
774+
"nsubj(know-2, I-1)\n" +
775+
"root(ROOT-0, know-2)\n" +
776+
"advmod(late-6, when-3)\n" +
777+
"nsubj(late-6, it-4)\n" +
778+
"cop(late-6, was-5)\n" +
779+
"ccomp(know-2, late-6)\n"},
725780
{TestType.BASIC,
726781
"(ROOT (SBARQ (WHPP (IN In) (WHNP (WDT which) (NN city))) (SQ (VBP do) (NP (PRP you)) (VP (VB live))) (. ?)))",
727782
"case(city-3, In-1)\n" +

0 commit comments

Comments
 (0)