-- 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.KA.Rules
  ( rules
  ) where

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

import Duckling.Dimensions.Types
import Duckling.Duration.Helpers (duration, isGrain)
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(..))
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

-- Georgian weekend
geoWeekend :: TimeData
geoWeekend :: TimeData
geoWeekend = case TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
fri TimeData
mon of
  Just TimeData
td -> TimeData
td
  Maybe TimeData
Nothing -> TimeData
weekend
  where
    fri :: TimeData
fri = Int -> TimeData
dayOfWeek Int
6
    mon :: TimeData
mon = Int -> TimeData
dayOfWeek Int
7

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
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]
    , 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]
_)
      | (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TimeData -> Bool
TTime.latent a
TimeData
td1) Bool -> Bool -> Bool
|| (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ TimeData -> Bool
TTime.latent 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) -> (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
  }

ruleAbsorbInYear :: Rule
ruleAbsorbInYear :: Rule
ruleAbsorbInYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Year
    , 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
  }

ruleYearInterval :: Rule
ruleYearInterval :: Rule
ruleYearInterval = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<integer> year"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , String -> PatternItem
regex String
"წელიწად(ის|ი|ში)?|წლ(ის)?|წელ(შ?ი|ს)"
    ]
  , prod :: Production
prod = \case
      (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
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Int -> TimeData
year Int
n) (Int -> TimeData
year (Int -> TimeData) -> Int -> TimeData
forall a b. (a -> b) -> a -> b
$ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleInstants :: [Rule]
ruleInstants :: [Rule]
ruleInstants = [(Text, Grain, Int, String)] -> [Rule]
mkRuleInstants
  [ (Text
"ახლა", Grain
TG.Second, Int
0, String
"ახლავე|ეხლავე|ეხლა|ახლა|ამ წამს|ამ წუთას|ამ მომენტისთვი")
  , (Text
"დღეს", Grain
TG.Day, Int
0, String
"დღეს")
  , (Text
"ხვალ", Grain
TG.Day, Int
1, String
"ხვალე?")
  , (Text
"ზეგ", Grain
TG.Day, Int
2, String
"ზეგ")
  , (Text
"მაზეგ", Grain
TG.Day, Int
3, String
"მაზეგ")
  , (Text
"გუშინ", Grain
TG.Day, -Int
1, String
"გუშინ?")
  , (Text
"გუშინწინ", 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 = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ 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
1 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
1 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
"ბოლო უიქ?კ? ?ენდი|ვიქ?კ? ?ენდი|შაბ?ფ?ათკვირა|შაბ?ფ?ათ-კვირა|უქმეები"
    , 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
geoWeekend a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastWorkweekOfMonth :: Rule
ruleLastWorkweekOfMonth :: Rule
ruleLastWorkweekOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last workweek of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ბოლო სამუშაო ?კვირას?(ში)?"
    , 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
workweek a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastWeekendOfMonth1 :: Rule
ruleLastWeekendOfMonth1 :: Rule
ruleLastWeekendOfMonth1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last weekend of <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"(ს? ?ბოლო უიქ?კ? ?ენდი ?|ს? ბოლო ?ვიქ?კ? ?ენდი ?|ს? ბოლო ?შაბ?ფ?ათკვირა ?|ს? ბოლო ?შაბ?ფ?ათ-კვირა ?)| ს?უქმეები ?"
    ]
  , prod :: Production
prod = \case
      (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
geoWeekend a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastWorkweekOfMonth1 :: Rule
ruleLastWorkweekOfMonth1 :: Rule
ruleLastWorkweekOfMonth1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last workweek of <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"(ს? ბოლო სამუშაო ?კვირას?(ში)?)"
    ]
  , prod :: Production
prod = \case
      (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
workweek a
TimeData
td2
      [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
"(შემდეგის შემდეგი? ?)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):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 (Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"შემდეგის შემდეგ") a
TimeData
td
      [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
"(ბოლოს წინა ?|წინის წინა ?)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):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) (Text -> Text
Text.toLower Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"ბოლოს წინა") a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNthTimeOfTime :: Rule
ruleNthTimeOfTime :: Rule
ruleNthTimeOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nth <time> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , 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
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td1:Token Dimension a
Ordinal a
od: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 TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"დან"
    , 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
    ]
  , 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
  }

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
$ 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
  }

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:[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
  }

ruleMonthDOMNumeral1 :: Rule
ruleMonthDOMNumeral1 :: Rule
ruleMonthDOMNumeral1 = 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
isDOMOrdinal
    , String -> PatternItem
regex String
"( დღეს?)?"
    ]
  , 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
  }

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 Bool
True Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleMMDDYYYY :: Rule
ruleMMDDYYYY :: Rule
ruleMMDDYYYY = 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])[-/\\s](1[0-2]|0?[1-9])[-/\\s](\\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
  }

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

