-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoRebindableSyntax #-}

module Duckling.Rules
  ( allRules
  , rulesFor
  ) where

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

import Duckling.Dimensions
import Duckling.Dimensions.Types
import Duckling.Locale
import Duckling.Types
import qualified Duckling.Rules.AF as AFRules
import qualified Duckling.Rules.AR as ARRules
import qualified Duckling.Rules.Common as CommonRules
import qualified Duckling.Rules.BG as BGRules
import qualified Duckling.Rules.BN as BNRules
import qualified Duckling.Rules.CA as CARules
import qualified Duckling.Rules.CS as CSRules
import qualified Duckling.Rules.DA as DARules
import qualified Duckling.Rules.DE as DERules
import qualified Duckling.Rules.EL as ELRules
import qualified Duckling.Rules.EN as ENRules
import qualified Duckling.Rules.ES as ESRules
import qualified Duckling.Rules.ET as ETRules
import qualified Duckling.Rules.FI as FIRules
import qualified Duckling.Rules.FA as FARules
import qualified Duckling.Rules.FR as FRRules
import qualified Duckling.Rules.GA as GARules
import qualified Duckling.Rules.HE as HERules
import qualified Duckling.Rules.HI as HIRules
import qualified Duckling.Rules.HR as HRRules
import qualified Duckling.Rules.HU as HURules
import qualified Duckling.Rules.ID as IDRules
import qualified Duckling.Rules.IS as ISRules
import qualified Duckling.Rules.IT as ITRules
import qualified Duckling.Rules.JA as JARules
import qualified Duckling.Rules.KA as KARules
import qualified Duckling.Rules.KM as KMRules
import qualified Duckling.Rules.KN as KNRules
import qualified Duckling.Rules.KO as KORules
import qualified Duckling.Rules.LO as LORules
import qualified Duckling.Rules.ML as MLRules
import qualified Duckling.Rules.MN as MNRules
import qualified Duckling.Rules.MY as MYRules
import qualified Duckling.Rules.NB as NBRules
import qualified Duckling.Rules.NE as NERules
import qualified Duckling.Rules.NL as NLRules
import qualified Duckling.Rules.PL as PLRules
import qualified Duckling.Rules.PT as PTRules
import qualified Duckling.Rules.RO as RORules
import qualified Duckling.Rules.RU as RURules
import qualified Duckling.Rules.SK as SKRules
import qualified Duckling.Rules.SV as SVRules
import qualified Duckling.Rules.SW as SWRules
import qualified Duckling.Rules.TA as TARules
import qualified Duckling.Rules.TE as TERules
import qualified Duckling.Rules.TH as THRules
import qualified Duckling.Rules.TR as TRRules
import qualified Duckling.Rules.UK as UKRules
import qualified Duckling.Rules.VI as VIRules
import qualified Duckling.Rules.ZH as ZHRules

-- | Returns the minimal set of rules required for `targets`.
rulesFor :: Locale -> HashSet (Seal Dimension) -> [Rule]
rulesFor :: Locale -> HashSet (Seal Dimension) -> [Rule]
rulesFor Locale
locale HashSet (Seal Dimension)
targets
  | HashSet (Seal Dimension) -> Bool
forall a. HashSet a -> Bool
HashSet.null HashSet (Seal Dimension)
targets = Locale -> [Rule]
allRules Locale
locale
  | Bool
otherwise = [ Rule
rules | Seal Dimension
dims <- HashSet (Seal Dimension) -> [Seal Dimension]
forall a. HashSet a -> [a]
HashSet.toList (HashSet (Seal Dimension) -> [Seal Dimension])
-> HashSet (Seal Dimension) -> [Seal Dimension]
forall a b. (a -> b) -> a -> b
$ HashSet (Seal Dimension) -> HashSet (Seal Dimension)
explicitDimensions HashSet (Seal Dimension)
targets
                        , Rule
rules <- Locale -> Seal Dimension -> [Rule]
rulesFor' Locale
locale Seal Dimension
dims ]

