-- 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 NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}

module Duckling.Time.UK.Rules
  ( rules
  ) where

import Prelude
import Data.Text (Text)
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers (isGrain)
import Duckling.Numeral.Helpers (parseInt)
import Duckling.Ordinal.Types (OrdinalData(..))
import Duckling.Regex.Types
import Duckling.Time.Helpers
import Duckling.Time.Types (TimeData(..))
import Duckling.Types
import qualified Duckling.Ordinal.Types as TOrdinal
import qualified Duckling.Time.Types as TTime
import qualified Duckling.TimeGrain.Types as TG

ruleInstants :: [Rule]
ruleInstants :: [Rule]
ruleInstants = [(Text, Grain, Int, String)] -> [Rule]
mkRuleInstants
  [ ( Text
"зараз"         , Grain
TG.Second ,  Int
0, String
"зараз"                 )
  , ( Text
"сьогодні"      , Grain
TG.Day    ,  Int
0, String
"сьогодні"              )
  , ( Text
"завтра"        , Grain
TG.Day    ,  Int
1, String
"завтра"                )
  , ( Text
"вчора"         , Grain
TG.Day    , -Int
1, String
"вчора"                 )
  , ( Text
"післязавтра"   , Grain
TG.Day    ,  Int
2, String
"післязавтра"           )
  , ( Text
"позавчора"     , Grain
TG.Day    , -Int
2, String
"позавчора"             )
  , ( Text
"Кінець місяця" , Grain
TG.Month  ,  Int
1, String
"(кінець|кінця) місяця" )
  , ( Text
"Кінець року"   , Grain
TG.Year   ,  Int
1, String
"(кінець|кінця) року"   )
  ]

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = [(Text, String)] -> [Rule]
mkRuleDaysOfWeek
  [ ( Text
"Понеділок" , String
"понеділ(ок|ка)|пн" )
  , ( Text
"Вівторок"  , String
"вівтор(ок|ка)|вт"  )
  , ( Text
"Середа"    , String
"серед(а|у)|ср"     )
  , ( Text
"Четвер"    , String
"четвер(га)?|чт"    )
  , ( Text
"П'ятниця"  , String
"п'ятниц(я|і|ю)|пт" )
  , ( Text
"Субота"    , String
"субот(а|и|у)|сб"   )
  , ( Text
"Неділя"    , String
"неділ(я|і|ю)|нд"   )
  ]

ruleMonths :: [Rule]
ruleMonths :: [Rule]
ruleMonths = [(Text, String)] -> [Rule]
mkRuleMonths
  [ ( Text
"Січень"   , String
"січ(ень|ня|ні)|січ\\.?"   )
  , ( Text
"Лютий"    , String
"лют(ий|ого|ому)|лют\\.?"   )
  , ( Text
"Березень" , String
"берез(ень|ня|ні)|бер\\.?" )
  , ( Text
"Квітень"  , String
"квіт(ень|ня|ні)|квi\\.?"  )
  , ( Text
"Травень"  , String
"трав(ень|ня|ні)|тра\\.?"  )
  , ( Text
"Червень"  , String
"черв(ень|ня|ні)|чер\\.?"  )
  , ( Text
"Липень"   , String
"лип(ень|ня|ні)|лип\\.?"   )
  , ( Text
"Серпень"  , String
"серп(ень|ня|ні)|сер\\.?"  )
  , ( Text
"Вересень" , String
"верес(ень|ня|ні)|вер\\.?" )
  , ( Text
"Жовтень"  , String
"жовт(ень|ня|ні)|жов\\.?"  )
  , ( Text
"Листопад" , String
"листопад(а|і)?|лис\\.?"    )
  , ( Text
"Грудень"  , String
"груд(ень|ня|ні)|гру\\.?"  )
  ]

ruleSeasons :: [Rule]
ruleSeasons :: [Rule]
ruleSeasons = [(Text, String, TimeData, TimeData)] -> [Rule]
mkRuleSeasons
  [ ( Text
"літо"  , String
"літо"  , Int -> Int -> TimeData
monthDay  Int
6  Int
1, Int -> Int -> TimeData
monthDay  Int
8 Int
31 )
  , ( Text
"осінь" , String
"осінь" , Int -> Int -> TimeData
monthDay  Int
9  Int
1, Int -> Int -> TimeData
monthDay Int
11 Int
30 )
  , ( Text
"зима"  , String
"зима"  , Int -> Int -> TimeData
monthDay Int
12  Int
1, Int -> Int -> TimeData
monthDay  Int
2 Int
28 )
  , ( Text
"весна" , String
"весна" , Int -> Int -> TimeData
monthDay  Int
3  Int
1, Int -> Int -> TimeData
monthDay  Int
5 Int
31 )
  ]

