{-# LANGUAGE MultiParamTypeClasses #-}

{-| Module  : FiniteCategories
Description : The __'Square'__ category contains 4 generating arrows forming a square. It has 6 non identity arrows.
Copyright   : Guillaume Sabbagh 2022
License     : GPL-3
Maintainer  : guillaumesabbagh@protonmail.com
Stability   : experimental
Portability : portable

The __'Square'__ category contains 4 generating arrows forming a square. It has 6 non identity arrows.
-}

module Math.FiniteCategories.Square
(
    SquareOb(..),
    SquareAr(..),
    Square(..)
)
where
    import          Math.FiniteCategory
    import          Math.IO.PrettyPrint
    
    import          Data.WeakSet.Safe
    
    -- | Objects of the __'Square'__ category.

    data SquareOb = SquareA | SquareB | SquareC | SquareD deriving (SquareOb -> SquareOb -> Bool
(SquareOb -> SquareOb -> Bool)
-> (SquareOb -> SquareOb -> Bool) -> Eq SquareOb
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SquareOb -> SquareOb -> Bool
$c/= :: SquareOb -> SquareOb -> Bool
== :: SquareOb -> SquareOb -> Bool
$c== :: SquareOb -> SquareOb -> Bool
Eq, Int -> SquareOb -> ShowS
[SquareOb] -> ShowS
SquareOb -> String
(Int -> SquareOb -> ShowS)
-> (SquareOb -> String) -> ([SquareOb] -> ShowS) -> Show SquareOb
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SquareOb] -> ShowS
$cshowList :: [SquareOb] -> ShowS
show :: SquareOb -> String
$cshow :: SquareOb -> String
showsPrec :: Int -> SquareOb -> ShowS
$cshowsPrec :: Int -> SquareOb -> ShowS
Show)
    
    -- | Morphisms of the __'Square'__ category.

    data SquareAr = SquareIdA | SquareIdB | SquareIdC | SquareIdD | SquareF | SquareG | SquareH | SquareI | SquareFH | SquareGI deriving (SquareAr -> SquareAr -> Bool
(SquareAr -> SquareAr -> Bool)
-> (SquareAr -> SquareAr -> Bool) -> Eq SquareAr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SquareAr -> SquareAr -> Bool
$c/= :: SquareAr -> SquareAr -> Bool
== :: SquareAr -> SquareAr -> Bool
$c== :: SquareAr -> SquareAr -> Bool
Eq, Int -> SquareAr -> ShowS
[SquareAr] -> ShowS
SquareAr -> String
(Int -> SquareAr -> ShowS)
-> (SquareAr -> String) -> ([SquareAr] -> ShowS) -> Show SquareAr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SquareAr] -> ShowS
$cshowList :: [SquareAr] -> ShowS
show :: SquareAr -> String
$cshow :: SquareAr -> String
showsPrec :: Int -> SquareAr -> ShowS
$cshowsPrec :: Int -> SquareAr -> ShowS
Show)
    
    -- | The __'Square'__ category.

    data Square = Square deriving (Square -> Square -> Bool
(Square -> Square -> Bool)
-> (Square -> Square -> Bool) -> Eq Square
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Square -> Square -> Bool
$c/= :: Square -> Square -> Bool
== :: Square -> Square -> Bool
$c== :: Square -> Square -> Bool
Eq, Int -> Square -> ShowS
[Square] -> ShowS
Square -> String
(Int -> Square -> ShowS)
-> (Square -> String) -> ([Square] -> ShowS) -> Show Square
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Square] -> ShowS
$cshowList :: [Square] -> ShowS
show :: Square -> String
$cshow :: Square -> String
showsPrec :: Int -> Square -> ShowS
$cshowsPrec :: Int -> Square -> ShowS
Show)
    
    instance Morphism SquareAr SquareOb where
        source :: SquareAr -> SquareOb
source SquareAr
SquareIdA = SquareOb
SquareA
        source SquareAr
SquareIdB = SquareOb
SquareB
        source SquareAr
SquareIdC = SquareOb
SquareC
        source SquareAr
SquareIdD = SquareOb
SquareD
        source SquareAr
SquareF = SquareOb
SquareA
        source SquareAr
SquareG = SquareOb
SquareA
        source SquareAr
SquareH = SquareOb
SquareB
        source SquareAr
SquareI = SquareOb
SquareC
        source SquareAr
SquareFH = SquareOb
SquareA
        source SquareAr
SquareGI = SquareOb
SquareA
        
        target :: SquareAr -> SquareOb
target SquareAr
SquareIdA = SquareOb
SquareA
        target SquareAr
SquareIdB = SquareOb
SquareB
        target SquareAr
SquareIdC = SquareOb
SquareC
        target SquareAr
SquareIdD = SquareOb
SquareD
        target SquareAr
SquareF = SquareOb
SquareB
        target SquareAr
SquareG = SquareOb
SquareC
        target SquareAr
SquareH = SquareOb
SquareD
        target SquareAr
SquareI = SquareOb
SquareD
        target SquareAr
SquareFH = SquareOb
SquareD
        target SquareAr
SquareGI = SquareOb
SquareD
        
        @? :: SquareAr -> SquareAr -> Maybe SquareAr
(@?) SquareAr
SquareIdA SquareAr
SquareIdA = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareIdA
        (@?) SquareAr
SquareF SquareAr
SquareIdA = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareF
        (@?) SquareAr
SquareG SquareAr
SquareIdA = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareG
        (@?) SquareAr
