-- 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 OverloadedStrings #-}

module Duckling.Volume.NL.Rules
  ( rules
  ) where

import Data.String
import Data.Text (Text)
import Prelude

import Duckling.Dimensions.Types
import Duckling.Types
import Duckling.Regex.Types (GroupMatch(..))
import Duckling.Volume.Helpers
import Duckling.Numeral.Helpers (isPositive)
import qualified Duckling.Volume.Types as TVolume
import qualified Duckling.Numeral.Types as TNumeral

volumes :: [(Text, String, TVolume.Unit)]
volumes :: [(Text, String, Unit)]
volumes = [ (Text
"<latent vol> ml"    , String
"m(illi)?l(iter)?" , Unit
TVolume.Millilitre)
          , (Text
"<vol> hl"           , String
"h(ecto)?l(iter)?"   , Unit
TVolume.Hectolitre)
          , (Text
"<vol> liters"       , String
"l(iters?)?"    , Unit
TVolume.Litre)
          ]

rulesVolumes :: [Rule]
rulesVolumes :: [Rule]
rulesVolumes = ((Text, String, Unit) -> Rule) -> [(Text, String, Unit)] -> [Rule]
forall a b. (a -> b) -> [a] -> [b]
map (Text, String, Unit) -> Rule
go [(Text, String, Unit)]
volumes
  where
    go :: (Text, String, TVolume.Unit) -> Rule
    go :: (Text, String, Unit) -> Rule
go (Text
name, String
regexPattern, Unit
u) = Rule :: Text -> Pattern -> Production -> Rule
Rule
      { name :: Text
name = Text
name
      , pattern :: Pattern
pattern =
        [ String -> PatternItem
regex String
regexPattern
        ]
      , prod :: Production
prod = \[Token]
_ -> Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> (VolumeData -> Token) -> VolumeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension VolumeData -> VolumeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension VolumeData
Volume (VolumeData -> Maybe Token) -> VolumeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Unit -> VolumeData
unitOnly Unit
u
      }

fractions :: [(Text, String, Double)]
fractions :: [(Text, String, Double)]
fractions = [ (Text
"half", String
"halve", Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
            ]

rulesFractionalVolume :: [Rule]
rulesFractionalVolume :: [Rule]
rulesFractionalVolume = ((Text, String, Double) -> Rule)
-> [(Text, String, Double)] -> [Rule]
forall a b. (a -> b) -> [a] -> [b]
map (Text, String, Double) -> Rule
go [(Text, String, Double)]
fractions
  where
    go :: (Text, String, Double) -> Rule
    go :: (Text, String, Double) -> Rule
go (Text
name, String
regexPattern, Double
f) = Rule :: Text -> Pattern -> Production -> Rule
Rule
      { name :: Text
name = Text
name
      , pattern :: Pattern
pattern =
        [ String -> PatternItem
regex String
regexPattern
        , Predicate -> PatternItem
Predicate Predicate
isUnitOnly
        ]
      , prod :: Production
prod = \case
        (Token
_:
         Token Dimension a
Volume TVolume.VolumeData{TVolume.unit = Just u}:
         [Token]
_) ->
          Token -> Maybe Token
forall a. a -> Maybe a
Just (Token -> Maybe Token)
-> (VolumeData -> Token) -> VolumeData -> Maybe Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension VolumeData -> VolumeData -> Token
forall a.
(Resolve a, Eq a, Hashable a, Show a, NFData a) =>
Dimension a -> a -> Token
Token Dimension VolumeData
Volume (VolumeData -> Maybe Token) -> VolumeData -> Maybe Token
forall a b. (a -> b) -> a -> b
$ Unit -> Double -> VolumeData
volume Unit
u Double
f
        [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
      }

rules :: [Rule]
rules :: [Rule]
rules =
  [
  ]
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulesVolumes
  [Rule] -> [Rule] -> [Rule]
forall a. [a] -> [a] -> [a]
++ [Rule]
rulesFractionalVolume