HU Time, TimeGrain

Summary: Closes https://github.com/facebookincubator/duckling/pull/83

Reviewed By: blandinw

Differential Revision: D5681515

Pulled By: patapizza

fbshipit-source-id: 918d0a4
This commit is contained in:
dubovinszky 2017-08-22 19:15:17 -07:00 committed by Facebook Github Bot
parent ff76927956
commit 60565c15aa
14 changed files with 1074 additions and 7 deletions

View File

@ -14,6 +14,8 @@ import Duckling.Dimensions.Types
allDimensions :: [Some Dimension]
allDimensions =
[ This Numeral
[ This Duration
, This Numeral
, This Ordinal
, This Time
]

View File

@ -0,0 +1,74 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE OverloadedStrings #-}
module Duckling.Duration.HU.Corpus
( corpus ) where
import Data.String
import Prelude
import Duckling.Duration.Types
import Duckling.Lang
import Duckling.Resolve
import Duckling.Testing.Types
import Duckling.TimeGrain.Types (Grain(..))
corpus :: Corpus
corpus = (testContext {lang = HU}, allExamples)
allExamples :: [Example]
allExamples = concat
[ examples (DurationData 1 Second)
[ "egy másodperc"
, "1 másodperc"
]
, examples (DurationData 2 Minute)
[ "2 perc"
, "kettő perc"
]
, examples (DurationData 15 Minute)
[ "negyed óra"
, "negyedóra"
, "negyed-óra"
]
, examples (DurationData 30 Minute)
[ "fél óra"
, "félóra"
, "fél-óra"
]
, examples (DurationData 45 Minute)
[ "háromnegyed óra"
, "háromnegyed-óra"
, "háromnegyedóra"
, "3/4 óra"
, "3/4óra"
]
, examples (DurationData 150 Minute)
[ "2.5 óra"
, "kettő és fél óra"
, "kettő és fél-óra"
, "kettő és félóra"
]
, examples (DurationData 30 Day)
[ "30 nap"
]
, examples (DurationData 7 Week)
[ "hét hét"
]
, examples (DurationData 1 Month)
[ "egy hónap"
]
, examples (DurationData 3 Quarter)
[ "3 negyedév"
]
, examples (DurationData 2 Year)
[ "2 év"
]
]

View File

@ -0,0 +1,91 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
module Duckling.Duration.HU.Rules
( rules ) where
import Control.Monad (join)
import Data.String
import Prelude
import qualified Data.Text as Text
import Duckling.Dimensions.Types
import Duckling.Duration.Helpers
import Duckling.Numeral.Helpers (parseInt, parseInteger)
import Duckling.Numeral.Types (NumeralData(..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Numeral.Types as TNumeral
import qualified Duckling.TimeGrain.Types as TG
ruleDurationQuarterOfAnHour :: Rule
ruleDurationQuarterOfAnHour = Rule
{ name = "quarter of an hour"
, pattern =
[ regex "(negyed[\\s-]?\x00F3ra)"
]
, prod = \_ -> Just . Token Duration $ duration TG.Minute 15
}
ruleDurationHalfAnHour :: Rule
ruleDurationHalfAnHour = Rule
{ name = "half an hour"
, pattern =
[ regex "(f\x00E9l[\\s-]?\x00F3ra)"
]
, prod = \_ -> Just . Token Duration $ duration TG.Minute 30
}
ruleDurationThreeQuartersOfAnHour :: Rule
ruleDurationThreeQuartersOfAnHour = Rule
{ name = "three-quarters of an hour"
, pattern =
[ regex "(3/4[\\s-]?óra|h\x00E1romnegyed[\\s-]?\x00F3ra)"
]
, prod = \_ -> Just . Token Duration $ duration TG.Minute 45
}
ruleDurationDotNumeralHours :: Rule
ruleDurationDotNumeralHours = Rule
{ name = "number.number hours"
, pattern =
[ regex "(\\d+)\\.(\\d+) óra"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (h:m:_)):_) -> do
hh <- parseInteger h
mnum <- parseInteger m
let mden = 10 ^ Text.length m
Just . Token Duration $ minutesFromHourMixedFraction hh mnum mden
_ -> Nothing
}
ruleDurationAndHalfHour :: Rule
ruleDurationAndHalfHour = Rule
{ name = "<integer> and an half hour"
, pattern =
[ Predicate isNatural
, regex "\x00E9s f\x00E9l[\\s-]?\x00F3ra"
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = v}):_) ->
Just . Token Duration . duration TG.Minute $ 30 + 60 * floor v
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleDurationQuarterOfAnHour
, ruleDurationHalfAnHour
, ruleDurationThreeQuartersOfAnHour
, ruleDurationDotNumeralHours
, ruleDurationAndHalfHour
]

