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

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

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

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

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

ruleIntersectOf :: Rule
ruleIntersectOf :: Rule
ruleIntersectOf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"intersect by \",\", \"of\", \"from\", \"'s\""
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"من|,|،|لـ?|بـ?|الموافق( ل)?"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

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

ruleAbsorbInMonth :: Rule
ruleAbsorbInMonth :: Rule
ruleAbsorbInMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"شهر"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
token:[Token]
_) -> Token -> Maybe Token
forall a. a -> Maybe a
Just Token
token
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

instants :: [(Text, String, TG.Grain, Int)]
instants :: [(Text, String, Grain, Int)]
instants =
  [ (Text
"right now", String
"الان|حالا|(في )?هذه اللحظ[ةه]", Grain
TG.Second, Int
0)
  , (Text
"today", String
"اليوم", Grain
TG.Day, Int
0)
  , (Text
"tomorrow", String
"((يوم )?(غدا?|الغد))|(بكر[اةه])", Grain
TG.Day, Int
1)
  -- TODO: add regex for more variation of yesterday
  , (Text
"yesterday", String
"[أا]مس|(ال|ام)بارح[ةه]?", Grain
TG.Day, - Int
1)
  , (Text
"end of month", String
"(نهاي[ةه] الشهر)", Grain
TG.Month, Int
1)
  , (Text
"end of year", String
"(نهاي[ةه] (السن[ةه]|العام))", Grain
TG.Year, Int
1)
  ]

ruleInstants :: [Rule]
ruleInstants :: [Rule]
ruleInstants = ((Text, String, Grain, Int) -> Rule)
-> [(Text, String, Grain, Int)] -> [Rule]
forall a b. (a -> b) -> [a] -> [b]
map (Text, String, Grain, Int) -> Rule
go [(Text, String, Grain, Int)]
instants
  where
    go :: (Text, String, Grain, Int) -> Rule
go (Text
name, String
regexPattern, Grain
grain, Int
n) = Rule :: Text -> Pattern -> Production -> Rule
Rule
      { name :: Text
name = Text
name
      , pattern :: Pattern
pattern = [String -> PatternItem
regex String
regexPattern]
      , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth Grain
grain Int
n
      }

ruleNow :: Rule
ruleNow :: Rule
ruleNow = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"now"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال[اآ]ن|حالا"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt TimeData
now
  }

ruleThisDOW :: Rule
ruleThisDOW :: Rule
ruleThisDOW = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this <day-of-week>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"هذا"
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOWNext :: Rule
ruleDOWNext :: Rule
ruleDOWNext = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-week> next"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
"القادم|التالي|ال[آا]تي?|القادم"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOWLast :: Rule
ruleDOWLast :: Rule
ruleDOWLast = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-week> last"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
"السابق|الماضي|المنصرم|الفا[يئ]ت"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ 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 -> 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
isOkWithThisNext]
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNextTime :: Rule
ruleNextTime :: Rule
ruleNextTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> next"
  , 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
isOkWithThisNext]
    , String -> PatternItem
regex String
"التالي"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth Int
0 Bool
True a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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 -> 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
isOkWithThisNext]
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth (- Int
1) Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- to match 'عام سابق', 'عامان سابقان' or 'سابقة' and the same for 'منصرم' and 'ماضي'
ruleLastTime2 :: Rule
ruleLastTime2 :: Rule
ruleLastTime2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> last"
  , 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
isOkWithThisNext]
    , String -> PatternItem
regex String
"((ال)?ماضيت?(ان|ين|ة|ه)?|(ال)?منصرمت?(ان|ين|ة|ه)?|(ال)?سابقت?(ان|ين|ة|ه)?)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> TimeData -> TimeData
predNth (- Int
1) Bool
False a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastDOWOfTime :: Rule
ruleLastDOWOfTime :: Rule
ruleLastDOWOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <day-of-week> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"[اآ]خر"
    , Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
"من|في"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData -> TimeData
predLastOf a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDOWTheLastOfTime :: Rule
ruleDOWTheLastOfTime :: Rule
ruleDOWTheLastOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-week> the last of <time>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isADayOfWeek
    , String -> PatternItem
regex String
"(ال[اأآ]خي?رة?) (من|في|ب|ل)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData -> TimeData
predLastOf a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleLastCycleOfTime :: Rule
ruleLastCycleOfTime :: Rule
ruleLastCycleOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last <cycle> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"[اآ]خر"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"(من|في|ل|ب)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf a
Grain
grain a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleLastOfTime :: Rule
ruleCycleLastOfTime :: Rule
ruleCycleLastOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> last of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"ال[اأ]خيرة? (من|في|ل|ب)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf a
Grain
grain a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

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

ruleNthTimeAfterTime :: Rule
ruleNthTimeAfterTime :: Rule
ruleNthTimeAfterTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"nth <time> after <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"بعد"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
  }

ruleTimeNthAfterTime :: Rule
ruleTimeNthAfterTime :: Rule
ruleTimeNthAfterTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> nth after <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
    , String -> PatternItem
regex String
"بعد"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token Dimension a
Ordinal a
od: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
  }

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

