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

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

import Control.Applicative ((<|>))
import Data.Maybe
import Data.Text (Text)
import Prelude
import qualified Data.Text as Text

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers (duration)
import Duckling.Duration.Types (DurationData (..))
import Duckling.Numeral.Helpers (isNatural, parseInt)
import Duckling.Numeral.Types (NumeralData (..))
import Duckling.Ordinal.Types (OrdinalData (..))
import Duckling.Regex.Types
import Duckling.Time.Computed
import Duckling.Time.Helpers
import Duckling.Time.Types (TimeData (..), TimeIntervalType (..))
import Duckling.Types
import qualified Duckling.Duration.Types as TDuration
import qualified Duckling.Numeral.Types as TNumeral
import qualified Duckling.Ordinal.Types as TOrdinal
import qualified Duckling.Time.Types as TTime
import qualified Duckling.TimeGrain.Types as TG

ruleIntersect :: Rule
ruleIntersect :: Rule
ruleIntersect = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect"
  , 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, Grain -> Predicate
isGrainFinerThan Grain
TG.Year]
    , 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 [Predicate
isNotLatent, Grain -> Predicate
isGrainOfTime Grain
TG.Year]
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleIntersectOf :: Rule
ruleIntersectOf :: Rule
ruleIntersectOf = 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 = \case
      (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
. TimeData -> TimeData
notLatent (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
  }

ruleIntersectYear :: Rule
ruleIntersectYear :: Rule
ruleIntersectYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect by \",\", \"of\", \"from\" for year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"на|,"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Year
    ]
  , prod :: Production
prod = \case
      (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
. TimeData -> TimeData
notLatent (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
  }

ruleAbsorbOnDay :: Rule
ruleAbsorbOnDay :: Rule
ruleAbsorbOnDay = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"on <day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"на"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Day
    ]
  , prod :: Production
prod = \case
      (Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAbsorbOnADOW :: Rule
ruleAbsorbOnADOW :: Rule
ruleAbsorbOnADOW = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"on a <named-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"в"
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    ]
  , prod :: Production
