{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoRebindableSyntax #-}
module Duckling.Numeral.KM.Rules
( rules
) where
import Data.HashMap.Strict (HashMap)
import Data.Maybe
import Data.String
import Data.Text (Text)
import Prelude
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text
import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Numeral.Types as TNumeral
ruleNumeralMap :: HashMap Text Integer
ruleNumeralMap :: HashMap Text Integer
ruleNumeralMap = [(Text, Integer)] -> HashMap Text Integer
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ ( Text
"០", Integer
0 )
, ( Text
"១", Integer
1 )
, ( Text
"២", Integer
2 )
, ( Text
"៣", Integer
3 )
, ( Text
"៤", Integer
4 )
, ( Text
"៥", Integer
5 )
, ( Text
"៦", Integer
6 )
, ( Text
"៧", Integer
7 )
, ( Text
"៨", Integer
8 )
, ( Text
"៩", Integer
9 )
, ( Text
"សូន្យ", Integer
0 )
, ( Text
"មួយ", Integer
1 )
, ( Text
"ពីរ", Integer
2 )
, ( Text
"បី", Integer
3 )
, ( Text
"បួន", Integer
4 )
, ( Text
"ប្រាំ", Integer
5 )
, ( Text
"ប្រាំមួយ", Integer
6 )
, ( Text
"ប្រាំពីរ", Integer
7 )
, ( Text
"ប្រាំបី", Integer
8 )
, ( Text
"ប្រាំបួន", Integer
9 )
]
ruleNumeral :: Rule
ruleNumeral :: Rule
ruleNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"integer (0..9)"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(០|១|២|៣|៤|៥|៦|៧|៨|៩|ប្រាំបួន|ប្រាំបី|ប្រាំពីរ|ប្រាំមួយ|ប្រាំ|បួន|បី|ពីរ|មួយ|សូន្យ)"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
Text -> HashMap Text Integer -> Maybe Integer
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
match HashMap Text Integer
ruleNumeralMap Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleTensMap :: HashMap Text Integer
ruleTensMap :: HashMap Text Integer
ruleTensMap = [(Text, Integer)] -> HashMap Text Integer
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ ( Text
"ដប់", Integer
10 )
, ( Text
"ម្ភៃ", Integer
20 )
, ( Text
"សាម", Integer
30 )
, ( Text
"សែ", Integer
40 )
, ( Text
"ហា", Integer
50 )
, ( Text
"ហុក", Integer
60 )
, ( Text
"ចិត", Integer
70 )
, ( Text
"ប៉ែត", Integer
80 )
, ( Text
"កៅ", Integer
90 )
]
ruleTens :: Rule
ruleTens :: Rule
ruleTens = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"integer (10..90)"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(កៅ|ប៉ែត|ចិត|ហុក|ហា|សែ|សាម|ម្ភៃ|ដប់)"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
Text -> HashMap Text Integer -> Maybe Integer
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup Text
match HashMap Text Integer
ruleTensMap Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleCompositeTens :: Rule
ruleCompositeTens :: Rule
ruleCompositeTens = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"integer (11..99)"
, pattern :: Pattern
pattern =
[ [Double] -> PatternItem
oneOf [Double
10, Double
20 .. Double
90]
, [Double] -> PatternItem
oneOf [Double
1 .. Double
9]
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
Numeral NumeralData{TNumeral.value = v1}:
Token Dimension a
Numeral NumeralData{TNumeral.value = v2}:
[Token]
_) -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
v2
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
rulePowersOfTen :: Rule
rulePowersOfTen :: Rule
rulePowersOfTen = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"powers of tens"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(រយ|ពាន់|ម៉ឺន|សែន|លាន)"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> case Text
match of
Text
"រយ" -> Double -> Maybe Token
double Double
1e2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
2 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
Text
"ពាន់" -> Double -> Maybe Token
double Double
1e3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
3 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
Text
"ម៉ឺន" -> Double -> Maybe Token
double Double
1e4 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
4 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
Text
"សែន" -> Double -> Maybe Token
double Double
1e5 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
5 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
Text
"លាន" -> Double -> Maybe Token
double Double
1e6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Int -> Token -> Maybe Token
withGrain Int
6 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
Text
_ -> Maybe Token
forall a. Maybe a
Nothing
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleSum :: Rule
ruleSum :: Rule
ruleSum = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"intersect 2 numbers"
, pattern :: Pattern
pattern =
[ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
hasGrain, Predicate
isPositive]
, Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Bool -> Bool
not (Bool -> Bool) -> Predicate -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Predicate
isMultipliable, Predicate
isPositive]
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
Numeral NumeralData{TNumeral.value = val1, TNumeral.grain = Just g}:
Token Dimension a
Numeral NumeralData{TNumeral.value = val2}:
[Token]
_) | (Double
10 Double -> Double -> Double
forall a. Floating a => a -> a -> a
** Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
g) Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
val2 -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
val1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
val2
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleMultiply :: Rule
ruleMultiply :: Rule
ruleMultiply = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"compose by multiplication"
, pattern :: Pattern
pattern =
[ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
, Predicate -> PatternItem
Predicate Predicate
isMultipliable
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token
token1:Token
token2:[Token]
_) -> Token -> Token -> Maybe Token
multiply Token
token1 Token
token2
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
rules :: [Rule]
rules :: [Rule]
rules =
[ Rule
ruleNumeral
, Rule
ruleTens
, Rule
ruleCompositeTens
, Rule
rulePowersOfTen
, Rule
ruleSum
, Rule
ruleMultiply
]