slopless 0.2.23 → 0.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rules/semantic-thinness/patterns/abstract-metaphor-claim.json +83 -1
- package/dist/rules/semantic-thinness/patterns/deictic-summary.json +31 -2
- package/dist/rules/semantic-thinness/patterns/empty-quantification.json +33 -0
- package/dist/rules/semantic-thinness/patterns/empty-scene-transition.json +2 -1
- package/dist/rules/semantic-thinness/private/concrete-guards.js +2 -0
- package/dist/rules/semantic-thinness/private/pattern-data-e.js +2 -0
- package/dist/rules/semantic-thinness/private/pattern-matcher.js +28 -7
- package/dist/rules/syntactic-patterns/closers/affirmation-closers.js +13 -3
- package/dist/rules/syntactic-patterns/contrast/contrastive-aphorism.js +2 -0
- package/dist/rules/syntactic-patterns/contrast/negation-reframe.js +1 -1
- package/dist/rules/syntactic-patterns/contrast/private/action-reframe-vocabulary.js +47 -0
- package/dist/rules/syntactic-patterns/contrast/private/audience-replacement.js +267 -0
- package/dist/rules/syntactic-patterns/contrast/private/copular-reframe.js +79 -0
- package/dist/rules/syntactic-patterns/contrast/private/evidence-limitation-pair.js +307 -0
- package/dist/rules/syntactic-patterns/contrast/private/inline-semicolon-reframe.js +50 -0
- package/dist/rules/syntactic-patterns/contrast/private/inline-short-negation.js +1 -0
- package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-matcher.js +78 -73
- package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-parts.js +99 -31
- package/dist/rules/syntactic-patterns/contrast/private/negation-vocabulary.js +27 -0
- package/dist/rules/syntactic-patterns/contrast/private/negative-consequence.js +301 -0
- package/dist/rules/syntactic-patterns/contrast/private/negative-slop-frames.js +155 -39
- package/dist/rules/syntactic-patterns/contrast/private/policy-object.js +55 -0
- package/dist/rules/syntactic-patterns/contrast/private/reframe-classification.js +214 -0
- package/dist/rules/syntactic-patterns/contrast/private/sequence-reframes.js +9 -0
- package/dist/rules/syntactic-patterns/contrast/private/temporal-reframe.js +318 -0
- package/dist/rules/syntactic-patterns/lead-ins/generic-signposting.js +96 -102
- package/dist/rules/syntactic-patterns/lead-ins/private/component-assignment-frame.js +239 -0
- package/dist/rules/syntactic-patterns/lead-ins/private/discourse-evaluation.js +150 -4
- package/dist/rules/syntactic-patterns/lead-ins/private/evaluative-colon-frame.js +166 -0
- package/dist/rules/syntactic-patterns/lead-ins/private/reaction-frame.js +29 -0
- package/dist/rules/syntactic-patterns/lead-ins/private/relative-discourse-frame.js +119 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { hasConcreteCorrectionEvidence } from "../../../../shared/matchers/concrete-evidence.js";
|
|
2
2
|
import { hasFactualConnectorAfterNegation } from "./negation-context-gates.js";
|
|
3
3
|
import { findCopularNegation, findNegationIndex, startsWithWords, words } from "./negation-reframe-parts.js";
|
|
4
|
+
export { matchesInlineSemicolonReframe } from "./inline-semicolon-reframe.js";
|
|
4
5
|
export function inlineNotJustCopularReframe(sentence, tokens) {
|
|
5
6
|
const negation = findCopularNegation(tokens);
|
|
6
7
|
const negationIndex = findNegationIndex(tokens);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DO_NEGATIONS, EXPLICIT_DO_AUXILIARIES,
|
|
1
|
+
import { ACTION_NEGATIONS, DO_NEGATIONS, EXPLICIT_DO_AUXILIARIES, FACTUAL_NEGATION_CONNECTORS, contrastPivotSubject, findCopularNegation, findNegationIndex, isCompleteSentence, skipOptionalAdverbs, startsWithSubjectOrPronoun, startsWithSubjectVerb, startsWithWords, stripLeadingPairPivot, validSubject, words } from "./negation-reframe-parts.js";
|
|
2
2
|
import { hasAbstractCommaContrast, hasAbstractNegationPayoff, hasFactualConnectorAfterNegation, hasMetaContext } from "./negation-context-gates.js";
|
|
3
3
|
import { hasInlineContrastConnectorAfterNegation } from "./inline-contrast-connector.js";
|
|
4
4
|
import { inlineNotBecauseReframe } from "./inline-not-because-reframe.js";
|
|
5
|
-
import { inlineNotJustCopularReframe, inlineShortNegatedBeat } from "./inline-short-negation.js";
|
|
6
|
-
import { hasNegativeSlopPairSignal, negativeSlopReframe } from "./negative-slop-frames.js";
|
|
5
|
+
import { matchesInlineSemicolonReframe, inlineNotJustCopularReframe, inlineShortNegatedBeat } from "./inline-short-negation.js";
|
|
6
|
+
import { hasNegativeSlopPairSignal, matchSequenceReframe, negatedActionPronounPayoff, negatedActionSetReplacement, negativeSlopReframe, progressiveVerbMirror, pronounCopularReframe, sameSubjectCopularReframe, shouldReportCopularReframe, startsWithNegatedPronounCopula } from "./negative-slop-frames.js";
|
|
7
7
|
import { makeMeaningReframe, meaningReframe } from "./meaning-reframe.js";
|
|
8
8
|
import { hasConcreteCorrectionEvidence } from "../../../../shared/matchers/concrete-evidence.js";
|
|
9
9
|
import { splitSentences } from "../../../../shared/text/sentences.js";
|
|
@@ -19,8 +19,25 @@ const INLINE_NON_CONTRAST_NEGATION_FOLLOWERS = new Set([
|
|
|
19
19
|
"only",
|
|
20
20
|
"too"
|
|
21
21
|
]);
|
|
22
|
+
const ACTION_PAIR_CONNECTORS = new Set([
|
|
23
|
+
...FACTUAL_NEGATION_CONNECTORS,
|
|
24
|
+
"after"
|
|
25
|
+
]);
|
|
26
|
+
function inlineSemicolonEvaluativeReframe(sentence) {
|
|
27
|
+
return matchesInlineSemicolonReframe(sentence.text)
|
|
28
|
+
? {
|
|
29
|
+
end: sentence.end,
|
|
30
|
+
start: sentence.start,
|
|
31
|
+
text: sentence.text
|
|
32
|
+
}
|
|
33
|
+
: undefined;
|
|
34
|
+
}
|
|
22
35
|
function inlineNegationContrast(sentence) {
|
|
23
36
|
const tokens = wordTokens(sentence.text);
|
|
37
|
+
const semicolonMatch = inlineSemicolonEvaluativeReframe(sentence);
|
|
38
|
+
if (semicolonMatch !== undefined) {
|
|
39
|
+
return semicolonMatch;
|
|
40
|
+
}
|
|
24
41
|
const negationIndex = findNegationIndex(tokens);
|
|
25
42
|
if (negationIndex === undefined) {
|
|
26
43
|
return undefined;
|
|
@@ -60,51 +77,6 @@ function inlineNegationContrast(sentence) {
|
|
|
60
77
|
}
|
|
61
78
|
: undefined;
|
|
62
79
|
}
|
|
63
|
-
function sameSubjectCopularReframe(aTokens, bTokens) {
|
|
64
|
-
const negation = findCopularNegation(aTokens);
|
|
65
|
-
if (negation === undefined || !validSubject(negation.subject)) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
return startsWithWords(bTokens, [
|
|
69
|
-
...negation.subject,
|
|
70
|
-
negation.affirmativeAux
|
|
71
|
-
]);
|
|
72
|
-
}
|
|
73
|
-
function pronounCopularReframe(aTokens, bTokens) {
|
|
74
|
-
const negation = findCopularNegation(aTokens);
|
|
75
|
-
return (negation !== undefined &&
|
|
76
|
-
validSubject(negation.subject) &&
|
|
77
|
-
!looksLikePassiveDefinition(aTokens, bTokens) &&
|
|
78
|
-
!startsWithNegatedPronounCopula(bTokens) &&
|
|
79
|
-
startsWithAny(bTokens, PRONOUN_REFRAME_STARTS));
|
|
80
|
-
}
|
|
81
|
-
function startsWithNegatedPronounCopula(tokens) {
|
|
82
|
-
for (const start of PRONOUN_REFRAME_STARTS) {
|
|
83
|
-
if (!startsWithWords(tokens, start)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const tokenWords = words(tokens);
|
|
87
|
-
const predicateIndex = skipOptionalAdverbs(tokenWords, start.length);
|
|
88
|
-
return NEGATION_WORDS.has(tokenWords[predicateIndex] ?? "");
|
|
89
|
-
}
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
function progressiveVerbMirror(aTokens, bTokens) {
|
|
93
|
-
const negation = findCopularNegation(aTokens);
|
|
94
|
-
if (negation === undefined || !validSubject(negation.subject)) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
const tokenWords = words(aTokens);
|
|
98
|
-
const predicateIndex = skipOptionalAdverbs(tokenWords, negation.negatedPredicateStart);
|
|
99
|
-
const verb = tokenWords[predicateIndex];
|
|
100
|
-
return (verb !== undefined &&
|
|
101
|
-
verb.endsWith("ing") &&
|
|
102
|
-
startsWithWords(bTokens, [
|
|
103
|
-
...negation.subject,
|
|
104
|
-
negation.affirmativeAux,
|
|
105
|
-
verb
|
|
106
|
-
]));
|
|
107
|
-
}
|
|
108
80
|
function needReframe(aTokens, bTokens) {
|
|
109
81
|
const tokenWords = words(aTokens);
|
|
110
82
|
for (let index = 0; index < tokenWords.length; index += 1) {
|
|
@@ -135,6 +107,11 @@ function startsWithNeedAffirmative(bTokens, subject) {
|
|
|
135
107
|
function actionVerbMirror(aTokens, bTokens) {
|
|
136
108
|
const tokenWords = words(aTokens);
|
|
137
109
|
const bContentTokens = stripLeadingPairPivot(bTokens);
|
|
110
|
+
const bWords = words(bContentTokens);
|
|
111
|
+
const firstConnectors = new Set(tokenWords.filter((word) => ACTION_PAIR_CONNECTORS.has(word)));
|
|
112
|
+
if (bWords.some((word) => ACTION_PAIR_CONNECTORS.has(word) && !firstConnectors.has(word))) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
138
115
|
for (let index = 0; index < tokenWords.length; index += 1) {
|
|
139
116
|
const current = tokenWords[index];
|
|
140
117
|
const next = tokenWords[index + 1];
|
|
@@ -142,7 +119,7 @@ function actionVerbMirror(aTokens, bTokens) {
|
|
|
142
119
|
if (!validSubject(subject)) {
|
|
143
120
|
continue;
|
|
144
121
|
}
|
|
145
|
-
if (
|
|
122
|
+
if (ACTION_NEGATIONS.has(current ?? "")) {
|
|
146
123
|
const verbIndex = skipOptionalAdverbs(tokenWords, index + 1);
|
|
147
124
|
const verb = tokenWords[verbIndex];
|
|
148
125
|
if (verb !== undefined &&
|
|
@@ -172,43 +149,36 @@ function startsWithExplicitReplacement(tokens) {
|
|
|
172
149
|
}
|
|
173
150
|
function hasPairNegationSignal(tokens) {
|
|
174
151
|
return (findNegationIndex(tokens) !== undefined ||
|
|
152
|
+
findCopularNegation(tokens) !== undefined ||
|
|
175
153
|
contrastPivotSubject(tokens) !== undefined ||
|
|
176
154
|
hasNegativeSlopPairSignal(tokens));
|
|
177
155
|
}
|
|
178
|
-
function looksLikePassiveDefinition(aTokens, bTokens) {
|
|
179
|
-
const aWords = words(aTokens);
|
|
180
|
-
const bWords = words(bTokens);
|
|
181
|
-
for (let index = 0; index < aWords.length - 2; index += 1) {
|
|
182
|
-
const current = aWords[index];
|
|
183
|
-
if ((current === "has" || current === "have" || current === "had") &&
|
|
184
|
-
aWords[index + 1] === "not" &&
|
|
185
|
-
aWords[index + 2] === "been" &&
|
|
186
|
-
startsWithWords(bTokens, ["it", "is"]) &&
|
|
187
|
-
PASSIVE_DEFINITION_VERBS.has(bWords[2] ?? "")) {
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
156
|
function sentencePairReframe(a, b) {
|
|
194
157
|
const aTokens = wordTokens(a.text);
|
|
195
158
|
const bTokens = wordTokens(b.text);
|
|
159
|
+
const pairText = `${a.text} ${b.text}`;
|
|
160
|
+
const hasNegatedActionSetReplacement = negatedActionSetReplacement(aTokens, bTokens);
|
|
161
|
+
const hasAllowedReplacementColon = b.text.trimEnd().endsWith(":") && hasNegatedActionSetReplacement;
|
|
196
162
|
if (!isCompleteSentence(a) ||
|
|
197
|
-
!isCompleteSentence(b) ||
|
|
163
|
+
(!isCompleteSentence(b) && !hasAllowedReplacementColon) ||
|
|
198
164
|
!hasPairNegationSignal(aTokens)) {
|
|
199
165
|
return undefined;
|
|
200
166
|
}
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
167
|
+
if ((shouldReportCopularReframe(aTokens, bTokens, pairText) &&
|
|
168
|
+
(sameSubjectCopularReframe(aTokens, bTokens) ||
|
|
169
|
+
pronounCopularReframe(aTokens, bTokens) ||
|
|
170
|
+
progressiveVerbMirror(aTokens, bTokens))) ||
|
|
204
171
|
(startsWithExplicitReplacement(bTokens) &&
|
|
205
|
-
|
|
172
|
+
shouldReportCopularReframe(aTokens, bTokens, pairText) &&
|
|
173
|
+
!hasConcreteCorrectionEvidence(pairText)) ||
|
|
206
174
|
meaningReframe(aTokens, bTokens) ||
|
|
207
175
|
makeMeaningReframe(aTokens, bTokens) ||
|
|
208
176
|
needReframe(aTokens, bTokens) ||
|
|
209
177
|
actionVerbMirror(aTokens, bTokens) ||
|
|
178
|
+
negatedActionPronounPayoff(aTokens, bTokens) ||
|
|
210
179
|
negativeSlopReframe(aTokens, bTokens) ||
|
|
211
|
-
|
|
180
|
+
(shouldReportCopularReframe(aTokens, bTokens, pairText) &&
|
|
181
|
+
explicitContrastPivotReframe(aTokens, bTokens))) {
|
|
212
182
|
return {
|
|
213
183
|
end: b.end,
|
|
214
184
|
start: a.start,
|
|
@@ -220,10 +190,26 @@ function sentencePairReframe(a, b) {
|
|
|
220
190
|
export function findSentenceNegationReframes(text) {
|
|
221
191
|
const sentences = splitSentences(text);
|
|
222
192
|
const matches = [];
|
|
193
|
+
const matchedRanges = new Set();
|
|
194
|
+
const addMatch = (match) => {
|
|
195
|
+
const range = `${match.start}:${match.end}`;
|
|
196
|
+
if (!matchedRanges.has(range)) {
|
|
197
|
+
matchedRanges.add(range);
|
|
198
|
+
matches.push(match);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
223
201
|
for (const sentence of sentences) {
|
|
224
202
|
const inlineMatch = inlineNegationContrast(sentence);
|
|
225
203
|
if (inlineMatch !== undefined) {
|
|
226
|
-
|
|
204
|
+
addMatch(inlineMatch);
|
|
205
|
+
}
|
|
206
|
+
const consequence = matchSequenceReframe(sentence.text, "");
|
|
207
|
+
if (consequence !== undefined) {
|
|
208
|
+
addMatch({
|
|
209
|
+
end: sentence.end,
|
|
210
|
+
start: sentence.start,
|
|
211
|
+
text: consequence
|
|
212
|
+
});
|
|
227
213
|
}
|
|
228
214
|
}
|
|
229
215
|
for (let index = 0; index < sentences.length - 1; index += 1) {
|
|
@@ -232,11 +218,30 @@ export function findSentenceNegationReframes(text) {
|
|
|
232
218
|
if (current === undefined || next === undefined) {
|
|
233
219
|
continue;
|
|
234
220
|
}
|
|
221
|
+
const third = sentences[index + 2];
|
|
222
|
+
const sequence = matchSequenceReframe(current.text, next.text, third?.text);
|
|
223
|
+
if (sequence !== undefined) {
|
|
224
|
+
const threeSentenceText = third === undefined
|
|
225
|
+
? undefined
|
|
226
|
+
: `${current.text} ${next.text} ${third.text}`;
|
|
227
|
+
addMatch({
|
|
228
|
+
end: sequence === current.text
|
|
229
|
+
? current.end
|
|
230
|
+
: sequence === threeSentenceText
|
|
231
|
+
? (third?.end ?? next.end)
|
|
232
|
+
: next.end,
|
|
233
|
+
start: current.start,
|
|
234
|
+
text: sequence
|
|
235
|
+
});
|
|
236
|
+
}
|
|
235
237
|
const pairMatch = sentencePairReframe(current, next);
|
|
236
238
|
if (pairMatch !== undefined) {
|
|
237
|
-
|
|
239
|
+
addMatch(pairMatch);
|
|
238
240
|
}
|
|
239
241
|
}
|
|
240
|
-
return matches
|
|
242
|
+
return matches.filter((match, index) => !matches.some((other, otherIndex) => otherIndex !== index &&
|
|
243
|
+
other.start <= match.start &&
|
|
244
|
+
other.end >= match.end &&
|
|
245
|
+
(other.start < match.start || other.end > match.end)));
|
|
241
246
|
}
|
|
242
247
|
//# sourceMappingURL=negation-reframe-matcher.js.map
|
|
@@ -1,20 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
"isn't",
|
|
4
|
-
"aren't",
|
|
5
|
-
"wasn't",
|
|
6
|
-
"weren't",
|
|
7
|
-
"don't",
|
|
8
|
-
"doesn't",
|
|
9
|
-
"didn't",
|
|
10
|
-
"can't",
|
|
11
|
-
"cannot",
|
|
12
|
-
"won't",
|
|
13
|
-
"wouldn't",
|
|
14
|
-
"shouldn't",
|
|
15
|
-
"couldn't"
|
|
16
|
-
]);
|
|
1
|
+
import { NEGATION_WORDS } from "./negation-vocabulary.js";
|
|
2
|
+
export { ACTION_NEGATIONS, DO_NEGATIONS, NEGATION_WORDS } from "./negation-vocabulary.js";
|
|
17
3
|
export const COPULAR_FORMS = new Map([
|
|
4
|
+
["am", "am"],
|
|
18
5
|
["are", "are"],
|
|
19
6
|
["aren't", "are"],
|
|
20
7
|
["is", "is"],
|
|
@@ -24,7 +11,6 @@ export const COPULAR_FORMS = new Map([
|
|
|
24
11
|
["were", "were"],
|
|
25
12
|
["weren't", "were"]
|
|
26
13
|
]);
|
|
27
|
-
export const DO_NEGATIONS = new Set(["don't", "doesn't", "didn't"]);
|
|
28
14
|
export const EXPLICIT_DO_AUXILIARIES = new Set(["do", "does", "did"]);
|
|
29
15
|
export const OPTIONAL_ADVERBS = new Set([
|
|
30
16
|
"actually",
|
|
@@ -38,13 +24,17 @@ export const FACTUAL_NEGATION_CONNECTORS = new Set([
|
|
|
38
24
|
"because",
|
|
39
25
|
"if",
|
|
40
26
|
"since",
|
|
27
|
+
"though",
|
|
41
28
|
"until",
|
|
42
29
|
"when",
|
|
43
30
|
"while"
|
|
44
31
|
]);
|
|
45
32
|
export const PRONOUN_REFRAME_STARTS = [
|
|
33
|
+
["i", "am"],
|
|
34
|
+
["he", "is"],
|
|
46
35
|
["it", "is"],
|
|
47
36
|
["it", "was"],
|
|
37
|
+
["she", "is"],
|
|
48
38
|
["this", "is"],
|
|
49
39
|
["that", "is"],
|
|
50
40
|
["they", "are"],
|
|
@@ -52,18 +42,26 @@ export const PRONOUN_REFRAME_STARTS = [
|
|
|
52
42
|
["you", "are"],
|
|
53
43
|
["we", "are"]
|
|
54
44
|
];
|
|
55
|
-
export const PASSIVE_DEFINITION_VERBS = new Set([
|
|
56
|
-
"associated",
|
|
57
|
-
"caused",
|
|
58
|
-
"classified",
|
|
59
|
-
"defined",
|
|
60
|
-
"described",
|
|
61
|
-
"linked",
|
|
62
|
-
"marked",
|
|
63
|
-
"produced"
|
|
64
|
-
]);
|
|
65
45
|
const IRREGULAR_PAST_TENSE = new Map([["go", "went"]]);
|
|
66
46
|
const CONTRAST_PIVOT_AFTER_NOT = new Set(["just", "merely", "only"]);
|
|
47
|
+
const NEGATIVE_COPULAR_PREDICATES = new Set([
|
|
48
|
+
"never",
|
|
49
|
+
"nobody",
|
|
50
|
+
"none",
|
|
51
|
+
"nothing",
|
|
52
|
+
"nowhere"
|
|
53
|
+
]);
|
|
54
|
+
const NEGATIVE_NOUN_DETERMINERS = new Set(["no"]);
|
|
55
|
+
const CONTRACTED_PRONOUN_COPULAS = new Map([
|
|
56
|
+
["i'm", { affirmativeAux: "am", subject: ["i"] }],
|
|
57
|
+
["he's", { affirmativeAux: "is", subject: ["he"] }],
|
|
58
|
+
["it's", { affirmativeAux: "is", subject: ["it"] }],
|
|
59
|
+
["she's", { affirmativeAux: "is", subject: ["she"] }],
|
|
60
|
+
["that's", { affirmativeAux: "is", subject: ["that"] }],
|
|
61
|
+
["they're", { affirmativeAux: "are", subject: ["they"] }],
|
|
62
|
+
["we're", { affirmativeAux: "are", subject: ["we"] }],
|
|
63
|
+
["you're", { affirmativeAux: "are", subject: ["you"] }]
|
|
64
|
+
]);
|
|
67
65
|
export function findNegationIndex(tokens) {
|
|
68
66
|
for (let index = 0; index < tokens.length; index += 1) {
|
|
69
67
|
const token = tokens[index];
|
|
@@ -88,7 +86,16 @@ function regularPastTense(verb) {
|
|
|
88
86
|
return verb.endsWith("e") ? `${verb}d` : `${verb}ed`;
|
|
89
87
|
}
|
|
90
88
|
function affirmativeVerbForms(verb) {
|
|
91
|
-
|
|
89
|
+
const thirdPerson = verb.endsWith("y")
|
|
90
|
+
? `${verb.slice(0, -1)}ies`
|
|
91
|
+
: ["s", "x", "z", "ch", "sh", "o"].some((ending) => verb.endsWith(ending))
|
|
92
|
+
? `${verb}es`
|
|
93
|
+
: `${verb}s`;
|
|
94
|
+
return [
|
|
95
|
+
verb,
|
|
96
|
+
thirdPerson,
|
|
97
|
+
IRREGULAR_PAST_TENSE.get(verb) ?? regularPastTense(verb)
|
|
98
|
+
];
|
|
92
99
|
}
|
|
93
100
|
export function stripLeadingPairPivot(tokens) {
|
|
94
101
|
return tokens[0]?.normalized === "instead" ? tokens.slice(1) : tokens;
|
|
@@ -108,9 +115,6 @@ export function startsWithSubjectVerb(tokens, subject, verb) {
|
|
|
108
115
|
export function words(tokens) {
|
|
109
116
|
return tokens.map((token) => token.normalized);
|
|
110
117
|
}
|
|
111
|
-
export function hasAnyWord(tokens, candidates) {
|
|
112
|
-
return tokens.some((token) => candidates.has(token));
|
|
113
|
-
}
|
|
114
118
|
export function skipOptionalAdverbs(tokens, start) {
|
|
115
119
|
let index = start;
|
|
116
120
|
while (OPTIONAL_ADVERBS.has(tokens[index] ?? "")) {
|
|
@@ -121,6 +125,39 @@ export function skipOptionalAdverbs(tokens, start) {
|
|
|
121
125
|
export function startsWithAny(tokens, starts) {
|
|
122
126
|
return starts.some((start) => startsWithWords(tokens, start));
|
|
123
127
|
}
|
|
128
|
+
export function pronounCopulaStart(tokens) {
|
|
129
|
+
const firstToken = tokens[0];
|
|
130
|
+
const contracted = firstToken === undefined
|
|
131
|
+
? undefined
|
|
132
|
+
: CONTRACTED_PRONOUN_COPULAS.get(firstToken.normalized);
|
|
133
|
+
if (contracted !== undefined) {
|
|
134
|
+
return { ...contracted, predicateStart: 1 };
|
|
135
|
+
}
|
|
136
|
+
for (const start of PRONOUN_REFRAME_STARTS) {
|
|
137
|
+
if (startsWithWords(tokens, start)) {
|
|
138
|
+
return {
|
|
139
|
+
affirmativeAux: start[1],
|
|
140
|
+
predicateStart: start.length,
|
|
141
|
+
subject: [start[0]]
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
export function startsWithPronounCopula(tokens) {
|
|
148
|
+
return pronounCopulaStart(tokens) !== undefined;
|
|
149
|
+
}
|
|
150
|
+
export function startsWithSubjectCopula(tokens, subject, affirmativeAux) {
|
|
151
|
+
if (startsWithWords(tokens, [...subject, affirmativeAux])) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
const contracted = CONTRACTED_PRONOUN_COPULAS.get(tokens[0]?.normalized ?? "");
|
|
155
|
+
if (contracted?.affirmativeAux !== affirmativeAux) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
return (subject.length === contracted.subject.length &&
|
|
159
|
+
subject.every((word, index) => word === contracted.subject[index]));
|
|
160
|
+
}
|
|
124
161
|
export function isCompleteSentence(sentence) {
|
|
125
162
|
const trimmed = sentence.text.trim();
|
|
126
163
|
const last = trimmed.at(-1);
|
|
@@ -140,6 +177,18 @@ export function hasCommaBeforeNegation(text, negationStart) {
|
|
|
140
177
|
}
|
|
141
178
|
export function findCopularNegation(tokens) {
|
|
142
179
|
const tokenWords = words(tokens);
|
|
180
|
+
const contracted = CONTRACTED_PRONOUN_COPULAS.get(tokenWords[0] ?? "");
|
|
181
|
+
const contractedNegator = tokenWords[1];
|
|
182
|
+
if (contracted !== undefined &&
|
|
183
|
+
contractedNegator !== undefined &&
|
|
184
|
+
(contractedNegator === "not" ||
|
|
185
|
+
NEGATIVE_COPULAR_PREDICATES.has(contractedNegator) ||
|
|
186
|
+
NEGATIVE_NOUN_DETERMINERS.has(contractedNegator))) {
|
|
187
|
+
return {
|
|
188
|
+
...contracted,
|
|
189
|
+
negatedPredicateStart: contractedNegator === "not" ? 2 : 1
|
|
190
|
+
};
|
|
191
|
+
}
|
|
143
192
|
for (let index = 0; index < tokenWords.length; index += 1) {
|
|
144
193
|
const current = tokenWords[index];
|
|
145
194
|
const next = tokenWords[index + 1];
|
|
@@ -161,6 +210,25 @@ export function findCopularNegation(tokens) {
|
|
|
161
210
|
subject: tokenWords.slice(0, index)
|
|
162
211
|
};
|
|
163
212
|
}
|
|
213
|
+
if (explicitAux !== undefined &&
|
|
214
|
+
next !== undefined &&
|
|
215
|
+
NEGATIVE_NOUN_DETERMINERS.has(next) &&
|
|
216
|
+
tokenWords[index + 2] !== "longer") {
|
|
217
|
+
return {
|
|
218
|
+
affirmativeAux: explicitAux,
|
|
219
|
+
negatedPredicateStart: index + 1,
|
|
220
|
+
subject: tokenWords.slice(0, index)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (explicitAux !== undefined &&
|
|
224
|
+
next !== undefined &&
|
|
225
|
+
NEGATIVE_COPULAR_PREDICATES.has(next)) {
|
|
226
|
+
return {
|
|
227
|
+
affirmativeAux: explicitAux,
|
|
228
|
+
negatedPredicateStart: index + 1,
|
|
229
|
+
subject: tokenWords.slice(0, index)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
164
232
|
}
|
|
165
233
|
return undefined;
|
|
166
234
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const DO_NEGATIONS = new Set(["don't", "doesn't", "didn't"]);
|
|
2
|
+
export const ACTION_NEGATIONS = new Set([
|
|
3
|
+
...DO_NEGATIONS,
|
|
4
|
+
"can't",
|
|
5
|
+
"couldn't",
|
|
6
|
+
"hadn't",
|
|
7
|
+
"hasn't",
|
|
8
|
+
"haven't",
|
|
9
|
+
"mightn't",
|
|
10
|
+
"mustn't",
|
|
11
|
+
"needn't",
|
|
12
|
+
"shan't",
|
|
13
|
+
"shouldn't",
|
|
14
|
+
"won't",
|
|
15
|
+
"wouldn't"
|
|
16
|
+
]);
|
|
17
|
+
export const NEGATION_WORDS = new Set([
|
|
18
|
+
"not",
|
|
19
|
+
"never",
|
|
20
|
+
"isn't",
|
|
21
|
+
"aren't",
|
|
22
|
+
"wasn't",
|
|
23
|
+
"weren't",
|
|
24
|
+
...ACTION_NEGATIONS,
|
|
25
|
+
"cannot"
|
|
26
|
+
]);
|
|
27
|
+
//# sourceMappingURL=negation-vocabulary.js.map
|