ruleHolidays :: [Rule]
ruleHolidays :: [Rule]
ruleHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"Новий рік"                 , String
"новий рік"
    , Int -> Int -> TimeData
monthDay  Int
1  Int
1 )
  , ( Text
"Різдво Христове"           , String
"різдв(о|а)"
    , Int -> Int -> TimeData
monthDay  Int
1  Int
7 )
  , ( Text
"Міжнародний жіночий день"  , String
"міжнародний жіночий день"
    , Int -> Int -> TimeData
monthDay  Int
3  Int
8 )
  , ( Text
"День праці"                , String
"день праці"
    , Int -> Int -> TimeData
monthDay  Int
5  Int
1 )
  , ( Text
"День Перемоги"             , String
"день перемоги"
    , Int -> Int -> TimeData
monthDay  Int
5  Int
9 )
  , ( Text
"День Конституції"          , String
"день конституції"
    , Int -> Int -> TimeData
monthDay  Int
6 Int
28 )
  , ( Text
"День незалежності України" , String
"день незалежності"
    , Int -> Int -> TimeData
monthDay  Int
8 Int
24 )
  , ( Text
"День захисника України"    , String
"день захисника"
    , Int -> Int -> TimeData
monthDay Int
10 Int
14 )
  , ( Text
"Католицьке Різдво"         , String
"католицьк(е|ого) різдв(о|а)"
    , Int -> Int -> TimeData
monthDay Int
12 Int
25 )
  ]

ruleLastTime :: Rule
ruleLastTime :: Rule
ruleLastTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в )?минул(ий|а|ого|ому|ої|у)"
    , Predicate -> PatternItem
Predicate Predicate
isOkWithThisNext
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth (-Int
1) Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDatetimeDatetimeInterval :: Rule
ruleDatetimeDatetimeInterval :: Rule
ruleDatetimeDatetimeInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<datetime> - <datetime> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"\\-"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDateDateInterval :: Rule
ruleDateDateInterval :: Rule
ruleDateDateInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dd.(mm.)? - dd.mm.(yy[yy]?)? (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(?:з\\s+)?(10|20|30|31|[012]?[1-9])\\.?((?<=\\.)(?:10|11|12|0?[1-9])(?:\\.?))?"
    , String -> PatternItem
regex String
"\\-|/|по"
    , String -> PatternItem
regex String
"(10|20|30|31|[012]?[1-9])\\.(10|11|12|0?[1-9])\\.?((?<=\\.)\\d{2,4})?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (d1:"":_)):
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (d2:m2:"":_)):
       [Token]
_) -> do
          Int
d1 <- Text -> Maybe Int
parseInt Text
d1
          Int
d2 <- Text -> Maybe Int
parseInt Text
d2
          Int
m2 <- Text -> Maybe Int
parseInt Text
m2
          Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed (Int -> Int -> TimeData
monthDay Int
m2 Int
d1) (Int -> Int -> TimeData
monthDay Int
m2 Int
d2)
      (Token Dimension a
RegexMatch (GroupMatch (d1:"":_)):
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (d2:m2:y:_)):
       [Token]
_) -> do
          Int
d1 <- Text -> Maybe Int
parseInt Text
d1
          Int
d2 <- Text -> Maybe Int
parseInt Text
d2
          Int
m2 <- Text -> Maybe Int
parseInt Text
m2
          Int
y <- Text -> Maybe Int
parseInt Text
y
          Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed (Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m2 Int
d1) (Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m2 Int
d2)
      (Token Dimension a
RegexMatch (GroupMatch (d1:m1:_)):
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (d2:m2:"":_)):
       [Token]
_) -> do
          Int
d1 <- Text -> Maybe Int
parseInt Text
d1
          Int
d2 <- Text -> Maybe Int
parseInt Text
d2
          Int
m1 <- Text -> Maybe Int
parseInt Text
m1
          Int
m2 <- Text -> Maybe Int
parseInt Text
m2
          Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed (Int -> Int -> TimeData
monthDay Int
m1 Int
d1) (Int -> Int -> TimeData
monthDay Int
m2 Int
d2)
      (Token Dimension a
RegexMatch (GroupMatch (d1:m1:_)):
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (d2:m2:y:_)):
       [Token]
