-- 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.


{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Numeral.PL.Rules
  ( rules
  ) where

import Data.Maybe
import Data.String
import Prelude
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

ruleSixteen :: Rule
ruleSixteen :: Rule
ruleSixteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"sixteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"szesna(s|ś)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
16
  }

ruleFourteen :: Rule
ruleFourteen :: Rule
ruleFourteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fourteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"czterna(s|ś)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
14
  }

ruleTwo :: Rule
ruleTwo :: Rule
ruleTwo = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"two"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dw(a|(o|ó)(ch|m)|oma|iema|ie)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
2
  }

ruleSixty :: Rule
ruleSixty :: Rule
ruleSixty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"sixty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"sze(ść)dziesi(ą)t|sze(ść)dziesi(ę)ci(u|oma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
60
  }

ruleSeventy :: Rule
ruleSeventy :: Rule
ruleSeventy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"seventy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"siedemdziesi((a|ą)t|(e|ę)ci(u|oma))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
70
  }

ruleEighty :: Rule
ruleEighty :: Rule
ruleEighty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"eighty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"osiemdziesi((a|ą)t|(e|ę)ci(u|oma))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
80
  }

ruleNinety :: Rule
ruleNinety :: Rule
ruleNinety = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ninety"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dziewi(e|ę)(c|ć)dziesi((a|ą)|(e|ę))(t|ci(u|oma))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
90
  }

ruleIntersectWithAnd :: Rule
ruleIntersectWithAnd :: Rule
ruleIntersectWithAnd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect (with and)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
hasGrain
    , String -> PatternItem
regex String
"i|a"
    , 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
_:
       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
  }

ruleNumeralsPrefixWithNegativeOrMinus :: Rule
ruleNumeralsPrefixWithNegativeOrMinus :: Rule
ruleNumeralsPrefixWithNegativeOrMinus = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"numbers prefix with -, negative or minus"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"-|minus|negative"
    , Predicate -> PatternItem
Predicate Predicate
isPositive
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Numeral a
nd:[Token]
_) -> Double -> Maybe Token
double (NumeralData -> Double
TNumeral.value a
NumeralData
nd Double -> Double -> Double
forall a. Num a => a -> a -> a
* (-Double
1))
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOne :: Rule
ruleOne :: Rule
ruleOne = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"one"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"jed(en|nego|nemu|nym|nej|n(a|ą))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
1
  }

ruleTen :: Rule
ruleTen :: Rule
ruleTen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"ten"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dzisi(e|ę)(ć|c)(iu|ioma)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
10
  }

ruleSpecialCompositionForMissingHundredsLikeInOneTwentyTwo :: Rule
ruleSpecialCompositionForMissingHundredsLikeInOneTwentyTwo :: Rule
ruleSpecialCompositionForMissingHundredsLikeInOneTwentyTwo = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"special composition for missing hundreds like in one twenty two"
  , pattern :: Pattern
pattern =
    [ Double -> Double -> PatternItem
numberBetween Double
1 Double
10
    , Double -> Double -> PatternItem
numberBetween Double
10 Double
100
    ]
  , 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
v1 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
100 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
v2)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDecimalWithThousandsSeparator :: Rule
ruleDecimalWithThousandsSeparator :: Rule
ruleDecimalWithThousandsSeparator = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"decimal with thousands separator"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d+(,\\d\\d\\d)+\\.\\d+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseDouble (Text -> Text -> Text -> Text
Text.replace Text
"," Text
Text.empty Text
match) Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNine :: Rule
ruleNine :: Rule
ruleNine = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nine"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dziewi(e|ę)(ć|c)(iu|ioma)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
9
  }

ruleNumeral8 :: Rule
ruleNumeral8 :: Rule
ruleNumeral8 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 800"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(osiem(set| setek))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
800 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
  }

ruleTwelve :: Rule
ruleTwelve :: Rule
ruleTwelve = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"twelve"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dwunast(u|oma)|dwana(ś|s)cie"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
12
  }

ruleDecimalNumeral :: Rule
ruleDecimalNumeral :: Rule
ruleDecimalNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"decimal number"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d*\\.\\d+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> Bool -> Text -> Maybe Token
parseDecimal Bool
True Text
match
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleFifteen :: Rule
ruleFifteen :: Rule
ruleFifteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fifteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pi(ę)tna(s|ś)(ta|tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
15
  }

ruleEleven :: Rule
ruleEleven :: Rule
ruleEleven = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"eleven"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"jedena(stu|(s|ś)cie|stoma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
11
  }