ruleAtTOD :: Rule
ruleAtTOD :: Rule
ruleAtTOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at <time-of-day>"
  , 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
  }

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
True 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
True 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
True Int
h Int
m Int
s
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMilitaryAMPM :: Rule
ruleMilitaryAMPM :: Rule
ruleMilitaryAMPM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hhmm (military) am|pm"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"((?:1[012]|0?\\d))([0-5]\\d)"
    , String -> PatternItem
regex String
"([ap])\\.?m?\\.?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (hh:mm:_)):
       Token Dimension a
RegexMatch (GroupMatch (ap:_)):
       [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
. Bool -> TimeData -> TimeData
timeOfDayAMPM (Text -> Text
Text.toLower Text
ap Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"a") (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
True Int
h Int
m
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMilitarySpelledOutAMPM :: Rule
ruleMilitarySpelledOutAMPM :: Rule
ruleMilitarySpelledOutAMPM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"military spelled out numbers am|pm"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
10 Int
12
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
59
    , String -> PatternItem
regex String
"([ap])(\\s|\\.)?m?\\.?"
    ]
    , prod :: Production
prod = \case
        (Token
h:Token
m:Token Dimension a
RegexMatch (GroupMatch (_:ap:_)):[Token]
_) -> do
          Int
hh <- Token -> Maybe Int
getIntValue Token
h
          Int
mm <- Token -> Maybe Int
getIntValue Token
m
          TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> TimeData -> TimeData
timeOfDayAMPM (Text -> Text
Text.toLower Text
ap Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"a") (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
True Int
hh Int
mm
        [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMilitarySpelledOutAMPM2 :: Rule
ruleMilitarySpelledOutAMPM2 :: Rule
ruleMilitarySpelledOutAMPM2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"six thirty six a.m."
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
110 Int
999
    , String -> PatternItem
regex String
"([ap])(\\s|\\.)?m?\\.?"
    ]
  , prod :: Production
prod = \case
      (Token
token:Token Dimension a
RegexMatch (GroupMatch (_:ap:_)):[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        Int
m <- case Int -> Int -> Int
forall a. Integral a => a -> a -> a
mod Int
n Int
100 of
          Int
v | Int
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
60 -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
v
          Int
_          -> Maybe Int
forall a. Maybe a
Nothing
        let h :: Int
h = Int -> Int -> Int
forall a. Integral a => a -> a -> a
quot Int
n Int
100
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> TimeData -> TimeData
timeOfDayAMPM (Text -> Text
Text.toLower Text
ap Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"a") (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
True Int
h Int
m
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTODAMPM :: Rule
ruleTODAMPM :: Rule
ruleTODAMPM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> am|pm"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"(in the )?([ap])(\\s|\\.)?(m?)\\.?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time td :: a
td@TimeData {TTime.latent = True}:
       Token Dimension a
RegexMatch (GroupMatch (_:ap:_:"":_)):[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 -> TimeData -> TimeData
timeOfDayAMPM (Text -> Text
Text.toLower Text
ap Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"a") a
TimeData
td
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (_:ap:_)):[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> TimeData -> TimeData
timeOfDayAMPM (Text -> Text
Text.toLower Text
ap Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"a") a
TimeData
td
      [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
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
59
    , String -> PatternItem
regex String
"(წუთი ?)აკლ(ია)?(და)?|(წუთი ?)უკლია"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData
t <- Int -> TimeData -> Maybe TimeData
minutesBefore Int
n a
TimeData
td
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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
t
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralToHOD1 :: Rule
ruleNumeralToHOD1 :: Rule
ruleNumeralToHOD1 = 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
    , String -> PatternItem
regex String
"(წუთი ?)აკლ(ია)?(და)?|(წუთი ?)უკლია"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData
t <- Int -> TimeData -> Maybe TimeData
minutesBefore Int
n a
TimeData
td
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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
t
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHalfToHOD :: Rule
ruleHalfToHOD :: Rule
ruleHalfToHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"half 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]
_) -> 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
30 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
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
59
    , String -> PatternItem
regex String
"წუთი?(ზე)?(სთვის)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData
t <- Int -> TimeData -> Maybe TimeData
minutesBefore (Int
60Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n) a
TimeData
td
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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
t
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralAfterHOD1 :: Rule
ruleNumeralAfterHOD1 :: Rule
ruleNumeralAfterHOD1 = 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
    , String -> PatternItem
regex String
"წუთი?(ზე)?(სთვის)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData
t <- Int -> TimeData -> Maybe TimeData
minutesBefore (Int
60Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
n) a
TimeData
td
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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
t
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralAfterHOD2 :: Rule
ruleNumeralAfterHOD2 :: Rule
ruleNumeralAfterHOD2 = 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
    , String -> PatternItem
regex String
"წუთი?(ზე)?(სთვის)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData
t <- Int -> TimeData -> Maybe TimeData
minutesAfter Int
n a
TimeData
td
        Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token) -> Token -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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
t
      [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 -> Int -> TimeData
yearMonthDay Int
y Int
m Int
1
      [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
  }

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
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
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
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
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
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
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
21, Bool -> Int -> TimeData
hour Bool
False Int
0)
              Text
"გვიან ღამით" -> (Bool -> Int -> TimeData
hour Bool
False Int
21, Bool -> Int -> TimeData
hour Bool
False Int
0)
              Text
"შუადღე" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
18)
              Text
"შუადღის" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
18)
              Text
"შუადღით" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
18)
              Text
"დღისით" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
18)
              Text
"დღის" -> (Bool -> Int -> TimeData
hour Bool
False Int
12, Bool -> Int -> TimeData
hour Bool
False Int
18)
              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)
  }

