{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -funbox-strict-fields -fobject-code #-}
{-# OPTIONS_HADDOCK show-extensions #-}

{- |
Module      :  Aftovolio.General.Syllables
Copyright   :  (c) Oleksandr Zhabenko 2021-2024
License     :  MIT
Stability   :  Experimental
Maintainer  :  oleksandr.zhabenko@yahoo.com

This module works with syllable segmentation. The generalized version for the module
'Aftovolio.Ukrainian.Syllable'.
-}
module Aftovolio.General.Syllables (
    -- * Data types and type synonyms
    PRS (..),
    PhoneticPhenomenonRep,
    PhoneticType (..),
    CharPhoneticClassification,
    StringRepresentation,
    SegmentationInfo1 (..),
    SegmentationPredFunction (..),
    SegmentationPredFData (..),
    SegmentationFDP,
    Eval2Bool (..),
    DListFunctionResult,
    SegmentationLineFunction (..),
    SegmentationRules1 (..),
    SegmentRulesG,
    DListRepresentation (..),
    BasicSpaces,
    AdditionalDelimiters,

    -- * Basic functions
    str2PRSs,
    sndGroups,
    groupSnds,
    divCnsnts,
    reSyllableCntnts,
    divSylls,
    createSyllablesPL,

    -- * Auxiliary functions
    gBF4,
    findC,
    createsSyllable,
    isSonorous1,
    isVoicedC1,
    isVoicelessC1,
    notCreatesSyllable2,
    notEqC,
    fromPhoneticType,
) where

import Aftovolio.General.Base
import CaseBi.Arr
import Data.Char (isLetter)
import Data.IntermediateStructures1 (mapI)
import qualified Data.List as L (find, groupBy, intercalate, words)
import Data.Maybe (fromJust, mapMaybe)
import Data.Tuple (fst, snd)
import GHC.Arr
import GHC.Base
import GHC.Enum (fromEnum)
import GHC.Exts
import GHC.Int
import GHC.List
import GHC.Num ((-))
import Text.Read (Read (..), readMaybe)
import Text.Show (Show (..))

-- Inspired by: https://github.com/OleksandrZhabenko/mm1/releases/tag/0.2.0.0

-- CAUTION: Please, do not mix with the show7s functions, they are not interoperable.

-- | The AFTOVolio phonetic phenomenon representation. 
data PRS = SylS
    { PhoneticPhenomenonRep -> Char
charS :: {-# UNPACK #-} !Char
    -- ^ Phonetic languages phenomenon representation. Usually, a phoneme, but it can be otherwise something different.
    , PhoneticPhenomenonRep -> PhoneticType
phoneType :: {-# UNPACK #-} !PhoneticType
    -- ^ Some encoded type. For the vowels it has reserved value of 'P' 0, for the sonorous consonants - 'P' 1 and 'P' 2,
    -- for the voiced consonants - 'P' 3 and 'P' 4, for the voiceless consonants - 'P' 5 and 'P' 6. Nevertheless, it is possible to redefine the data by rewriting the
    -- respective parts of the code here.
    }
    deriving (PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
(PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool)
-> (PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool)
-> Eq PhoneticPhenomenonRep
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
== :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
$c/= :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
/= :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
Eq, ReadPrec [PhoneticPhenomenonRep]
ReadPrec PhoneticPhenomenonRep
Int -> ReadS PhoneticPhenomenonRep
ReadS [PhoneticPhenomenonRep]
(Int -> ReadS PhoneticPhenomenonRep)
-> ReadS [PhoneticPhenomenonRep]
-> ReadPrec PhoneticPhenomenonRep
-> ReadPrec [PhoneticPhenomenonRep]
-> Read PhoneticPhenomenonRep
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS PhoneticPhenomenonRep
readsPrec :: Int -> ReadS PhoneticPhenomenonRep
$creadList :: ReadS [PhoneticPhenomenonRep]
readList :: ReadS [PhoneticPhenomenonRep]
$creadPrec :: ReadPrec PhoneticPhenomenonRep
readPrec :: ReadPrec PhoneticPhenomenonRep
$creadListPrec :: ReadPrec [PhoneticPhenomenonRep]
readListPrec :: ReadPrec [PhoneticPhenomenonRep]
Read)

-- | Type synonym to be used for clarity and better code readability.
type PhoneticPhenomenonRep = PRS

instance Ord PRS where
    compare :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Ordering
compare (SylS Char
x1 PhoneticType
y1) (SylS Char
x2 PhoneticType
y2) =
        case Char -> Char -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Char
x1 Char
x2 of
            Ordering
EQ -> PhoneticType -> PhoneticType -> Ordering
forall a. Ord a => a -> a -> Ordering
compare PhoneticType
y1 PhoneticType
y2
            ~Ordering
z -> Ordering
z

instance Show PRS where
    show :: PhoneticPhenomenonRep -> String
show (SylS Char
c (P Int8
x)) = String
"SylS \'" String -> ShowS
forall a. Monoid a => a -> a -> a
`mappend` (Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: Char
'\'' Char -> ShowS
forall a. a -> [a] -> [a]
: Char
' ' Char -> ShowS
forall a. a -> [a] -> [a]
: Int8 -> String
forall a. Show a => a -> String
show Int8
x)

data PhoneticType = P {-# UNPACK #-} !Int8 deriving (PhoneticType -> PhoneticType -> Bool
(PhoneticType -> PhoneticType -> Bool)
-> (PhoneticType -> PhoneticType -> Bool) -> Eq PhoneticType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PhoneticType -> PhoneticType -> Bool
== :: PhoneticType -> PhoneticType -> Bool
$c/= :: PhoneticType -> PhoneticType -> Bool
/= :: PhoneticType -> PhoneticType -> Bool
Eq, Eq PhoneticType
Eq PhoneticType =>
(PhoneticType -> PhoneticType -> Ordering)
-> (PhoneticType -> PhoneticType -> Bool)
-> (PhoneticType -> PhoneticType -> Bool)
-> (PhoneticType -> PhoneticType -> Bool)
-> (PhoneticType -> PhoneticType -> Bool)
-> (PhoneticType -> PhoneticType -> PhoneticType)
-> (PhoneticType -> PhoneticType -> PhoneticType)
-> Ord PhoneticType
PhoneticType -> PhoneticType -> Bool
PhoneticType -> PhoneticType -> Ordering
PhoneticType -> PhoneticType -> PhoneticType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: PhoneticType -> PhoneticType -> Ordering
compare :: PhoneticType -> PhoneticType -> Ordering
$c< :: PhoneticType -> PhoneticType -> Bool
< :: PhoneticType -> PhoneticType -> Bool
$c<= :: PhoneticType -> PhoneticType -> Bool
<= :: PhoneticType -> PhoneticType -> Bool
$c> :: PhoneticType -> PhoneticType -> Bool
> :: PhoneticType -> PhoneticType -> Bool
$c>= :: PhoneticType -> PhoneticType -> Bool
>= :: PhoneticType -> PhoneticType -> Bool
$cmax :: PhoneticType -> PhoneticType -> PhoneticType
max :: PhoneticType -> PhoneticType -> PhoneticType
$cmin :: PhoneticType -> PhoneticType -> PhoneticType
min :: PhoneticType -> PhoneticType -> PhoneticType
Ord, ReadPrec [PhoneticType]
ReadPrec PhoneticType
Int -> ReadS PhoneticType
ReadS [PhoneticType]
(Int -> ReadS PhoneticType)
-> ReadS [PhoneticType]
-> ReadPrec PhoneticType
-> ReadPrec [PhoneticType]
-> Read PhoneticType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS PhoneticType
readsPrec :: Int -> ReadS PhoneticType
$creadList :: ReadS [PhoneticType]
readList :: ReadS [PhoneticType]
$creadPrec :: ReadPrec PhoneticType
readPrec :: ReadPrec PhoneticType
$creadListPrec :: ReadPrec [PhoneticType]
readListPrec :: ReadPrec [PhoneticType]
Read)

instance Show PhoneticType where
    show :: PhoneticType -> String
show (P Int8
x) = Char
'P' Char -> ShowS
forall a. a -> [a] -> [a]
: Char
' ' Char -> ShowS
forall a. a -> [a] -> [a]
: Int8 -> String
forall a. Show a => a -> String
show Int8
x

fromPhoneticType :: PhoneticType -> Int
fromPhoneticType :: PhoneticType -> Int
fromPhoneticType (P Int8
x) = Int8 -> Int
forall a. Enum a => a -> Int
fromEnum Int8
x

-- | The 'Array' 'Int' must be sorted in the ascending order to be used in the module correctly.
type CharPhoneticClassification = Array Int PhoneticPhenomenonRep

{- | The 'String' of converted phonetic language representation 'Char' data is converted to this type to apply syllable
segmentation or other transformations.
-}
type StringRepresentation = [PhoneticPhenomenonRep]

-- | Is somewhat rewritten from the 'CaseBi.Arr.gBF3' function (not exported) from the @mmsyn2-array@ package.
gBF4 ::
    (Ix i) =>
    (# Int#, PhoneticPhenomenonRep #) ->
    (# Int#, PhoneticPhenomenonRep #) ->
    Char ->
    Array i PhoneticPhenomenonRep ->
    Maybe PhoneticPhenomenonRep
gBF4 :: forall i.
Ix i =>
(# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
gBF4 (# !Int#
i#, PhoneticPhenomenonRep
k #) (# !Int#
j#, PhoneticPhenomenonRep
m #) Char
c Array i PhoneticPhenomenonRep
arrayCharClassification
    | Int# -> Bool
isTrue# ((Int#
j# Int# -> Int# -> Int#
-# Int#
i#) Int# -> Int# -> Int#
># Int#
1#) =
        case Char -> Char -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Char
c (PhoneticPhenomenonRep -> Char
charS PhoneticPhenomenonRep
p) of
            Ordering
GT -> (# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
forall i.
Ix i =>
(# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
gBF4 (# Int#
n#, PhoneticPhenomenonRep
p #) (# Int#
j#, PhoneticPhenomenonRep
m #) Char
c Array i PhoneticPhenomenonRep
arrayCharClassification
            Ordering
LT -> (# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
forall i.
Ix i =>
(# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
gBF4 (# Int#
i#, PhoneticPhenomenonRep
k #) (# Int#
n#, PhoneticPhenomenonRep
p #) Char
c Array i PhoneticPhenomenonRep
arrayCharClassification
            Ordering
_ -> PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep
forall a. a -> Maybe a
Just PhoneticPhenomenonRep
p
    | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== PhoneticPhenomenonRep -> Char
charS PhoneticPhenomenonRep
m = PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep
forall a. a -> Maybe a
Just PhoneticPhenomenonRep
m
    | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== PhoneticPhenomenonRep -> Char
charS PhoneticPhenomenonRep
k = PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep
forall a. a -> Maybe a
Just PhoneticPhenomenonRep
k
    | Bool
otherwise = Maybe PhoneticPhenomenonRep
forall a. Maybe a
Nothing
  where
    !n# :: Int#
n# = (Int#
i# Int# -> Int# -> Int#
+# Int#
j#) Int# -> Int# -> Int#
`quotInt#` Int#
2#
    !p :: PhoneticPhenomenonRep
p = Array i PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array i PhoneticPhenomenonRep
arrayCharClassification (Int# -> Int
I# Int#
n#)

findC ::
    Char ->
    Array Int PhoneticPhenomenonRep ->
    Maybe PhoneticPhenomenonRep
findC :: Char
-> Array Int PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep
findC Char
c Array Int PhoneticPhenomenonRep
arrayCharClassification = (# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array Int PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
forall i.
Ix i =>
(# Int#, PhoneticPhenomenonRep #)
-> (# Int#, PhoneticPhenomenonRep #)
-> Char
-> Array i PhoneticPhenomenonRep
-> Maybe PhoneticPhenomenonRep
gBF4 (# Int#
i#, PhoneticPhenomenonRep
k #) (# Int#
j#, PhoneticPhenomenonRep
m #) Char
c Array Int PhoneticPhenomenonRep
arrayCharClassification
  where
    !(I# Int#
i#, I# Int#
j#) = Array Int PhoneticPhenomenonRep -> (Int, Int)
forall i e. Array i e -> (i, i)
bounds Array Int PhoneticPhenomenonRep
arrayCharClassification
    !k :: PhoneticPhenomenonRep
k = Array Int PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array Int PhoneticPhenomenonRep
arrayCharClassification (Int# -> Int
I# Int#
i#)
    !m :: PhoneticPhenomenonRep
m = Array Int PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array Int PhoneticPhenomenonRep
arrayCharClassification (Int# -> Int
I# Int#
i#)
{-# INLINE findC #-}

str2PRSs :: CharPhoneticClassification -> String -> StringRepresentation
str2PRSs :: Array Int PhoneticPhenomenonRep
-> String -> [PhoneticPhenomenonRep]
str2PRSs Array Int PhoneticPhenomenonRep
arrayCharClassification = (Char -> PhoneticPhenomenonRep)
-> String -> [PhoneticPhenomenonRep]
forall a b. (a -> b) -> [a] -> [b]
map (\Char
c -> Maybe PhoneticPhenomenonRep -> PhoneticPhenomenonRep
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe PhoneticPhenomenonRep -> PhoneticPhenomenonRep)
-> (Array Int PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep)
-> Array Int PhoneticPhenomenonRep
-> PhoneticPhenomenonRep
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char
-> Array Int PhoneticPhenomenonRep -> Maybe PhoneticPhenomenonRep
findC Char
c (Array Int PhoneticPhenomenonRep -> PhoneticPhenomenonRep)
-> Array Int PhoneticPhenomenonRep -> PhoneticPhenomenonRep
forall a b. (a -> b) -> a -> b
$ Array Int PhoneticPhenomenonRep
arrayCharClassification)
{-# INLINE str2PRSs #-}

{- | Function-predicate 'createsSyllable' checks whether its argument is a phoneme representation that
every time being presented in the text leads to the creation of the new syllable (in the 'PhoneticPhenomenonRep' format).
Usually it is a vowel, but in some languages there can be syllabic phonemes that are not considered to be
vowels.
-}
createsSyllable :: PhoneticPhenomenonRep -> Bool
createsSyllable :: PhoneticPhenomenonRep -> Bool
createsSyllable = (PhoneticType -> PhoneticType -> Bool
forall a. Eq a => a -> a -> Bool
== Int8 -> PhoneticType
P Int8
0) (PhoneticType -> Bool)
-> (PhoneticPhenomenonRep -> PhoneticType)
-> PhoneticPhenomenonRep
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticPhenomenonRep -> PhoneticType
phoneType
{-# INLINE createsSyllable #-}

-- | Function-predicate 'isSonorous1' checks whether its argument is a sonorous consonant representation in the 'PhoneticPhenomenonRep' format.
isSonorous1 :: PhoneticPhenomenonRep -> Bool
isSonorous1 :: PhoneticPhenomenonRep -> Bool
isSonorous1 = (Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` [Int
1, Int
2]) (Int -> Bool)
-> (PhoneticPhenomenonRep -> Int) -> PhoneticPhenomenonRep -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticType -> Int
fromPhoneticType (PhoneticType -> Int)
-> (PhoneticPhenomenonRep -> PhoneticType)
-> PhoneticPhenomenonRep
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticPhenomenonRep -> PhoneticType
phoneType
{-# INLINE isSonorous1 #-}

-- | Function-predicate 'isVoicedC1' checks whether its argument is a voiced consonant representation in the 'PhoneticPhenomenonRep' format.
isVoicedC1 :: PhoneticPhenomenonRep -> Bool
isVoicedC1 :: PhoneticPhenomenonRep -> Bool
isVoicedC1 = (Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` [Int
3, Int
4]) (Int -> Bool)
-> (PhoneticPhenomenonRep -> Int) -> PhoneticPhenomenonRep -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticType -> Int
fromPhoneticType (PhoneticType -> Int)
-> (PhoneticPhenomenonRep -> PhoneticType)
-> PhoneticPhenomenonRep
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticPhenomenonRep -> PhoneticType
phoneType
{-# INLINE isVoicedC1 #-}

-- | Function-predicate 'isVoiceless1' checks whether its argument is a voiceless consonant representation in the 'PhoneticPhenomenonRep' format.
isVoicelessC1 :: PhoneticPhenomenonRep -> Bool
isVoicelessC1 :: PhoneticPhenomenonRep -> Bool
isVoicelessC1 = (Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` [Int
5, Int
6]) (Int -> Bool)
-> (PhoneticPhenomenonRep -> Int) -> PhoneticPhenomenonRep -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticType -> Int
fromPhoneticType (PhoneticType -> Int)
-> (PhoneticPhenomenonRep -> PhoneticType)
-> PhoneticPhenomenonRep
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticPhenomenonRep -> PhoneticType
phoneType
{-# INLINE isVoicelessC1 #-}

-- | Binary function-predicate 'notCreatesSyllable2' checks whether its arguments are both consonant representations in the 'PhoneticPhenomenonRep' format.
notCreatesSyllable2 :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
notCreatesSyllable2 :: PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
notCreatesSyllable2 PhoneticPhenomenonRep
x PhoneticPhenomenonRep
y
    | PhoneticPhenomenonRep -> PhoneticType
phoneType PhoneticPhenomenonRep
x PhoneticType -> PhoneticType -> Bool
forall a. Eq a => a -> a -> Bool
== Int8 -> PhoneticType
P Int8
0 Bool -> Bool -> Bool
|| PhoneticPhenomenonRep -> PhoneticType
phoneType PhoneticPhenomenonRep
y PhoneticType -> PhoneticType -> Bool
forall a. Eq a => a -> a -> Bool
== Int8 -> PhoneticType
P Int8
0 = Bool
False
    | Bool
otherwise = Bool
True
{-# INLINE notCreatesSyllable2 #-}

-- | Binary function-predicate 'notEqC' checks whether its arguments are not the same consonant sound representations (not taking palatalization into account).
notEqC ::
    -- | 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.
    [(Char, Char)] ->
    PhoneticPhenomenonRep ->
    PhoneticPhenomenonRep ->
    Bool
notEqC :: [(Char, Char)]
-> PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
notEqC [(Char, Char)]
xs PhoneticPhenomenonRep
x PhoneticPhenomenonRep
y
    | (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
cy) (Char -> Bool) -> (Char -> Char) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> [(Char, Char)] -> Char -> Char
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' Char
cx [(Char, Char)]
xs (Char -> Bool) -> Char -> Bool
forall a b. (a -> b) -> a -> b
$ Char
cx = Bool
False
    | Bool
otherwise = Char
cx Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
cy
  where
    !cx :: Char
cx = PhoneticPhenomenonRep -> Char
charS PhoneticPhenomenonRep
x
    !cy :: Char
cy = PhoneticPhenomenonRep -> Char
charS PhoneticPhenomenonRep
y
{-# INLINE notEqC #-}

{- | Function 'sndGroups' converts a word being a list of 'PhoneticPhenomenonRep' to the list of phonetically similar (consonants grouped with consonants and each vowel separately)
sounds representations in 'PhoneticPhenomenonRep' format.
-}
sndGroups :: [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
sndGroups :: [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
sndGroups ys :: [PhoneticPhenomenonRep]
ys@(PhoneticPhenomenonRep
_ : [PhoneticPhenomenonRep]
_) = (PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool)
-> [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
L.groupBy PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
notCreatesSyllable2 [PhoneticPhenomenonRep]
ys
sndGroups [PhoneticPhenomenonRep]
_ = []
{-# INLINE sndGroups #-}

groupSnds :: [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
groupSnds :: [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
groupSnds = (PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool)
-> [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
L.groupBy (\PhoneticPhenomenonRep
x PhoneticPhenomenonRep
y -> PhoneticPhenomenonRep -> Bool
createsSyllable PhoneticPhenomenonRep
x Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== PhoneticPhenomenonRep -> Bool
createsSyllable PhoneticPhenomenonRep
y)
{-# INLINE groupSnds #-}

data SegmentationInfo1 = SI
    { SegmentationInfo1 -> Int8
fieldN :: !Int8
    -- ^ Number of fields in the pattern matching that are needed to apply the segmentation rules. Not less than 1.
    , SegmentationInfo1 -> Int8
predicateN :: Int8
    -- ^ Number of predicates in the definition for the 'fieldN' that are needed to apply the segmentation rules.
    }
    deriving (SegmentationInfo1 -> SegmentationInfo1 -> Bool
(SegmentationInfo1 -> SegmentationInfo1 -> Bool)
-> (SegmentationInfo1 -> SegmentationInfo1 -> Bool)
-> Eq SegmentationInfo1
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SegmentationInfo1 -> SegmentationInfo1 -> Bool
== :: SegmentationInfo1 -> SegmentationInfo1 -> Bool
$c/= :: SegmentationInfo1 -> SegmentationInfo1 -> Bool
/= :: SegmentationInfo1 -> SegmentationInfo1 -> Bool
Eq, ReadPrec [SegmentationInfo1]
ReadPrec SegmentationInfo1
Int -> ReadS SegmentationInfo1
ReadS [SegmentationInfo1]
(Int -> ReadS SegmentationInfo1)
-> ReadS [SegmentationInfo1]
-> ReadPrec SegmentationInfo1
-> ReadPrec [SegmentationInfo1]
-> Read SegmentationInfo1
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SegmentationInfo1
readsPrec :: Int -> ReadS SegmentationInfo1
$creadList :: ReadS [SegmentationInfo1]
readList :: ReadS [SegmentationInfo1]
$creadPrec :: ReadPrec SegmentationInfo1
readPrec :: ReadPrec SegmentationInfo1
$creadListPrec :: ReadPrec [SegmentationInfo1]
readListPrec :: ReadPrec [SegmentationInfo1]
Read, Int -> SegmentationInfo1 -> ShowS
[SegmentationInfo1] -> ShowS
SegmentationInfo1 -> String
(Int -> SegmentationInfo1 -> ShowS)
-> (SegmentationInfo1 -> String)
-> ([SegmentationInfo1] -> ShowS)
-> Show SegmentationInfo1
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SegmentationInfo1 -> ShowS
showsPrec :: Int -> SegmentationInfo1 -> ShowS
$cshow :: SegmentationInfo1 -> String
show :: SegmentationInfo1 -> String
$cshowList :: [SegmentationInfo1] -> ShowS
showList :: [SegmentationInfo1] -> ShowS
Show)

instance PhoneticElement SegmentationInfo1 where
    readPEMaybe :: String -> Maybe SegmentationInfo1
readPEMaybe String
rs
        | Bool -> Bool
not (Bool -> Bool) -> (String -> Bool) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> Bool
forall a. (a -> Bool) -> [a] -> Bool
any Char -> Bool
isLetter (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String
rs = Maybe SegmentationInfo1
forall a. Maybe a
Nothing
        | Bool
otherwise =
            let (String
ys : [String]
yss) = String -> [String]
L.words String
rs
             in case String
ys of
                    String
"SI" -> case [String]
yss of
                        [String
xs, String
ts] -> case (String -> Maybe Int8
forall a. Read a => String -> Maybe a
readMaybe String
xs :: Maybe Int8) of
                            Just Int8
m -> case (String -> Maybe Int8
forall a. Read a => String -> Maybe a
readMaybe String
ts :: Maybe Int8) of
                                Just Int8
n -> SegmentationInfo1 -> Maybe SegmentationInfo1
forall a. a -> Maybe a
Just (Int8 -> Int8 -> SegmentationInfo1
SI Int8
m Int8
n)
                                Maybe Int8
_ -> Maybe SegmentationInfo1
forall a. Maybe a
Nothing
                            Maybe Int8
_ -> Maybe SegmentationInfo1
forall a. Maybe a
Nothing
                        [String]
_ -> Maybe SegmentationInfo1
forall a. Maybe a
Nothing
                    String
_ -> Maybe SegmentationInfo1
forall a. Maybe a
Nothing

{- | We can think of 'SegmentationPredFunction' in terms of @f ('SI' fN pN) ks [x_{1},x_{2},...,x_{i},...,x_{fN}]@. Comparing with
'divCnsnts' from the 'Aftovolio.Ukrainian.Syllable' we can postulate that it consists of the following logical terms in
the symbolic form:

1) 'phoneType' x_{i} \`'elem'\` (X{...} = 'map' 'P' ['Int8'])

2) 'notEqC' ks x_{i} x_{j} (j /= i)

combined with the standard logic Boolean operations of '(&&)', '(||)' and 'not'. Further, the 'not' can be transformed into the
positive (affirmative) form using the notion of the universal set for the task. This transformation needs that the similar
phonetic phenomenae (e. g. the double sounds -- the prolonged ones) belong to the one syllable and not to the different ones
(so they are not related to different syllables, but just to the one and the same). Since such assumption has been used,
we can further represent the function by the following data type and operations with it, see 'SegmentationPredFData'.
-}
data SegmentationPredFunction
    = PF (SegmentationInfo1 -> [(Char, Char)] -> [PhoneticPhenomenonRep] -> Bool)

data SegmentationPredFData a b
    = L Int [Int] (Array Int a)
    | NEC Int Int (Array Int a) [b]
    | C (SegmentationPredFData a b) (SegmentationPredFData a b)
    | D (SegmentationPredFData a b) (SegmentationPredFData a b)
    deriving (SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
(SegmentationPredFData a b -> SegmentationPredFData a b -> Bool)
-> (SegmentationPredFData a b -> SegmentationPredFData a b -> Bool)
-> Eq (SegmentationPredFData a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b.
(Eq a, Eq b) =>
SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
$c== :: forall a b.
(Eq a, Eq b) =>
SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
== :: SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
$c/= :: forall a b.
(Eq a, Eq b) =>
SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
/= :: SegmentationPredFData a b -> SegmentationPredFData a b -> Bool
Eq, ReadPrec [SegmentationPredFData a b]
ReadPrec (SegmentationPredFData a b)
Int -> ReadS (SegmentationPredFData a b)
ReadS [SegmentationPredFData a b]
(Int -> ReadS (SegmentationPredFData a b))
-> ReadS [SegmentationPredFData a b]
-> ReadPrec (SegmentationPredFData a b)
-> ReadPrec [SegmentationPredFData a b]
-> Read (SegmentationPredFData a b)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall a b.
(Read a, Read b) =>
ReadPrec [SegmentationPredFData a b]
forall a b.
(Read a, Read b) =>
ReadPrec (SegmentationPredFData a b)
forall a b.
(Read a, Read b) =>
Int -> ReadS (SegmentationPredFData a b)
forall a b. (Read a, Read b) => ReadS [SegmentationPredFData a b]
$creadsPrec :: forall a b.
(Read a, Read b) =>
Int -> ReadS (SegmentationPredFData a b)
readsPrec :: Int -> ReadS (SegmentationPredFData a b)
$creadList :: forall a b. (Read a, Read b) => ReadS [SegmentationPredFData a b]
readList :: ReadS [SegmentationPredFData a b]
$creadPrec :: forall a b.
(Read a, Read b) =>
ReadPrec (SegmentationPredFData a b)
readPrec :: ReadPrec (SegmentationPredFData a b)
$creadListPrec :: forall a b.
(Read a, Read b) =>
ReadPrec [SegmentationPredFData a b]
readListPrec :: ReadPrec [SegmentationPredFData a b]
Read, Int -> SegmentationPredFData a b -> ShowS
[SegmentationPredFData a b] -> ShowS
SegmentationPredFData a b -> String
(Int -> SegmentationPredFData a b -> ShowS)
-> (SegmentationPredFData a b -> String)
-> ([SegmentationPredFData a b] -> ShowS)
-> Show (SegmentationPredFData a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b.
(Show a, Show b) =>
Int -> SegmentationPredFData a b -> ShowS
forall a b.
(Show a, Show b) =>
[SegmentationPredFData a b] -> ShowS
forall a b. (Show a, Show b) => SegmentationPredFData a b -> String
$cshowsPrec :: forall a b.
(Show a, Show b) =>
Int -> SegmentationPredFData a b -> ShowS
showsPrec :: Int -> SegmentationPredFData a b -> ShowS
$cshow :: forall a b. (Show a, Show b) => SegmentationPredFData a b -> String
show :: SegmentationPredFData a b -> String
$cshowList :: forall a b.
(Show a, Show b) =>
[SegmentationPredFData a b] -> ShowS
showList :: [SegmentationPredFData a b] -> ShowS
Show)

class Eval2Bool a where
    eval2Bool :: a -> Bool

type SegmentationFDP = SegmentationPredFData PhoneticPhenomenonRep (Char, Char)

instance Eval2Bool (SegmentationPredFData PhoneticPhenomenonRep (Char, Char)) where
    eval2Bool :: SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
eval2Bool (L Int
i [Int]
js Array Int PhoneticPhenomenonRep
arrayCharClassification)
        | (Int -> Bool) -> [Int] -> Bool
forall a. (a -> Bool) -> [a] -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n) [Int]
js Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1 Bool -> Bool -> Bool
&& (Int -> Bool) -> [Int] -> Bool
forall a. (a -> Bool) -> [a] -> Bool
all (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1) [Int]
js =
            PhoneticType -> Int
fromPhoneticType (PhoneticPhenomenonRep -> PhoneticType
phoneType (Array Int PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array Int PhoneticPhenomenonRep
arrayCharClassification (Int -> PhoneticPhenomenonRep) -> Int -> PhoneticPhenomenonRep
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` [Int]
js
        | Bool
otherwise =
            String -> Bool
forall a. HasCallStack => String -> a
error
                String
"Aftovolio.General.Syllables.eval2Bool: 'L' element is not properly defined. "
      where
        n :: Int
n = Array Int PhoneticPhenomenonRep -> Int
forall i e. Array i e -> Int
numElements Array Int PhoneticPhenomenonRep
arrayCharClassification
    eval2Bool (NEC Int
i Int
j Array Int PhoneticPhenomenonRep
arrayCharClassification [(Char, Char)]
allophones)
        | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1 Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
1 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
j Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n =
            [(Char, Char)]
-> PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool
notEqC [(Char, Char)]
allophones (Array Int PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array Int PhoneticPhenomenonRep
arrayCharClassification (Int -> PhoneticPhenomenonRep) -> Int -> PhoneticPhenomenonRep
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (Array Int PhoneticPhenomenonRep -> Int -> PhoneticPhenomenonRep
forall i e. Array i e -> Int -> e
unsafeAt Array Int PhoneticPhenomenonRep
arrayCharClassification (Int -> PhoneticPhenomenonRep) -> Int -> PhoneticPhenomenonRep
forall a b. (a -> b) -> a -> b
$ Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
        | Bool
otherwise =
            String -> Bool
forall a. HasCallStack => String -> a
error
                String
"Aftovolio.General.Syllables.eval2Bool: 'NEC' element is not properly defined. "
      where
        n :: Int
n = Array Int PhoneticPhenomenonRep -> Int
forall i e. Array i e -> Int
numElements Array Int PhoneticPhenomenonRep
arrayCharClassification
    eval2Bool (C SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
x SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
y) = SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
forall a. Eval2Bool a => a -> Bool
eval2Bool SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
x Bool -> Bool -> Bool
&& SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
forall a. Eval2Bool a => a -> Bool
eval2Bool SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
y
    eval2Bool (D SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
x SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
y) = SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
forall a. Eval2Bool a => a -> Bool
eval2Bool SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
x Bool -> Bool -> Bool
|| SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
forall a. Eval2Bool a => a -> Bool
eval2Bool SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
y

type DListFunctionResult = ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep], [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])

class DListRepresentation a b where
    toDLR :: b -> [a] -> ([a] -> [a], [a] -> [a])

instance DListRepresentation PhoneticPhenomenonRep Int8 where
    toDLR :: Int8
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
    [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
toDLR Int8
left [PhoneticPhenomenonRep]
xs
        | [PhoneticPhenomenonRep] -> Bool
forall a. [a] -> Bool
null [PhoneticPhenomenonRep]
xs = ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id, [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id)
        | [PhoneticPhenomenonRep] -> Bool
forall a. [a] -> Bool
null [PhoneticPhenomenonRep]
ts = ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id, ([PhoneticPhenomenonRep]
zs [PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend`))
        | [PhoneticPhenomenonRep] -> Bool
forall a. [a] -> Bool
null [PhoneticPhenomenonRep]
zs = (([PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend` [PhoneticPhenomenonRep]
ts), [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id)
        | Bool
otherwise = (([PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend` [PhoneticPhenomenonRep]
ts), ([PhoneticPhenomenonRep]
zs [PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend`))
      where
        ([PhoneticPhenomenonRep]
ts, [PhoneticPhenomenonRep]
zs) = Int
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep], [PhoneticPhenomenonRep])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int8 -> Int
forall a. Enum a => a -> Int
fromEnum Int8
left) [PhoneticPhenomenonRep]
xs

data SegmentationLineFunction = LFS
    { SegmentationLineFunction -> SegmentationInfo1
infoSP :: SegmentationInfo1
    , SegmentationLineFunction
-> SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
predF :: SegmentationFDP
    -- ^ The predicate to check the needed rule for segmentation.
    , SegmentationLineFunction -> Int8
resF :: Int8
    -- ^ The result argument to be appended to the left of the group of consonants if the 'predF' returns 'True' for its arguments. Is an argument to the 'toDLR'.
    }
    deriving (ReadPrec [SegmentationLineFunction]
ReadPrec SegmentationLineFunction
Int -> ReadS SegmentationLineFunction
ReadS [SegmentationLineFunction]
(Int -> ReadS SegmentationLineFunction)
-> ReadS [SegmentationLineFunction]
-> ReadPrec SegmentationLineFunction
-> ReadPrec [SegmentationLineFunction]
-> Read SegmentationLineFunction
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SegmentationLineFunction
readsPrec :: Int -> ReadS SegmentationLineFunction
$creadList :: ReadS [SegmentationLineFunction]
readList :: ReadS [SegmentationLineFunction]
$creadPrec :: ReadPrec SegmentationLineFunction
readPrec :: ReadPrec SegmentationLineFunction
$creadListPrec :: ReadPrec [SegmentationLineFunction]
readListPrec :: ReadPrec [SegmentationLineFunction]
Read, Int -> SegmentationLineFunction -> ShowS
[SegmentationLineFunction] -> ShowS
SegmentationLineFunction -> String
(Int -> SegmentationLineFunction -> ShowS)
-> (SegmentationLineFunction -> String)
-> ([SegmentationLineFunction] -> ShowS)
-> Show SegmentationLineFunction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SegmentationLineFunction -> ShowS
showsPrec :: Int -> SegmentationLineFunction -> ShowS
$cshow :: SegmentationLineFunction -> String
show :: SegmentationLineFunction -> String
$cshowList :: [SegmentationLineFunction] -> ShowS
showList :: [SegmentationLineFunction] -> ShowS
Show)

data SegmentationRules1 = SR1
    { SegmentationRules1 -> SegmentationInfo1
infoS :: SegmentationInfo1
    , SegmentationRules1 -> [SegmentationLineFunction]
lineFs :: [SegmentationLineFunction]
    -- ^ The list must be sorted in the appropriate order of the guards usage for the predicates.
    -- The length of the list must be equal to the ('fromEnum' . 'predicateN' . 'infoS') value.
    }
    deriving (ReadPrec [SegmentationRules1]
ReadPrec SegmentationRules1
Int -> ReadS SegmentationRules1
ReadS [SegmentationRules1]
(Int -> ReadS SegmentationRules1)
-> ReadS [SegmentationRules1]
-> ReadPrec SegmentationRules1
-> ReadPrec [SegmentationRules1]
-> Read SegmentationRules1
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SegmentationRules1
readsPrec :: Int -> ReadS SegmentationRules1
$creadList :: ReadS [SegmentationRules1]
readList :: ReadS [SegmentationRules1]
$creadPrec :: ReadPrec SegmentationRules1
readPrec :: ReadPrec SegmentationRules1
$creadListPrec :: ReadPrec [SegmentationRules1]
readListPrec :: ReadPrec [SegmentationRules1]
Read, Int -> SegmentationRules1 -> ShowS
[SegmentationRules1] -> ShowS
SegmentationRules1 -> String
(Int -> SegmentationRules1 -> ShowS)
-> (SegmentationRules1 -> String)
-> ([SegmentationRules1] -> ShowS)
-> Show SegmentationRules1
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SegmentationRules1 -> ShowS
showsPrec :: Int -> SegmentationRules1 -> ShowS
$cshow :: SegmentationRules1 -> String
show :: SegmentationRules1 -> String
$cshowList :: [SegmentationRules1] -> ShowS
showList :: [SegmentationRules1] -> ShowS
Show)

{- | List of the 'SegmentationRules1' sorted in the descending order by the 'fieldN' 'SegmentationInfo1' data and where the
length of all the 'SegmentationPredFunction' lists of 'PhoneticPhenomenonRep' are equal to the 'fieldN' 'SegmentationInfo1' data by definition.
-}
type SegmentRulesG = [SegmentationRules1]

{- | Function 'divCnsnts' is used to divide groups of consonants into two-elements lists that later are made belonging to
different neighbour syllables if the group is between two vowels in a word. The group must be not empty, but this is not checked.
The example phonetical information for the proper performance in Ukrainian can be found from the:
https://msn.khnu.km.ua/pluginfile.php/302375/mod_resource/content/1/%D0%9B.3.%D0%86%D0%86.%20%D0%A1%D0%BA%D0%BB%D0%B0%D0%B4.%D0%9D%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D1%81.pdf
The example of the 'divCnsnts' can be found at: https://hackage.haskell.org/package/aftovolio-0.6.2.0/docs/Aftovolio-Ukrainian-Syllable.html#v:divCnsnts
-}
divCnsnts ::
    -- | 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.
    [(Char, Char)] ->
    SegmentRulesG ->
    [PhoneticPhenomenonRep] ->
    DListFunctionResult
divCnsnts :: [(Char, Char)]
-> [SegmentationRules1]
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
    [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
divCnsnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules xs :: [PhoneticPhenomenonRep]
xs@(PhoneticPhenomenonRep
_ : [PhoneticPhenomenonRep]
_) = Int8
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
    [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
forall a b.
DListRepresentation a b =>
b -> [a] -> ([a] -> [a], [a] -> [a])
toDLR Int8
left [PhoneticPhenomenonRep]
xs
  where
    !js :: SegmentationRules1
js = Maybe SegmentationRules1 -> SegmentationRules1
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe SegmentationRules1 -> SegmentationRules1)
-> ([SegmentationRules1] -> Maybe SegmentationRules1)
-> [SegmentationRules1]
-> SegmentationRules1
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SegmentationRules1 -> Bool)
-> [SegmentationRules1] -> Maybe SegmentationRules1
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find ((Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [PhoneticPhenomenonRep] -> Int
forall a. [a] -> Int
length [PhoneticPhenomenonRep]
xs) (Int -> Bool)
-> (SegmentationRules1 -> Int) -> SegmentationRules1 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int8 -> Int
forall a. Enum a => a -> Int
fromEnum (Int8 -> Int)
-> (SegmentationRules1 -> Int8) -> SegmentationRules1 -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SegmentationInfo1 -> Int8
fieldN (SegmentationInfo1 -> Int8)
-> (SegmentationRules1 -> SegmentationInfo1)
-> SegmentationRules1
-> Int8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SegmentationRules1 -> SegmentationInfo1
infoS) ([SegmentationRules1] -> SegmentationRules1)
-> [SegmentationRules1] -> SegmentationRules1
forall a b. (a -> b) -> a -> b
$ [SegmentationRules1]
segmentRules -- js :: SegmentationRules1
    !left :: Int8
left = SegmentationLineFunction -> Int8
resF (SegmentationLineFunction -> Int8)
-> (SegmentationRules1 -> SegmentationLineFunction)
-> SegmentationRules1
-> Int8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe SegmentationLineFunction -> SegmentationLineFunction
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe SegmentationLineFunction -> SegmentationLineFunction)
-> (SegmentationRules1 -> Maybe SegmentationLineFunction)
-> SegmentationRules1
-> SegmentationLineFunction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SegmentationLineFunction -> Bool)
-> [SegmentationLineFunction] -> Maybe SegmentationLineFunction
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool
forall a. Eval2Bool a => a -> Bool
eval2Bool (SegmentationPredFData PhoneticPhenomenonRep (Char, Char) -> Bool)
-> (SegmentationLineFunction
    -> SegmentationPredFData PhoneticPhenomenonRep (Char, Char))
-> SegmentationLineFunction
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SegmentationLineFunction
-> SegmentationPredFData PhoneticPhenomenonRep (Char, Char)
predF) ([SegmentationLineFunction] -> Maybe SegmentationLineFunction)
-> (SegmentationRules1 -> [SegmentationLineFunction])
-> SegmentationRules1
-> Maybe SegmentationLineFunction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SegmentationRules1 -> [SegmentationLineFunction]
lineFs (SegmentationRules1 -> Int8) -> SegmentationRules1 -> Int8
forall a b. (a -> b) -> a -> b
$ SegmentationRules1
js
divCnsnts [(Char, Char)]
_ [SegmentationRules1]
_ [] = ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id, [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. a -> a
id)

reSyllableCntnts ::
    -- | 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.
    [(Char, Char)] ->
    SegmentRulesG ->
    [[PhoneticPhenomenonRep]] ->
    [[PhoneticPhenomenonRep]]
reSyllableCntnts :: [(Char, Char)]
-> [SegmentationRules1]
-> [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]]
reSyllableCntnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules ([PhoneticPhenomenonRep]
xs : [PhoneticPhenomenonRep]
ys : [PhoneticPhenomenonRep]
zs : [[PhoneticPhenomenonRep]]
xss)
    | (PhoneticType -> PhoneticType -> Bool
forall a. Eq a => a -> a -> Bool
/= Int8 -> PhoneticType
P Int8
0) (PhoneticType -> Bool)
-> ([PhoneticPhenomenonRep] -> PhoneticType)
-> [PhoneticPhenomenonRep]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PhoneticPhenomenonRep -> PhoneticType
phoneType (PhoneticPhenomenonRep -> PhoneticType)
-> ([PhoneticPhenomenonRep] -> PhoneticPhenomenonRep)
-> [PhoneticPhenomenonRep]
-> PhoneticType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PhoneticPhenomenonRep] -> PhoneticPhenomenonRep
forall a. HasCallStack => [a] -> a
last ([PhoneticPhenomenonRep] -> Bool)
-> [PhoneticPhenomenonRep] -> Bool
forall a b. (a -> b) -> a -> b
$ [PhoneticPhenomenonRep]
ys =
        ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
 [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a b. (a, b) -> a
fst ([(Char, Char)]
-> [SegmentationRules1]
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
    [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
divCnsnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules [PhoneticPhenomenonRep]
ys) [PhoneticPhenomenonRep]
xs
            [PhoneticPhenomenonRep]
-> [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
forall a. a -> [a] -> [a]
: [(Char, Char)]
-> [SegmentationRules1]
-> [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]]
reSyllableCntnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules (([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
 [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a b. (a, b) -> b
snd ([(Char, Char)]
-> [SegmentationRules1]
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep],
    [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
divCnsnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules [PhoneticPhenomenonRep]
ys) [PhoneticPhenomenonRep]
zs [PhoneticPhenomenonRep]
-> [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
forall a. a -> [a] -> [a]
: [[PhoneticPhenomenonRep]]
xss)
    | Bool
otherwise = [(Char, Char)]
-> [SegmentationRules1]
-> [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]]
reSyllableCntnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules (([PhoneticPhenomenonRep]
xs [PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend` [PhoneticPhenomenonRep]
ys) [PhoneticPhenomenonRep]
-> [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
forall a. a -> [a] -> [a]
: [PhoneticPhenomenonRep]
zs [PhoneticPhenomenonRep]
-> [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
forall a. a -> [a] -> [a]
: [[PhoneticPhenomenonRep]]
xss)
reSyllableCntnts [(Char, Char)]
_ [SegmentationRules1]
_ ([PhoneticPhenomenonRep]
xs : [PhoneticPhenomenonRep]
ys : [[PhoneticPhenomenonRep]]
_) = [([PhoneticPhenomenonRep]
xs [PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend` [PhoneticPhenomenonRep]
ys)]
reSyllableCntnts [(Char, Char)]
_ [SegmentationRules1]
_ [[PhoneticPhenomenonRep]]
xss = [[PhoneticPhenomenonRep]]
xss

divSylls :: [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
divSylls :: [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
divSylls = ([PhoneticPhenomenonRep] -> Bool)
-> ([PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]])
-> [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]]
forall a. (a -> Bool) -> (a -> [a]) -> [a] -> [a]
mapI (\[PhoneticPhenomenonRep]
ws -> ([PhoneticPhenomenonRep] -> Int
forall a. [a] -> Int
length ([PhoneticPhenomenonRep] -> Int)
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
-> [PhoneticPhenomenonRep]
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PhoneticPhenomenonRep -> Bool)
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. (a -> Bool) -> [a] -> [a]
filter PhoneticPhenomenonRep -> Bool
createsSyllable ([PhoneticPhenomenonRep] -> Int) -> [PhoneticPhenomenonRep] -> Int
forall a b. (a -> b) -> a -> b
$ [PhoneticPhenomenonRep]
ws) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
h3
  where
    h3 :: [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
h3 [PhoneticPhenomenonRep]
us =
        [[PhoneticPhenomenonRep]
ys [PhoneticPhenomenonRep]
-> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Monoid a => a -> a -> a
`mappend` Int -> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Int -> [a] -> [a]
take Int
1 [PhoneticPhenomenonRep]
zs]
            [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
forall a. Monoid a => a -> a -> a
`mappend` ((PhoneticPhenomenonRep -> PhoneticPhenomenonRep -> Bool)
-> [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
L.groupBy (\PhoneticPhenomenonRep
x PhoneticPhenomenonRep
y -> PhoneticPhenomenonRep -> Bool
createsSyllable PhoneticPhenomenonRep
x Bool -> Bool -> Bool
&& PhoneticPhenomenonRep -> PhoneticType
phoneType PhoneticPhenomenonRep
y PhoneticType -> PhoneticType -> Bool
forall a. Eq a => a -> a -> Bool
/= Int8 -> PhoneticType
P Int8
0) ([PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]])
-> ([PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep])
-> [PhoneticPhenomenonRep]
-> [[PhoneticPhenomenonRep]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [PhoneticPhenomenonRep] -> [PhoneticPhenomenonRep]
forall a. Int -> [a] -> [a]
drop Int
1 ([PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]])
-> [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
forall a b. (a -> b) -> a -> b
$ [PhoneticPhenomenonRep]
zs)
      where
        ([PhoneticPhenomenonRep]
ys, [PhoneticPhenomenonRep]
zs) = (PhoneticPhenomenonRep -> Bool)
-> [PhoneticPhenomenonRep]
-> ([PhoneticPhenomenonRep], [PhoneticPhenomenonRep])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break PhoneticPhenomenonRep -> Bool
createsSyllable [PhoneticPhenomenonRep]
us

-- | Basic group of delimiters in the 'String' that are not converted to the phonemes or not silent sounds. Silent sounds or their absense, e. g. word gaps.
type BasicSpaces = String

-- | Is used for additional delimiters that are not included in the 'BasicSpaces' group for some reason.
type AdditionalDelimiters = String

{- | The function actually creates syllables using the provided data. Each resulting inner-most list is a phonetic language representation
of the syllable according to the rules provided.
-}
createSyllablesPL ::
    -- | Data used to obtain the phonetic language representation of the text.
    GWritingSystemPRPLX ->
    -- | 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.
    [(Char, Char)] ->
    CharPhoneticClassification ->
    SegmentRulesG ->
    -- | Corresponds to the 100 delimiter in the @ukrainian-phonetics-basic-array@ package.
    BasicSpaces ->
    -- | Corresponds to the 101 delimiter in the @ukrainian-phonetics-basic-array@ package.
    AdditionalDelimiters ->
    -- | Actually the converted 'String'.
    String ->
    [[[PhoneticPhenomenonRep]]]
createSyllablesPL :: GWritingSystemPRPLX
-> [(Char, Char)]
-> Array Int PhoneticPhenomenonRep
-> [SegmentationRules1]
-> String
-> String
-> String
-> [[[PhoneticPhenomenonRep]]]
createSyllablesPL GWritingSystemPRPLX
writingSystem [(Char, Char)]
allophones Array Int PhoneticPhenomenonRep
arrayCharClassification [SegmentationRules1]
segmentRules String
basicSpaces String
additionalDelims =
    (String -> [[PhoneticPhenomenonRep]])
-> [String] -> [[[PhoneticPhenomenonRep]]]
forall a b. (a -> b) -> [a] -> [b]
map ([[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]]
divSylls ([[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]])
-> (String -> [[PhoneticPhenomenonRep]])
-> String
-> [[PhoneticPhenomenonRep]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Char, Char)]
-> [SegmentationRules1]
-> [[PhoneticPhenomenonRep]]
-> [[PhoneticPhenomenonRep]]
reSyllableCntnts [(Char, Char)]
allophones [SegmentationRules1]
segmentRules ([[PhoneticPhenomenonRep]] -> [[PhoneticPhenomenonRep]])
-> (String -> [[PhoneticPhenomenonRep]])
-> String
-> [[PhoneticPhenomenonRep]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]]
groupSnds ([PhoneticPhenomenonRep] -> [[PhoneticPhenomenonRep]])
-> (String -> [PhoneticPhenomenonRep])
-> String
-> [[PhoneticPhenomenonRep]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array Int PhoneticPhenomenonRep
-> String -> [PhoneticPhenomenonRep]
str2PRSs Array Int PhoneticPhenomenonRep
arrayCharClassification)
        ([String] -> [[[PhoneticPhenomenonRep]]])
-> (String -> [String]) -> String -> [[[PhoneticPhenomenonRep]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
words1
        (String -> [String]) -> ShowS -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Maybe Char) -> ShowS
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Char -> Maybe Char
g
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
convertToProperPL
        ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> ShowS
forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-' then Char
' ' else Char
x)
  where
    g :: Char -> Maybe Char
g Char
x
        | Char
x Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
`elem` String
basicSpaces = Maybe Char
forall a. Maybe a
Nothing
        | Char
x Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
`notElem` String
additionalDelims = Char -> Maybe Char
forall a. a -> Maybe a
Just Char
x
        | Bool
otherwise = Char -> Maybe Char
forall a. a -> Maybe a
Just Char
' '
    words1 :: String -> [String]
words1 String
xs = if String -> Bool
forall a. [a] -> Bool
null String
ts then [] else String
w String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [String]
words1 String
s'' -- Practically this is an optimized version for this case 'words' function from Prelude.
      where
        ts :: String
ts = (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') String
xs
        (String
w, String
s'') = (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
ts
    {-# NOINLINE words1 #-}
    convertToProperPL :: ShowS
convertToProperPL = (PhoneticsRepresentationPLX -> String)
-> [PhoneticsRepresentationPLX] -> String
forall a b. (a -> [b]) -> [a] -> [b]
concatMap PhoneticsRepresentationPLX -> String
string1 ([PhoneticsRepresentationPLX] -> String)
-> (String -> [PhoneticsRepresentationPLX]) -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GWritingSystemPRPLX -> String -> [PhoneticsRepresentationPLX]
stringToXG GWritingSystemPRPLX
writingSystem
{-# INLINE createSyllablesPL #-}