Added AmountOfMoney Dimension to Russian language

Summary: Closes https://github.com/facebook/duckling/pull/120

Reviewed By: patapizza

Differential Revision: D6520302

Pulled By: panagosg7

fbshipit-source-id: 2c9ac6e15ca3ee90b2bf5911ee62835966fcacd1
This commit is contained in:
Zahar Shimanchik 2017-12-12 12:13:25 -08:00 committed by Facebook Github Bot
parent 6df3b26707
commit 2274e40369
8 changed files with 502 additions and 2 deletions

View File

@ -0,0 +1,168 @@
-- 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.AmountOfMoney.RU.Corpus
( corpus
) where
import Data.String
import Prelude
import Duckling.AmountOfMoney.Types
import Duckling.Locale
import Duckling.Resolve
import Duckling.Testing.Types
corpus :: Corpus
corpus = (testContext {locale = makeLocale RU Nothing}, allExamples)
allExamples :: [Example]
allExamples = concat
[ examples (simple RUB 1)
[ "1 rub"
, "один рубль"
, "1 ₽"
, "1 рубль"
]
, examples (simple RUB 10)
[ "10 рублей"
, "₽ 10"
, "10₽"
, "10RUB"
, "10руб"
, "10 рублей"
, "рублей 10"
, "10 рублях"
]
, examples (simple Dollar 1)
[ "$1"
, "один доллар"
]
, examples (simple Dollar 10)
[ "$10"
, "$ 10"
, "10$"
, "10 долларов"
, "десять долларов"
]
, examples (simple Cent 10)
[ "10 центов"
, "десять пени"
, "десять центов"
, "10 c"
, "10¢"
]
, examples (simple Dollar 1e4)
[ "$10К"
, "10к$"
, "$10,000"
]
, examples (simple USD 3.14)
[ "USD3.14"
, "3.14US$"
, "US$ 3.14"
]
, examples (simple EUR 20)
[ "20\x20ac"
, "20 euros"
, "20 Euro"
, "20 Euros"
, "EUR 20"
, "EUR 20.0"
, "20€"
, "20 €ur"
, "20 евро"
, "Евро 20"
]
, examples (simple Pound 10)
[ "\x00a3\&10"
, "десять фунтов"
]
, examples (simple INR 20)
[ "Rs. 20"
, "Rs 20"
, "20Rs"
, "Rs20"
]
, examples (simple Dollar 20.43)
[ "$20 и 43ц"
, "$20 43"
, "20 долларов 43ц"
, "20 долларов 43 центов"
, "20 долларами 43 центами"
, "20 долларов 43"
, "двадцать долларов и 43"
]
, examples (simple GBP 3.01)
[ "GBP3.01"
, "GBP 3.01"
, "3 GBP 1 пенс"
]
, examples (simple Unnamed 42)
[ "42 бакса"
, "бакса 42"
, "42 баксов"
]
, examples (simple BYN 42)
[ "42 BYN"
]
, examples (simple KWD 42)
[ "42 KWD"
]
, examples (simple LBP 42)
[ "42 LBP"
]
, examples (simple EGP 42)
[ "42 EGP"
]
, examples (simple QAR 42)
[ "42 QAR"
]
, examples (simple SAR 42)
[ "42 SAR"
]
, examples (simple BGN 42)
[ "42 BGN"
]
, examples (simple MYR 42)
[ "42 MYR"
, "42 RM"
, "RM 42"
, "MYR 42"
, "42MYR"
, "42RM"
, "RM42"
, "MYR42"
]
, examples (between Dollar (10, 20))
[ "между 10 и 20 долларами"
, "от 10 долларов до 20"
, "10-20 долларов"
, "между 10 долларами и 20 долларами"
, "от 10 до 20 долларов"
, "10$-20$"
, "10-20 долларов"
]
, examples (under EUR 7)
[ "менее 7 евро"
, "меньше чем 7 EUR"
, "ниже 7€"
, "меньше 7 евро"
, "не больше 7 евро"
, "не более 7 евро"
]
, examples (above Dollar 1.42)
[ "больше чем 1 доллар и сорок два цента"
, "как минимум $1.42"
, "более 1.42 долларов"
, "выше 1 доллара и 42 центов"
, "свыше 1 доллара и 42 центов"
]
]

