Skip to content

Commit

Permalink
fix: first and last week of month and year (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
scroskey-clinc authored Jun 28, 2021
1 parent 3361f93 commit 4c04a18
Show file tree
Hide file tree
Showing 18 changed files with 4,328 additions and 4,609 deletions.
670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_AU.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_BZ.hs

Large diffs are not rendered by default.

697 changes: 337 additions & 360 deletions Duckling/Ranking/Classifiers/EN_CA.hs

Large diffs are not rendered by default.

690 changes: 333 additions & 357 deletions Duckling/Ranking/Classifiers/EN_GB.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_IE.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_IN.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_JM.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_NZ.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_PH.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_TT.hs

Large diffs are not rendered by default.

739 changes: 358 additions & 381 deletions Duckling/Ranking/Classifiers/EN_US.hs

Large diffs are not rendered by default.

682 changes: 329 additions & 353 deletions Duckling/Ranking/Classifiers/EN_XX.hs

Large diffs are not rendered by default.

670 changes: 323 additions & 347 deletions Duckling/Ranking/Classifiers/EN_ZA.hs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Duckling/Ranking/Classifiers/FR_XX.hs
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ classifiers
-6.215607598755275),
("intersectyear", -5.52246041819533),
("Fevrierfin de matin\233e", -6.215607598755275),
("minuteday", -3.474767574830074),
("minuteday", -3.4747675748300746),
("le <time>d\233but de matin\233e", -6.215607598755275),
("Mardile <time>", -4.829313237635384),
("aujourd'hui\224|vers <time-of-day>", -5.29931686688112),
Expand Down
4 changes: 2 additions & 2 deletions Duckling/Ranking/Classifiers/IT_XX.hs
Original file line number Diff line number Diff line change
Expand Up @@ -327,10 +327,10 @@ classifiers
unseen = -4.31748811353631,
likelihoods =
HashMap.fromList
[("<integer> (latent time-of-day)", -0.9718605830289657),
[("<integer> (latent time-of-day)", -0.9718605830289658),
("intersect by \"di\", \"della\", \"del\"", -3.20545280453606),
("day", -2.3581549441488563), ("Lunedi", -3.6109179126442243),
("hour", -0.9718605830289657),
("hour", -0.9718605830289658),
("two time tokens separated by `di`", -3.20545280453606),
("Domenica", -3.6109179126442243)],
n = 33}}),
Expand Down
10 changes: 5 additions & 5 deletions Duckling/Time/EN/Corpus.hs
Original file line number Diff line number Diff line change
Expand Up @@ -468,23 +468,23 @@ allExamples = concat
, examples (datetime (2013, 10, 3, 0, 0, 0) Day)
[ "third day of october"
]
, examples (datetime (2014, 10, 6, 0, 0, 0) Week)
, examples (datetime (2014, 9, 29, 0, 0, 0) Week)
[ "first week of october 2014"
]
, examples (datetime (2018, 12, 10, 0, 0, 0) Week)
, examples (datetime (2018, 12, 17, 0, 0, 0) Week)
[ "third last week of 2018"
, "the third last week of 2018"
, "the 3rd last week of 2018"
]
, examples (datetime (2018, 10, 15, 0, 0, 0) Week)
, examples (datetime (2018, 10, 22, 0, 0, 0) Week)
[ "2nd last week of October 2018"
, "the second last week of October 2018"
]
, examples (datetime (2013, 5, 27, 0, 0, 0) Day)
[ "fifth last day of May"
, "the 5th last day of May"
]
, examples (datetime (2013, 10, 7, 0, 0, 0) Week)
, examples (datetime (2013, 9, 30, 0, 0, 0) Week)
[ "the week of october 6th"
]
, examples (datetime (2013, 10, 7, 0, 0, 0) Week)
Expand All @@ -494,7 +494,7 @@ allExamples = concat
[ "last day of october 2015"
, "last day in october 2015"
]
, examples (datetime (2014, 9, 22, 0, 0, 0) Week)
, examples (datetime (2014, 9, 29, 0, 0, 0) Week)
[ "last week of september 2014"
]
, examples (datetime (2013, 10, 1, 0, 0, 0) Day)
Expand Down
43 changes: 18 additions & 25 deletions Duckling/Time/EN/Rules.hs
Original file line number Diff line number Diff line change
Expand Up @@ -266,21 +266,6 @@ ruleLastDOWOfTime = Rule
_ -> Nothing
}

