{-# OPTIONS_HADDOCK show-extensions #-}

-- |
-- Module      :  Phonetic.Languages.Array.General.PropertiesSyllablesG2
-- Copyright   :  (c) OleksandrZhabenko 2020-2021
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Generalization and extension of the functionality of the DobutokO.Poetry.Norms
-- and DobutokO.Poetry.Norms.Extended modules
-- from the @dobutokO-poetry@ package and more recent package @phonetic-languages-simplified-properties-array@.
-- Uses syllables information.
-- Instead of the vector-related, uses arrays.
-- If you use the functionality of the Phonetic.Languages.Array.Ukrainian.PropertiesSyllablesG2 module,
-- then import it qualified (or this module) because they have many common data. Is provided as a standalone one
-- to reduce dependencies list in general case. 

{-# LANGUAGE CPP, BangPatterns #-}

module Phonetic.Languages.Array.General.PropertiesSyllablesG2 (
    -- * Newtype to work with
  CoeffTwo(..)
  , Coeffs2
  , isEmpty
  , isPair
  , fstCF
  , sndCF
  , readCF
  -- * Rhythmicity properties (semi-empirical)
  -- ** Simple one
  , rhythmicity0i
  , rhythmicity0Fi
  -- ** With weight coefficients
  , rhythmicityKi
  , rhythmicityKFi
  -- * General
  , rhythmicityG
  , rhythmicity
) where

#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__>=710
/* code that applies only to GHC 7.10.* and higher versions */
import GHC.Base (mconcat)
#endif
#endif

import Languages.Rhythmicity
import Languages.Rhythmicity.Factor
import Data.Phonetic.Languages.Base
import Data.Phonetic.Languages.Syllables
import Data.Maybe (isNothing,fromMaybe)
import Text.Read (readMaybe)

#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__==708
/* code that applies only to GHC 7.8.* */
mconcat = concat
#endif
#endif

data CoeffTwo a = CF0 | CF2 (Maybe a) (Maybe a) deriving (CoeffTwo a -> CoeffTwo a -> Bool
(CoeffTwo a -> CoeffTwo a -> Bool)
-> (CoeffTwo a -> CoeffTwo a -> Bool) -> Eq (CoeffTwo a)
forall a. Eq a => CoeffTwo a -> CoeffTwo a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CoeffTwo a -> CoeffTwo a -> Bool
$c/= :: forall a. Eq a => CoeffTwo a -> CoeffTwo a -> Bool
== :: CoeffTwo a -> CoeffTwo a -> Bool
$c== :: forall a. Eq a => CoeffTwo a -> CoeffTwo a -> Bool
Eq)

isEmpty :: CoeffTwo a -> Bool
isEmpty :: CoeffTwo a -> Bool
isEmpty CoeffTwo a
CF0 = Bool
True
isEmpty CoeffTwo a
_ = Bool
False

isPair :: CoeffTwo a -> Bool
isPair :: CoeffTwo a -> Bool
isPair CoeffTwo a
CF0 = Bool
False
isPair CoeffTwo a
_ = Bool
True

fstCF :: CoeffTwo a -> Maybe a
fstCF :: CoeffTwo a -> Maybe a
fstCF (CF2 Maybe a
x Maybe a
_) = Maybe a
x
fstCF CoeffTwo a
_ = Maybe a
forall a. Maybe a
Nothing

sndCF :: CoeffTwo a -> Maybe a
sndCF :: CoeffTwo a -> Maybe a
sndCF (CF2 Maybe a
_ Maybe a
y) = Maybe a
y
sndCF CoeffTwo a
_ = Maybe a
forall a. Maybe a
Nothing

readCF :: String -> Coeffs2
readCF :: String -> Coeffs2
readCF String
xs
  | (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_') String
xs = let (!Maybe Double
ys,!Maybe Double
zs) = (\(String
ks,String
ts) -> (String -> Maybe Double
forall a. Read a => String -> Maybe a
readMaybe String
ks::Maybe Double,String -> Maybe Double
forall a. Read a => String -> Maybe a
readMaybe (Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1 String
ts)::Maybe Double)) ((String, String) -> (Maybe Double, Maybe Double))
-> (String -> (String, String))
-> String
-> (Maybe Double, Maybe Double)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_') (String -> (Maybe Double, Maybe Double))
-> String -> (Maybe Double, Maybe Double)
forall a b. (a -> b) -> a -> b
$ String
xs in
     if (Maybe Double -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Double
ys Bool -> Bool -> Bool
&& Maybe Double -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Double
zs) then Coeffs2
forall a. CoeffTwo a
CF0 else Maybe Double -> Maybe Double -> Coeffs2
forall a. Maybe a -> Maybe a -> CoeffTwo a
CF2 Maybe Double
ys Maybe Double
zs
  | Bool
otherwise = Coeffs2
forall a. CoeffTwo a
CF0

-- | A data type that is used to represent the coefficients of the rhythmicity functions as a one argument value.
type Coeffs2 = CoeffTwo Double

--------------------------------------------------------------------------------------------

eval23 :: [[Double]] -> Double
eval23 = [Double] -> Double
forall a. (RealFrac a, Floating a) => [a] -> a
evalRhythmicity23 ([Double] -> Double)
-> ([[Double]] -> [Double]) -> [[Double]] -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Double]] -> [Double]
forall a. Monoid a => [a] -> a
mconcat
{-# INLINE eval23 #-}

eval23K :: c -> c -> [[c]] -> c
eval23K c
k2 c
k3 = c -> c -> [c] -> c
forall a. (RealFrac a, Floating a) => a -> a -> [a] -> a
evalRhythmicity23K c
k2 c
k3 ([c] -> c) -> ([[c]] -> [c]) -> [[c]] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[c]] -> [c]
forall a. Monoid a => [a] -> a
mconcat
{-# INLINE eval23K #-}

eval23F :: c -> [[c]] -> c
eval23F c
k = c -> [c] -> c
forall a. (RealFrac a, Floating a) => a -> [a] -> a
evalRhythmicity23F c
k ([c] -> c) -> ([[c]] -> [c]) -> [[c]] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[c]] -> [c]
forall a. Monoid a => [a] -> a
mconcat
{-# INLINE eval23F #-}

eval23KF :: c -> c -> c -> [[c]] -> c
eval23KF c
k c
k2 c
k3 = c -> c -> c -> [c] -> c
forall a. (RealFrac a, Floating a) => a -> a -> a -> [a] -> a
evalRhythmicity23KF c
k c
k2 c
k3 ([c] -> c) -> ([[c]] -> [c]) -> [[c]] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[c]] -> [c]
forall a. Monoid a => [a] -> a
mconcat
{-# INLINE eval23KF #-}

rhythmicityG
  :: ([[[PRS]]] -> [[Double]])-- ^ A function that specifies the syllables durations, analogue of the
  -- syllableDurationsD functions from the @ukrainian-phonetics-basics-array@ package. 
  -> ([[Double]] -> Double) -- ^ Usually some kind of flattening of the double list into a single value.
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String -- ^ Corresponds to the \'0\' symbol delimiter in the @ukrainian-phonetics-basic-array@ package.
  -> String -- ^ Corresponds to the \'1\' and \'-\' symbol delimiters in the @ukrainian-phonetics-basic-array@ package.
  -> String
  -> Double
rhythmicityG :: ([[[PRS]]] -> [[Double]])
-> ([[Double]] -> Double)
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityG [[[PRS]]] -> [[Double]]
f [[Double]] -> Double
g GWritingSystemPRPLX
wrs [(Char, Char)]
ks CharPhoneticClassification
arr SegmentRulesG
hs String
us String
vs String
xs
 | String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
xs = Double
0.0
 | Bool
otherwise = [[Double]] -> Double
g ([[Double]] -> Double)
-> (String -> [[Double]]) -> String -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[[PRS]]] -> [[Double]]
f ([[[PRS]]] -> [[Double]])
-> (String -> [[[PRS]]]) -> String -> [[Double]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> [[[PRS]]]
createSyllablesPL GWritingSystemPRPLX
wrs [(Char, Char)]
ks CharPhoneticClassification
arr SegmentRulesG
hs String
us String
vs (String -> Double) -> String -> Double
forall a b. (a -> b) -> a -> b
$ String
xs
{-# INLINE rhythmicityG #-} 

-------------------------------------------------------

rhythmicity0i
  :: ([[[PRS]]] -> [[Double]]) -- ^ A function that specifies the syllables durations, analogue of the
  -- syllableDurationsD functions from the @ukrainian-phonetics-basics-array@ package. 
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String -- ^ Corresponds to the \'0\' symbol delimiter in the @ukrainian-phonetics-basic-array@ package.
  -> String -- ^ Corresponds to the \'1\' and \'-\' symbol delimiters in the @ukrainian-phonetics-basic-array@ package.
  -> String
  -> Double
rhythmicity0i :: ([[[PRS]]] -> [[Double]])
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicity0i [[[PRS]]] -> [[Double]]
f = ([[[PRS]]] -> [[Double]])
-> ([[Double]] -> Double)
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityG [[[PRS]]] -> [[Double]]
f [[Double]] -> Double
eval23 
{-# INLINE rhythmicity0i #-}

-------------------------------------------------------

rhythmicityKi
  :: ([[[PRS]]] -> [[Double]]) -- ^ A function that specifies the syllables durations, analogue of the
  -- syllableDurationsD functions from the @ukrainian-phonetics-basics-array@ package. 
  -> Double
  -> Double
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String -- ^ Corresponds to the \'0\' symbol delimiter in the @ukrainian-phonetics-basic-array@ package.
  -> String -- ^ Corresponds to the \'1\' and \'-\' symbol delimiters in the @ukrainian-phonetics-basic-array@ package.
  -> String
  -> Double
rhythmicityKi :: ([[[PRS]]] -> [[Double]])
-> Double
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityKi [[[PRS]]] -> [[Double]]
f Double
k2 Double
k3 = ([[[PRS]]] -> [[Double]])
-> ([[Double]] -> Double)
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityG [[[PRS]]] -> [[Double]]
f (Double -> Double -> [[Double]] -> Double
forall c. (RealFrac c, Floating c) => c -> c -> [[c]] -> c
eval23K Double
k2 Double
k3)
{-# INLINE rhythmicityKi #-}

--------------------------------------------------------

rhythmicity0Fi
  :: ([[[PRS]]] -> [[Double]]) -- ^ A function that specifies the syllables durations, analogue of the
  -- syllableDurationsD functions from the @ukrainian-phonetics-basics-array@ package. 
  -> Double
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String -- ^ Corresponds to the \'0\' symbol delimiter in the @ukrainian-phonetics-basic-array@ package.
  -> String -- ^ Corresponds to the \'1\' and \'-\' symbol delimiters in the @ukrainian-phonetics-basic-array@ package.
  -> String
  -> Double
rhythmicity0Fi :: ([[[PRS]]] -> [[Double]])
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicity0Fi [[[PRS]]] -> [[Double]]
f Double
k = ([[[PRS]]] -> [[Double]])
-> ([[Double]] -> Double)
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityG [[[PRS]]] -> [[Double]]
f (Double -> [[Double]] -> Double
forall c. (RealFrac c, Floating c) => c -> [[c]] -> c
eval23F Double
k)
{-# INLINE rhythmicity0Fi #-}

--------------------------------------------------------

rhythmicityKFi
  :: ([[[PRS]]] -> [[Double]]) -- ^ A function that specifies the syllables durations, analogue of the
  -- syllableDurationsD functions from the @ukrainian-phonetics-basics-array@ package. 
  -> Double
  -> Double
  -> Double
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String -- ^ Corresponds to the \'0\' symbol delimiter in the @ukrainian-phonetics-basic-array@ package.
  -> String -- ^ Corresponds to the \'1\' and \'-\' symbol delimiters in the @ukrainian-phonetics-basic-array@ package.
  -> String
  -> Double
rhythmicityKFi :: ([[[PRS]]] -> [[Double]])
-> Double
-> Double
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityKFi [[[PRS]]] -> [[Double]]
f Double
k Double
k2 Double
k3 = ([[[PRS]]] -> [[Double]])
-> ([[Double]] -> Double)
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityG [[[PRS]]] -> [[Double]]
f (Double -> Double -> Double -> [[Double]] -> Double
forall c. (RealFrac c, Floating c) => c -> c -> c -> [[c]] -> c
eval23KF Double
k Double
k2 Double
k3)
{-# INLINE rhythmicityKFi #-}

--------------------------------------------------------

-- | It is intended to provide different functions :: 'Double' -> 'String' -> ([[['PRS']]] -> [['Double']]) for at least the
-- following values: \"0z\", \"02z\", \"03z\", \"04z\", \"0y\", \"02y\", \"03y\" and the default one for other variants.
-- The \"z\"-line uses \'F\' functions. 
rhythmicity
  :: Double
  -> String -- ^ Is intended to be one of the following strings: \"02y\", \"02z\", \"03y\", \"03z\", \"04y\", \"04z\",
 -- \"0y\", \"0z\", \"y\", \"y0\", \"y2\", \"y3\", \"y4\", \"yy\", \"yy2\", \"yy3\", \"z\", \"z2\", \"z3\", \"z4\",
 -- \"zz\", \"zz2\", \"zz3\", \"zz4\" or some other one (that is the default one). Specifies the applied properties
 -- to get the result. The \"z\"-line uses \'F\' functions. 
  -> (Double -> String -> ([[[PRS]]] -> [[Double]]))-- ^ The function that is needed in the 'procRhythmicity23F' function.
 -- Specifies a way how the syllables represented in the phonetic language approach transforms into their durations and
 -- depends on two parameters.
  -> Coeffs2
  -> GWritingSystemPRPLX -- ^ Data used to obtain the phonetic language representation of the text.
  -> [(Char,Char)] -- ^ The pairs of the 'Char' that corresponds to the similar phonetic languages consonant phenomenon
  -- (e. g. allophones). Must be sorted in the ascending order to be used correctly. 
  -> CharPhoneticClassification -- ^ The 'Array' 'Int' 'PRS' must be sorted in the ascending order to be used in the module correctly.
  -> SegmentRulesG
  -> String
  -> String
  -> String
  -> Double
rhythmicity :: Double
-> String
-> (Double -> String -> [[[PRS]]] -> [[Double]])
-> Coeffs2
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicity Double
k String
choice Double -> String -> [[[PRS]]] -> [[Double]]
h Coeffs2
CF0
 | String
choice String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"0z",String
"02z",String
"03z",String
"04z"] = ([[[PRS]]] -> [[Double]])
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicity0Fi [[[PRS]]] -> [[Double]]
f Double
k
 | Bool
otherwise = ([[[PRS]]] -> [[Double]])
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicity0i [[[PRS]]] -> [[Double]]
f
     where f :: [[[PRS]]] -> [[Double]]
f = Double -> String -> [[[PRS]]] -> [[Double]]
h Double
k String
choice
rhythmicity Double
k String
choice Double -> String -> [[[PRS]]] -> [[Double]]
h (CF2 Maybe Double
x Maybe Double
y)
 | String
choice String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"0z",String
"02z",String
"03z",String
"04z"] = ([[[PRS]]] -> [[Double]])
-> Double
-> Double
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityKFi [[[PRS]]] -> [[Double]]
f Double
k (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
1.0 Maybe Double
x) (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
1.0 Maybe Double
y)
 | Bool
otherwise = ([[[PRS]]] -> [[Double]])
-> Double
-> Double
-> GWritingSystemPRPLX
-> [(Char, Char)]
-> CharPhoneticClassification
-> SegmentRulesG
-> String
-> String
-> String
-> Double
rhythmicityKi [[[PRS]]] -> [[Double]]
f (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
1.0 Maybe Double
x) (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
1.0 Maybe Double
y)
     where f :: [[[PRS]]] -> [[Double]]
f = Double -> String -> [[[PRS]]] -> [[Double]]
h Double
k String
choice