RJ3vans commited on
Commit
4eaca2e
·
verified ·
1 Parent(s): 166949e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -10
app.py CHANGED
@@ -1828,6 +1828,16 @@ def rewrite_residual_list_comma(sent, coordinator="and"):
1828
  return out
1829
  ###############################################################################
1830
 
 
 
 
 
 
 
 
 
 
 
1831
  ###############################################################################
1832
  def _singular_present_form(lemma: str) -> str:
1833
  """Map verb lemma → 3rd person singular present."""
@@ -1882,29 +1892,28 @@ def subject_is_singular(subj_token) -> bool:
1882
 
1883
  def fix_subject_verb_agreement(sent: str) -> str:
1884
  """
1885
- After CMN1 splits a plural subject, repair the finite verb / aux.
1886
- The man live … → The man lives …
1887
- The man are going … → The man is going …
 
1888
  """
1889
  if not sent or not sent.strip():
1890
  return sent
1891
 
1892
  if re.search(r"\bdo(?:es|ing)?\s+so\b", sent, flags=re.I):
1893
  return sent
1894
-
1895
  sent = sent.strip()
1896
  doc = nlp(sent)
1897
  if not doc:
1898
  return sent
1899
 
1900
- # --- subject: first nsubj, else first noun ---
1901
  subj = next((t for t in doc if t.dep_ in ("nsubj", "nsubjpass")), None)
1902
  if subj is None:
1903
  subj = next((t for t in doc if t.tag_ in ("NN", "NNP", "PRP")), None)
1904
  if subj is None:
1905
  return sent
1906
 
1907
- # Coordinated subject still plural
1908
  if any(t.dep_ == "cc" for t in subj.subtree):
1909
  return sent
1910
  if subj.lower_ in {"i", "you", "we", "they"}:
@@ -1914,10 +1923,22 @@ def fix_subject_verb_agreement(sent: str) -> str:
1914
  if subj.tag_ not in ("NN", "NNP", "PRP"):
1915
  return sent
1916
 
 
 
 
 
 
 
 
 
 
 
 
1917
  def to_3sg(word: str) -> str:
1918
  low = word.lower()
