-- | -- Module : Main -- Copyright : (c) OleksandrZhabenko 2020 -- License : MIT -- Stability : Experimental -- Maintainer : olexandr543@yahoo.com -- -- Analyzes a poetic text in Ukrainian, for every line prints statistic data and -- then for the whole poem prints the hypothesis evaluation information. Since the 0.4.0.0 version -- the program tries to be more accurate in cases of the lines consisting entirely of the words -- which are unique in phonetic meaning alongside the line. Another hypothesis is for the seventh command line -- argument (since the 0.12.0.0 version) equal to \"y0\" that the distribution -- of the placement of the actual poetic text in Ukrainian is not one of the standard distributions. -- It can probably have approximately a form of and is different for different authors: -- -- > -- -- -- -- > / \_/ \_/ \ -- -- To enable parallel computations (potentially, they can speed up the work), please, run the @propertiesText@ executable with -- @+RTS -threaded -RTS@ command line options with possibly @-N@ option inside. -- {-# OPTIONS_GHC -threaded -rtsopts #-} {-# LANGUAGE BangPatterns, FlexibleContexts #-} module Main where import Data.SubG import System.IO import Control.Concurrent import Control.Exception import Control.Parallel.Strategies import Data.Maybe (fromMaybe) import Text.Read (readMaybe) import qualified Data.Vector as VB import Languages.UniquenessPeriods.Vector.General.DebugG hiding (newLineEnding) import Languages.UniquenessPeriods.Vector.PropertiesG import Languages.UniquenessPeriods.Vector.PropertiesFuncRepG import Languages.UniquenessPeriods.Vector.PropertiesSyllablesG import Melodics.ByteString.Ukrainian import System.Environment import Languages.Phonetic.Ukrainian.PrepareText import Languages.UniquenessPeriods.Vector.DataG import Languages.UniquenessPeriods.Vector.AuxiliaryG import Languages.UniquenessPeriods.Vector.StrictVG import Numeric (showFFloat) import Languages.UniquenessPeriods.Vector.Filters import Data.Char (isAlpha) import Data.Statistics.RulesIntervals import Languages.UniquenessPeriods.Vector.FuncRepRelatedG main :: IO () main = do args <- getArgs let !coeffs = readCF . concat . take 1 $ args -- The first command line argument. If not sure, just enter \"1_\". if isPair coeffs then do let !file = concat . drop 1 . take 2 $ args -- The second command line arguments except those ones that are RTS arguments !gzS = concat . take 1 . drop 2 $ args -- The third command line argument that controls the choice of the number of intervals !printLine = fromMaybe 0 (readMaybe (concat . take 1 . drop 3 $ args)::(Maybe Int)) -- The fourth command line argument except those ones that are RTS arguments. Set to 1 if you would like to print the current line within the information !toOneLine = fromMaybe 0 (readMaybe (concat . take 1 . drop 4 $ args)::(Maybe Int)) -- The fifth command line argument except those ones that are RTS arguments. Set to 1 if you would like to convert the text into one single line before applying to it the processment (it can be more conceptually consistent in such a case) !choice = concat . drop 5 . take 6 $ args -- The sixth command line argument that controls what properties are used. generalProc coeffs file gzS printLine toOneLine choice else do let !file = concat . take 1 $ args !gzS = concat . take 1 . drop 1 $ args !printLine = fromMaybe 0 (readMaybe (concat . take 1 . drop 2 $ args)::(Maybe Int)) !toOneLine = fromMaybe 0 (readMaybe (concat . take 1 . drop 3 $ args)::(Maybe Int)) !choice = concat . drop 4 . take 5 $ args generalProc coeffs file gzS printLine toOneLine choice generalProc :: Coeffs2 -> FilePath -> String -> Int -> Int -> String -> IO () generalProc coeffs file gzS printLine toOneLine choice = do contents <- readFile file let !flines = fLines toOneLine contents getData3 coeffs (getIntervalsN gzS flines) printLine choice flines getIntervalsN :: String -> [VB.Vector Char] -> Int getIntervalsN xs ys | xs == "s" = sturgesH (length ys) | xs == "l" = levynskyiMod (length ys) | otherwise = fromMaybe 9 (readMaybe xs::(Maybe Int)) {-# INLINE getIntervalsN #-} getData3 :: Coeffs2 -> Int -> Int -> String -> [VB.Vector Char] -> IO () getData3 coeffs gz printLine choice zs = let !permsV4 = genPermutationsV in mapM_ (process1Line coeffs gz printLine choice permsV4) zs process1Line :: Coeffs2 -> Int -> Int -> String -> VB.Vector (VB.Vector (VB.Vector Int)) -> VB.Vector Char -> IO () process1Line coeffs gz printLine choice !permsV5 v = bracket (do myThread <- forkIO (do let !whspss = VB.fromList " 01-" !v2 = subG whspss v !l2 = (subtract 2) . VB.length $ v2 (!maxE,!minE,!data2) | compare l2 0 /= LT = runEval (parTuple3 rpar rpar rpar ((\k -> if k == 0.0 then 1.0 else k) . (\ls -> if null ls then 0.0 else head ls) . firstFrom3 . maximumElBy 1 (VB.singleton oneProperty) $ UL2 (VB.empty,uniquenessVariants2GNB ' ' id id id (VB.unsafeIndex permsV5 l2) (VB.singleton oneProperty) (chooseMax coeffs choice) v2), (\k -> if k == 0.0 then 1.0 else k) . abs . (\ls -> if null ls then 0.0 else head ls) . firstFrom3 . maximumElBy 1 (VB.singleton oneProperty) $ UL2 (VB.empty,uniquenessVariants2GNB ' ' id id id (VB.unsafeIndex permsV5 l2) (VB.singleton oneProperty) (chooseMin coeffs choice) v2), (\k -> if k == 0.0 then 1.0 else k) . head . getAC (chooseMax coeffs choice) $ v)) | otherwise = let !mono = (\k -> if k == 0.0 then 1.0 else k) . head . getAC (chooseMax coeffs choice) $ v in (mono,mono,mono) (!wordsN,!intervalN) | maxE == 1.0 = (0, 0) | otherwise = runEval (parTuple2 rpar rpar (l2 + 2, intervalNRealFrac minE maxE gz data2)) !ratio = if maxE == 1.0 then 0.0 else 2.0 * data2 / (minE + maxE) in do hPutStr stdout . showFFloat (precChoice choice) minE $ "\t" hPutStr stdout . showFFloat (precChoice choice) data2 $ "\t" hPutStr stdout . showFFloat (precChoice choice) maxE $ "\t" hPutStr stdout . showFFloat (Just 4) (data2 / minE) $ "\t" hPutStr stdout . showFFloat (Just 4) (maxE / minE) $ "\t" hPutStr stdout . showFFloat (Just 4) (maxE / data2) $ "\t" hPutStr stdout . showFFloat Nothing ratio $ "\t" hPutStr stdout ('\t':show (wordsN::Int)) hPutStr stdout ('\t':show (intervalN::Int)) hPutStrLn stdout (if printLine == 1 then '\t':(VB.toList v) else "")) return myThread) (killThread) (\_ -> putStr "") fLines :: Int -> String -> [VB.Vector Char] fLines !toOneLine ys = let preText = filter (any (\x -> isUkrainianL x && isAlpha x)) . prepareText . (\z -> if toOneLine == 1 then unwords . words $ z else z) $ ys wss = map (length . subG " 01-") preText g (t:ts) (r:rs) = if r > 7 then filter (`notElem` "01-") t:g ts rs else t:g ts rs g _ _ = [] in map VB.fromList . g preText $ wss