1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15- from pynini import closure , cross , string_file , union
16- from pynini .lib .pynutil import delete , insert
15+ from pynini import closure , cross , invert , string_file , union
16+ from pynini .lib .pynutil import add_weight , delete , insert
1717
1818from itn .english .rules .cardinal import Cardinal
1919from tn .processor import Processor
@@ -39,58 +39,77 @@ def __init__(self, cardinal=None):
3939 self .build_verbalizer ()
4040
4141 def build_tagger (self ):
42- cardinal_graph = self .cardinal .graph
42+ cardinal_graph = add_weight ( self .cardinal .graph_no_exception , - 0.7 )
4343 time_suffix = string_file (get_abs_path ("../itn/english/data/time/time_suffix.tsv" ))
44- time_zone = string_file (get_abs_path ("../itn/english/data/time/time_zone.tsv" ))
44+ time_zone = invert (string_file (get_abs_path ("../itn/english/data/time/time_zone.tsv" )))
45+ to_hour = string_file (get_abs_path ("../itn/english/data/time/to_hour.tsv" ))
46+ minute_to = string_file (get_abs_path ("../itn/english/data/time/minute_to.tsv" ))
4547 ds = delete (" " )
4648
47- # hours: 0-23, only valid hour words, with zero-padding
48- hour_labels = [_num_to_word (x ) for x in range (0 , 24 ) if _num_to_word (x )]
49- hour_padded = union (* [cross (_num_to_word (x ), f"{ x :02d} " ) for x in range (0 , 24 ) if _num_to_word (x )])
50- # minutes: 1-9 (single), 10-59 (double)
51- min_single = [_num_to_word (x ) for x in range (1 , 10 )]
52- min_double = [_num_to_word (x ) for x in range (10 , 60 )]
53- graph_min_single = union (* [cross (_num_to_word (x ), f"{ x :02d} " ) for x in range (1 , 10 )])
49+ hour_all = union (* [cross (_num_to_word (x ), f"{ x :02d} " ) for x in range (0 , 24 ) if _num_to_word (x )])
50+ hour_12 = union (* [cross (_num_to_word (x ), f"{ x :02d} " ) for x in range (1 , 13 )])
51+ graph_min_single = union (* [cross (_num_to_word (x ), f"0{ x } " ) for x in range (1 , 10 )])
5452 graph_min_double = union (* [cross (_num_to_word (x ), str (x )) for x in range (10 , 60 )])
53+ graph_min_verbose = cross ("half" , "30" ) | cross ("quarter" , "15" )
5554
56- hour = insert ('hour: "' ) + hour_padded + insert ('"' )
5755 oclock = cross ("o'clock" , "" ) | cross ("oclock" , "" ) | cross ("hundred hours" , "" )
58- minute = (
59- oclock + insert ("00" )
60- | delete ("o" ) + ds + graph_min_single
61- | graph_min_double
62- )
6356
57+ hour = insert ('hour: "' ) + hour_all + insert ('"' )
58+ hour12 = insert ('hour: "' ) + hour_12 + insert ('"' )
6459 suffix = ds + insert (' noon: "' ) + time_suffix + insert ('"' )
6560 zone = ds + insert (' zone: "' ) + time_zone + insert ('"' )
61+ zone_opt = closure (zone , 0 , 1 )
6662
67- # "eight oclock" (no suffix needed)
68- graph_oclock = hour + ds + insert (' minute: "' ) + oclock + insert ('00"' )
69- # "two o five" (no suffix needed)
63+ # "eight oclock" / "eight oclock gmt"
64+ graph_oclock = hour + ds + insert (' minute: "' ) + oclock + insert ('00"' ) + zone_opt
65+ # "two o five"
7066 graph_o_min = hour + ds + insert (' minute: "' ) + delete ("o" ) + ds + graph_min_single + insert ('"' )
71- # "two pm", "three am" (hour + suffix, minutes = 00)
72- graph_h_suffix = hour + insert (' minute: "00"' ) + suffix + closure ( zone , 0 , 1 )
73- # "two thirty am" (hour + minute + suffix required)
67+ # "two pm" / "three am est"
68+ graph_h_suffix = hour + insert (' minute: "00"' ) + suffix + zone_opt
69+ # "two thirty am"
7470 graph_hm_suffix = (
75- hour + ds + insert (' minute: "' ) + graph_min_double + insert ('"' )
76- + suffix + closure (zone , 0 , 1 )
71+ hour + ds + insert (' minute: "' ) + graph_min_double + insert ('"' ) + suffix + zone_opt
72+ )
73+ # "two thirty" (1-12 only, no suffix)
74+ graph_hm = hour12 + ds + insert (' minute: "' ) + graph_min_double + insert ('"' )
75+ # "eleven o six pm"
76+ graph_o_min_suffix = (
77+ hour + ds + insert (' minute: "' ) + delete ("o" ) + ds + graph_min_single + insert ('"' ) + suffix + zone_opt
7778 )
7879 # "half past two", "quarter past two"
79- graph_half_quarter = (
80+ graph_past = (
81+ insert ('minute: "' ) + graph_min_verbose + insert ('"' ) + ds + delete ("past" ) + ds + hour
82+ )
83+ # "quarter to one" => 12:45
84+ graph_quarter_to = (
85+ insert ('minute: "' ) + cross ("quarter" , "45" ) + insert ('"' )
86+ + ds + delete ("to" ) + ds
87+ + insert ('hour: "' ) + to_hour + insert ('"' )
88+ )
89+ # "ten to eleven pm" => 10:50 p.m.
90+ graph_min_to = (
8091 insert ('minute: "' )
81- + (cross ( "half" , "30" ) | cross ( "quarter" , "15" ) )
92+ + (( graph_min_single | graph_min_double ) @ minute_to )
8293 + insert ('"' )
83- + ds + delete ("past" ) + ds
84- + hour
94+ + closure (ds + delete ("min" ) + delete ("ute" ).ques + delete ("s" ).ques , 0 , 1 )
95+ + ds + delete ("to" ) + ds
96+ + insert ('hour: "' ) + to_hour + insert ('"' )
97+ + suffix
8598 )
8699
87- final_graph = graph_oclock | graph_o_min | graph_h_suffix | graph_hm_suffix | graph_half_quarter
100+ final_graph = (
101+ graph_oclock | graph_o_min | graph_h_suffix
102+ | graph_hm_suffix | graph_hm | graph_o_min_suffix
103+ | graph_past | graph_quarter_to | graph_min_to
104+ )
88105 self .tagger = self .add_tokens (final_graph )
89106
90107 def build_verbalizer (self ):
91108 hour = delete ('hour: "' ) + self .NOT_QUOTE .plus + delete ('"' )
92109 minute = delete (' minute: "' ) + self .NOT_QUOTE .plus + delete ('"' )
93110 noon = delete (' noon: "' ) + self .NOT_QUOTE .plus + delete ('"' )
111+ zone = delete (' zone: "' ) + self .NOT_QUOTE .plus + delete ('"' )
94112 graph = hour + insert (":" ) + self .DELETE_SPACE + minute
95113 graph += closure (insert (" " ) + self .DELETE_SPACE + noon , 0 , 1 )
114+ graph += closure (insert (" " ) + self .DELETE_SPACE + zone , 0 , 1 )
96115 self .verbalizer = self .delete_tokens (graph )
0 commit comments