rulePODIn :: Rule
rulePODIn :: Rule
rulePODIn = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in|during the <part-of-day>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , 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
  }

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 (Grain -> Int -> TimeData
cycleNth Grain
TG.Day Int
0) 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 today :: TimeData
today = Grain -> Int -> TimeData
cycleNth Grain
TG.Day Int
0
            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
"((სკოლის|ლანჩის|სამსახურის) (მერე|შემდეგ))"
    ]
  , 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
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
"სკოლის შემდეგ" -> (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 (Grain -> Int -> TimeData
cycleNth Grain
TG.Day Int
0) 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> <time>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
pod: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 = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
mkOkForThisNext TimeData
geoWeekend
  }

ruleWorkweek :: Rule
ruleWorkweek :: Rule
ruleWorkweek = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"work-week"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(მიმდინარე )?სამუშაო ?კვირას?(ში)?"
    ]
  , prod :: Production
prod = Maybe Token -> Production
forall a b. a -> b -> a
const (Maybe Token -> Production) -> Maybe Token -> Production
forall a b. (a -> b) -> a -> b
$ TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
mkOkForThisNext TimeData
workweek
  }

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
"(ამ|ეს|ახლანდელი|მიმდინარე|შემდეგი|მომავალი|წინა|ბოლო|გასული?) სეზონი?(ზე)?"
    ]
  , 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
_ -> 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
"ზაფხული", String
"ზაფხული?(ში)?ს?", Int -> Int -> TimeData
monthDay Int
6 Int
1, Int -> Int -> TimeData
monthDay Int
8 Int
31)
  , (Text
"შემოდგომა", String
"შემოდგომა?(ში)?ს?", Int -> Int -> TimeData
monthDay Int
9 Int
1, Int -> Int -> TimeData
monthDay Int
11 Int
30)
  , (Text
"ზამთარი", String
"ზამთარი?(ში)?ს?", Int -> Int -> TimeData
monthDay Int
12 Int
1, Int -> Int -> TimeData
monthDay Int
2 Int
28)
  , (Text
"გაზაფხული", String
"გაზაფხული?(ში)?ს?", Int -> Int -> TimeData
monthDay Int
3 Int
1, Int -> Int -> TimeData
monthDay Int
5 Int
31)
  ]

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
    , String -> PatternItem