prod = \case
      (Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAbsorbInMonthYear :: Rule
ruleAbsorbInMonthYear :: Rule
ruleAbsorbInMonthYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in|during <named-month>|year"
  , pattern :: Pattern
pattern =
    [ 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
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 [Predicate
isAMonth, Grain -> Predicate
isGrainOfTime Grain
TG.Year]
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleAbsorbCommaTOD :: Rule
ruleAbsorbCommaTOD :: Rule
ruleAbsorbCommaTOD = 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 = \case
      (Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInstants :: [Rule]
ruleInstants :: [Rule]
ruleInstants = [(Text, Grain, Int, String)] -> [Rule]
mkRuleInstants
  [ (Text
"right now"        , Grain
TG.Second, Int
0  , String
"((точно\\s+)?сега)|веднага")
  , (Text
"today"            , Grain
TG.Day   , Int
0  , String
"днес|(по това време)"      )
  , (Text
"tomorrow"         , Grain
TG.Day   , Int
1  , String
"утре"                      )
  , (Text
"yesterday"        , Grain
TG.Day   , - Int
1, String
"вчера"                     )
  , ( Text
"after tomorrow"  , Grain
TG.Day   , Int
2  , String
"(в\\s*)?другиден"          )
  , ( Text
"before yesterday", Grain
TG.Day   , - Int
2, String
"(оня ден)|завчера"         )
  ]

ruleNow :: Rule
ruleNow :: Rule
ruleNow = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"now"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"сега"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt TimeData
now
  }

ruleNextDOW :: Rule
ruleNextDOW :: Rule
ruleNextDOW = 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 = \case
      (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
  }

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 = \case
      (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
  }

ruleNextTime :: Rule
ruleNextTime :: Rule
ruleNextTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"next <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"следващ((ия(т)?)|ата|ото)"
    , Predicate -> PatternItem
Predicate Predicate
isOkWithThisNext
    ]
  , prod :: Production
prod = \case
      (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
  }

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 = \case
      (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
  }

ruleLastWeekendOfMonth :: Rule
ruleLastWeekendOfMonth :: Rule
ruleLastWeekendOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last weekend of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"последния(т)? уикенд\\s+(през|на)"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (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 TimeData
weekend a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTimeBeforeLast :: Rule
ruleTimeBeforeLast :: Rule
ruleTimeBeforeLast = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> before last"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"по(\\-|\\s+)((пред(н|ишн))|минал)((ия(т)?)|ата|ото)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
    (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
2) Bool
False a
TimeData
td
    [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 =
    [ String -> PatternItem
regex String
"по(\\-|\\s+)следващ((ия(т)?)|ата|ото)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
    (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
True a
TimeData
td
    [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastDOWOfTime :: Rule
ruleLastDOWOfTime :: Rule
ruleLastDOWOfTime = 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 = \case
      (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
  }

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 = \case
      (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
  }

ruleLastNight :: Rule
ruleLastNight :: Rule
ruleLastNight = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last night"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(късно )?снощи"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        let hours :: Int
hours = if Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"късно " then Int
3 else Int
6
            start :: TimeData
start = DurationData -> TimeData -> TimeData
durationBefore (Int -> Grain -> DurationData
DurationData Int
hours Grain
TG.Hour) TimeData
today
        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
partOfDay (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (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
start TimeData
today
      [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 = \case
      (Token Dimension a
Ordinal a
od: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 (OrdinalData -> Int
TOrdinal.value a
OrdinalData
od 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
  }

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 = \case
      (Token Dimension a
Ordinal a
od: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 (OrdinalData -> Int
TOrdinal.value a
OrdinalData
od 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
  }

ruleNDOWFromTime :: Rule
ruleNDOWFromTime :: Rule
ruleNDOWFromTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> <day-of-week> from <time>"
  , pattern :: Pattern
pattern =
    [ Dimension NumeralData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension NumeralData
Numeral
    , 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 = \case
      (Token
token:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[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
$ Int -> TimeData -> TimeData -> TimeData
predNthAfter (Int
n 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
  }

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
10000]
      ]
  , prod :: Production
prod = \case
      (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
$ Int -> TimeData
year Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYearADBC :: Rule
ruleYearADBC :: Rule
ruleYearADBC = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<year> (bc|ad)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween (-Int
10000) Int
10000
    , String -> PatternItem
regex String
"(пр|сл)\\.?\\s+(Хр\\.?|н\\.?\\e.?)"
    ]
  , prod :: Production
prod = \case
    (Token
token:Token Dimension a
RegexMatch (GroupMatch (ab:_)):[Token]
_) -> do
      Int
y <- Token -> Maybe Int
getIntValue Token
token
      TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> TimeData
yearADBC (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ if Text -> Char
Text.head (Text -> Text
Text.toLower Text
ab) Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'п' then -Int
y else Int
y
    [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOMLatent :: Rule
ruleDOMLatent :: Rule
ruleDOMLatent = 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 = \case
      (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
$ Int -> TimeData
dayOfMonth Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTheDOMNumeral :: Rule
ruleTheDOMNumeral :: Rule
ruleTheDOMNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the <day-of-month> (number)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMInteger
    ]
  , prod :: Production
prod = \case
      (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
$ Int -> TimeData
dayOfMonth Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTheDOMOrdinal :: Rule
ruleTheDOMOrdinal :: Rule
ruleTheDOMOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the <day-of-month> (ordinal)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleNamedDOMOrdinal :: Rule
ruleNamedDOMOrdinal :: Rule
ruleNamedDOMOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<named-month>|<named-day> <day-of-month> (ordinal)"
  , 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 [Predicate
isAMonth, Predicate
isADayOfWeek]
    , Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleMonthDOMNumeral :: Rule
ruleMonthDOMNumeral :: Rule
ruleMonthDOMNumeral = 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 = \case
      (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
  }

ruleDOMMonth :: Rule
ruleDOMMonth :: Rule
ruleDOMMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (ordinal or number) <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleDOMMonthYear :: Rule
ruleDOMMonthYear :: Rule
ruleDOMMonthYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month>(ordinal or number)/<named-month>/year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"[-/\\s]"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"[-/\\s]"
    , String -> PatternItem
regex String
"(\\d{4})"
    ]
  , prod :: Production
prod = \case
      (Token
token:
       Token
_:
       Token Dimension a
Time a
td:
       Token
_:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [Token]
_) -> do
         Int
intVal <- 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
intVal)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOMOrdinalMonthYear :: Rule
ruleDOMOrdinalMonthYear :: Rule
ruleDOMOrdinalMonthYear = 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 = \case
      (Token
token:Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        Int
intVal <- 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
intVal)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMonthYear :: Rule
ruleMonthYear :: Rule
ruleMonthYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<named-month> year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"(\\d{2,4})"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        Int
intVal <- Text -> Maybe Int
parseInt Text
match
        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
td (Int -> TimeData
year Int
intVal)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIdesOfMonth :: Rule
ruleIdesOfMonth :: Rule
ruleIdesOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the ides of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"средата на"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Time td :: a
td@TimeData {TTime.form = Just (TTime.Month m)}:[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
td (Int -> TimeData
dayOfMonth (Int -> TimeData) -> Int -> TimeData
forall a b. (a -> b) -> a -> b
$ if Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Int
m [Int
3, Int
5, Int
7, Int
10] then Int
15 else Int
13)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTODLatent :: Rule
ruleTODLatent :: Rule
ruleTODLatent = 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 = \case
      (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
13) Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAtTOD :: Rule
ruleAtTOD :: Rule
ruleAtTOD = 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 = \case
      (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
  }

ruleTODOClock :: Rule
ruleTODOClock :: Rule
ruleTODOClock = 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
"часа"
    ]
  , prod :: Production
prod = \case
      (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
  }

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 = \case
      (Token Dimension a
RegexMatch (GroupMatch (hh:mm:_)):[Token]
_) -> do
        Int
h <- Text -> Maybe Int
parseInt Text
hh
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        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
  }

ruleHHhMM :: Rule
ruleHHhMM :: Rule
ruleHHhMM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hhhmm"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(?<!/)((?:[01]?\\d)|(?:2[0-3]))ч(([0-5]\\d)|(?!\\d))"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (hh:mm:_)):[Token]
_) -> do
        Int
h <- Text -> Maybe Int
parseInt Text
hh
        Int
m <- Text -> Maybe Int
parseInt Text
mm Maybe Int -> Maybe Int -> Maybe Int
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
        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
  }

ruleHHMMLatent :: Rule
ruleHHMMLatent :: Rule
ruleHHMMLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hhmm (latent)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((?:[01]?\\d)|(?:2[0-3]))([0-5]\\d)(?!.\\d)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (hh:mm:_)):[Token]
_) -> do
        Int
h <- Text -> Maybe Int
parseInt Text
hh
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        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
h Int
m
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleTODAM :: Rule
ruleTODAM :: Rule
ruleTODAM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> am"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"сутрин(та)?"
    ]
  , prod :: Production
prod = \case
      (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 -> TimeData -> TimeData
timeOfDayAMPM Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTODPM :: Rule
ruleTODPM :: Rule
ruleTODPM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> pm"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"вечер(та)?|след об(е|я)д"
    ]
  , prod :: Production
prod = \case
      (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 -> TimeData -> TimeData
timeOfDayAMPM Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHONumeral :: Rule
ruleHONumeral :: Rule
ruleHONumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> <integer>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate 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 = \case
      (Token Dimension a
Time TimeData{TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)
                          ,TTime.latent = isLatent}:
       Token
token:
       [Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        if Bool
isLatent
          then 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
is12H Int
hours Int
n
          else 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
  }

ruleHODHalf :: Rule
ruleHODHalf :: Rule
ruleHODHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> half"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"и половина"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time TimeData{TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:
       [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
30
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODQuarter :: Rule
ruleHODQuarter :: Rule
ruleHODQuarter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> quarter"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"и (четвърт|(петнайсе(т)?))"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time TimeData{TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:
       [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
15
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralToHOD :: Rule
ruleNumeralToHOD :: Rule
ruleNumeralToHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> to|till|before <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , 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
59
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue 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
<$> Int -> TimeData -> Maybe TimeData
minutesBefore Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleQuarterToHOD :: Rule
ruleQuarterToHOD :: Rule
ruleQuarterToHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"quarter to|till|before <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"без (четвърт|(петнайсе(т)?))"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
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
<$> Int -> TimeData -> Maybe TimeData
minutesBefore Int
15 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralAfterHOD :: Rule
ruleNumeralAfterHOD :: Rule
ruleNumeralAfterHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer after|past <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , 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
59
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue 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
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMMYYYY :: Rule
ruleMMYYYY :: Rule
ruleMMYYYY = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"mm/yyyy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(0?[1-9]|1[0-2])[/-](\\d{4})"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (mm:yy:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
yearMonth Int
y Int
m
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYYYYMM :: Rule
ruleYYYYMM :: Rule
ruleYYYYMM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"yyyy-mm"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{4})\\s*[/-]\\s*(1[0-2]|0?[1-9])"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (yy:mm:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
yearMonth Int
y Int
m
      [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]|1[0-2])-(3[01]|[12]\\d|0?[1-9])"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (yy:mm:dd:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        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
  }

ruleDDMMYYYYDot :: Rule
ruleDDMMYYYYDot :: Rule
ruleDDMMYYYYDot = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dd.mm.yyyy"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(3[01]|[12]\\d|0?[1-9])\\.(1[0-2]|0?[1-9])\\.(\\d{2,4})"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (dd:mm:yy:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        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
  }

ruleYYYYQQ :: Rule
ruleYYYYQQ :: Rule
ruleYYYYQQ = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"yyyyqq"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{2,4})q([1-4])"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (yy:qq:_)):[Token]
_) -> do
        Int
y <- Text -> Maybe Int
parseInt Text
yy
        Int
q <- Text -> Maybe Int
parseInt Text
qq
        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
True Grain
TG.Quarter (Int
q 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
$ Int -> TimeData
year Int
y
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNoonMidnightEOD :: Rule
ruleNoonMidnightEOD :: Rule
ruleNoonMidnightEOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"noon|midnight|EOD|end of day"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(обед|обяд|полунощ|((в )?(края на деня)))"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int -> TimeData
hour Bool
False (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$
        if (Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"обед" Bool -> Bool -> Bool
|| Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"обяд")  then Int
12 else Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePartOfDays :: Rule
rulePartOfDays :: Rule
rulePartOfDays = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"part of days"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(сутрин(та)?|(по|след) ?об(е|я)д|вечер(та)?|(през )?нощ(та)?)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        let (TimeData
start, TimeData
end) = case Text -> Text
Text.toLower Text
match of
              Text
"сутрин"  -> (Bool -> Int -> TimeData
hour Bool
False Int
4, Bool -> Int -> TimeData
hour Bool
False Int
12)
              Text
"сутринта"  -> (Bool -> Int -> TimeData
hour Bool
False Int
4, Bool -> Int -> TimeData
hour Bool
False Int
12)
              Text
"вечер"  -> (Bool -> Int -> TimeData
hour Bool
False Int
18, Bool -> Int -> TimeData
hour Bool
False Int
0)
              Text
"вечерта"  -> (Bool -> Int -> TimeData
hour Bool
False Int
18, Bool -> Int -> TimeData
hour Bool
False Int
0)
              Text
"нощ"    -> (Bool -> Int -> TimeData
hour Bool
False Int
0, Bool -> Int -> TimeData
hour Bool
False Int
4)
              Text
"нощта"    -> (Bool -> Int -> TimeData
hour Bool
False Int
0, Bool -> Int -> TimeData
hour Bool
False Int
4)
              Text
"през нощта"    -> (Bool -> Int -> TimeData
hour Bool
False Int
0, Bool -> Int -> TimeData
hour Bool
False Int
4)
              Text
"обед"    -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
14)
              Text
"по обед" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
14)
              Text
"обяд"    -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
14)
              Text
"по обяд" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
14)
              Text
_          -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
19)
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
mkLatent TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleEarlyMorning :: Rule
ruleEarlyMorning :: Rule
ruleEarlyMorning = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"early morning"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"рано сутрин(та)?"
    ]
  , prod :: Production
prod = \[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 -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (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 (Bool -> Int -> TimeData
hour Bool
False Int
4) (Bool -> Int -> TimeData
hour Bool
False Int
9)
  }

rulePODThis :: Rule
rulePODThis :: Rule
rulePODThis = 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 = \case
      (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 -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (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
  }

ruleTonight :: Rule
ruleTonight :: Rule
ruleTonight = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"tonight"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(късно )?вечер(та)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        let h :: Int
h = if Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"късно " then Int
21 else Int
18
        TimeData
evening <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Bool -> Int -> TimeData
hour Bool
False Int
h) (Bool -> Int -> TimeData
hour Bool
False Int
0)
        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 -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (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 TimeData
evening
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleAfterPartofday :: Rule
ruleAfterPartofday :: Rule
ruleAfterPartofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"after lunch/work/school"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"след[\\s*]?((об(е|я)д)|работа|училище)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        (TimeData
start, TimeData
end) <- case Text -> Text
Text.toLower Text
match of
          Text
"обед"  -> (TimeData, TimeData) -> Maybe (TimeData, TimeData)
forall a. a -> Maybe a
Just (Bool -> Int -> TimeData
hour Bool
False Int
13, Bool -> Int -> TimeData
hour Bool
False Int
17)
          Text
"обяд"  -> (TimeData, TimeData) -> Maybe (TimeData, TimeData)
forall a. a -> Maybe a
Just (Bool -> Int -> TimeData
hour Bool
False Int
13, Bool -> Int -> TimeData
hour Bool
False Int
17)
          Text
"работа"   -> (TimeData, TimeData) -> Maybe (TimeData, TimeData)
forall a. a -> Maybe a
Just (Bool -> Int -> TimeData
hour Bool
False Int
17, Bool -> Int -> TimeData
hour Bool
False Int
21)
          Text
"училище" -> (TimeData, TimeData) -> Maybe (TimeData, TimeData)
forall a. a -> Maybe a
Just (Bool -> Int -> TimeData
hour Bool
False Int
15, Bool -> Int -> TimeData
hour Bool
False Int
21)
          Text
_        -> Maybe (TimeData, TimeData)
forall a. Maybe a
Nothing
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end
        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 -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (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 TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- Since part of days are latent, general time intersection is blocked
ruleTimePOD :: Rule
ruleTimePOD :: Rule
ruleTimePOD = 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 = \case
      (Token Dimension a
Time a
td:Token Dimension a
Time a
pod:[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
pod a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePODofTime :: Rule
rulePODofTime :: Rule
rulePODofTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<part-of-day> of <time>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , String -> PatternItem
regex String
"на"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
pod: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 -> TimeData -> Maybe TimeData
intersect a
TimeData
pod a
TimeData
td
      [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
  }

ruleWeek :: Rule
ruleWeek :: Rule
ruleWeek = Rule :: Text -> Pattern -> Production -> Rule
Rule
 { name :: Text
name = Text
"week"
 , pattern :: Pattern
pattern = [String -> PatternItem
regex String
"(цяла|(остатъка на( тази)?)) седмица(та)?"]
 , prod :: Production
prod = \case
     (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
       let end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True Grain
TG.Day (-Int
2) (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Week Int
1
           period :: Maybe TimeData
period = case Text -> Text
Text.toLower Text
match of
                      Text
"цяла" -> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
Closed (Grain -> Int -> TimeData
cycleNth Grain
TG.Week Int
0) TimeData
end
                      Text
"остатъка на" -> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
Open TimeData
today TimeData
end
                      Text
"остатъка на тази" -> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
Open TimeData
today TimeData
end
                      Text
_ -> Maybe TimeData
forall a. Maybe a
Nothing
       in case Text -> Text
Text.toLower Text
match of
         Text
"тази" -> 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 -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe TimeData
period
         Text
_ -> 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
<$> Maybe TimeData
period
     [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
 }

ruleSeason :: Rule
ruleSeason :: Rule
ruleSeason = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last|this|next <season>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(това|тази|(по\\-)?(по\\-)?((настоящ|следващ|друг|последн|минал|предн)(ото|ата))) seasons?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        Int
n <- case Text -> Text
Text.toLower Text
match of
               Text
"това" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
               Text
"тази" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
               Text
"настоящото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
               Text
"настоящата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
               Text
"миналото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"миналата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"последното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"последната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"предното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"предната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
1)
               Text
"следващото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
               Text
"следващата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
               Text
"другото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
               Text
"другата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1
               Text
"по-миналото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-миналата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-последното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-последната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-предното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-предната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
2)
               Text
"по-следващото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
               Text
"по-следващата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
               Text
"по-другото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
               Text
"по-другата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
               Text
"по-по-миналото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-миналата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-последното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-последната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-предното" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-предната" -> Int -> Maybe Int
forall a. a -> Maybe a
Just (-Int
3)
               Text
"по-по-следващото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3
               Text
"по-по-следващата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3
               Text
"по-по-другото" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3
               Text
"по-по-другата" -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
3
               Text
_ -> Maybe Int
forall a. Maybe a
Nothing
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
n Bool
False TimeData
season
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleSeasons :: [Rule]
ruleSeasons :: [Rule]
ruleSeasons = [(Text, String, TimeData, TimeData)] -> [Rule]
mkRuleSeasons
  [ ( Text
"summer", String
"лято"     , Int -> Int -> TimeData
monthDay  Int
6 Int
21, Int -> Int -> TimeData
monthDay  Int
9 Int
23 )
  , ( Text
"fall"  , String
"есен"     , Int -> Int -> TimeData
monthDay  Int
9 Int
23, Int -> Int -> TimeData
monthDay Int
12 Int
21 )
  , ( Text
"winter", String
"зима"     , Int -> Int -> TimeData
monthDay Int
12 Int
21, Int -> Int -> TimeData
monthDay  Int
3 Int
20 )
  , ( Text
"spring", String
"пролет"   , Int -> Int -> TimeData
monthDay  Int
3 Int
20, Int -> Int -> TimeData
monthDay  Int
6 Int
21 )
  ]

ruleTODPrecision :: Rule
ruleTODPrecision :: Rule
ruleTODPrecision = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> sharp|exactly"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в )?точно( в )?"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \case
      (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
  }

rulePrecisionTOD :: Rule
rulePrecisionTOD :: Rule
rulePrecisionTOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"about|exactly <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"около"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainFinerThan Grain
TG.Year
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleIntervalMonthDDDD :: Rule
ruleIntervalMonthDDDD :: Rule
ruleIntervalMonthDDDD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<month> dd-dd (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|до"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:
       Token
token1:
       Token
_:
       Token
token2:
       [Token]
_) -> do
        TimeData
dom1 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
dom2 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token2
        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
dom1 TimeData
dom2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalDDDDMonth :: Rule
ruleIntervalDDDDMonth :: Rule
ruleIntervalDDDDMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dd-dd <month> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|до"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token
token1:
       Token
_:
       Token
token2:
       Token Dimension a
Time a
td:
       [Token]
_) -> do
        TimeData
dom1 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
dom2 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token2
        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
dom1 TimeData
dom2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalFromDDDDMonth :: Rule
ruleIntervalFromDDDDMonth :: Rule
ruleIntervalFromDDDDMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from the <day-of-month> (ordinal or number) to the <day-of-month> (ordinal or number) <named-month> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"от"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|до"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token
_:
       Token
token1:
       Token
_:
       Token
token2:
       Token Dimension a
Time a
td:
       [Token]
_) -> do
        TimeData
dom1 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
dom2 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token2
        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
dom1 TimeData
dom2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- Blocked for :latent time. May need to accept certain latents only, like hours
ruleIntervalDash :: Rule
ruleIntervalDash :: Rule
ruleIntervalDash = 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 = \case
      (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
  }

ruleIntervalSlash :: Rule
ruleIntervalSlash :: Rule
ruleIntervalSlash = 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 = \case
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        if TimeData -> TimeData -> Bool
sameGrain a
TimeData
td1 a
TimeData
td2 then
          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
        else Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalFrom :: Rule
ruleIntervalFrom :: Rule
ruleIntervalFrom = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <datetime> - <datetime> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"от"
    , 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 = \case
      (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
  }

ruleIntervalBetween :: Rule
ruleIntervalBetween :: Rule
ruleIntervalBetween = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time> and <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"между"
    , 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 = \case
      (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
  }

-- Specific for time-of-day, to help resolve ambiguities
ruleIntervalTODDash :: Rule
ruleIntervalTODDash :: Rule
ruleIntervalTODDash = 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 = \case
      (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
  }

ruleIntervalTODBetween :: Rule
ruleIntervalTODBetween :: Rule
ruleIntervalTODBetween = 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 = \case
      (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
  }

ruleIntervalBy :: Rule
ruleIntervalBy :: Rule
ruleIntervalBy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"by <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"до"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (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
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
now a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalByTheEndOf :: Rule
ruleIntervalByTheEndOf :: Rule
ruleIntervalByTheEndOf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"by the end of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"до края на"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (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
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed TimeData
now a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalUntilTime :: Rule
ruleIntervalUntilTime :: Rule
ruleIntervalUntilTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"until <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"преди|до"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.Before (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
  }

ruleIntervalAfterFromSinceTime :: Rule
ruleIntervalAfterFromSinceTime :: Rule
ruleIntervalAfterFromSinceTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from|since|after <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"след|от"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.After (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
  }

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = [(Text, String)] -> [Rule]
mkRuleDaysOfWeek
  [ ( Text
"Monday"   , String
"понеделник|пон\\.?|пн\\.?" )
  , ( Text
"Tuesday"  , String
"вторник|вт\\.?"            )
  , ( Text
"Wednesday", String
"сряда|ср\\.?"              )
  , ( Text
"Thursday" , String
"четвъртък|четв\\.?|чт\\.?" )
  , ( Text
"Friday"   , String
"петък|пет\\.?|пт\\.?"      )
  , ( Text
"Saturday" , String
"събота|съб\\.?|сб\\.?"     )
  , ( Text
"Sunday"   , String
"неделя|нед\\.?|нд\\.?"     )
  ]

ruleMonths :: [Rule]
ruleMonths :: [Rule]
ruleMonths = [(Text, String)] -> [Rule]
mkRuleMonths
  [ ( Text
"January"  , String
"януари|ян\\.?"     )
  , ( Text
"February" , String
"февруари|февр\\.?" )
  , ( Text
"March"    , String
"март"              )
  , ( Text
"April"    , String
"април|апр\\.?"     )
  , ( Text
"May"      , String
"май"               )
  , ( Text
"June"     , String
"юни"               )
  , ( Text
"July"     , String
"юли"               )
  , ( Text
"August"   , String
"август|авг\\.?"    )
  , ( Text
"September", String
"септември|септ\\.?")
  , ( Text
"October"  , String
"октомври|окт\\.?"  )
  , ( Text
"November" , String
"ноември|ноем\\.?"  )
  , ( Text
"December" , String
"декември|дек\\.?"  )
  ]

rulePartOfMonth :: Rule
rulePartOfMonth :: Rule
rulePartOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"part of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(началото|средата|края) на"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):Token Dimension a
Time a
td:[Token]
_) -> do
        (Int
sd, Int
ed) <- case Text -> Text
Text.toLower Text
match of
          Text
"началото" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
1, Int
10)
          Text