-- | Returns all the rules for the provided locale.
-- We can't really use `allDimensions` as-is, since `TimeGrain` is not present.
allRules :: Locale -> [Rule]
allRules :: Locale -> [Rule]
allRules locale :: Locale
locale@(Locale Lang
lang Maybe Region
_) = (Seal Dimension -> [Rule]) -> [Seal Dimension] -> [Rule]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Locale -> Seal Dimension -> [Rule]
rulesFor' Locale
locale) ([Seal Dimension] -> [Rule])
-> ([Seal Dimension] -> [Seal Dimension])
-> [Seal Dimension]
-> [Rule]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet (Seal Dimension) -> [Seal Dimension]
forall a. HashSet a -> [a]
HashSet.toList
  (HashSet (Seal Dimension) -> [Seal Dimension])
-> ([Seal Dimension] -> HashSet (Seal Dimension))
-> [Seal Dimension]
-> [Seal Dimension]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashSet (Seal Dimension) -> HashSet (Seal Dimension)
explicitDimensions (HashSet (Seal Dimension) -> HashSet (Seal Dimension))
-> ([Seal Dimension] -> HashSet (Seal Dimension))
-> [Seal Dimension]
-> HashSet (Seal Dimension)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Seal Dimension] -> HashSet (Seal Dimension)
forall a. (Eq a, Hashable a) => [a] -> HashSet a
HashSet.fromList ([Seal Dimension] -> [Rule]) -> [Seal Dimension] -> [Rule]
forall a b. (a -> b) -> a -> b
$ Lang -> [Seal Dimension]
allDimensions Lang
lang

rulesFor' :: Locale -> Seal Dimension -> [Rule]
rulesFor' :: Locale -> Seal Dimension -> [Rule]
rulesFor' (Locale Lang
lang (Just Region
region)) Seal Dimension
dim =
  Seal Dimension -> [Rule]
