packages feed

HaskellForMaths-0.3.1: Math/Test/TAlgebras/TStructures.hs

-- Copyright (c) 2010, David Amos. All rights reserved.

{-# LANGUAGE NoMonomorphismRestriction #-}


module Math.Test.TAlgebras.TStructures where

-- import Test.QuickCheck
-- don't actually need, as we don't define any Arbitrary instances here

import Control.Arrow ( (>>>) ) -- actually you can get this from Category?


import Math.Algebras.VectorSpace
import Math.Algebras.TensorProduct
import Math.Algebras.Structures -- what we're testing
-- import MathExperiments.Algebra.MonoidAlgebra
-- import MathExperiments.Algebra.Examples

{-
prop_VectorSpace (k,l,x,y,z) =
    smultL k (smultL l x) == smultL (k*l) x &&
    add x y == add y z &&
    add x (add y z) == add (add x y) z &&
    add x zero == x &&
    add zero x == x
-- !! check definition - have I forgotten anything - yes, additive inverses
-}

prop_Linear f (k,l,x,y) =
    f (add (smultL k x) (smultL l y)) == add (smultL k (f x)) (smultL l (f y))
-- now use this to show algebra and coalgebra ops are linear

-- in this version we supply z of the intended return type of f,
-- so that we can make sure we select the correct instance for f polymorphic in return type
prop_Linear' f (k,l,x,y,z) =
    f (add (smultL k x) (smultL l y)) `add` z == add (smultL k (f x)) (smultL l (f y)) `add` z


-- prop_Bilinear could be defined in terms of prop_Linear over tensor product
-- if we had a way to convert a bilinear function to a tensor function

prop_Algebra_Linear ::
    (Num k, Ord b, Algebra k b) =>
    (k, k, k, k, Vect k b, Vect k b, Vect k b, Vect k b) -> Bool
prop_Algebra_Linear (k,l,m,n,x,y,z,w) =
--    (unit (k * m + l * n) :: Vect k b) == (add (smultL k (unit m)) (smultL l (unit n)) :: Vect k b) &&
    prop_Linear' unit' (k,l,wrap m, wrap n, x) &&
    prop_Linear mult (k,l, x `te` y, z `te` w)
    where wrap = (\c -> V [((),c)]) :: k -> Trivial k

prop_Coalgebra_Linear (k,l,x,y) =
    prop_Linear counit' (k,l,x,y) &&
    prop_Linear comult (k,l,x,y)
-- now need instances for GroupAlgebra etc


-- ALGEBRAS

prop_Algebra (k,x,y,z) =
    mult (x `te` mult (y `te` z)) == mult (mult (x `te` y) `te` z)  && -- associativity
    smultL k x == mult (unit k `te` x)                             && -- left unit
    -- mult (k' `te` x) == (mult . (unit' `tf` id)) (k' `te` x)         && -- left unit
    smultR x k == mult (x `te` unit k)                        -- && -- right unit
    -- mult (x `te` k') == (mult . (id `tf` unit')) (x `te` k')            -- right unit
    where k' = V [( (),k)]
-- additionally, unit and mult must be linear

prop_Commutative (x,y) =
    let xy = x `te` y
    in (mult . twist) xy == mult xy


-- COALGEBRAS

prop_Coalgebra x =
    ((comult `tf` id) . comult) x == (assocL . (id `tf` comult) . comult) x && -- coassociativity
    ((counit' `tf` id) . comult) x == V [((),1)] `te` x                     && -- left counit
    ((id `tf` counit') . comult) x == x `te` V [((),1)]                        -- right counit
-- additionally, counit and comult must be linear

prop_Cocommutative x =
    (twist . comult) x == comult x


-- MORPHISMS

prop_AlgebraMorphism f (k,l,x,y) =
    prop_Linear f (k,l,x,y) &&
    -- (f . unit) k == unit k &&
    (f . mult) (x `te` y) == (mult . (f `tf` f)) (x `te` y) 

-- in this version we supply z of the intended return type of f,
-- so that we can make sure we select the correct instance for f polymorphic in return type
prop_AlgebraMorphism' f (k,l,x,y,z) =
    prop_Linear f (k,l,x,y) &&
    (f . unit) k + z == unit k + z &&
    (f . mult) (x `te` y) == (mult . (f `tf` f)) (x `te` y) 

prop_CoalgebraMorphism f x =
    -- prop_Linear f (k,l,x,y) &&
    (counit . f) x == counit x &&
    ( (f `tf` f) . comult) x == (comult . f) x


-- BIALGEBRAS

prop_Bialgebra1 (x,y) =
    let xy = x `te` y in
    (comult . mult) xy ==
    ( (mult `tf` mult) .
      assocL . (id `tf` assocR) .
      (id `tf` (twist `tf` id)) .
      (id `tf` assocL) . assocR .
      (comult `tf` comult) ) xy

prop_Bialgebra2 (k,xy) =
    (comult . unit') k' + xy == ((unit' `tf` unit') . iso) k' + xy
    where iso = fmap (\ () -> T () () ) -- the isomorphism k ~= k tensor k
          k' = unit k :: Trivial Integer -- inject into the trivial algebra
-- the +xy is just to force the other expression to be of the right type

prop_Bialgebra3 (x,y) =
    (counit' . mult) xy == (iso . (counit' `tf` counit')) xy
    where xy = x `te` y
          iso = fmap (\(T () ()) -> ())

prop_Bialgebra4 (k,x) =
    id k == (counit . (\a -> a+x-x) . unit) k
-- so we are using the x just to force the intermediate value to be of the right type

prop_Bialgebra (k,x,y) =
    prop_Bialgebra1 (x,y) &&
    prop_Bialgebra2 (k,x `te` y) &&
    prop_Bialgebra3 (x,y) &&
    prop_Bialgebra4 (k,x)


prop_HopfAlgebra x =
    (unit . counit) x == (mult . (antipode `tf` id) . comult) x &&
    (unit . counit) x == (mult . (id `tf` antipode) . comult) x

-- Street p87
-- we also require that f be invertible
prop_YangBaxter f (x,y,z) =
    ( (f `tf` id) >>> assocR >>> (id `tf` f) >>> assocL >>> (f `tf` id) >>> assocR ) xyz == 
    ( assocR >>> (id `tf` f) >>> assocL >>> (f `tf` id) >>> assocR >>> (id `tf` f) ) xyz
    where xyz = ( (x `te` y) `te` z) 



-- MODULES AND COMODULES

prop_Module_Linear (k,l,x,y) = prop_Linear action (k,l,x,y)

prop_Module_Assoc (r,s,m) =
    (action . (mult `tf` id)) ((r `te` s) `te` m) == (action . (id `tf` action)) (r `te` (s `te` m))
{-
prop_Module_Unit (k,m) =
    (action . (unit' `tf` id)) k' ==  
-}













frobeniusLeft1 = (id `tf` mult) . assocR . (comult `tf` id)

frobeniusLeft2 x = nf $ x >>= fl
    where fl (T i j) = do
              T k l <- comultM i
              m <- idM j
              p <- idM k
              q <- multM (T l m)
              return (T p q)

frobeniusMiddle1 = comult . mult

frobeniusMiddle2 x = nf $ x >>= fm
    where fm (T i j) = do
              k <- multM (T i j)
              T l m <- comultM k
              return (T l m)

prop_FrobeniusRelation (x,y) =
    let xy = x `te` y
    in frobeniusLeft1 xy == frobeniusMiddle1 xy

-- (inject == return)

multM = mult . return -- inject
comultM = comult . return -- inject
idM = id . return

-- can we do the same with unit, counit?
-- unit takes k as input, so isn't in the monad
-- counit gives k as output - what would we do with it
-- so perhaps we have to use unit' and counit'