-- |
-- Module      :  Phonetic.Languages.Permutations
-- Copyright   :  (c) OleksandrZhabenko 2020
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Commonly used versions of the @phonetic-languages-common@ package functions.

module Phonetic.Languages.Permutations (
  universalSetG
  , universalSetGL
  , genPermutations
  , genPermutationsV
  , genPermutationsL
  , genPermutationsVL
) where

import qualified Data.Vector as VB
import qualified Data.List as L (permutations)
import Data.SubG
import Data.SubG.InstancesPlus ()
import qualified Data.Foldable as F (concat,foldr')
--import Data.List ()
import Data.Monoid

-- | A key point of the evaluation -- the universal set of the task represented as a 'VB.Vector' of 'VB.Vector' of @a@.
universalSetG ::
  (Eq a, Foldable t, InsertLeft t a, Monoid (t a), Monoid (t (t a))) => t a
  -> t (t a)
  -> (t a -> VB.Vector a) -- ^ The function that is used internally to convert to the boxed 'VB.Vector' of @a@ so that the function can process further the permutations
  -> ((t (t a)) -> VB.Vector (VB.Vector a)) -- ^ The function that is used internally to convert to the boxed 'VB.Vector' of 'VB.Vector' of @a@ so that the function can process further
  -> VB.Vector (VB.Vector Int) -- ^ The list of permutations of 'Int' indices starting from 0 and up to n (n is probably less than 7).
  -> VB.Vector (VB.Vector a)
  -> VB.Vector (VB.Vector a)
universalSetG :: t a
-> t (t a)
-> (t a -> Vector a)
-> (t (t a) -> Vector (Vector a))
-> Vector (Vector Int)
-> Vector (Vector a)
-> Vector (Vector a)
universalSetG t a
ts t (t a)
uss t a -> Vector a
f1 t (t a) -> Vector (Vector a)
f2 Vector (Vector Int)
perms Vector (Vector a)
baseV = (Vector Int -> Vector a)
-> Vector (Vector Int) -> Vector (Vector a)
forall a b. (a -> b) -> Vector a -> Vector b
VB.map ((Vector a -> Vector a -> Vector a)
-> Vector a -> Vector (Vector a) -> Vector a
forall a b. (a -> b -> b) -> b -> Vector a -> b
VB.foldr' Vector a -> Vector a -> Vector a
forall a. Monoid a => a -> a -> a
mappend Vector a
forall a. Monoid a => a
mempty (Vector (Vector a) -> Vector a)
-> (Vector Int -> Vector (Vector a)) -> Vector Int -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> Vector (Vector a) -> Vector (Vector a)
forall a. a -> Vector a -> Vector a
VB.cons (t a -> Vector a
f1 t a
ts) (Vector (Vector a) -> Vector (Vector a))
-> (Vector Int -> Vector (Vector a))
-> Vector Int
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a. Monoid a => a -> a -> a
`mappend` (t (t a) -> Vector (Vector a)
f2 t (t a)
uss)) (Vector (Vector a) -> Vector (Vector a))
-> (Vector Int -> Vector (Vector a))
-> Vector Int
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (Vector a) -> Vector Int -> Vector (Vector a)
forall a. Vector a -> Vector Int -> Vector a
VB.unsafeBackpermute Vector (Vector a)
baseV) Vector (Vector Int)
perms
{-# INLINE universalSetG #-}

-- | A key point of the evaluation -- the universal set of the task represented as a 'VB.Vector' of 'VB.Vector' of @a@. Because the order is not
universalSetGL ::
  (Eq a, Foldable t, InsertLeft t a, Monoid (t a), Monoid (t (t a))) => t a
  -> t (t a)
  -> (t a -> [a]) -- ^ The function that is used internally to convert to the @[a]@ so that the function can process further the permutations
  -> ((t (t a)) -> [[a]]) -- ^ The function that is used internally to convert to the needed representation so that the function can process further
  -> [VB.Vector Int] -- ^ The list of permutations of 'Int' indices starting from 0 and up to n (n is probably less than 7).
  -> VB.Vector [a]
  -> [[a]]
universalSetGL :: t a
-> t (t a)
-> (t a -> [a])
-> (t (t a) -> [[a]])
-> [Vector Int]
-> Vector [a]
-> [[a]]
universalSetGL t a
ts t (t a)
uss t a -> [a]
f1 t (t a) -> [[a]]
f2 [Vector Int]
permsL Vector [a]
baseV = (Vector Int -> [a]) -> [Vector Int] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map ([[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
F.concat ([[a]] -> [a]) -> (Vector Int -> [[a]]) -> Vector Int -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [[a]] -> [[a]]) -> [[a]] -> [[a]] -> [[a]]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
F.foldr' (:) [] ([[a]] -> [[a]]) -> (Vector Int -> [[a]]) -> Vector Int -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t a -> [a]
f1 t a
ts[a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
:) ([[a]] -> [[a]]) -> (Vector Int -> [[a]]) -> Vector Int -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[a]] -> [[a]] -> [[a]]
forall a. Monoid a => a -> a -> a
`mappend` t (t a) -> [[a]]
f2 t (t a)
uss) ([[a]] -> [[a]]) -> (Vector Int -> [[a]]) -> Vector Int -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector [a] -> [[a]]
forall a. Vector a -> [a]
VB.toList (Vector [a] -> [[a]])
-> (Vector Int -> Vector [a]) -> Vector Int -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector [a] -> Vector Int -> Vector [a]
forall a. Vector a -> Vector Int -> Vector a
VB.unsafeBackpermute Vector [a]
baseV) [Vector Int]
permsL
{-# INLINE universalSetGL #-}

genPermutations :: Int -> VB.Vector (VB.Vector Int)
genPermutations :: Int -> Vector (Vector Int)
genPermutations Int
n = ([Int] -> Vector Int) -> Vector [Int] -> Vector (Vector Int)
forall a b. (a -> b) -> Vector a -> Vector b
VB.map [Int] -> Vector Int
forall a. [a] -> Vector a
VB.fromList (Vector [Int] -> Vector (Vector Int))
-> ([Int] -> Vector [Int]) -> [Int] -> Vector (Vector Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Int]] -> Vector [Int]
forall a. [a] -> Vector a
VB.fromList ([[Int]] -> Vector [Int])
-> ([Int] -> [[Int]]) -> [Int] -> Vector [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [[Int]]
forall a. [a] -> [[a]]
L.permutations ([Int] -> [[Int]]) -> ([Int] -> [Int]) -> [Int] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> Vector (Vector Int)) -> [Int] -> Vector (Vector Int)
forall a b. (a -> b) -> a -> b
$ [Int
0..]
{-# INLINE genPermutations #-}

genPermutationsV :: VB.Vector (VB.Vector (VB.Vector Int))
genPermutationsV :: Vector (Vector (Vector Int))
genPermutationsV = (Int -> Vector (Vector Int))
-> Vector Int -> Vector (Vector (Vector Int))
forall a b. (a -> b) -> Vector a -> Vector b
VB.map (\Int
n -> ([Int] -> Vector Int) -> Vector [Int] -> Vector (Vector Int)
forall a b. (a -> b) -> Vector a -> Vector b
VB.map [Int] -> Vector Int
forall a. [a] -> Vector a
VB.fromList (Vector [Int] -> Vector (Vector Int))
-> ([Int] -> Vector [Int]) -> [Int] -> Vector (Vector Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Int]] -> Vector [Int]
forall a. [a] -> Vector a
VB.fromList ([[Int]] -> Vector [Int])
-> ([Int] -> [[Int]]) -> [Int] -> Vector [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [[Int]]
forall a. [a] -> [[a]]
L.permutations ([Int] -> [[Int]]) -> ([Int] -> [Int]) -> [Int] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> Vector (Vector Int)) -> [Int] -> Vector (Vector Int)
forall a b. (a -> b) -> a -> b
$ [Int
0..]) (Vector Int -> Vector (Vector (Vector Int)))
-> (Int -> Vector Int) -> Int -> Vector (Vector (Vector Int))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> Vector Int
forall a. Enum a => a -> a -> Vector a
VB.enumFromTo Int
2 (Int -> Vector (Vector (Vector Int)))
-> Int -> Vector (Vector (Vector Int))
forall a b. (a -> b) -> a -> b
$ Int
7
{-# INLINE genPermutationsV #-}

genPermutationsL :: Int -> [VB.Vector Int]
genPermutationsL :: Int -> [Vector Int]
genPermutationsL Int
n = ([Int] -> Vector Int) -> [[Int]] -> [Vector Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Vector Int
forall a. [a] -> Vector a
VB.fromList ([[Int]] -> [Vector Int])
-> ([Int] -> [[Int]]) -> [Int] -> [Vector Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [[Int]]
forall a. [a] -> [[a]]
L.permutations ([Int] -> [[Int]]) -> ([Int] -> [Int]) -> [Int] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Vector Int]) -> [Int] -> [Vector Int]
forall a b. (a -> b) -> a -> b
$ [Int
0..]
{-# INLINE genPermutationsL #-}

genPermutationsVL :: VB.Vector [VB.Vector Int]
genPermutationsVL :: Vector [Vector Int]
genPermutationsVL = (Int -> [Vector Int]) -> Vector Int -> Vector [Vector Int]
forall a b. (a -> b) -> Vector a -> Vector b
VB.map (\Int
n -> ([Int] -> Vector Int) -> [[Int]] -> [Vector Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Vector Int
forall a. [a] -> Vector a
VB.fromList ([[Int]] -> [Vector Int])
-> ([Int] -> [[Int]]) -> [Int] -> [Vector Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [[Int]]
forall a. [a] -> [[a]]
L.permutations ([Int] -> [[Int]]) -> ([Int] -> [Int]) -> [Int] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Vector Int]) -> [Int] -> [Vector Int]
forall a b. (a -> b) -> a -> b
$ [Int
0..]) (Vector Int -> Vector [Vector Int])
-> (Int -> Vector Int) -> Int -> Vector [Vector Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int -> Vector Int
forall a. Enum a => a -> a -> Vector a
VB.enumFromTo Int
2 (Int -> Vector [Vector Int]) -> Int -> Vector [Vector Int]
forall a b. (a -> b) -> a -> b
$ Int
7
{-# INLINE genPermutationsVL #-}