View File

@ -0,0 +1,296 @@
-- 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.AmountOfMoney.RU.Rules
( rules ) where
import Data.Maybe
import qualified Data.Text as Text
import Prelude
import Data.String
import Duckling.AmountOfMoney.Helpers
import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..))
import Duckling.Dimensions.Types
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney
import qualified Duckling.Numeral.Types as TNumeral
ruleRuble :: Rule
ruleRuble = Rule
{ name = "руб"
, pattern =
[ regex "руб(л(ь|ями|ям|ях|я|ю|(е|ё)м|ей|е|и))?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly RUB
}
rulePounds :: Rule
rulePounds = Rule
{ name = "£"
, pattern =
[ regex "фунт(ами|ам|ах|а|у|ом|е|ы|ов)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Pound
}
ruleDollar :: Rule
ruleDollar = Rule
{ name = "$"
, pattern =
[ regex "долл?ар(ами|ам|ах|а|у|ом|е|ы|ов)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Dollar
}
ruleCent :: Rule
ruleCent = Rule
{ name = "cent"
, pattern =
[ regex "цент(ами|ам|ах|а|у|ом|е|ы|ов)?|пени|пенс(ами|ам|ах|а|у|ом|е|ы|ов)?|ц"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Cent
}
ruleEUR :: Rule
ruleEUR = Rule
{ name = ""
, pattern =
[ regex "евр(о|а)"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly EUR
}
ruleBucks :: Rule
ruleBucks = Rule
{ name = "bucks"
, pattern =
[ regex "бакс(ами|ам|ах|а|у|ом|ах|ы|ов)?"
]
, prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Unnamed
}
ruleIntersectAndXCents :: Rule
ruleIntersectAndXCents = Rule
{ name = "intersect (and X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, regex "и"
, financeWith TAmountOfMoney.currency (== Cent)
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just c}):
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersect :: Rule
ruleIntersect = Rule
{ name = "intersect"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, dimension Numeral
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
Token Numeral (NumeralData {TNumeral.value = c}):
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersectAndNumeral :: Rule
ruleIntersectAndNumeral = Rule
{ name = "intersect (and number)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, regex "и"
, dimension Numeral
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
_:
Token Numeral (NumeralData {TNumeral.value = c}):
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
ruleIntersectXCents :: Rule
ruleIntersectXCents = Rule
{ name = "intersect (X cents)"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, financeWith id $ \x -> case TAmountOfMoney.value x of
Just v | v > 0 -> TAmountOfMoney.currency x == Cent
_ -> False
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney fd:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just c}):
_) -> Just . Token AmountOfMoney $ withCents c fd
_ -> Nothing
}
rulePrecision :: Rule
rulePrecision = Rule
{ name = "about|exactly <amount-of-money>"
, pattern =
[ regex "точно|около|приблизительно|блико( к)?|почти"
, dimension AmountOfMoney
]
, prod = \tokens -> case tokens of
(_:token:_) -> Just token
_ -> Nothing
}
ruleIntervalBetweenNumeral :: Rule
ruleIntervalBetweenNumeral = Rule
{ name = "between|from <numeral> to|and <amount-of-money>"
, pattern =
[ regex "между|от"
, dimension Numeral
, regex "до|и"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
Token Numeral (NumeralData {TNumeral.value = from}):
_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}):
_) ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
ruleIntervalBetweenNumeral2 :: Rule
ruleIntervalBetweenNumeral2 = Rule
{ name = "between|from <amount-of-money> to|and <numeral>"
, pattern =
[ regex "между|от"
, financeWith TAmountOfMoney.value isJust
, regex "до|и"
, dimension Numeral
]
, prod = \tokens -> case tokens of
(_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c}):
_:
Token Numeral (NumeralData {TNumeral.value = to}):
_) ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
ruleIntervalBetween :: Rule
ruleIntervalBetween = Rule
{ name = "between|from <amount-of-money> to|and <amount-of-money>"
, pattern =
[ regex "между|от"
, financeWith TAmountOfMoney.value isJust
, regex "до|и"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}):
_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}):
_) | c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
ruleIntervalNumeralDash :: Rule
ruleIntervalNumeralDash = Rule
{ name = "<numeral> - <amount-of-money>"
, pattern =
[ dimension Numeral
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = from}):
_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}):
_) ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c
_ -> Nothing
}
ruleIntervalDash :: Rule
ruleIntervalDash = Rule
{ name = "<amount-of-money> - <amount-of-money>"
, pattern =
[ financeWith TAmountOfMoney.value isJust
, regex "-"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}):
_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}):
_) | c1 == c2 ->
Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1
_ -> Nothing
}
ruleIntervalMax :: Rule
ruleIntervalMax = Rule
{ name = "under/less/lower/no more than <amount-of-money>"
, pattern =
[ regex "под|((менее|меньше|ниже|не больше|не более)( чем)?)"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}):
_) -> Just . Token AmountOfMoney . withMax to $ currencyOnly c
_ -> Nothing
}
ruleIntervalMin :: Rule
ruleIntervalMin = Rule
{ name = "over/above/at least/more than <amount-of-money>"
, pattern =
[ regex "сверх|как минимум|((с?выше|больше|более)( чем)?)"
, financeWith TAmountOfMoney.value isJust
]
, prod = \tokens -> case tokens of
(_:
Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}):
_) -> Just . Token AmountOfMoney . withMin to $ currencyOnly c
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleBucks
, ruleCent
, ruleDollar
, ruleEUR
, ruleIntersect
, ruleIntersectAndNumeral
, ruleIntersectAndXCents
, ruleIntersectXCents
, ruleIntervalBetweenNumeral
, ruleIntervalBetweenNumeral2
, ruleIntervalBetween
, ruleIntervalMax
, ruleIntervalMin
, ruleIntervalNumeralDash
, ruleIntervalDash
, rulePounds
, rulePrecision
, ruleRuble
]

