module Monocle.Rules where import Monocle.Core import Monocle.Markup import Monocle.Tex obA = object "A" obB = object "B" obC = object "C" obD = object "D" -- * Duality -- | For given object create it's left dual: . ldual'of :: Mor a -> Mor a ldual'of x = Func "ldual" [x] Function -- | Same as 'ldual'of', for usage in calculations. ldual :: Mor a -> Mor a ldual x = ldual'of x -- | Same as 'ldual'of', for usage in rule descriptions. ldual'r :: Mor a -> Mor a ldual'r x = ldual'of x -- | For given object create it's right dual: . rdual'of :: Mor a -> Mor a rdual'of x = Func "rdual" [x] Function -- | Same as 'rdual'of', for usage in calculations. rdual :: Mor a -> Mor a rdual x = rdual'of x -- | Same as 'rdual'of', for usage in rule descriptions. rdual'r :: Mor a -> Mor a rdual'r x = rdual'of x -- | For given dual pair of objects @(x, y)@ and name @nm@ call @unit'of nm x y@ to create named -- duality unit arrow. Generates error if @(x, y)@ is not a dual pair. unit'of :: (Eq a) => a -> Mor a -> Mor a -> Mor a unit'of nm x y = if (x == ldual y) || (y == rdual x) then let f = (element nm (y \* x)) in Transform "unit" f [x, y] else error "unit'of: not a dual pair" -- | Same as @'unit'of' \"\\\\eta\"@, for usage in calculations. unit :: Mor String -> Mor String -> Mor String unit = unit'of "\\eta" -- | Same as @'unit'of' \"*\\\\eta\"@, except that it does not check duality. For usage in -- rule descriptions. unit'r :: Mor String -> Mor String -> Mor String unit'r x y = let f = (element "*\\eta" (y \* x)) in Transform "unit" f [x, y] -- | For given dual pair of objects @(x, y)@ and name @nm@ call @counit'of nm x y@ to create named -- duality counit arrow. Generates error if @(x, y)@ is not a dual pair. counit'of :: (Eq a) => a -> Mor a -> Mor a -> Mor a counit'of nm x y = if (x == ldual y) || (y == rdual x) then let f = (coelement nm (x \* y)) in Transform "counit" f [x, y] else error "counit'of: not a dual pair" -- | Same as @'counit'of' \"\\\\epsilon\"@, for usage in calculations. counit :: Mor String -> Mor String -> Mor String counit = counit'of "\\epsilon" -- | Same as @'counit'of' \"*\\\\epsilon\"@, except that it does not check duality. For usage in -- rule descriptions. counit'r :: Mor String -> Mor String -> Mor String counit'r x y = let f = (coelement "*\\epsilon" (x \* y)) in Transform "counit" f [x, y] -- | One of \"zigzag rules\" for duality. zigzag'rule'Left :: Rule String zigzag'rule'Left = (counit'r obA obB) \* obA \. obA \* (unit'r obA obB) \== obA -- | One of \"zigzag rules\" for duality. zigzag'rule'Right :: Rule String zigzag'rule'Right = obB \* (counit'r obA obB) \. (unit'r obA obB) \* obB \== obB -- * Braiding -- | For given pair of objects @(x, y)@ and name @nm@ call @braid'of nm x y@ to create named -- braid arrow: braid'of :: (Eq a) => a -> Mor a -> Mor a -> Mor a braid'of nm x y = let f = (arrow nm (x \* y) (y \* x)) in Transform "braid" f [x, y] -- | Same as @'braid'of' \"\\\\beta\"@, for usage in calculations. braid :: Mor String -> Mor String -> Mor String braid x y = braid'of "\\beta" x y -- | Same as @'braid'of' \"*\\\\beta\"@, for usage in rule descriptions. braid'r :: Mor String -> Mor String -> Mor String braid'r x y = braid'of ("*\\beta") x y -- | For given pair of objects @(x, y)@ and name @nm@ call @unbraid'of nm x y@ to create named -- unbraid arrow (inverse of braid arrow). unbraid'of :: (Eq a) => a -> Mor a -> Mor a -> Mor a unbraid'of nm x y = let f = (arrow nm (x \* y) (y \* x)) in Transform "unbraid" f [x, y] -- | Same as @'unbraid'of' \"\\\\beta^{-1}\"@, for usage in calculations. unbraid :: Mor String -> Mor String -> Mor String unbraid x y = unbraid'of "\\beta^{-1}" x y -- | Same as @'unbraid'of' \"*\\\\beta^{-1}\"@, for usage in rule descriptions. unbraid'r :: Mor String -> Mor String -> Mor String unbraid'r x y = unbraid'of ("*\\beta^{-1}") x y -- | Isomorphism rule: 'unbraid' as inverse of 'braid'. braid'rule'Iso'Left :: Rule String braid'rule'Iso'Left = (unbraid'r obB obA) \. (braid'r obA obB) \== obA \* obB -- | Isomorphism rule: 'braid' as inverse of 'unbraid'. braid'rule'Iso'Right :: Rule String braid'rule'Iso'Right = (braid'r obB obA) \. (unbraid'r obA obB) \== obA \* obB -- | Naturality rule on the \"left wire\". braid'rule'Nat'Left :: Rule String braid'rule'Nat'Left = let f = arrow "f" obA obA in (braid'r obA obB) \. f \* obB \== obB \* f \. (braid'r obA obB) -- | Naturality rule on the \"right wire\". braid'rule'Nat'Right :: Rule String braid'rule'Nat'Right = let f = arrow "f" obB obB in (braid'r obA obB) \. obA \* f \== f \* obA \. (braid'r obA obB) -- | Hexagon identity for 'braid', strict monoidal case. braid'rule'Hex'Braid :: Rule String braid'rule'Hex'Braid = obB \* (braid'r obA obC) \. (braid'r obA obB) \* obC \== braid'r obA (obB \* obC) -- | Hexagon identity for 'unbraid', strict monoidal case. braid'rule'Hex'Unbraid :: Rule String braid'rule'Hex'Unbraid = obB \* (unbraid'r obA obC) \. (unbraid'r obA obB) \* obC \== unbraid'r obA (obB \* obC) -- * Symmetry -- | Rule for the \"cross\" arrow: it's simply self-inverse braid. cross'rule :: Rule String cross'rule = braid'r obA obB \== unbraid'r obA obB -- * Twisting -- | For given object @x@ and name @nm@ call @twist'of nm x@ to create named -- twist arrow. twist'of :: (Eq a) => a -> Mor a -> Mor a twist'of nm x = let f = (arrow nm x x) in Transform "twist" f [x] -- | Same as @'twist'of' \"\\\\theta\"@, for usage in calculations. twist :: Mor String -> Mor String twist x = twist'of "\\theta" x -- | Same as @'twist'of' \"*\\\\theta\"@, for usage in rule descriptions. twist'r :: Mor String -> Mor String twist'r x = twist'of ("*\\theta") x -- | For given object @x@ and name @nm@ call @untwist'of nm x@ to create named -- untwist arrow. untwist'of :: (Eq a) => a -> Mor a -> Mor a untwist'of nm x = let f = (arrow nm x x) in Transform "untwist" f [x] -- | Same as @'untwist'of' \"\\\\theta^{-1}\"@, for usage in calculations. untwist :: Mor String -> Mor String untwist x = untwist'of "\\theta^{-1}" x -- | Same as @'untwist'of' \"*\\\\theta^{-1}\"@, for usage in rule descriptions. untwist'r :: Mor String -> Mor String untwist'r x = untwist'of ("*\\theta^{-1}") x -- | Isomorphism rule: 'untwist' as inverse of 'twist'. twist'rule'Iso'Left :: Rule String twist'rule'Iso'Left = (untwist'r obA) \. (twist'r obA) \== obA \* obB -- | Isomorphism rule: 'twist' as inverse of 'untwist'. twist'rule'Iso'Right :: Rule String twist'rule'Iso'Right = (twist'r obA) \. (untwist'r obA) \== obA -- | Twisting the identity object changes nothing. twist'rule'Id :: Rule String twist'rule'Id = (twist'r tid) \== tid -- | Twisting naturality. twist'rule'Natural :: Rule String twist'rule'Natural = let f = arrow "f" obA obA in (twist'r obA) \. f \== f \. (twist'r obA) -- | Twist\/braid interaction. twist'rule'Braid :: Rule String twist'rule'Braid = (braid'r obB obA) \. (twist'r obB) \* (twist'r obA) \. (braid'r obA obB) \== twist'r (obA \* obB) -- * Dagger -- | @dagger'of f@ creates daggered version of the arrow @f@. dagger'of :: (Eq a) => Mor a -> Mor a dagger'of f = Func "dagger" [f] Cofunctor -- | Same as 'dagger'of', for usage in calculations. dagger :: (Eq a) => Mor a -> Mor a dagger = dagger'of -- | Same as 'dagger'of', for usage in rule descriptions. dagger'r :: (Eq a) => Mor a -> Mor a dagger'r f = dagger'of f -- | As contravariant functor 'dagger' maps id's to id's. dagger'rule'Id :: Rule String dagger'rule'Id = (dagger'r obA) \== obA -- | 'dagger' is contravariant functor, i.e. inverts composition order. dagger'rule'Cofunctor :: Rule String dagger'rule'Cofunctor = let f = arrow "f" obB obC; g = arrow "g" obA obB in (dagger'r (f \. g)) \== (dagger'r g) \. (dagger'r f) -- | 'dagger' involution rule. dagger'rule'Inv :: Rule String dagger'rule'Inv = let f = arrow "f" obA obA in (dagger'r $ dagger'r f) \== f