1919
  irregular = {
1920
  "are": "is",
 
1921
  "were": "was",
1922
  "have": "has",
1923
  "do": "does",
@@ -1936,22 +1957,31 @@ def fix_subject_verb_agreement(sent: str) -> str:
1936
  new = new[0].upper() + new[1:]
1937
  return new
1938
 
1939
- # Prefer agreeing AUX (are going, have gone, …)
1940
  target = None
1941
  for t in doc:
 
 
1942
  if t.dep_ in ("aux", "auxpass") and t.lower_ in {
1943
  "are", "were", "have", "do", "am"
1944
  }:
1945
  target = t
1946
  break
 
1947
  if target is None:
1948
  for t in doc:
1949
- if t.tag_ in ("VBP", "VB") and t.lower_ not in {"to"}:
 
 
 
 
 
1950
  target = t
1951
  break
 
1952
  if target is None:
1953
  return sent
1954
- if target.lower_ in {"is", "was", "has", "does"}:
1955
  return sent
1956
 
1957
  new = to_3sg(target.text)
@@ -2343,7 +2373,7 @@ def fix_apostrophe_spacing(s):
2343
  def clean_output(text):
2344
  if not text:
2345
  return ""
2346
-
2347
  # brackets and WordPiece fragments
2348
  text = re.sub(r'[\[\]]+', '', text)
2349
  text = re.sub(r'\s*##\s*', '', text)
@@ -2374,6 +2404,9 @@ def clean_output(text):
2374
  text = re.sub(r"(\w)'\s+(\w)", r"\1'\2", text)
2375
  text = re.sub(r"(\w)\s+'(\w)", r"\1'\2", text)
2376
 
 
 
 
2377
  text = text.strip()
2378
 
2379
  if text:
 
1828
  return out
1829
  ###############################################################################
1830
 
1831
+ ###############################################################################
1832
+ def repair_mangled_infinitive_be(sent: str) -> str:
1833
+ """Undo earlier bugs: to bes / to beses → to be."""
1834
+ if not sent:
1835
+ return sent
1836
+ sent = re.sub(r"\bto\s+bes(?:es)?\b", "to be", sent, flags=re.I)
1837
+ sent = re.sub(r"\bto\s+bees\b", "to be", sent, flags=re.I)
1838
+ return sent
1839
+ ###############################################################################
1840
+
1841
  ###############################################################################
1842
  def _singular_present_form(lemma: str) -> str:
1843
  """Map verb lemma → 3rd person singular present."""
 
1892
 
1893
  def fix_subject_verb_agreement(sent: str) -> str:
1894
  """
1895
+ After a split, repair a finite verb / aux that no longer matches
1896
+ a singular subject.
1897
+
1898
+ Do not touch infinitives (to be, to go, …) or already-singular forms.
1899
  """
1900
  if not sent or not sent.strip():
1901
  return sent
1902
 
1903
  if re.search(r"\bdo(?:es|ing)?\s+so\b", sent, flags=re.I):
1904
  return sent
1905
+
1906
  sent = sent.strip()
1907
  doc = nlp(sent)
1908
  if not doc:
1909
  return sent
1910
 
 
1911
  subj = next((t for t in doc if t.dep_ in ("nsubj", "nsubjpass")), None)
1912
  if subj is None:
1913
  subj = next((t for t in doc if t.tag_ in ("NN", "NNP", "PRP")), None)
1914
  if subj is None:
1915
  return sent
1916
 
 
1917
  if any(t.dep_ == "cc" for t in subj.subtree):
1918
  return sent
1919
  if subj.lower_ in {"i", "you", "we", "they"}:
 
1923
  if subj.tag_ not in ("NN", "NNP", "PRP"):
1924
  return sent
1925
 
1926
+ def is_infinitive(tok) -> bool:
1927
+ # to be / to go / to live …
1928
+ if tok.i > 0 and doc[tok.i - 1].lower_ == "to":
1929
+ return True
1930
+ if tok.head is not None and tok.head.lower_ == "to":
1931
+ return True
1932
+ # xcomp/acl of another verb, typically an infinitive
1933
+ if tok.dep_ in {"xcomp", "acl", "oprd"} and tok.tag_ in {"VB", "VBG"}:
1934
+ return True
1935
+ return False
1936
+
1937
  def to_3sg(word: str) -> str:
1938
  low = word.lower()
1939
  irregular = {
1940
  "are": "is",
1941
+ "am": "is",
1942
  "were": "was",
1943
  "have": "has",
1944
  "do": "does",
 
1957
  new = new[0].upper() + new[1:]
1958
  return new
1959
 
1960
+ # Finite auxiliaries that actually need agreement
1961
  target = None
1962
  for t in doc:
1963
+ if is_infinitive(t):
1964
+ continue
1965
  if t.dep_ in ("aux", "auxpass") and t.lower_ in {
1966
  "are", "were", "have", "do", "am"
1967
  }:
1968
  target = t
1969
  break
1970
+
1971
  if target is None:
1972
  for t in doc:
1973
+ if is_infinitive(t):
1974
+ continue
1975
+ # Infinitive lemma "be" must never get -s / -es
1976
+ if t.lemma_ == "be" and t.lower_ in {"be", "bes", "beses"}:
1977
+ continue
1978
+ if t.tag_ in ("VBP", "VB") and t.lower_ not in {"to", "be"}:
1979
  target = t
1980
  break
1981
+
1982
  if target is None:
1983
  return sent
1984
+ if target.lower_ in {"is", "was", "has", "does", "be"}:
1985
  return sent
1986
 
1987
  new = to_3sg(target.text)
 
2373
  def clean_output(text):
2374
  if not text:
2375
  return ""
2376
+
2377
  # brackets and WordPiece fragments
2378
  text = re.sub(r'[\[\]]+', '', text)
2379
  text = re.sub(r'\s*##\s*', '', text)
 
2404
  text = re.sub(r"(\w)'\s+(\w)", r"\1'\2", text)
2405
  text = re.sub(r"(\w)\s+'(\w)", r"\1'\2", text)
2406
 
2407
+ # --- restore infinitival be that SVA rewrote as is/are/was/were ---
2408
+ text = repair_mangled_infinitive_be(text)
2409
+
2410
  text = text.strip()
2411
 
2412
  if text: