module Duckling.Numeral.AR.Rules
( rules ) where
import Data.Maybe
import qualified Data.Text as Text
import Prelude
import Data.String
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers
import Duckling.Numeral.Types (NumeralData (..))
import qualified Duckling.Numeral.Types as TNumeral
import Duckling.Regex.Types
import Duckling.Types
ruleInteger5 :: Rule
ruleInteger5 = Rule
{ name = "integer 4"
, pattern =
[ regex "(\x0623\x0631\x0628\x0639(\x0629)?)"
]
, prod = \_ -> integer 4
}
ruleInteger23 :: Rule
ruleInteger23 = Rule
{ name = "integer 101..999"
, pattern =
[ oneOf [100, 200 .. 900]
, regex "\x0648"
, numberBetween 1 100
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = v1}):
_:
Token Numeral (NumeralData {TNumeral.value = v2}):
_) -> double $ v1 + v2
_ -> Nothing
}
ruleInteger18 :: Rule
ruleInteger18 = Rule
{ name = "integer 12"
, pattern =
[ regex "(\x0625\x062b\x0646(\x062a)?\x0649 \x0639\x0634\x0631)"
]
, prod = \_ -> integer 12
}
ruleIntegerNumeric :: Rule
ruleIntegerNumeric = Rule
{ name = "integer (numeric)"
, pattern =
[ regex "(\\d{1,18})"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> do
v <- parseInt match
integer $ toInteger v
_ -> Nothing
}
ruleInteger19 :: Rule
ruleInteger19 = Rule
{ name = "integer (20..90)"
, pattern =
[ regex "(\x0639\x0634\x0631\x0648\x0646|\x062b\x0644\x0627\x062b\x0648\x0646|\x0623\x0631\x0628\x0639\x0648\x0646|\x062e\x0645\x0633\x0648\x0646|\x0633\x062a\x0648\x0646|\x0633\x0628\x0639\x0648\x0646|\x062b\x0645\x0627\x0646\x0648\x0646|\x062a\x0633\x0639\x0648\x0646)"
]
, prod = \tokens -> case tokens of
Token RegexMatch (GroupMatch (match:_)):_ -> case match of
"\x0639\x0634\x0631\x0648\x0646" -> integer 20
"\x062b\x0644\x0627\x062b\x0648\x0646" -> integer 30
"\x0623\x0631\x0628\x0639\x0648\x0646" -> integer 40
"\x062e\x0645\x0633\x0648\x0646" -> integer 50
"\x0633\x062a\x0648\x0646" -> integer 60
"\x0633\x0628\x0639\x0648\x0646" -> integer 70
"\x062b\x0645\x0627\x0646\x0648\x0646" -> integer 80
"\x062a\x0633\x0639\x0648\x0646" -> integer 90
_ -> Nothing
_ -> Nothing
}
ruleInteger22 :: Rule
ruleInteger22 = Rule
{ name = "integer 21..99"
, pattern =
[ numberBetween 1 10
, regex "\x0648"
, oneOf [20, 30 .. 90]
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = v1}):
_:
Token Numeral (NumeralData {TNumeral.value = v2}):
_) -> double $ v1 + v2
_ -> Nothing
}
ruleInteger21 :: Rule
ruleInteger21 = Rule
{ name = "integer (13..19)"
, pattern =
[ numberBetween 3 10
, numberWith TNumeral.value (== 10)
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = v}):_) -> double $ v + 10
_ -> Nothing
}
ruleDecimalWithThousandsSeparator :: Rule
ruleDecimalWithThousandsSeparator = Rule
{ name = "decimal with thousands separator"
, pattern =
[ regex "(\\d+(,\\d\\d\\d)+\\.\\d+)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) ->
parseDouble (Text.replace (Text.singleton ',') Text.empty match) >>= double
_ -> Nothing
}
ruleMultiply :: Rule
ruleMultiply = Rule
{ name = "compose by multiplication"
, pattern =
[ dimension Numeral
, numberWith TNumeral.multipliable id
]
, prod = \tokens -> case tokens of
(token1:token2:_) -> multiply token1 token2
_ -> Nothing
}
ruleInteger15 :: Rule
ruleInteger15 = Rule
{ name = "integer 11"
, pattern =
[ regex "(\x0625\x062d\x062f\x0649 \x0639\x0634\x0631(\x0629)?)"
]
, prod = \_ -> integer 11
}
ruleDecimalNumeral :: Rule
ruleDecimalNumeral = Rule
{ name = "decimal number"
, pattern =
[ regex "(\\d*\\.\\d+)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) ->
parseDecimal True match
_ -> Nothing
}
rulePowersOfTen :: Rule
rulePowersOfTen = Rule
{ name = "powers of tens"
, pattern =
[ regex "(\x0645\x0627\x0626\x0629|\x0645\x0626\x0627\x062a|\x0623\x0644\x0641|\x0627\x0644\x0641|\x0622\x0644\x0627\x0641|\x0645\x0644\x0627\x064a\x064a(\x0646)?)"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) -> case Text.toLower match of
"\x0645\x0627\x0626\x0629" ->
double 1e2 >>= withGrain 2 >>= withMultipliable
"\x0645\x0626\x0627\x062a" ->
double 1e2 >>= withGrain 2 >>= withMultipliable
"\x0623\x0644\x0641" -> double 1e3 >>= withGrain 3 >>= withMultipliable
"\x0627\x0644\x0641" -> double 1e3 >>= withGrain 3 >>= withMultipliable
"\x0622\x0644\x0627\x0641" ->
double 1e3 >>= withGrain 3 >>= withMultipliable
"\x0645\x0644\x0627\x064a\x064a" ->
double 1e6 >>= withGrain 6 >>= withMultipliable
"\x0645\x0644\x0627\x064a\x064a\x0646" ->
double 1e6 >>= withGrain 6 >>= withMultipliable
_ -> Nothing
_ -> Nothing
}
ruleInteger3 :: Rule
ruleInteger3 = Rule
{ name = "integer 2"
, pattern =
[ regex "(\x0627\x062b\x0646\x0627\x0646|\x0627\x062b\x0646\x064a\x0646)"
]
, prod = \_ -> integer 2
}
ruleInteger13 :: Rule
ruleInteger13 = Rule
{ name = "integer 9"
, pattern =
[ regex "(\x062a\x0633\x0639\x0629|\x062a\x0633\x0639)"
]
, prod = \_ -> integer 9
}
ruleInteger12 :: Rule
ruleInteger12 = Rule
{ name = "integer 8"
, pattern =
[ regex "(\x062b\x0645\x0627\x0646\x064a\x0629|\x062b\x0645\x0627\x0646)"
]
, prod = \_ -> integer 8
}
ruleNumeralsPrefixWithMinus :: Rule
ruleNumeralsPrefixWithMinus = Rule
{ name = "numbers prefix with -, minus"
, pattern =
[ regex "-"
, dimension Numeral
]
, prod = \tokens -> case tokens of
(_:Token Numeral (NumeralData {TNumeral.value = v}):_) ->
double (v * ( 1))
_ -> Nothing
}
ruleInteger7 :: Rule
ruleInteger7 = Rule
{ name = "integer 5"
, pattern =
[ regex "(\x062e\x0645\x0633)(\x0629)?"
]
, prod = \_ -> integer 5
}
ruleInteger14 :: Rule
ruleInteger14 = Rule
{ name = "integer 10"
, pattern =
[ regex "(\x0639\x0634\x0631\x0629|\x0639\x0634\x0631)"
]
, prod = \_ -> integer 10
}
ruleInteger9 :: Rule
ruleInteger9 = Rule
{ name = "integer 6"
, pattern =
[ regex "(\x0633\x062a(\x0629)?)"
]
, prod = \_ -> integer 6
}
ruleInteger :: Rule
ruleInteger = Rule
{ name = "integer 0"
, pattern =
[ regex "(\x0635\x0641\x0631)"
]
, prod = \_ -> integer 0
}
ruleInteger4 :: Rule
ruleInteger4 = Rule
{ name = "integer 3"
, pattern =
[ regex "(\x062b\x0644\x0627\x062b|\x062b\x0644\x0627\x062b\x0629)"
]
, prod = \_ -> integer 3
}
ruleInteger2 :: Rule
ruleInteger2 = Rule
{ name = "integer 1"
, pattern =
[ regex "(\x0648\x0627\x062d\x062f\x0629|\x0648\x0627\x062d\x062f\x0647|\x0648\x0627\x062d\x062f)"
]
, prod = \_ -> integer 1
}
ruleInteger11 :: Rule
ruleInteger11 = Rule
{ name = "integer 7"
, pattern =
[ regex "(\x0633\x0628\x0639\x0629|\x0633\x0628\x0639)"
]
, prod = \_ -> integer 7
}
ruleInteger20 :: Rule
ruleInteger20 = Rule
{ name = "integer (100..900)"
, pattern =
[ regex "(\x0645\x0627\x0626\x0629|\x0645\x0627\x0626\x062a\x0627\x0646|\x062b\x0644\x0627\x062b\x0645\x0627\x0626\x0629|\x0623\x0631\x0628\x0639\x0645\x0627\x0626\x0629|\x062e\x0645\x0633\x0645\x0627\x0626\x0629|\x0633\x062a\x0645\x0627\x0626\x0629|\x0633\x0628\x0639\x0645\x0627\x0626\x0629|\x062b\x0645\x0627\x0646\x0645\x0627\x0626\x0629|\x062a\x0633\x0639\x0645\x0627\x0626\x0629)"
]
, prod = \tokens -> case tokens of
Token RegexMatch (GroupMatch (match:_)):_ -> case match of
"\x0645\x0627\x0626\x0629" -> integer 100
"\x0633\x0628\x0639\x0645\x0627\x0626\x0629" -> integer 700
"\x062e\x0645\x0633\x0645\x0627\x0626\x0629" -> integer 500
"\x0623\x0631\x0628\x0639\x0645\x0627\x0626\x0629" -> integer 400
"\x0633\x062a\x0645\x0627\x0626\x0629" -> integer 600
"\x0645\x0627\x0626\x062a\x0627\x0646" -> integer 200
"\x062b\x0644\x0627\x062b\x0645\x0627\x0626\x0629" -> integer 300
"\x062b\x0645\x0627\x0646\x0645\x0627\x0626\x0629" -> integer 800
"\x062a\x0633\x0639\x0645\x0627\x0626\x0629" -> integer 900
_ -> Nothing
_ -> Nothing
}
ruleNumeralDotNumeral :: Rule
ruleNumeralDotNumeral = Rule
{ name = "number dot number"
, pattern =
[ dimension Numeral
, regex "\x0641\x0627\x0635\x0644\x0629"
, numberWith TNumeral.grain isNothing
]
, prod = \tokens -> case tokens of
(Token Numeral (NumeralData {TNumeral.value = v1}):
_:
Token Numeral (NumeralData {TNumeral.value = v2}):
_) -> double $ v1 + decimalsToDouble v2
_ -> Nothing
}
ruleIntegerWithThousandsSeparator :: Rule
ruleIntegerWithThousandsSeparator = Rule
{ name = "integer with thousands separator ,"
, pattern =
[ regex "(\\d{1,3}(,\\d\\d\\d){1,5})"
]
, prod = \tokens -> case tokens of
(Token RegexMatch (GroupMatch (match:_)):_) ->
parseDouble (Text.replace (Text.singleton ',') Text.empty match) >>= double
_ -> Nothing
}
rules :: [Rule]
rules =
[ ruleDecimalNumeral
, ruleDecimalWithThousandsSeparator
, ruleInteger
, ruleInteger11
, ruleInteger12
, ruleInteger13
, ruleInteger14
, ruleInteger15
, ruleInteger18
, ruleInteger19
, ruleInteger2
, ruleInteger20
, ruleInteger21
, ruleInteger22
, ruleInteger23
, ruleInteger3
, ruleInteger4
, ruleInteger5
, ruleInteger7
, ruleInteger9
, ruleIntegerNumeric
, ruleIntegerWithThousandsSeparator
, ruleMultiply
, ruleNumeralDotNumeral
, ruleNumeralsPrefixWithMinus
, rulePowersOfTen
]