_) -> do
          Int
d1 <- Text -> Maybe Int
parseInt Text
d1
          Int
d2 <- Text -> Maybe Int
parseInt Text
d2
          Int
m1 <- Text -> Maybe Int
parseInt Text
m1
          Int
m2 <- Text -> Maybe Int
parseInt Text
m2
          Int
y <- Text -> Maybe Int
parseInt Text
y
          Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed (Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m1 Int
d1) (Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m2 Int
d2)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInDuration :: Rule
ruleInDuration :: Rule
ruleInDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in <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 Dimension a
Duration a
dd:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
inDuration a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastCycleOfTime :: Rule
ruleLastCycleOfTime :: Rule
ruleLastCycleOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"останній"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"в|у"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf a
Grain
grain a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastCycleOfTime2 :: Rule
ruleLastCycleOfTime2 :: Rule
ruleLastCycleOfTime2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"останній"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf a
Grain
grain a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMonthDdddInterval :: Rule
ruleMonthDdddInterval :: Rule
ruleMonthDdddInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<month> dd-dd (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(?:з\\s+)?([012]?\\d|30|31)(го|\\.)?"
    , String -> PatternItem
regex String
"\\-|по|до"
    , String -> PatternItem
regex String
"([012]?\\d|30|31)(ое|\\.)?"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (m1:_)):
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (m2:_)):
       Token Dimension a
Time a
td:
       [Token]
_) -> do
        Int
v1 <- Text -> Maybe Int
parseInt Text
m1
        Int
v2 <- Text -> Maybe Int
parseInt Text
m2
        TimeData
from <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
v1) a
TimeData
td
        TimeData
to <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
v2) a
TimeData
td
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed TimeData
from TimeData
to
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYearLatent2 :: Rule
ruleYearLatent2 :: Rule
ruleYearLatent2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"year (latent)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
2101 Int
10000
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:[Token]
_) -> do
        Int
v <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
year Int
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeAfterNext :: Rule
ruleTimeAfterNext :: Rule
ruleTimeAfterNext = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> after next"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"після наступн(ої|ого)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:Token
_:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
1 Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNoon :: Rule
ruleNoon :: Rule
ruleNoon = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"noon"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"опівдні"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> TimeData
hour Bool
False Int
12
  }

ruleThisnextDayofweek :: Rule
ruleThisnextDayofweek :: Rule
ruleThisnextDayofweek = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this|next <day-of-week>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"наступн(ого|а)"
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleBetweenTimeofdayAndTimeofdayInterval :: Rule
ruleBetweenTimeofdayAndTimeofdayInterval :: Rule
ruleBetweenTimeofdayAndTimeofdayInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time-of-day> and <time-of-day> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"з"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"до"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNextCycle :: Rule
ruleNextCycle :: Rule
ruleNextCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"next <cycle>"
  , 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]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOnDate :: Rule
ruleOnDate :: Rule
ruleOnDate = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"on <date>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"в"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
x:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
x
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastCycle :: Rule
ruleLastCycle :: Rule
ruleLastCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <cycle>"
  , 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]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLunch :: Rule
ruleLunch :: Rule
ruleLunch = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"lunch"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в )?обід"
    ]
  , prod :: Production
prod = \[Token]
_ ->
      let from :: TimeData
from = Bool -> Int -> TimeData
hour Bool
False Int
12
          to :: TimeData
to = Bool -> Int -> TimeData
hour Bool
False Int
14
      in Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
from TimeData
to
  }

ruleAfternoon :: Rule
ruleAfternoon :: Rule
ruleAfternoon = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"afternoon"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"дня|днем"
    ]
  , prod :: Production
prod = \[Token]
_ ->
      let from :: TimeData
from = Bool -> Int -> TimeData
hour Bool
False Int
12
          to :: TimeData
to = Bool -> Int -> TimeData
hour Bool
False Int
19
      in Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
from TimeData
to
  }

ruleEvening :: Rule
ruleEvening :: Rule
ruleEvening = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"evening"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"вечора|ввечері"
    ]
  , prod :: Production
prod = \[Token]
_ ->
      let from :: TimeData
from = Bool -> Int -> TimeData
hour Bool
False Int
18
          to :: TimeData
to = Bool -> Int -> TimeData
hour Bool
False Int
0
      in Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
