{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses, NoMonomorphismRestriction #-}
module Math.QuantumAlgebra.QuantumPlane where
import Math.Algebra.Field.Base hiding (powers)
import Math.Algebras.VectorSpace
import Math.Algebras.TensorProduct
import Math.Algebras.Structures
import Math.Algebras.LaurentPoly
import Math.Algebras.NonCommutative
import qualified Data.List as L
qvar v = let V [(m,1)] = var v in V [(m,1 :: LaurentPoly Q)]
a = qvar "a"
b = qvar "b"
c = qvar "c"
d = qvar "d"
detq = a*d-unit q'*b*c
x = qvar "x"
y = qvar "y"
u = qvar "u"
v = qvar "v"
aq20 = [y*x-unit q*x*y]
newtype Aq20 v = Aq20 (NonComMonomial v) deriving (Eq,Ord)
instance (Eq v, Show v) => Show (Aq20 v) where show (Aq20 m) = show m
instance Monomial Aq20 where
    var v = V [(Aq20 (NCM 1 [v]),1)]
    powers (Aq20 m) = powers m
instance Algebra (LaurentPoly Q) (Aq20 String) where
    unit 0 = zerov 
    unit x = V [(munit,x)] where munit = Aq20 (NCM 0 [])
    mult x = x''' where
        x' = mult $ fmap ( \(Aq20 a, Aq20 b) -> (a,b) ) x 
        x'' = x' %% aq20 
        x''' = fmap Aq20 x'' 
aq02 = [u^2, v^2, u*v+unit q*v*u]
newtype Aq02 v = Aq02 (NonComMonomial v) deriving (Eq,Ord)
instance (Eq v, Show v) => Show (Aq02 v) where show (Aq02 m) = show m
instance Monomial Aq02 where
    var v = V [(Aq02 (NCM 1 [v]),1)]
    powers (Aq02 m) = powers m
instance Algebra (LaurentPoly Q) (Aq02 String) where
    unit 0 = zerov 
    unit x = V [(munit,x)] where munit = Aq02 (NCM 0 [])
    mult x = x''' where
        x' = mult $ fmap ( \(Aq02 a, Aq02 b) -> (a,b) ) x 
        x'' = x' %% aq02 
        x''' = fmap Aq02 x'' 
m2q = [a*b-unit q'*b*a, a*c-unit q'*c*a, c*d-unit q'*d*c, b*d-unit q'*d*b,
       b*c-c*b, a*d-d*a-unit (q'-q)*b*c]
newtype M2q v = M2q (NonComMonomial v) deriving (Eq,Ord)
instance (Eq v, Show v) => Show (M2q v) where show (M2q m) = show m
instance Monomial M2q where
    var v = V [(M2q (NCM 1 [v]),1)]
    powers (M2q m) = powers m
instance Algebra (LaurentPoly Q) (M2q String) where
    unit 0 = zerov 
    unit x = V [(munit,x)] where munit = M2q (NCM 0 [])
    mult x = x''' where
        x' = mult $ fmap ( \(M2q a, M2q b) -> (a,b) ) x 
        x'' = x' %% m2q 
        x''' = fmap M2q x'' 
instance Coalgebra (LaurentPoly Q) (M2q String) where
    counit x = case x `bind` cu of
               V [] -> 0
               V [(M2q (NCM 0 []), c)] -> c
        where cu "a" = 1 :: Vect (LaurentPoly Q) (M2q String)
              cu "b" = 0
              cu "c" = 0
              cu "d" = 1
    comult x = x `bind` cm
        where cm "a" = a `te` a + b `te` c
              cm "b" = a `te` b + b `te` d
              cm "c" = c `te` a + d `te` c
              cm "d" = c `te` b + d `te` d
instance Bialgebra (LaurentPoly Q) (M2q String) where {}
instance Comodule (LaurentPoly Q) (M2q String) (Aq20 String) where
    coaction xy = xy `bind` ca where
        ca "x" = (a `te` x) + (b `te` y) 
        ca "y" = (c `te` x) + (d `te` y)
sl2q = [a*b-unit q'*b*a, a*c-unit q'*c*a, c*d-unit q'*d*c, b*d-unit q'*d*b,
        b*c-c*b, a*d-d*a-unit (q'-q)*b*c,
        -unit q*c*b + d*a - 1] 
newtype SL2q v = SL2q (NonComMonomial v) deriving (Eq,Ord)
instance (Eq v, Show v) => Show (SL2q v) where show (SL2q m) = show m
instance Monomial SL2q where
    var v = V [(SL2q (NCM 1 [v]),1)]
    powers (SL2q m) = powers m
instance Algebra (LaurentPoly Q) (SL2q String) where
    unit 0 = zerov 
    unit x = V [(munit,x)] where munit = SL2q (NCM 0 [])
    mult x = x''' where
        x' = mult $ fmap ( \(SL2q a, SL2q b) -> (a,b) ) x 
        x'' = x' %% sl2q 
        x''' = fmap SL2q x'' 
instance Coalgebra (LaurentPoly Q) (SL2q String) where
    counit x = case x `bind` cu of
               V [] -> 0
               V [(SL2q (NCM 0 []), c)] -> c
        where cu "a" = 1 :: Vect (LaurentPoly Q) (SL2q String)
              cu "b" = 0
              cu "c" = 0
              cu "d" = 1
    comult x = x `bind` cm
        where cm "a" = a `te` a + b `te` c
              cm "b" = a `te` b + b `te` d
              cm "c" = c `te` a + d `te` c
              cm "d" = c `te` b + d `te` d
instance Bialgebra (LaurentPoly Q) (SL2q String) where {}
instance HopfAlgebra (LaurentPoly Q) (SL2q String) where
    antipode x = x `bind` antipode'
        where antipode' "a" = d
              antipode' "b" = - unit q * b
              antipode' "c" = - unit q' * c
              antipode' "d" = a
yb x = nf $ x >>= yb' where
    yb' (a,b) = case compare a b of
                 GT -> return (b,a)
                 LT -> return (b,a) + unit (q-q') * return (a,b)
                 EQ -> unit q * return (a,a)