ruleYearPastLatent :: Rule
ruleYearPastLatent :: Rule
ruleYearPastLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
 { name :: Text
name = Text
"past year (latent)"
 , pattern :: Pattern
pattern =
   [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$
       [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Int -> Int -> Predicate
isIntegerBetween (- Int
10000) Int
0, Int -> Int -> Predicate
isIntegerBetween Int
25 Int
999]
   ]
 , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
     (Token
token:[Token]
_) -> do
       Int
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
 }

ruleYearFutureLatent :: Rule
ruleYearFutureLatent :: Rule
ruleYearFutureLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
 { name :: Text
name = Text
"future year (latent)"
 , pattern :: Pattern
pattern = [Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
2101 Int
10000]
 , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
     (Token
token:[Token]
_) -> do
       Int
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
 }

ruleDOMLatent :: Rule
ruleDOMLatent :: Rule
ruleDOMLatent = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (ordinal)"
  , pattern :: Pattern
pattern = [Predicate -> PatternItem
Predicate Predicate
isDOMOrdinal]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
mkLatent (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
dayOfMonth Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

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

ruleDOMOfMonth :: Rule
ruleDOMOfMonth :: Rule
ruleDOMOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<day-of-month> (ordinal or number) of <named-month>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"(من|في|بـ?)"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
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
  }

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

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

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

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

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

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

ruleAtHourTOD :: Rule
ruleAtHourTOD :: Rule
ruleAtHourTOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"at <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"عند ((ال)?ساع[ةه])?"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
notLatent a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODAndInteger :: Rule
ruleHODAndInteger :: Rule
ruleHODAndInteger = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> and integer"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isNotLatent, Predicate
isAnHourOfDay]
    , String -> PatternItem
regex String
"و"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
0 Int
60
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODAndIntegerMinutes :: Rule
ruleHODAndIntegerMinutes :: Rule
ruleHODAndIntegerMinutes = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> and integer minutes"
  , 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
0 Int
60
    , String -> PatternItem
regex String
"دقيق[ةه]|دقا[ئي]ق"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours (Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHHMM :: Rule
ruleHHMM :: Rule
ruleHHMM = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"hh:mm"
  , pattern :: Pattern
pattern = [String -> PatternItem
regex String
"((?:[01]?\\d)|(?:2[0-3]))[:.]([0-5]\\d)"]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (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)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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 = \[Token]
tokens -> case [Token]
tokens of
      (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
  }

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
"([ap])(\\s|\\.)?m?\\.?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
  }

ruleHONumeral :: Rule
ruleHONumeral :: Rule
ruleHONumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> <integer>"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isNotLatent, Predicate
isAnHourOfDay]
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
59
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:
       Token
token:
       [Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODHalf :: Rule
ruleHODHalf :: Rule
ruleHODHalf = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> half"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"(و ?)?نصف?( ساع[ةه])?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours Int
30
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODThird :: Rule
ruleHODThird :: Rule
ruleHODThird = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> third"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"(و ?)?ثلث( ساع[ةه])?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours Int
20
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODQuarter :: Rule
ruleHODQuarter :: Rule
ruleHODQuarter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> quarter"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"(و ?)?ربع( ساع[ةه])?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time TimeData {TTime.form = Just (TTime.TimeOfDay (Just hours) is12H)}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Int -> Int -> TimeData
hourMinute Bool
is12H Int
hours Int
15
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleThirdToHOD :: Rule
ruleThirdToHOD :: Rule
ruleThirdToHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> till third"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"[إا]لا ثلثا?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
20 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleQuarterToHOD :: Rule
ruleQuarterToHOD :: Rule
ruleQuarterToHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<hour-of-day> till quarter"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    , String -> PatternItem
regex String
"[إا]لا ربعا?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
15 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHODAndNumeralAfter :: Rule
ruleHODAndNumeralAfter :: Rule
ruleHODAndNumeralAfter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<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 = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleNumeralAfterHOD :: Rule
ruleNumeralAfterHOD :: Rule
ruleNumeralAfterHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer after <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ 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
"(دقيق[ةه]|دقا[ئي]ق) بعد"
    , Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:Token
_:Token Dimension a
Time a
td:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
n a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleHalfAfterHOD :: Rule
ruleHalfAfterHOD :: Rule
ruleHalfAfterHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"half after <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"نصف? ساع[ةه] بعد"
    , Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
30 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleThirdAfterHOD :: Rule
ruleThirdAfterHOD :: Rule
ruleThirdAfterHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"third after <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ثلث ساع[ةه] بعد"
    , Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
20 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleQuarterAfterHOD :: Rule
ruleQuarterAfterHOD :: Rule
ruleQuarterAfterHOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"quarter after <hour-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ربع ساع[ةه] بعد"
    , Predicate -> PatternItem
Predicate Predicate
isAnHourOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> TimeData -> Maybe TimeData
minutesAfter Int
15 a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDDMM :: Rule
ruleDDMM :: Rule
ruleDDMM = 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 = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (dd:mm:_)):[Token]
_) -> do
        Int
d <- Text -> Maybe Int
parseInt Text
dd
        Int
m <- Text -> Maybe Int
parseInt Text
mm
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> Int -> TimeData
monthDay Int
m Int
d
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleNoonMidnightEOD :: Rule
ruleNoonMidnightEOD :: Rule
ruleNoonMidnightEOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"noon|midnight|EOD|end of day"
  , pattern :: Pattern
