Add "<part-of-day> at "<time-of-day>" rule.

Summary:
Parts of day are time ranges, e.g. "tonight" is a range from 6:00pm to midnight. We have intersect logic in place to resolve a string like "tonight at 7pm" to one time, at 7pm. But if the time is outside of the part of day's range (e.g. "tonight at 5pm"), the string is resolved to 2 separate times ("tonight" and "at 5pm").

These changes resolve e.g. "tonight at xx" to "xx" irrespective of the range of tonight, as long as the am/pm makes sense (so "tonight at 5am" would still resolve to 2 separate times - "tonight" and at "5am").

"this/early morning at xx" gets resolved to "xx am". All other parts of day get resolved to "xx pm", with one exception: all parts of day resolve "... at 12" to midnight.

Differential Revision: D17694898

fbshipit-source-id: 1e24023759bb942659285d18a6a4d0b09f77c9da
This commit is contained in:
Franz-Julius Chen 2019-10-25 16:51:57 -07:00 committed by Facebook Github Bot
parent b6fc40aff3
commit 6f560efa7b
16 changed files with 8247 additions and 7140 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -139,7 +139,7 @@ latentCorpus = (testContext, testOptions {withLatent = True}, xs)
[ "May"
]
, examples (datetimeInterval
((2013, 2, 12, 4, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
((2013, 2, 12, 0, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
[ "morning"
]
, examples (datetimeInterval
@ -484,6 +484,14 @@ allExamples = concat
, "at 3 AM"
, "3 oclock am"
, "at three am"
, "this morning at 3"
, "3 in the morning"
, "at 3 in the morning"
, "early morning @ 3"
]
, examples (datetime (2013, 2, 12, 10, 0, 0) Hour)
[ "this morning @ 10"
, "this morning at 10am"
]
, examples (datetime (2013, 2, 13, 3, 18, 0) Minute)
[ "3:18am"
@ -535,6 +543,8 @@ allExamples = concat
, "15h20"
, "at three twenty"
, "20 minutes past 3pm"
, "this afternoon at 3:20"
, "tonight @ 3:20"
]
, examples (datetime (2013, 2, 12, 15, 30, 0) Minute)
[ "at half past three pm"
@ -602,6 +612,7 @@ allExamples = concat
]
, examples (datetime (2013, 2, 16, 9, 0, 0) Hour)
[ "at 9am on Saturday"
, "Saturday morning at 9"
]
, examples (datetime (2013, 2, 16, 9, 0, 0) Hour)
[ "on Saturday for 9am"
@ -805,7 +816,7 @@ allExamples = concat
, examples (datetimeHoliday (2013, 12, 25, 18, 0, 0) Hour "Christmas")
[ "xmas at 6 pm"
]
, examples (datetimeIntervalHoliday ((2013, 12, 25, 4, 0, 0), (2013, 12, 25, 12, 0, 0)) Hour "Christmas")
, examples (datetimeIntervalHoliday ((2013, 12, 25, 0, 0, 0), (2013, 12, 25, 12, 0, 0)) Hour "Christmas")
[ "morning of xmas"
, "morning of christmas 2013"
, "morning of this christmas day"
@ -954,10 +965,10 @@ allExamples = concat
, examples (datetimeInterval ((2013, 2, 15, 18, 0, 0), (2013, 2, 18, 0, 0, 0)) Hour)
[ "this week-end"
]
, examples (datetimeInterval ((2013, 2, 18, 4, 0, 0), (2013, 2, 18, 12, 0, 0)) Hour)
, examples (datetimeInterval ((2013, 2, 18, 0, 0, 0), (2013, 2, 18, 12, 0, 0)) Hour)
[ "monday mOrnIng"
]
, examples (datetimeInterval ((2013, 2, 18, 4, 0, 0), (2013, 2, 18, 9, 0, 0)) Hour)
, examples (datetimeInterval ((2013, 2, 18, 0, 0, 0), (2013, 2, 18, 9, 0, 0)) Hour)
[ "monday early in the morning"
, "monday early morning"
, "monday in the early hours of the morning"
@ -966,7 +977,7 @@ allExamples = concat
[ "late tonight"
, "late tonite"
]
, examples (datetimeInterval ((2013, 2, 15, 4, 0, 0), (2013, 2, 15, 12, 0, 0)) Hour)
, examples (datetimeInterval ((2013, 2, 15, 0, 0, 0), (2013, 2, 15, 12, 0, 0)) Hour)
[ "february the 15th in the morning"
, "15 of february in the morning"
, "morning of the 15th of february"
@ -1193,6 +1204,9 @@ allExamples = concat
, examples (datetime (2013, 2, 12, 14, 0, 0) Hour)
[ "today at 2pm"
, "at 2pm"
, "this afternoon at 2"
, "this evening at 2"
, "tonight at 2"
]
, examples (datetime (2013, 2, 13, 15, 0, 0) Hour)
[ "3pm tomorrow"
@ -1250,7 +1264,7 @@ allExamples = concat
[ "10:30"
, "approximately 1030"
]
, examples (datetimeInterval ((2013, 2, 12, 4, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
, examples (datetimeInterval ((2013, 2, 12, 0, 0, 0), (2013, 2, 12, 12, 0, 0)) Hour)
[ "this morning"
]
, examples (datetime (2013, 2, 18, 0, 0, 0) Day)
@ -1263,6 +1277,9 @@ allExamples = concat
, examples (datetime (2013, 2, 13, 0, 0, 0) Hour)
[ "at 12am"
, "at midnight"
, "this morning at 12"
, "this evening at 12"
, "this afternoon at 12"
]
, examples (datetime (2013, 2, 13, 9, 0, 0) Hour)
[ "9 tomorrow morning"
@ -1281,6 +1298,7 @@ allExamples = concat
, "at 5 tomorrow afternoon"
, "at 5pm tomorrow"
, "tomorrow at 5pm"
, "tomorrow evening at 5"
]
, examples (datetimeInterval ((2013, 2, 13, 12, 0, 0), (2013, 2, 13, 19, 0, 0)) Hour)
[ "tomorrow afternoon"
@ -1307,6 +1325,9 @@ allExamples = concat
]
, examples (datetime (2013, 2, 12, 23, 0, 0) Hour)
[ "tonight at 11"
, "this evening at 11"
, "this afternoon at 11"
, "tonight at 11pm"
]
, examples (datetime (2013, 2, 12, 4, 23, 0) Minute)
-- yes, the result is in the past, we may need to revisit

View File

@ -545,6 +545,28 @@ ruleTODOClock = Rule
_ -> Nothing
}
rulePODatTOD :: Rule
rulePODatTOD = Rule
{ name = "<part-of-day> at <time-of-day>"
, pattern =
[ Predicate isAPartOfDay
, regex "at|@"
, Predicate isATimeOfDay
]
, prod = \tokens -> case tokens of
(Token Time TimeData{TTime.timePred = TTime.IntersectPredicate
(TTime.TimeIntervalsPredicate
_ TTime.TimeDatePredicate{TTime.tdHour = Just (False, start)} _) _}:_:
Token Time tod@TimeData{TTime.form = Just (TTime.TimeOfDay (Just hours) True)}:_) ->
tt $ timeOfDayAMPM (start < 12 || hours == 12) tod
(Token Time TimeData{TTime.timePred = TTime.TimeIntervalsPredicate
_ TTime.TimeDatePredicate{TTime.tdHour = Just (False, start)} _}:_:
Token Time tod@TimeData{TTime.form = Just (TTime.TimeOfDay (Just hours) True)}:_) ->
tt $ timeOfDayAMPM (start < 12 || hours == 12) tod
_ -> Nothing
}
ruleHHMM :: Rule
ruleHHMM = Rule
{ name = "hh:mm"
@ -881,7 +903,7 @@ rulePartOfDays = Rule
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> do
let (start, end) = case Text.toLower match of
"morning" -> (hour False 4, hour False 12)
"morning" -> (hour False 0, hour False 12)
"evening" -> (hour False 18, hour False 0)
"night" -> (hour False 18, hour False 0)
"lunch" -> (hour False 12, hour False 14)
@ -899,7 +921,7 @@ ruleEarlyMorning = Rule
[ regex "early ((in|hours of) the )?morning"
]
, prod = \_ -> Token Time . partOfDay . mkLatent <$>
interval TTime.Open (hour False 4) (hour False 9)
interval TTime.Open (hour False 0) (hour False 9)
}
rulePODIn :: Rule
@ -1050,6 +1072,18 @@ ruleTODPrecision = Rule
_ -> Nothing
}
ruleTODPOD :: Rule
ruleTODPOD = Rule
{ name = "<time-of-day> <part-of-day>"
, pattern =
[ Predicate isATimeOfDay
, Predicate isAPartOfDay
]
, prod = \tokens -> case tokens of
(Token Time td:Token Time pod:_) -> Token Time . notLatent <$> intersect td pod
_ -> Nothing
}
rulePrecisionTOD :: Rule
rulePrecisionTOD = Rule
{ name = "about|exactly <time-of-day>"
@ -2436,6 +2470,7 @@ rules =
, ruleTODLatent
, ruleAtTOD
, ruleTODOClock
, rulePODatTOD
, ruleHHMM
, ruleHHhMM
, ruleHHMMLatent
@ -2470,6 +2505,7 @@ rules =
, ruleWeekend
, ruleWeek
, ruleTODPrecision
, ruleTODPOD
, rulePrecisionTOD
, ruleIntervalFromMonthDDDD
, ruleIntervalFromDDDDMonth

View File

@ -146,7 +146,6 @@ valuesTest = testCase "Values Test" $
xs = examplesCustom (parserCheck 1 parseValuesSize)
[ "now"
, "8 o'clock tonight"
, "tonight at 8 o'clock"
, "yesterday"
]
parseValuesSize :: Value -> Maybe Int