from TimeData
to
  }

ruleNamedmonthDayofmonthOrdinal :: Rule
ruleNamedmonthDayofmonthOrdinal :: Rule
ruleNamedmonthDayofmonthOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<named-month> <day-of-month> (ordinal)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:Token
token:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }


ruleHourofdayIntegerAsRelativeMinutes :: Rule
ruleHourofdayIntegerAsRelativeMinutes :: Rule
ruleHourofdayIntegerAsRelativeMinutes = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> <integer> (as relative minutes)"
  , 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
isNotLatent, Predicate
isAnHourOfDay]
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
59
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:
       Token
token:
       [Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDayofmonthordinalNamedmonth :: Rule
ruleDayofmonthordinalNamedmonth :: Rule
ruleDayofmonthordinalNamedmonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month>(ordinal) <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersectBy :: Rule
ruleIntersectBy :: Rule
ruleIntersectBy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect by ','"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
","
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNthTimeAfterTime :: Rule
ruleNthTimeAfterTime :: Rule
ruleNthTimeAfterTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nth <time> after <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"після"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal OrdinalData{TOrdinal.value = v}:
       Token Dimension a
Time a
td1:
       Token
_:
       Token Dimension a
Time a
td2:
       [Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData -> TimeData -> TimeData
predNthAfter (Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMmdd :: Rule
ruleMmdd :: Rule
ruleMmdd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm/dd"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([012]?[1-9]|10|20|30|31)\\.(10|11|12|0?[1-9])\\.?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (m1:m2:_)):[Token]
_) -> do
        Int
d <- Text -> Maybe Int
parseInt Text
m1
        Int
m <- Text -> Maybe Int
parseInt Text
m2
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeofdayLatent :: Rule
ruleTimeofdayLatent :: Rule
ruleTimeofdayLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"time-of-day (latent)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
0 Int
23
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> TimeData
hour (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
12) Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAgo :: Rule
ruleDurationAgo :: Rule
ruleDurationAgo = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> ago"
  , pattern :: Pattern
pattern =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"тому"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Duration a
dd:Token
_:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
durationAgo a
DurationData
dd
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastNCycle :: Rule
ruleLastNCycle :: Rule
ruleLastNCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last n <cycle>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"останні"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
9999
    , 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
token:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True a
Grain
grain (- Int
n)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleWithinDuration :: Rule
ruleWithinDuration :: Rule
ruleWithinDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"within <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 Dimension a
Duration a
dd:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
now (DurationData -> TimeData
inDuration a
DurationData
dd)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMidnighteodendOfDay :: Rule
ruleMidnighteodendOfDay :: Rule
ruleMidnighteodendOfDay = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"midnight|EOD|end of day"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(кінця|концеції) дня"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> TimeData
hour Bool
False Int
0
  }

ruleDayofmonthNonOrdinalNamedmonth :: Rule
ruleDayofmonthNonOrdinalNamedmonth :: Rule
ruleDayofmonthNonOrdinalNamedmonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (non ordinal) <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMInteger
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersect :: Rule
ruleIntersect :: Rule
ruleIntersect = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleUntilTimeofday :: Rule
ruleUntilTimeofday :: Rule
ruleUntilTimeofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"until <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"до"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.Before a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAtTimeofday :: Rule
ruleAtTimeofday :: Rule
ruleAtTimeofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"о"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
notLatent a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNthTimeOfTime :: Rule
ruleNthTimeOfTime :: Rule
ruleNthTimeOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nth <time> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"в|у"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal OrdinalData{TOrdinal.value = v}:
       Token Dimension a
Time a
td1:
       Token
_:
       Token Dimension a
Time a
td2:
       [Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Bool -> TimeData -> TimeData
predNth (Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Bool
False (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td2 a
TimeData
td1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNthTimeOfTime2 :: Rule
ruleNthTimeOfTime2 :: Rule
ruleNthTimeOfTime2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nth <time> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal OrdinalData{TOrdinal.value = v}:
       Token Dimension a
Time a
td1:
       Token Dimension a
Time a
td2:
       [Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Bool -> TimeData -> TimeData
predNth (Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Bool
False (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td2 a
TimeData
td1
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimePartofday :: Rule
ruleTimePartofday :: Rule
ruleTimePartofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> <part-of-day>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleWeekend :: Rule
ruleWeekend :: Rule
ruleWeekend = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"week-end"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"вихідні"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
mkOkForThisNext TimeData
weekend
  }

ruleOrdinalQuarterYear :: Rule
ruleOrdinalQuarterYear :: Rule
ruleOrdinalQuarterYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> quarter <year>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Quarter
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal a
od:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Quarter (OrdinalData -> Int
TOrdinal.value a
OrdinalData
od Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYyyymmdd :: Rule
ruleYyyymmdd :: Rule
ruleYyyymmdd = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"yyyy-mm-dd"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{2,4})-(0?[1-9]|10|11|12)-([012]?[1-9]|10|20|30|31)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (m1:m2:m3:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
m1
        Int
m <- Text -> Maybe Int
parseInt Text
m2
        Int
d <- Text -> Maybe Int
parseInt Text
m3
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntersectByOfFromS :: Rule
ruleIntersectByOfFromS :: Rule
ruleIntersectByOfFromS = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect by 'of', 'from', 's"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"на"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNextNCycle :: Rule
ruleNextNCycle :: Rule
ruleNextNCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"next n <cycle>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"наступні"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
9999
    , 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
token:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        Int
v <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True a
Grain
grain Int
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMorning :: Rule
ruleMorning :: Rule
ruleMorning = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"morning"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ранку|вранці"
    ]
  , prod :: Production
prod = \[Token]
_ ->
      let from :: TimeData
from = Bool -> Int -> TimeData
hour Bool
False Int
3
          to :: TimeData
to = Bool -> Int -> TimeData
hour Bool
False Int
12
      in Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
from TimeData
to
  }

ruleThisPartofday :: Rule
ruleThisPartofday :: Rule
ruleThisPartofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this <part-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(на |в )?(цьому|ця|цей|цього|це|ці)"
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect TimeData
today a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleThisCycle :: Rule
ruleThisCycle :: Rule
ruleThisCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this <cycle>"
  , 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]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleThisTime :: Rule
ruleThisTime :: Rule
ruleThisTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(на |в )?(цьому|ця|цей|цього|це|ці)"
    , Predicate -> PatternItem
Predicate Predicate
isOkWithThisNext
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYearLatent :: Rule
ruleYearLatent :: Rule
ruleYearLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"year (latent)"
  , 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
or ([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 [Int -> Int -> Predicate
isIntegerBetween (- Int
10000) Int
0, Int -> Int -> Predicate
isIntegerBetween Int
25 Int
999]
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:[Token]
_) -> do
        Int
y <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
year Int
y
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAfterTimeofday :: Rule
ruleAfterTimeofday :: Rule
ruleAfterTimeofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"after <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"після"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.After a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNight :: Rule
ruleNight :: Rule
ruleNight = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"night"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ночі"
    ]
  , prod :: Production
prod = \[Token]
_ ->
      let from :: TimeData
from = Bool -> Int -> TimeData
hour Bool
False Int
0
          to :: TimeData
to = Bool -> Int -> TimeData
hour Bool
False Int
4
      in Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
           TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
from TimeData
to
  }

ruleDayofmonthOrdinal :: Rule
ruleDayofmonthOrdinal :: Rule
ruleDayofmonthOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (ordinal)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal OrdinalData{TOrdinal.value = v}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOrdinalCycleOfTime :: Rule
ruleOrdinalCycleOfTime :: Rule
ruleOrdinalCycleOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"у|в"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal a
od:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True a
Grain
grain (OrdinalData -> Int
TOrdinal.value a
OrdinalData
od Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }


ruleHhmm :: Rule
ruleHhmm :: Rule
ruleHhmm = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hh:mm"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((?:[01]?\\d)|(?:2[0-3]))[:.ч]([0-5]\\d)(?:годин(и|і|а)?|ч)?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (m1:m2:_)):[Token]
_) -> do
        Int
h <- Text -> Maybe Int
parseInt Text
m1
        Int
m <- Text -> Maybe Int
parseInt Text
m2
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
False Int
h Int
m
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYear :: Rule
ruleYear :: Rule
ruleYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1000 Int
2100
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:[Token]
_) -> do
        Int
y <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
year Int
y
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNamedmonthDayofmonthNonOrdinal :: Rule
ruleNamedmonthDayofmonthNonOrdinal :: Rule
ruleNamedmonthDayofmonthNonOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<named-month> <day-of-month> (non ordinal)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , Predicate -> PatternItem
Predicate Predicate
isDOMInteger
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:Token
token:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHhmmMilitary :: Rule
ruleHhmmMilitary :: Rule
ruleHhmmMilitary = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hhmm (military)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((?:[01]?\\d)|(?:2[0-3]))([0-5]\\d)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (h:m:_)):[Token]
_) -> do
        Int
