slopless 0.2.24 → 0.2.26

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.
Files changed (29) hide show
  1. package/README.md +9 -9
  2. package/dist/rules/semantic-thinness/patterns/abstract-metaphor-claim.json +83 -1
  3. package/dist/rules/semantic-thinness/patterns/deictic-summary.json +31 -2
  4. package/dist/rules/semantic-thinness/patterns/empty-scene-transition.json +2 -1
  5. package/dist/rules/semantic-thinness/private/concrete-guards.js +2 -0
  6. package/dist/rules/semantic-thinness/private/pattern-matcher.js +22 -6
  7. package/dist/rules/syntactic-patterns/contrast/contrastive-aphorism.js +2 -0
  8. package/dist/rules/syntactic-patterns/contrast/negation-reframe.js +1 -1
  9. package/dist/rules/syntactic-patterns/contrast/private/action-reframe-vocabulary.js +47 -0
  10. package/dist/rules/syntactic-patterns/contrast/private/audience-replacement.js +267 -0
  11. package/dist/rules/syntactic-patterns/contrast/private/copular-reframe.js +39 -1
  12. package/dist/rules/syntactic-patterns/contrast/private/evidence-limitation-pair.js +307 -0
  13. package/dist/rules/syntactic-patterns/contrast/private/inline-semicolon-reframe.js +50 -0
  14. package/dist/rules/syntactic-patterns/contrast/private/inline-short-negation.js +1 -0
  15. package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-matcher.js +64 -7
  16. package/dist/rules/syntactic-patterns/contrast/private/negation-reframe-parts.js +37 -25
  17. package/dist/rules/syntactic-patterns/contrast/private/negation-vocabulary.js +27 -0
  18. package/dist/rules/syntactic-patterns/contrast/private/negative-consequence.js +301 -0
  19. package/dist/rules/syntactic-patterns/contrast/private/negative-slop-frames.js +51 -38
  20. package/dist/rules/syntactic-patterns/contrast/private/reframe-classification.js +21 -0
  21. package/dist/rules/syntactic-patterns/contrast/private/sequence-reframes.js +9 -0
  22. package/dist/rules/syntactic-patterns/contrast/private/temporal-reframe.js +318 -0
  23. package/dist/rules/syntactic-patterns/lead-ins/generic-signposting.js +85 -22
  24. package/dist/rules/syntactic-patterns/lead-ins/private/component-assignment-frame.js +239 -0
  25. package/dist/rules/syntactic-patterns/lead-ins/private/discourse-evaluation.js +1 -0
  26. package/dist/rules/syntactic-patterns/lead-ins/private/evaluative-colon-frame.js +166 -0
  27. package/dist/rules/syntactic-patterns/lead-ins/private/reaction-frame.js +29 -0
  28. package/dist/rules/syntactic-patterns/lead-ins/private/relative-discourse-frame.js +119 -0
  29. package/package.json +5 -5