pattern = [String -> PatternItem
regex String
"(ليلا|مساء|نهاية (ال)يوم)|منتصف الليل"]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Int -> TimeData
hour Bool
False (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$
        if Text
match Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"منتصف الليل" then Int
12 else Int
0
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

parOfDaysMap :: HashMap Text (Int, Int)
parOfDaysMap :: HashMap Text (Int, Int)
parOfDaysMap = [(Text, (Int, Int))] -> HashMap Text (Int, Int)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
  [ ( Text
"فجر",    (Int
3, Int
6)   )
  , ( Text
"صبح",    (Int
0, Int
12)  )
  , ( Text
"صباح",   (Int
0, Int
12)  )
  , ( Text
"نهار",   (Int
6, Int
17)  )
  , ( Text
"ظهر",    (Int
11, Int
15) )
  , ( Text
"ظهر",    (Int
11, Int
15) )
  , ( Text
"ظهيرة",  (Int
11, Int
15) )
  , ( Text
"عصر",    (Int
15, Int
18) )
  , ( Text
"مغرب",   (Int
17, Int
21) )
  , ( Text
"غداء",   (Int
13, Int
16) )
  , ( Text
"عشاء",   (Int
18, Int
3)  )
  , ( Text
"ليلة",   (Int
18, Int
3)  )
  , ( Text
"ليله",   (Int
18, Int
3)  )
  , ( Text
"مساء",   (Int
12, Int
24)  )
  ]

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 = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (_:match:_)):[Token]
_) -> do
        (Int
start, Int
end) <- Text -> HashMap Text (Int, Int) -> Maybe (Int, Int)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text (Int, Int)
parOfDaysMap
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Bool -> Int -> TimeData
hour Bool
False Int
start) (Bool -> Int -> TimeData
hour Bool
False Int
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
  }

ruleAfterPartOfDays :: Rule
ruleAfterPartOfDays :: Rule
ruleAfterPartOfDays = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"after part of days"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"بعد ال(فجر|ظهر|ظهيرة|فطور|إفطار|عصر|مغرب|عشاء|ليل|غداء)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        (Int
start, Int
end) <- Text -> HashMap Text (Int, Int) -> Maybe (Int, Int)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text (Int, Int)
parOfDaysMap
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Bool -> Int -> TimeData
hour Bool
False Int
start) (Bool -> Int -> TimeData
hour Bool
False (Int
end Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
        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
notLatent TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleBeforePartOfDays :: Rule
ruleBeforePartOfDays :: Rule
ruleBeforePartOfDays = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"before part of days"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"قبل ال(فجر|ظهر|ظهيرة|فطور|إفطار|عصر|مغرب|عشاء|ليل|غداء)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) -> do
        (Int
start, Int
end) <- Text -> HashMap Text (Int, Int) -> Maybe (Int, Int)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HashMap.lookup (Text -> Text
Text.toLower Text
match) HashMap Text (Int, Int)
parOfDaysMap
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Bool -> Int -> TimeData
hour Bool
False (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) (Bool -> Int -> TimeData
hour Bool
False Int
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
notLatent 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 =
    [ String -> PatternItem
regex String
"(في|خلال|في خلال|عند)(وقت )?( ال)?|وقت ال"
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> 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 = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
        TimeData -> TimeData -> Maybe TimeData
intersect TimeData
today a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleTonight :: Rule
ruleTonight :: Rule
ruleTonight = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"tonight"
  , pattern :: Pattern
pattern = [String -> PatternItem
regex String
"(هذه )?الليل[ةه]"]
  , prod :: Production
prod = \[Token]
_ -> do
      TimeData
evening <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open (Bool -> Int -> TimeData
hour Bool
False Int
18) (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
  }

ruleAfterPartofday :: Rule
ruleAfterPartofday :: Rule
ruleAfterPartofday = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"after lunch/work/school"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"بعد[\\s-]?((ال)?غداء|(ال)?عمل|(ال)?شغل|(ال)?مدرس[ةه])"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
17, Bool -> Int -> TimeData
hour Bool
False Int
21)
          Text
"(ال)?مدرس[ةه]" -> (TimeData, TimeData) -> Maybe (TimeData, TimeData)
forall a. a -> Maybe a
Just (Bool -> Int -> TimeData
hour Bool
False Int
15, Bool -> Int -> TimeData
hour Bool
False Int
21)
          Text
_        -> Maybe (TimeData, TimeData)
forall a. Maybe a
Nothing
        TimeData
td <- TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> (TimeData -> TimeData) -> TimeData -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
partOfDay (TimeData -> TimeData)
-> (TimeData -> TimeData) -> TimeData -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TimeData -> TimeData
notLatent (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeData -> TimeData -> Maybe TimeData
intersect TimeData
today TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- Since part of days are latent, general time intersection is blocked
ruleTimePOD :: Rule
ruleTimePOD :: Rule
ruleTimePOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> <part-of-day>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , Predicate -> PatternItem
Predicate Predicate
isAPartOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
  }

ruleWeekend :: Rule
ruleWeekend :: Rule
ruleWeekend = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"week-end"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(عطل[ةه] )?نهاي[ةه] ال[اأ]سبوع"
    ]
  , prod :: Production
prod = \[Token]
_ -> TimeData -> Maybe Token
tt TimeData
weekend
  }

ruleSeasons :: [Rule]
ruleSeasons :: [Rule]
ruleSeasons = [(Text, String, TimeData, TimeData)] -> [Rule]
mkRuleSeasons
  [ (Text
"summer", String
"صيف|الصيف"  , Int -> Int -> TimeData
monthDay  Int
6 Int
21, Int -> Int -> TimeData
monthDay  Int
9 Int
23)
  , (Text
"fall"  , String
"الخريف|خريف", Int -> Int -> TimeData
monthDay  Int
9 Int
23, Int -> Int -> TimeData
monthDay Int
12 Int
21)
  , (Text
"winter", String
"شتاء|الشتاء", Int -> Int -> TimeData
monthDay Int
12 Int
21, Int -> Int -> TimeData
monthDay  Int
3 Int
20)
  , (Text
"spring", String
"ربيع|الربيع", Int -> Int -> TimeData
monthDay  Int
3 Int
20, Int -> Int -> TimeData
monthDay  Int
6 Int
21)
  ]

ruleTODPrecision :: Rule
ruleTODPrecision :: Rule
ruleTODPrecision = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> sharp|exactly"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"(تقريبا)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
notLatent a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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 = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ TimeData -> TimeData
notLatent a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalMonthDDDD :: Rule
ruleIntervalMonthDDDD :: Rule
ruleIntervalMonthDDDD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<month> dd-dd (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isAMonth
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|[اإ]لى|لـ?|حتى"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td:
       Token
token1:
       Token
_:
       Token
token2:
       [Token]
_) -> do
        TimeData
dom1 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
dom2 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token2
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed TimeData
dom1 TimeData
dom2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalDDDDMonth :: Rule
ruleIntervalDDDDMonth :: Rule
ruleIntervalDDDDMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"dd-dd <month> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|[اإ]لى|لـ?|حتى"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (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
  }

ruleIntervalFromMonthDDDD :: Rule
ruleIntervalFromMonthDDDD :: Rule
ruleIntervalFromMonthDDDD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <month> dd-dd (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"من"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"\\-|[اإ]لى|لـ?|حتى"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:
       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
  }

ruleIntervalFromDDDDMonth :: Rule
ruleIntervalFromDDDDMonth :: Rule
ruleIntervalFromDDDDMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <day-of-month> (ordinal or number) to <day-of-month> (ordinal or number) <named-month> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"من|بين"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , String -> PatternItem
regex String
"(و ?)?(\\-|[اإ]لى|لـ?|حتى)"
    , Predicate -> PatternItem
Predicate Predicate
isDOMValue
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:
       Token
token1:
       Token
_:
       Token
token2:
       Token Dimension a
Time a
td:
       [Token]
_) -> do
        TimeData