regex String
"-მდე|მდე| მდე"
    ]
  , 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
  }

ruleIntervalMonthDDDD1 :: Rule
ruleIntervalMonthDDDD1 :: Rule
ruleIntervalMonthDDDD1 = 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
    , String -> PatternItem
regex String
"-მდე|მდე| მდე"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \case
      (Token
token1:Token
_:Token
token2:Token
_: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
  }

ruleIntervalDDDDMonth1 :: Rule
ruleIntervalDDDDMonth1 :: Rule
ruleIntervalDDDDMonth1 = 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
  }

ruleIntervalBetweenMM :: Rule
ruleIntervalBetweenMM :: Rule
ruleIntervalBetweenMM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time> and <time>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"-ი?დან ?|ი?დან ?| ი?დან ?"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , prod :: Production
prod = \case
      (Token
token1:Token
_:Token
token2:Token Dimension a
Time a
td:[Token]
_) -> do
        TimeData
start <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
end <- 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
start TimeData
end
      [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 =
    [ 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
    , String -> PatternItem
regex String
"-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , 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
  }

ruleIntervalBetween1 :: Rule
ruleIntervalBetween1 :: Rule
ruleIntervalBetween1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time> and <time> 1"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"-ი?დან ?|ი?დან ?| ი?დან ?"
    , String -> PatternItem
regex String
"დღემდე|ამ წუთამდე|ახლამდე|ამ მომენტამდე"
    ]
  , prod :: Production
prod = \case
      (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 TimeData
now
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalBetween2 :: Rule
ruleIntervalBetween2 :: Rule
ruleIntervalBetween2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time-of-day> and <time-of-day>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , String -> PatternItem
regex String
"დან|-ი?დან ?|ი?დან ?| ი?დან ?"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    , String -> PatternItem
regex String
"მდე|-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td1:Token Dimension a
Time a
pod1:Token
_:Token Dimension a
Time a
td2:Token Dimension a
Time a
pod2:[Token]
_) -> do
        TimeData
dom1 <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
pod1 a
TimeData
td1
        TimeData
dom2 <- TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
pod2 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
dom1 TimeData
dom2
      [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
    , String -> PatternItem
regex String
"მდე|-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , 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
  }

ruleIntervalTODFrom :: Rule
ruleIntervalTODFrom :: Rule
ruleIntervalTODFrom = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <time-of-day> - <time-of-day> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"დან|-ი?დან ?|ი?დან ?| ი?დან ?"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"მდე|-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , 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 =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
" ?და ?"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"შორის"
    ]
  , 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
  }

ruleIntervalBy :: Rule
ruleIntervalBy :: Rule
ruleIntervalBy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"by <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"მდე|-ა?მდე ?|ა?მდე ?| ა?მდე ?"
    ]
  , 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
  }

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = [(Text, String)] -> [Rule]
mkRuleDaysOfWeek
  [ (Text
"ორშაბათი", String
"ორშაბათი?ს?")
  , (Text
"სამშაბათი", String
"სამშაბათი?ს?")
  , (Text
"ოთხშაბათი", String
"ოთხშაბათი?ს?")
  , (Text
"ხუთშაბათი", String
"ხუთშაბათი?ს?")
  , (Text
"პარასკევი", String
"პარასკევი?ს?")
  , (Text
"შაბათი", String
"შაბათი?ს?")
  , (Text
"კვირა", String
"კვირას?|კვირის")
  ]

ruleMonths :: [Rule]
ruleMonths :: [Rule]
ruleMonths = [(Text, String, Bool)] -> [Rule]
mkRuleMonthsWithLatent
  [ (Text
"იანვარი", String
"იანვა?რი?ს?(ის)?", Bool
False)
  , (Text
"თებერვალი", String
"თებერვა?ლი?ს?(ის)?", Bool
False)
  , (Text
"მარტი", String
"მარტი?ს?(ის)?", Bool
False)
  , (Text
"აპრილი", String
"აპრილი?ს?(ის)?", Bool
False)
  , (Text
"მაისი", String
"მაისი?ს?(ის)?", Bool
False)
  , (Text
"ივნისი", String
"ივნისი?ს?(ის)?", Bool
False)
  , (Text
"ივლისი", String
"ივლისი?ს?(ის)?", Bool
False)
  , (Text
"აგვისტო", String
"აგვისტო?ს?", Bool
False)
  , (Text
"სექტემბერი", String
"სექტემბე?რის|სექტემბე?რი?ს?", Bool
False)
  , (Text
"ოქტომბერი", String
"ოქტომბე?რის|ოქტომბე?რი?ს?", Bool
False)
  , (Text
"ნოემბერი", String
"ნოემბე?რის|ნოემბე?რი?ს?", Bool
False)
  , (Text
"დეკემბერი", String
"დეკემბრის?|დეკემბე?რი?ს?", Bool
False)
  ]