ruleThirteen :: Rule
ruleThirteen :: Rule
ruleThirteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"thirteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"trzyna(ś|s)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
13
  }

ruleThirty :: Rule
ruleThirty :: Rule
ruleThirty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"thirty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"trzydzie(ś)ci|trzydziest(u|oma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
30
  }

ruleNumeral2 :: Rule
ruleNumeral2 :: Rule
ruleNumeral2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 200"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dwie((ś)cie| setki)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
200 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
  }

ruleSeventeen :: Rule
ruleSeventeen :: Rule
ruleSeventeen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"seventeen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"siedemna(s|ś)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
17
  }

ruleNumeral :: Rule
ruleNumeral :: Rule
ruleNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 100"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(sto|setki)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
100 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
  }

ruleNumeral9 :: Rule
ruleNumeral9 :: Rule
ruleNumeral9 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 900"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dziewi(ęć)(set| setek)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
900 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
  }

ruleSingle :: Rule
ruleSingle :: Rule
ruleSingle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"single"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pojedynczy"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
1
  }

ruleTwenty :: Rule
ruleTwenty :: Rule
ruleTwenty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"twenty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dwadzie(ś|s)cia|dwudziest(u|oma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
20
  }

ruleAFew :: Rule
ruleAFew :: Rule
ruleAFew = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"a few"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"kilk(a|u)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
3
  }

ruleEight :: Rule
ruleEight :: Rule
ruleEight = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"eight"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"o(s|ś)(iem|miu|mioma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
8
  }

ruleNumeral5 :: Rule
ruleNumeral5 :: Rule
ruleNumeral5 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 500"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pi(ęć)(set| setek)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
500 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
  }

ruleNumeral3 :: Rule
ruleNumeral3 :: Rule
ruleNumeral3 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 300"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(trzy(sta| setki))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
300 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
  }

ruleZero :: Rule
ruleZero :: Rule
ruleZero = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"zero"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(zero|nic)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
0
  }

ruleThousand :: Rule
ruleThousand :: Rule
ruleThousand = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"thousand"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ty(s|ś)i(a|ą|ę)c(e|y)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
1000 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
  }

ruleMillion :: Rule
ruleMillion :: Rule
ruleMillion = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"million"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"milion(y|(ó)w)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
1000000 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
  }

ruleIntersect :: Rule
ruleIntersect :: Rule
ruleIntersect = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
hasGrain
    , 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
  }

ruleThree :: Rule
ruleThree :: Rule
ruleThree = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"three"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"trz(y|ema|ech)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
3
  }

ruleFour :: Rule
ruleFour :: Rule
ruleFour = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"four"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"czter(ej|y|ech|em|ema)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
4
  }

ruleNumeralsSuffixesKMG :: Rule
ruleNumeralsSuffixesKMG :: Rule
ruleNumeralsSuffixesKMG = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"numbers suffixes (K, M, G)"
  , pattern :: Pattern
pattern =
    [ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    , String -> PatternItem
regex String
"([kmg])(?=[\\W\\$€]|$)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [Token]
_) -> case Text -> Text
Text.toLower Text
match of
         Text
"k" -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1e3
         Text
"m" -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1e6
         Text
"g" -> Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double
v Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1e9
         Text
_   -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeral7 :: Rule
ruleNumeral7 :: Rule
ruleNumeral7 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 700"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(siedem(set| setek))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
700 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
  }

ruleAPair :: Rule
ruleAPair :: Rule
ruleAPair = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"a pair"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"para?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
2
  }

ruleCouple :: Rule
ruleCouple :: Rule
ruleCouple = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"couple"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pare"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
2
  }

ruleSix :: Rule
ruleSix :: Rule
ruleSix = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"six"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"sze(s|ś)(c|ć)(iu|oma|u)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
6
  }

ruleNumeral6 :: Rule
ruleNumeral6 :: Rule
ruleNumeral6 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 600"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(sześć(set| setek))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
600 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
  }

ruleNumeral4 :: Rule
ruleNumeral4 :: Rule
ruleNumeral4 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number 400"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(cztery(sta| setki))"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
400 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
  }

ruleFive :: Rule
ruleFive :: Rule
ruleFive = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"five"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pi(e|ę)(c|ć)(iu|oma|u)?"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
5
  }

ruleFourty :: Rule
ruleFourty :: Rule
ruleFourty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fou?rty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"czterdzie(ś)ci|czterdziest(u|oma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
40
  }

