{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
module Duckling.Duration.UK.Rules
( rules ) where
import Control.Monad (join)
import Data.Semigroup ((<>))
import Data.String
import Prelude
import qualified Data.Text as Text
import Duckling.Dimensions.Types
import Duckling.Duration.Helpers
import Duckling.Duration.Types (DurationData(..))
import Duckling.Numeral.Helpers (parseInt, parseInteger)
import Duckling.Numeral.Types (NumeralData(..))
import Duckling.Regex.Types
import Duckling.Types
import qualified Duckling.Duration.Types as TDuration
import qualified Duckling.Numeral.Types as TNumeral
import qualified Duckling.TimeGrain.Types as TG
ruleHalfAnHour :: Rule
ruleHalfAnHour :: Rule
ruleHalfAnHour = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"half an hour"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(1/2\\s?|пів\\s?)години?"
]
, prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> (DurationData -> Token) -> DurationData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Maybe Token) -> DurationData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration Grain
TG.Minute Int
30
}
ruleNumeralnumberHours :: Rule
ruleNumeralnumberHours :: Rule
ruleNumeralnumberHours = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"number.number hours"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(\\d+)\\.(\\d+) години?"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
RegexMatch (GroupMatch (h:m:_)):[Token]
_) -> do
Integer
hh <- Text -> Maybe Integer
parseInteger Text
h
Integer
mnum <- Text -> Maybe Integer
parseInteger Text
m
let mden :: Integer
mden = Integer
10 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Text -> Int
Text.length Text
m
Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> (DurationData -> Token) -> DurationData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Maybe Token) -> DurationData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Integer -> Integer -> Integer -> DurationData
minutesFromHourMixedFraction Integer
hh Integer
mnum Integer
mden
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleIntegerAndAnHalfHours :: Rule
ruleIntegerAndAnHalfHours :: Rule
ruleIntegerAndAnHalfHours = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"<integer> and an half hours"
, pattern :: Pattern
pattern =
[ Predicate -> PatternItem
Predicate Predicate
isNatural
, String -> PatternItem
regex String
"з половиною години"
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> (Int -> Token) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> (Int -> DurationData) -> Int -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Minute (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int
30 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleAboutDuration :: Rule
ruleAboutDuration :: Rule
ruleAboutDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"about <duration>"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"близько"
, Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleExactlyDuration :: Rule
ruleExactlyDuration :: Rule
ruleExactlyDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"exactly <duration>"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"рівно"
, Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleDurationHalfATimeGrain :: Rule
ruleDurationHalfATimeGrain :: Rule
ruleDurationHalfATimeGrain = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"half a <time-grain>"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"(1/2|пів)"
, Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token
_:Token Dimension a
TimeGrain a
grain:[Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
0
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleDurationOneGrainAndHalf :: Rule
ruleDurationOneGrainAndHalf :: Rule
ruleDurationOneGrainAndHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"one and a hald <unit-of-duration>"
, pattern :: Pattern
pattern =
[ String -> PatternItem
regex String
"півтори"
, Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token
_:Token Dimension a
TimeGrain a
grain:[Token]
_) -> Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Token) -> Maybe DurationData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Grain -> Int -> Maybe DurationData
nPlusOneHalf a
Grain
grain Int
1
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
ruleCompositeDurationCommasAnd :: Rule
ruleCompositeDurationCommasAnd :: Rule
ruleCompositeDurationCommasAnd = Rule :: Text -> Pattern -> Production -> Rule
Rule
{ name :: Text
name = Text
"composite <duration> (with ,/and)"
, pattern :: Pattern
pattern =
[ Predicate -> PatternItem
Predicate Predicate
isNatural
, Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
, String -> PatternItem
regex String
",|і"
, Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
]
, prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
(Token Dimension a
Numeral NumeralData{TNumeral.value = v}:
Token Dimension a
TimeGrain a
g:
Token
_:
Token Dimension a
Duration dd :: a
dd@DurationData{TDuration.grain = dg}:
[Token]
_) | a
g a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
Grain
dg -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> (DurationData -> Token) -> DurationData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension DurationData -> DurationData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension DurationData
Duration (DurationData -> Maybe Token) -> DurationData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> DurationData
duration a
Grain
g (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v) DurationData -> DurationData -> DurationData
forall a. Semigroup a => a -> a -> a
<> a
DurationData
dd
[Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}
rules :: [Rule]
rules :: [Rule]
rules =
[ Rule
ruleAboutDuration
, Rule
ruleExactlyDuration
, Rule
ruleHalfAnHour
, Rule
ruleIntegerAndAnHalfHours
, Rule
ruleNumeralnumberHours
, Rule
ruleDurationHalfATimeGrain
, Rule
ruleDurationOneGrainAndHalf
, Rule
ruleCompositeDurationCommasAnd
]