mirror of
https://github.com/facebook/duckling.git
synced 2024-11-30 23:33:33 +03:00
Time/FR: don't parse 'a un'
Summary: In French, the form "at hh" is not valid (it requires an hour indicator). This fixes false positives such as in "John a un rendez-vous." Fixes https://github.com/wit-ai/wit/issues/666. Reviewed By: JonCoens Differential Revision: D5530713 fbshipit-source-id: ecee1e5
This commit is contained in:
parent
8710b9d59b
commit
ef461c3133
File diff suppressed because it is too large
Load Diff
@ -10,6 +10,7 @@
|
||||
|
||||
module Duckling.Time.FR.Corpus
|
||||
( corpus
|
||||
, negativeCorpus
|
||||
) where
|
||||
|
||||
import Data.String
|
||||
@ -17,14 +18,21 @@ import Prelude
|
||||
|
||||
import Duckling.Lang
|
||||
import Duckling.Resolve
|
||||
import Duckling.Testing.Types hiding (examples)
|
||||
import Duckling.Time.Corpus
|
||||
import Duckling.Time.Types hiding (Month)
|
||||
import Duckling.TimeGrain.Types hiding (add)
|
||||
import Duckling.Testing.Types hiding (examples)
|
||||
|
||||
corpus :: Corpus
|
||||
corpus = (testContext {lang = FR}, allExamples)
|
||||
|
||||
negativeCorpus :: NegativeCorpus
|
||||
negativeCorpus = (testContext {lang = FR}, examples)
|
||||
where
|
||||
examples =
|
||||
[ "Ana a un court de tennis"
|
||||
]
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (datetime (2013, 2, 12, 4, 30, 0) Second)
|
||||
|
@ -718,7 +718,7 @@ ruleHourofdayInteger :: Rule
|
||||
ruleHourofdayInteger = Rule
|
||||
{ name = "<hour-of-day> <integer> (as relative minutes)"
|
||||
, pattern =
|
||||
[ Predicate isAnHourOfDay
|
||||
[ Predicate $ liftM2 (&&) isAnHourOfDay hasNoDirection
|
||||
, Predicate $ isIntegerBetween 1 59
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
@ -1587,11 +1587,10 @@ ruleVersTimeofday = Rule
|
||||
{ name = "à|vers <time-of-day>"
|
||||
, pattern =
|
||||
[ regex "(vers|autour de|(a|\x00e0) environ|aux alentours de|(a|\x00e0))"
|
||||
, Predicate isATimeOfDay
|
||||
, Predicate $ liftM2 (&&) isATimeOfDay isNotLatent
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(_:Token Time td:_) ->
|
||||
tt $ notLatent td
|
||||
(_:x:_) -> Just x
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
@ -1667,7 +1666,7 @@ ruleLeCycleAprssuivantTime :: Rule
|
||||
ruleLeCycleAprssuivantTime = Rule
|
||||
{ name = "le <cycle> après|suivant <time>"
|
||||
, pattern =
|
||||
[ regex "l[ea']? ?"
|
||||
[ regex "l[ea']?"
|
||||
, dimension TimeGrain
|
||||
, regex "suivante?|apr(e|\x00e8|\x00e9)s"
|
||||
, dimension Time
|
||||
@ -1689,7 +1688,12 @@ ruleEntreDdEtDdMonthinterval = Rule
|
||||
, Predicate isAMonth
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(_:Token RegexMatch (GroupMatch (m1:_)):_:Token RegexMatch (GroupMatch (m2:_)):Token Time td:_) -> do
|
||||
(_:
|
||||
Token RegexMatch (GroupMatch (m1:_)):
|
||||
_:
|
||||
Token RegexMatch (GroupMatch (m2:_)):
|
||||
Token Time td:
|
||||
_) -> do
|
||||
n1 <- parseInt m1
|
||||
n2 <- parseInt m2
|
||||
from <- intersect (dayOfMonth n1) td
|
||||
@ -1742,7 +1746,7 @@ ruleDudansLePartofday :: Rule
|
||||
ruleDudansLePartofday = Rule
|
||||
{ name = "du|dans le <part-of-day>"
|
||||
, pattern =
|
||||
[ regex "du|dans l[ae']? ?|au|en|l[ae' ]|d(\x00e8|e)s l?[ae']? ?"
|
||||
[ regex "du|dans l[ae']? ?|au|en|l[ae' ]|d(\x00e8|e)s l?[ae']?"
|
||||
, Predicate isAPartOfDay
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
@ -1787,7 +1791,7 @@ ruleMaintenant :: Rule
|
||||
ruleMaintenant = Rule
|
||||
{ name = "maintenant"
|
||||
, pattern =
|
||||
[ regex "maintenant|(tout de suite)"
|
||||
[ regex "maintenant|tout de suite"
|
||||
]
|
||||
, prod = \_ -> tt $ cycleNth TG.Second 0
|
||||
}
|
||||
@ -1811,7 +1815,7 @@ ruleLeCycleAvantprcdentTime :: Rule
|
||||
ruleLeCycleAvantprcdentTime = Rule
|
||||
{ name = "le <cycle> avant|précédent <time>"
|
||||
, pattern =
|
||||
[ regex "l[ea']? ?"
|
||||
[ regex "l[ea']?"
|
||||
, dimension TimeGrain
|
||||
, regex "avant|pr(\x00e9|e)c(\x00e9|e)dent"
|
||||
, dimension Time
|
||||
@ -1826,7 +1830,7 @@ ruleDayOfMonthPremier :: Rule
|
||||
ruleDayOfMonthPremier = Rule
|
||||
{ name = "day of month (premier)"
|
||||
, pattern =
|
||||
[ regex "premier|prem\\.?|1er|1 er"
|
||||
[ regex "premier|prem\\.?|1 ?er"
|
||||
]
|
||||
, prod = \_ -> tt $ dayOfMonth 1
|
||||
}
|
||||
|
@ -12,10 +12,10 @@
|
||||
|
||||
module Duckling.Time.Helpers
|
||||
( -- Patterns
|
||||
isADayOfWeek, isAMonth, isAnHourOfDay, isAPartOfDay, isATimeOfDay
|
||||
, isDOMInteger, isDOMOrdinal, isDOMValue, isGrain, isGrainFinerThan
|
||||
, isGrainOfTime, isIntegerBetween, isNotLatent, isOrdinalBetween
|
||||
, isMidnightOrNoon, isNumeralSafeToUse
|
||||
hasNoDirection, isADayOfWeek, isAMonth, isAnHourOfDay, isAPartOfDay
|
||||
, isATimeOfDay, isDOMInteger, isDOMOrdinal, isDOMValue, isGrain
|
||||
, isGrainFinerThan, isGrainOfTime, isIntegerBetween, isNotLatent
|
||||
, isOrdinalBetween, isMidnightOrNoon, isNumeralSafeToUse
|
||||
-- Production
|
||||
, cycleLastOf, cycleN, cycleNth, cycleNthAfter, dayOfMonth, dayOfWeek
|
||||
, daysOfWeekOfMonth, durationAfter, durationAgo, durationBefore, form, hour
|
||||
@ -275,6 +275,10 @@ isNotLatent :: Predicate
|
||||
isNotLatent (Token Time td) = not $ TTime.latent td
|
||||
isNotLatent _ = False
|
||||
|
||||
hasNoDirection :: Predicate
|
||||
hasNoDirection (Token Time td) = isNothing $ TTime.direction td
|
||||
hasNoDirection _ = False
|
||||
|
||||
isIntegerBetween :: Int -> Int -> Predicate
|
||||
isIntegerBetween low high (Token Numeral nd) =
|
||||
TNumeral.isIntegerBetween (TNumeral.value nd) low high
|
||||
|
@ -20,4 +20,5 @@ import Duckling.Time.FR.Corpus
|
||||
tests :: TestTree
|
||||
tests = testGroup "FR Tests"
|
||||
[ makeCorpusTest [This Time] corpus
|
||||
, makeNegativeCorpusTest [This Time] negativeCorpus
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user