CommonRules.rules Seal Dimension
dim [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ Lang -> Seal Dimension -> [Rule]
langRules Lang
lang Seal Dimension
dim [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ Lang -> Region -> Seal Dimension -> [Rule]
localeRules Lang
lang Region
region Seal Dimension
dim
rulesFor' (Locale Lang
lang Maybe Region
Nothing) Seal Dimension
dim =
  Seal Dimension -> [Rule]
CommonRules.rules Seal Dimension
dim [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ Lang -> Seal Dimension -> [Rule]
defaultRules Lang
lang Seal Dimension
dim

-- | Default rules when no locale, for backward compatibility.
defaultRules :: Lang -> Seal Dimension -> [Rule]
defaultRules :: Lang -> Seal Dimension -> [Rule]
defaultRules Lang
AF = Seal Dimension -> [Rule]
AFRules.defaultRules
defaultRules Lang
AR = Seal Dimension -> [Rule]
ARRules.defaultRules
defaultRules Lang
BG = Seal Dimension -> [Rule]
BGRules.defaultRules
defaultRules Lang
BN = Seal Dimension -> [Rule]
BNRules.defaultRules
defaultRules Lang
CA = Seal Dimension -> [Rule]
CARules.defaultRules
defaultRules Lang
CS = Seal Dimension -> [Rule]
CSRules.defaultRules
defaultRules Lang
DA = Seal Dimension -> [Rule]
DARules.defaultRules
defaultRules Lang
DE = Seal Dimension -> [Rule]
DERules.defaultRules
defaultRules Lang
EL = Seal Dimension -> [Rule]
ELRules.defaultRules
defaultRules Lang
EN = Seal Dimension -> [Rule]
ENRules.defaultRules
defaultRules Lang
ES = Seal Dimension -> [Rule]
ESRules.defaultRules
defaultRules Lang
ET = Seal Dimension -> [Rule]
ETRules.defaultRules
defaultRules Lang
FI = Seal Dimension -> [Rule]
FIRules.defaultRules
defaultRules Lang
FA = Seal Dimension -> [Rule]
FARules.defaultRules
defaultRules Lang
FR = Seal Dimension -> [Rule]
FRRules.defaultRules
defaultRules Lang
GA = Seal Dimension -> [Rule]
GARules.defaultRules
defaultRules Lang
HE = Seal Dimension -> [Rule]
HERules.defaultRules
defaultRules Lang
HI = Seal Dimension -> [Rule]
HIRules.defaultRules
defaultRules Lang
HR = Seal Dimension -> [Rule]
HRRules.defaultRules
defaultRules Lang
HU = Seal Dimension -> [Rule]
HURules.defaultRules
defaultRules Lang
ID = Seal Dimension -> [Rule]
IDRules.defaultRules
defaultRules Lang
IS = Seal Dimension -> [Rule]
ISRules.defaultRules
defaultRules Lang
IT = Seal Dimension -> [Rule]
ITRules.defaultRules
defaultRules Lang
JA = Seal Dimension -> [Rule]
JARules.defaultRules
defaultRules Lang
KA = Seal Dimension -> [Rule]
KARules.defaultRules
defaultRules Lang
KM = Seal Dimension -> [Rule]
KMRules.defaultRules
defaultRules Lang
KN = Seal Dimension -> [Rule]
KNRules.defaultRules
defaultRules Lang
KO = Seal Dimension -> [Rule]
KORules.defaultRules
defaultRules Lang
LO = Seal Dimension -> [Rule]
LORules.defaultRules
defaultRules Lang
ML = Seal Dimension -> [Rule]
MLRules.defaultRules
defaultRules Lang
MN = Seal Dimension -> [Rule]
MNRules.defaultRules
defaultRules Lang
MY = Seal Dimension -> [Rule]
MYRules.defaultRules
defaultRules Lang
NB = Seal Dimension -> [Rule]
NBRules.defaultRules
defaultRules Lang
NE = Seal Dimension -> [Rule]
NERules.defaultRules
defaultRules Lang
NL = Seal Dimension -> [Rule]
NLRules.defaultRules
defaultRules Lang
PL = Seal Dimension -> [Rule]
PLRules.defaultRules
defaultRules Lang
PT = Seal Dimension -> [Rule]
PTRules.defaultRules
defaultRules Lang
RO = Seal Dimension -> [Rule]
RORules.defaultRules
defaultRules Lang
RU = Seal Dimension -> [Rule]
RURules.defaultRules
defaultRules Lang
SK = Seal Dimension -> [Rule]
SKRules.defaultRules
defaultRules Lang
SV = Seal Dimension -> [Rule]
SVRules.defaultRules
defaultRules Lang
SW = Seal Dimension -> [Rule]
SWRules.defaultRules
defaultRules Lang
TA = Seal Dimension -> [Rule]
TARules.defaultRules
defaultRules Lang
TE = Seal Dimension -> [Rule]
TERules.defaultRules
defaultRules Lang
TH = Seal Dimension -> [Rule]
THRules.defaultRules
defaultRules Lang
TR = Seal Dimension -> [Rule]
TRRules.defaultRules
defaultRules Lang
UK = Seal Dimension -> [Rule]
UKRules.defaultRules
defaultRules Lang
VI = Seal Dimension -> [Rule]
VIRules.defaultRules
defaultRules Lang
ZH = Seal Dimension -> [Rule]
ZHRules.defaultRules

localeRules :: Lang -> Region -> Seal Dimension -> [Rule]
localeRules :: Lang -> Region -> Seal Dimension -> [Rule]
localeRules Lang
AF = Region -> Seal Dimension -> [Rule]
AFRules.localeRules
localeRules Lang
AR = Region -> Seal Dimension -> [Rule]
ARRules.localeRules
localeRules Lang
BG = Region -> Seal Dimension -> [Rule]
BGRules.localeRules
localeRules Lang
BN = Region -> Seal Dimension -> [Rule]
BNRules.localeRules
localeRules Lang
CA = Region -> Seal Dimension -> [Rule]
CARules.localeRules
localeRules Lang
CS = Region -> Seal Dimension -> [Rule]
CSRules.localeRules
localeRules Lang
DA = Region -> Seal Dimension -> [Rule]
DARules.localeRules
localeRules Lang
DE = Region -> Seal Dimension -> [Rule]
DERules.localeRules
localeRules Lang
EL = Region -> Seal Dimension -> [Rule]
ELRules.localeRules
localeRules Lang
EN = Region -> Seal Dimension -> [Rule]
ENRules.localeRules
localeRules Lang
ES = Region -> Seal Dimension -> [Rule]
ESRules.localeRules
localeRules Lang
ET = Region -> Seal Dimension -> [Rule]
ETRules.localeRules
localeRules Lang
FI = Region -> Seal Dimension -> [Rule]
FIRules.localeRules
localeRules Lang
FA = Region -> Seal Dimension -> [Rule]
FARules.localeRules
localeRules Lang
FR = Region -> Seal Dimension -> [Rule]
FRRules.localeRules
localeRules Lang
GA = Region -> Seal Dimension -> [Rule]
GARules.localeRules
localeRules Lang
HE = Region -> Seal Dimension -> [Rule]
HERules.localeRules
localeRules Lang
HI = Region -> Seal Dimension -> [Rule]
HIRules.localeRules
localeRules Lang
HR = Region -> Seal Dimension -> [Rule]
HRRules.localeRules
localeRules Lang
HU = Region -> Seal Dimension -> [Rule]
HURules.localeRules
localeRules Lang
ID = Region -> Seal Dimension -> [Rule]
IDRules.localeRules
localeRules Lang
IS = Region -> Seal Dimension -> [Rule]
ISRules.localeRules
localeRules Lang
IT = Region -> Seal Dimension -> [Rule]
ITRules.localeRules
localeRules Lang
JA = Region -> Seal Dimension -> [Rule]
JARules.localeRules
localeRules Lang
KA = Region -> Seal Dimension -> [Rule]
KARules.localeRules
localeRules Lang
KM = Region -> Seal Dimension -> [Rule]
KMRules.localeRules
localeRules Lang
KN = Region -> Seal Dimension -> [Rule]
KNRules.localeRules
localeRules Lang
KO = Region -> Seal Dimension -> [Rule]
KORules.localeRules
localeRules Lang
LO = Region -> Seal Dimension -> [Rule]
LORules.localeRules
localeRules Lang
ML = Region -> Seal Dimension -> [Rule]
MLRules.localeRules
localeRules Lang
MN = Region -> Seal Dimension -> [Rule]
MNRules.localeRules
localeRules Lang
MY = Region -> Seal Dimension -> [Rule]
MYRules.localeRules
localeRules Lang
NB = Region -> Seal Dimension -> [Rule]
NBRules.localeRules
localeRules Lang
NE = Region -> Seal Dimension -> [Rule]
NERules.localeRules
localeRules Lang
NL = Region -> Seal Dimension -> [Rule]
NLRules.localeRules
localeRules Lang
PL = Region -> Seal Dimension -> [Rule]
PLRules.localeRules
localeRules Lang
PT = Region -> Seal Dimension -> [Rule]
PTRules.localeRules
localeRules Lang
RO = Region -> Seal Dimension -> [Rule]
RORules.localeRules
localeRules Lang
RU = Region -> Seal Dimension -> [Rule]
RURules.localeRules
localeRules Lang
SK = Region -> Seal Dimension -> [Rule]
SKRules.localeRules
localeRules Lang
SV = Region -> Seal Dimension -> [Rule]
SVRules.localeRules
localeRules Lang
SW = Region -> Seal Dimension -> [Rule]
SWRules.localeRules
localeRules Lang
TA = Region -> Seal Dimension -> [Rule]
TARules.localeRules
localeRules Lang
TE = Region -> Seal Dimension -> [Rule]
TERules.localeRules
localeRules Lang
TH = Region -> Seal Dimension -> [Rule]
THRules.localeRules
localeRules Lang
TR = Region -> Seal Dimension -> [Rule]
TRRules.localeRules
localeRules Lang
UK = Region -> Seal Dimension -> [Rule]
UKRules.localeRules
localeRules Lang
VI = Region -> Seal Dimension -> [Rule]
VIRules.localeRules
localeRules Lang
ZH = Region -> Seal Dimension -> [Rule]
ZHRules.localeRules

langRules :: Lang -> Seal Dimension -> [Rule]
langRules :: Lang -> Seal Dimension -> [Rule]
langRules Lang
AF = Seal Dimension -> [Rule]
AFRules.langRules
langRules Lang
AR = Seal Dimension -> [Rule]
ARRules.langRules
langRules Lang
BG = Seal Dimension -> [Rule]
BGRules.langRules
langRules Lang
BN = Seal Dimension -> [Rule]
BNRules.langRules
langRules Lang
CA = Seal Dimension -> [Rule]
CARules.langRules
langRules Lang
CS = Seal Dimension -> [Rule]
CSRules.langRules
langRules Lang
DA = Seal Dimension -> [Rule]
DARules.langRules
langRules Lang
DE = Seal Dimension -> [Rule]
DERules.langRules
langRules Lang
EL = Seal Dimension -> [Rule]
ELRules.langRules
langRules Lang
EN = Seal Dimension -> [Rule]
ENRules.langRules
langRules Lang
ES = Seal Dimension -> [Rule]
ESRules.langRules
langRules Lang
ET = Seal Dimension -> [Rule]
ETRules.langRules
langRules Lang
FI = Seal Dimension -> [Rule]
FIRules.langRules
langRules Lang
FA = Seal Dimension -> [Rule]
FARules.langRules
langRules Lang
FR = Seal Dimension -> [Rule]
FRRules.langRules
langRules Lang
GA = Seal Dimension -> [Rule]
GARules.langRules
langRules Lang
HE = Seal Dimension -> [Rule]
HERules.langRules
langRules Lang
HI = Seal Dimension -> [Rule]
HIRules.langRules
langRules Lang
KN = Seal Dimension -> [Rule]
KNRules.langRules
langRules Lang
HR = Seal Dimension -> [Rule]
HRRules.langRules
langRules Lang
HU = Seal Dimension -> [Rule]
HURules.langRules
langRules Lang
ID = Seal Dimension -> [Rule]
IDRules.langRules
langRules Lang
IS = Seal Dimension -> [Rule]
ISRules.langRules
langRules Lang
IT = Seal Dimension -> [Rule]
ITRules.langRules
langRules Lang
JA = Seal Dimension -> [Rule]
JARules.langRules
langRules Lang
KA = Seal Dimension -> [Rule]
KARules.langRules
langRules Lang
KM = Seal Dimension -> [Rule]
KMRules.langRules
langRules Lang
KO = Seal Dimension -> [Rule]
KORules.langRules
langRules Lang
LO = Seal Dimension -> [Rule]
LORules.langRules
langRules Lang
ML = Seal Dimension -> [Rule]
MLRules.langRules
langRules Lang
MN = Seal Dimension -> [Rule]
MNRules.langRules
langRules Lang
MY = Seal Dimension -> [Rule]
MYRules.langRules
langRules Lang
NB = Seal Dimension -> [Rule]
NBRules.langRules
langRules Lang
NE = Seal Dimension -> [Rule]
NERules.langRules
langRules Lang
NL = Seal Dimension -> [Rule]
NLRules.langRules
langRules Lang
PL = Seal Dimension -> [Rule]
PLRules.langRules
langRules Lang
PT = Seal Dimension -> [Rule]
PTRules.langRules
langRules Lang
RO = Seal Dimension -> [Rule]
RORules.langRules
langRules Lang
RU = Seal Dimension -> [Rule]
RURules.langRules
langRules Lang
SK = Seal Dimension -> [Rule]
SKRules.langRules
langRules Lang
SV = Seal Dimension -> [Rule]
SVRules.langRules
langRules Lang
SW = Seal Dimension -> [Rule]
SWRules.langRules
langRules Lang
TA = Seal Dimension -> [Rule]
TARules.langRules
langRules Lang
TE = Seal Dimension -> [Rule]
TERules.langRules
langRules Lang
TH = Seal Dimension -> [Rule]
THRules.langRules
langRules Lang
TR = Seal Dimension -> [Rule]
TRRules.langRules
langRules Lang
UK = Seal Dimension -> [Rule]
UKRules.langRules
langRules Lang
VI = Seal Dimension -> [Rule]
VIRules.langRules
langRules Lang
ZH = Seal Dimension -> [Rule]
ZHRules.langRules