"средата"   -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
11, Int
20)
          Text
"края"  -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          Text
_       -> Maybe (Int, Int)
forall a. Maybe a
Nothing
        TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
sd
        TimeData
end <- if Int
ed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= -Int
1
          then TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
ed
          else TimeData -> Maybe TimeData
forall a. a -> Maybe a
Just (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf Grain
TG.Day 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.Open TimeData
start TimeData
end
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleEndOrBeginningOfMonth :: Rule
ruleEndOrBeginningOfMonth :: Rule
ruleEndOrBeginningOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at the beginning|end of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в )?(началото|края) на"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (_:match:_)):Token Dimension a
Time a
td:[Token]
_) -> do
        (Int
sd, Int
ed) <- case Text -> Text
Text.toLower Text
match of
          Text
"началото" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
1, Int
10)
          Text
"края"       -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          Text
_           -> Maybe (Int, Int)
forall a. Maybe a
Nothing
        TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
sd
        TimeData
end <- if Int
ed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= -Int
1
          then TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
ed
          else TimeData -> Maybe TimeData
forall a. a -> Maybe a
Just (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf Grain
TG.Day 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.Open TimeData
start TimeData
end
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleEndOfMonth :: Rule
ruleEndOfMonth :: Rule
ruleEndOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"end of month"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((до|в)\\s+)?края на месеца"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_)
        | (Just TimeData
start, Just TimeData
end) <- (Maybe TimeData, Maybe TimeData)
parsed ->
          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
start TimeData
end
        where
          cycleMonth :: Int -> TimeData
cycleMonth = Grain -> Int -> TimeData
cycleNth Grain
TG.Month
          parsed :: (Maybe TimeData, Maybe TimeData)
parsed = if Text
"до" Text -> Text -> Bool
`Text.isPrefixOf` Text -> Text
Text.toLower Text
match
            then
              ( TimeData -> Maybe TimeData
forall a. a -> Maybe a
Just TimeData
now
              , TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
1) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
cycleMonth Int
1)
            else
              ( TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
21) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
cycleMonth Int
0
              , TimeData -> Maybe TimeData