SquareFH SquareAr
SquareIdA = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareFH
        (@?) SquareAr
SquareGI SquareAr
SquareIdA = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareGI
        (@?) SquareAr
SquareIdB SquareAr
SquareIdB = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareIdB
        (@?) SquareAr
SquareH SquareAr
SquareIdB = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareH
        (@?) SquareAr
SquareIdC SquareAr
SquareIdC = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareIdC
        (@?) SquareAr
SquareI SquareAr
SquareIdC = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareI
        (@?) SquareAr
SquareIdD SquareAr
SquareIdD = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareIdD
        (@?) SquareAr
SquareIdB SquareAr
SquareF = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareF
        (@?) SquareAr
SquareH SquareAr
SquareF = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareFH
        (@?) SquareAr
SquareIdC SquareAr
SquareG = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareG
        (@?) SquareAr
SquareI SquareAr
SquareG = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareGI
        (@?) SquareAr
SquareIdD SquareAr
SquareH = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareH
        (@?) SquareAr
SquareIdD SquareAr
SquareI = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareI
        (@?) SquareAr
SquareIdD SquareAr
SquareFH = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareFH
        (@?) SquareAr
SquareIdD SquareAr
SquareGI = SquareAr -> Maybe SquareAr
forall a. a -> Maybe a
Just SquareAr
SquareGI
        (@?) SquareAr
_ SquareAr
_ = Maybe SquareAr
forall a. Maybe a
Nothing
        
    instance Category Square SquareAr SquareOb where
        identity :: Morphism SquareAr SquareOb => Square -> SquareOb -> SquareAr
identity Square
_ SquareOb
SquareA = SquareAr
SquareIdA
        identity Square
_ SquareOb
SquareB = SquareAr
SquareIdB
        identity Square
_ SquareOb
SquareC = SquareAr
SquareIdC
        identity Square
_ SquareOb
SquareD = SquareAr
SquareIdD
        
        ar :: Morphism SquareAr SquareOb =>
Square -> SquareOb -> SquareOb -> Set SquareAr
ar Square
_ SquareOb
SquareA SquareOb
SquareA = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdA]
        ar Square
_ SquareOb
SquareA SquareOb
SquareB = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareF]
        ar Square
_ SquareOb
SquareA SquareOb
SquareC = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareG]
        ar Square
_ SquareOb
SquareA SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareFH,SquareAr
SquareGI]
        ar Square
_ SquareOb
SquareB SquareOb
SquareB = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdB]
        ar Square
_ SquareOb
SquareB SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareH]
        ar Square
_ SquareOb
SquareC SquareOb
SquareC = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdC]
        ar Square
_ SquareOb
SquareC SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareI]
        ar Square
_ SquareOb
SquareD SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdD]
        ar Square
_ SquareOb
_ SquareOb
_ = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set []
        
        genAr :: Morphism SquareAr SquareOb =>
Square -> SquareOb -> SquareOb -> Set SquareAr
genAr Square
_ SquareOb
SquareA SquareOb
SquareA = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdA]
        genAr Square
_ SquareOb
SquareA SquareOb
SquareB = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareF]
        genAr Square
_ SquareOb
SquareA SquareOb
SquareC = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareG]
        genAr Square
_ SquareOb
SquareB SquareOb
SquareB = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdB]
        genAr Square
_ SquareOb
SquareB SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareH]
        genAr Square
_ SquareOb
SquareC SquareOb
SquareC = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdC]
        genAr Square
_ SquareOb
SquareC SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareI]
        genAr Square
_ SquareOb
SquareD SquareOb
SquareD = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set [SquareAr
SquareIdD]
        genAr Square
_ SquareOb
_ SquareOb
_ = [SquareAr] -> Set SquareAr
forall a. [a] -> Set a
set []
        
        decompose :: Morphism SquareAr SquareOb => Square -> SquareAr -> [SquareAr]
decompose Square
_ SquareAr
SquareFH = [SquareAr
SquareH, SquareAr
SquareF]
        decompose Square
_ SquareAr
SquareGI = [SquareAr
SquareI, SquareAr
SquareG]
        decompose Square
_ SquareAr
x = [SquareAr
x]
        
    instance FiniteCategory Square SquareAr SquareOb where
        ob :: Square -> Set SquareOb
ob Square
_ = [SquareOb] -> Set SquareOb
forall a. [a] -> Set a
set [SquareOb
SquareA, SquareOb
SquareB, SquareOb
SquareC, SquareOb
SquareD]
    
    instance PrettyPrint SquareOb where
        pprint :: SquareOb -> String
pprint SquareOb
SquareA = String
"A"
        pprint SquareOb
SquareB = String
"B"
        pprint SquareOb
SquareC = String
"C"
        pprint SquareOb
SquareD = String
"D"
    
    instance PrettyPrint SquareAr where
        pprint :: SquareAr -> String
pprint SquareAr
SquareIdA = String
"IdA"
        pprint SquareAr
SquareIdB = String
"IdB"
        pprint SquareAr
SquareIdC = String
"IdC"
        pprint SquareAr
SquareIdD = String
"IdD"
        pprint SquareAr
SquareF = String
"f"
        pprint SquareAr
SquareG = String
"g"
        pprint SquareAr
SquareH = String
"h"
        pprint SquareAr
SquareI = String
"i"
        pprint SquareAr
SquareFH = String
"h o f"
        pprint SquareAr
SquareGI = String
"i o g"
    
    instance PrettyPrint Square where
        pprint :: Square -> String
pprint = Square -> String
forall a. Show a => a -> String
show