Skip to content

fix(itn/en): read spoken fractions instead of misfiring the ordinal tagger (#82) - #85

Merged
Alex-Wengg merged 1 commit into
mainfrom
fix/en-fraction-itn-82
Jul 23, 2026
Merged

fix(itn/en): read spoken fractions instead of misfiring the ordinal tagger (#82)#85
Alex-Wengg merged 1 commit into
mainfrom
fix/en-fraction-itn-82

Conversation

@Alex-Wengg

Copy link
Copy Markdown
Member

Fixes #82.

Problem

nemo_normalize_sentence("use one third of a cup") returned use 4th of a cup.

English ITN had no fraction tagger (fr/de/es/hi/ja/zh do), so one third fell through to the ordinal tagger. Its compound-ordinal path blindly adds prefix + ordinal — correct for twenty first (20 + 1 = 21st) but nonsense for one third (1 + 3 = 4th). The bug hits every ones-cardinal + ones-ordinal denominator (one fifth → 6th, one eighth → 9th, ...); other phrasings leaked the numerator instead (two thirds2 thirds, one half1 half).

Fix

  • New itn::en::fraction tagger, run before ordinal in both the single-expression and sentence pipelines (priority 78, below decimal/above ordinal). Emits N/D:
    • one third1/3, one half1/2, one quarter1/4
    • two thirds2/3, three quarters3/4, twenty two thirds22/3
  • Plural/singular disambiguation (the crux): a plural denominator (thirds) is always a fraction; a singular one (third) is a fraction only with numerator one. So twenty third stays the ordinal 23rd, while one third becomes 1/3.
    • Excludes first/secondone second is a duration, not 1/2.
    • Singular scale words stay ordinals: one hundredth100th (only two hundredths → 2/100).
    • The article a is not a numerator, so a quarter of the pizza is left unchanged (matches existing behavior/test).
  • Ordinal guard: the compound-addition path now requires the prefix to be a round multiple of the next power of ten, so it no longer fabricates ordinals from one + ones-ordinal (one second no longer becomes 3rd). Genuine compounds (twenty first, one hundred tenth) are unaffected.

Tests

  • Unit tests in fraction.rs (singular/plural, deferral to ordinals, excluded denominators, article-is-not-a-numerator).
  • Integration tests in en_tests.rs for the reported case + ordinal regression guards.
  • Full suite green (13 binaries, 0 failures); fst-engine feature still builds; cargo fmt --check clean.

Scope

Default (hand-written Rust) taggers only — the fst-engine path is untouched.

…agger (#82)

`normalize_sentence("use one third of a cup")` returned "use 4th of a cup":
English ITN had no fraction tagger, so "one third" fell to the ordinal tagger,
whose compound-ordinal path blindly added prefix + ordinal (1 + 3 = "4th").

- Add `itn::en::fraction`, run before ordinal in both the single-expression
  and sentence pipelines (priority 78, below decimal/above ordinal). It emits
  N/D for spoken fractions: "one third" -> 1/3, "two thirds" -> 2/3,
  "three quarters" -> 3/4, "twenty two thirds" -> 22/3.
- Disambiguate via denominator number: a plural denominator ("thirds") is
  always a fraction; a singular one ("third") only with numerator one, so
  "twenty third" stays the ordinal 23rd. Exclude "first"/"second" ("one
  second" is a duration) and keep singular scale words as ordinals
  ("one hundredth" -> 100th). The article "a" is not a numerator, so
  "a quarter of the pizza" is left unchanged.
- Guard the ordinal compound-addition path: the prefix must be a round
  multiple of the next power of ten, so it no longer fabricates ordinals from
  "one" + ones-ordinal ("one second" no longer becomes "3rd").

Adds unit tests for the fraction tagger and issue #82 integration tests.
@Alex-Wengg
Alex-Wengg merged commit 8a043f1 into main Jul 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fraction denominators misidentified as ordinals: "one third of a cup" → "4th of a cup"

1 participant