forall a. a -> Maybe a
Just (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf Grain
TG.Day (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
cycleMonth Int
0)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleBeginningOfMonth :: Rule
ruleBeginningOfMonth :: Rule
ruleBeginningOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"beginning of month"
  , pattern :: Pattern
pattern = [ String -> PatternItem
regex String
"(в\\s+ )?началото на месеца" ]
  , prod :: Production
prod = \[Token]
_ -> do
      TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
1) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Month Int
0
      TimeData
end <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
10) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Month Int
0
      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
start TimeData
end
  }

ruleEndOrBeginningOfYear :: Rule
ruleEndOrBeginningOfYear :: Rule
ruleEndOrBeginningOfYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at the beginning|end of <year>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в\\s+)?(началото|края) на"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Year
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (_:match:_)):Token Dimension a
Time a
td:[Token]
_) -> do
        (Int
sd, Int
ed) <- case Text -> Text
Text.toLower Text
match of
          Text
"началото" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
1, Int
4)
          Text
"края"       -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
9, -Int
1)
          Text
_           -> Maybe (Int, Int)
forall a. Maybe a
Nothing
        TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
month Int
sd
        TimeData
end <- if Int
ed Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= -Int
1
          then TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf Grain
TG.Month (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
month Int
ed
          else Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Year Int
1 (TimeData -> TimeData) -> Maybe TimeData -> Maybe TimeData
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (Int -> TimeData
month Int
1)
        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
start TimeData
end
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleEndOfYear :: Rule
ruleEndOfYear :: Rule
ruleEndOfYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"end of year"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((до|в)\\s+)?края на годината"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        TimeData
start <- Maybe TimeData
std
        TimeData
end <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
month Int
1) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
cycleYear Int
1
        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