View File

@ -36,6 +36,7 @@ currencies = HashMap.fromList
, ("aud", AUD)
, ("bgn", BGN)
, ("brl", BRL)
, ("byn", BYN)
, ("¢", Cent)
, ("c", Cent)
, ("$", Dollar)
@ -74,7 +75,9 @@ currencies = HashMap.fromList
, ("ptas", PTS)
, ("pts", PTS)
, ("qar", QAR)
, ("", RUB)
, ("ron", RON)
, ("rub", RUB)
, ("sar", SAR)
, ("sek", SEK)
, ("sgd", SGD)
@ -87,7 +90,7 @@ ruleCurrencies :: Rule
ruleCurrencies = Rule
{ name = "currencies"
, pattern =
[ regex "(aed|aud|bgn|brl|¢|c|\\$|dollars?|egp|(e|€)uro?s?|€|gbp|hrk|idr|inr|¥|jpy|krw|kwd|lbp|myr|rm|nok|£|pta?s?|qar|rs\\.?|ron|rupees?|sar|sek|sgb|us(d|\\$)|vnd|yen)"
[ regex "(aed|aud|bgn|brl|byn|¢|c|\\$|dollars?|egp|(e|€)uro?s?|€|gbp|hrk|idr|inr|¥|jpy|krw|kwd|lbp|myr|rm|nok|£|pta?s?|qar|₽|rs\\.?|ron|rub|rupees?|sar|sek|sgb|us(d|\\$)|vnd|yen)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> do

View File

@ -36,6 +36,7 @@ data Currency
| AUD
| BGN
| BRL
| BYN
| EGP
| EUR
| GBP
@ -51,6 +52,7 @@ data Currency
| PTS
| QAR
| RON
| RUB
| SAR
| SEK
| SGD
@ -67,6 +69,7 @@ instance ToJSON Currency where
toJSON AUD = "AUD"
toJSON BGN = "BGN"
toJSON BRL = "BRL"
toJSON BYN = "BYN"
toJSON EGP = "EGP"
toJSON EUR = "EUR"
toJSON GBP = "GBP"
@ -82,6 +85,7 @@ instance ToJSON Currency where
toJSON PTS = "PTS"
toJSON QAR = "QAR"
toJSON RON = "RON"
toJSON RUB = "RUB"
toJSON SAR = "SAR"
toJSON SEK = "SEK"
toJSON SGD = "SGD"

View File

@ -18,6 +18,7 @@ module Duckling.Rules.RU
import Duckling.Dimensions.Types
import Duckling.Locale
import Duckling.Types
import qualified Duckling.AmountOfMoney.RU.Rules as AmountOfMoney
import qualified Duckling.Distance.RU.Rules as Distance
import qualified Duckling.Duration.RU.Rules as Duration
import qualified Duckling.Numeral.RU.Rules as Numeral
@ -33,7 +34,7 @@ localeRules :: Region -> Some Dimension -> [Rule]
localeRules _ _ = []
langRules :: Some Dimension -> [Rule]
langRules (This AmountOfMoney) = []
langRules (This AmountOfMoney) = AmountOfMoney.rules
langRules (This Distance) = Distance.rules
langRules (This Duration) = Duration.rules
langRules (This Email) = []

View File

@ -177,6 +177,8 @@ library
, Duckling.AmountOfMoney.PT.Rules
, Duckling.AmountOfMoney.RO.Corpus
, Duckling.AmountOfMoney.RO.Rules
, Duckling.AmountOfMoney.RU.Corpus
, Duckling.AmountOfMoney.RU.Rules
, Duckling.AmountOfMoney.SV.Corpus
, Duckling.AmountOfMoney.SV.Rules
, Duckling.AmountOfMoney.VI.Corpus
@ -642,6 +644,7 @@ test-suite duckling-test
, Duckling.AmountOfMoney.NB.Tests
, Duckling.AmountOfMoney.PT.Tests
, Duckling.AmountOfMoney.RO.Tests
, Duckling.AmountOfMoney.RU.Tests
, Duckling.AmountOfMoney.SV.Tests
, Duckling.AmountOfMoney.VI.Tests
, Duckling.AmountOfMoney.Tests

View File

@ -0,0 +1,23 @@
-- 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.AmountOfMoney.RU.Tests
( tests ) where
import Data.String
import Prelude
import Test.Tasty
import Duckling.AmountOfMoney.RU.Corpus
import Duckling.Dimensions.Types
import Duckling.Testing.Asserts
tests :: TestTree
tests = testGroup "RU Tests"
[ makeCorpusTest [This AmountOfMoney] corpus
]

View File

@ -23,6 +23,7 @@ import qualified Duckling.AmountOfMoney.KO.Tests as KO
import qualified Duckling.AmountOfMoney.NB.Tests as NB
import qualified Duckling.AmountOfMoney.PT.Tests as PT
import qualified Duckling.AmountOfMoney.RO.Tests as RO
import qualified Duckling.AmountOfMoney.RU.Tests as RU
import qualified Duckling.AmountOfMoney.SV.Tests as SV
import qualified Duckling.AmountOfMoney.VI.Tests as VI
@ -39,6 +40,7 @@ tests = testGroup "AmountOfMoney Tests"
, NB.tests
, PT.tests
, RO.tests
, RU.tests
, SV.tests
, VI.tests
]