@@ -0,0 +1,301 @@
1
+ import { wordTokens } from "../../../../shared/text/tokens.js";
2
+ const OMISSION_VERBS = new Set(["drop", "leave", "omit", "remove", "skip"]);
3
+ const INFORMATION_ARTIFACTS = new Set([
4
+ "attribute",
5
+ "catalog",
6
+ "content",
7
+ "description",
8
+ "document",
9
+ "evidence",
10
+ "feed",
11
+ "field",
12
+ "listing",
13
+ "metadata",
14
+ "page",
15
+ "profile",
16
+ "record",
17
+ "report"
18
+ ]);
19
+ const CONSEQUENCE_VERBS = new Set([
20
+ "fail",
21
+ "fails",
22
+ "failed",
23
+ "lose",
24
+ "loses",
25
+ "lost",
26
+ "miss",
27
+ "misses",
28
+ "missed"
29
+ ]);
30
+ const NEGATIVE_AUXILIARIES = new Set([
31
+ "aren't",
32
+ "cannot",
33
+ "can't",
34
+ "didn't",
35
+ "doesn't",
36
+ "don't",
37
+ "hadn't",
38
+ "hasn't",
39
+ "haven't",
40
+ "isn't",
41
+ "not",
42
+ "wasn't",
43
+ "weren't",
44
+ "won't",
45
+ "wouldn't"
46
+ ]);
47
+ const ABSTRACT_OUTCOMES = new Set([
48
+ "comparison",
49
+ "consideration",
50
+ "decision",
51
+ "discoverability",
52
+ "distribution",
53
+ "market",
54
+ "ranking",
55
+ "recommendation",
56
+ "results",
57
+ "selection",
58
+ "visibility"
59
+ ]);
60
+ const ENTRY_VERBS = new Set([
61
+ "appear",
62
+ "appears",
63
+ "compare",
64
+ "compares",
65
+ "enter",
66
+ "enters",
67
+ "include",
68
+ "includes",
69
+ "qualify",
70
+ "qualifies",
71
+ "rank",
72
+ "ranks",
73
+ "reach",
74
+ "reaches",
75
+ "recommend",
76
+ "recommends",
77
+ "select",
78
+ "selects"
79
+ ]);
80
+ const INFORMATION_VERBS = new Set([
81
+ "describe",
82
+ "described",
83
+ "describes",
84
+ "explain",
85
+ "explained",
86
+ "explains",
87
+ "include",
88
+ "included",
89
+ "includes",
90
+ "list",
91
+ "listed",
92
+ "lists",
93
+ "mention",
94
+ "mentioned",
95
+ "mentions",
96
+ "say",
97
+ "said",
98
+ "says",
99
+ "show",
100
+ "showed",
101
+ "shown",
102
+ "shows",
103
+ "state",
104
+ "stated",
105
+ "states"
106
+ ]);
107
+ const SELECTION_PREDICATES = new Map([
108
+ ["appeared", "appear"],
109
+ ["compared", "compare"],
110
+ ["considered", "consider"],
111
+ ["included", "include"],
112
+ ["qualified", "qualify"],
113
+ ["ranked", "rank"],
114
+ ["reached", "reach"],
115
+ ["recommended", "recommend"],
116
+ ["rejected", "reject"],
117
+ ["selected", "select"],
118
+ ["shown", "show"]
119
+ ]);
120
+ const CAUSAL_CONNECTORS = new Set([
121
+ "after",
122
+ "because",
123
+ "if",
124
+ "since",
125
+ "therefore",
126
+ "until",
127
+ "when",
128
+ "while"
129
+ ]);
130
+ const TECHNICAL_OR_SAFETY_WORDS = new Set([
131
+ "backup",
132
+ "bytes",
133
+ "checksum",
134
+ "citation",
135
+ "citations",
136
+ "code",
137
+ "database",
138
+ "debug",
139
+ "debugging",
140
+ "disk",
141
+ "error",
142
+ "measurement",
143
+ "measurements",
144
+ "parser",
145
+ "pressure",
146
+ "psi",
147
+ "records",
148
+ "schema",
149
+ "semicolon",
150
+ "stack",
151
+ "tank",
152
+ "trace",
153
+ "valve",
154
+ "voltage"
155
+ ]);
156
+ function words(text) {
157
+ return wordTokens(text).map((token) => token.normalized);
158
+ }
159
+ function hasQuotedText(text) {
160
+ return [...text].some((character) => character === '"' ||
161
+ character === "\u201c" ||
162
+ character === "\u201d" ||
163
+ character === "`");
164
+ }
165
+ function hasDigit(word) {
166
+ return [...word].some((character) => character >= "0" && character <= "9");
167
+ }
168
+ function hasDash(text) {
169
+ for (let index = 0; index < text.length; index += 1) {
170
+ const character = text[index];
171
+ if (character === "\u2013" || character === "\u2014") {
172
+ return true;
173
+ }
174
+ if (character === "-" &&
175
+ (text[index - 1]?.trim() === "" || text[index + 1]?.trim() === "")) {
176
+ return true;
177
+ }
178
+ }
179
+ return false;
180
+ }
181
+ function hasRejectedContext(text, sentenceWords) {
182
+ return (hasQuotedText(text) ||
183
+ sentenceWords.some((word) => CAUSAL_CONNECTORS.has(word) ||
184
+ TECHNICAL_OR_SAFETY_WORDS.has(word) ||
185
+ hasDigit(word)));
186
+ }
187
+ function containsAny(sentenceWords, candidates) {
188
+ return sentenceWords.some((word) => candidates.has(word));
189
+ }
190
+ function omissionConsequence(first, second) {
191
+ const firstWords = words(first);
192
+ const secondWords = words(second);
193
+ const comma = first.indexOf(",");
194
+ const startsWithOmission = OMISSION_VERBS.has(firstWords[0] ?? "") &&
195
+ containsAny(words(first.slice(0, comma < 0 ? first.length : comma)), INFORMATION_ARTIFACTS);
196
+ const namesMissingInformation = firstWords.some((word, index) => word === "no" &&
197
+ firstWords
198
+ .slice(index + 1, index + 4)
199
+ .some((candidate) => INFORMATION_ARTIFACTS.has(candidate)));
200
+ if (firstWords.length > 32 ||
201
+ secondWords.length > 16 ||
202
+ (!startsWithOmission && !namesMissingInformation) ||
203
+ hasRejectedContext(first, firstWords) ||
204
+ hasRejectedContext(second, secondWords)) {
205
+ return false;
206
+ }
207
+ const consequenceStart = firstWords.findIndex((word, index) => index > 0 && CONSEQUENCE_VERBS.has(word));
208
+ const hasNegativeConsequence = consequenceStart > 0 &&
209
+ firstWords
210
+ .slice(Math.max(0, consequenceStart - 3), consequenceStart)
211
+ .some((word) => NEGATIVE_AUXILIARIES.has(word));
212
+ const neverIndex = secondWords.indexOf("never");
213
+ const entryVerb = neverIndex < 0
214
+ ? undefined
215
+ : secondWords.slice(neverIndex + 1).find((word) => ENTRY_VERBS.has(word));
216
+ const combined = [...firstWords, ...secondWords];
217
+ return (hasNegativeConsequence &&
218
+ neverIndex > 0 &&
219
+ entryVerb !== undefined &&
220
+ containsAny(combined, ABSTRACT_OUTCOMES));
221
+ }
222
+ function selectionOccurrences(sentenceWords) {
223
+ const occurrences = [];
224
+ sentenceWords.forEach((word, index) => {
225
+ const canonical = SELECTION_PREDICATES.get(word);
226
+ if (canonical !== undefined) {
227
+ occurrences.push({ canonical, index });
228
+ }
229
+ });
230
+ return occurrences;
231
+ }
232
+ function hasNegativeMarkerBefore(sentenceWords, index, marker) {
233
+ const previous = sentenceWords[index - 1];
234
+ if (previous === marker) {
235
+ return true;
236
+ }
237
+ const clauseStart = sentenceWords.lastIndexOf(marker, index - 1);
238
+ return clauseStart >= 0 && index - clauseStart <= 3;
239
+ }
240
+ function inlineSelectionClaim(text, allowStackedNever) {
241
+ const sentenceWords = words(text);
242
+ if (sentenceWords.length > 14 || hasRejectedContext(text, sentenceWords)) {
243
+ return false;
244
+ }
245
+ const occurrences = selectionOccurrences(sentenceWords);
246
+ if (occurrences.length < 2) {
247
+ return false;
248
+ }
249
+ const repeatedAcrossNegation = occurrences.some((firstOccurrence, index) => occurrences
250
+ .slice(index + 1)
251
+ .some((secondOccurrence) => firstOccurrence.canonical === secondOccurrence.canonical &&
252
+ hasNegativeMarkerBefore(sentenceWords, firstOccurrence.index, "not") &&
253
+ hasNegativeMarkerBefore(sentenceWords, secondOccurrence.index, "never")));
254
+ const stackedNeverPredicates = occurrences.filter((occurrence) => hasNegativeMarkerBefore(sentenceWords, occurrence.index, "never")).length >= 2;
255
+ return ((hasDash(text) && repeatedAcrossNegation) ||
256
+ (allowStackedNever && stackedNeverPredicates));
257
+ }
258
+ function artifactInformationClaim(text) {
259
+ const sentenceWords = words(text);
260
+ if (sentenceWords.length > 18 || hasRejectedContext(text, sentenceWords)) {
261
+ return false;
262
+ }
263
+ const neverIndex = sentenceWords.indexOf("never");
264
+ if (neverIndex < 1 || neverIndex > 5) {
265
+ return false;
266
+ }
267
+ const subject = sentenceWords.slice(0, neverIndex);
268
+ return (containsAny(subject, INFORMATION_ARTIFACTS) &&
269
+ INFORMATION_VERBS.has(sentenceWords[neverIndex + 1] ?? "") &&
270
+ sentenceWords.length > neverIndex + 2);
271
+ }
272
+ function shortOutcomeFragment(text) {
273
+ const sentenceWords = words(text);
274
+ return (sentenceWords.length > 0 &&
275
+ sentenceWords.length <= 3 &&
276
+ !hasRejectedContext(text, sentenceWords) &&
277
+ !sentenceWords.includes("never"));
278
+ }
279
+ function artifactSelectionSequence(first, second, third) {
280
+ if (!artifactInformationClaim(first)) {
281
+ return undefined;
282
+ }
283
+ if (inlineSelectionClaim(second, true)) {
284
+ return `${first} ${second}`;
285
+ }
286
+ return third !== undefined &&
287
+ shortOutcomeFragment(second) &&
288
+ inlineSelectionClaim(third, true)
289
+ ? `${first} ${second} ${third}`
290
+ : undefined;
291
+ }
292
+ export function matchNegativeConsequence(first, second, third) {
293
+ if (second.length === 0) {
294
+ return inlineSelectionClaim(first, false) ? first : undefined;
295
+ }
296
+ if (omissionConsequence(first, second)) {
297
+ return `${first} ${second}`;
298
+ }
299
+ return artifactSelectionSequence(first, second, third);
300
+ }
301
+ //# sourceMappingURL=negative-consequence.js.map
@@ -1,36 +1,11 @@
1
1
  import { hasFactualConnectorAfterNegation } from "./negation-context-gates.js";