ruleNamedMonth :: Rule
ruleNamedMonth :: Rule
ruleNamedMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , String -> PatternItem
regex String
"ში"
    ]
  , prod :: Production
prod = \case
      (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
        (Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Month Int
0 a
TimeData
td2)
        (Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Month Int
0 a
TimeData
td2)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rulePartOfMonth :: Rule
rulePartOfMonth :: Rule
rulePartOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"part of <named-month>"
  , 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, Grain -> Predicate
isGrainOfTime Grain
TG.Month]
    , String -> PatternItem
regex String
"(ის )?(დასაწყის(ი|ში|ისას|ისკენ)|შუ(ა|აში|ისკენ)|ბოლო(ს|მდე|ში|სკენ)?)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (_:match:_)):[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
1, Int
10)
          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
1, Int
10)
          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
11, Int
20)
          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
"ბოლოსკენ" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          Text
"ბოლოში" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          Text
"ბოლოს" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          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 =
    [ 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.Month]
    , String -> PatternItem
regex String
"(ის )?(დასაწყისშ?ი|ბოლო(ს?|ში))"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (_:match:_)):[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
1, Int
10)
          Text
"ბოლოს" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          Text
"ბოლოში" -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
21, -Int
1)
          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
"(ამ )?(მიმდინარე )?თვის ბოლოს?(კენ)?(თვის)?"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch a
_:[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 =
              ( 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
"(ამ )?(მიმდინარე )?თვის დასაწყისი?(ში)?(სკენ)?(სთვის)?"
    ]
  , 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 =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Year
    , String -> PatternItem
regex String
"(წლის )?დასაწყისი?(ისკენ)?(ში)? |ბოლოს?(კენ)?(ში)? "
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (_:match:_)):[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
1, Int
4)
          Text
"ბოლოსკენ"       -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
9, -Int
1)
          Text
"ბოლოს"       -> (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
9, -Int
1)
          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
"((მიმდინარე )?(ამ )?წლის ბოლოს?(კენ)?(ში)?(თვის)?)"
    ]
  , prod :: Production
prod = \[Token]
_ -> do
        TimeData
start <- TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
month Int
9) (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
1) (TimeData -> Maybe TimeData) -> TimeData -> Maybe TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Year 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
  }

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
"((ამ )?(მიმდინარე )?წლის დასაწყისი?(ში)?(სკენ)?(სთვის)?)" ]
  , 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 =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Week
    , String -> PatternItem
regex String
"(დასაწყისი|დასაწყისში|ბოლოში|ბოლოს)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token Dimension a
RegexMatch (GroupMatch (_:match:_)):[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
3)
          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