View File

@ -19,4 +19,300 @@ import qualified Data.HashMap.Strict as HashMap
import Data.String
classifiers :: Classifiers
classifiers = HashMap.fromList []
classifiers
= HashMap.fromList
[("Thursday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [("", 0.0)], n = 1},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("integer (numeric)",
Classifier{okData =
ClassData{prior = -1.2205021062771466, unseen = -2.995732273553991,
likelihoods = HashMap.fromList [("", 0.0)], n = 18},
koData =
ClassData{prior = -0.3496737484797488,
unseen = -3.8066624897703196,
likelihoods = HashMap.fromList [("", 0.0)], n = 43}}),
("pm <time-of-day>",
Classifier{okData =
ClassData{prior = 0.0, unseen = -3.1354942159291497,
likelihoods =
HashMap.fromList
[("time-of-day (latent)", -0.6931471805599453),
("hour", -0.6931471805599453)],
n = 10},
koData =
ClassData{prior = -infinity, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [], n = 0}}),
("<time> <part-of-day>",
Classifier{okData =
ClassData{prior = -0.5108256237659907, unseen = -2.995732273553991,
likelihoods =
HashMap.fromList
[("dayhour", -0.9985288301111273),
("todaypart of days", -1.3350010667323402),
("tomorrowpart of days", -2.2512917986064953),
("yesterdaypart of days", -2.2512917986064953)],
n = 6},
koData =
ClassData{prior = -0.916290731874155, unseen = -2.772588722239781,
likelihoods =
HashMap.fromList
[("dayhour", -1.0986122886681098),
("next <day-of-week>part of days", -2.0149030205422647),
("yyyy.mm.ddpart of days", -2.0149030205422647),
("Wednesdaypart of days", -1.6094379124341003)],
n = 4}}),
("today",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.9459101490553135,
likelihoods = HashMap.fromList [("", 0.0)], n = 5},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("month (grain)",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("January",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.6094379124341003,
likelihoods = HashMap.fromList [("", 0.0)], n = 3},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("Wednesday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.0794415416798357,
likelihoods = HashMap.fromList [("", 0.0)], n = 6},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("intersect",
Classifier{okData =
ClassData{prior = -0.40546510810816444,
unseen = -3.713572066704308,
likelihoods =
HashMap.fromList
[("dayhour", -1.0498221244986778),
("yyyy.mm.ddhh:mm", -2.995732273553991),
("Wednesdaypm <time-of-day>", -2.3025850929940455),
("todaypart of days", -2.0794415416798357),
("yyyy.mm.ddpm <time-of-day>", -2.995732273553991),
("dayminute", -2.995732273553991),
("tomorrowpart of days", -2.995732273553991),
("next <day-of-week>pm <time-of-day>", -2.3025850929940455),
("yesterdaypart of days", -2.995732273553991)],
n = 14},
koData =
ClassData{prior = -1.0986122886681098, unseen = -3.295836866004329,
likelihoods =
HashMap.fromList
[("dayhour", -1.1786549963416462),
("next <day-of-week>part of days", -2.5649493574615367),
("Wednesdaypm <time-of-day>", -1.8718021769015913),
("yyyy.mm.ddpart of days", -2.5649493574615367),
("Wednesdaypart of days", -2.159484249353372)],
n = 7}}),
("year (grain)",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("day before yesterday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [("", 0.0)], n = 1},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("Monday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.6094379124341003,
likelihoods = HashMap.fromList [("", 0.0)], n = 3},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("yesterday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("hh:mm:ss",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.6094379124341003,
likelihoods = HashMap.fromList [("", 0.0)], n = 3},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("am <time-of-day>",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.1972245773362196,
likelihoods =
HashMap.fromList
[("time-of-day (latent)", -0.6931471805599453),
("hour", -0.6931471805599453)],
n = 3},
koData =
ClassData{prior = -infinity, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [], n = 0}}),
("end of month",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("tomorrow",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("this|last|next <cycle>",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.5649493574615367,
likelihoods =
HashMap.fromList
[("month (grain)", -1.3862943611198906),
("year (grain)", -1.3862943611198906),
("year", -1.3862943611198906), ("month", -1.3862943611198906)],
n = 4},
koData =
ClassData{prior = -infinity, unseen = -1.6094379124341003,
likelihoods = HashMap.fromList [], n = 0}}),
("next <day-of-week>",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.4849066497880004,
likelihoods =
HashMap.fromList
[("Thursday", -1.7047480922384253),
("Wednesday", -1.0116009116784799),
("day", -0.7884573603642702)],
n = 4},
koData =
ClassData{prior = -infinity, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [], n = 0}}),
("Sunday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.6094379124341003,
likelihoods = HashMap.fromList [("", 0.0)], n = 3},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("time-of-day (latent)",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.70805020110221,
likelihoods = HashMap.fromList [("integer (numeric)", 0.0)],
n = 13},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("hh:mm",
Classifier{okData =
ClassData{prior = -0.6931471805599453, unseen = -1.791759469228055,
likelihoods = HashMap.fromList [("", 0.0)], n = 4},
koData =
ClassData{prior = -0.6931471805599453, unseen = -1.791759469228055,
likelihoods = HashMap.fromList [("", 0.0)], n = 4}}),
("March",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.4849066497880004,
likelihoods = HashMap.fromList [("", 0.0)], n = 10},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("yyyy.mm.dd",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.0794415416798357,
likelihoods = HashMap.fromList [("", 0.0)], n = 6},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("number (0..10)",
Classifier{okData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0},
koData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2}}),
("Tuesday",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [("", 0.0)], n = 1},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("<named-month> <day-of-month> (non ordinal)",
Classifier{okData =
ClassData{prior = 0.0, unseen = -2.5649493574615367,
likelihoods =
HashMap.fromList
[("Marchinteger (numeric)", -0.6931471805599453),
("month", -0.6931471805599453)],
n = 5},
koData =
ClassData{prior = -infinity, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [], n = 0}}),
("ordinal (digits)",
Classifier{okData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0},
koData =
ClassData{prior = 0.0, unseen = -2.1972245773362196,
likelihoods = HashMap.fromList [("", 0.0)], n = 7}}),
("seasons",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [("", 0.0)], n = 1},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("mm.dd",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.791759469228055,
likelihoods = HashMap.fromList [("", 0.0)], n = 4},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("right now",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("end of year",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.3862943611198906,
likelihoods = HashMap.fromList [("", 0.0)], n = 2},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("day after tomorrow",
Classifier{okData =
ClassData{prior = 0.0, unseen = -1.0986122886681098,
likelihoods = HashMap.fromList [("", 0.0)], n = 1},
koData =
ClassData{prior = -infinity, unseen = -0.6931471805599453,
likelihoods = HashMap.fromList [], n = 0}}),
("part of days",
Classifier{okData =
ClassData{prior = -0.40546510810816444,
unseen = -2.4849066497880004,
likelihoods = HashMap.fromList [("", 0.0)], n = 10},
koData =
ClassData{prior = -1.0986122886681098,
unseen = -1.9459101490553135,
likelihoods = HashMap.fromList [("", 0.0)], n = 5}})]