start TimeData
end
          where
            std :: Maybe TimeData
std = if Text
"до" Text -> Text -> Bool
`Text.isPrefixOf` Text -> Text
Text.toLower Text
match
              then TimeData -> Maybe TimeData
forall a. a -> Maybe a
Just TimeData
now
              else TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
month Int
9) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
cycleYear Int
0
            cycleYear :: Int -> TimeData
cycleYear = Grain -> Int -> TimeData
cycleNth Grain
TG.Year
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleBeginningOfYear :: Rule
ruleBeginningOfYear :: Rule
ruleBeginningOfYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"beginning of year"
  , pattern :: Pattern
pattern = [ String -> PatternItem
regex String
"(в\\s+)?началото на годината" ]
  , prod :: Production
prod = \[Token]
_ -> do
      TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
month Int
1) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Year Int
0
      TimeData
end <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
month Int
4) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Year Int
0
      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
start TimeData
end
  }

ruleEndOrBeginningOfWeek :: Rule
ruleEndOrBeginningOfWeek :: Rule
ruleEndOrBeginningOfWeek = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at the beginning|end of <week>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(в\\s+)?(началото|края) на"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Week
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (_:match1:_)):Token Dimension a
Time a
td:[Token]
_) -> do
        (Int
sd, Int
ed) <- case Text -> Text
Text.toLower Text
match1 of
          Text