dom1 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token1
        TimeData
dom2 <- TimeData -> Token -> Maybe TimeData
intersectDOM a
TimeData
td Token
token2
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed TimeData
dom1 TimeData
dom2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalFromDDDDInMonth :: Rule
ruleIntervalFromDDDDInMonth :: Rule
ruleIntervalFromDDDDInMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <day-of-month> (ordinal or number) to <day-of-month> (ordinal or number) in <named-month> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"من|بين"
    , 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 = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:
       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
  }

-- Blocked for :latent time. May need to accept certain latents only, like hours
ruleIntervalDash :: Rule
ruleIntervalDash :: Rule
ruleIntervalDash = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<datetime> - <datetime> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"(و ?)?(\\-|[اإ]لى|حتى)"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalFrom :: Rule
ruleIntervalFrom :: Rule
ruleIntervalFrom = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"from <datetime> - <datetime> (interval)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"من"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    , String -> PatternItem
regex String
"(و ?)?(\\-|[اإ]لى|لـ?|حتى)"
    , Predicate -> PatternItem
Predicate Predicate
isNotLatent
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalBetween :: Rule
ruleIntervalBetween :: Rule
ruleIntervalBetween = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"between <time> and <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"بين ?((ال)?ساع[ةه])?"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"و ?(بين)? ?((ال)?ساع[ةه])?"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

-- Specific for time-of-day, to help resolve ambiguities
ruleIntervalTODDash :: Rule
ruleIntervalTODDash :: Rule
ruleIntervalTODDash = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time-of-day> - <time-of-day> (interval)"
  , pattern :: Pattern
pattern =
    [ Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> (Token -> [Bool]) -> Predicate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Predicate] -> Token -> [Bool]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Predicate
isNotLatent, Predicate
isATimeOfDay]
    , String -> PatternItem
regex String
"(و ?)?(\\-|:|[اإ]لى|لـ?|حتى)"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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 =
    [ String -> PatternItem
regex String
"(من|بين|)((ال)?ساع[ةه]?)"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    , String -> PatternItem
regex String
"(و ?)?(\\-|[اإ]لى|لـ?|حتى)((ال)?ساع[ةه]?)"
    , Predicate -> PatternItem
Predicate Predicate
isATimeOfDay
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td1:Token
_:Token Dimension a
Time a
td2:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Closed a
TimeData
td1 a
TimeData
td2
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleIntervalBy :: Rule
ruleIntervalBy :: Rule
ruleIntervalBy = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"by <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"حتى"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> 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
  }

