{-# LANGUAGE FunctionalDependencies #-}
---------------------------------------------------------------------------------------------------
-- |
-- Module      : LieAlgebra
-- Description : Translation of a mathematical definition of a Lie Algebra into a Class LieAlgebra
-- Copyright   : (c) Felix Springer, 2019
-- License     : BSD3
-- Maintainer  : felixspringer149@gmail.com
-- Stability   : experimental
-- Portability : POSIX
--
-- This module translates the mathematical definition of a Lie Algebra into a Class LieAlgebra,
-- which also wraps around the other modules.
--
---------------------------------------------------------------------------------------------------

module Lie.LieAlgebra ( LieAlgebra (..)
                      ) where

-- | Vectorspace with Lie Bracket
class LieAlgebra a s | a -> s where

  -- | Addition should satisfy the following attributes.
  --
  --   - Associativity:
  --
  --     prop> (x |+| y) |+| z == x |+| (y |+| z)
  --
  --   - Commutativity:
  --
  --     prop> x |+| y == y |+| x
  --
  --   - Neutral element 0 exists:
  --
  --     prop> x |+| 0 == x
  --
  --   - Inverse element (-x) exists:
  --
  --     prop> x |+| (-x) == 0
  --
  (|+|) :: a -> a -> a

  -- | Scalar Multiplication should satisfy the following attributes.
  --
  --   - Distributivity:
  --
  --     prop> a |*| (x |+| y) == (a |*| x) |+| (a |*| y)
  --
  --   - Neutral element 1 exists:
  --
  --     prop> 1 |*| x == x
  --
  (|*|) :: s -> a -> a

  -- | Lie Bracket should satisfy the following attributes.
  --
  --   - Bilinearity:
  --
  --     prop> a |*| (x |.| y) == (a |*| x) |.| y
  --     prop> (x |+| y) |.| z == (x |.| z) |+| (y |.| z)
  --
  --   - Antisymmetry:
  --
  --     prop> x |.| y == - (y |.| x)
  --
  --   - Jacobi-Identity:
  --
  --     prop> x |.| (y |.| z) + y |.| (z |.| x) + z |.| (x |.| y) = 0
  --
  (|.|) :: a -> a -> a

  -- | Ordered Basis Vectors of the Lie Algebra:
  --
  --   - linearly independent
  --   - span the whole Vectorspace
  basis :: [a]

  -- | Linear Combination of basis vectors, where the order refers to the Basis and the values are
  -- the coefficients
  linearCombination :: [s] -> a
  linearCombination coeffs = sumVectors $ zipWith (|*|) coeffs basis
    where sumVectors (v:[]) = v
          sumVectors (v:vs) = v |+| (sumVectors vs)

  -- | Natural way one would define a dual to the elements in the Lie Algebra
  adjunction :: a -> (a -> a)
  adjunction a = (|.|) a

  -- | Calculates the Trace of an object in the Dual Vectorspace of the Lie Algebra
  trace :: (a -> a) -> s

  -- | Killing Form, which is a scalar product on the Dual Vectorspace of the Lie Algebra
  (<|>) :: (a -> a) -> (a -> a) -> s
  (<|>) a b = trace $ a . b