2
2
  import { hasAbstractPolicyDirectObject } from "./policy-object.js";
3
+ import { negatedProgressiveNeverPayoff } from "./copular-reframe.js";
4
+ import { GENERIC_ACTION_VERBS } from "./action-reframe-vocabulary.js";
3
5
  export { shouldReportCopularReframe } from "./reframe-classification.js";
4
6
  export { progressiveVerbMirror, pronounCopularReframe, sameSubjectCopularReframe, startsWithNegatedPronounCopula } from "./copular-reframe.js";
5
- import { DO_NEGATIONS, EXPLICIT_DO_AUXILIARIES, FACTUAL_NEGATION_CONNECTORS, PRONOUN_REFRAME_STARTS, hasAnyWord, skipOptionalAdverbs, startsWithAny, startsWithSubjectOrPronoun, startsWithWords, stripLeadingPairPivot, validSubject, words } from "./negation-reframe-parts.js";
6
- const GENERIC_ACTION_VERBS = new Set([
7
- "asked",
8
- "built",
9
- "called",
10
- "crossed",
11
- "found",
12
- "gave",
13
- "left",
14
- "looked",
15
- "made",
16
- "moved",
17
- "opened",
18
- "pointed",
19
- "raised",
20
- "reached",
21
- "pulled",
22
- "kept",
23
- "said",
24
- "sat",
25
- "shifted",
26
- "stood",
27
- "started",
28
- "stopped",
29
- "took",
30
- "turned",
31
- "walked",
32
- "went"
33
- ]);
7
+ export { matchSequenceReframe } from "./sequence-reframes.js";
8
+ import { ACTION_NEGATIONS, EXPLICIT_DO_AUXILIARIES, FACTUAL_NEGATION_CONNECTORS, PRONOUN_REFRAME_STARTS, findCopularNegation, pronounCopulaStart, skipOptionalAdverbs, startsWithAny, startsWithSubjectOrPronoun, startsWithWords, stripLeadingPairPivot, validSubject, words } from "./negation-reframe-parts.js";
34
9
  const NEGATED_ACTION_REFRAME_VERBS = new Set([
35
10
  "avoid",
36
11
  "change",
@@ -48,6 +23,14 @@ const NEGATED_ACTION_REFRAME_VERBS = new Set([
48
23
  "solve"
49
24
  ]);
50
25
  const REPLACEMENT_SUBJECT_PRONOUNS = new Set(["he", "she"]);
26
+ const EMBEDDED_CLAUSE_VERBS = new Set([
27
+ "believed",
28
+ "explained",
29
+ "reckoned",
30
+ "reported",
31
+ "said",
32
+ "thought"
33
+ ]);
51
34
  const PRONOUN_PAYOFF_VERBS = new Set([
52
35
  "becomes",
53
36
  "creates",
@@ -65,6 +48,10 @@ const PRONOUN_PAYOFF_VERBS = new Set([
65
48
  "turns"
66
49
  ]);
67
50
  const PRONOUN_SUBJECTS = new Set(["it", "this", "that", "they", "we", "you"]);
51
+ const ACTION_REPLACEMENT_CONNECTORS = new Set([
52
+ ...FACTUAL_NEGATION_CONNECTORS,
53
+ "after"
54
+ ]);
68
55
  function startsWithPassiveCopula(tokens) {
69
56
  const tokenWords = words(tokens);
70
57
  const predicateIndex = startsWithAny(tokens, PRONOUN_REFRAME_STARTS)
@@ -74,6 +61,13 @@ function startsWithPassiveCopula(tokens) {
74
61
  }
75
62
  function noLongerCopularReframe(aTokens, bTokens) {
76
63
  const tokenWords = words(aTokens);
64
+ const contractedStart = pronounCopulaStart(aTokens);
65
+ if (contractedStart !== undefined &&
66
+ tokenWords[contractedStart.predicateStart] === "no" &&
67
+ tokenWords[contractedStart.predicateStart + 1] === "longer") {
68
+ return (startsWithSubjectOrPronoun(bTokens, contractedStart.subject) &&
69
+ !startsWithPassiveCopula(bTokens));
70
+ }
77
71
  for (let index = 0; index < tokenWords.length - 2; index += 1) {
78
72
  const current = tokenWords[index];
79
73
  const subject = tokenWords.slice(0, index);
@@ -103,18 +97,31 @@ function fragmentDefinitionReframe(aTokens, bTokens) {
103
97
  }
104
98
  function negatedActionSubject(tokens) {
105
99
  const tokenWords = words(tokens);
100
+ const copularNegation = findCopularNegation(tokens);
101
+ if (copularNegation !== undefined &&
102
+ validSubject(copularNegation.subject) &&
103
+ tokenWords[copularNegation.negatedPredicateStart]?.endsWith("ing") === true) {
104
+ return copularNegation.subject;
105
+ }
106
106
  for (let index = 0; index < tokenWords.length; index += 1) {
107
107
  const current = tokenWords[index];
108
108
  const next = tokenWords[index + 1];
109
109
  const subject = tokenWords.slice(0, index);
110
- if (!validSubject(subject)) {
110
+ if (!validSubject(subject) ||
111
+ subject.some((word) => EMBEDDED_CLAUSE_VERBS.has(word))) {
111
112
  continue;
112
113
  }
113
- if (DO_NEGATIONS.has(current ?? "")) {
114
- return subject;
114
+ if (ACTION_NEGATIONS.has(current ?? "")) {
115
+ return tokenWords[index + 1] !== undefined &&
116
+ !tokenWords.slice(index + 1).includes("and")
117
+ ? subject
118
+ : undefined;
115
119
  }
116
120
  if (EXPLICIT_DO_AUXILIARIES.has(current ?? "") && next === "not") {
117
- return subject;
121
+ return tokenWords[index + 2] !== undefined &&
122
+ !tokenWords.slice(index + 2).includes("and")
123
+ ? subject
124
+ : undefined;
118
125
  }
119
126
  }
120
127
  return undefined;
@@ -139,10 +146,14 @@ export function negatedActionReplacement(aTokens, bTokens) {
139
146
  }
140
147
  const bContentTokens = stripLeadingPairPivot(bTokens);
141
148
  const bWords = words(bContentTokens);
142
- const genericVerbIndex = skipOptionalAdverbs(bWords, subject.length);
149
+ const subjectLength = constrainedSetSubjectLength(bContentTokens, subject);
150
+ const genericVerbIndex = subjectLength === undefined
151
+ ? undefined
152
+ : skipOptionalAdverbs(bWords, subjectLength);
143
153
  return (tokenWords.length <= 14 &&
144
- !hasAnyWord(tokenWords, FACTUAL_NEGATION_CONNECTORS) &&
145
- ((startsWithSubjectOrPronoun(bContentTokens, subject) &&
154
+ !tokenWords.some((word) => FACTUAL_NEGATION_CONNECTORS.has(word)) &&
155
+ !bWords.some((word) => ACTION_REPLACEMENT_CONNECTORS.has(word)) &&
156
+ ((genericVerbIndex !== undefined &&
146
157
  GENERIC_ACTION_VERBS.has(bWords[genericVerbIndex] ?? "")) ||
147
158
  negatedActionSetReplacement(aTokens, bTokens)));
148
159
  }
@@ -159,7 +170,8 @@ export function negatedActionSetReplacement(aTokens, bTokens) {
159
170
  ? undefined
160
171
  : skipOptionalAdverbs(bWords, subjectLength);
161
172
  return (tokenWords.length <= 14 &&
162
- !hasAnyWord(tokenWords, FACTUAL_NEGATION_CONNECTORS) &&
173
+ !tokenWords.some((word) => FACTUAL_NEGATION_CONNECTORS.has(word)) &&
174
+ !bWords.some((word) => ACTION_REPLACEMENT_CONNECTORS.has(word)) &&
163
175
  verbIndex !== undefined &&
164
176
  hasAbstractPolicyDirectObject(bWords, verbIndex));
165
177
  }
@@ -221,7 +233,7 @@ function hasNegatedReframeVerb(tokens, tokenWords, index) {
221
233
  if (!validSubject(subject)) {
222
234
  return false;
223
235
  }
224
- const negationIndex = DO_NEGATIONS.has(current ?? "")
236
+ const negationIndex = ACTION_NEGATIONS.has(current ?? "")
225
237
  ? index
226
238
  : EXPLICIT_DO_AUXILIARIES.has(current ?? "") && next === "not"
227
239
  ? index + 1
@@ -235,6 +247,7 @@ function hasNegatedReframeVerb(tokens, tokenWords, index) {
235
247
  }
236
248
  export function negativeSlopReframe(aTokens, bTokens) {
237
249
  return (noLongerCopularReframe(aTokens, bTokens) ||
250
+ negatedProgressiveNeverPayoff(aTokens, bTokens) ||
238
251
  fragmentDefinitionReframe(aTokens, bTokens) ||
239
252
  negatedActionReplacement(aTokens, bTokens) ||
240
253
  notBecauseReframe(aTokens, bTokens) ||
@@ -80,6 +80,21 @@ const QUANTITY_WORDS = new Set([
80
80
  "nine",
81
81
  "ten"
82
82
  ]);
83
+ const TIME_DETAIL_WORDS = new Set([
84
+ "today",
85
+ "tomorrow",
86
+ "tonight",
87
+ "yesterday",
88
+ "noon",
89
+ "midnight",
90
+ "monday",
91
+ "tuesday",
92
+ "wednesday",
93
+ "thursday",
94
+ "friday",
95
+ "saturday",
96
+ "sunday"
97
+ ]);
83
98
  function digitTokenCount(tokens) {
84
99
  return tokens.filter((token) => [...token.text].some((character) => character >= "0" && character <= "9")).length;
85
100
  }
@@ -158,6 +173,11 @@ function hasCausalPassiveExplanation(aTokens, bTokens) {
158
173
  return (words(aTokens).some((word) => FACTUAL_NEGATION_CONNECTORS.has(word)) &&
159
174
  hasPassiveExplanation(bTokens));
160
175
  }
176
+ function hasCausalConcreteCorrection(aTokens, bTokens) {
177
+ return (words(aTokens).some((word) => FACTUAL_NEGATION_CONNECTORS.has(word)) &&
178
+ (quantityTokenCount(bTokens) > 0 ||
179
+ words(bTokens).some((word) => TIME_DETAIL_WORDS.has(word))));
180
+ }
161
181
  function hasDistinctCauseExplanation(aTokens, bTokens) {
162
182
  const aWords = words(aTokens);
163
183
  const bWords = words(stripLeadingPairPivot(bTokens));
@@ -170,6 +190,7 @@ function hasConcreteExplanatoryEvidence(aTokens, bTokens, pairText) {
170
190
  hasPurposeOrProvenance(tokenWords) ||
171
191
  hasDistinctCauseExplanation(aTokens, bTokens) ||
172
192
  hasCausalPassiveExplanation(aTokens, bTokens) ||
193
+ hasCausalConcreteCorrection(aTokens, bTokens) ||
173
194
  (hasReferenceEvidence(aTokens, bTokens, pairText) &&
174
195
  hasPassiveExplanation(bTokens)));
175
196
  }
@@ -0,0 +1,9 @@
1
+ import { matchAudienceReplacement } from "./audience-replacement.js";
2
+ import { matchNegativeConsequence } from "./negative-consequence.js";
3
+ import { matchTemporalReframe } from "./temporal-reframe.js";
4
+ export function matchSequenceReframe(first, second, third) {
5
+ return (matchTemporalReframe(first, second) ??
6
+ matchAudienceReplacement(first, second) ??
7
+ matchNegativeConsequence(first, second, third));
8
+ }
9
+ //# sourceMappingURL=sequence-reframes.js.map