mirror of
https://github.com/facebook/duckling.git
synced 2024-11-30 23:33:33 +03:00
Distance interval support.
Summary: Interval support for distances (common types + EN rules). Reviewed By: patapizza Differential Revision: D6942340 fbshipit-source-id: d05ff337167b11c9186f38ca04bacf0d24a41526
This commit is contained in:
parent
c8501d3e85
commit
1f7290880c
@ -25,36 +25,36 @@ corpus = (testContext {locale = makeLocale CS Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilometry"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 mil"
|
||||
, "osm mil"
|
||||
]
|
||||
, examples (DistanceValue Metre 1)
|
||||
, examples (simple Metre 1)
|
||||
[ "1m"
|
||||
, "1 metr"
|
||||
]
|
||||
, examples (DistanceValue Metre 2)
|
||||
, examples (simple Metre 2)
|
||||
[ "2m"
|
||||
, "2 metry"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9 metrů"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 1)
|
||||
, examples (simple Centimetre 1)
|
||||
[ "1cm"
|
||||
, "1 centimetr"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centimetry"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 9)
|
||||
, examples (simple Centimetre 9)
|
||||
[ "9cm"
|
||||
, "9 centimetrů"
|
||||
]
|
||||
|
@ -22,29 +22,50 @@ corpus = (testContext, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilometers"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
, "3.0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 miles"
|
||||
, "eight mile"
|
||||
, "8 mi"
|
||||
]
|
||||
, examples (DistanceValue M 9)
|
||||
, examples (simple M 9)
|
||||
[ "9m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centimeters"
|
||||
]
|
||||
, examples (DistanceValue Inch 5)
|
||||
, examples (simple Inch 5)
|
||||
[ "5 in"
|
||||
, "5''"
|
||||
, "five inches"
|
||||
, "5\""
|
||||
]
|
||||
, examples (simple Metre 1.87)
|
||||
[ "1.87 meters"
|
||||
]
|
||||
, examples (between Kilometre (3, 5))
|
||||
[ "between 3 and 5 kilometers"
|
||||
, "from 3km to 5km"
|
||||
, "around 3-5 kilometers"
|
||||
, "about 3km-5km"
|
||||
, "3-5 kilometers"
|
||||
]
|
||||
, examples (under Mile 3.5)
|
||||
[ "under 3.5 miles"
|
||||
, "less than 3.5mi"
|
||||
, "lower than three point five miles"
|
||||
]
|
||||
, examples (above Inch 5)
|
||||
[ "more than five inches"
|
||||
, "at least 5''"
|
||||
, "over 5\""
|
||||
, "above 5 in"
|
||||
]
|
||||
]
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Duckling.Distance.EN.Rules
|
||||
@ -20,19 +21,22 @@ import Prelude
|
||||
import Duckling.Dimensions.Types
|
||||
import Duckling.Distance.Helpers
|
||||
import Duckling.Distance.Types (DistanceData(..))
|
||||
import qualified Duckling.Distance.Types as TDistance
|
||||
import Duckling.Numeral.Helpers
|
||||
import Duckling.Numeral.Types (NumeralData (..))
|
||||
import Duckling.Types
|
||||
import qualified Duckling.Distance.Types as TDistance
|
||||
import qualified Duckling.Numeral.Types as TNumeral
|
||||
|
||||
ruleDistanceFeetInch :: Rule
|
||||
ruleDistanceFeetInch = Rule
|
||||
{ name = "<distance|feet> <distance|inch>"
|
||||
, pattern =
|
||||
[ unitDistance TDistance.Foot
|
||||
, unitDistance TDistance.Inch
|
||||
[ Predicate $ isDistanceOfUnit TDistance.Foot
|
||||
, Predicate $ isDistanceOfUnit TDistance.Inch
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(Token Distance DistanceData {TDistance.value = feet}:
|
||||
Token Distance DistanceData {TDistance.value = inches}:
|
||||
, prod = \case
|
||||
(Token Distance DistanceData {TDistance.value = Just feet}:
|
||||
Token Distance DistanceData {TDistance.value = Just inches}:
|
||||
_) -> Just . Token Distance . withUnit TDistance.Inch . distance $
|
||||
feet * 12 + inches
|
||||
_ -> Nothing
|
||||
@ -42,30 +46,42 @@ ruleDistanceFeetAndInch :: Rule
|
||||
ruleDistanceFeetAndInch = Rule
|
||||
{ name = "<distance|feet> and <distance|inch>"
|
||||
, pattern =
|
||||
[ unitDistance TDistance.Foot
|
||||
[ Predicate $ isDistanceOfUnit TDistance.Foot
|
||||
, regex "and"
|
||||
, unitDistance TDistance.Inch
|
||||
, Predicate $ isDistanceOfUnit TDistance.Inch
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(Token Distance DistanceData {TDistance.value = feet}:
|
||||
, prod = \case
|
||||
(Token Distance DistanceData {TDistance.value = Just feet}:
|
||||
_:
|
||||
Token Distance DistanceData {TDistance.value = inches}:
|
||||
Token Distance DistanceData {TDistance.value = Just inches}:
|
||||
_) -> Just . Token Distance . withUnit TDistance.Inch . distance $
|
||||
feet * 12 + inches
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
distances :: [(Text, String, TDistance.Unit)]
|
||||
distances = [ ("<latent dist> km", "k(ilo)?m?(eter)?s?", TDistance.Kilometre)
|
||||
, ("<latent dist> feet", "('|f(oo|ee)?ts?)", TDistance.Foot)
|
||||
, ("<latent dist> inch", "(\"|''|in(ch(es)?)?)", TDistance.Inch)
|
||||
, ("<latent dist> yard", "y(ar)?ds?", TDistance.Yard)
|
||||
, ("<dist> meters", "meters?", TDistance.Metre)
|
||||
, ("<dist> centimeters", "cm|centimeters?", TDistance.Centimetre)
|
||||
, ("<dist> miles", "mi(le(s)?)?", TDistance.Mile)
|
||||
, ("<dist> m (ambiguous miles or meters)", "m", TDistance.M)
|
||||
distances = [ ("km", "k(ilo)?m?(eter)?s?", TDistance.Kilometre)
|
||||
, ("feet", "('|f(oo|ee)?ts?)", TDistance.Foot)
|
||||
, ("inch", "(\"|''|in(ch(es)?)?)", TDistance.Inch)
|
||||
, ("yard", "y(ar)?ds?", TDistance.Yard)
|
||||
, ("meters", "meters?", TDistance.Metre)
|
||||
, ("centimeters", "cm|centimeters?", TDistance.Centimetre)
|
||||
, ("miles", "mi(le(s)?)?", TDistance.Mile)
|
||||
, ("m (ambiguous miles or meters)", "m", TDistance.M)
|
||||
]
|
||||
|
||||
rulePrecision :: Rule
|
||||
rulePrecision = Rule
|
||||
{ name = "about|exactly <dist>"
|
||||
, pattern =
|
||||
[ regex "exactly|precisely|about|approx(\\.|imately)?|close to| near( to)?|around|almost"
|
||||
, dimension Distance
|
||||
]
|
||||
, prod = \case
|
||||
(_:token:_) -> Just token
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleDistances :: [Rule]
|
||||
ruleDistances = map go distances
|
||||
where
|
||||
@ -73,14 +89,120 @@ ruleDistances = map go distances
|
||||
go (name, regexPattern, u) = Rule
|
||||
{ name = name
|
||||
, pattern = [ dimension Distance, regex regexPattern ]
|
||||
, prod = \tokens -> case tokens of
|
||||
, prod = \case
|
||||
(Token Distance dd:_) -> Just . Token Distance $ withUnit u dd
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalBetweenNumeral :: Rule
|
||||
ruleIntervalBetweenNumeral = Rule
|
||||
{ name = "between|from <numeral> to|and <dist>"
|
||||
, pattern =
|
||||
[ regex "between|from"
|
||||
, Predicate isPositive
|
||||
, regex "to|and"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(_:
|
||||
Token Numeral NumeralData{TNumeral.value = from}:
|
||||
_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u}:
|
||||
_) | from < to ->
|
||||
Just . Token Distance . withInterval (from, to) $ unitOnly u
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalBetween :: Rule
|
||||
ruleIntervalBetween = Rule
|
||||
{ name = "between|from <dist> to|and <dist>"
|
||||
, pattern =
|
||||
[ regex "between|from"
|
||||
, Predicate isSimpleDistance
|
||||
, regex "to|and"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(_:
|
||||
Token Distance DistanceData{TDistance.value = Just from, TDistance.unit = Just u1}:
|
||||
_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u2}:
|
||||
_) | from < to && u1 == u2 ->
|
||||
Just . Token Distance . withInterval (from, to) $ unitOnly u1
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalNumeralDash :: Rule
|
||||
ruleIntervalNumeralDash = Rule
|
||||
{ name = "<numeral> - <dist>"
|
||||
, pattern =
|
||||
[ Predicate isPositive
|
||||
, regex "-"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(Token Numeral NumeralData{TNumeral.value = from}:
|
||||
_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u}:
|
||||
_) | from < to ->
|
||||
Just . Token Distance . withInterval (from, to) $ unitOnly u
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalDash :: Rule
|
||||
ruleIntervalDash = Rule
|
||||
{ name = "<dist> - <dist>"
|
||||
, pattern =
|
||||
[ Predicate isSimpleDistance
|
||||
, regex "-"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(Token Distance DistanceData{TDistance.value = Just from, TDistance.unit = Just u1}:
|
||||
_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u2}:
|
||||
_) | from < to && u1 == u2 ->
|
||||
Just . Token Distance . withInterval (from, to) $ unitOnly u1
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalMax :: Rule
|
||||
ruleIntervalMax = Rule
|
||||
{ name = "under/less/lower/no more than <dist>"
|
||||
, pattern =
|
||||
[ regex "under|(less|lower|not? more) than"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u}:
|
||||
_) -> Just . Token Distance . withMax to $ unitOnly u
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleIntervalMin :: Rule
|
||||
ruleIntervalMin = Rule
|
||||
{ name = "over/above/at least/more than <dist>"
|
||||
, pattern =
|
||||
[ regex "over|above|at least|more than"
|
||||
, Predicate isSimpleDistance
|
||||
]
|
||||
, prod = \case
|
||||
(_:
|
||||
Token Distance DistanceData{TDistance.value = Just to, TDistance.unit = Just u}:
|
||||
_) -> Just . Token Distance . withMin to $ unitOnly u
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
rules :: [Rule]
|
||||
rules =
|
||||
[ ruleDistanceFeetInch
|
||||
, ruleDistanceFeetAndInch
|
||||
]
|
||||
, ruleIntervalBetweenNumeral
|
||||
, ruleIntervalBetween
|
||||
, ruleIntervalMax
|
||||
, ruleIntervalMin
|
||||
, ruleIntervalNumeralDash
|
||||
, ruleIntervalDash
|
||||
, rulePrecision]
|
||||
++ ruleDistances
|
||||
|
@ -25,24 +25,24 @@ corpus = (testContext {locale = makeLocale ES Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilómetros"
|
||||
, "3 kilometros"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 miles"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9 metros"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centímetros"
|
||||
]
|
||||
|
@ -24,24 +24,24 @@ corpus = (testContext {locale = makeLocale FR Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilomètres"
|
||||
, "3 kilometres"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 miles"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9 metres"
|
||||
, "9m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centimetres"
|
||||
]
|
||||
|
@ -24,23 +24,23 @@ corpus = (testContext {locale = makeLocale GA Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 ciliméadair"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3.0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 mhíle"
|
||||
, "8 míle"
|
||||
]
|
||||
, examples (DistanceValue M 9)
|
||||
, examples (simple M 9)
|
||||
[ "9m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 cheintiméadar"
|
||||
]
|
||||
|
@ -23,22 +23,22 @@ corpus = (testContext {locale = makeLocale HR Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilometra"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 milja"
|
||||
]
|
||||
, examples (DistanceValue M 9)
|
||||
, examples (simple M 9)
|
||||
[ "9m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centimetra"
|
||||
]
|
||||
|
@ -8,34 +8,64 @@
|
||||
|
||||
{-# LANGUAGE GADTs #-}
|
||||
|
||||
|
||||
module Duckling.Distance.Helpers
|
||||
( distance
|
||||
, unitDistance
|
||||
, isDistanceOfUnit
|
||||
, isSimpleDistance
|
||||
, unitOnly
|
||||
, withInterval
|
||||
, withMax
|
||||
, withMin
|
||||
, withUnit
|
||||
, withValue
|
||||
) where
|
||||
|
||||
|
||||
import Prelude
|
||||
|
||||
import Duckling.Dimensions.Types
|
||||
import Duckling.Distance.Types (DistanceData(..))
|
||||
import qualified Duckling.Distance.Types as TDistance
|
||||
import Duckling.Types
|
||||
import qualified Duckling.Distance.Types as TDistance
|
||||
|
||||
-- -----------------------------------------------------------------
|
||||
-- Patterns
|
||||
|
||||
unitDistance :: TDistance.Unit -> PatternItem
|
||||
unitDistance value = Predicate $ \x -> case x of
|
||||
(Token Distance DistanceData {TDistance.unit = Just unit}) -> value == unit
|
||||
_ -> False
|
||||
isSimpleDistance :: Predicate
|
||||
isSimpleDistance (Token Distance DistanceData {TDistance.value = Just _
|
||||
, TDistance.unit = Just _}) = True
|
||||
isSimpleDistance _ = False
|
||||
|
||||
isDistanceOfUnit :: TDistance.Unit -> Predicate
|
||||
isDistanceOfUnit unit (Token Distance DistanceData {TDistance.unit = Just u}) = unit == u
|
||||
isDistanceOfUnit _ _ = False
|
||||
|
||||
-- -----------------------------------------------------------------
|
||||
-- Production
|
||||
|
||||
distance :: Double -> DistanceData
|
||||
distance x = DistanceData {TDistance.value = x, TDistance.unit = Nothing}
|
||||
distance x = DistanceData {TDistance.value = Just x
|
||||
, TDistance.unit = Nothing
|
||||
, TDistance.minValue = Nothing
|
||||
, TDistance.maxValue = Nothing}
|
||||
|
||||
unitOnly :: TDistance.Unit -> DistanceData
|
||||
unitOnly u = DistanceData {TDistance.unit = Just u
|
||||
, TDistance.value = Nothing
|
||||
, TDistance.minValue = Nothing
|
||||
, TDistance.maxValue = Nothing}
|
||||
|
||||
withUnit :: TDistance.Unit -> DistanceData -> DistanceData
|
||||
withUnit value dd = dd {TDistance.unit = Just value}
|
||||
withUnit u dd = dd {TDistance.unit = Just u}
|
||||
|
||||
withValue :: Double -> DistanceData -> DistanceData
|
||||
withValue value dd = dd {TDistance.value = Just value}
|
||||
|
||||
withInterval :: (Double, Double) -> DistanceData -> DistanceData
|
||||
withInterval (from, to) dd = dd {TDistance.minValue = Just from
|
||||
, TDistance.maxValue = Just to}
|
||||
|
||||
withMin :: Double -> DistanceData -> DistanceData
|
||||
withMin from dd = dd {TDistance.minValue = Just from}
|
||||
|
||||
withMax :: Double -> DistanceData -> DistanceData
|
||||
withMax to dd = dd {TDistance.maxValue = Just to}
|
||||
|
@ -24,28 +24,28 @@ corpus = (testContext {locale = makeLocale KO Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 킬로미터"
|
||||
, "3 킬로"
|
||||
, "3 키로"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3.0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 miles"
|
||||
, "8 마일"
|
||||
, "8 마일즈"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9미터"
|
||||
, "9메터"
|
||||
, "구메터"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 센치"
|
||||
, "이센치"
|
||||
|
@ -24,25 +24,25 @@ corpus = (testContext {locale = makeLocale NL Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilometer"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
, "3,0km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 mijl"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9 m"
|
||||
, "9 meter"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 cm"
|
||||
, "2 centimeter"
|
||||
|
@ -24,24 +24,24 @@ corpus = (testContext {locale = makeLocale PT Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilómetros"
|
||||
, "3 kilometros"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3k"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 milhas"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9 metros"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centímetros"
|
||||
]
|
||||
|
@ -24,24 +24,24 @@ corpus = (testContext {locale = makeLocale RO Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 kilometri"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
, "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 mile"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9m"
|
||||
, "9 m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2cm"
|
||||
, "2 centimetri"
|
||||
]
|
||||
, examples (DistanceValue Foot 10)
|
||||
, examples (simple Foot 10)
|
||||
[ "zece picioare"
|
||||
]
|
||||
]
|
||||
|
@ -25,41 +25,41 @@ corpus = (testContext {locale = makeLocale RU Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 километра"
|
||||
, "3 км"
|
||||
, "3км"
|
||||
, "3.0 км"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 миль"
|
||||
, "восемь миль"
|
||||
]
|
||||
, examples (DistanceValue Metre 1)
|
||||
, examples (simple Metre 1)
|
||||
[ "1 м",
|
||||
"1 метр",
|
||||
"один метр"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2см"
|
||||
, "2 сантиметра"
|
||||
]
|
||||
, examples (DistanceValue Millimetre 4)
|
||||
, examples (simple Millimetre 4)
|
||||
[ "4мм"
|
||||
, "4 миллиметра"
|
||||
]
|
||||
, examples (DistanceValue Inch 5)
|
||||
, examples (simple Inch 5)
|
||||
[ "5 дюймов"
|
||||
, "5''"
|
||||
, "пять дюймов"
|
||||
, "5\""
|
||||
]
|
||||
, examples (DistanceValue Foot 35)
|
||||
, examples (simple Foot 35)
|
||||
[ "35 футов"
|
||||
, "35'"
|
||||
, "тридцать пять футов"
|
||||
]
|
||||
, examples (DistanceValue Yard 47)
|
||||
, examples (simple Yard 47)
|
||||
[ "47 ярдов"
|
||||
, "сорок семь ярдов"
|
||||
]
|
||||
|
@ -24,26 +24,26 @@ corpus = (testContext {locale = makeLocale TR Nothing}, allExamples)
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (DistanceValue Kilometre 3)
|
||||
[ examples (simple Kilometre 3)
|
||||
[ "3 Kilometre"
|
||||
, "3 kilometre"
|
||||
, "3 km"
|
||||
, "3km"
|
||||
]
|
||||
, examples (DistanceValue Kilometre 3.0)
|
||||
, examples (simple Kilometre 3.0)
|
||||
[ "3,0 km"
|
||||
]
|
||||
, examples (DistanceValue Mile 8)
|
||||
, examples (simple Mile 8)
|
||||
[ "8 Mil"
|
||||
, "8 mil"
|
||||
]
|
||||
, examples (DistanceValue Metre 9)
|
||||
, examples (simple Metre 9)
|
||||
[ "9 Metre"
|
||||
, "9 metre"
|
||||
, "9 m"
|
||||
, "9m"
|
||||
]
|
||||
, examples (DistanceValue Centimetre 2)
|
||||
, examples (simple Centimetre 2)
|
||||
[ "2 Santimetre"
|
||||
, "2 santim"
|
||||
, "2 cm"
|
||||
|
@ -21,6 +21,7 @@ import Data.Hashable
|
||||
import Data.Text (Text)
|
||||
import GHC.Generics
|
||||
import Prelude
|
||||
import qualified Data.HashMap.Strict as H
|
||||
import qualified Data.Text as Text
|
||||
|
||||
import Duckling.Resolve (Resolve(..))
|
||||
@ -41,26 +42,85 @@ instance ToJSON Unit where
|
||||
toJSON = String . Text.toLower . Text.pack . show
|
||||
|
||||
data DistanceData = DistanceData
|
||||
{ unit :: Maybe Unit
|
||||
, value :: Double
|
||||
{ unit :: Maybe Unit
|
||||
, value :: Maybe Double
|
||||
, minValue :: Maybe Double
|
||||
, maxValue :: Maybe Double
|
||||
}
|
||||
deriving (Eq, Generic, Hashable, Ord, Show, NFData)
|
||||
|
||||
instance Resolve DistanceData where
|
||||
type ResolvedValue DistanceData = DistanceValue
|
||||
resolve _ DistanceData {unit = Nothing} = Nothing
|
||||
resolve _ DistanceData {unit = Just unit, value} =
|
||||
Just DistanceValue {vValue = value, vUnit = unit}
|
||||
resolve _ DistanceData {unit = Just unit, value = Just val} =
|
||||
Just $ simple unit val
|
||||
resolve _ DistanceData {unit = Just unit, value = Nothing
|
||||
, minValue = Just from, maxValue = Just to} =
|
||||
Just $ between unit (from, to)
|
||||
resolve _ DistanceData {unit = Just unit, value = Nothing
|
||||
, minValue = Just from, maxValue = Nothing} =
|
||||
Just $ above unit from
|
||||
resolve _ DistanceData {unit = Just unit, value = Nothing
|
||||
, minValue = Nothing, maxValue = Just to} =
|
||||
Just $ under unit to
|
||||
resolve _ _ = Nothing
|
||||
|
||||
data DistanceValue = DistanceValue
|
||||
data IntervalDirection = Above | Under
|
||||
deriving (Eq, Generic, Hashable, Ord, Show, NFData)
|
||||
|
||||
data SingleValue = SingleValue
|
||||
{ vUnit :: Unit
|
||||
, vValue :: Double
|
||||
}
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
instance ToJSON DistanceValue where
|
||||
toJSON (DistanceValue unit value) = object
|
||||
instance ToJSON SingleValue where
|
||||
toJSON (SingleValue unit value) = object
|
||||
[ "type" .= ("value" :: Text)
|
||||
, "value" .= value
|
||||
, "unit" .= unit
|
||||
]
|
||||
|
||||
data DistanceValue
|
||||
= SimpleValue SingleValue
|
||||
| IntervalValue (SingleValue, SingleValue)
|
||||
| OpenIntervalValue (SingleValue, IntervalDirection)
|
||||
deriving (Eq, Ord, Show)
|
||||
|
||||
instance ToJSON DistanceValue where
|
||||
toJSON (SimpleValue value) = case toJSON value of
|
||||
Object o -> Object $ H.insert "type" (toJSON ("value" :: Text)) o
|
||||
_ -> Object H.empty
|
||||
toJSON (IntervalValue (from, to)) = object
|
||||
[ "type" .= ("interval" :: Text)
|
||||
, "from" .= toJSON from
|
||||
, "to" .= toJSON to
|
||||
]
|
||||
toJSON (OpenIntervalValue (from, Above)) = object
|
||||
[ "type" .= ("interval" :: Text)
|
||||
, "from" .= toJSON from
|
||||
]
|
||||
toJSON (OpenIntervalValue (to, Under)) = object
|
||||
[ "type" .= ("interval" :: Text)
|
||||
, "to" .= toJSON to
|
||||
]
|
||||
|
||||
-- -----------------------------------------------------------------
|
||||
-- Value helpers
|
||||
|
||||
simple :: Unit -> Double -> DistanceValue
|
||||
simple u v = SimpleValue $ single u v
|
||||
|
||||
between :: Unit -> (Double, Double) -> DistanceValue
|
||||
between u (from, to) = IntervalValue (single u from, single u to)
|
||||
|
||||
above :: Unit -> Double -> DistanceValue
|
||||
above = openInterval Above
|
||||
|
||||
under :: Unit -> Double -> DistanceValue
|
||||
under = openInterval Under
|
||||
|
||||
openInterval :: IntervalDirection -> Unit -> Double -> DistanceValue
|
||||
openInterval direction u v = OpenIntervalValue (single u v, direction)
|
||||
|
||||
single :: Unit -> Double -> SingleValue
|
||||
single u v = SingleValue {vUnit = u, vValue = v}
|
||||
|
Loading…
Reference in New Issue
Block a user