"ბოლოს" -> (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
"ახალი წელი", String
"ახალი წე?ლი?ს?", Int -> Int -> TimeData
monthDay Int
1 Int
1)
  , (Text
"შობა", String
"შობა?(ი)?ს?", Int -> Int -> TimeData
monthDay Int
1 Int
7 )
  , (Text
"ნათლისღება", String
"ნათლისღება?(ი)?ს?", Int -> Int -> TimeData
monthDay Int
1 Int
19 )
  , (Text
"დედის დღე", String
"დედის დღე?ს?", Int -> Int -> TimeData
monthDay Int
3 Int
3)
  , (Text
"ქალთა საერთაშორისო დღე", String
"ქალთა (საერთაშორისო )?დღე?ს?", Int -> Int -> TimeData
monthDay Int
3 Int
8 )
  , (Text
"საქართველოს დამოუკიდებლობის აღდგენის დღე", String
"საქართველოს (თავისუფლებისა და ერთიანობისთვის დაღუპულთა მოხსენიების)?(დამოუკიდებლობის აღდგენის )?დღეს?", Int -> Int -> TimeData
monthDay Int
4 Int
9 )
  , (Text
"გამარჯვების დღე", String
"(ფაშიზმზე)?გამარჯვების დღეს?", Int -> Int -> TimeData
monthDay Int
5 Int
9 )
  , (Text
"წმინდა ანდრია პირველწოდებულის ხსენების დღე", String
"(წმინდა)?ანდრია პირველწოდებულის ხსენების დღე?ს?", Int -> Int -> TimeData
monthDay Int
5 Int
12 )
  , (Text
"დამოუკიდებლობის დღე", String
"(საქართველოს)?დამოუკიდებლობის დღე?ს?", Int -> Int -> TimeData
monthDay Int
5 Int
26 )
  , (Text
"მცხეთობა", String
"მცხეთობა?ს?", Int -> Int -> TimeData
monthDay Int
10 Int
14)
  , (Text
"გიორგობა", String
"გიორგობა?ს?", Int -> Int -> TimeData
monthDay Int
11 Int
26)
  ]

ruleComputedHolidays :: [Rule]
ruleComputedHolidays :: [Rule]
ruleComputedHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ (Text
"Orthodox Easter Monday", String
"orthodox\\s+easter\\s+mon(day)?"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day Int
1 TimeData
orthodoxEaster)
  , (Text
"აღდგომა", String
"აღდგომი?ა?ს?(ისას)?"
    , TimeData
orthodoxEaster)
  , (Text
"დიდი შაბათი", String
"დიდი? შაბათი?ს?(ისას)?"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
1) TimeData
orthodoxEaster)
  , (Text
"წითელი პარასკევი", String
"წითელი? პარასკევი?ს?(სას)?"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
2) TimeData
orthodoxEaster)
  , (Text
"დიდი ხუთშაბათი", String
"დიდი? ხუთშაბათი?ს?(ისას)?"
    , Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
7) TimeData
orthodoxEaster)
  ]

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)
-> (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
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
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
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleThisLastNextInterval :: Rule
ruleCycleThisLastNextInterval :: Rule
ruleCycleThisLastNextInterval = 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]
_) -> let
         n :: Int
n = case Text -> Text
Text.toLower Text
match of
           Text
"ეს" -> Int
0
           Text
"ამ" -> Int
0
           Text
"მიმდინარე" -> Int
0
           Text
"წინა" -> -Int
1
           Text
"გასული" -> -Int
1
           Text
"გასულ" -> -Int
1
           Text
"წინის წინ" -> -Int
2
           Text
"წინის წინა" -> -Int
2
           Text
_ -> Int
1
         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) -> 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 (Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
n) (Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
n)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOMOfTimeMonth :: Rule
ruleDOMOfTimeMonth :: Rule
ruleDOMOfTimeMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (ordinal or number) of <month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainOfTime Grain
TG.Month
    ]
  , 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
  }

ruleCycleTheAfterBeforeTime :: Rule
ruleCycleTheAfterBeforeTime :: Rule
ruleCycleTheAfterBeforeTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the <cycle> after|before <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , 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
Time a
td
       : Token Dimension a
RegexMatch (GroupMatch (match:_))
       : Token Dimension a
TimeGrain a
grain
       : [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
  }

ruleCycleTheAfterBeforeTime1 :: Rule
ruleCycleTheAfterBeforeTime1 :: Rule
ruleCycleTheAfterBeforeTime1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the <cycle> after <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , 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
99999
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"ში|ის შემდეგ"
    ]
  , prod :: Production
prod = \case
      (  Token Dimension a
Time a
td
       : Token
_
       : Token
token
       : Token Dimension a
TimeGrain a
grain
       : [Token]
_) -> do
          Int
n <- Token -> Maybe Int
getIntValue Token
token
          TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False a
Grain
grain Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleOrdinalOfTime :: Rule
ruleCycleOrdinalOfTime :: Rule
ruleCycleOrdinalOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"დან"
    , Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True a
