Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -2292,6 +2292,77 @@ def build_single_sign_bracketed(tagged_list, mode="ccv"):
|
|
| 2292 |
|
| 2293 |
###############################################################################
|
| 2294 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2295 |
|
| 2296 |
###############################################################################
|
| 2297 |
@spaces.GPU(duration=120)
|
|
|
|
| 2292 |
|
| 2293 |
###############################################################################
|
| 2294 |
|
| 2295 |
+
###############################################################################
|
| 2296 |
+
def fix_subject_verb_agreement(sent: str) -> str:
|
| 2297 |
+
"""
|
| 2298 |
+
If the finite verb is present plural (VBP) but the subject is singular,
|
| 2299 |
+
rewrite the verb to singular present (lives, is, has, …).
|
| 2300 |
+
"""
|
| 2301 |
+
doc = nlp(sent)
|
| 2302 |
+
if not doc:
|
| 2303 |
+
return sent
|
| 2304 |
+
|
| 2305 |
+
# Find root verb
|
| 2306 |
+
root = None
|
| 2307 |
+
for t in doc:
|
| 2308 |
+
if t.dep_ == "ROOT" and t.pos_ in ("VERB", "AUX"):
|
| 2309 |
+
root = t
|
| 2310 |
+
break
|
| 2311 |
+
if root is None:
|
| 2312 |
+
return sent
|
| 2313 |
+
|
| 2314 |
+
# Only repair present non-3sg forms that look plural/base
|
| 2315 |
+
if root.tag_ not in ("VBP", "VB"):
|
| 2316 |
+
return sent
|
| 2317 |
+
|
| 2318 |
+
# Collect nsubj / nsubjpass text
|
| 2319 |
+
subj_tokens = [t for t in root.lefts if t.dep_ in ("nsubj", "nsubjpass")]
|
| 2320 |
+
if not subj_tokens:
|
| 2321 |
+
return sent
|
| 2322 |
+
|
| 2323 |
+
subj = subj_tokens[0]
|
| 2324 |
+
# Coordinated subject still plural → leave alone
|
| 2325 |
+
if any(t.dep_ == "cc" for t in subj.subtree):
|
| 2326 |
+
return sent
|
| 2327 |
+
|
| 2328 |
+
singular = subj.tag_ in ("NN", "NNP", "PRP") and subj.lower_ not in (
|
| 2329 |
+
"i", "you", "we", "they",
|
| 2330 |
+
)
|
| 2331 |
+
# "I/you" take VBP; don't force -s
|
| 2332 |
+
if subj.lower_ in ("i", "you", "we", "they"):
|
| 2333 |
+
return sent
|
| 2334 |
+
if not singular and subj.tag_ not in ("NN", "NNP"):
|
| 2335 |
+
# Heuristic: plural NNS / NNPS → keep verb
|
| 2336 |
+
if subj.tag_ in ("NNS", "NNPS"):
|
| 2337 |
+
return sent
|
| 2338 |
+
|
| 2339 |
+
if not singular and subj.tag_ not in ("NN", "NNP", "PRP"):
|
| 2340 |
+
return sent
|
| 2341 |
+
|
| 2342 |
+
# Map verb → 3sg present
|
| 2343 |
+
irregular = {
|
| 2344 |
+
"are": "is", "were": "was", "have": "has", "do": "does",
|
| 2345 |
+
"go": "goes", "do": "does",
|
| 2346 |
+
}
|
| 2347 |
+
lemma = root.lemma_.lower()
|
| 2348 |
+
form = root.text
|
| 2349 |
+
lower = form.lower()
|
| 2350 |
+
|
| 2351 |
+
if lower in irregular:
|
| 2352 |
+
new = irregular[lower]
|
| 2353 |
+
elif lower.endswith(("s", "sh", "ch", "x", "z", "o")):
|
| 2354 |
+
new = lower + "es"
|
| 2355 |
+
elif lower.endswith("y") and len(lower) > 1 and lower[-2] not in "aeiou":
|
| 2356 |
+
new = lower[:-1] + "ies"
|
| 2357 |
+
else:
|
| 2358 |
+
new = lower + "s"
|
| 2359 |
+
|
| 2360 |
+
if form[0].isupper():
|
| 2361 |
+
new = new[0].upper() + new[1:]
|
| 2362 |
+
|
| 2363 |
+
# Splice back into the sentence using character offsets
|
| 2364 |
+
return sent[: root.idx] + new + sent[root.idx + len(root.text) :]
|
| 2365 |
+
###############################################################################
|
| 2366 |
|
| 2367 |
###############################################################################
|
| 2368 |
@spaces.GPU(duration=120)
|