"началото" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
1, Int
3)
          Text
"края"       -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
5, Int
7)
          Text
_           -> Maybe (Int, Int)
forall a. Maybe a
Nothing
        TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfWeek Int
sd
        TimeData
end <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfWeek Int
ed
        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
start TimeData
end
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  -- Fixed dates, year over year
  [ ( Text
"April Fools", String
"първи април", Int -> Int -> TimeData
monthDay Int
4 Int
1 )
  , ( Text
"Bulgarian Liberation Day", String
"(трети март)|(ден(я|ят)? на освобождението на българия( от турско робство)?)", Int -> Int -> TimeData
monthDay Int
3 Int
3 )
  , ( Text
"Bulgarian Indenpendence Day", String
"ден(я|ят)? на (обявянето на)? независимостта на българия", Int -> Int -> TimeData
monthDay Int
9 Int
22 )
  , ( Text
"Bulgarian Unification Day", String
"ден(я|ят)? на съединението на (княжество )?българия(и източна румелия)?", Int -> Int -> TimeData
monthDay Int
9 Int
6 )
  , ( Text
"Slavonic Litaracy Day", String
"(ден(я|ят)? на славянската писменост)|(св(\\.|ети)?(св(\\.|ети)?)? кирил и методи(й)?)", Int -> Int -> TimeData
monthDay Int
5 Int
24 )
  , ( Text
"Saint Geroge's Day", String
"(св(\\.|ети)? георги)|гергьовден", Int -> Int -> TimeData
monthDay Int
5 Int
6 )
  , ( Text
"Assumption of Mary", String
"голяма богородица", Int -> Int -> TimeData
monthDay Int
8 Int
15 )
  , ( Text
"Christmas", String
"коледа|(рождество( христово)?)", Int -> Int -> TimeData
monthDay Int
12 Int
25 )
  , ( Text
"Christmas Eve", String
"бъдни вечер", Int -> Int -> TimeData
monthDay Int
12 Int
24 )
  , ( Text
"Earth Day", String
"ден(я|ят) на земята", Int -> Int -> TimeData
monthDay Int
4 Int
22 )
  , ( Text
"May Day", String
"(първи май)|(ден(я|ят)? на труда)", Int -> Int -> TimeData
monthDay Int
5 Int
1 )
  , ( Text
"New Year's Day", String
"нова година", Int -> Int -> TimeData
monthDay  Int
1  Int
1 )
  , ( Text
"St. George's Day", String
"гергьовден|(св(\\.|ети)? георги)", Int -> Int -> TimeData
monthDay Int
5 Int
6 )
  , ( Text
"Valentine's Day", String
"св(\\.|ети)? валентин", Int -> Int -> TimeData
monthDay Int
2 Int
14 )
  , ( Text
"International Women's Day", String
"ден(я|ят)? на (майката|жената)", Int -> Int -> TimeData
monthDay Int
3 Int
8 )
  ]

ruleComputedHolidays :: [Rule]
ruleComputedHolidays :: [Rule]
ruleComputedHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"Orthodox Easter Monday", String
"велики понеделник"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
1 TimeData
orthodoxEaster )
  , ( Text
"Orthodox Easter Sunday", String
"великден"
    , TimeData
orthodoxEaster )
  , ( Text
"Orthodox Holy Saturday", String
"велика събота"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
1) TimeData
orthodoxEaster )
  , ( Text
"Orthodox Great Friday", String
"(велики|разпети) петък"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
2) TimeData
orthodoxEaster )
  , ( Text
"Orthodox Palm Sunday", String
"цветница"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
7) TimeData
orthodoxEaster )
  ]

ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' = [(Text, String, Maybe TimeData)] -> [Rule]
mkRuleHolidays'
  [ ( Text
"Great Lent", String
"велики(те)? пости"
    , let start :: TimeData
start = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
48) TimeData
orthodoxEaster
          end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
9) TimeData
orthodoxEaster
        in TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end )

  -- Other
  -- Last Saturday of March unless it falls on Holy Saturday
  -- In which case it's the Saturday before
  , ( Text
"Earth Hour", String
"час(а|ът) на земята"
    , let holySaturday :: TimeData
holySaturday = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
1) TimeData
easterSunday
          tentative :: TimeData
