module Math.PureSet
(
PureSet(..),
pureSet,
emptySet,
singleton,
pair,
first,
second,
maybeFirst,
maybeSecond,
cartesianProduct,
numberToSet,
(||||),
(&&&&),
isInP,
isIncludedInP,
card,
powerSetP,
prettify,
formatPureSet,
)
where
import Data.WeakSet (Set)
import Data.WeakSet.Safe
import qualified Data.WeakSet as S
import Data.List (intersect, nub, intercalate, subsequences)
import Data.Maybe (fromJust, catMaybes)
data PureSet = PureSet (Set PureSet) deriving (PureSet -> PureSet -> Bool
(PureSet -> PureSet -> Bool)
-> (PureSet -> PureSet -> Bool) -> Eq PureSet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PureSet -> PureSet -> Bool
== :: PureSet -> PureSet -> Bool
$c/= :: PureSet -> PureSet -> Bool
/= :: PureSet -> PureSet -> Bool
Eq, Int -> PureSet -> ShowS
[PureSet] -> ShowS
PureSet -> String
(Int -> PureSet -> ShowS)
-> (PureSet -> String) -> ([PureSet] -> ShowS) -> Show PureSet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PureSet -> ShowS
showsPrec :: Int -> PureSet -> ShowS
$cshow :: PureSet -> String
show :: PureSet -> String
$cshowList :: [PureSet] -> ShowS
showList :: [PureSet] -> ShowS
Show)
pureSet :: [PureSet] -> PureSet
pureSet :: [PureSet] -> PureSet
pureSet = (Set PureSet -> PureSet
PureSet)(Set PureSet -> PureSet)
-> ([PureSet] -> Set PureSet) -> [PureSet] -> PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[PureSet] -> Set PureSet
forall a. [a] -> Set a
set
pureSetToSet :: PureSet -> Set PureSet
pureSetToSet :: PureSet -> Set PureSet
pureSetToSet (PureSet Set PureSet
xs) = Set PureSet
xs
emptySet :: PureSet
emptySet :: PureSet
emptySet = [PureSet] -> PureSet
pureSet []
singleton :: PureSet -> PureSet
singleton :: PureSet -> PureSet
singleton PureSet
x = [PureSet] -> PureSet
pureSet ([PureSet] -> PureSet) -> [PureSet] -> PureSet
forall a b. (a -> b) -> a -> b
$ [PureSet
x]
pair :: PureSet -> PureSet -> PureSet
pair :: PureSet -> PureSet -> PureSet
pair PureSet
x PureSet
y = Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ [PureSet] -> Set PureSet
forall a. [a] -> Set a
set [PureSet -> PureSet
singleton PureSet
x, [PureSet] -> PureSet
pureSet ([PureSet] -> PureSet) -> [PureSet] -> PureSet
forall a b. (a -> b) -> a -> b
$ [PureSet
x,PureSet
y]]
first :: PureSet -> PureSet
first :: PureSet -> PureSet
first (PureSet Set PureSet
s)
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
f
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = if PureSet -> Int
card (Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
s) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then (Set PureSet -> PureSet
forall a. Set a -> a
anElement(Set PureSet -> PureSet)
-> (Set PureSet -> Set PureSet) -> Set PureSet -> PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Set PureSet
pureSetToSet(PureSet -> Set PureSet)
-> (Set PureSet -> PureSet) -> Set PureSet -> Set PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Set PureSet -> PureSet
forall a. Set a -> a
anElement (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
s) else (String -> PureSet
forall a. HasCallStack => String -> a
error (String -> PureSet) -> String -> PureSet
forall a b. (a -> b) -> a -> b
$ String
"Math.PureSet.first : malformed pair " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Set PureSet -> String
forall a. Show a => a -> String
show Set PureSet
s))
| Bool
otherwise = String -> PureSet
forall a. HasCallStack => String -> a
error (String -> PureSet) -> String -> PureSet
forall a b. (a -> b) -> a -> b
$ String
"Math.PureSet.first : malformed pair " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Set PureSet -> String
forall a. Show a => a -> String
show Set PureSet
s)
where
l :: [PureSet]
l = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
s
a :: PureSet
a = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
b :: PureSet
b = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
PureSet Set PureSet
f = if PureSet -> Int
card PureSet
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then PureSet
a else PureSet
b
second :: PureSet -> PureSet
second :: PureSet -> PureSet
second i :: PureSet
i@(PureSet Set PureSet
s)
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = if PureSet -> Int
card (Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
s) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then (Set PureSet -> PureSet
forall a. Set a -> a
anElement(Set PureSet -> PureSet)
-> (Set PureSet -> Set PureSet) -> Set PureSet -> PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Set PureSet
pureSetToSet(PureSet -> Set PureSet)
-> (Set PureSet -> PureSet) -> Set PureSet -> Set PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Set PureSet -> PureSet
forall a. Set a -> a
anElement (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
s) else (String -> PureSet
forall a. HasCallStack => String -> a
error (String -> PureSet) -> String -> PureSet
forall a b. (a -> b) -> a -> b
$ String
"Math.PureSet.second : malformed pair " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Set PureSet -> String
forall a. Show a => a -> String
show Set PureSet
s))
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = if [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0 PureSet -> PureSet -> Bool
forall a. Eq a => a -> a -> Bool
== PureSet -> PureSet
first PureSet
i then [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1 else (if [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1 PureSet -> PureSet -> Bool
forall a. Eq a => a -> a -> Bool
== PureSet -> PureSet
first PureSet
i then [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0 else (String -> PureSet
forall a. HasCallStack => String -> a
error (String -> PureSet) -> String -> PureSet
forall a b. (a -> b) -> a -> b
$ String
"Math.PureSet.second : malformed pair " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Set PureSet -> String
forall a. Show a => a -> String
show Set PureSet
s)))
| Bool
otherwise = String -> PureSet
forall a. HasCallStack => String -> a
error (String -> PureSet) -> String -> PureSet
forall a b. (a -> b) -> a -> b
$ String
"Math.PureSet.second : malformed pair " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Set PureSet -> String
forall a. Show a => a -> String
show Set PureSet
s)
where
l :: [PureSet]
l = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
s
a :: PureSet
a = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
b :: PureSet
b = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
PureSet Set PureSet
r = if PureSet -> Int
card PureSet
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 then PureSet
a else PureSet
b
r2 :: [PureSet]
r2 = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
r
maybeFirst :: PureSet -> Maybe PureSet
maybeFirst :: PureSet -> Maybe PureSet
maybeFirst (PureSet Set PureSet
s)
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = PureSet -> Maybe PureSet
forall a. a -> Maybe a
Just (PureSet -> Maybe PureSet) -> PureSet -> Maybe PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
f
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = if PureSet -> Int
card (Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
s) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then PureSet -> Maybe PureSet
forall a. a -> Maybe a
Just (Set PureSet -> PureSet
forall a. Set a -> a
anElement(Set PureSet -> PureSet)
-> (Set PureSet -> Set PureSet) -> Set PureSet -> PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Set PureSet
pureSetToSet(PureSet -> Set PureSet)
-> (Set PureSet -> PureSet) -> Set PureSet -> Set PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Set PureSet -> PureSet
forall a. Set a -> a
anElement (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
s) else Maybe PureSet
forall a. Maybe a
Nothing
| Bool
otherwise = Maybe PureSet
forall a. Maybe a
Nothing
where
l :: [PureSet]
l = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
s
a :: PureSet
a = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
b :: PureSet
b = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
PureSet Set PureSet
f = if PureSet -> Int
card PureSet
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then PureSet
a else PureSet
b
maybeSecond :: PureSet -> Maybe PureSet
maybeSecond :: PureSet -> Maybe PureSet
maybeSecond i :: PureSet
i@(PureSet Set PureSet
s)
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = if PureSet -> Int
card (Set PureSet -> PureSet
forall a. Set a -> a
anElement Set PureSet
s) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then PureSet -> Maybe PureSet
forall a. a -> Maybe a
Just (Set PureSet -> PureSet
forall a. Set a -> a
anElement(Set PureSet -> PureSet)
-> (Set PureSet -> Set PureSet) -> Set PureSet -> PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Set PureSet
pureSetToSet(PureSet -> Set PureSet)
-> (Set PureSet -> PureSet) -> Set PureSet -> Set PureSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Set PureSet -> PureSet
forall a. Set a -> a
anElement (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
s) else Maybe PureSet
forall a. Maybe a
Nothing
| [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = if [PureSet] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [PureSet]
r2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
2 then Maybe PureSet
forall a. Maybe a
Nothing else (if [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0 PureSet -> PureSet -> Bool
forall a. Eq a => a -> a -> Bool
== PureSet -> PureSet
first PureSet
i then PureSet -> Maybe PureSet
forall a. a -> Maybe a
Just ([PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1) else (if [PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1 PureSet -> PureSet -> Bool
forall a. Eq a => a -> a -> Bool
== PureSet -> PureSet
first PureSet
i then PureSet -> Maybe PureSet
forall a. a -> Maybe a
Just ([PureSet]
r2 [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0) else Maybe PureSet
forall a. Maybe a
Nothing))
| Bool
otherwise = Maybe PureSet
forall a. Maybe a
Nothing
where
l :: [PureSet]
l = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
s
a :: PureSet
a = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
b :: PureSet
b = [PureSet]
l [PureSet] -> Int -> PureSet
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
PureSet Set PureSet
r = if PureSet -> Int
card PureSet
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 then PureSet
a else PureSet
b
r2 :: [PureSet]
r2 = Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
r
cartesianProduct :: PureSet -> PureSet -> PureSet
cartesianProduct :: PureSet -> PureSet -> PureSet
cartesianProduct (PureSet Set PureSet
xs) (PureSet Set PureSet
ys) = [PureSet] -> PureSet
pureSet ([PureSet] -> PureSet) -> [PureSet] -> PureSet
forall a b. (a -> b) -> a -> b
$ [PureSet -> PureSet -> PureSet
pair PureSet
x PureSet
y | PureSet
x <- Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
xs, PureSet
y <- Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
ys]
(||||) :: PureSet -> PureSet -> PureSet
|||| :: PureSet -> PureSet -> PureSet
(||||) (PureSet Set PureSet
xs) (PureSet Set PureSet
ys) = Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
xs Set PureSet -> Set PureSet -> Set PureSet
forall a. Set a -> Set a -> Set a
||| Set PureSet
ys
(&&&&) :: PureSet -> PureSet -> PureSet
&&&& :: PureSet -> PureSet -> PureSet
(&&&&) (PureSet Set PureSet
xs) (PureSet Set PureSet
ys) = Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
xs Set PureSet -> Set PureSet -> Set PureSet
forall a. Eq a => Set a -> Set a -> Set a
|&| Set PureSet
ys
(\\\\) :: PureSet -> PureSet -> PureSet
\\\\ :: PureSet -> PureSet -> PureSet
(\\\\) (PureSet Set PureSet
xs) (PureSet Set PureSet
ys) = Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet
xs Set PureSet -> Set PureSet -> Set PureSet
forall a. Eq a => Set a -> Set a -> Set a
|-| Set PureSet
ys
numberToSet :: (Num a, Eq a) => a -> PureSet
numberToSet :: forall a. (Num a, Eq a) => a -> PureSet
numberToSet a
0 = PureSet
emptySet
numberToSet a
n = (a -> PureSet
forall a. (Num a, Eq a) => a -> PureSet
numberToSet (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1)) PureSet -> PureSet -> PureSet
|||| (PureSet -> PureSet
singleton (a -> PureSet
forall a. (Num a, Eq a) => a -> PureSet
numberToSet (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1)))
isInP :: PureSet -> PureSet -> Bool
isInP :: PureSet -> PureSet -> Bool
isInP PureSet
x (PureSet Set PureSet
xs) = PureSet
x PureSet -> Set PureSet -> Bool
forall a. Eq a => a -> Set a -> Bool
`isIn` Set PureSet
xs
isIncludedInP :: PureSet -> PureSet -> Bool
isIncludedInP :: PureSet -> PureSet -> Bool
isIncludedInP (PureSet Set PureSet
xs) (PureSet Set PureSet
ys) = Set PureSet
xs Set PureSet -> Set PureSet -> Bool
forall a. Eq a => Set a -> Set a -> Bool
`isIncludedIn` Set PureSet
ys
card :: PureSet -> Int
card :: PureSet -> Int
card (PureSet Set PureSet
xs) = Set PureSet -> Int
forall a. Eq a => Set a -> Int
cardinal Set PureSet
xs
powerSetP :: PureSet -> PureSet
powerSetP :: PureSet -> PureSet
powerSetP (PureSet Set PureSet
xs) = Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set PureSet -> PureSet
forall a b. (a -> b) -> a -> b
$ Set PureSet -> PureSet
PureSet (Set PureSet -> PureSet) -> Set (Set PureSet) -> Set PureSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set PureSet -> Set (Set PureSet)
forall a. Set a -> Set (Set a)
S.powerSet Set PureSet
xs
prettify :: PureSet -> String
prettify :: PureSet -> String
prettify (PureSet Set PureSet
xs)
| Set PureSet -> Int
forall a. Eq a => Set a -> Int
cardinal Set PureSet
xs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = String
"{}"
| Bool
otherwise = String
"{" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ PureSet -> String
prettify (PureSet -> String) -> [PureSet] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList Set PureSet
xs) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"
formatPureSet :: PureSet -> String
formatPureSet :: PureSet -> String
formatPureSet PureSet
x
| (Bool -> Bool
not(Bool -> Bool) -> (Maybe Integer -> Bool) -> Maybe Integer -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Maybe Integer -> Bool
forall a. Maybe a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) (Maybe Integer -> Bool) -> Maybe Integer -> Bool
forall a b. (a -> b) -> a -> b
$ PureSet -> Maybe Integer
forall {a}. (Num a, Enum a, Ord a) => PureSet -> Maybe a
toNumber PureSet
x = Integer -> String
forall a. Show a => a -> String
show(Integer -> String)
-> (Maybe Integer -> Integer) -> Maybe Integer -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Maybe Integer -> Integer
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Integer -> String) -> Maybe Integer -> String
forall a b. (a -> b) -> a -> b
$ PureSet -> Maybe Integer
forall {a}. (Num a, Enum a, Ord a) => PureSet -> Maybe a
toNumber PureSet
x
| (Bool -> Bool
not(Bool -> Bool) -> (Maybe String -> Bool) -> Maybe String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Maybe String -> Bool
forall a. Maybe a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null) (Maybe String -> Bool) -> Maybe String -> Bool
forall a b. (a -> b) -> a -> b
$ PureSet -> Maybe String
toPair PureSet
x = Maybe String -> String
forall a. HasCallStack => Maybe a -> a
fromJust(Maybe String -> String)
-> (PureSet -> Maybe String) -> PureSet -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Maybe String
toPair (PureSet -> String) -> PureSet -> String
forall a b. (a -> b) -> a -> b
$ PureSet
x
| Bool
otherwise = String
"{"String -> ShowS
forall a. [a] -> [a] -> [a]
++String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," (PureSet -> String
formatPureSet (PureSet -> String) -> [PureSet] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Set PureSet -> [PureSet]
forall a. Eq a => Set a -> [a]
setToList(Set PureSet -> [PureSet])
-> (PureSet -> Set PureSet) -> PureSet -> [PureSet]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> Set PureSet
pureSetToSet (PureSet -> [PureSet]) -> PureSet -> [PureSet]
forall a b. (a -> b) -> a -> b
$ PureSet
x))String -> ShowS
forall a. [a] -> [a] -> [a]
++String
"}"
where
toNumber :: PureSet -> Maybe a
toNumber s :: PureSet
s@(PureSet Set PureSet
xs)
| PureSet
s PureSet -> PureSet -> Bool
forall a. Eq a => a -> a -> Bool
== PureSet
emptySet = a -> Maybe a
forall a. a -> Maybe a
Just a
0
| Bool
otherwise = let
numbers :: [Maybe a]
numbers = Set (Maybe a) -> [Maybe a]
forall a. Eq a => Set a -> [a]
setToList (Set (Maybe a) -> [Maybe a]) -> Set (Maybe a) -> [Maybe a]
forall a b. (a -> b) -> a -> b
$ PureSet -> Maybe a
toNumber (PureSet -> Maybe a) -> Set PureSet -> Set (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set PureSet
xs
anyMissing :: Bool
anyMissing = Maybe a -> Bool
forall a. Maybe a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Maybe a -> Bool) -> Maybe a -> Bool
forall a b. (a -> b) -> a -> b
$ (Maybe a -> Maybe a -> Maybe a) -> [Maybe a] -> Maybe a
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Maybe a -> Maybe a -> Maybe a
forall a b. Maybe a -> Maybe b -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>) [Maybe a]
numbers
maxNb :: a
maxNb = [a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ [Maybe a] -> [a]
forall a. [Maybe a] -> [a]
catMaybes [Maybe a]
numbers
in
if (Bool -> Bool
not Bool
anyMissing) Bool -> Bool -> Bool
&& ([Maybe a] -> Set (Maybe a)
forall a. [a] -> Set a
set (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> [a] -> [Maybe a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a
0..a
maxNb])) Set (Maybe a) -> Set (Maybe a) -> Bool
forall a. Eq a => a -> a -> Bool
== ([Maybe a] -> Set (Maybe a)
forall a. [a] -> Set a
set [Maybe a]
numbers) then a -> Maybe a
forall a. a -> Maybe a
Just (a
maxNb a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) else Maybe a
forall a. Maybe a
Nothing
toPair :: PureSet -> Maybe String
toPair PureSet
x
| Maybe PureSet -> Bool
forall a. Maybe a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (PureSet -> Maybe PureSet
maybeSecond PureSet
x) Bool -> Bool -> Bool
|| Maybe PureSet -> Bool
forall a. Maybe a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (PureSet -> Maybe PureSet
maybeFirst PureSet
x) = Maybe String
forall a. Maybe a
Nothing
| Bool
otherwise = String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (PureSet -> String
formatPureSet(PureSet -> String) -> (PureSet -> PureSet) -> PureSet -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> PureSet
first (PureSet -> String) -> PureSet -> String
forall a b. (a -> b) -> a -> b
$ PureSet
x) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"," String -> ShowS
forall a. [a] -> [a] -> [a]
++ (PureSet -> String
formatPureSet(PureSet -> String) -> (PureSet -> PureSet) -> PureSet -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.PureSet -> PureSet
second (PureSet -> String) -> PureSet -> String
forall a b. (a -> b) -> a -> b
$ PureSet
x) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"