module Lie.Classification ( Simple (..)
, SemiSimple (..)
) where
import Data.List (sortBy)
data Simple = A Int
| B Int
| C Int
| D Int
| E6 | E7 | E8
| F4
| G2
instance Eq Simple where
(==) (A n) (A m) = n == m
(==) (B n) (B m) = n == m
(==) (C n) (C m) = n == m
(==) (D n) (D m) = n == m
(==) E6 E6 = True
(==) E7 E7 = True
(==) E8 E8 = True
(==) F4 F4 = True
(==) G2 G2 = True
(==) (A 3) (D 3) = True
(==) (D 3) (A 3) = True
(==) (B 3) (C 3) = True
(==) (C 3) (B 3) = True
(==) _ _ = False
instance Show Simple where
show (A n) = wordIndex "A" n
show (B n) = wordIndex "B" n
show (C n) = wordIndex "C" n
show (D n) = wordIndex "D" n
show E6 = wordIndex "E" 6
show E7 = wordIndex "E" 7
show E8 = wordIndex "E" 8
show F4 = wordIndex "F" 4
show G2 = wordIndex "G" 2
wordIndex :: String -> Int -> String
wordIndex word n = word ++ indexSub n
where indexSub :: Int -> String
indexSub n
| n == 0 = []
| otherwise = indexSub(n `div` 10) ++ [ toEnum (n `mod` 10 + fromEnum '₀') ]
data SemiSimple = DirectSum [Simple]
instance Eq SemiSimple where
(==) (DirectSum xs) (DirectSum ys) = sortBy compareSimple xs == sortBy compareSimple ys
compareSimple :: Simple -> Simple -> Ordering
compareSimple x y
| x == y = EQ
| smallerEq x y = LT
| otherwise = GT
smallerEq :: Simple -> Simple -> Bool
smallerEq (A n) (A m) = n <= m
smallerEq (B n) (B m) = n <= m
smallerEq (C n) (C m) = n <= m
smallerEq (D n) (D m) = n <= m
smallerEq x y = (toInt) x <= (toInt y)
where toInt :: Simple -> Int
toInt (A _) = 1
toInt (B _) = 2
toInt (C _) = 3
toInt (D _) = 4
toInt E6 = 5
toInt E7 = 6
toInt E8 = 7
toInt F4 = 8
toInt G2 = 9
instance Show SemiSimple where
show (DirectSum (x:xs))
| null xs = show x
| otherwise = show x ++ " ⊕ " ++ show (DirectSum xs)