tentative = TimeData -> TimeData -> TimeData
predLastOf (Int -> TimeData
dayOfWeek Int
6) (Int -> TimeData
month Int
3)
          alternative :: TimeData
alternative = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
7) TimeData
tentative
        in do
          TimeData
day <- TimeData -> TimeData -> TimeData -> Maybe TimeData
intersectWithReplacement TimeData
holySaturday TimeData
tentative TimeData
alternative
          TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect TimeData
day (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
True Int
20 Int
30
          TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed TimeData
start (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Minute Int
60 TimeData
start )
  ]

ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this|last|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 = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):Token Dimension a
TimeGrain a
grain:[Token]
_) ->
        case Text -> Text
Text.toLower Text
match of
          Text
"този"          -> 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
          Text
"тази"          -> 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
          Text
"това"          -> 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
          Text
"настоящия"     -> 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
          Text
"настоящият"    -> 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
          Text
"настоящата"    -> 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
          Text
"настоящото"    -> 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
          Text
"последния"     -> 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
          Text
"последният"    -> 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
          Text
"последната"    -> 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
          Text
"последното"    -> 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
          Text
"миналия"       -> 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
          Text
"миналият"      -> 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
          Text
"миналата"      -> 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
          Text
"миналото"      -> 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
          Text
"предишния"     -> 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
          Text
"предишният"    -> 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
          Text
"предишната"    -> 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
          Text
"предишното"    -> 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
          Text
"следващия"     -> 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
          Text
"следващият"    -> 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
          Text
"следващата"    -> 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
          Text
"следващото"    -> 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
          Text
"идния"         -> 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
          Text
"идният"        -> 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
          Text
"идната"        -> 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
          Text
"идното"        -> 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
          Text
"по-последния"     -> 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
2
          Text
"по-последният"    -> 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
2
          Text
"по-последната"    -> 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
2
          Text
"по-последното"    -> 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
2
          Text
"по-миналия"       -> 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
2
          Text
"по-миналият"      -> 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
2
          Text
"по-миналата"      -> 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
2
          Text
"по-миналото"      -> 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
2
          Text
"по-предишния"     -> 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
2
          Text
"по-предишният"    -> 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
2
          Text
"по-предишната"    -> 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
2
          Text
"по-предишното"    -> 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
2
          Text
"по-следващия"     -> 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
2
          Text
"по-следващият"    -> 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
2
          Text
"по-следващата"    -> 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
2
          Text
"по-следващото"    -> 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
2
          Text
"по-по-последния"     -> 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
3
          Text
"по-по-последният"    -> 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
3
          Text
"по-по-последната"    -> 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
3
          Text
"по-по-последното"    -> 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
3
          Text
"по-по-миналия"       -> 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
3
          Text
"по-по-миналият"      -> 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
3
          Text
"по-по-миналата"      -> 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
3
          Text
"по-по-миналото"      -> 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
3
          Text
"по-по-предишния"     -> 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
3
          Text
"по-по-предишният"    -> 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
3
          Text
"по-по-предишната"    -> 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
3
          Text
"по-по-предишното"    -> 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
3
          Text
"по-по-следващия"     -> 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
3
          Text
"по-по-следващият"    -> 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
3
          Text
"по-по-следващата"    -> 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
3
          Text
"по-по-следващото"    -> 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
3
          Text
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleAfterBeforeTime :: Rule
ruleCycleAfterBeforeTime :: Rule
ruleCycleAfterBeforeTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> after|before <time>"
  , pattern :: Pattern
pattern =
    [ 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 = \case
      (Token Dimension a
TimeGrain a
grain:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
Time a
td:
       [Token]
_) ->
        let n :: Int
n = if Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"след" then Int
1 else - Int
1 in
          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 a
Grain
grain Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDayInDuration :: Rule
ruleDayInDuration :: Rule
ruleDayInDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day> in <duration>"
  , 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 [Grain -> Predicate
isGrainOfTime Grain
TG.Day, Grain -> Predicate
isGrainOfTime Grain
TG.Month]
    , String -> PatternItem
regex String
"в|през"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isDurationGreaterThan Grain
TG.Hour
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td: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
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (DurationData -> TimeData
inDurationInterval a
DurationData
dd)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationInWithinAfter :: Rule
ruleDurationInWithinAfter :: Rule
ruleDurationInWithinAfter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in|within|after <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 = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
        Token Dimension a
Duration a
dd:
        [Token]
_) -> case Text -> Text
Text.toLower Text
match of
          Text
"в рамките на" -> 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)
          Text
"след"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.After (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
inDuration a
DurationData
dd
          Text
"за"     -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
inDuration a
DurationData
dd
          Text
_        -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNDOWago :: Rule
ruleNDOWago :: Rule
ruleNDOWago = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> <named-day> ago|back"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"преди"
    , Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}: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 (- (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v)) Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationHenceAgo :: Rule
ruleDurationHenceAgo :: Rule
ruleDurationHenceAgo = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> hence|ago"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(от|преди)"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):Token Dimension a
Duration a
dd:[Token]
_) ->
        case Text -> Text
Text.toLower Text
match of
          Text
"от" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
durationAgo a
DurationData
dd
          Text
_     -> 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
  }

ruleInNumeral :: Rule
ruleInNumeral :: Rule
ruleInNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in <number> (implicit minutes)"
  , 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