View File

@ -15,21 +15,25 @@ module Duckling.Rules.HU
import Duckling.Dimensions.Types
import Duckling.Types
import qualified Duckling.Duration.HU.Rules as Duration
import qualified Duckling.Numeral.HU.Rules as Numeral
import qualified Duckling.Ordinal.HU.Rules as Ordinal
import qualified Duckling.Time.HU.Rules as Time
import qualified Duckling.TimeGrain.HU.Rules as TimeGrain
rules :: Some Dimension -> [Rule]
rules (This AmountOfMoney) = []
rules (This Distance) = []
rules (This Duration) = []
rules (This Duration) = Duration.rules
rules (This Numeral) = Numeral.rules
rules (This Email) = []
rules (This AmountOfMoney) = []
rules (This Ordinal) = Ordinal.rules
rules (This PhoneNumber) = []
rules (This Quantity) = []
rules (This RegexMatch) = []
rules (This Temperature) = []
rules (This Time) = []
rules (This TimeGrain) = []
rules (This Time) = Time.rules
rules (This TimeGrain) = TimeGrain.rules
rules (This Url) = []
rules (This Volume) = []

176
Duckling/Time/HU/Corpus.hs Normal file
View File

@ -0,0 +1,176 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE OverloadedStrings #-}
module Duckling.Time.HU.Corpus
( corpus
) where
import Data.String
import Prelude
import Duckling.Lang
import Duckling.Resolve
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 = HU}, allExamples)
allExamples :: [Example]
allExamples = concat
[ examples (datetime (2013, 2, 12, 4, 30, 0) Second)
[ "most"
, "épp most"
]
, examples (datetime (2013, 2, 12, 0, 0, 0) Day)
[ "ma"
]
, examples (datetime (2013, 2, 13, 0, 0, 0) Day)
[ "holnap"
]
, examples (datetime (2013, 2, 14, 0, 0, 0) Day)
[ "holnapután"
]
, examples (datetime (2013, 2, 11, 0, 0, 0) Day)
[ "tegnap"
]
, examples (datetime (2013, 2, 10, 0, 0, 0) Day)
[ "tegnapelőtt"
]
, examples (datetime (2013, 3, 1, 0, 0, 0) Month)
[ "hónap vége"
, "a hónap vége"
]
, examples (datetime (2014, 1, 1, 0, 0, 0) Year)
[ "év vége"
, "az év vége"
]
, examples (datetime (2013, 2, 18, 0, 0, 0) Day)
[ "hétfő"
, "hét"
, "hét."
]
, examples (datetime (2013, 2, 19, 0, 0, 0) Day)
[ "kedd"
]
, examples (datetime (2013, 2, 17, 0, 0, 0) Day)
[ "vasárnap"
, "vas"
, "vas."
]
, examples (datetime (2014, 1, 1, 0, 0, 0) Month)
[ "január"
, "jan"
, "jan."
]
, examples (datetime (2013, 3, 1, 0, 0, 0) Month)
[ "március"
, "már"
, "már."
, "márc"
, "márc"
]
, examples (datetime (2013, 3, 15, 0, 0, 0) Day)
[ "március 15"
, "már 15"
, "már. 15"
, "márc 15"
, "márc. 15"
]
, examples (datetime (2013, 3, 1, 0, 0, 0) Month)
[ "következő hónap"
, "jövő hónap"
]
, examples (datetime (2012, 1, 1, 0, 0, 0) Year)
[ "előző év"
, "múlt év"
]
, examples (datetime (2013, 2, 21, 0, 0, 0) Day)
[ "jövő csütörtök"
]
, examples (datetime (2013, 2, 12, 15, 20, 0) Minute)
[ "15:20"
]
, examples (datetime (2013, 2, 12, 8, 20, 0) Minute)
[ "08:20"
, "8:20"
]
, examples (datetime (2013, 2, 12, 15, 20, 44) Second)
[ "15:20:44"
]
, examples (datetime (2013, 2, 12, 8, 20, 44) Second)
[ "08:20:44"
, "8:20:44"
]
, examples (datetime (2013, 2, 12, 11, 0, 0) Hour)
[ "de 11"
, "de. 11"
, "délelőtt 11"
]
, examples (datetime (2013, 2, 12, 23, 0, 0) Hour)
[ "du 11"
, "du. 11"
, "délután 11"
]
, examples (datetime (2013, 2, 13, 23, 0, 0) Hour)
[ "szerda du 11"
, "szerda du. 11"
, "szerda délután 11"
]
, examples (datetime (2013, 2, 20, 23, 0, 0) Hour)
[ "jövő szerda du 11"
, "jövő szerda du. 11"
, "jövő szerda délután 11"
]
, examples (datetime (2013, 8, 20, 0, 0, 0) Day)
[ "2013.08.20"
, "2013 . 08 . 20"
, "2013-08-20"
, "2013 - 08 - 20"
]
, examples (datetime (2013, 8, 20, 11, 45, 0) Minute)
[ "2013.08.20 11:45"
]
, examples (datetime (2013, 8, 20, 17, 0, 0) Hour)
[ "2013.08.20 délután 5"
]
, examples (datetime (2013, 8, 20, 0, 0, 0) Day)
[ "08.20"
, "08 . 20"
, "08-20"
, "08 - 20"
]
, examples (datetimeInterval ((2013, 2, 12, 6, 0, 0), (2013, 2, 12, 10, 0, 0)) Hour)
[ "ma reggel"
, "reggel"
]
, examples (datetimeInterval ((2013, 2, 13, 8, 0, 0), (2013, 2, 13, 12, 0, 0)) Hour)
[ "holnap délelőtt"
]
, examples (datetimeInterval ((2013, 2, 11, 12, 0, 0), (2013, 2, 11, 13, 0, 0)) Hour)
[ "tegnap délben"
]
, examples (datetimeInterval ((2013, 2, 12, 12, 0, 0), (2013, 2, 12, 18, 0, 0)) Hour)
[ "ma délután"
, "délután"
]
, examples (datetimeInterval ((2013, 2, 12, 16, 0, 0), (2013, 2, 12, 20, 0, 0)) Hour)
[ "ma este"
, "este"
]
, examples (datetimeInterval ((2013, 2, 12, 20, 0, 0), (2013, 2, 12, 23, 0, 0)) Hour)
[ "ma éjszaka"
, "éjszaka"
]
, examples (datetimeInterval ((2013, 6, 21, 0, 0, 0), (2013, 9, 24, 0, 0, 0)) Day)
[ "nyár"
]
]

326
Duckling/Time/HU/Rules.hs Normal file
View File

@ -0,0 +1,326 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}
module Duckling.Time.HU.Rules
( rules ) where
import Control.Monad (liftM2)
import Data.Maybe
import Data.String
import Data.Text (Text)
import Prelude
import qualified Data.Text as Text
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Regex.Types
import Duckling.Types
import Duckling.Time.Helpers
import qualified Duckling.Time.Types as TTime
import qualified Duckling.TimeGrain.Types as TG
ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ Predicate isNotLatent
, Predicate isNotLatent
]
, prod = \tokens -> case tokens of
(Token Time td1:Token Time td2:_) -> Token Time <$> intersect td1 td2
_ -> Nothing
}
instants :: [(Text, String, TG.Grain, Int)]
instants =
[ ("right now", "((\x00E9pp )?most)|azonnal", TG.Second, 0 )
, ("today", "ma", TG.Day, 0 )
, ("tomorrow", "holnap", TG.Day, 1 )
, ("day after tomorrow", "holnaput\x00E1n", TG.Day, 2 )
, ("yesterday", "tegnap", TG.Day, -1 )
, ("day before yesterday", "tegnapel\x0151tt", TG.Day, -2 )
, ("end of month", "(a )?h\x00F3nap v\x00E9ge", TG.Month, 1 )
, ("end of year", "(az )?\x00E9v v\x00E9ge", TG.Year, 1 )
]
ruleInstants :: [Rule]
ruleInstants = map go instants
where
go (name, regexPattern, grain, n) = Rule
{ name = name
, pattern = [regex regexPattern]
, prod = \_ -> tt $ cycleNth grain n
}
daysOfWeek :: [(Text, String)]
daysOfWeek =
[ ( "Monday" , "h\x00E9tf\x0151|h\x00E9t\\.?" )
, ( "Tuesday" , "kedd" )
, ( "Wednesday", "szerda|szer\\.?" )
, ( "Thursday" , "cs\x00FCt\x00F6rt\x00F6k|cs\x00FCt\\.?" )
, ( "Friday" , "p\x00E9ntek|p\x00E9n\\.?" )
, ( "Saturday" , "szombat|szom\\.?" )
, ( "Sunday" , "vas\x00E1rnap|vas\\.?" )
]
ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = zipWith go daysOfWeek [1..7]
where
go (name, regexPattern) i = Rule
{ name = name
, pattern = [regex regexPattern]
, prod = \_ -> tt $ dayOfWeek i
}
months :: [(Text, String)]
months =
[ ( "January" , "janu\x00E1r|jan\\.?" )
, ( "February" , "febru\x00E1r|febr?\\.?" )
, ( "March" , "m\x00E1rcius|m\x00E1rc?\\.?" )
, ( "April" , "\x00E1prilis|\x00E1pr\\.?" )
, ( "May" , "m\x00E1jus|m\x00E1j\\.?" )
, ( "June" , "j\x00FAnius|j\x00FAn\\.?" )
, ( "July" , "j\x00FAlius|j\x00FAl\\.?" )
, ( "August" , "augusztus|aug\\.?" )
, ( "September", "szeptember|szept?\\.?" )
, ( "October" , "okt\x00F3ber|okt\\.?" )
, ( "November" , "november|nov\\.?" )
, ( "December" , "december|dec\\.?" )
]
ruleMonths :: [Rule]
ruleMonths = zipWith go months [1..12]
where
go (name, regexPattern) i = Rule
{ name = name
, pattern = [regex regexPattern]
, prod = \_ -> tt $ month i
}
ruleMonthDOMNumeral :: Rule
ruleMonthDOMNumeral = Rule
{ name = "<named-month> <day-of-month> (non ordinal)"
, pattern =
[ Predicate isAMonth
, Predicate isDOMInteger
]
, prod = \tokens -> case tokens of
(Token Time td:token:_) -> Token Time <$> intersectDOM td token
_ -> Nothing
}
ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext = Rule
{ name = "this|last|next <cycle>"
, pattern =
[ regex "(most|el\x0151z\x0151|m\x00FAlt|k\x00F6vetkez\x0151|j\x00F6v\x0151)"
, dimension TimeGrain
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):Token TimeGrain grain:_) ->
case Text.toLower match of
"most" -> tt $ cycleNth grain 0
"el\x0151z\x0151" -> tt . cycleNth grain $ - 1
"m\x00FAlt" -> tt . cycleNth grain $ - 1
"k\x00F6vetkez\x0151" -> tt $ cycleNth grain 1
"j\x00F6v\x0151" -> tt $ cycleNth grain 1
_ -> Nothing
_ -> Nothing
}
ruleNextDOW :: Rule
ruleNextDOW = Rule
{ name = "next <day-of-week>"
, pattern =
[ regex "j\x00F6v\x0151"
, Predicate isADayOfWeek
]
, prod = \tokens -> case tokens of
(_:Token Time td:_) -> tt $ predNth 1 True td
_ -> Nothing
}
ruleHHMM :: Rule
ruleHHMM = Rule
{ name = "hh:mm"
, pattern =
[ regex "((?:[01]?\\d)|(?:2[0-3]))[:.]([0-5]\\d)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (hh:mm:_)):_) -> do
h <- parseInt hh
m <- parseInt mm
tt $ hourMinute True h m
_ -> Nothing
}
ruleHHMMSS :: Rule
ruleHHMMSS = Rule
{ name = "hh:mm:ss"
, pattern =
[ regex "((?:[01]?\\d)|(?:2[0-3]))[:.]([0-5]\\d)[:.]([0-5]\\d)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (hh:mm:ss:_)):_) -> do
h <- parseInt hh
m <- parseInt mm
s <- parseInt ss
tt $ hourMinuteSecond True h m s
_ -> Nothing
}
ruleTODLatent :: Rule
ruleTODLatent = Rule
{ name = "time-of-day (latent)"
, pattern =
[ Predicate $ liftM2 (&&) isNumeralSafeToUse (isIntegerBetween 0 23)
]
, prod = \tokens -> case tokens of
(token:_) -> do
n <- getIntValue token
tt . mkLatent $ hour True n
_ -> Nothing
}
ruleTODAM :: Rule
ruleTODAM = Rule
{ name = "am <time-of-day>"
, pattern =
[ regex "(de\\.?|d\x00E9lel\x0151tt)"
, Predicate isATimeOfDay
]
, prod = \tokens -> case tokens of
(_:Token Time td:_) ->
tt . timeOfDayAMPM td $ True
_ -> Nothing
}
ruleTODPM :: Rule
ruleTODPM = Rule
{ name = "pm <time-of-day>"
, pattern =
[ regex "(du\\.?|d\x00E9lut\x00E1n)"
, Predicate isATimeOfDay
]
, prod = \tokens -> case tokens of
(_:Token Time td:_) -> tt . timeOfDayAMPM td $ False
_ -> Nothing
}
ruleYYYYMMDD :: Rule
ruleYYYYMMDD = Rule
{ name = "yyyy.mm.dd"
, pattern =
[ regex "(\\d{2,4})\\s?[-\\.]\\s?(0?[1-9]|1[0-2])\\s?[-\\.]\\s?(3[01]|[12]\\d|0?[1-9])"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (yy:mm:dd:_)):_) -> do
y <- parseInt yy
m <- parseInt mm
d <- parseInt dd
tt $ yearMonthDay y m d
_ -> Nothing
}
ruleMMDD :: Rule
ruleMMDD = Rule
{ name = "mm.dd"
, pattern =
[ regex "(0?[1-9]|1[0-2])\\s?[-\\.]\\s?(3[01]|[12]\\d|0?[1-9])"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (mm:dd:_)):_) -> do
m <- parseInt mm
d <- parseInt dd
tt $ monthDay m d
_ -> Nothing
}
rulePartOfDays :: Rule
rulePartOfDays = Rule
{ name = "part of days"
, pattern =
[ regex "(reggel|d\x00E9lel\x0151tt|d\x00E9lben|d\x00E9lut\x00E1n|este|\x00E9jszaka)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> do
let (start, end) = case Text.toLower match of
"reggel" -> (hour False 6, hour False 10)
"d\x00E9lel\x0151tt" -> (hour False 08, hour False 12)
"d\x00E9lben" -> (hour False 12, hour False 13)
"d\x00E9lut\x00E1n" -> (hour False 12, hour False 18)
"este" -> (hour False 16, hour False 20)
_ -> (hour False 20, hour False 23)
td <- interval TTime.Open start end
tt . partOfDay $ td
_ -> Nothing
}
-- Since part of days are latent, general time intersection is blocked
ruleTimePOD :: Rule
ruleTimePOD = Rule
{ name = "<time> <part-of-day>"
, pattern =
[ dimension Time
, Predicate isAPartOfDay
]
, prod = \tokens -> case tokens of
(Token Time td:Token Time pod:_) -> Token Time <$> intersect pod td
_ -> Nothing
}
ruleSeasons :: Rule
ruleSeasons = Rule
{ name = "seasons"
, pattern =
[ regex "(ny\x00E1r|\x0151sz|t\x00E9l|tavasz)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> do
start <- case Text.toLower match of
"ny\x00E1r" -> Just $ monthDay 6 21
"\x0151sz" -> Just $ monthDay 9 23
"t\x00E9l" -> Just $ monthDay 12 21
"tavasz" -> Just $ monthDay 3 20
_ -> Nothing
end <- case Text.toLower match of
"ny\x00E1r" -> Just $ monthDay 9 23
"\x0151sz" -> Just $ monthDay 12 21
"t\x00E9l" -> Just $ monthDay 3 20
"tavasz" -> Just $ monthDay 6 21
_ -> Nothing
Token Time <$> interval TTime.Open start end
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleIntersect
, ruleMonthDOMNumeral
, ruleCycleThisLastNext
, ruleNextDOW
, ruleHHMM
, ruleHHMMSS
, ruleTODLatent
, ruleTODAM
, ruleTODPM
, ruleYYYYMMDD
, ruleMMDD
, rulePartOfDays
, ruleTimePOD
, ruleSeasons
]
++ ruleInstants
++ ruleDaysOfWeek
++ ruleMonths

View File

@ -0,0 +1,40 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
{-# LANGUAGE OverloadedStrings #-}
module Duckling.TimeGrain.HU.Rules
( rules ) where
import Data.String
import Data.Text (Text)
import Prelude
import Duckling.Dimensions.Types
import Duckling.Types
import qualified Duckling.TimeGrain.Types as TG
grains :: [(Text, String, TG.Grain)]
grains = [ ("second (grain) ", "m\x00E1sodperc(ek)?|mp", TG.Second)
, ("minute (grain)" , "perc(ek)?", TG.Minute)
, ("hour (grain)" , "\x00F3ra|\x00F3r\x00E1k", TG.Hour)
, ("day (grain)" , "nap(ok)?", TG.Day)
, ("week (grain)" , "h\x00E9t|hetek", TG.Week)
, ("month (grain)" , "h\x00F3nap|h\x00F3napok", TG.Month)
, ("quarter (grain)", "negyed\\s?\x00E9v(ek)?", TG.Quarter)
, ("year (grain)" , "\x00E9v(ek)?", TG.Year)
]
rules :: [Rule]
rules = map go grains
where
go (name, regexPattern, grain) = Rule
{ name = name
, pattern = [regex regexPattern]
, prod = \_ -> Just $ Token TimeGrain grain
}

View File

@ -210,6 +210,8 @@ library
, Duckling.Duration.GA.Rules
, Duckling.Duration.HE.Rules
, Duckling.Duration.HR.Rules
, Duckling.Duration.HU.Corpus
, Duckling.Duration.HU.Rules
, Duckling.Duration.IT.Rules
, Duckling.Duration.JA.Corpus
, Duckling.Duration.KO.Corpus
@ -430,6 +432,8 @@ library
, Duckling.Time.HR.Rules
, Duckling.Time.HE.Corpus
, Duckling.Time.HE.Rules
, Duckling.Time.HU.Corpus
, Duckling.Time.HU.Rules
, Duckling.Time.IT.Corpus
, Duckling.Time.IT.Rules
, Duckling.Time.KO.Corpus
@ -463,6 +467,7 @@ library
, Duckling.TimeGrain.GA.Rules
, Duckling.TimeGrain.HE.Rules
, Duckling.TimeGrain.HR.Rules
, Duckling.TimeGrain.HU.Rules
, Duckling.TimeGrain.IT.Rules
, Duckling.TimeGrain.JA.Rules
, Duckling.TimeGrain.KO.Rules
@ -584,6 +589,7 @@ test-suite duckling-test
, Duckling.Duration.EN.Tests
, Duckling.Duration.FR.Tests
, Duckling.Duration.GA.Tests
, Duckling.Duration.HU.Tests
, Duckling.Duration.JA.Tests
, Duckling.Duration.KO.Tests
, Duckling.Duration.NB.Tests
@ -698,6 +704,7 @@ test-suite duckling-test
, Duckling.Time.GA.Tests
, Duckling.Time.HR.Tests
, Duckling.Time.HE.Tests
, Duckling.Time.HU.Tests
, Duckling.Time.IT.Tests
, Duckling.Time.KO.Tests
, Duckling.Time.NB.Tests

View File

@ -34,6 +34,7 @@ import qualified Duckling.Time.FR.Corpus as FRTime
import qualified Duckling.Time.GA.Corpus as GATime
import qualified Duckling.Time.HR.Corpus as HRTime
import qualified Duckling.Time.HE.Corpus as HETime
import qualified Duckling.Time.HU.Corpus as HUTime
import qualified Duckling.Time.IT.Corpus as ITTime
import qualified Duckling.Time.KO.Corpus as KOTime
import qualified Duckling.Time.NB.Corpus as NBTime
@ -80,7 +81,7 @@ regenClassifiers lang = do
GA -> GATime.corpus
HR -> HRTime.corpus
HE -> HETime.corpus
HU -> (testContext, [])
HU -> HUTime.corpus
ID -> (testContext, [])
IT -> ITTime.corpus
JA -> (testContext, [])

View File

@ -0,0 +1,24 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
module Duckling.Duration.HU.Tests
( tests
) where
import Data.String
import Prelude
import Test.Tasty
import Duckling.Dimensions.Types
import Duckling.Duration.HU.Corpus
import Duckling.Testing.Asserts
tests :: TestTree
tests = testGroup "HU Tests"
[ makeCorpusTest [This Duration] corpus
]

View File

@ -17,6 +17,7 @@ import Test.Tasty
import qualified Duckling.Duration.EN.Tests as EN
import qualified Duckling.Duration.FR.Tests as FR
import qualified Duckling.Duration.GA.Tests as GA
import qualified Duckling.Duration.HU.Tests as HU
import qualified Duckling.Duration.JA.Tests as JA
import qualified Duckling.Duration.KO.Tests as KO
import qualified Duckling.Duration.NB.Tests as NB
@ -32,6 +33,7 @@ tests = testGroup "Duration Tests"
[ EN.tests
, FR.tests
, GA.tests
, HU.tests
, JA.tests
, KO.tests
, NB.tests

View File

@ -0,0 +1,22 @@
-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree. An additional grant
-- of patent rights can be found in the PATENTS file in the same directory.
module Duckling.Time.HU.Tests
( tests ) where
import Data.String
import Prelude
import Test.Tasty
import Duckling.Dimensions.Types
import Duckling.Testing.Asserts
import Duckling.Time.HU.Corpus
tests :: TestTree
tests = testGroup "HU Tests"
[ makeCorpusTest [This Time] corpus
]

View File

@ -32,6 +32,7 @@ import qualified Duckling.Time.FR.Tests as FR
import qualified Duckling.Time.GA.Tests as GA
import qualified Duckling.Time.HR.Tests as HR
import qualified Duckling.Time.HE.Tests as HE
import qualified Duckling.Time.HU.Tests as HU
import qualified Duckling.Time.IT.Tests as IT
import qualified Duckling.Time.KO.Tests as KO
import qualified Duckling.Time.NB.Tests as NB
@ -52,6 +53,7 @@ tests = testGroup "Time Tests"
, GA.tests
, HR.tests
, HE.tests
, HU.tests
, IT.tests
, KO.tests
, NB.tests