hh <- Text -> Maybe Int
parseInt Text
h
        Int
mm <- Text -> Maybe Int
parseInt Text
m
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
False Int
hh Int
mm
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAbsorptionOfAfterNamedDay :: Rule
ruleAbsorptionOfAfterNamedDay :: Rule
ruleAbsorptionOfAfterNamedDay = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"absorption of , after named day"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
","
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
x:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
x
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastDayofweekOfTime :: Rule
ruleLastDayofweekOfTime :: Rule
ruleLastDayofweekOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <day-of-week> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"останній"
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
"у|в"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData -> TimeData
predLastOf a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeofdayTimeofdayInterval :: Rule
ruleTimeofdayTimeofdayInterval :: Rule
ruleTimeofdayTimeofdayInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> - <time-of-day> (interval)"
  , 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
isNotLatent, Predicate
isATimeOfDay]
    , String -> PatternItem
regex String
"\\-"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeofdayTimeofdayInterval2 :: Rule
ruleTimeofdayTimeofdayInterval2 :: Rule
ruleTimeofdayTimeofdayInterval2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> - <time-of-day> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"\\-|/"
    , 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
isNotLatent, Predicate
isATimeOfDay]
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAfterTime :: Rule
ruleDurationAfterTime :: Rule
ruleDurationAfterTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> after <time>"
  , pattern :: Pattern