ruleIntervalUntilTOD :: Rule
ruleIntervalUntilTOD :: Rule
ruleIntervalUntilTOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"until <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([اأ]ي وقت)?(قبل|حتى|[إا]لى)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.Before a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleIntervalAfterTOD :: Rule
ruleIntervalAfterTOD :: Rule
ruleIntervalAfterTOD = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"after <time-of-day>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([اأ]ي وقت)?(بعد)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Time a
td:[Token]
_) -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.After a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek :: [Rule]
ruleDaysOfWeek = [(Text, String)] -> [Rule]
mkRuleDaysOfWeek
  [ ( Text
"Monday"   , String
"(ال)?[اإ]ثنين"   )
  , ( Text
"Tuesday"  , String
"(ال)?ثلاثاء?"     )
  , ( Text
"Wednesday", String
"(ال)?[اأ]ربعاء?" )
  , ( Text
"Thursday" , String
"(ال)?خميس"       )
  , ( Text
"Friday"   , String
"(ال)?جمع[ةه]"    )
  , ( Text
"Saturday" , String
"(ال)?سبت"        )
  , ( Text
"Sunday"   , String
"(ال)?[اأ]حد"     )
  ]

ruleMonths :: [Rule]
ruleMonths :: [Rule]
ruleMonths = [(Text, String)] -> [Rule]
mkRuleMonths
  [ ( Text
"January"  , String
"يناير|كانون (ال)ثاني?"       )
  , ( Text
"February" , String
"فبراير|شباط"                 )
  , ( Text
"March"    , String
"مارس|[اآ]ذار"                )
  , ( Text
"April"    , String
"[اأ]بريل|نيسان"              )
  , ( Text
"May"      , String
"مايو|[اأ]ي[اآ]ر"             )
  , ( Text
"June"     , String
"يونيو|حزيران"                )
  , ( Text
"July"     , String
"يوليو|تموز"                  )
  , ( Text
"August"   , String
"[اأ]غسطس|[اآ]ب"              )
  , ( Text
"September", String
"سي?بتمبر|[اأ]يلول"           )
  , ( Text
"October"  , String
"[اأ]كتوبر|تشرين (ال)?[اأ]ول" )
  , ( Text
"November" , String
"نوفمبر|تشرين (ال)?ثاني"      )
  , ( Text
"December" , String
"ديسمبر|كانون (ال)?[اأ]ول"    )
  ]

ruleMonthsNumeral :: Rule
ruleMonthsNumeral :: Rule
ruleMonthsNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"month (integer)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"شهر"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
12
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
month Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleMonthsOrdinal :: Rule
ruleMonthsOrdinal :: Rule
ruleMonthsOrdinal = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"month (ordinal)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"الشهر"
    , Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
month Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleYearInteger :: Rule
ruleYearInteger :: Rule
ruleYearInteger = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"year (integer)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"سنة|عام"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
3000
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Int -> TimeData
year Int
n
      [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 =
    [ String -> PatternItem
regex String
"([اأ]وائل|[اأ]واخر|نهاي[ةه])-?"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):Token Dimension a
Time a
td:[Token]
_) -> do
        (Int
sd, (Just TimeData
end)) <- case Text -> Text
Text.toLower Text
match of
          Text
"اوائل" -> (Int, Maybe TimeData) -> Maybe (Int, Maybe TimeData)
forall a. a -> Maybe a
Just (Int
1, TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
10) a
TimeData
td)
          Text
"أوائل" -> (Int, Maybe TimeData) -> Maybe (Int, Maybe TimeData)
forall a. a -> Maybe a
Just (Int
1, TimeData -> TimeData -> Maybe TimeData
intersect (Int -> TimeData
dayOfMonth Int
10) a
TimeData
td)
          Text
"اواخر" -> (Int, Maybe TimeData) -> Maybe (Int, Maybe TimeData)
forall a. a -> Maybe a
Just (Int
21, 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)
          Text
"أواخر" -> (Int, Maybe TimeData) -> Maybe (Int, Maybe TimeData)
forall a. a -> Maybe a
Just (Int
21, 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)
          Text
_       -> Maybe (Int, Maybe TimeData)
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
        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
  }

ruleDayOfMonth :: Rule
ruleDayOfMonth :: Rule
ruleDayOfMonth = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"day of <named-month>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(بداي[ةه]|منتصف|نصف?|[اآ]خر|نهاي[ةه])-?"
    , Predicate -> PatternItem