0 Int
60
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurationData -> TimeData
inDuration (DurationData -> TimeData)
-> (Int -> DurationData) -> Int -> TimeData
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
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalForDurationFrom :: Rule
ruleIntervalForDurationFrom :: Rule
ruleIntervalForDurationFrom = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"for <duration> from <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"за"
    , 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 = \case
      (Token
_:Token Dimension a
Duration a
dd:Token
_:Token Dimension a
Time a
td1:[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 (DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}

ruleIntervalTimeForDuration :: Rule
ruleIntervalTimeForDuration :: Rule
ruleIntervalTimeForDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> for <duration>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"за"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td1: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.Closed a
TimeData
td1 (DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}

ruleIntervalFromTimeForDuration :: Rule
ruleIntervalFromTimeForDuration :: Rule
ruleIntervalFromTimeForDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <time> for <duration>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"от|след"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"за"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \case
      (Token
_:Token Dimension a
Time a
td1: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.Closed a
TimeData
td1 (DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}

timezoneName :: String
timezoneName :: String
timezoneName = String
"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"

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, Predicate
hasNoTimezone]
    , String -> PatternItem
regex (String -> PatternItem) -> String -> PatternItem
forall a b. (a -> b) -> a -> b
$ String
"\\b(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
timezoneName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\\b"
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleTimezoneBracket :: Rule
ruleTimezoneBracket :: Rule
ruleTimezoneBracket = 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, Predicate
hasNoTimezone]
    , String -> PatternItem
regex (String -> PatternItem) -> String -> PatternItem
forall a b. (a -> b) -> a -> b
$ String
"\\((" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
timezoneName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\\)"
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleIntervalDashTimezone :: Rule
ruleIntervalDashTimezone :: Rule
ruleIntervalDashTimezone = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<datetime> - <datetime> (interval) 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
isATimeOfDay, Predicate
hasNoTimezone]
    , 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
isATimeOfDay, Predicate
hasNoTimezone]
    , String -> PatternItem
regex (String -> PatternItem) -> String -> PatternItem
forall a b. (a -> b) -> a -> b
$ String
"\\b(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
timezoneName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")\\b"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td1:
       Token
_:
       Token Dimension a
Time a
td2:
       Token Dimension a
RegexMatch (GroupMatch (tz:_)):
       [Token]
_) -> do
        TimeData
tdz1 <- Text -> TimeData -> Maybe TimeData
inTimezone (Text -> Text
Text.toUpper Text
tz) a
TimeData
td1
        TimeData
tdz2 <- Text -> TimeData -> Maybe TimeData
inTimezone (Text -> Text
Text.toUpper Text
tz) a
TimeData
td2
        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
tdz1 TimeData
tdz2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleIntersect
  , Rule
ruleIntersectOf
  , Rule
ruleIntersectYear
  , Rule
ruleAbsorbOnDay
  , Rule
ruleAbsorbInMonthYear
  , Rule
ruleAbsorbCommaTOD
  , Rule
ruleAbsorbOnADOW
  , Rule
ruleNextDOW
  , Rule
ruleNextTime
  , Rule
ruleThisTime
  , Rule
ruleLastTime
  , Rule
ruleTimeBeforeLast
  , Rule
ruleTimeAfterNext
  , Rule
ruleLastDOWOfTime
  , Rule
ruleLastCycleOfTime
  , Rule
ruleLastNight
  , Rule
ruleLastWeekendOfMonth
  , Rule
ruleNthTimeOfTime
  , Rule
ruleNthTimeAfterTime
  , Rule
ruleNDOWFromTime
  , Rule
ruleYearLatent
  , Rule
ruleYearADBC
  , Rule
ruleTheDOMNumeral
  , Rule
ruleTheDOMOrdinal
  , Rule
ruleDOMLatent
  , Rule
ruleNamedDOMOrdinal
  , Rule
ruleMonthDOMNumeral
  , Rule
ruleDOMMonth
  , Rule
ruleDOMOrdinalMonthYear
  , Rule
ruleDOMMonthYear
  , Rule
ruleIdesOfMonth
  , Rule
ruleTODLatent
  , Rule
ruleAtTOD
  , Rule
ruleTODOClock
  , Rule
ruleTODAM
  , Rule
ruleTODPM
  , Rule
ruleHHMM
  , Rule
ruleHHhMM
  , Rule
ruleHHMMLatent
  , Rule
ruleHHMMSS
  , Rule
ruleHONumeral
  , Rule
ruleHODHalf
  , Rule
ruleHODQuarter
  , Rule
ruleNumeralToHOD
  , Rule
ruleQuarterToHOD
  , Rule
ruleNumeralAfterHOD
  , Rule
ruleYYYYQQ
  , Rule
ruleYYYYMM
  , Rule
ruleYYYYMMDD
  , Rule
ruleDDMMYYYYDot
  , Rule
ruleMMYYYY
  , Rule
ruleNoonMidnightEOD
  , Rule
rulePartOfDays
  , Rule
ruleEarlyMorning
  , Rule
rulePODThis
  , Rule
ruleTonight
  , Rule
ruleAfterPartofday
  , Rule
ruleTimePOD
  , Rule
rulePODofTime
  , Rule
ruleWeekend
  , Rule
ruleWeek
  , Rule
ruleTODPrecision
  , Rule
rulePrecisionTOD
  , Rule
ruleIntervalFromDDDDMonth
  , Rule
ruleIntervalMonthDDDD
  , Rule
ruleIntervalDDDDMonth
  , Rule
ruleIntervalDash
  , Rule
ruleIntervalSlash
  , Rule
ruleIntervalFrom
  , Rule
ruleIntervalBetween
  , Rule
ruleIntervalTODDash
  , Rule
ruleIntervalTODBetween
  , Rule
ruleIntervalBy
  , Rule
ruleIntervalByTheEndOf
  , Rule
ruleIntervalUntilTime
  , Rule
ruleIntervalAfterFromSinceTime
  , Rule
ruleCycleThisLastNext
  , Rule
ruleCycleAfterBeforeTime
  , Rule
ruleDayInDuration
  , Rule
ruleDurationInWithinAfter
  , Rule
ruleNDOWago
  , Rule
ruleDurationHenceAgo
  , Rule
ruleIntervalForDurationFrom
  , Rule
ruleIntervalFromTimeForDuration
  , Rule
ruleIntervalTimeForDuration
  , Rule
ruleInNumeral
  , Rule
ruleTimezone
  , Rule
ruleTimezoneBracket
  , Rule
ruleIntervalDashTimezone
  , Rule
rulePartOfMonth
  , Rule
ruleEndOrBeginningOfMonth
  , Rule
ruleEndOrBeginningOfYear
  , Rule
ruleEndOrBeginningOfWeek
  , Rule
ruleNow
  , Rule
ruleSeason
  , Rule
ruleEndOfMonth
  , Rule
ruleBeginningOfMonth
  , Rule
ruleEndOfYear
  , Rule
ruleBeginningOfYear
  , Rule
ruleMonthYear
  ]
  [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]
ruleComputedHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleComputedHolidays'
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulePeriodicHolidays