{-# language CPP #-}
{-# language DerivingStrategies #-}
{-# language FlexibleInstances #-}
{-# language PackageImports #-}
{-# language PatternSynonyms #-}
{-# language Safe #-}
#if MIN_VERSION_base(4,12,0)
{-# language TypeOperators #-}
#endif
{-# language ViewPatterns #-}
module Data.Group
(
G.Group(..)
, minus
, gtimes
, (><)
, conjugate
, unconjugate
, pattern Conjugate
, pattern Inverse
, pattern IdentityElem
, Abelianizer(..)
, abelianize
, commutate
, pattern Abelianized
, pattern Quotiented
, G.Abelian
) where
import Data.Bool
import "groups" Data.Group as G
import Data.Monoid
import Prelude hiding (negate, exponent)
infixr 6 ><
gtimes :: (Group a, Integral n) => n -> a -> a
gtimes :: n -> a -> a
gtimes = (a -> n -> a) -> n -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> n -> a
forall m x. (Group m, Integral x) => m -> x -> m
pow
{-# inline gtimes #-}
minus :: Group a => a -> a -> a
minus :: a -> a -> a
minus a
a a
b = a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a
forall m. Group m => m -> m
invert a
b
{-# inline minus #-}
(><) :: Group a => a -> a -> a
a
a >< :: a -> a -> a
>< a
b = a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a
{-# inline (><) #-}
conjugate :: Group a => a -> a -> a
conjugate :: a -> a -> a
conjugate a
g a
a = (a
g a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a) a -> a -> a
forall a. Group a => a -> a -> a
`minus` a
g
{-# inline conjugate #-}
unconjugate :: Group a => a -> a -> a
unconjugate :: a -> a -> a
unconjugate a
g a
a = a -> a
forall m. Group m => m -> m
invert a
g a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
g
pattern Conjugate :: Group a => (a,a) -> (a,a)
pattern $bConjugate :: (a, a) -> (a, a)
$mConjugate :: forall r a. Group a => (a, a) -> ((a, a) -> r) -> (Void# -> r) -> r
Conjugate t <- (\(g,a) -> (g, conjugate g a) -> t) where
Conjugate (a
g,a
a) = (a
g, a -> a -> a
forall a. Group a => a -> a -> a
unconjugate a
g a
a)
{-# complete Conjugate #-}
pattern Inverse :: (Group g) => g -> g
pattern $bInverse :: g -> g
$mInverse :: forall r g. Group g => g -> (g -> r) -> (Void# -> r) -> r
Inverse t <- (invert -> t) where
Inverse g
g = g -> g
forall m. Group m => m -> m
invert g
g
pattern IdentityElem :: (Eq m, Monoid m) => m
pattern $bIdentityElem :: m
$mIdentityElem :: forall r m.
(Eq m, Monoid m) =>
m -> (Void# -> r) -> (Void# -> r) -> r
IdentityElem <- ((== mempty) -> True) where
IdentityElem = m
forall a. Monoid a => a
mempty
data Abelianizer a = Quot | Commuted a
deriving stock (Abelianizer a -> Abelianizer a -> Bool
(Abelianizer a -> Abelianizer a -> Bool)
-> (Abelianizer a -> Abelianizer a -> Bool) -> Eq (Abelianizer a)
forall a. Eq a => Abelianizer a -> Abelianizer a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Abelianizer a -> Abelianizer a -> Bool
$c/= :: forall a. Eq a => Abelianizer a -> Abelianizer a -> Bool
== :: Abelianizer a -> Abelianizer a -> Bool
$c== :: forall a. Eq a => Abelianizer a -> Abelianizer a -> Bool
Eq, Int -> Abelianizer a -> ShowS
[Abelianizer a] -> ShowS
Abelianizer a -> String
(Int -> Abelianizer a -> ShowS)
-> (Abelianizer a -> String)
-> ([Abelianizer a] -> ShowS)
-> Show (Abelianizer a)
forall a. Show a => Int -> Abelianizer a -> ShowS
forall a. Show a => [Abelianizer a] -> ShowS
forall a. Show a => Abelianizer a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Abelianizer a] -> ShowS
$cshowList :: forall a. Show a => [Abelianizer a] -> ShowS
show :: Abelianizer a -> String
$cshow :: forall a. Show a => Abelianizer a -> String
showsPrec :: Int -> Abelianizer a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Abelianizer a -> ShowS
Show)
instance Functor Abelianizer where
fmap :: (a -> b) -> Abelianizer a -> Abelianizer b
fmap a -> b
_ Abelianizer a
Quot = Abelianizer b
forall a. Abelianizer a
Quot
fmap a -> b
f (Commuted a
a) = b -> Abelianizer b
forall a. a -> Abelianizer a
Commuted (a -> b
f a
a)
instance Applicative Abelianizer where
pure :: a -> Abelianizer a
pure = a -> Abelianizer a
forall a. a -> Abelianizer a
Commuted
Abelianizer (a -> b)
Quot <*> :: Abelianizer (a -> b) -> Abelianizer a -> Abelianizer b
<*> Abelianizer a
_ = Abelianizer b
forall a. Abelianizer a
Quot
Abelianizer (a -> b)
_ <*> Abelianizer a
Quot = Abelianizer b
forall a. Abelianizer a
Quot
Commuted a -> b
f <*> Commuted a
a = b -> Abelianizer b
forall a. a -> Abelianizer a
Commuted (a -> b
f a
a)
instance Monad Abelianizer where
return :: a -> Abelianizer a
return = a -> Abelianizer a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
>> :: Abelianizer a -> Abelianizer b -> Abelianizer b
(>>) = Abelianizer a -> Abelianizer b -> Abelianizer b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
Abelianizer a
Quot >>= :: Abelianizer a -> (a -> Abelianizer b) -> Abelianizer b
>>= a -> Abelianizer b
_ = Abelianizer b
forall a. Abelianizer a
Quot
Commuted a
a >>= a -> Abelianizer b
f = a -> Abelianizer b
f a
a
instance Foldable Abelianizer where
foldMap :: (a -> m) -> Abelianizer a -> m
foldMap a -> m
_ Abelianizer a
Quot = m
forall a. Monoid a => a
mempty
foldMap a -> m
f (Commuted a
a) = a -> m
f a
a
instance Traversable Abelianizer where
traverse :: (a -> f b) -> Abelianizer a -> f (Abelianizer b)
traverse a -> f b
_ Abelianizer a
Quot = Abelianizer b -> f (Abelianizer b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Abelianizer b
forall a. Abelianizer a
Quot
traverse a -> f b
f (Commuted a
a) = b -> Abelianizer b
forall a. a -> Abelianizer a
Commuted (b -> Abelianizer b) -> f b -> f (Abelianizer b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a
instance Semigroup g => Semigroup (Abelianizer g) where
Abelianizer g
Quot <> :: Abelianizer g -> Abelianizer g -> Abelianizer g
<> Abelianizer g
t = Abelianizer g
t
Abelianizer g
t <> Abelianizer g
Quot = Abelianizer g
t
Commuted g
a <> Commuted g
b = g -> Abelianizer g
forall a. a -> Abelianizer a
Commuted (g
a g -> g -> g
forall a. Semigroup a => a -> a -> a
<> g
b)
instance Monoid g => Monoid (Abelianizer g) where
mempty :: Abelianizer g
mempty = Abelianizer g
forall a. Abelianizer a
Quot
instance (Eq g, Group g) => Group (Abelianizer g) where
invert :: Abelianizer g -> Abelianizer g
invert Abelianizer g
Quot = Abelianizer g
forall a. Abelianizer a
Quot
invert (Commuted g
IdentityElem) = Abelianizer g
forall a. Abelianizer a
Quot
invert (Commuted g
a) = g -> Abelianizer g
forall a. a -> Abelianizer a
Commuted (g -> g
forall m. Group m => m -> m
invert g
a)
commutate :: Group g => g -> g -> g
commutate :: g -> g -> g
commutate g
g g
g' = g
g g -> g -> g
forall a. Semigroup a => a -> a -> a
<> g
g' g -> g -> g
forall a. Semigroup a => a -> a -> a
<> g -> g
forall m. Group m => m -> m
invert g
g g -> g -> g
forall a. Semigroup a => a -> a -> a
<> g -> g
forall m. Group m => m -> m
invert g
g'
{-# inline commutate #-}
abelianize :: (Eq g, Group g) => g -> g -> Abelianizer g
abelianize :: g -> g -> Abelianizer g
abelianize g
g g
g'
| g
x g -> g -> Bool
forall a. Eq a => a -> a -> Bool
== g
forall a. Monoid a => a
mempty = Abelianizer g
forall a. Abelianizer a
Quot
| Bool
otherwise = g -> Abelianizer g
forall a. a -> Abelianizer a
Commuted g
x
where
x :: g
x = g -> g -> g
forall a. Group a => a -> a -> a
commutate g
g g
g'
{-# inline abelianize #-}
pattern Abelianized :: (Eq g, Group g) => g -> (g,g)
pattern $mAbelianized :: forall r g.
(Eq g, Group g) =>
(g, g) -> (g -> r) -> (Void# -> r) -> r
Abelianized x <- (uncurry abelianize -> Commuted x)
pattern Quotiented :: (Eq g, Group g) => (g,g)
pattern $mQuotiented :: forall r g.
(Eq g, Group g) =>
(g, g) -> (Void# -> r) -> (Void# -> r) -> r
Quotiented <- (uncurry abelianize -> Quot)