{-# LANGUAGE BangPatterns #-}
module Math.Combinat.Partitions.Set where
import Data.List
import Data.Ord
import System.Random
import Math.Combinat.Sets
import Math.Combinat.Numbers
import Math.Combinat.Helper
import Math.Combinat.Classes
import Math.Combinat.Partitions.Integer
newtype SetPartition = SetPartition [[Int]] deriving (SetPartition -> SetPartition -> Bool
(SetPartition -> SetPartition -> Bool)
-> (SetPartition -> SetPartition -> Bool) -> Eq SetPartition
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SetPartition -> SetPartition -> Bool
$c/= :: SetPartition -> SetPartition -> Bool
== :: SetPartition -> SetPartition -> Bool
$c== :: SetPartition -> SetPartition -> Bool
Eq,Eq SetPartition
Eq SetPartition
-> (SetPartition -> SetPartition -> Ordering)
-> (SetPartition -> SetPartition -> Bool)
-> (SetPartition -> SetPartition -> Bool)
-> (SetPartition -> SetPartition -> Bool)
-> (SetPartition -> SetPartition -> Bool)
-> (SetPartition -> SetPartition -> SetPartition)
-> (SetPartition -> SetPartition -> SetPartition)
-> Ord SetPartition
SetPartition -> SetPartition -> Bool
SetPartition -> SetPartition -> Ordering
SetPartition -> SetPartition -> SetPartition
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
min :: SetPartition -> SetPartition -> SetPartition
$cmin :: SetPartition -> SetPartition -> SetPartition
max :: SetPartition -> SetPartition -> SetPartition
$cmax :: SetPartition -> SetPartition -> SetPartition
>= :: SetPartition -> SetPartition -> Bool
$c>= :: SetPartition -> SetPartition -> Bool
> :: SetPartition -> SetPartition -> Bool
$c> :: SetPartition -> SetPartition -> Bool
<= :: SetPartition -> SetPartition -> Bool
$c<= :: SetPartition -> SetPartition -> Bool
< :: SetPartition -> SetPartition -> Bool
$c< :: SetPartition -> SetPartition -> Bool
compare :: SetPartition -> SetPartition -> Ordering
$ccompare :: SetPartition -> SetPartition -> Ordering
$cp1Ord :: Eq SetPartition
Ord,Int -> SetPartition -> ShowS
[SetPartition] -> ShowS
SetPartition -> String
(Int -> SetPartition -> ShowS)
-> (SetPartition -> String)
-> ([SetPartition] -> ShowS)
-> Show SetPartition
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SetPartition] -> ShowS
$cshowList :: [SetPartition] -> ShowS
show :: SetPartition -> String
$cshow :: SetPartition -> String
showsPrec :: Int -> SetPartition -> ShowS
$cshowsPrec :: Int -> SetPartition -> ShowS
Show,ReadPrec [SetPartition]
ReadPrec SetPartition
Int -> ReadS SetPartition
ReadS [SetPartition]
(Int -> ReadS SetPartition)
-> ReadS [SetPartition]
-> ReadPrec SetPartition
-> ReadPrec [SetPartition]
-> Read SetPartition
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SetPartition]
$creadListPrec :: ReadPrec [SetPartition]
readPrec :: ReadPrec SetPartition
$creadPrec :: ReadPrec SetPartition
readList :: ReadS [SetPartition]
$creadList :: ReadS [SetPartition]
readsPrec :: Int -> ReadS SetPartition
$creadsPrec :: Int -> ReadS SetPartition
Read)
_standardizeSetPartition :: [[Int]] -> [[Int]]
_standardizeSetPartition :: [[Int]] -> [[Int]]
_standardizeSetPartition = ([Int] -> [Int] -> Ordering) -> [[Int]] -> [[Int]]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (([Int] -> Int) -> [Int] -> [Int] -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing [Int] -> Int
forall p. [p] -> p
myhead) ([[Int]] -> [[Int]]) -> ([[Int]] -> [[Int]]) -> [[Int]] -> [[Int]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Int] -> [Int]) -> [[Int]] -> [[Int]]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort where
myhead :: [p] -> p
myhead [p]
xs = case [p]
xs of
(p
x:[p]
xs) -> p
x
[] -> String -> p
forall a. HasCallStack => String -> a
error String
"_standardizeSetPartition: empty subset"
fromSetPartition :: SetPartition -> [[Int]]
fromSetPartition :: SetPartition -> [[Int]]
fromSetPartition (SetPartition [[Int]]
zzs) = [[Int]]
zzs
toSetPartitionUnsafe :: [[Int]] -> SetPartition
toSetPartitionUnsafe :: [[Int]] -> SetPartition
toSetPartitionUnsafe = [[Int]] -> SetPartition
SetPartition
toSetPartition :: [[Int]] -> SetPartition
toSetPartition :: [[Int]] -> SetPartition
toSetPartition [[Int]]
zzs = if [[Int]] -> Bool
_isSetPartition [[Int]]
zzs
then [[Int]] -> SetPartition
SetPartition ([[Int]] -> [[Int]]
_standardizeSetPartition [[Int]]
zzs)
else String -> SetPartition
forall a. HasCallStack => String -> a
error String
"toSetPartition: not a set partition"
_isSetPartition :: [[Int]] -> Bool
_isSetPartition :: [[Int]] -> Bool
_isSetPartition [[Int]]
zzs = [Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort ([[Int]] -> [Int]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Int]]
zzs) [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
== [Int
1..Int
n] where
n :: Int
n = [Int] -> Int
forall a. Num a => [a] -> a
sum' (([Int] -> Int) -> [[Int]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Int]]
zzs)
instance HasNumberOfParts SetPartition where
numberOfParts :: SetPartition -> Int
numberOfParts (SetPartition [[Int]]
p) = [[Int]] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Int]]
p
setPartitionShape :: SetPartition -> Partition
setPartitionShape :: SetPartition -> Partition
setPartitionShape (SetPartition [[Int]]
pps) = [Int] -> Partition
mkPartition (([Int] -> Int) -> [[Int]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Int]]
pps)
setPartitions :: Int -> [SetPartition]
setPartitions :: Int -> [SetPartition]
setPartitions = Int -> [SetPartition]
setPartitionsNaive
setPartitionsWithKParts
:: Int
-> Int
-> [SetPartition]
setPartitionsWithKParts :: Int -> Int -> [SetPartition]
setPartitionsWithKParts = Int -> Int -> [SetPartition]
setPartitionsWithKPartsNaive
setPartitionsNaive :: Int -> [SetPartition]
setPartitionsNaive :: Int -> [SetPartition]
setPartitionsNaive Int
n = ([[Int]] -> SetPartition) -> [[[Int]]] -> [SetPartition]
forall a b. (a -> b) -> [a] -> [b]
map ([[Int]] -> SetPartition
SetPartition ([[Int]] -> SetPartition)
-> ([[Int]] -> [[Int]]) -> [[Int]] -> SetPartition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Int]] -> [[Int]]
_standardizeSetPartition) ([[[Int]]] -> [SetPartition]) -> [[[Int]]] -> [SetPartition]
forall a b. (a -> b) -> a -> b
$ [Int] -> [[[Int]]]
go [Int
1..Int
n] where
go :: [Int] -> [[[Int]]]
go :: [Int] -> [[[Int]]]
go [] = [[]]
go (Int
z:[Int]
zs) = [ [Int]
s [Int] -> [[Int]] -> [[Int]]
forall a. a -> [a] -> [a]
: [[Int]]
rest | Int
k <- [Int
1..Int
n] , [Int]
s0 <- Int -> [Int] -> [[Int]]
forall a. Int -> [a] -> [[a]]
choose (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int]
zs , let s :: [Int]
s = Int
zInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
s0 , [[Int]]
rest <- [Int] -> [[[Int]]]
go ([Int]
zs [Int] -> [Int] -> [Int]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Int]
s) ]
setPartitionsWithKPartsNaive
:: Int
-> Int
-> [SetPartition]
setPartitionsWithKPartsNaive :: Int -> Int -> [SetPartition]
setPartitionsWithKPartsNaive Int
k Int
n = ([[Int]] -> SetPartition) -> [[[Int]]] -> [SetPartition]
forall a b. (a -> b) -> [a] -> [b]
map ([[Int]] -> SetPartition
SetPartition ([[Int]] -> SetPartition)
-> ([[Int]] -> [[Int]]) -> [[Int]] -> SetPartition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Int]] -> [[Int]]
_standardizeSetPartition) ([[[Int]]] -> [SetPartition]) -> [[[Int]]] -> [SetPartition]
forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> [[[Int]]]
go Int
k [Int
1..Int
n] where
go :: Int -> [Int] -> [[[Int]]]
go :: Int -> [Int] -> [[[Int]]]
go !Int
k [] = if Int
kInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
0 then [[]] else []
go Int
1 [Int]
zs = [[[Int]
zs]]
go !Int
k (Int
z:[Int]
zs) = [ [Int]
s [Int] -> [[Int]] -> [[Int]]
forall a. a -> [a] -> [a]
: [[Int]]
rest | Int
l <- [Int
1..Int
n] , [Int]
s0 <- Int -> [Int] -> [[Int]]
forall a. Int -> [a] -> [[a]]
choose (Int
lInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [Int]
zs , let s :: [Int]
s = Int
zInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
s0 , [[Int]]
rest <- Int -> [Int] -> [[[Int]]]
go (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) ([Int]
zs [Int] -> [Int] -> [Int]
forall a. Eq a => [a] -> [a] -> [a]
\\ [Int]
s) ]
countSetPartitions :: Int -> Integer
countSetPartitions :: Int -> Integer
countSetPartitions = Int -> Integer
forall a. Integral a => a -> Integer
bellNumber
countSetPartitionsWithKParts
:: Int
-> Int
-> Integer
countSetPartitionsWithKParts :: Int -> Int -> Integer
countSetPartitionsWithKParts Int
k Int
n = Int -> Int -> Integer
forall a. Integral a => a -> a -> Integer
stirling2nd Int
n Int
k