pattern =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"після"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Duration a
dd:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleOrdinalQuarter :: Rule
ruleOrdinalQuarter :: Rule
ruleOrdinalQuarter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> quarter"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Quarter
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Ordinal OrdinalData{TOrdinal.value = v}:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
        Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Quarter (Int
v Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Year Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationBeforeTime :: Rule
ruleDurationBeforeTime :: Rule
ruleDurationBeforeTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> before <time>"
  , pattern :: Pattern
pattern =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"перед"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Duration a
dd:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData -> TimeData
durationBefore a
DurationData
dd a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePartofdayOfTime :: Rule
rulePartofdayOfTime :: Rule
rulePartofdayOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<part-of-day> of <time>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMmddyyyy :: Rule
ruleMmddyyyy :: Rule
ruleMmddyyyy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm/dd/yyyy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([012]?[1-9]|10|20|30|31)\\.(0?[1-9]|10|11|12)\\.(\\d{2,4})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (m1:m2:m3:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
m3
        Int
m <- Text -> Maybe Int
parseInt Text
m2
        Int
d <- Text -> Maybe Int
parseInt Text
m1
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> TimeData
yearMonthDay Int
y Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeofdayOclock :: Rule
ruleTimeofdayOclock :: Rule
ruleTimeofdayOclock = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day>  o'clock"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"годин(и|і|а)?|ч(?:[\\s'\"-_{}\\[\\]()]|$)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
notLatent a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDayofmonthordinalNamedmonthYear :: Rule
ruleDayofmonthordinalNamedmonthYear :: Rule
ruleDayofmonthordinalNamedmonthYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month>(ordinal) <named-month> year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"(\\d{2,4})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:
       Token Dimension a
Time a
td:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [Token]
_) -> do
        Int
n <- Text -> Maybe Int
parseInt Text
match
        TimeData
dom <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect TimeData
dom (Int -> TimeData
year Int
n)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimezone :: Rule
ruleTimezone :: Rule
ruleTimezone = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> timezone"
  , 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
isNotLatent, Predicate
isATimeOfDay]
    , String -> PatternItem