Predicate Predicate
isAMonth
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
Time a
td:
       [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 (Int -> TimeData
dayOfMonth Int
1) a
TimeData
td
        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 (Int -> TimeData
dayOfMonth Int
1) a
TimeData
td
        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 (Int -> TimeData
dayOfMonth Int
15) a
TimeData
td
        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 (Int -> TimeData
dayOfMonth Int
15) a
TimeData
td
        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 (Int -> TimeData
dayOfMonth Int
15) a
TimeData
td
        Text
_       -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> TimeData -> TimeData
cycleLastOf Grain
TG.Day a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleUSHolidays :: [Rule]
ruleUSHolidays :: [Rule]
ruleUSHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"Christmas"       , String
"(يوم |عطل[ةه] )?((ال)?كري?سماس)"           , Int -> Int -> TimeData
monthDay Int
12 Int
25)
  , ( Text
"Christmas Eve"   , String
"(ليل[ةه] )((ال)?كري?سماس)"                 , Int -> Int -> TimeData
monthDay Int
12 Int
24)
  , ( Text
"New Year's Eve"  , String
"(ليل[ةه] )(ر[اأ]س السن[ةه])"               , Int -> Int -> TimeData
monthDay Int
12 Int
31)
  , ( Text
"New Year's Day"  , String
"(وم |عطل[ةه] )?(ر[اأ]س السن[ةه])"          , Int -> Int -> TimeData
monthDay  Int
1  Int
1)
  , ( Text
"Valentine's Day" , String
"(عيد|يوم|عطل[ةه])((ال)?حب|(ال)?فالنتا?ين)" , Int -> Int -> TimeData
monthDay  Int
2 Int
12)
  , ( Text
"Halloween"       , String
"(عيد |يوم |عطل[ةه] )?((ال)?هالوي?ين)"      , Int -> Int -> TimeData
monthDay Int
10 Int
31 )
  ]

ruleThisLastNextCycle :: Rule
ruleThisLastNextCycle :: Rule
ruleThisLastNextCycle = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this|last <cycle>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(هذا|هذه|اخر|آخر)"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token 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)
-> (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
_     -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleThisLastNextCycle2 :: Rule
ruleThisLastNextCycle2 :: Rule
ruleThisLastNextCycle2 = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"this|last the <cycle>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(هذا|هذه|اخر|آخر)"
    , String -> PatternItem
regex String
"(ال)"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token
_:
       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)