Grain
grain (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleLastOrdinalOfTime :: Rule
ruleCycleLastOrdinalOfTime :: Rule
ruleCycleLastOrdinalOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> last <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"ბოლოდან"
    , Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:Token
_:Token
token:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True a
Grain
grain (-Int
n) (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter
          Bool
True (TimeData -> Grain
timeGrain a
TimeData
td) Int
1 (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ a
TimeData
td
      [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 =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"(განმავლობაში|შემდეგ)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [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
_        -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationLastNext :: Rule
ruleDurationLastNext :: Rule
ruleDurationLastNext = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last|past|next <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 DurationData{TDuration.grain, TDuration.value}:
       [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
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True Grain
grain Int
value
         Text
"მომავალ" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True Grain
grain Int
value
         Text
"წინა" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True Grain
grain (- Int
value)
         Text
"გასული" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True Grain
grain (- Int
value)
         Text
"გასულ" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True Grain
grain (- Int
value)
         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 =
    [ Predicate -> PatternItem
Predicate Predicate
isNatural
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
" ?დღის წინ| ?დღის უკან"
    ]
  , prod :: Production
prod = \case
      (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 =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"წინ|უკან"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [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
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
  }

ruleDayDurationHenceAgo :: Rule
ruleDayDurationHenceAgo :: Rule
ruleDayDurationHenceAgo = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day> <duration> hence|ago"
  , 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]
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"(წინ|უკან)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:
       Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [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
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (DurationData -> TimeData
durationIntervalAgo a
DurationData
dd)
         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
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td (DurationData -> TimeData
inDurationInterval 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 =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
0 Int
60
    , String -> PatternItem
regex String
" ?წუთში"
    ]
  , prod :: Production
prod = \case
      (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
  }

ruleDurationAfterBeforeTime :: Rule
ruleDurationAfterBeforeTime :: Rule
ruleDurationAfterBeforeTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> after|before|from <time>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"(წინ)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Time a
td:
       Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [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 -> TimeData
durationBefore a
DurationData
dd a
TimeData
td
         Text
_        -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAfterBeforeTime1 :: Rule
ruleDurationAfterBeforeTime1 :: Rule
ruleDurationAfterBeforeTime1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<duration> after|before|from <time>"
  , pattern :: Pattern
pattern =
    [ Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"(წინ)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       [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 -> TimeData
durationBefore a
DurationData
dd TimeData
now
         Text
_        -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd TimeData
now
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationLastNext1 :: Rule
ruleDurationLastNext1 :: Rule
ruleDurationLastNext1 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last|past|next <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
_:
       Token Dimension a
Duration a
dd:
       [Token]
_) -> do
        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 (DurationData -> TimeData
durationAgo a
DurationData
dd) TimeData
now
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleOrdinalQuarter :: Rule
ruleCycleOrdinalQuarter :: Rule
ruleCycleOrdinalQuarter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> quarter"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrain Grain
TG.Quarter
    ]
  , prod :: Production
prod = \case
      (Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        let
          start :: TimeData
start = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True Grain
TG.Quarter (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (TimeData -> TimeData) -> TimeData -> TimeData
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
TG.Year Int
0
          end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
True Grain
TG.Quarter Int
n (TimeData -> TimeData) -> TimeData -> 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
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- For example, Today(დღეს), This year(წელს)
ruleGrainOfTime :: Rule
ruleGrainOfTime :: Rule
ruleGrainOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<TimeGrain>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Grain -> Predicate
isGrainCoarserThan Grain
TG.Day
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        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 (Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
0) TimeData
now
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYear :: Rule
ruleYear :: Rule
ruleYear = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this|last|next year"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(შარშან ?წინის? ?წინ|შარშან ?წინ|შარშან|გასული? წელი?ს?|წელს)"
    ]
  , prod :: Production
prod = \case
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> let
        n :: Int
n = case Text -> Text
Text.toLower Text
match of
          Text
"წელს" -> Int
0
          Text
"შარშან" -> -Int
1
          Text
"გასული წელი" -> -Int
1
          Text
"გასულ წელს" -> -Int
1
          Text
"შარშან წინ" -> -Int
2
          Text
"შარშანწინ" -> -Int
2
          Text
_ -> -Int
3
        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) -> 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 (Grain -> Int -> TimeData
cycleNth Grain
TG.Year Int
n) (Grain -> Int -> TimeData
cycleNth Grain
TG.Year (Int -> TimeData) -> Int -> TimeData
forall a b. (a -> b) -> a -> b
$ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleIntersect
  , Rule
ruleCycleOrdinalQuarter
  , Rule
ruleDurationLastNext1
  , Rule
ruleAbsorbInYear
  , Rule
ruleNextDOW
  , Rule
ruleNextTime
  , Rule
ruleThisTime
  , Rule
ruleLastTime
  , Rule
ruleTimeAfterNext
  , Rule
ruleTimeBeforeLast
  , Rule
ruleLastWeekendOfMonth
  , Rule
ruleLastWeekendOfMonth1
  , Rule
ruleLastWorkweekOfMonth
  , Rule
ruleLastWorkweekOfMonth1
  , Rule
ruleNthTimeOfTime
  , Rule
ruleNthTimeAfterTime
  , Rule
ruleYearLatent
  , Rule
ruleTheDOMNumeral
  , Rule
ruleMonthDOMNumeral1
  , Rule
ruleTODLatent
  , Rule
ruleAtTOD
  , Rule
ruleTODOClock
  , Rule
ruleHHMM
  , Rule
ruleHHMMLatent
  , Rule
ruleHHMMSS
  , Rule
ruleMilitaryAMPM
  , Rule
ruleMilitarySpelledOutAMPM
  , Rule
ruleMilitarySpelledOutAMPM2
  , Rule
ruleTODAMPM
  , Rule
ruleHalfToHOD
  , Rule
ruleNumeralAfterHOD
  , Rule
ruleNumeralAfterHOD1
  , Rule
ruleNumeralAfterHOD2
  , Rule
ruleNumeralToHOD
  , Rule
ruleNumeralToHOD1
  , Rule
rulePODIn
  , Rule
rulePODThis
  , Rule
ruleYYYYMMDD
  , Rule
ruleMMYYYY
  , Rule
rulePartOfDays
  , Rule
ruleEarlyMorning
  , Rule
ruleTonight
  , Rule
ruleAfterPartofday
  , Rule
ruleTimePOD
  , Rule
rulePODofTime
  , Rule
ruleWeekend
  , Rule
ruleTODPrecision
  , Rule
rulePrecisionTOD
  , Rule
ruleIntervalMonthDDDD
  , Rule
ruleIntervalMonthDDDD1
  , Rule
ruleIntervalDDDDMonth
  , Rule
ruleIntervalDDDDMonth1
  , Rule
ruleIntervalBetween
  , Rule
ruleIntervalBetween1
  , Rule
ruleIntervalBetween2
  , Rule
ruleIntervalTODDash
  , Rule
ruleIntervalTODBetween
  , Rule
ruleIntervalTODFrom
  , Rule
ruleIntervalBy
  , Rule
ruleCycleTheAfterBeforeTime
  , Rule
ruleCycleTheAfterBeforeTime1
  , Rule
ruleCycleThisLastNext
  , Rule
ruleDOMOfTimeMonth
  , Rule
ruleCycleOrdinalOfTime
  , Rule
ruleCycleLastOrdinalOfTime
  , Rule
ruleDurationInWithinAfter
  , Rule
ruleNDOWago
  , Rule
ruleDurationLastNext
  , Rule
ruleDurationHenceAgo
  , Rule
ruleDayDurationHenceAgo
  , Rule
ruleDurationAfterBeforeTime
  , Rule
ruleDurationAfterBeforeTime1
  , Rule
ruleInNumeral
  , Rule
ruleCycleThisLastNextInterval
  , Rule
rulePartOfMonth
  , Rule
ruleEndOrBeginningOfYear
  , Rule
ruleEndOrBeginningOfMonth
  , Rule
ruleEndOrBeginningOfWeek
  , Rule
ruleNow
  , Rule
ruleSeason
  , Rule
ruleEndOfMonth
  , Rule
ruleBeginningOfMonth
  , Rule
ruleEndOfYear
  , Rule
ruleBeginningOfYear
  , Rule
ruleGrainOfTime
  , Rule
ruleYear
  , Rule
ruleIntervalBetweenMM
  , Rule
ruleWorkweek
  , Rule
ruleNamedMonth
  , Rule
ruleMMDD
  , Rule
ruleMMDDYYYY
  , Rule
ruleMMDDYYYYDot
  , Rule
ruleYearInterval
  ]
  [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]
rulePeriodicHolidays