-- |
-- 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
  , genPermutations
  , genPermutationsV
) where

import qualified Data.Vector as VB
import qualified Data.List as L (permutations)
import Data.SubG
import Data.SubG.InstancesPlus ()
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 #-}

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 #-}