mirror of
https://github.com/facebook/duckling.git
synced 2024-08-17 09:10:29 +03:00
Quantity/PT: Extend quantity to include grams in portuguese (#631)
Summary: I'm using Duckling in my project but I noticed that quantities in kg weren't being detected correctly, though other entities such as numeral/volume were all working as expected. Investigating more I noticed that this was just because in Portuguese the Quantity entity was only configured to detect cups and pounds, never grams. And even for cups/pounds, products weren't being detected correctly. So I've just adapted the rules from English Quantity to work in Portuguese as well, while keeping the cups/pounds too. It's all working as expected now and it's backwards compatible. Pull Request resolved: https://github.com/facebook/duckling/pull/631 Reviewed By: stroxler Differential Revision: D29701339 Pulled By: chessai fbshipit-source-id: fca08a14c50844d418f101b885ca54554d993f58
This commit is contained in:
parent
b10e1d6a78
commit
328e59ebc4
@ -23,13 +23,43 @@ corpus = (testContext {locale = makeLocale PT Nothing}, testOptions, allExamples
|
||||
|
||||
allExamples :: [Example]
|
||||
allExamples = concat
|
||||
[ examples (simple Cup 2 (Just "café"))
|
||||
[ "2 copos de café"
|
||||
[ examples (simple Pound 2 (Just "carne"))
|
||||
[ "duas libras de carne"
|
||||
]
|
||||
, examples (simple Cup 1 Nothing)
|
||||
[ "um Copo"
|
||||
, examples (simple Gram 2 Nothing)
|
||||
[ "2 gramas"
|
||||
, "0,002 kg"
|
||||
, "2 g"
|
||||
, "2/1000 quilogramas"
|
||||
, "2/1000 quilos"
|
||||
, "2000 miligramas"
|
||||
, "2000 miligramas"
|
||||
]
|
||||
, examples (simple Pound 100 (Just "acucar"))
|
||||
[ "100 Libras de acucar"
|
||||
, examples (simple Gram 1000 Nothing)
|
||||
[ "um quilograma"
|
||||
, "um quilo"
|
||||
, "um kg"
|
||||
, "1 kg"
|
||||
, "1000 g"
|
||||
]
|
||||
, examples (simple Pound 1 Nothing)
|
||||
[ "uma Libra"
|
||||
, "1 lb"
|
||||
, "uma lb"
|
||||
]
|
||||
, examples (simple Cup 3 (Just "acucar"))
|
||||
[ "3 copos de acucar"
|
||||
, "3 copos de AcucAr"
|
||||
]
|
||||
, examples (simple Cup 0.75 Nothing)
|
||||
[ "3/4 copo"
|
||||
, "0,75 copo"
|
||||
]
|
||||
, examples (simple Gram 500 (Just "morangos"))
|
||||
[ "500 gramas de morangos"
|
||||
, "500g de morangos"
|
||||
, "0,5 quilos de morangos"
|
||||
, "0,5 kg de morangos"
|
||||
, "500000mg de morangos"
|
||||
]
|
||||
]
|
||||
|
@ -7,55 +7,78 @@
|
||||
|
||||
{-# LANGUAGE GADTs #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
|
||||
module Duckling.Quantity.PT.Rules
|
||||
( rules ) where
|
||||
|
||||
import Data.HashMap.Strict (HashMap)
|
||||
import qualified Data.HashMap.Strict as HashMap
|
||||
import qualified Data.Text as Text
|
||||
import Prelude
|
||||
import Data.String
|
||||
import Data.Text (Text)
|
||||
|
||||
import Duckling.Dimensions.Types
|
||||
import Duckling.Numeral.Types (NumeralData (..))
|
||||
import qualified Duckling.Numeral.Types as TNumeral
|
||||
import Duckling.Numeral.Helpers
|
||||
import Duckling.Quantity.Helpers
|
||||
import qualified Duckling.Quantity.Types as TQuantity
|
||||
import Duckling.Regex.Types
|
||||
import Duckling.Types
|
||||
|
||||
ruleNumeralUnits :: Rule
|
||||
ruleNumeralUnits = Rule
|
||||
{ name = "<number> <units>"
|
||||
, pattern =
|
||||
[ dimension Numeral
|
||||
, regex "(libra|copo)s?"
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(Token Numeral NumeralData {TNumeral.value = v}:
|
||||
Token RegexMatch (GroupMatch (match:_)):
|
||||
_) -> case Text.toLower match of
|
||||
"copo" -> Just . Token Quantity $ quantity TQuantity.Cup v
|
||||
"libra" -> Just . Token Quantity $ quantity TQuantity.Pound v
|
||||
_ -> Nothing
|
||||
_ -> Nothing
|
||||
}
|
||||
quantities :: [(Text, String, TQuantity.Unit)]
|
||||
quantities =
|
||||
[ ("<quantity> copos", "(copos?)", TQuantity.Cup)
|
||||
, ("<quantity> gramas", "((((mili)|(quilo))?(grama)s?)|(quilos?)|((m|k)?g))", TQuantity.Gram)
|
||||
, ("<quantity> libras", "((lb|libra)s?)", TQuantity.Pound)
|
||||
]
|
||||
|
||||
opsMap :: HashMap Text (Double -> Double)
|
||||
opsMap = HashMap.fromList
|
||||
[ ( "miligrama" , (/ 1000))
|
||||
, ( "miligramas" , (/ 1000))
|
||||
, ( "mg" , (/ 1000))
|
||||
, ( "mgs" , (/ 1000))
|
||||
, ( "quilograma" , (* 1000))
|
||||
, ( "quilogramas", (* 1000))
|
||||
, ( "quilo" , (* 1000))
|
||||
, ( "quilos" , (* 1000))
|
||||
, ( "kg" , (* 1000))
|
||||
, ( "kgs" , (* 1000))
|
||||
]
|
||||
|
||||
ruleNumeralQuantities :: [Rule]
|
||||
ruleNumeralQuantities = map go quantities
|
||||
where
|
||||
go :: (Text, String, TQuantity.Unit) -> Rule
|
||||
go (name, regexPattern, u) = Rule
|
||||
{ name = name
|
||||
, pattern = [Predicate isPositive, regex regexPattern]
|
||||
, prod = \case
|
||||
(Token Numeral nd:
|
||||
Token RegexMatch (GroupMatch (match:_)):
|
||||
_) -> do
|
||||
let value = getValue opsMap match $ TNumeral.value nd
|
||||
Just $ Token Quantity $ quantity u value
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
ruleQuantityOfProduct :: Rule
|
||||
ruleQuantityOfProduct = Rule
|
||||
{ name = "<quantity> of product"
|
||||
, pattern =
|
||||
[ dimension Quantity
|
||||
, regex "de (caf(e|é)|a(ç|c)ucar)"
|
||||
, regex "de (\\w+)"
|
||||
]
|
||||
, prod = \tokens -> case tokens of
|
||||
(Token Quantity qd:
|
||||
Token RegexMatch (GroupMatch (match:_)):
|
||||
_) -> Just . Token Quantity $ withProduct match qd
|
||||
, prod = \case
|
||||
(Token Quantity qd:Token RegexMatch (GroupMatch (product:_)):_) ->
|
||||
Just $ Token Quantity $ withProduct (Text.toLower product) qd
|
||||
_ -> Nothing
|
||||
}
|
||||
|
||||
rules :: [Rule]
|
||||
rules =
|
||||
[ ruleNumeralUnits
|
||||
, ruleQuantityOfProduct
|
||||
]
|
||||
[ ruleQuantityOfProduct ]
|
||||
++ ruleNumeralQuantities
|
||||
|
Loading…
Reference in New Issue
Block a user