ruleLastCycleOfTime :: Rule
ruleLastCycleOfTime = Rule
{ name = "last <cycle> of <time>"
, pattern =
[ regex "last"
, dimension TimeGrain
, regex "of|in"
, dimension Time
]
, prod = \tokens -> case tokens of
(_:Token TimeGrain grain:_:Token Time td:_) ->
tt $ cycleLastOf grain td
_ -> Nothing
}

ruleLastNight :: Rule
ruleLastNight = Rule
{ name = "last night"
Expand Down Expand Up @@ -2271,7 +2256,7 @@ ruleCycleOrdinalOfTime = Rule
, prod = \tokens -> case tokens of
(token:Token TimeGrain grain:_:Token Time td:_) -> do
n <- getIntValue token
tt $ cycleNthAfter True grain (n - 1) td
tt $ cycleNthAfter False grain (n - 1) td
_ -> Nothing
}

Expand All @@ -2280,15 +2265,18 @@ ruleCycleLastOrdinalOfTime = Rule
{ name = "<ordinal> last <cycle> of <time>"
, pattern =
[ dimension Ordinal
, regex "last"
, regex "(to )?(last|final)"
, dimension TimeGrain
, regex "of|in|from"
, dimension Time
]
, prod = \tokens -> case tokens of
(token:_:Token TimeGrain grain:_:Token Time td:_) -> do
n <- getIntValue token
tt . cycleNthAfter True grain (-n) . cycleNthAfter True (timeGrain td) 1 $ td
base <- Just $ cycleNthAfter True (timeGrain td) 1 td
case grain of
TG.Week -> tt $ cycleNthWeekToLast grain (-n) base
_ -> tt $ cycleNthAfter True grain (-n) base
_ -> Nothing
}

Expand All @@ -2305,7 +2293,7 @@ ruleCycleTheOrdinalOfTime = Rule
, prod = \tokens -> case tokens of
(_:token:Token TimeGrain grain:_:Token Time td:_) -> do
n <- getIntValue token
tt $ cycleNthAfter True grain (n - 1) td
tt $ cycleNthAfter False grain (n - 1) td
_ -> Nothing
}

Expand All @@ -2315,15 +2303,18 @@ ruleCycleTheLastOrdinalOfTime = Rule
, pattern =
[ regex "the"
, dimension Ordinal
, regex "last|final"
, regex "(to )?(last|final)"
, dimension TimeGrain
, regex "of|in|from"
, dimension Time
]
, prod = \tokens -> case tokens of
(_:token:_:Token TimeGrain grain:_:Token Time td:_) -> do
n <- getIntValue token
tt . cycleNthAfter True grain (-n) . cycleNthAfter True (timeGrain td) 1 $ td
base <- Just $ cycleNthAfter True (timeGrain td) 1 td
case grain of
TG.Week -> tt $ cycleNthWeekToLast grain (-n) base
_ -> tt $ cycleNthAfter True grain (-n) base
_ -> Nothing
}

Expand All @@ -2338,7 +2329,10 @@ ruleCycleTheLastOfTime = Rule
]
, prod = \tokens -> case tokens of
(_:Token TimeGrain grain:_:Token Time td:_) -> do
tt . cycleNthAfter True grain (-1) . cycleNthAfter True (timeGrain td) 1 $ td
base <- Just $ cycleNthAfter True (timeGrain td) 1 td
case grain of
TG.Week -> tt $ cycleNthWeekToLast grain (-1) base
_ -> tt $ cycleNthAfter True grain (-1) base
_ -> Nothing
}

Expand All @@ -2353,7 +2347,7 @@ ruleCycleTheOfTime = Rule
]
, prod = \tokens -> case tokens of
(_:Token TimeGrain grain:_:Token Time td:_) ->
tt $ cycleNthAfter True grain 0 td
tt $ cycleNthAfter False grain 0 td
_ -> Nothing
}