-> (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
_     -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext :: Rule
ruleCycleThisLastNext = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> this|last|next"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"(هذ|القادم|التالي|الحالي|المقبل|الجاي|السابق|الماضي?|الفا[ئي]ت|المنصرم)[اةه]?(ين|ان|ات)?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:
       Token Dimension a
TimeGrain a
grain:
       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
$ 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
1
        Text
"التالي"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
1
        Text
"المقبل"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
1
        Text
"الجاي"   -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Grain -> Int -> TimeData
cycleNth a
Grain
grain Int
1
        Text
"السابق"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
"الماضي"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
"الماض"   -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
"المنصرم" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
"الفائت"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
"الفايت"  -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> TimeData
cycleNth a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
1
        Text
_         -> Maybe Token
forall a. Maybe a
Nothing
      [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 =
    [ String -> PatternItem
regex String
"ال"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"(الذ?ي |ال)(قبل|بعد)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:
       Token Dimension a
TimeGrain a
grain:
       Token Dimension a
RegexMatch (GroupMatch (_:match:_)):
       Token Dimension a
Time a
td:
       [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 -> TimeData
cycleNthAfter Bool
False a
Grain
grain Int
1 a
TimeData
td
        Text
_     -> 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
1) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleAfterBeforeTime :: Rule
ruleCycleAfterBeforeTime :: Rule
ruleCycleAfterBeforeTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> after|before <time>"
  , pattern :: Pattern
pattern =
    [ Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"(قبل|بعد)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
TimeGrain a
grain:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
Time a
td:
       [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 -> TimeData
cycleNthAfter Bool
False a
Grain
grain Int
1 a
TimeData
td
        Text
_     -> 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
1) a
TimeData
td
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleLastN :: Rule
ruleCycleLastN :: Rule
ruleCycleLastN = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"last n <cycle>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"([اآ]خر)"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
9999
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token
token:Token Dimension a
TimeGrain a
grain:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Grain -> Int -> TimeData
cycleN Bool
True a
Grain
grain (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ - Int
n
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleCycleNextN :: Rule
ruleCycleNextN :: Rule
ruleCycleNextN = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> n next"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"ال"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
1 Int
9999
    , String -> PatternItem
regex String
"(ال)(تالي|قادم)[ةه]?"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token
_:Token
token:[Token]
_) -> do
        Int
n <- Token -> Maybe Int
getIntValue Token
token
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Bool -> Grain -> Int -> TimeData
cycleN Bool
True a
Grain
grain Int
n
      [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 OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"في|من|بـ?"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[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
  }

ruleCycleOrdinalDayOfTime :: Rule
ruleCycleOrdinalDayOfTime :: Rule
ruleCycleOrdinalDayOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<cycle> <ordinal> day? of <time>"
  , pattern :: Pattern
pattern =
    [ Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , String -> PatternItem
regex String
"((ال)?يوم )?(بـ?|في|من)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
TimeGrain a
grain:Token
token:Token
_:Token Dimension a
Time a
td:[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
  }

ruleTheCycleTheOrdinalOfTime :: Rule
ruleTheCycleTheOrdinalOfTime :: Rule
ruleTheCycleTheOrdinalOfTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"the <cycle> the <ordinal> of <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"ال"
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , String -> PatternItem
regex String
"في|من|بـ?"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
TimeGrain a
grain:Token
token:Token
_:Token Dimension a
Time a
td:[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
  }


ruleCycleOrdinalAfterTime :: Rule
ruleCycleOrdinalAfterTime :: Rule
ruleCycleOrdinalAfterTime = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<ordinal> <cycle> after <time>"
  , pattern :: Pattern
pattern =
    [ Dimension OrdinalData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension OrdinalData
Ordinal
    , Dimension Grain -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension Grain
TimeGrain
    , String -> PatternItem
regex String
"بعد"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
token:Token Dimension a
TimeGrain a
grain:Token
_:Token Dimension a
Time a
td:[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
  }

ruleDurationInWithinAfter :: Rule
ruleDurationInWithinAfter :: Rule
ruleDurationInWithinAfter = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in|within|after <duration>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(في|خلال|بعد)"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
Duration a
dd:
       [Token]
_) -> case Text -> Text
Text.toLower Text
match of
         Text
"خلال" -> Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
now (DurationData -> TimeData
inDuration a
DurationData
dd)
         Text
"بعد" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (TimeData -> TimeData) -> TimeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntervalDirection -> TimeData -> TimeData
withDirection IntervalDirection
TTime.After (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
inDuration a
DurationData
dd
         Text
"في" -> TimeData -> Maybe Token
tt (TimeData -> Maybe Token) -> TimeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ DurationData -> TimeData
inDuration a
DurationData
dd
         Text
_ -> Maybe Token
forall a. Maybe a
Nothing
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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 = \[Token]
tokens -> case [Token]
tokens of
      (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
inDuration 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
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

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

ruleInNumeral :: Rule
ruleInNumeral :: Rule
ruleInNumeral = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"in <number> (implicit minutes)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"في|خلال"
    , Predicate -> PatternItem
Predicate (Predicate -> PatternItem) -> Predicate -> PatternItem
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Predicate
isIntegerBetween Int
0 Int
60
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Numeral NumeralData{TNumeral.value = v}:[Token]
_) ->
        TimeData -> Maybe Token
tt (TimeData -> Maybe Token)
-> (Int -> TimeData) -> Int -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DurationData -> TimeData
inDuration (DurationData -> TimeData)
-> (Int -> DurationData) -> Int -> TimeData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Grain -> Int -> DurationData
duration Grain
TG.Minute (Int -> Maybe Token) -> Int -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
floor Double
v
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleDurationAfterBeforeTime :: Rule
ruleDurationAfterBeforeTime :: Rule
ruleDurationAfterBeforeTime = 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
"(من|قبل|بعد)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Duration a
dd:
       Token Dimension a
RegexMatch (GroupMatch (match:_)):
       Token Dimension a
Time a
td:
       [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
  }

ruleIntervalForDurationFrom :: Rule
ruleIntervalForDurationFrom :: Rule
ruleIntervalForDurationFrom = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"for <duration> from <time>"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"لمدة|ل"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    , String -> PatternItem
regex String
"(من بداي[ةه]|ابتداء ب|بداية من|من)"
    , Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token
_:Token Dimension a
Duration a
dd:Token
_:Token Dimension a
Time a
td1:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open a
TimeData
td1 (DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}

ruleTimeForDuration :: Rule
ruleTimeForDuration :: Rule
ruleTimeForDuration = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"<time> for <duration>"
  , pattern :: Pattern
pattern =
    [ Dimension TimeData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension TimeData
Time
    , String -> PatternItem
regex String
"لمدة|ل"
    , Dimension DurationData -> PatternItem
forall a. Typeable a => Dimension a -> PatternItem
dimension Dimension DurationData
Duration
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
Time a
td1:Token
_:Token Dimension a
Duration a
dd:[Token]
_) ->
        Dimension TimeData -> TimeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension TimeData
Time (TimeData -> Token) -> Maybe TimeData -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open a
TimeData
td1 (DurationData -> TimeData -> TimeData
durationAfter a
DurationData
dd a
TimeData
td1)
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
}

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

rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays :: [Rule]
rulePeriodicHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"عيد الميلاد" ,String
"عيد الميلاد", Int -> Int -> TimeData
monthDay Int
12 Int
25 )
  ]

ruleComputedHolidays :: [Rule]
ruleComputedHolidays :: [Rule]
ruleComputedHolidays = [(Text, String, TimeData)] -> [Rule]
mkRuleHolidays
  [ ( Text
"عيد الأضحى" ,String
"عيد الأضحى", TimeData
eidalAdha )
  , ( Text
"عيد الفطر" ,String
"عيد الفطر", TimeData
eidalFitr )
  , ( Text
"عيد الفصح" ,String
"عيد الفصح", TimeData
easterSunday )
  , ( Text
"رأس السنة الهجرية" ,String
"رأس السنة الهجرية", TimeData
muharram )
  ]

ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' :: [Rule]
ruleComputedHolidays' = [(Text, String, Maybe TimeData)] -> [Rule]
mkRuleHolidays'
  [ ( Text
"رمضان", String
"رمضان"
    , let start :: TimeData
start = TimeData
ramadan
          end :: TimeData
end = Bool -> Grain -> Int -> TimeData -> TimeData
cycleNthAfter Bool
False Grain
TG.Day (-Int
1) TimeData
eidalFitr
        in TimeIntervalType -> TimeData -> TimeData -> Maybe TimeData
interval TimeIntervalType
TTime.Open TimeData
start TimeData
end )
  ]

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleIntersect
  , Rule
ruleIntersectOf
  , Rule
ruleAbsorbOnTime
  , Rule
ruleAbsorbOnADOW
  , Rule
ruleAbsorbInMonth
  , Rule
ruleAbsorbCommaTOD
  , Rule
ruleThisDOW
  , Rule
ruleDOWNext
  , Rule
ruleDOWLast
  , Rule
ruleThisTime
  , Rule
ruleNextTime
  , Rule
ruleLastTime
  , Rule
ruleLastTime2
  , Rule
ruleLastDOWOfTime
  , Rule
ruleDOWTheLastOfTime
  , Rule
ruleLastCycleOfTime
  , Rule
ruleCycleLastOfTime
  , Rule
ruleNthTimeOfTime
  , Rule
ruleTimeNthOfTime
  , Rule
ruleNthTimeAfterTime
  , Rule
ruleTimeNthAfterTime
  , Rule
ruleYear
  , Rule
ruleYearPastLatent
  , Rule
ruleYearFutureLatent
  , Rule
ruleYearInteger
  , Rule
ruleMonthsNumeral
  , Rule
ruleMonthsOrdinal
  , Rule
ruleDOMLatent
  , Rule
ruleNamedDOMOrdinal
  , Rule
ruleMonthDOMNumeral
  , Rule
ruleDOMMonth
  , Rule
ruleDOMOfMonth
  , Rule
ruleDOMOrdinalMonthYear
  , Rule
ruleDOMOrdinalDayMonthYear
  , Rule
ruleTODIntegerLatent
  , Rule
ruleTODOrdinalLatent
  , Rule
ruleAtHourTOD
  , Rule
ruleHODAndInteger
  , Rule
ruleHODAndIntegerMinutes
  , Rule
ruleHourTOD
  , Rule
ruleHHMM
  , Rule
ruleHHMMLatent
  , Rule
ruleHHMMSS
  , Rule
ruleTODAMPM
  , Rule
ruleHONumeral
  , Rule
ruleHODHalf
  , Rule
ruleHODThird
  , Rule
ruleHODQuarter
  , Rule
ruleThirdToHOD
  , Rule
ruleQuarterToHOD
  , Rule
ruleHODAndNumeralAfter
  , Rule
ruleNumeralAfterHOD
  , Rule
ruleHalfAfterHOD
  , Rule
ruleThirdAfterHOD
  , Rule
ruleQuarterAfterHOD
  , Rule
ruleDDMM
  , Rule
ruleDDMMYYYY
  , Rule
ruleYYYYMMDD
  , Rule
ruleMMYYYY
  , Rule
ruleNoonMidnightEOD
  , Rule
rulePartOfDays
  , Rule
ruleAfterPartOfDays
  , Rule
ruleBeforePartOfDays
  , Rule
ruleEarlyMorning
  , Rule
rulePODIn
  , Rule
rulePODThis
  , Rule
ruleTonight
  , Rule
ruleAfterPartofday
  , Rule
ruleTimePOD
  , Rule
ruleWeekend
  , Rule
ruleTODPrecision
  , Rule
rulePrecisionTOD
  , Rule
ruleIntervalFromMonthDDDD
  , Rule
ruleIntervalFromDDDDMonth
  , Rule
ruleIntervalFromDDDDInMonth
  , Rule
ruleIntervalMonthDDDD
  , Rule
ruleIntervalDDDDMonth
  , Rule
ruleIntervalDash
  , Rule
ruleIntervalFrom
  , Rule
ruleIntervalBetween
  , Rule
ruleIntervalTODDash
  , Rule
ruleIntervalTODFrom
  , Rule
ruleIntervalTODBetween
  , Rule
ruleIntervalBy
  , Rule
ruleIntervalUntilTOD
  , Rule
ruleIntervalAfterTOD
  , Rule
ruleIntervalSinceTOD
  , Rule
ruleThisLastNextCycle
  , Rule
ruleThisLastNextCycle2
  , Rule
ruleCycleThisLastNext
  , Rule
ruleCycleTheAfterBeforeTime
  , Rule
ruleCycleAfterBeforeTime
  , Rule
ruleCycleLastN
  , Rule
ruleCycleNextN
  , Rule
ruleTheCycleTheOrdinalOfTime
  , Rule
ruleCycleOrdinalOfTime
  , Rule
ruleCycleOrdinalDayOfTime
  , Rule
ruleCycleOrdinalAfterTime
  , Rule
ruleDurationInWithinAfter
  , Rule
ruleDurationHenceAgo
  , Rule
ruleBeforeDuration
  , Rule
ruleDurationAfterBeforeTime
  , Rule
ruleIntervalForDurationFrom
  , Rule
ruleTimeForDuration
  , Rule
ruleInNumeral
  , Rule
ruleTimezone
  , Rule
rulePartOfMonth
  , Rule
ruleDayOfMonth
  , Rule
ruleNow
  ]

  [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]
ruleUSHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulePeriodicHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleComputedHolidays
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
ruleComputedHolidays'