-- 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.TR.Rules ( rules ) where import Prelude import qualified Data.Text as Text import Duckling.Dimensions.Types import Duckling.Duration.Helpers (isGrain) import Duckling.Numeral.Helpers (parseInt) import Duckling.Ordinal.Types (OrdinalData(..)) import Duckling.Regex.Types (GroupMatch(..)) import Duckling.Time.Computed import Duckling.Time.Helpers import Duckling.Time.Types (TimeData(..), TimeIntervalType (Closed, Open)) import Duckling.Types import qualified Duckling.Ordinal.Types as TOrdinal import qualified Duckling.Time.Types as TTime import qualified Duckling.TimeGrain.Types as TG ruleInstants :: [Rule] ruleInstants = mkRuleInstants [ ( "now" , TG.Second, 0, "ş?imdi|şu(\\s)?an" ) , ( "today" , TG.Day , 0, "bugün" ) , ( "tomorrow" , TG.Day , 1, "yarın" ) , ( "yesterday" , TG.Day , -1, "dün" ) , ( "after tomorrow" , TG.Day , 2, "(yarından\\ssonraki)\\s?(gün)?" ) , ( "before yesterday", TG.Day , -2, "(dün\\sdeğil\\sevvelsi|dünden\\sönceki|öbürsü|öbürki)\\s(gün)?") , ( "EOM|End of day", TG.Day , 1, "gün\\s(sonu(na|ndan?)?|bitimi(ne|nden?)?)?" ) , ( "EOM|End of month", TG.Month , 1, "ay\\s(sonu(na|ndan?)?|bitimi(ne|nden?)?)?" ) , ( "EOY|End of year" , TG.Year , 1, "yıl\\s(sonu(na|ndan?)?|bitimi(ne|nden?)?)?" ) ] ruleDaysOfWeek :: [Rule] ruleDaysOfWeek = mkRuleDaysOfWeek [ ( "Pazartesi", "pazartesi'?(si|den|ye)?|pzts?") , ( "Salı" , "salı?'?(sı|dan|ya)?" ) , ( "Çarşamba" , "çar(şamba)?'?(sı|dan|ya)?" ) , ( "Perşembe" , "per(şembe)?'?(si|den|ye)?" ) , ( "Cuma" , "cuma?'?(sı|dan|ya)?" ) , ( "Cumartesi", "cumartesi'?(si|den|ye)?|cmt" ) , ( "Pazar" , "paz(ar)?'?(ı|dan|a)?" ) ] ruleMonths :: [Rule] ruleMonths = mkRuleMonths [ ( "Ocak" , "ocak?'?(ğın|tan|ğ?a)?" ) , ( "Şubat" , "şub(at)?'?(a|ın|tan)?" ) , ( "Mart" , "mart?'?(ın|a|tan)?" ) , ( "Nisan" , "nis(an)?'?(ın|a|dan)?" ) , ( "Mayıs" , "may(ıs)?'?(ın|a|tan)?" ) , ( "Haziran", "haz(iran)?'?(ın|a|dan)?" ) , ( "Temmuz" , "tem(muz)?'?(un|a|dan)?" ) , ( "Ağustos", "ağu(stos)?'?(un|a|tan)?" ) , ( "Eylül" , "eyl(ül)?'?(ün|e|den)?" ) , ( "Ekim" , "ekim?'?(in|den|e)?" ) , ( "Kasım" , "kas(ım)?'?(ın|dan|a)?" ) , ( "Aralık" , "ara(lık?)?'?(ğın|ğa|tan)?") ] ruleSeasons :: [Rule] ruleSeasons = mkRuleSeasons [ ( "yaz", "yaz(ın|a|dan)?", monthDay 6 21, monthDay 9 23 ) , ( "sonbahar", "sonbahar(ın|a|dan)?", monthDay 9 23, monthDay 12 21 ) , ( "kış", "kış(ın|a|tan)?", monthDay 12 21, monthDay 3 20 ) , ( "ilkbahar", "ilkbahar(ın|a|dan)?", monthDay 3 20, monthDay 6 21 ) ] ruleHolidays :: [Rule] ruleHolidays = mkRuleHolidays [ ( "Yılbaşı" , "yılbaşı(ndan|na)?|yılbaşı(\\statili(nden|ne))?" , monthDay 1 1 ) , ( "Ulusal Egemenlik ve Çocuk Bayramı" , "(ulusal\\segemenlik\\sve\\s)?çocuk\\sbayramı" , monthDay 4 23 ) , ( "Emek ve Dayanışma Günü" , "emek\\sve\\sdayanışma\\sgünü" , monthDay 5 1 ) , ( "Atatürk’ü Anma, Gençlik ve Spor Bayramı", "(gençlik\\sve\\sspor|spor|gençlik)\\sbayramı" , monthDay 5 19 ) , ( "Zafer Bayramı" , "zafer\\sbayramı" , monthDay 8 30 ) , ( "Cumhuriyet Bayramı" , "cumhuriyet\\sbayramı" , monthDay 10 29 ) ] ruleComputedHolidays:: [Rule] ruleComputedHolidays = mkRuleHolidays [ ("Kurban Bayramı", "kurban\\sbayramı", eidalAdha) , ("Ramazan Bayramı", "ramazan\\sbayramı", eidalFitr) ] rulePartOfDays :: Rule rulePartOfDays = Rule { name = "part of days" , pattern = [ regex "(sabahı?|öğlen?|akşam|gece|öğle\\syemeği)" ] , prod = \case (Token RegexMatch (GroupMatch (match:_)):_) -> do let (start, end) = case Text.toLower match of "sabah" -> (hour False 0, hour False 12 ) "sabahı" -> (hour False 0, hour False 12 ) "akşam" -> (hour False 18, hour False 0 ) "gece" -> (hour False 18, hour False 0 ) "öğlen" -> (hour False 12, hour False 14) "öğle" -> (hour False 12, hour False 14) "öğle yemeği" -> (hour False 12, hour False 14) _ -> (hour False 12, hour False 19) td <- interval TTime.Open start end tt $ partOfDay $ mkLatent td _ -> Nothing } rulePrecisionTOD :: Rule rulePrecisionTOD = Rule { name = "about|exactly " , pattern = [ Predicate $ isGrainFinerThan TG.Year , regex "gibi|civarı(nda)?" ] , prod = \case (Token Time td:_) -> tt $ notLatent td _ -> Nothing } rulePrecisionTOD2 :: Rule rulePrecisionTOD2 = Rule { name = "about|exactly " , pattern = [ regex "yaklaşık|tam(\\solarak)?" , Predicate $ isGrainFinerThan TG.Year ] , prod = \case (_:Token Time td:_) -> tt $ notLatent td _ -> Nothing } ruleDatetimeDatetimeInterval :: Rule ruleDatetimeDatetimeInterval = Rule { name = " - (interval)" , pattern = [ Predicate isNotLatent , regex "\\-" , Predicate isNotLatent ] , prod = \case (Token Time td1:_:Token Time td2:_) -> Token Time <$> interval TTime.Closed td1 td2 _ -> Nothing } ruleDateDateInterval :: Rule ruleDateDateInterval = Rule { name = "dd.(mm.)? - dd.mm.(yy[yy]?)? (interval)" , pattern = [ regex "(?:с\\s+)?(10|20|30|31|[012]?[1-9])\\.?((?<=\\.)(?:10|11|12|0?[1-9])(?:\\.?))?" , regex "\\-|/" , regex "(10|20|30|31|[012]?[1-9])\\.(10|11|12|0?[1-9])\\.?((?<=\\.)\\d{2,4})?" ] , prod = \case (Token RegexMatch (GroupMatch (d1:"":_)): _: Token RegexMatch (GroupMatch (d2:m2:"":_)): _) -> do d1 <- parseInt d1 d2 <- parseInt d2 m2 <- parseInt m2 Token Time <$> interval TTime.Closed (monthDay m2 d1) (monthDay m2 d2) (Token RegexMatch (GroupMatch (d1:"":_)): _: Token RegexMatch (GroupMatch (d2:m2:y:_)): _) -> do d1 <- parseInt d1 d2 <- parseInt d2 m2 <- parseInt m2 y <- parseInt y Token Time <$> interval TTime.Closed (yearMonthDay y m2 d1) (yearMonthDay y m2 d2) (Token RegexMatch (GroupMatch (d1:m1:_)): _: Token RegexMatch (GroupMatch (d2:m2:"":_)): _) -> do d1 <- parseInt d1 d2 <- parseInt d2 m1 <- parseInt m1 m2 <- parseInt m2 Token Time <$> interval TTime.Closed (monthDay m1 d1) (monthDay m2 d2) (Token RegexMatch (GroupMatch (d1:m1:_)): _: Token RegexMatch (GroupMatch (d2:m2:y:_)): _) -> do d1 <- parseInt d1 d2 <- parseInt d2 m1 <- parseInt m1 m2 <- parseInt m2 y <- parseInt y Token Time <$> interval TTime.Closed (yearMonthDay y m1 d1) (yearMonthDay y m2 d2) _ -> Nothing } ruleInDuration :: Rule ruleInDuration = Rule { name = "in " , pattern = [ dimension Duration , regex "içinde|içerisinde" ] , prod = \case (Token Duration dd:_) -> tt $ inDuration dd _ -> Nothing } ruleDurationHence :: Rule ruleDurationHence = Rule { name = " hence" , pattern = [ dimension Duration , regex "sonra" ] , prod = \case (Token Duration dd:_) -> tt $ inDuration dd _ -> Nothing } ruleDurationFromNow :: Rule ruleDurationFromNow = Rule { name = " from now" , pattern = [ regex "(bugünden\\s)?sonra(ki)?" , dimension Duration ] , prod = \case (_:Token Duration dd:_) -> tt $ inDuration dd _ -> Nothing } ruleLastCycleOfTime :: Rule ruleLastCycleOfTime = Rule { name = "last of