Expand All @@ -2375,7 +2369,7 @@ ruleCycleOrdinalAfterTime = Rule

ruleCycleTheOrdinalAfterTime :: Rule
ruleCycleTheOrdinalAfterTime = Rule
{ name = "<ordinal> <cycle> after <time>"
{ name = "the <ordinal> <cycle> after <time>"
, pattern =
[ regex "the"
, dimension Ordinal
Expand Down Expand Up @@ -2799,7 +2793,6 @@ rules =
, ruleTimeBeforeLastAfterNext
, ruleOrdinalDOWOfTime
, ruleLastDOWOfTime
, ruleLastCycleOfTime
, ruleLastNight
, ruleLastWeekendOfMonth
, ruleNthTimeOfTime
Expand Down
40 changes: 38 additions & 2 deletions Duckling/Time/Helpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ module Duckling.Time.Helpers
, isIntegerBetween, isNotLatent , isOrdinalBetween, isMidnightOrNoon
, isOkWithThisNext, sameGrain, hasTimezone, hasNoTimezone, today
-- Production
, cycleLastOf, cycleN, cycleNth, cycleNthAfter, dayOfMonth, dayOfWeek
, durationAfter, durationAgo, durationBefore, mkOkForThisNext, form, hour
, cycleLastOf, cycleN, cycleNth, cycleNthAfter, cycleNthWeekToLast, dayOfMonth
, dayOfWeek, durationAfter, durationAgo, durationBefore, mkOkForThisNext, form, hour
, hourMinute, hourMinuteSecond, inDuration, intersect, intersectDOM, interval
, inTimezone, longWEBefore, minute, minutesAfter, minutesBefore, mkLatent
, month, monthDay, notLatent, now, nthDOWOfMonth, partOfDay, predLastOf
Expand Down Expand Up @@ -192,6 +192,35 @@ takeNthAfter n notImmediate cyclicPred basePred =
[] -> Nothing
(nth:_) -> Just nth

-- | Like `takeNthAfter`, but corrects predicates which overshoot to next grain
takeNthWeekToLast
:: Int
-> TTime.Predicate
-> TTime.Predicate
-> TTime.Predicate
takeNthWeekToLast n cyclicPred basePred =
mkSeriesPredicate $! TTime.timeSeqMap False f basePred
where
f t ctx =
let (past, future) = runPredicate cyclicPred t ctx
rest = if n >= 0
then case future of
(ahead:_) | True && TTime.timeBefore ahead t
-> drop (n + 1) future
_ -> drop n future
else drop (- (n + 1)) past
in case rest of
[] -> Nothing
(nth:_) -> t
where
-- get last week of cycle and second to last week of cycle
-- if they are in the same month, then add a week to the current result
(TTime.TimeObject (Time.UTCTime day _) _ _) = TTime.timePlusEnd nth TG.Week $ toInteger $ negate n
(TTime.TimeObject (Time.UTCTime day2 _) _ _) = TTime.timePlusEnd nth TG.Week $ toInteger $ negate (n + 1)
(_, month, _) = Time.toGregorian day
(_, month2, _) = Time.toGregorian day2
t = if month == month2 then Just $ TTime.timePlusEnd nth TG.Week 1 else Just nth

-- | Take the nth closest value to `basePred` among those yielded by
-- `cyclicPred`.
-- n = 0 is the closest value, n = 1 is the second closest value, etc.
Expand Down Expand Up @@ -503,6 +532,13 @@ cycleNthAfter notImmediate grain n TimeData {TTime.timePred = p} =
, TTime.timeGrain = grain
}

cycleNthWeekToLast :: TG.Grain -> Int -> TimeData -> TimeData
cycleNthWeekToLast grain n TimeData {TTime.timePred = p} =
TTime.timedata'
{ TTime.timePred = takeNthWeekToLast n (timeCycle grain) p
, TTime.timeGrain = grain
}

cycleLastOf :: TG.Grain -> TimeData -> TimeData
cycleLastOf grain TimeData {TTime.timePred = p} = TTime.timedata'
{ TTime.timePred = takeLastOf (timeCycle grain) p
Expand Down

0 comments on commit 4c04a18

Please sign in to comment.