ruleDozen :: Rule
ruleDozen :: Rule
ruleDozen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dozen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"tuzin"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
12 Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
withMultipliable
  }

ruleSeven :: Rule
ruleSeven :: Rule
ruleSeven = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"seven"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"sied(miu|em|mioma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
7
  }

ruleNineteen :: Rule
ruleNineteen :: Rule
ruleNineteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nineteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"dziewietna(s|ś)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
19
  }

ruleInteger2 :: Rule
ruleInteger2 :: Rule
ruleInteger2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer 21..99"
  , pattern :: Pattern
pattern =
    [ [Double] -> PatternItem
oneOf [Double
20, Double
30 .. Double
90]
    , Double -> Double -> PatternItem
numberBetween Double
1 Double
10
    ]
  , 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
  }

ruleEighteen :: Rule
ruleEighteen :: Rule
ruleEighteen = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"eighteen"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"osiemna(s|ś)(tu|cie|toma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
18
  }

ruleNumeralDotNumeral :: Rule
ruleNumeralDotNumeral :: Rule
ruleNumeralDotNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"number dot number"
  , pattern :: Pattern
pattern =
    [ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    , String -> PatternItem
regex String
"dot|point"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Predicate -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Predicate
hasGrain
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Numeral a
nd1:Token
_:Token Dimension a
Numeral a
nd2:[Token]
_) ->
        Double -> Maybe Token
double (Double -> Maybe Token) -> Double -> Maybe Token
forall a b. (a -> b) -> a -> b
$ NumeralData -> Double
TNumeral.value a
NumeralData
nd1 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double -> Double
decimalsToDouble (NumeralData -> Double
TNumeral.value a
NumeralData
nd2)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntegerWithThousandsSeparator :: Rule
ruleIntegerWithThousandsSeparator :: Rule
ruleIntegerWithThousandsSeparator = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer with thousands separator ,"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{1,3}(,\\d\\d\\d){1,5})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Text -> Maybe Double
parseDouble (Text -> Text -> Text -> Text
Text.replace Text
"," Text
Text.empty Text
match) Maybe Double -> (Double -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Double -> Maybe Token
double
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleFifty :: Rule
ruleFifty :: Rule
ruleFifty = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fifty"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"pi(ęć)dziesi(ą)t|pi(ęć)dziesi(ę)ci(u|oma)"
    ]
  , prod :: Production
prod = \[Token]
_ -> Integer -> Maybe Token
integer Integer
50
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleAFew
  , Rule
ruleAPair
  , Rule
ruleCouple
  , Rule
ruleDecimalNumeral
  , Rule
ruleDecimalWithThousandsSeparator
  , Rule
ruleDozen
  , Rule
ruleEight
  , Rule
ruleEighteen
  , Rule
ruleEighty
  , Rule
ruleEleven
  , Rule
ruleFifteen
  , Rule
ruleFifty
  , Rule
ruleFive
  , Rule
ruleFour
  , Rule
ruleFourteen
  , Rule
ruleFourty
  , Rule
ruleInteger2
  , Rule
ruleIntegerWithThousandsSeparator
  , Rule
ruleIntersect
  , Rule
ruleIntersectWithAnd
  , Rule
ruleMillion
  , Rule
ruleMultiply
  , Rule
ruleNine
  , Rule
ruleNineteen
  , Rule
ruleNinety
  , Rule
ruleNumeral
  , Rule
ruleNumeral2
  , Rule
ruleNumeral3
  , Rule
ruleNumeral4
  , Rule
ruleNumeral5
  , Rule
ruleNumeral6
  , Rule
ruleNumeral7
  , Rule
ruleNumeral8
  , Rule
ruleNumeral9
  , Rule
ruleNumeralDotNumeral
  , Rule
ruleNumeralsPrefixWithNegativeOrMinus
  , Rule
ruleNumeralsSuffixesKMG
  , Rule
ruleOne
  , Rule
ruleSeven
  , Rule
ruleSeventeen
  , Rule
ruleSeventy
  , Rule
ruleSingle
  , Rule
ruleSix
  , Rule
ruleSixteen
  , Rule
ruleSixty
  , Rule
ruleSpecialCompositionForMissingHundredsLikeInOneTwentyTwo
  , Rule
ruleTen
  , Rule
ruleThirteen
  , Rule
ruleThirty
  , Rule
ruleThousand
  , Rule
ruleThree
  , Rule
ruleTwelve
  , Rule
ruleTwenty
  , Rule
ruleTwo
  , Rule
ruleZero
  ]