regex String
"\\b(YEKT|YEKST|YAKT|YAKST|WITA|WIT|WIB|WGT|WGST|WFT|WET|WEST|WAT|WAST|VUT|VLAT|VLAST|VET|UZT|UYT|UYST|UTC|ULAT|TVT|TMT|TLT|TKT|TJT|TFT|TAHT|SST|SRT|SGT|SCT|SBT|SAST|SAMT|RET|PYT|PYST|PWT|PST|PONT|PMST|PMDT|PKT|PHT|PHOT|PGT|PETT|PETST|PET|PDT|OMST|OMSST|NZST|NZDT|NUT|NST|NPT|NOVT|NOVST|NFT|NDT|NCT|MYT|MVT|MUT|MST|MSK|MSD|MMT|MHT|MDT|MAWT|MART|MAGT|MAGST|LINT|LHST|LHDT|KUYT|KST|KRAT|KRAST|KGT|JST|IST|IRST|IRKT|IRKST|IRDT|IOT|IDT|ICT|HOVT|HKT|GYT|GST|GMT|GILT|GFT|GET|GAMT|GALT|FNT|FKT|FKST|FJT|FJST|EST|EGT|EGST|EET|EEST|EDT|ECT|EAT|EAST|EASST|DAVT|ChST|CXT|CVT|CST|COT|CLT|CLST|CKT|CHAST|CHADT|CET|CEST|CDT|CCT|CAT|CAST|BTT|BST|BRT|BRST|BOT|BNT|AZT|AZST|AZOT|AZOST|AWST|AWDT|AST|ART|AQTT|ANAT|ANAST|AMT|AMST|ALMT|AKST|AKDT|AFT|AEST|AEDT|ADT|ACST|ACDT)\\b"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:
       Token Dimension a
RegexMatch (GroupMatch (tz:_)):
       [Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> TimeData -> Maybe TimeData
inTimezone (Text -> Text
Text.toUpper Text
tz) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [Rule
ruleAbsorptionOfAfterNamedDay
  , Rule
ruleAfterTimeofday
  , Rule
ruleAfternoon
  , Rule
ruleAtTimeofday
  , Rule
ruleBetweenTimeofdayAndTimeofdayInterval
  , Rule
ruleDatetimeDatetimeInterval
  , Rule
ruleDateDateInterval
  , Rule
ruleDayofmonthNonOrdinalNamedmonth
  , Rule
ruleDayofmonthOrdinal
  , Rule
ruleDayofmonthordinalNamedmonth
  , Rule
ruleDayofmonthordinalNamedmonthYear
  , Rule
ruleDurationAfterTime
  , Rule
ruleDurationAgo
  , Rule
ruleDurationBeforeTime
  , Rule
ruleEvening
  , Rule
ruleHhmm
  , Rule
ruleHhmmMilitary
  , Rule
ruleHourofdayIntegerAsRelativeMinutes
  , Rule
ruleInDuration
  , Rule
ruleIntersect
  , Rule
ruleIntersectBy
  , Rule
ruleIntersectByOfFromS
  , Rule
ruleLastCycle
  , Rule
ruleLastCycleOfTime
  , Rule
ruleLastCycleOfTime2
  , Rule
ruleLastDayofweekOfTime
  , Rule
ruleLastNCycle
  , Rule
ruleLastTime
  , Rule
ruleLunch
  , Rule
ruleMidnighteodendOfDay
  , Rule
ruleMmdd
  , Rule
ruleMmddyyyy
  , Rule
ruleMonthDdddInterval
  , Rule
ruleMorning
  , Rule
ruleNamedmonthDayofmonthNonOrdinal
  , Rule
ruleNamedmonthDayofmonthOrdinal
  , Rule
ruleNextCycle
  , Rule
ruleNextNCycle
  , Rule
ruleNight
  , Rule
ruleNoon
  , Rule
ruleNthTimeAfterTime
  , Rule
ruleNthTimeOfTime
  , Rule
ruleNthTimeOfTime2
  , Rule
ruleOnDate
  , Rule
ruleOrdinalCycleOfTime
  , Rule
ruleOrdinalQuarter
  , Rule
ruleOrdinalQuarterYear
  , Rule
rulePartofdayOfTime
  , Rule
ruleThisCycle
  , Rule
ruleThisPartofday
  , Rule
ruleThisTime
  , Rule
ruleThisnextDayofweek
  , Rule
ruleTimeAfterNext
  , Rule
ruleTimePartofday
  , Rule
ruleTimeofdayLatent
  , Rule
ruleTimeofdayOclock
  , Rule
ruleTimeofdayTimeofdayInterval
  , Rule
ruleTimeofdayTimeofdayInterval2
  , Rule
ruleUntilTimeofday
  , Rule
ruleWeekend
  , Rule
ruleWithinDuration
  , Rule
ruleYear
  , Rule
ruleYearLatent
  , Rule
ruleYearLatent2
  , Rule
ruleYyyymmdd
  , Rule
ruleTimezone
  ]
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleInstants
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleDaysOfWeek
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleMonths
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleSeasons
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleHolidays