packages feed

FiniteCategories 0.2.0.0 → 0.3.0.0

raw patch · 36 files changed

+659/−760 lines, 36 filesdep −fgldep −graphvizdep −processdep ~WeakSetsdep ~basedep ~containersPVP ok

version bump matches the API change (PVP)

Dependencies removed: fgl, graphviz, process

Dependency ranges changed: WeakSets, base, containers, directory, filepath, text

API changes (from Hackage documentation)

- Math.Categories.FunctorCategory: instance (GHC.Classes.Eq o1, GHC.Classes.Eq m1, GHC.Classes.Eq o2, GHC.Classes.Eq m2) => GHC.Classes.Eq (Math.Categories.FunctorCategory.DiagramError c1 m1 o1 c2 m2 o2)
- Math.Categories.FunctorCategory: instance (GHC.Show.Show o1, GHC.Show.Show m1, GHC.Show.Show o2, GHC.Show.Show m2) => GHC.Show.Show (Math.Categories.FunctorCategory.DiagramError c1 m1 o1 c2 m2 o2)
- Math.FiniteCategoryError: instance (GHC.Classes.Eq m, GHC.Classes.Eq o) => GHC.Classes.Eq (Math.FiniteCategoryError.FiniteCategoryError m o)
- Math.FiniteCategoryError: instance (GHC.Show.Show m, GHC.Show.Show o) => GHC.Show.Show (Math.FiniteCategoryError.FiniteCategoryError m o)
- Math.IO.FiniteCategories.ExportGraphViz: catToDot :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: catToDotFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: catToPdf :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: catToPdfFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: categoryToGraph :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> Gr String String
- Math.IO.FiniteCategories.ExportGraphViz: categoryToGraphFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> Gr String String
- Math.IO.FiniteCategories.ExportGraphViz: diagToDot :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToDot2 :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToDot2Format :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToDotCluster :: (Eq c1, Eq o1, PrettyPrint o1, PrettyPrint m1, Morphism m1 o1, FiniteCategory c1 m1 o1, Eq c2, Eq o2, PrettyPrint o2, PrettyPrint m2, Morphism m2 o2, FiniteCategory c2 m2 o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToPdf :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToPdf2 :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToPdf2Format :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) => Diagram c1 m1 o1 c2 m2 o2 -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: diagToPdfCluster :: (Eq c1, Eq o1, PrettyPrint o1, PrettyPrint m1, Morphism m1 o1, FiniteCategory c1 m1 o1, Eq c2, Eq o2, PrettyPrint o2, PrettyPrint m2, Morphism m2 o2, FiniteCategory c2 m2 o2) => Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: genToDot :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: genToPdf :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: natToDot :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) => NaturalTransformation c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: natToDotFormat :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) => NaturalTransformation c1 m1 o1 c2 m2 o2 -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: natToPdf :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) => NaturalTransformation c1 m1 o1 c2 m2 o2 -> String -> IO ()
- Math.IO.FiniteCategories.ExportGraphViz: natToPdfFormat :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1, Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) => NaturalTransformation c1 m1 o1 c2 m2 o2 -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
+ Math.Categories.CommaCategory: instance (Math.IO.PrettyPrint.PrettyPrint c1, Math.IO.PrettyPrint.PrettyPrint m1, Math.IO.PrettyPrint.PrettyPrint o1, Math.IO.PrettyPrint.PrettyPrint c2, Math.IO.PrettyPrint.PrettyPrint m2, Math.IO.PrettyPrint.PrettyPrint o2, Math.IO.PrettyPrint.PrettyPrint c3, Math.IO.PrettyPrint.PrettyPrint m3, Math.IO.PrettyPrint.PrettyPrint o3, GHC.Classes.Eq m1, GHC.Classes.Eq o1, GHC.Classes.Eq m2, GHC.Classes.Eq o2, GHC.Classes.Eq m3, GHC.Classes.Eq o3) => Math.IO.PrettyPrint.PrettyPrint (Math.Categories.CommaCategory.CommaCategory c1 m1 o1 c2 m2 o2 c3 m3 o3)
+ Math.Categories.FinCat: instance Math.IO.PrettyPrint.PrettyPrint (Math.Categories.FinCat.FinCat c m o)
+ Math.Categories.FunctorCategory: instance (GHC.Classes.Eq o1, GHC.Classes.Eq o2, GHC.Classes.Eq m1, GHC.Classes.Eq m2) => GHC.Classes.Eq (Math.Categories.FunctorCategory.DiagramError c1 m1 o1 c2 m2 o2)
+ Math.Categories.FunctorCategory: instance (GHC.Show.Show o1, GHC.Show.Show o2, GHC.Show.Show m1, GHC.Show.Show m2) => GHC.Show.Show (Math.Categories.FunctorCategory.DiagramError c1 m1 o1 c2 m2 o2)
+ Math.Category: arWithoutId :: (Category c m o, Morphism m o, Eq m, Eq o) => c -> o -> o -> Set m
+ Math.Category: genArWithoutId :: (Category c m o, Morphism m o, Eq m, Eq o) => c -> o -> o -> Set m
+ Math.FiniteCategories.CompositionGraph: arrowToCGMorphism :: (Eq a, Eq b) => CompositionGraph a b -> Arrow a b -> Maybe (CGMorphism a b)
+ Math.FiniteCategories.CompositionGraph: cgmorphismToArrow :: CGMorphism a b -> Maybe (Arrow a b)
+ Math.FiniteCategories.CompositionGraph: coequalizeCompositionGraphDiagrams :: (Eq a, Eq b) => Set (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+ Math.FiniteCategories.CompositionGraph: colimitOfCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq c1, Eq m1, Eq o1, Eq a, Eq b) => Diagram c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b) -> (o1 -> a -> a) -> (o1 -> b -> b) -> Cocone c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b)
+ Math.FiniteCategories.CompositionGraph: coproductOfCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Eq a, Eq b) => Diagram c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b) -> (o1 -> a -> a) -> (o1 -> b -> b) -> Cocone c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b)
+ Math.FiniteCategories.CompositionGraph: coproductOfStringCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Show o1) => Diagram c1 m1 o1 (FinCat (CompositionGraph String String) (CGMorphism String String) String) (FinFunctor (CompositionGraph String String) (CGMorphism String String) String) (CompositionGraph String String) -> Cocone c1 m1 o1 (FinCat (CompositionGraph String String) (CGMorphism String String) String) (FinFunctor (CompositionGraph String String) (CGMorphism String String) String) (CompositionGraph String String)
+ Math.FiniteCategories.CompositionGraph: coproductOfTextCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Show o1) => Diagram c1 m1 o1 (FinCat (CompositionGraph Text Text) (CGMorphism Text Text) Text) (FinFunctor (CompositionGraph Text Text) (CGMorphism Text Text) Text) (CompositionGraph Text Text) -> Cocone c1 m1 o1 (FinCat (CompositionGraph Text Text) (CGMorphism Text Text) Text) (FinFunctor (CompositionGraph Text Text) (CGMorphism Text Text) Text) (CompositionGraph Text Text)
+ Math.FiniteCategories.CompositionGraph: glueMorphisms :: (Eq a, Eq b) => CompositionGraph a b -> Set (CGMorphism a b) -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+ Math.FiniteCategories.CompositionGraph: glueObjects :: (Eq a, Eq b) => CompositionGraph a b -> Set a -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+ Math.FiniteCategories.CompositionGraph: unsafeArrowToCGMorphism :: CompositionGraph a b -> Arrow a b -> CGMorphism a b
+ Math.FiniteCategories.CompositionGraph: unsafeCGMorphismToArrow :: CGMorphism a b -> Arrow a b
+ Math.FiniteCategory: arFrom2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+ Math.FiniteCategory: arFromWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+ Math.FiniteCategory: arTo2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+ Math.FiniteCategory: arToWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+ Math.FiniteCategory: arrowsWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set m
+ Math.FiniteCategory: genArFrom2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+ Math.FiniteCategory: genArFromWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+ Math.FiniteCategory: genArTo2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+ Math.FiniteCategory: genArToWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+ Math.FiniteCategory: genArrowsWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set m
+ Math.FiniteCategory: pprintFiniteCategory :: (FiniteCategory c m o, Morphism m o, PrettyPrint c, PrettyPrint m, PrettyPrint o, Eq m, Eq o) => c -> String
+ Math.FiniteCategoryError: instance (GHC.Classes.Eq o, GHC.Classes.Eq m) => GHC.Classes.Eq (Math.FiniteCategoryError.FiniteCategoryError m o)
+ Math.FiniteCategoryError: instance (GHC.Show.Show o, GHC.Show.Show m) => GHC.Show.Show (Math.FiniteCategoryError.FiniteCategoryError m o)

Files

CHANGELOG.md view
@@ -6,4 +6,8 @@ 
 ## 0.2.0.0 -- 2023-03-13
 
-* Separation between Category and FiniteCategory typeclasses, new architecture for the project, Kan extensions, etc.+* Separation between Category and FiniteCategory typeclasses, new architecture for the project, Kan extensions, etc.
+
+## 0.3.0.0 -- 2023-09-29
+
+* Splitting the package with FiniteCategoriesGraphViz. Colimit of composition graphs.
FiniteCategories.cabal view
@@ -14,14 +14,14 @@ -- PVP summary:      +-+------- breaking API changes
 --                   | | +----- non-breaking API additions
 --                   | | | +--- code changes with no API change
-version:            0.2.0.0
+version:            0.3.0.0
 
 -- A short (one-line) description of the package.
 synopsis: Finite categories and usual categorical constructions on them.
     
 
 -- A longer description of the package.
-description: This package provides tools to create categories at the value level. This is different from the __Hask__ category where types are objects in a category with infinite objects and arrows, here we construct categories where objects and arrows are arbitrary values so that we can change categories during runtime. Each category implements two functions following the category structure axioms : @ar@ which returns arrows between two objects of the category and @identity@ which returns the identity of an object. A FiniteCategory implements an additional function : @ob@ which returns objects of the category. Thanks to these functions, we can construct automatically all the usual constructions on the categories (limits and colimits, adjunctions, Yoneda embedding, etc.) Functors are different from usual @Functor@ typeclass, we store functors as mapping between objects and morphisms of two categories. This package is also different from the package @data-category@ because we can enumerate objects and arrows in a finite category.  This allows us to construct limit, colimits, adjunctions, etc. automatically for arbitrary finite categories. On the other hand, we loose typecheck at compilation time which ensures that composition is sound in __Hask__, composition in our package might lead to an error raised during runtime. See the Readme file for installation help.
+description: This package provides tools to create categories at the value level. This is different from the __Hask__ category where types are objects in a category with an infinite collection of objects and functions, here we construct categories where objects and arrows are arbitrary values so that we can change categories during runtime. Each category implements two functions following the category structure axioms : @ar@ which returns arrows between two objects of the category and @identity@ which returns the identity of an object. A FiniteCategory implements an additional function : @ob@ which returns objects of the category. Thanks to these functions, we can construct automatically all the usual constructions on the categories (limits and colimits, adjunctions, Yoneda embedding, etc.) Functors are different from usual @Functor@ typeclass, we store functors as mapping between objects and morphisms of two categories. This package is also different from the package @data-category@ because we can enumerate objects and arrows in a finite category.  This allows us to construct limit, colimits, adjunctions, etc. automatically for arbitrary finite categories. On the other hand, we loose typecheck at compilation time which ensures that composition is sound in __Hask__, composition in our package might lead to an error raised during runtime. See the Readme file for installation help. See the package FiniteCategoriesGraphViz to visualize categories with graphviz.
 
 -- URL for the project homepage or repository.
 homepage: https://gitlab.utc.fr/gsabbagh/FiniteCategories
@@ -116,9 +116,7 @@                         Math.Functors.KanExtension.Example,
                         Math.Functors.YonedaEmbedding.Example,
                         Math.Functors.SetValued.Example,
-                        Math.IO.PrettyPrint,
-                        Math.IO.FiniteCategories.ExportGraphViz,
-
+                        Math.IO.PrettyPrint
 
     -- Modules included in this library but not exported.
     -- other-modules:  
@@ -127,17 +125,14 @@     other-extensions: MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances, FlexibleInstances
 
     -- Other library packages from which modules are imported.
-    build-depends:      base             >= 4.15.0.0 && < 4.16,
-                        containers       >= 0.6.4 && < 0.7,
-                        directory        >= 1.3.6 && < 1.4,
-                        filepath         >= 1.4.2 && < 1.5,
-                        fgl              >= 5.7.0 && < 5.8,
-                        graphviz         >= 2999.20.1 && < 2999.21,
-                        text             >= 1.2.4 && < 1.3,
-                        process          >= 1.6.11 && < 1.7,
+    build-depends:      base             >= 4.18.0.0 && < 4.19,
                         random           >= 1.2.1 && < 1.3,
-                        WeakSets         >= 1.4.0.0 && < 1.4.0.1,
-
+                        WeakSets         >= 1.4.0.1 && < 1.4.0.2,
+                        containers       >= 0.6.6.0 && < 0.7,
+                        text             >= 2.1 && < 2.2,
+                        filepath         >= 1.4.100.1 && < 1.5,
+                        directory        >= 1.3.8.1 && < 1.4,
+                        
     -- Directories containing source files.
     hs-source-dirs:   src
 
@@ -160,14 +155,11 @@ 
     -- Test dependencies.
     build-depends:      FiniteCategories,
-                        base             >=4.15.0.0 && < 4.16,
-                        containers       >= 0.6.4 && < 0.7,
-                        directory        >= 1.3.6 && < 1.4,
-                        filepath         >= 1.4.2 && < 1.5,
-                        fgl              >= 5.7.0 && < 5.8,
-                        graphviz         >= 2999.20.1 && < 2999.21,
-                        text             >= 1.2.4 && < 1.3,
-                        process          >= 1.6.11 && < 1.7,
+                        base             >=4.18.0.0 && < 4.19,
                         random           >= 1.2.1 && < 1.3,
-                        WeakSets         >= 1.4.0.0 && < 1.4.0.1,
+                        WeakSets         >= 1.4.0.1 && < 1.4.0.2,
+                        containers       >= 0.6.6.0 && < 0.7,
+                        text             >= 2.1 && < 2.2,
+                        filepath         >= 1.4.100.1 && < 1.5,
+                        directory        >= 1.3.8.1 && < 1.4,
     other-modules:  CheckAllFiniteCategories
Readme.md view
@@ -1,6 +1,6 @@ # FiniteCategories
 
-The goal of this project is to represent small finite categories in order to make usual constructions automatically on them (e.g. (co)limits, (co)completion, adjunctions, etc.)
+The goal of this project is to represent small finite categories in order to make usual constructions automatically on them (e.g. (co)limits, (co)completion, adjunctions, kan extensions, etc.)
 
 ## Table of Contents
 1. [General Info](#general-info)
@@ -15,17 +15,13 @@ 
 This package is also different from the package `data-category` because we can enumerate objects and arrows in a category.  This allows us to construct limit, colimits, adjunctions, etc. automatically for arbitrary finite categories. On the other hand, we loose typecheck at compilation time which ensures that composition is sound in __Hask__, composition in our package might lead to an error raised during runtime.
 
-## Technologies
-
-The project uses GraphViz for visualizing the categories created.
+## See also
 
-There is another version no longer maintained programmed in Python : [repository link](https://gitlab.utc.fr/gsabbagh/modification-de-categories)
+See the package `FiniteCategoriesGraphViz` to export the categories as images created with GraphViz.
 
 ## Installation
 
-To use the graphviz exports, you must first install graphviz (see [graphviz website](https://graphviz.org/download/)) and make sure that Graphviz folder is in the path (dot should be a callable program from your terminal, if you are on Windows see [this tutorial](https://stackoverflow.com/questions/44272416/how-to-add-a-folder-to-path-environment-variable-in-windows-10-with-screensho#44272417) and if you are on unix see [this tutorial]( https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path)).
-
-Then you can check the numerous examples provided to understand how to use the package.
+Simply run ```cabal install FiniteCategories```
 
 ## Collaboration
 
@@ -33,11 +29,33 @@ 
 ## Usage
 
-To run all examples of the project, clone the repository and run in a terminal from the repository the following command :
+If you want to construct small categories by hand, see `Math.FiniteCategories.CompositionGraph` which allows to construct the free category generated by a graph quotiented by a congruence relation on paths of the graph. The function `readCGFile` allows to construct a `CompositionGraph` from a simple file, for example :
 
-```cabal test```
+```
+A -f-> B -g-> D = A -h-> C -i-> D
+```
 
-You can then find the graphviz output in the folder `OutputGraphViz/`.
+is a square category where the two diagonals are identified.
+
+To construct a functor, see `Diagram` in `Math.FiniteCategories.FunctorCategory`. You can also use `readCGDFile` from `Math.FiniteCategories.CompositionGraph` :
+
+```
+<SRC>
+X
+Y -1-> Z
+</SRC>
+<TGT>
+A -f-> B -g-> D = A -h-> C -i-> D
+</TGT>
+
+X => A
+Y -1-> Z => B -g-> D
+```
+
+See `Math.Categories.ConeCategory`, `Math.Functors.Adjunction` and `Math.Functors.KanExtension` for useful functions to construct usual categorical constructions.
+
+
+
 
 
 ## Examples
src/Math/Categories/CommaCategory.hs view
@@ -178,6 +178,11 @@         ob CommaCategory{leftDiagram = t, rightDiagram = s} = [CommaObject{indexSource=e,indexTarget=d,selectedArrow=f}| e <- (ob (src t)), d <- (ob (src s)), f <- ar (tgt t) (t ->$ e) (s ->$ d)]
         
     
+    instance (PrettyPrint c1, PrettyPrint m1, PrettyPrint o1,
+              PrettyPrint c2, PrettyPrint m2, PrettyPrint o2,
+              PrettyPrint c3, PrettyPrint m3, PrettyPrint o3,
+              Eq m1, Eq o1, Eq m2, Eq o2, Eq m3, Eq o3) => PrettyPrint (CommaCategory c1 m1 o1 c2 m2 o2 c3 m3 o3) where
+        pprint cc = "CommaCategory("++ pprint (leftDiagram cc) ++ ", "++ pprint (rightDiagram cc)++")"
         
     -- | Construct the slice category of a category /C/ over an object /o/.
     --
src/Math/Categories/FinCat.hs view
@@ -68,3 +68,5 @@                 appObj = Map.enumerateMaps (ob s) (ob t)
                 twoObjToMaps a b appO = Map.enumerateMaps (ar s a b) (ar t (appO |!| a) (appO |!| b))
                     
+    instance PrettyPrint (FinCat c m o) where
+        pprint = show
src/Math/Category.hs view
@@ -28,6 +28,7 @@     compose,
     -- * Category
     Category(..),
+    arWithoutId,
     -- ** Morphism predicates
     isIdentity,
     isNotIdentity,
@@ -36,6 +37,7 @@     isRetraction,
     areIsomorphic,
     -- ** Generator predicates
+    genArWithoutId,
     isGenerator,
     isComposite,
     -- ** Find special morphisms
@@ -142,6 +144,14 @@         -- The default implementation returns the morphism in a list as all arrows are generators.
         decompose :: (Morphism m o) => c -> m -> [m]
         decompose _ = (:[])
+      
+    -- | Return the arrows between two objects without the identities.
+    arWithoutId :: (Category c m o, Morphism m o, Eq m, Eq o) => c -> o -> o -> Set m
+    arWithoutId c s t = Set.filter (isNotIdentity c) $ ar c s t
+      
+    -- | Return the generators between two objects without the identities.
+    genArWithoutId :: (Category c m o, Morphism m o, Eq m, Eq o) => c -> o -> o -> Set m
+    genArWithoutId c s t = Set.filter (isNotIdentity c) $ genAr c s t
             
     -- | Return wether a morphism is an identity in a category.
     isIdentity :: (Category c m o, Morphism m o, Eq m, Eq o) => c -> m -> Bool
@@ -189,4 +199,6 @@     
     -- | Opposite of `isGenerator`, i.e. returns if the morphism is composite.
     isComposite :: (Category c m o, Morphism m o, Eq m) => c -> m -> Bool
-    isComposite c f = not (isGenerator c f)+    isComposite c f = not (isGenerator c f)
+    
+    
src/Math/FiniteCategories/All.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : Export all modules from the FiniteCategories package.
+Description : ll modules from the FiniteCategories package.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Export all modules from the FiniteCategories package.
+ll modules from the FiniteCategories package.
 
-Export all categories, all finite categories, category and finite category functions, IO, Debug...
+ll categories, all finite categories, category and finite category functions, IO, Debug...
 -}
 
 module Math.FiniteCategories.All (
@@ -18,8 +18,7 @@     module Math.Categories,
     module Math.FiniteCategories,
     module Math.Functors,
-    module Math.IO.PrettyPrint,
-    module Math.IO.FiniteCategories.ExportGraphViz,
+    module Math.IO.PrettyPrint
 ) where
     import Math.Category
     import Math.FiniteCategory
@@ -27,5 +26,4 @@     import Math.Categories
     import Math.Functors
     import Math.FiniteCategories
-    import Math.IO.PrettyPrint
-    import Math.IO.FiniteCategories.ExportGraphViz+    import Math.IO.PrettyPrint
src/Math/FiniteCategories/CommaCategory/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : Examples of 'CommaCategory' exported with GraphViz.
+Description : Examples of 'CommaCategory' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Examples of 'CommaCategory' exported with GraphViz.
-
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/CommaCategory".
+Examples of 'CommaCategory' pretty printed.
 -}
 module Math.FiniteCategories.CommaCategory.Example
 (
@@ -22,17 +20,16 @@     import Math.FiniteCategory
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
     import Math.IO.PrettyPrint
     
-    -- | Examples of 'CommaCategory' exported with GraphViz.
+    -- | Examples of 'CommaCategory' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.CommaCategory.Example"
-        catToPdf (numberCategory 4) "OutputGraphViz/Examples/FiniteCategories/CommaCategory/4"
+        putStrLn $ pprintFiniteCategory (numberCategory 4)
         let Just slice = sliceCategory (numberCategory 4) 2
         let Just coslice = cosliceCategory (numberCategory 4) 2
-        catToPdf slice "OutputGraphViz/Examples/FiniteCategories/CommaCategory/slice2"
-        catToPdf coslice "OutputGraphViz/Examples/FiniteCategories/CommaCategory/coslice2"
-        catToPdf (arrowCategory (numberCategory 4)) "OutputGraphViz/Examples/FiniteCategories/CommaCategory/arrow"
+        putStrLn $ pprintFiniteCategory slice
+        putStrLn $ pprintFiniteCategory coslice
+        putStrLn $ pprintFiniteCategory (arrowCategory (numberCategory 4))
         putStrLn "End of Math.FiniteCategories.CommaCategory.Example"
src/Math/FiniteCategories/CompositionGraph.hs view
@@ -28,6 +28,10 @@     CGMorphism(..),
     -- ** Functions for composition graph morphism
     getLabel,
+    cgmorphismToArrow,
+    arrowToCGMorphism,
+    unsafeCGMorphismToArrow,
+    unsafeArrowToCGMorphism,
     -- * Composition graph
     CompositionLaw(..),
     CompositionGraph,
@@ -42,6 +46,13 @@     readCGString,
     unsafeReadCGFile,
     readCGFile,
+    coproductOfCompositionGraphs,
+    coproductOfStringCompositionGraphs,
+    coproductOfTextCompositionGraphs,
+    glueObjects,
+    glueMorphisms,
+    coequalizeCompositionGraphDiagrams,
+    colimitOfCompositionGraphs,
     -- * Serialization
     writeCGString,
     writeCGFile,
@@ -74,12 +85,18 @@     import              Math.Category
     import              Math.FiniteCategory
     import              Math.FiniteCategoryError
+    import              Math.FiniteCategories.One
+    import              Math.Categories.ConeCategory
+    import              Math.Categories.FinCat
+    import              Math.Categories.CommaCategory
     import              Math.IO.PrettyPrint
     
     import              System.Directory            (createDirectoryIfMissing)
     import              System.FilePath.Posix       (takeDirectory)
     import              System.Random               (RandomGen, uniformR)
     
+    
+    
     -- | A `RawPath` is a list of arrows, arrows should be compatible.
     type RawPath a b = [Arrow a b]
     
@@ -200,12 +217,37 @@         acyclicPaths = (simplify cl) <$> (findAcyclicRawPaths g s t)
         allPaths = (simplify cl <$> Set.unions (setToList ((intertwineWithCycles g cl s) <$> acyclicPaths)))
     
-    -- | Return the label of a 'CompositionGraph' generator.
+    -- | Return Just the label of a 'CompositionGraph' non identity generator, Nothing if the morphism is not a non identity generator.
     getLabel :: CGMorphism a b -> Maybe b
-    getLabel CGMorphism{path=(s,rp), compositionLaw=_}
+    getLabel CGMorphism{path=(_,rp), compositionLaw=_}
         | null rp = Nothing
         | null.tail $ rp = Just (labelArrow.head $ rp)
         | otherwise = Nothing
+        
+    -- | Return Just the 'Arrow' of a 'CompositionGraph' non identity generator, Nothing if the morphism is not a non identity generator.
+    cgmorphismToArrow :: CGMorphism a b -> Maybe (Arrow a b)
+    cgmorphismToArrow CGMorphism{path=(_,rp), compositionLaw=_}
+        | null rp = Nothing
+        | null.tail $ rp = Just (head $ rp)
+        | otherwise = Nothing
+        
+    -- | Given a composition graph, transform an 'Arrow' into a 'CGMorphism' if this 'CGMorphism' is in the composition graph, return Nothing otherwise. 
+    arrowToCGMorphism :: (Eq a, Eq b) => CompositionGraph a b -> Arrow a b -> Maybe (CGMorphism a b)
+    arrowToCGMorphism cg arr
+        | arr `isIn` (edges.support $ cg) = Just $ mkCGMorphism (law cg) arr
+        | otherwise = Nothing
+        
+        
+    -- | Unsafe version of 'cgmorphismToArrow'.
+    unsafeCGMorphismToArrow :: CGMorphism a b -> (Arrow a b)
+    unsafeCGMorphismToArrow CGMorphism{path=(_,rp), compositionLaw=_}
+        | null rp = error "no arrow in CGMorphism"
+        | null.tail $ rp = head rp
+        | otherwise = error "several arrows in CGMorphism"
+        
+    -- | Unsafe version of 'arrowToCGMorphism'.
+    unsafeArrowToCGMorphism :: CompositionGraph a b -> Arrow a b -> CGMorphism a b
+    unsafeArrowToCGMorphism cg arr = mkCGMorphism (law cg) arr
     
     -- | A 'CompositionGraph' is a graph with a composition law such that the free category generated by the graph quotiented out by the composition law gives a 'FiniteCategory'.
     -- 
@@ -315,6 +357,7 @@             parserLexHelper ('-':'>':' ':str) = EndArrow : (parserLexHelper str)
             parserLexHelper (' ':'=':' ':str) = Equals : (parserLexHelper str)
             parserLexHelper ('<':'I':'D':'/':'>':str) = Identity : (parserLexHelper str)
+            parserLexHelper ('<':'I':'D':'>':str) = Identity : (parserLexHelper str)
             parserLexHelper ('<':'S':'R':'C':'>':str) = BeginSrc : (parserLexHelper str)
             parserLexHelper ('<':'T':'G':'T':'>':str) = BeginTgt : (parserLexHelper str)
             parserLexHelper ('<':'/':'S':'R':'C':'>':str) = EndSrc : (parserLexHelper str)
@@ -756,4 +799,122 @@             (cat1, g4) = constructRandomCompositionGraph nbArrows1 nbAttempts1 5 g3
             (nbArrows2, g5) = uniformR (1,11-nbArrows1) g4
             (nbAttempts2, g6) = uniformR (0,nbArrows2+nbArrows2) g5
-            (cat2, g7) = constructRandomCompositionGraph nbArrows2 nbAttempts2 5 g6+            (cat2, g7) = constructRandomCompositionGraph nbArrows2 nbAttempts2 5 g6
+    
+    
+    
+    
+    
+    -- | Takes a discrete diagram of composition graphs and two functions and returns a colimit cocone object of this diagram. The two functions are used to combine an object (an arrow) of the indexing category with an object (an arrow) of a composition graph in order to distinguish an object (an arrow) with same identifier in the disjunct union constructed.
+    --
+    -- Two properties should be met and are not verified at runtime : the diagram given should be discrete and the two functions should be injective.
+    --
+    -- Moreover, the base of the diagram should not be empty. This function throws an error if this condition is not verified.
+    coproductOfCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Eq a, Eq b) => Diagram c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b) -> (o1 -> a -> a) -> (o1 -> b -> b) -> Cocone c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b)
+    coproductOfCompositionGraphs diagOfCG combObj combArr
+        | Set.null (ob indexingCategory) = error "The base should not be empty."
+        | otherwise = unsafeCommaObject One coproduct natCoproduct
+        where
+            indexingCategory = src diagOfCG
+            coproduct = unsafeCompositionGraph coproduct_graph (Map.unions [weakMap $ (\(rp1,rp2) -> (transformArrowIntoArrowCoproduct i <$> rp1, transformArrowIntoArrowCoproduct i <$> rp2)) <$> (Map.mapToList (law (diagOfCG ->$ i))) | i <- (setToList (ob indexingCategory))])
+            transformObjectIntoObjectCoproduct i x = combObj i x
+            transformArrowIntoArrowCoproduct i a = Arrow{sourceArrow = combObj i (sourceArrow a), targetArrow = combObj i (targetArrow a), labelArrow = combArr i (labelArrow a)}
+            coproduct_graph = unsafeGraph (Set.concat2 ((\i -> transformObjectIntoObjectCoproduct i <$> (ob (diagOfCG ->$ i))) <$> (ob indexingCategory))) (Set.concat2 ((\i -> (transformArrowIntoArrowCoproduct i) <$> (unsafeCGMorphismToArrow <$> genArrowsWithoutId (diagOfCG ->$ i))) <$> (ob indexingCategory)))
+            natCoproduct = unsafeNaturalTransformation diagOfCG (constantDiagram indexingCategory FinCat coproduct) (weakMapFromSet [(i, insertionFunctor i)| i <- ob indexingCategory])
+            insertionFunctor i = completeDiagram Diagram{src = diagOfCG ->$ i, tgt = coproduct, omap = weakMapFromSet [(o, transformObjectIntoObjectCoproduct i o)| o <- ob (diagOfCG ->$ i)], mmap = weakMapFromSet [(m, (unsafeArrowToCGMorphism coproduct (transformArrowIntoArrowCoproduct i (unsafeCGMorphismToArrow m)))) | m <- (genArrowsWithoutId (diagOfCG ->$ i))]}
+    
+    
+    -- | Specialized version of 'coproductOfCompositionGraphs' to CompositionGraph String String.
+    coproductOfStringCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Show o1) => Diagram c1 m1 o1 (FinCat (CompositionGraph String String) (CGMorphism String String) String) (FinFunctor (CompositionGraph String String) (CGMorphism String String) String) (CompositionGraph String String) -> Cocone c1 m1 o1 (FinCat (CompositionGraph String String) (CGMorphism String String) String) (FinFunctor (CompositionGraph String String) (CGMorphism String String) String) (CompositionGraph String String)
+    coproductOfStringCompositionGraphs diag = coproductOfCompositionGraphs diag (\x o -> (show $ x) <> "." <>o) (\x m -> (show x) <> "." <>m)
+    
+    
+    -- | Specialized version of 'coproductOfCompositionGraphs' to CompositionGraph Text Text.
+    coproductOfTextCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq o1, Show o1) => Diagram c1 m1 o1 (FinCat (CompositionGraph Text Text) (CGMorphism Text Text) Text) (FinFunctor (CompositionGraph Text Text) (CGMorphism Text Text) Text) (CompositionGraph Text Text) -> Cocone c1 m1 o1 (FinCat (CompositionGraph Text Text) (CGMorphism Text Text) Text) (FinFunctor (CompositionGraph Text Text) (CGMorphism Text Text) Text) (CompositionGraph Text Text)
+    coproductOfTextCompositionGraphs diag = coproductOfCompositionGraphs diag (\x o -> (pack.show $ x) <> (pack ".")<>o) (\x m -> (pack.show$ x) <>(pack ".")<>m)
+    
+    
+    -- | Glue two objects of a 'CompositionGraph' and return an insertion diagram into the new CompositionGraph.
+    glueObject :: (Eq a, Eq b) => CompositionGraph a b -> a -> a -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+    glueObject cg a b = completeDiagram $ Diagram{src=cg,tgt=newCG, omap = omapD, mmap = mmapD}
+        where
+            glueObj obj = if obj == b then a else obj
+            omapD = memorizeFunction glueObj (nodes.support $ cg)
+            glueArr arr = Arrow{sourceArrow = glueObj.sourceArrow $ arr, targetArrow = glueObj.targetArrow $ arr, labelArrow = labelArrow arr}
+            mmapD = memorizeFunction ((unsafeArrowToCGMorphism cg).glueArr.unsafeCGMorphismToArrow) (genArrowsWithoutId cg)
+            newCG = unsafeCompositionGraph (unsafeGraph (Map.values omapD) (glueArr <$> (edges.support $ cg))) (law cg)
+    
+    -- | Glue objects of a 'CompositionGraph' and return an insertion diagram into the new CompositionGraph.
+    glueObjects :: (Eq a, Eq b) => CompositionGraph a b -> Set a -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+    glueObjects cg objects
+        | Set.null objects = error "glue 0 object"
+        | otherwise = Set.foldr (\obj funct -> (glueObject (tgt funct) representant obj) @ funct) (identity FinCat cg) objects
+        where
+            representant = anElement objects
+            
+    
+    -- | Change the law of a CGMorphism
+    updateCGMorphismWithNewLaw :: CompositionLaw a b -> CGMorphism a b -> CGMorphism a b
+    updateCGMorphismWithNewLaw l m = CGMorphism{path=path m, compositionLaw=l}
+    
+    -- | Glue two morphisms with same source and target of a 'Compositiongraph' and return an insertion diagram into the new CompositionGraph.
+    -- The first argument should not be composite if the second is a generator.
+    glueMorphism :: (Eq a, Eq b) => CompositionGraph a b -> CGMorphism a b -> CGMorphism a b -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+    glueMorphism cg m1 m2
+        | isComposite_ m1 && isGenerator_ m2 = error "Glue composite to generator."
+        | m1 == m2 = identity FinCat cg
+        | isGenerator_ m1 && isGenerator_ m2 = completeDiagram Diagram{src=cg,tgt=newCGGG,omap=omapGG,mmap=mmapGG}
+        | otherwise = completeDiagram Diagram{src=cg,tgt=newCG,omap=omapGG,mmap=mmapId}
+        where
+            isGenerator_ m = length (snd.path $ m) == 1
+            isComposite_ = not.isGenerator_
+            glueMorph m = if m == m2 then m1 else m
+            glueArr a = if a == (unsafeCGMorphismToArrow m2) then unsafeCGMorphismToArrow m1 else a
+            omapGG = memorizeFunction id (nodes.support $ cg)
+            mmapGG = memorizeFunction glueMorph (genArrowsWithoutId cg)
+            newLawGG =  weakMapFromSet $ (\(x,y) -> (glueArr <$> x, glueArr <$> y)) <$> ((Map.mapToSet).law $ cg)
+            newCGGG = unsafeCompositionGraph (unsafeGraph (nodes.support $ cg) ((edges.support $ cg) `Set.difference` (set [unsafeCGMorphismToArrow m2]))) newLawGG
+            newLaw = Map.insert (snd.path $ m2) (snd.path $ m1) (law cg)
+            mmapId = memorizeFunction id (genArrowsWithoutId cg)
+            newCG = unsafeCompositionGraph (support cg) newLaw
+            
+    -- | Glue morphisms with same source and target of a 'CompositionGraph' and return an insertion diagram into the new CompositionGraph.
+    glueMorphisms :: (Eq a, Eq b) => CompositionGraph a b -> Set (CGMorphism a b) -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+    glueMorphisms cg morphisms
+        | Set.null morphisms = error "glue 0 morphism"
+        | Set.null generators = Set.foldr (\morph funct -> (glueMorphism (tgt funct) (anElement morphisms) morph) @ funct) (identity FinCat cg) morphisms
+        | otherwise = Set.foldr (\morph funct -> (glueMorphism (tgt funct) (anElement generators) morph) @ funct) (identity FinCat cg) morphisms
+        where
+            generators = Set.filter (isGenerator cg) morphisms
+            
+    
+    -- | Takes diagrams with same source and target composition graphs and returns a diagram from the target to the coequalizer of the diagrams. The set of diagrams should not be empty
+    coequalizeCompositionGraphDiagrams :: (Eq a, Eq b) => Set (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) -> FinFunctor (CompositionGraph a b) (CGMorphism a b) a
+    coequalizeCompositionGraphDiagrams diags
+        | Set.null diags = error "coequalize no diagram"
+        | otherwise = glueArrowsFunctor
+        where
+            aDiagram = anElement diags
+            selectingObjects = ob.src $ aDiagram
+            glueObjectsFunctor = Set.foldr (\obj funct -> (glueObjects (tgt funct) [(funct @ diag) ->$ obj | diag <- diags]) @ funct) (identity FinCat (tgt aDiagram)) selectingObjects
+            selectingArrows = genArrowsWithoutId.src $ aDiagram
+            glueArrowsFunctor = Set.foldr (\morph funct -> (glueMorphisms (tgt funct) [(funct @ diag) ->£ morph| diag <- diags]) @ funct) glueObjectsFunctor selectingArrows
+            
+    
+    -- | Takes a diagram of compositions graphs, a function to combine an object of the indexing category with an object of a composition graph, a function to combine an object of the indexing category with a morphism of a composition graph and return the colimit cocone with the constructed composition graph as nadir. Note that the functions to combine objects and morphisms should be injective. The base should not be empty.
+    colimitOfCompositionGraphs :: (FiniteCategory c1 m1 o1, Morphism m1 o1, Eq c1, Eq m1, Eq o1, Eq a, Eq b) =>
+        Diagram c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b) -> (o1 -> a -> a) -> (o1 -> b -> b) -> Cocone c1 m1 o1 (FinCat (CompositionGraph a b) (CGMorphism a b) a) (FinFunctor (CompositionGraph a b) (CGMorphism a b) a) (CompositionGraph a b)
+    colimitOfCompositionGraphs diagOfCG combObj combMorph 
+        | Set.null (ob indexingCategory) = error "The base should not be empty."
+        | otherwise =  unsafeCommaObject One (tgt (coequalizedNat =>$ (anElement.ob $ indexingCategory))) coequalizedNat
+        where
+            indexingCategory = src diagOfCG
+            coproductCocone = coproductOfCompositionGraphs diagOfCG combObj combMorph
+            coproductNat = legsCocone coproductCocone
+            functorToNat funct = unsafeNaturalTransformation (constantDiagram indexingCategory FinCat (src funct)) (constantDiagram indexingCategory FinCat (tgt funct)) (memorizeFunction (const funct) (ob indexingCategory))
+            composeNatWithFunctor nat funct = (functorToNat funct) @ nat
+            notBottomObjects = Set.filter (not.(Set.null).(arFromWithoutId indexingCategory)) (ob indexingCategory)
+            indexingFunctToLeg nat indexingFunct = (nat =>$ (target indexingFunct)) @ (diagOfCG ->£ indexingFunct)
+            coequalizedNat = Set.foldr (\indexingObj nat -> composeNatWithFunctor nat (coequalizeCompositionGraphDiagrams (indexingFunctToLeg nat <$> (genArFrom indexingCategory indexingObj)))) coproductNat notBottomObjects
+            
+           
src/Math/FiniteCategories/CompositionGraph/Example.hs view
@@ -1,20 +1,18 @@ {-| Module  : FiniteCategories
-Description : An example of 'CompositionGraph' exported with GraphViz.
+Description : An example of 'CompositionGraph' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of 'CompositionGraph' exported with GraphViz.
-
-Examples of other categories transformed into 'CompositionGraph's are also exported.
+An example of 'CompositionGraph' pretty printed.
 
-A random example of 'CompositionGraph' is also exported.
+Examples of other categories transformed into 'CompositionGraph's are also pretty printed.
 
-A 'CompositionGraph' created from a string is also exported.
+A random example of 'CompositionGraph' is also pretty printed.
 
-Export the categories in the directory "OutputGraphViz\/Examples\/FiniteCategories\/CompositionGraph".
+A 'CompositionGraph' created from a string is also pretty printed.
 -}
 module Math.FiniteCategories.CompositionGraph.Example
 (
@@ -28,21 +26,64 @@     import Math.FiniteCategory
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
     import Math.IO.PrettyPrint
+    import Math.FiniteCategories.FunctorCategory
+    import Math.Categories.FinCat
     
+    import Data.Text (pack)
+    
     import System.Random
     import Numeric.Natural
     
-    -- | An example of 'CompositionGraph' exported with GraphViz.
+    -- | An example of 'CompositionGraph' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.CompositionGraph.Example"
-        catToPdf (unsafeCompositionGraph (unsafeGraph (set [1 :: Int,2,3]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=2,labelArrow='b'},Arrow{sourceArrow=2,targetArrow=3,labelArrow='c'}])) (weakMap [([Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}],[Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])])) "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/CompositionGraph"
-        diagToPdf2 (finiteCategoryToCompositionGraph (ens.(Set.powerSet).set $ "AB")) "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/EnsToCompositionGraph"
-        diagToPdf2 (finiteCategoryToCompositionGraph (numberCategory 4)) "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/NumberCategoryToCompositionGraph"
-        catToPdf (fst.defaultConstructRandomCompositionGraph $ (mkStdGen 123456)) "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/RandomCompositionGraph"
-        diagToPdf2 (fst.defaultConstructRandomDiagram $ (mkStdGen 12345678)) "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/RandomDiagram"
+        putStrLn $ pprintFiniteCategory (unsafeCompositionGraph (unsafeGraph (set [1 :: Int,2,3]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=2,labelArrow='b'},Arrow{sourceArrow=2,targetArrow=3,labelArrow='c'}])) (weakMap [([Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}],[Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])])) 
+        putStrLn $ pprint (finiteCategoryToCompositionGraph (ens.(Set.powerSet).set $ "AB"))
+        putStrLn $ pprint  (finiteCategoryToCompositionGraph (numberCategory 4)) 
+        putStrLn $ pprintFiniteCategory (fst.defaultConstructRandomCompositionGraph $ (mkStdGen 123456))
+        putStrLn $ pprint  (fst.defaultConstructRandomDiagram $ (mkStdGen 12345678))
         let (Right cg) = readCGString "A -f-> B -g-> C = A -h-> C"
-        catToPdf cg "OutputGraphViz/Examples/FiniteCategories/CompositionGraph/CompositionGraphFromString"
+        putStrLn $ pprintFiniteCategory cg
+        let (Right cg) = readCGString "A -f-> B\nB -g-> C\nC -h-> B\nB -g-> C -h-> B = <ID>\nC -h-> B -g-> C -h-> B -g-> C = C -h-> B -g-> C"
+        putStrLn $ pprintFiniteCategory cg
+        
+        putStrLn (take 30 (repeat '\n'))
+        
+        -- let (Right cg1) = readCGString "A -f-> B"
+        -- let (Right cg2) = readCGString "A -g-> C"
+        -- let diag = discreteDiagram FinCat [cg1,cg2]
+        -- let colimit = colimitOfCompositionGraphs diag (\x o -> (pack.show $ x) <> (pack ".")<>o) (\x m -> (pack.show$ x) <>(pack ".")<>m)
+        
+        -- putStrLn $ show $ nadir colimit
+        -- putStrLn "\n\n\n"
+        -- putStrLn $ show $ colimit
+        
+        let (Right cg1) = readCGString "A -f-> B\nB -g-> C"
+        let (Right cg2) = readCGString "1 -a-> 2\n 2 -b-> 3"
+        let (Right cg3) = readCGString "A1 -(gof)a-> C2"
+        let f = completeDiagram Diagram{src = cg3, tgt = cg1, omap = weakMap [(pack "A1", pack "A"),(pack "C2", pack "C")], mmap = weakMap [(anElement $ genAr cg3 (pack "A1") (pack "C2"), anElement $ ar cg1 (pack "A") (pack "C"))]}
+        let g = completeDiagram Diagram{src = cg3, tgt = cg2, omap = weakMap [(pack "A1", pack "1"),(pack "C2", pack "2")], mmap = weakMap [(anElement $ genAr cg3 (pack "A1") (pack "C2"), anElement $ ar cg2 (pack "1") (pack "2"))]}
+        let diag = completeDiagram Diagram{src = Hat, tgt = FinCat, omap = weakMap [(HatA,cg3) , (HatB,cg2), (HatC, cg1)], mmap = weakMap [(HatF, g), (HatG, f)]}
+        
+        let coproduct = coproductOfTextCompositionGraphs diag
+        putStrLn $ pprintFiniteCategory $ nadir coproduct
+        putStrLn $ "\n\n"
+        putStrLn $ show $ coproduct
+        putStrLn $ "\n\n"
+        
+        
+        -- let Just f_ = ((legsCocone coproduct) =>$ HatB) @? f
+        -- let Just g_ = ((legsCocone coproduct) =>$ HatC) @? g
+        -- let coequalizer = coequalizeCompositionGraphs f_ g_
+        -- putStrLn $ pprintFiniteCategory $ tgt coequalizer
+        -- putStrLn $ "\n\n"
+        -- putStrLn $ show $ coequalizer
+        -- putStrLn $ "\n\n"
+        
+        let colimit = colimitOfCompositionGraphs diag (\x o -> (pack.show $ x) <> (pack ".")<>o) (\x m -> (pack.show$ x) <>(pack ".")<>m)
+        putStrLn $ pprintFiniteCategory $ nadir colimit
+        putStrLn $ "\n\n"
+        putStrLn $ show $ colimit
         putStrLn "End of Math.FiniteCategories.CompositionGraph.Example"
src/Math/FiniteCategories/ConeCategory/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An exemple of 'ConeCategory' exported with GraphViz.
+Description : An exemple of 'ConeCategory' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An exemple of 'ConeCategory' exported with GraphViz.
+An exemple of 'ConeCategory' pretty printed.
 
-Export the 'ConeCategory' of a 'V' 'Diagram' in a square category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/ConeCategory".
+Pretty print the 'ConeCategory' of a 'V' 'Diagram'.
 -}
 module Math.FiniteCategories.ConeCategory.Example
 (
@@ -22,8 +22,10 @@     import              Math.FiniteCategories.V
     import              Math.FiniteCategories.Hat
     import              Math.FiniteCategories.SafeCompositionGraph
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
     
+    
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
     import              Data.WeakSet.Safe
@@ -31,15 +33,15 @@     import qualified    Data.WeakMap           as Map
     import              Data.WeakMap.Safe
     
-    -- | An exemple of 'ConeCategory' exported with GraphViz.
+    -- | An exemple of 'ConeCategory' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.ConeCategory.Example"
         let Right scg = safeCompositionGraph (unsafeGraph (set "ABCD") (set [Arrow{sourceArrow = 'A', targetArrow = 'B', labelArrow='f'}, Arrow{sourceArrow = 'A', targetArrow = 'C', labelArrow='g'}, Arrow{sourceArrow = 'B', targetArrow = 'D', labelArrow='h'}, Arrow{sourceArrow = 'C', targetArrow = 'D', labelArrow='I'}])) (weakMap [([Arrow{sourceArrow = 'C', targetArrow = 'D', labelArrow='I'}, Arrow{sourceArrow = 'A', targetArrow = 'C', labelArrow='g'}],[Arrow{sourceArrow = 'B', targetArrow = 'D', labelArrow='h'}, Arrow{sourceArrow = 'A', targetArrow = 'B', labelArrow='f'}])]) 3
         let diag = completeDiagram Diagram{src=V,tgt=scg,omap=weakMap [(VA,'D'),(VB,'B'),(VC,'C')], mmap=weakMap [(VF,anElement (genAr scg 'B' 'D')),(VG,anElement (genAr scg 'C' 'D'))]}
-        diagToPdf2 diag "OutputGraphViz/Examples/FiniteCategories/ConeCategory/Diag"
-        catToPdf (coneCategory diag) "OutputGraphViz/Examples/FiniteCategories/ConeCategory/ConeCategory"
+        putStrLn $ pprint  diag 
+        putStrLn $ pprintFiniteCategory  (coneCategory diag) 
         let diag2 = completeDiagram Diagram{src=Hat,tgt=scg,omap=weakMap [(HatA,'A'),(HatB,'B'),(HatC,'C')], mmap=weakMap [(HatF,anElement (genAr scg 'A' 'B')),(HatG,anElement (genAr scg 'A' 'C'))]}
-        diagToPdf2 diag2 "OutputGraphViz/Examples/FiniteCategories/ConeCategory/Diag2"
-        catToPdf (coconeCategory diag2) "OutputGraphViz/Examples/FiniteCategories/ConeCategory/CoconeCategory"
+        putStrLn $ pprint  diag2 
+        putStrLn $ pprintFiniteCategory  (coconeCategory diag2) 
         putStrLn "End of Math.FiniteCategories.ConeCategory.Example"
src/Math/FiniteCategories/DiscreteCategory/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : Six examples of 'DiscreteCategory' exported with GraphViz.
+Description : Six examples of 'DiscreteCategory' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Six examples of 'DiscreteCategory' exported with GraphViz.
+Six examples of 'DiscreteCategory' pretty printed.
 
-Export categories __0__ up to __5__ in the directory "OutputGraphViz\/Examples\/FiniteCategories\/DiscreteCategory".
+Pretty print categories __0__ up to __5__ .
 -}
 module Math.FiniteCategories.DiscreteCategory.Example
 (
@@ -18,13 +18,14 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories.DiscreteCategory
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | Six examples of 'DiscreteCategory' exported with GraphViz.
+    -- | Six examples of 'DiscreteCategory' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.DiscreteCategory.Example"
         let cats = discreteCategory <$> (\n -> set (take n ['A'..])) <$> [0..5]
-        let exports = uncurry catToPdf <$> zip cats (("OutputGraphViz/Examples/FiniteCategories/DiscreteCategory/"++) <$> show <$> [0..5])
-        sequence exports
+        let ps = (putStrLn.pprintFiniteCategory) <$> cats
+        sequence ps
         putStrLn "End of Math.FiniteCategories.DiscreteCategory.Example"
src/Math/FiniteCategories/Ens/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : An example of  __'Ens'__ exported with GraphViz.
+Description : An example of  __'Ens'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of  __'Ens'__ exported with GraphViz.
-
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/Ens".
+An example of  __'Ens'__ pretty printed.
 -}
 module Math.FiniteCategories.Ens.Example
 (
@@ -19,11 +17,12 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | __'Ens'__ exported with GraphViz.
+    -- | __'Ens'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.Ens.Example"
-        catToPdf (ens.powerSet.set $ "ABC") "OutputGraphViz/Examples/FiniteCategories/Ens/Ens"
+        putStrLn $ pprintFiniteCategory (ens.powerSet.set $ "ABC")
         putStrLn "End of Math.FiniteCategories.Ens.Example"
src/Math/FiniteCategories/Examples.hs view
@@ -6,7 +6,7 @@ Stability   : experimental
 Portability : portable
 
-Run all finite categories examples. See results in the folder "OutputGraphViz\/Examples\/FiniteCategories".
+Run all finite categories examples. See results in the folder 
 -}
 
 module Math.FiniteCategories.Examples
src/Math/FiniteCategories/FinCat/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : An example of 'FullSubcategory' of __'FinCat'__ exported with GraphViz.
+Description : An example of 'FullSubcategory' of __'FinCat'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of 'FullSubcategory' of __'FinCat'__ exported with GraphViz.
-
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/FinCat".
+An example of 'FullSubcategory' of __'FinCat'__ pretty printed.
 -}
 module Math.FiniteCategories.FinCat.Example
 (
@@ -19,13 +17,14 @@     
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
     import Numeric.Natural
     
-    -- | An example of 'FullSubcategory' of __'FinCat'__ exported with GraphViz.
+    -- | An example of 'FullSubcategory' of __'FinCat'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.FinCat.Example"
-        catToPdf (FullSubcategory FinCat (numberCategory <$> (set [0..2])) :: FullSubcategory (FinCat NumberCategory NumberCategoryMorphism Natural) (FinFunctor NumberCategory NumberCategoryMorphism Natural) NumberCategory) "OutputGraphViz/Examples/FiniteCategories/FinCat/FinCat"
+        putStrLn $ pprintFiniteCategory (FullSubcategory FinCat (numberCategory <$> (set [0..2])) :: FullSubcategory (FinCat NumberCategory NumberCategoryMorphism Natural) (FinFunctor NumberCategory NumberCategoryMorphism Natural) NumberCategory)
         putStrLn "End of Math.FiniteCategories.FinCat.Example"
src/Math/FiniteCategories/FinGrph/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An example of 'FullSubcategory' of __'FinGrph'__ exported with GraphViz.
+Description : An example of 'FullSubcategory' of __'FinGrph'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of 'FullSubcategory' of __'FinGrph'__ exported with GraphViz.
+An example of 'FullSubcategory' of __'FinGrph'__ pretty printed.
 
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/FinGrph".
+
 -}
 module Math.FiniteCategories.FinGrph.Example
 (
@@ -25,15 +25,17 @@     
     import              Math.Categories  
     import              Math.FiniteCategories
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
     
+    
     import              Numeric.Natural
     
     
-    -- | A 'FullSubcategory' __'FinGrph'__ exported with GraphViz.
+    -- | A 'FullSubcategory' __'FinGrph'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.FinGrph.Example"
         let c = FullSubcategory FinGrph $ (underlyingGraphFormat id (const.pack $ "")).numberCategory <$> set [0..2] :: FullSubcategory (FinGrph Natural Text) (GraphHomomorphism Natural Text) (Graph Natural Text)
-        catToPdf c "OutputGraphViz/Examples/FiniteCategories/FinGrph/FinGrph"
+        putStrLn $ pprintFiniteCategory c 
         putStrLn "End of Math.FiniteCategories.FinGrph.Example"
src/Math/FiniteCategories/FunctorCategory/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An example of 'FunctorCategory' exported with GraphViz.
+Description : An example of 'FunctorCategory' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of 'FunctorCategory' exported with GraphViz.
+An example of 'FunctorCategory' pretty printed.
 
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/FunctorCategory".
+
 -}
 module Math.FiniteCategories.FunctorCategory.Example
 (
@@ -21,23 +21,22 @@     import Math.FiniteCategory
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    
     import Math.IO.PrettyPrint
     
     import Numeric.Natural
     
-    -- | An example of 'FunctorCategory' exported with GraphViz.
+    -- | An example of 'FunctorCategory' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.FunctorCategory.Example"
-        catToPdf (FunctorCategory (numberCategory 2) (numberCategory 3)) "OutputGraphViz/Examples/FiniteCategories/FunctorCategory/FunctorCategory"
-        sequence $ (uncurry diagToPdfCluster) <$> zip (setToList (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/FunctorCategory/functCluster"++).show) <$> (take (cardinal (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) [1..]))
-        sequence $ (uncurry diagToPdf) <$> zip (setToList (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/FunctorCategory/funct"++).show) <$> (take (cardinal (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) [1..]))
-        sequence $ (uncurry diagToPdf2) <$> zip (setToList (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/FunctorCategory/diag"++).show) <$> (take (cardinal (ob (FunctorCategory (numberCategory 2) (numberCategory 3)))) [1..]))
-        sequence $ (uncurry natToPdf) <$> zip (setToList (arrows (FunctorCategory (numberCategory 2) (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/FunctorCategory/nat"++).show) <$> (take (cardinal (arrows (FunctorCategory (numberCategory 2) (numberCategory 3)))) [1..]))
+        putStrLn $  pprintFiniteCategory (FunctorCategory (numberCategory 2) (numberCategory 3)) 
+        sequence $ (putStrLn.pprint) <$> (setToList (ob (FunctorCategory (numberCategory 2) (numberCategory 3))))
+        sequence $ (putStrLn.pprint) <$> (setToList (ob (FunctorCategory (numberCategory 2) (numberCategory 3))))
+        sequence $ (putStrLn.pprint) <$> (setToList (arrows (FunctorCategory (numberCategory 2) (numberCategory 3))))
         let diag = completeDiagram Diagram{src=discreteCategory (set [1,2]), tgt = (numberCategory 2), omap=memorizeFunction id (set [1,2]), mmap = weakMap []}
-        diagToPdf2 diag "OutputGraphViz/Examples/FiniteCategories/PrecomposedFunctorCategory/Functor"
-        catToPdf (PrecomposedFunctorCategory diag (numberCategory 3)) "OutputGraphViz/Examples/FiniteCategories/PrecomposedFunctorCategory/PrecomposedFunctorCategory"
-        sequence $ (uncurry diagToPdf2) <$> zip (setToList (ob (PrecomposedFunctorCategory diag (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/PrecomposedFunctorCategory/precompFunct"++).show) <$> (take (cardinal (ob (PrecomposedFunctorCategory diag (numberCategory 3)))) [1..]))
-        sequence $ (uncurry natToPdf) <$> zip (setToList (arrows (PrecomposedFunctorCategory diag (numberCategory 3)))) ((("OutputGraphViz/Examples/FiniteCategories/PrecomposedFunctorCategory/nat"++).show) <$> (take (cardinal (arrows (PrecomposedFunctorCategory diag (numberCategory 3)))) [1..]))
+        (putStrLn.pprint) $ diag 
+        putStrLn $  pprintFiniteCategory (PrecomposedFunctorCategory diag (numberCategory 3)) 
+        sequence $ (putStrLn.pprint) <$> (setToList (ob (PrecomposedFunctorCategory diag (numberCategory 3))))
+        sequence $ (putStrLn.pprint) <$> (setToList (arrows (PrecomposedFunctorCategory diag (numberCategory 3))))
         putStrLn "End of Math.FiniteCategories.FunctorCategory.Example"
src/Math/FiniteCategories/Hat/Example.hs view
@@ -1,14 +1,13 @@ {-| Module  : FiniteCategories
-Description : __'Hat'__ exported with GraphViz.
+Description : __'Hat'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-__'Hat'__ exported with GraphViz.
+__'Hat'__ pretty printed.
 
-Export the __'Hat'__ category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/Hat".
 -}
 module Math.FiniteCategories.Hat.Example
 (
@@ -18,11 +17,13 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories.Hat
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | __'Hat'__ exported with GraphViz.
+    
+    -- | __'Hat'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.Hat.Example"
-        catToPdf Hat "OutputGraphViz/Examples/FiniteCategories/Hat/Hat"
+        putStrLn $ pprintFiniteCategory Hat 
         putStrLn "End of Math.FiniteCategories.Hat.Example"
src/Math/FiniteCategories/NumberCategory/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : Six examples of 'NumberCategory' exported with GraphViz.
+Description : Six examples of 'NumberCategory' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Six examples of 'NumberCategory' exported with GraphViz.
-
-Export categories __0__ up to __5__ in the directory "OutputGraphViz\/Examples\/FiniteCategories\/NumberCategory".
+Six examples of 'NumberCategory' pretty printed. 
 -}
 module Math.FiniteCategories.NumberCategory.Example
 (
@@ -16,13 +14,15 @@ )
 where
     import Math.FiniteCategories.NumberCategory
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | Six examples of 'NumberCategory' exported with GraphViz.
+    
+    -- | Six examples of 'NumberCategory' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.NumberCategory.Example"
         let cats = numberCategory <$> [0..5]
-        let exports = uncurry catToPdf <$> zip cats (("OutputGraphViz/Examples/FiniteCategories/NumberCategory/"++) <$> show <$> [0..5])
-        sequence exports
+        let p = (putStrLn.pprintFiniteCategory) <$> cats
+        sequence p
         putStrLn "End of Math.FiniteCategories.NumberCategory.Example"
src/Math/FiniteCategories/One/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : __1__ exported with GraphViz.
+Description : __1__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-__1__ exported with GraphViz.
-
-Export the __1__ category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/One".
+__1__ pretty printed.
 -}
 module Math.FiniteCategories.One.Example
 (
@@ -16,11 +14,13 @@ )
 where
     import Math.FiniteCategories.One
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.FiniteCategory
+    import Math.IO.PrettyPrint
     
-    -- | __'One'__ exported with GraphViz.
+    
+    -- | __'One'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.One.Example"
-        catToPdf One "OutputGraphViz/Examples/FiniteCategories/One/One"
+        putStrLn $  pprintFiniteCategory One 
         putStrLn "End of Math.FiniteCategories.One.Example"
src/Math/FiniteCategories/Opposite/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An example of opposite category exported with GraphViz.
+Description : An example of opposite category pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of opposite category exported with GraphViz.
+An example of opposite category pretty printed.
 
-Export the category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/Opposite".
+
 -}
 module Math.FiniteCategories.Opposite.Example
 (
@@ -20,14 +20,16 @@     
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.FiniteCategory
+    import Math.IO.PrettyPrint
     
-    -- | An example of opposite category exported with GraphViz.
+    
+    -- | An example of opposite category pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.Opposite.Example"
-        catToPdf (ens.powerSet.set $ "AB") "OutputGraphViz/Examples/FiniteCategories/Opposite/Ens"
-        catToPdf (Op (ens.powerSet.set $ "AB")) "OutputGraphViz/Examples/FiniteCategories/Opposite/OppositeEns"
-        catToPdf (numberCategory 4) "OutputGraphViz/Examples/FiniteCategories/Opposite/4"
-        catToPdf (Op (numberCategory 4)) "OutputGraphViz/Examples/FiniteCategories/Opposite/Opposite4"
+        putStrLn $  pprintFiniteCategory (ens.powerSet.set $ "AB") 
+        putStrLn $  pprintFiniteCategory (Op (ens.powerSet.set $ "AB")) 
+        putStrLn $  pprintFiniteCategory (numberCategory 4) 
+        putStrLn $  pprintFiniteCategory (Op (numberCategory 4)) 
         putStrLn "End of Math.FiniteCategories.Opposite.Example"
src/Math/FiniteCategories/Parallel/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : __'Parallel'__ exported with GraphViz.
+Description : __'Parallel'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-__'Parallel'__ exported with GraphViz.
-
-Export the __'Parallel'__ category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/Parallel".
+__'Parallel'__ pretty printed.
 -}
 module Math.FiniteCategories.Parallel.Example
 (
@@ -18,11 +16,13 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories.Parallel
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | __'Parallel'__ exported with GraphViz.
+    
+    -- | __'Parallel'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.Parallel.Example"
-        catToPdf Parallel "OutputGraphViz/Examples/FiniteCategories/Parallel/Parallel"
+        putStrLn $  pprintFiniteCategory Parallel 
         putStrLn "End of Math.FiniteCategories.Parallel.Example"
src/Math/FiniteCategories/SafeCompositionGraph.hs view
@@ -259,6 +259,7 @@             parserLexHelper ('-':'>':' ':str) = EndArrow : (parserLexHelper str)
             parserLexHelper (' ':'=':' ':str) = Equals : (parserLexHelper str)
             parserLexHelper ('<':'I':'D':'/':'>':str) = Identity : (parserLexHelper str)
+            parserLexHelper ('<':'I':'D':'>':str) = Identity : (parserLexHelper str)
             parserLexHelper ('<':'S':'R':'C':'>':str) = BeginSrc : (parserLexHelper str)
             parserLexHelper ('<':'T':'G':'T':'>':str) = BeginTgt : (parserLexHelper str)
             parserLexHelper ('<':'/':'S':'R':'C':'>':str) = EndSrc : (parserLexHelper str)
src/Math/FiniteCategories/SafeCompositionGraph/Example.hs view
@@ -1,18 +1,16 @@ {-| Module  : FiniteCategories
-Description : An example of 'SafeCompositionGraph' exported with GraphViz.
+Description : An example of 'SafeCompositionGraph' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of 'SafeCompositionGraph' exported with GraphViz.
-
-A 'SafeCompositionGraph' created from a string is also exported.
+An example of 'SafeCompositionGraph' pretty printed.
 
-A random 'SafeCompositionGraph' is also exported.
+A 'SafeCompositionGraph' created from a string is also pretty printed.
 
-Export the categories in the directory "OutputGraphViz\/Examples\/FiniteCategories\/SafeCompositionGraph".
+A random 'SafeCompositionGraph' is also pretty printed.
 -}
 module Math.FiniteCategories.SafeCompositionGraph.Example
 (
@@ -26,21 +24,21 @@     import Math.FiniteCategory
     import Math.Categories
     import Math.FiniteCategories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    
     import Math.IO.PrettyPrint
     
     import Numeric.Natural
     import System.Random
     
-    -- | An example of 'SafeCompositionGraph' exported with GraphViz.
+    -- | An example of 'SafeCompositionGraph' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.SafeCompositionGraph.Example"
-        catToPdf (unsafeSafeCompositionGraph (unsafeGraph (set [1 :: Int,2,3]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=2,labelArrow='b'},Arrow{sourceArrow=2,targetArrow=3,labelArrow='c'}])) (weakMap [([Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}],[Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])]) 3) "OutputGraphViz/Examples/FiniteCategories/SafeCompositionGraph/SafeCompositionGraph"
-        catToPdf (unsafeSafeCompositionGraph (unsafeGraph (set [1 :: Int]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])) (weakMap []) 3) "OutputGraphViz/Examples/FiniteCategories/SafeCompositionGraph/SafeCompositionGraphOnFreeMonoid"
+        putStrLn $  pprintFiniteCategory (unsafeSafeCompositionGraph (unsafeGraph (set [1 :: Int,2,3]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=2,labelArrow='b'},Arrow{sourceArrow=2,targetArrow=3,labelArrow='c'}])) (weakMap [([Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'},Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}],[Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])]) 3) 
+        putStrLn $  pprintFiniteCategory (unsafeSafeCompositionGraph (unsafeGraph (set [1 :: Int]) (set [Arrow{sourceArrow=1,targetArrow=1,labelArrow='a'}])) (weakMap []) 3) 
         
-        catToPdf (fst.defaultConstructRandomSafeCompositionGraph $ (mkStdGen 123456)) "OutputGraphViz/Examples/FiniteCategories/SafeCompositionGraph/RandomSafeCompositionGraph"
+        putStrLn $  pprintFiniteCategory (fst.defaultConstructRandomSafeCompositionGraph $ (mkStdGen 123456)) 
         
         let (Right scg) = readSCGString "2\nA -f-> B -g-> C = A -h-> C"
-        catToPdf scg "OutputGraphViz/Examples/FiniteCategories/SafeCompositionGraph/SafeCompositionGraphFromString"
+        putStrLn $  pprintFiniteCategory scg 
         putStrLn "End of Math.FiniteCategories.SafeCompositionGraph.Example"
src/Math/FiniteCategories/Square/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : __'Square'__ exported with GraphViz.
+Description : __'Square'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-__'Square'__ exported with GraphViz.
-
-Export the __'Square'__ category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/Square".
+__'Square'__ pretty printed.
 -}
 module Math.FiniteCategories.Square.Example
 (
@@ -18,11 +16,13 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories.Square
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | __'Square'__ exported with GraphViz.
+    
+    -- | __'Square'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.Square.Example"
-        catToPdf Square "OutputGraphViz/Examples/FiniteCategories/Square/Square"
+        putStrLn $  pprintFiniteCategory Square 
         putStrLn "End of Math.FiniteCategories.Square.Example"
src/Math/FiniteCategories/V/Example.hs view
@@ -1,14 +1,12 @@ {-| Module  : FiniteCategories
-Description : __'V'__ exported with GraphViz.
+Description : __'V'__ pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-__'V'__ exported with GraphViz.
-
-Export the __'V'__ category in the directory "OutputGraphViz\/Examples\/FiniteCategories\/V".
+__'V'__ pretty printed.
 -}
 module Math.FiniteCategories.V.Example
 (
@@ -18,11 +16,13 @@     import Data.WeakSet.Safe
     
     import Math.FiniteCategories.V
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import Math.IO.PrettyPrint
+    import Math.FiniteCategory
     
-    -- | __'V'__ exported with GraphViz.
+    
+    -- | __'V'__ pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.V.Example"
-        catToPdf V "OutputGraphViz/Examples/FiniteCategories/V/V"
+        putStrLn $  pprintFiniteCategory V 
         putStrLn "End of Math.FiniteCategories.V.Example"
src/Math/FiniteCategory.hs view
@@ -23,6 +23,11 @@     arTo,
     arFrom2,
     arTo2,
+    arrowsWithoutId,
+    arFromWithoutId,
+    arToWithoutId,
+    arFrom2WithoutId,
+    arTo2WithoutId,
     identities,
     -- ** Morphism predicates
     isEpic,
@@ -40,17 +45,25 @@     genArTo,
     genArFrom2,
     genArTo2,
+    genArrowsWithoutId,
+    genArFromWithoutId,
+    genArToWithoutId,
+    genArFrom2WithoutId,
+    genArTo2WithoutId,
+    
     -- ** Helper
     bruteForceDecompose,
+    pprintFiniteCategory,
     module Math.Category
 )
 where
     import              Data.WeakSet                (Set)
     import qualified    Data.WeakSet           as   Set
     import              Data.WeakSet.Safe
-    import              Data.List                   (elemIndex)
+    import              Data.List                   (elemIndex, intercalate)
     
     import              Math.Category
+    import              Math.IO.PrettyPrint
     
     import              Control.Monad               (join)
     
@@ -81,7 +94,27 @@     -- | `arFrom2` same as `arFrom` but for multiple sources.
     arFrom2 :: (FiniteCategory c m o, Morphism m o) => c -> Set o -> Set m
     arFrom2 c ss = join $ ar c <$> ss <*> ob c
+    
+    -- | Same as `arrows` but without identities.  
+    arrowsWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set m
+    arrowsWithoutId c = Set.filter (isNotIdentity c) (arrows c)
 
+    -- | Same as `arTo` but without identities. 
+    arToWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+    arToWithoutId c t = (Set.filter (isNotIdentity c)) $ arTo c t
+        
+    -- | Same as `arTo2` but without identities. 
+    arTo2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+    arTo2WithoutId c ts = (Set.filter (isNotIdentity c)) $ arTo2 c ts
+        
+    -- | Same as `arFrom` but without identities. 
+    arFromWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+    arFromWithoutId c s = (Set.filter (isNotIdentity c)) $ arFrom c s
+        
+    -- | Same as `arFrom2` but without identities.
+    arFrom2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+    arFrom2WithoutId c ss = (Set.filter (isNotIdentity c)) $ arFrom2 c ss
+
     -- | Same as `arrows` but only returns the generators. @genArrows c@ should be included in @arrows c@.  
     genArrows :: (FiniteCategory c m o, Morphism m o) => c -> Set m
     genArrows c = join $ genAr c <$> ob c <*> ob c
@@ -102,6 +135,30 @@     genArFrom2 :: (FiniteCategory c m o, Morphism m o) => c -> Set o -> Set m
     genArFrom2 c ss = join $ genAr c <$> ss <*> ob c 
 
+    -- | Same as `genArrows` but without identities.  
+    genArrowsWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set m
+    genArrowsWithoutId c = Set.filter (isNotIdentity c) (genArrows c)
+
+    -- | Same as `genArTo` but without identities. 
+    genArToWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+    genArToWithoutId c t = (Set.filter (isNotIdentity c)) $ genArTo c t
+        
+    -- | Same as `genArTo2` but without identities. 
+    genArTo2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+    genArTo2WithoutId c ts = (Set.filter (isNotIdentity c)) $ genArTo2 c ts
+        
+    -- | Same as `genArFrom` but without identities. 
+    genArFromWithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> o -> Set m
+    genArFromWithoutId c s = (Set.filter (isNotIdentity c)) $ genArFrom c s
+        
+    -- | Same as `genArFrom2` but without identities.
+    genArFrom2WithoutId :: (FiniteCategory c m o, Morphism m o, Eq m, Eq o) => c -> Set o -> Set m
+    genArFrom2WithoutId c ss = (Set.filter (isNotIdentity c)) $ genArFrom2 c ss
+    
+    
+
+
+
     -- | `identities` returns all the identities of a category.
     identities :: (FiniteCategory c m o, Morphism m o) => c -> Set m
     identities c = identity c <$> ob c
@@ -151,4 +208,8 @@     -- This method is meant to be used temporarly until a proper decompose method is implemented. (It is very slow.)
     bruteForceDecompose :: (FiniteCategory c m o, Morphism m o, Eq m) => c -> m -> [m]
     bruteForceDecompose c m = bruteForce c m ((:[]) <$> (setToList $ genArFrom c (source m))) 
-    +    
+    
+    -- | Pretty print a category by enumerating all objects, and then all arrows.
+    pprintFiniteCategory :: (FiniteCategory c m o, Morphism m o, PrettyPrint c, PrettyPrint m, PrettyPrint o, Eq m, Eq o) => c -> String
+    pprintFiniteCategory c = "Category : " ++ pprint c ++ "\nObjects :\n"++ (intercalate "\n" (setToList $ pprint <$> ob c)) ++ "\nArrows :\n"++ (intercalate "\n" (setToList $ pprint <$> arrows c)) 
src/Math/Functors/Adjunction/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An exemple of 'leftAdjoint' and 'rightAdjoint' use exported with GraphViz.
+Description : An exemple of 'leftAdjoint' and 'rightAdjoint' use pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An exemple of 'leftAdjoint' and 'rightAdjoint' use exported with GraphViz.
+An exemple of 'leftAdjoint' and 'rightAdjoint' use pretty printed.
 
-Export the lim functor of a discrete 'Diagram' in 'Ens' in the directory "OutputGraphViz\/Examples\/Functor\/Adjunction".
+
 -}
 module Math.Functors.Adjunction.Example
 (
@@ -21,7 +21,9 @@     import              Math.Categories.FunctorCategory   
     import              Math.Functors.Adjunction
     import              Math.Functors.DiagonalFunctor
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
+
     
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
@@ -30,7 +32,7 @@     import qualified    Data.WeakMap           as Map
     import              Data.WeakMap.Safe
     
-    -- | An exemple of 'leftAdjoint' and 'rightAdjoint' use exported with GraphViz.
+    -- | An exemple of 'leftAdjoint' and 'rightAdjoint' use pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.Functors.Adjunction.Example"
@@ -39,8 +41,8 @@         let diagFunct = diagonalFunctor indexing universe
         let leftAdj = leftAdjoint diagFunct
         let rightAdj = rightAdjoint diagFunct
-        catToPdf universe "OutputGraphViz/Examples/Functors/Adjunction/ens"
-        catToPdf indexing "OutputGraphViz/Examples/Functors/Adjunction/indexing"
-        diagToPdf2 (fst.anElement.(Map.mapToSet).omap $ leftAdj) "OutputGraphViz/Examples/Functors/Adjunction/diag"
-        diagToPdf2 (selectObject universe (snd.anElement.(Map.mapToSet).omap $ leftAdj)) "OutputGraphViz/Examples/Functors/Adjunction/limit"        
+        putStrLn $ pprintFiniteCategory universe 
+        putStrLn $ pprintFiniteCategory indexing 
+        putStrLn $ pprint (fst.anElement.(Map.mapToSet).omap $ leftAdj) 
+        putStrLn $ pprint (selectObject universe (snd.anElement.(Map.mapToSet).omap $ leftAdj)) 
         putStrLn "End of Math.Functors.Adjunction.Example"
src/Math/Functors/DataMigration/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An exemple of a 'dataMigration' exported with GraphViz.
+Description : An exemple of a 'dataMigration' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An exemple of 'dataMigration' exported with GraphViz.
+An exemple of 'dataMigration' pretty printed.
 
-Export a data migration in the directory "OutputGraphViz\/Examples\/Functor\/DataMigration".
+
 -}
 module Math.Functors.DataMigration.Example
 (
@@ -20,7 +20,9 @@     import              Math.FiniteCategories
     import              Math.Functors.DataMigration
     import              Math.Categories.FinSet
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
+
     
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
@@ -29,7 +31,7 @@     import qualified    Data.WeakMap           as Map
     import              Data.WeakMap.Safe
     
-    -- | An exemple of 'DataMigration' exported with GraphViz.
+    -- | An exemple of 'DataMigration' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.Functors.DataMigration.Example"
@@ -37,21 +39,21 @@         -- let Right autographSketch = readSCGString "3\nA -s-> A -s-> A = A -t-> A\nA -s-> A -t-> A = <ID>\nA -t-> A -s-> A = <ID>\n A -t-> A -t-> A = A -s-> A"
         -- let f = (setToList $ ob (FunctorCategory graphSketch autographSketch)) !! 7
         -- --Diagram{src=graphSketch, tgt=autographSketch, omap=memorizeFunction (const.anElement.ob $ autographSketch) (ob graphSketch), mmap = weakMap (zip (setToList (arrows graphSketch)) (setToList (arrows autographSketch)))}
-        -- catToPdf graphSketch "OutputGraphViz/Examples/Functors/DataMigration/graphSketch"
-        -- catToPdf autographSketch "OutputGraphViz/Examples/Functors/DataMigration/autographSketch"
-        -- diagToPdf2 f "OutputGraphViz/Examples/Functors/DataMigration/f"
+        -- putStrLn $ pprintFiniteCategory graphSketch 
+        -- putStrLn $ pprintFiniteCategory autographSketch 
+        -- putStrLn $ pprint f 
         -- putStrLn (show f)
         -- let universe = ens $ set [set [1 :: Int,2]]
         -- let delta = (deltaFunctor universe f)
         -- let anInstance = anElement (ob.source $ delta)
-        -- diagToPdf anInstance "OutputGraphViz/Examples/Functors/DataMigration/autograph1"
-        -- diagToPdf (delta ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/delta_autograph1"
+        -- putStrLn $ pprint anInstance 
+        -- putStrLn $ pprint (delta ->$ anInstance) 
         
         -- let universe = ens $ set [set[], set[1], set[1 :: Int,2]]
         -- let pii = (piFunctor universe f)
         -- let anInstance = (setToList.ob.source $ delta) !! 0
-        -- diagToPdf anInstance "OutputGraphViz/Examples/Functors/DataMigration/graph1"
-        -- diagToPdf (pii ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/pi_graph1"
+        -- putStrLn $ pprint anInstance 
+        -- putStrLn $ pprint (pii ->$ anInstance) 
         
         -- let c = V
         -- let d = numberCategory 2
@@ -59,21 +61,21 @@         let c = Parallel
         let d = discreteCategory (set "A")
         let f = completeDiagram Diagram{src=d,tgt=c,omap=weakMap [('A',ParallelA)],mmap = Map.empty}
-        diagToPdf f "OutputGraphViz/Examples/Functors/DataMigration/functor"
+        putStrLn $ pprint f 
         
         let universe = ens $ set [set[], set [1 :: Int,2], set [1]]
         let anInstance = completeDiagram Diagram{src=d,tgt=universe,omap=weakMap [('A',set [1])],mmap=Map.empty}
-        diagToPdf anInstance "OutputGraphViz/Examples/Functors/DataMigration/anInstance"
-        diagToPdf2 anInstance "OutputGraphViz/Examples/Functors/DataMigration/anInstance2"
+        putStrLn $ pprint anInstance 
+        putStrLn $ pprint anInstance 
         
         let pii = (piFunctor universe f)
-        diagToPdf (pii ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/pi_anInstance1"
-        diagToPdf2 (pii ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/pi_anInstance2"
+        putStrLn $ pprint (pii ->$ anInstance) 
+        putStrLn $ pprint (pii ->$ anInstance) 
         putStrLn $ show (pii ->$ anInstance)
         
         let sigmaa = (sigmaFunctor universe f)
-        diagToPdf (sigmaa ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/sigma_anInstance1"
-        diagToPdf2 (sigmaa ->$ anInstance) "OutputGraphViz/Examples/Functors/DataMigration/sigma_anInstance2"
+        putStrLn $ pprint (sigmaa ->$ anInstance) 
+        putStrLn $ pprint (sigmaa ->$ anInstance) 
         putStrLn $ show (sigmaa ->$ anInstance)
         
         putStrLn "End of Math.Functors.DataMigration.Example"
src/Math/Functors/DiagonalFunctor/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An exemple of a 'diagonalFunctor' exported with GraphViz.
+Description : An exemple of a 'diagonalFunctor' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An exemple of 'diagonalFunctor' exported with GraphViz.
+An exemple of 'diagonalFunctor' pretty printed.
 
-Export a diagonal functor in the directory "OutputGraphViz\/Examples\/Functor\/DiagonalFunctor".
+
 -}
 module Math.Functors.DiagonalFunctor.Example
 (
@@ -19,7 +19,9 @@     import              Math.FiniteCategories.DiscreteCategory
     import              Math.FiniteCategories.V
     import              Math.Functors.DiagonalFunctor
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
+
     
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
@@ -28,11 +30,11 @@     import qualified    Data.WeakMap           as Map
     import              Data.WeakMap.Safe
     
-    -- | An exemple of 'diagonalFunctor' exported with GraphViz.
+    -- | An exemple of 'diagonalFunctor' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.Functors.DiagonalFunctor.Example"
-        catToPdf (discreteCategory (set [1 :: Int,2])) "OutputGraphViz/Examples/Functors/DiagonalFunctor/indexing"
-        catToPdf V "OutputGraphViz/Examples/Functors/DiagonalFunctor/target"
-        diagToPdf2 (diagonalFunctor (discreteCategory (set [1 :: Int,2])) V) "OutputGraphViz/Examples/Functors/DiagonalFunctor/diagonalFunctor"
+        putStrLn $ pprintFiniteCategory (discreteCategory (set [1 :: Int,2])) 
+        putStrLn $ pprintFiniteCategory V 
+        putStrLn $ pprint (diagonalFunctor (discreteCategory (set [1 :: Int,2])) V) 
         putStrLn "End of Math.Functors.DiagonalFunctor.Example"
src/Math/Functors/Examples.hs view
@@ -6,7 +6,7 @@ Stability   : experimental
 Portability : portable
 
-Run all functors examples. See results in the folder "OutputGraphViz\/Examples\/Functors".
+Run all functors examples. See results in the folder 
 -}
 
 module Math.Functors.Examples
src/Math/Functors/KanExtension/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : Examples of Kan extensions exported with GraphViz.
+Description : Examples of Kan extensions pretty printed.
 Copyright   : Guillaume Sabbagh 2023
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Examples of Kan extensions exported with GraphViz.
+Examples of Kan extensions pretty printed.
 
-Export extensions in the directory "OutputGraphViz\/Examples\/Functor\/KanExtension".
+
 -}
 module Math.Functors.KanExtension.Example
 (
@@ -18,7 +18,9 @@     import              Math.FiniteCategory
     import              Math.FiniteCategories
     import              Math.Functors.KanExtension
-    import              Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.IO.PrettyPrint
+    import              Math.FiniteCategory
+
     
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
@@ -27,38 +29,117 @@     import qualified    Data.WeakMap           as Map
     import              Data.WeakMap.Safe
     
-    -- | Examples of Kan extensions exported with GraphViz.
+    -- | Examples of Kan extensions pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.Functors.KanExtension.Example"
         let d1 = (setToList $ ob (FunctorCategory (numberCategory 2) (numberCategory 4)))!! 3
         let d2 = (setToList $ ob (FunctorCategory (numberCategory 2) (numberCategory 3)))!! 2
-        diagToPdf2 d1 "OutputGraphViz/Examples/Functors/KanExtension/F"
-        diagToPdf2 d2 "OutputGraphViz/Examples/Functors/KanExtension/X"
+        putStrLn $ pprint d1 
+        putStrLn $ pprint d2 
         let Just (lk,lknat) = (leftKan d1 d2)
-        diagToPdf2 lk "OutputGraphViz/Examples/Functors/KanExtension/Lan_F(X)"
-        natToPdf lknat "OutputGraphViz/Examples/Functors/KanExtension/EtaLan_F(X)"
+        putStrLn $ pprint lk 
+        putStrLn $ pprint lknat 
         let Just (rk,rknat) = (rightKan d1 d2)
-        diagToPdf2 rk "OutputGraphViz/Examples/Functors/KanExtension/Ran_F(X)"
-        natToPdf rknat "OutputGraphViz/Examples/Functors/KanExtension/RhoRan_F(X)"
+        putStrLn $ pprint rk 
+        putStrLn $ pprint rknat 
         
         let a = unsafeReadSCGString "2\nA\n"
-        catToPdf a "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/A"
+        putStrLn $ pprintFiniteCategory a 
         let b = unsafeReadSCGString "2\nA -f-> B\n"
-        catToPdf b "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/B"
+        putStrLn $ pprintFiniteCategory b 
         let c = unsafeReadSCGString "2\nA -f-> B -g-> A = <ID>\nB -g-> A -f-> B = <ID>\n"
-        catToPdf c "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/C"
+        putStrLn $ pprintFiniteCategory c 
         let f = unsafeReadSCGDString "<SRC>\n2\nA\n</SRC>\n<TGT>\n2\nA -f-> B -g-> A = <ID>\nB -g-> A -f-> B = <ID>\n</TGT>\nA => A"
-        diagToPdf2 f "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/F"
+        putStrLn $ pprint f 
         let g = unsafeReadSCGDString "<SRC>\n2\nA\n</SRC>\n<TGT>\n2\nA -f-> B\n</TGT>\nA => A"
-        diagToPdf2 g "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/G"
+        putStrLn $ pprint g 
         
         let Just (lk,lknat) = (leftKan f g)
-        diagToPdf2 lk "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/Lan_F(G)"
-        natToPdf lknat "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/EtaLan_F(G)"
+        putStrLn $ pprint lk 
+        putStrLn $ pprint lknat 
         
         let Just (rk,rknat) = (rightKan f g)
-        diagToPdf2 rk "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/Ran_F(G)"
-        natToPdf rknat "OutputGraphViz/Examples/Functors/KanExtension/NotPointwise/EpsilonLan_F(G)"
+        putStrLn $ pprint rk 
+        putStrLn $ pprint rknat 
+        
+        
+        let a = unsafeReadSCGString "2\nA\nB\n"
+        putStrLn $ pprintFiniteCategory a 
+        let b = unsafeReadSCGString "2\nC -p1-> A\nC -p2-> B\n"
+        putStrLn $ pprintFiniteCategory b 
+        let c = unsafeReadSCGString "2\n0 -abs-> 1\n"
+        putStrLn $ pprintFiniteCategory c 
+        let f = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\nC -p1-> A\nC -p2-> B\n</TGT>\nA => A\nB => B\n"
+        putStrLn $ pprint f 
+        let x = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\n0 -abs-> 1\n</TGT>\nA => 1\nB => 1"
+        putStrLn $ pprint x 
+        
+        -- let Just (lk,lknat) = (leftKan f x)
+        -- putStrLn $ pprint lk 
+        -- putStrLn $ pprint lknat 
+        
+        let Just (rk,rknat) = (rightKan f x)
+        putStrLn $ pprint rk 
+        putStrLn $ pprint rknat 
+        
+        
+        let a = unsafeReadSCGString "2\nA\nB\n"
+        putStrLn $ pprintFiniteCategory a 
+        let b = unsafeReadSCGString "2\nA -q1-> C\nB -q2-> C\n"
+        putStrLn $ pprintFiniteCategory b 
+        let c = unsafeReadSCGString "2\n0 -abs-> 1\n"
+        putStrLn $ pprintFiniteCategory c 
+        let f = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\nA -q1-> C\nB -q2-> C\n</TGT>\nA => A\nB => B\n"
+        putStrLn $ pprint f 
+        let x = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\n0 -abs-> 1\n</TGT>\nA => 1\nB => 1"
+        putStrLn $ pprint x 
+        
+        let Just (lk,lknat) = (leftKan f x)
+        putStrLn $ pprint lk 
+        putStrLn $ pprint lknat 
+        
+        -- let Just (rk,rknat) = (rightKan f x)
+        -- putStrLn $ pprint rk 
+        -- putStrLn $ pprint rknat 
+        
+        
+        let a = unsafeReadSCGString "2\nA\nB\n"
+        putStrLn $ pprintFiniteCategory a 
+        let b = unsafeReadSCGString "2\nA -f-> C\nB -g-> C\n"
+        putStrLn $ pprintFiniteCategory b 
+        let c = unsafeReadSCGString "2\n0 -f-> 1\n1 -g-> 2\n"
+        putStrLn $ pprintFiniteCategory c 
+        let f = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\nA -f-> C\nB -g-> C\n</TGT>\nA => A\nB => B\n"
+        putStrLn $ pprint f 
+        let x = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\n0 -f-> 1\n1 -g-> 2\n</TGT>\nA => 1\nB => 1"
+        putStrLn $ pprint x 
+        
+        let Just (lk,lknat) = (leftKan f x)
+        putStrLn $ pprint lk 
+        putStrLn $ pprint lknat 
+        
+        let Just (rk,rknat) = (rightKan f x)
+        putStrLn $ pprint rk 
+        putStrLn $ pprint rknat 
+        
+        -- let a = unsafeReadSCGString "2\nA\nB\n"
+        -- putStrLn $ pprintFiniteCategory a 
+        -- let b = unsafeReadSCGString "2\nA -q1-> C\nB -q2-> C\n"
+        -- putStrLn $ pprintFiniteCategory b 
+        -- let c = unsafeReadSCGString "2\n0 -abs-> 1\n"
+        -- putStrLn $ pprintFiniteCategory c 
+        -- let f = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\nA -q1-> C\nB -q2-> C\n</TGT>\nA => A\nB => B\n"
+        -- putStrLn $ pprint f 
+        -- let x = unsafeReadSCGDString "<SRC>\n2\nA\nB\n</SRC>\n<TGT>\n2\n0 -abs-> 1\n</TGT>\nA => 0\nB => 1"
+        -- putStrLn $ pprint x 
+        
+        -- let Just (lk,lknat) = (leftKan f x)
+        -- putStrLn $ pprint lk 
+        -- putStrLn $ pprint lknat 
+        
+        -- let Just (rk,rknat) = (rightKan f x)
+        -- putStrLn $ pprint rk 
+        -- putStrLn $ pprint rknat 
         
         putStrLn "End of Math.Functors.KanExtension.Example"
src/Math/Functors/SetValued.hs view
@@ -54,7 +54,7 @@     formatSetOfLimitObjects :: (Eq o1, Eq m2, Eq a, PrettyPrint a) => Set (LimitObject o1 m2 a) -> String
     formatSetOfLimitObjects setOfMaps = "{" ++ intercalate "," (formatLimitObject <$> setToList setOfMaps) ++ "}"
     
-    -- | Format a 'LimitObject' to be readable.
+    -- | Format a 'Function' of 'LimitObject's to be readable.
     formatFunctionOfLimitObjects :: (Eq o1, Eq m2, Eq a, PrettyPrint a) => Function (LimitObject o1 m2 a) -> String
     formatFunctionOfLimitObjects func = intercalate "," [(formatLimitObject k) ++ " -> " ++ (formatLimitObject v) | (k,v) <- (Map.mapToList (function func))]
     
@@ -127,7 +127,7 @@     formatSetOfColimitObjects :: (Eq o1, Eq m2, Eq a, PrettyPrint a) => Set (ColimitObject o1 m2 a) -> String
     formatSetOfColimitObjects setOfEquivClasses = "{" ++ intercalate "," (formatColimitObject <$> setToList setOfEquivClasses) ++ "}"
     
-    -- | Format a 'ColimitObject' to be readable.
+    -- | Format a 'Function' of 'ColimitObject's to be readable.
     formatFunctionOfColimitObjects :: (Eq o1, Eq m2, Eq a, PrettyPrint a) => Function (ColimitObject o1 m2 a) -> String
     formatFunctionOfColimitObjects func = intercalate "," [(formatColimitObject k) ++ " -> " ++ (formatColimitObject v) | (k,v) <- (Map.mapToList (function func))]
  
src/Math/Functors/SetValued/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : Examples of Kan extensions of set-valued functors exported with GraphViz.
+Description : Examples of Kan extensions of set-valued functors pretty printed.
 Copyright   : Guillaume Sabbagh 2023
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-Examples of Kan extensions of set-valued functors exported with GraphViz.
+Examples of Kan extensions of set-valued functors pretty printed.
 
-Export extensions in the directory "OutputGraphViz\/Examples\/Functor\/SetValued".
+
 -}
 module Math.Functors.SetValued.Example
 (
@@ -16,10 +16,11 @@ )
 where
     import              Math.FiniteCategory
+    import              Math.IO.PrettyPrint
     import              Math.FiniteCategories
     import              Math.Categories.FinSet
     import              Math.Functors.SetValued
-    import              Math.IO.FiniteCategories.ExportGraphViz
+
     
     import              Data.WeakSet             (Set)
     import qualified    Data.WeakSet           as Set
@@ -30,24 +31,26 @@     
     import              Data.Text                (pack)
     
-    -- | Examples of Kan extensions of set-valued functors exported with GraphViz.
+
+    
+    -- | Examples of Kan extensions of set-valued functors pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.Functors.SetValued.Example"
-        let c1 = unsafeReadSCGString "2\nA -f-> B\n"
-        catToPdf c1 "OutputGraphViz/Examples/Functors/SetValued/A"
-        let c2 = unsafeReadSCGString "2\nA -f-> B -g-> A = <ID>\nB -g-> A -f-> B = <ID>\n"
-        catToPdf c2 "OutputGraphViz/Examples/Functors/SetValued/B"
-        let f = unsafeReadSCGDString "<SRC>\n2\nA -f-> B\n</SRC>\n<TGT>\n2\nA -f-> B -g-> A = <ID>\nB -g-> A -f-> B = <ID>\n</TGT>\nA -f-> B => A -f-> B\n"
-        diagToPdf2 f "OutputGraphViz/Examples/Functors/SetValued/F"
-        let x = completeDiagram Diagram{src=c1,tgt=FinSet,omap=weakMap [(pack "A",set [0,1 :: Int]),(pack "B", set [2,3,4])], mmap=weakMap [(anElement (genAr c1 (pack "A") (pack "B")),Function{function=weakMap [(0,2),(1,2)], codomain = set [2,3,4]})]}
-        diagToPdf2 (fullDiagram2 x) "OutputGraphViz/Examples/Functors/SetValued/X"
+        let Right c1 = readSCGString "2\nA -f-> B\nC -g-> B\n"
+        putStrLn $ pprintFiniteCategory c1 
+        let Right c2 = readSCGString "2\nA -f-> B\nC -g-> B\nB -h-> C\nA -i-> C\nC -g-> B -h-> C = <ID>\nB -h-> C -g-> B = <ID>\nA -i-> C -g-> B = A -f-> B\nA -f-> B -h-> C = A -i-> C\n"
+        putStrLn $ pprintFiniteCategory c2 
+        let Right f = readSCGDString "<SRC>\n2\nA -f-> B\nC -g-> B\n</SRC>\n<TGT>\n2\nA -f-> B\nC -g-> B\nB -h-> C\nA -i-> C\nC -g-> B -h-> C = <ID>\nB -h-> C -g-> B = <ID>\nA -i-> C -g-> B = A -f-> B\nA -f-> B -h-> C = A -i-> C\n</TGT>\nA -f-> B => A -f-> B\nC -g-> B => C -g-> B\n"
+        putStrLn $ pprint f 
+        let x = completeDiagram Diagram{src=c1,tgt=FinSet,omap=weakMap [(pack "A",set [1 :: Int]),(pack "B",set [2,3]),(pack "C",set [4,5])], mmap= weakMap [(anElement (genAr c1 (pack "A") (pack "B")),Function{function=weakMap [(1,2)], codomain = set [2,3]}),(anElement (genAr c1 (pack "C") (pack "B")),Function{function=weakMap [(4,2),(5,3)], codomain = set [2,3]})]}
+        putStrLn $ pprint (fullDiagram2 x) 
         let (ran, epsilon) = rightKanSetValued f x
-        diagToPdf (fullDiagram2 ran) "OutputGraphViz/Examples/Functors/SetValued/Ran2"
-        diagToPdf2Format (fullDiagram2 ran) formatSetOfLimitObjects formatFunctionOfLimitObjects "OutputGraphViz/Examples/Functors/SetValued/Ran"
-        natToPdfFormat (fullNaturalTransformation2 epsilon) formatSetOfLimitObjects formatFunctionOfLimitObjects "OutputGraphViz/Examples/Functors/SetValued/Epsilon"
+        putStrLn $ pprint (fullDiagram2 ran) 
+        putStrLn $ pprint (fullDiagram2 ran)
+        putStrLn $ pprint (fullNaturalTransformation2 epsilon)
         let (lan, eta) = leftKanSetValued f x
-        diagToPdf (fullDiagram2 lan) "OutputGraphViz/Examples/Functors/SetValued/Lan2"
-        diagToPdf2Format (fullDiagram2 lan) formatSetOfColimitObjects formatFunctionOfColimitObjects "OutputGraphViz/Examples/Functors/SetValued/Lan"
-        natToPdfFormat (fullNaturalTransformation2 eta) formatSetOfColimitObjects formatFunctionOfColimitObjects "OutputGraphViz/Examples/Functors/SetValued/Eta"
+        putStrLn $ pprint (fullDiagram2 lan) 
+        putStrLn $ pprint (fullDiagram2 lan)
+        putStrLn $ pprint (fullNaturalTransformation2 eta) 
         putStrLn "End of Math.Functors.SetValued.Example"
src/Math/Functors/YonedaEmbedding/Example.hs view
@@ -1,14 +1,14 @@ {-| Module  : FiniteCategories
-Description : An example of 'yonedaEmbedding' exported with GraphViz.
+Description : An example of 'yonedaEmbedding' pretty printed.
 Copyright   : Guillaume Sabbagh 2022
 License     : GPL-3
 Maintainer  : guillaumesabbagh@protonmail.com
 Stability   : experimental
 Portability : portable
 
-An example of  'yonedaEmbedding' exported with GraphViz.
+An example of  'yonedaEmbedding' pretty printed.
 
-Export the diagram in the directory "OutputGraphViz\/Examples\/Functors\/YonedaEmbedding".
+
 -}
 module Math.Functors.YonedaEmbedding.Example
 (
@@ -20,12 +20,13 @@     
     import Math.FiniteCategories
     import Math.Categories
-    import Math.IO.FiniteCategories.ExportGraphViz
+    import              Math.FiniteCategory
+    import              Math.IO.PrettyPrint
     
-    -- | 'yonedaEmbedding' exported with GraphViz.
+    -- | 'yonedaEmbedding' pretty printed.
     main :: IO ()
     main = do
         putStrLn "Start of Math.FiniteCategories.YonedaEmbedding.Example"
-        diagToPdf2 (fullDiagram.yonedaEmbedding $ Hat) "OutputGraphViz/Examples/FiniteCategories/YonedaEmbedding/YonedaEmbeddingHat"
-        diagToPdf2 (fullDiagram.yonedaEmbedding $ Square) "OutputGraphViz/Examples/FiniteCategories/YonedaEmbedding/YonedaEmbeddingSquare"
+        putStrLn $ pprint (fullDiagram.yonedaEmbedding $ Hat) 
+        putStrLn $ pprint (fullDiagram.yonedaEmbedding $ Square) 
         putStrLn "End of Math.FiniteCategories.YonedaEmbedding.Example"
− src/Math/IO/FiniteCategories/ExportGraphViz.hs
@@ -1,487 +0,0 @@-{-# LANGUAGE MonadComprehensions #-}
-
-{-| Module  : FiniteCategories
-Description : Visualize finite categories with GraphViz.
-Copyright   : Guillaume Sabbagh 2022
-License     : GPL-3
-Maintainer  : guillaumesabbagh@protonmail.com
-Stability   : experimental
-Portability : portable
-
-This module is a way of exporting finite categories with GraphViz.
-
-Every function assumes that the 'FiniteCategory' is a 'FiniteCategory', if you want to export a category without implementing an instantiation of 'FiniteCategory', you can instantiate 'FiniteCategory' with the default functions 'defaultGenAr' and 'defaultDecompose'.
--}
-
-module Math.IO.FiniteCategories.ExportGraphViz
-(
-    -- * Visualize categories
-    categoryToGraph,
-    catToDot,
-    catToPdf,
-    genToDot,
-    genToPdf,
-    categoryToGraphFormat,
-    catToDotFormat,
-    catToPdfFormat,
-    -- * Visualize diagrams
-    diagToDotCluster,
-    diagToPdfCluster,
-    diagToDot,
-    diagToPdf,
-    diagToDot2,
-    diagToPdf2,
-    diagToDot2Format,
-    diagToPdf2Format,
-    -- * Visualize natural transformations
-    natToDot,
-    natToPdf,
-    natToDotFormat,
-    natToPdfFormat,
-)
-where
-    import              Math.FiniteCategory
-    import              Math.FiniteCategories
-    import              Math.IO.PrettyPrint
-    
-    import qualified    Data.Text.Lazy                      as L    (pack, Text)
-    import qualified    Data.Text.Lazy.IO                   as IO   (putStrLn, writeFile)
-    import              Data.Graph.Inductive.Graph                  (mkGraph, Node, Edge, LNode, LEdge)
-    import              Data.Graph.Inductive.PatriciaTree           (Gr)
-    import              Data.GraphViz                               (graphToDot, nonClusteredParams, fmtNode, fmtEdge, GraphvizParams(..), NodeCluster(..), blankParams,GraphID( Num ), Number(..))
-    import              Data.GraphViz.Attributes.Complete           (Label(StrLabel), Attribute(Label))
-    import              Data.GraphViz.Attributes                    (X11Color(..), color)
-    import              Data.GraphViz.Printing                      (renderDot, toDot)
-    import              Data.Maybe                                  (fromJust)
-    import              Data.List                                   (elemIndex,intercalate)
-    import              Data.WeakSet.Safe
-    import  qualified   Data.WeakSet                        as Set
-    import              Data.WeakMap.Safe
-    
-    import              System.Process                              (callCommand)
-    import              System.Directory                            (createDirectoryIfMissing)
-    import              System.FilePath.Posix                       (takeDirectory)
-
-
-
-    -- | Write lazy text to a file specified by a path, if the path leads to non existing directories, it creates the directories. Credits to wisn : https://stackoverflow.com/a/58685979
-    createAndWriteFile :: FilePath -> L.Text -> IO ()
-    createAndWriteFile path content = do
-        createDirectoryIfMissing True $ takeDirectory path
-        IO.writeFile path content
-    
-    -- | Transform an object of a category into a pure node.
-    objToNode :: (Eq o, FiniteCategory c m o) => c -> o -> Node
-    objToNode c o
-        | index == Nothing = error("Call objToNod on an object not in the category.")
-        | otherwise = i
-        where 
-            Just i = index
-            index = elemIndex o (setToList.ob $ c)
-
-    -- | Transform an object of a category into a labeled node.
-    objToLNode :: (Eq o, PrettyPrint o, FiniteCategory c m o) => c -> o -> LNode String
-    objToLNode c o = (objToNode c o, pprint o)
-    
-    -- | Transform an object of a category into a labeled node, using a custom function.
-    objToLNodeFormat :: (Eq o, FiniteCategory c m o) => c -> (o -> String) -> o -> LNode String
-    objToLNodeFormat c formatObj o = (objToNode c o, formatObj o)
-    
-    -- | Transform a morphism of a category into a pure edge.
-    arToEdge :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> m -> Edge
-    arToEdge c m = ((objToNode c). source $ m, (objToNode c). target $ m)
-    
-    -- | Transform a morphism of a category into a labeled edge.
-    arToLEdge :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> m -> LEdge String
-    arToLEdge c m = ((objToNode c). source $ m, (objToNode c). target $ m, pprint m)
-    
-    -- | Transform a morphism of a category into a labeled edge using a custom function.
-    arToLEdgeFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (m -> String) -> m -> LEdge String
-    arToLEdgeFormat c formatMorph m = ((objToNode c). source $ m, (objToNode c). target $ m, formatMorph m)
-    
-    -- | Transform a category into an underlying inductive graph.
-    categoryToGraph :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> Gr String String
-    categoryToGraph c = mkGraph (setToList (objToLNode c <$> (ob c))) (setToList (arToLEdge c <$> (arrows c)))
-    
-    -- | Transform a category into an underlying inductive graph using formatting functions.
-    categoryToGraphFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> Gr String String
-    categoryToGraphFormat c formatObj formatMorph = mkGraph (setToList (objToLNodeFormat c formatObj <$> (ob c))) (setToList (arToLEdgeFormat c formatMorph <$> (arrows c)))
-    
-    -- | Transform a dot representation of a graph into a pdf file.
-    dotToPdf :: IO () -> String -> IO ()
-    dotToPdf dot path = dot >> callCommand ("dot "++path++" -o "++path++".pdf -T pdf") 
-    
-    -- | Export a category with GraphViz. If the category is too large, use `genToDot` instead.
-    --
-    -- The black arrows are generating arrows, grey one are generated arrows.
-    catToDot :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
-    catToDot c path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label))],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)),
-                                                   if label `isIn` generatorsLabels then color Black else color Gray80]} (categoryToGraph c)
-        generators = genArrows c
-        generatorsLabels = pprint <$> generators
-
-    -- | Export a category with GraphViz, format the objects and the morphisms. If the category is too large, use `genToDot` instead.
-    --
-    -- The black arrows are generating arrows, grey one are generated arrows.
-    catToDotFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> String -> IO ()
-    catToDotFormat c formatObj formatMorph path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label))],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)),
-                                                   if label `isIn` generatorsLabels then color Black else color Gray80]} (categoryToGraphFormat c formatObj formatMorph)
-        generators = genArrows c
-        generatorsLabels = formatMorph <$> generators
-
-
-    -- | Export a category with GraphViz. If the category is too large, use `genToPdf` instead.
-    --
-    -- The black arrows are generating arrows, grey one are generated arrows.
-    catToPdf :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
-    catToPdf c path = dotToPdf (catToDot c path) path
-    
-    -- | Export a category with GraphViz and format objects and arrows. If the category is too large, use `genToPdf` instead.
-    --
-    -- The black arrows are generating arrows, grey one are generated arrows.
-    catToPdfFormat :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> (o -> String) -> (m -> String) -> String -> IO ()
-    catToPdfFormat c formatObj formatMorph path = dotToPdf (catToDotFormat c formatObj formatMorph path) path
-    
-    -- | Transforms a category into an inductive graph.
-    categoryToGeneratorGraph :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> Gr String String
-    categoryToGeneratorGraph c = mkGraph (setToList (objToLNode c <$> (ob c))) (setToList (arToLEdge c <$> (genArrows c)))
-    
-    -- | Export the generator of a category with GraphViz. Use this when the category is too large to be fully exported.
-    genToDot :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
-    genToDot c path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label))],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label))]} (categoryToGeneratorGraph c)
-
-    -- | Export the generator of a category with GraphViz. Use this when the category is to large to be fully exported.
-    genToPdf :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> String -> IO ()
-    genToPdf c path =  dotToPdf (genToDot c path) path
-    
-    
-     -- __________________________________
-    -- __________________________________
-    --
-    -- Diagram representation with cluster of objects mapped together
-    -- __________________________________
-    -- __________________________________
-    
-
-    
-    -- | If the node is pair, then it is part of the source category, else it is part of the target category.
-    diagObjToNodeCluster :: (Eq o, FiniteCategory c m o) => c -> Bool -> o -> Node
-    diagObjToNodeCluster c b o
-        | index == Nothing = error("Call diagObjToNod on an object not in the category.")
-        | otherwise = if b then 2*i else 2*i+1
-        where 
-            Just i = index
-            index = elemIndex o (setToList (ob c))
-            
-    diagObjToLNodeCluster :: (Eq o, PrettyPrint o, FiniteCategory c m o) => c -> Bool -> o -> LNode String
-    diagObjToLNodeCluster c b o = (diagObjToNodeCluster c b o, pprint o)
-    
-    diagArToEdgeCluster :: (Eq o, Morphism m o, FiniteCategory c m o) => c -> Bool -> m -> Edge
-    diagArToEdgeCluster c b m = ((diagObjToNodeCluster c b). source $ m, (diagObjToNodeCluster c b). target $ m)
-    
-    diagArToLEdgeCluster :: (Eq o, PrettyPrint o, PrettyPrint m, Morphism m o, FiniteCategory c m o) => c -> Bool -> m -> LEdge String
-    diagArToLEdgeCluster c b m = ((diagObjToNodeCluster c b). source $ m, (diagObjToNodeCluster c b). target $ m, pprint m)
-    
-    diagToGraphCluster :: (Eq c1, Eq o1, PrettyPrint o1, PrettyPrint m1, Morphism m1 o1, FiniteCategory c1 m1 o1,
-                           Eq c2, Eq o2, PrettyPrint o2, PrettyPrint m2, Morphism m2 o2, FiniteCategory c2 m2 o2) =>
-                           Diagram c1 m1 o1 c2 m2 o2 -> Gr String String
-    diagToGraphCluster f = mkGraph (setToList ((diagObjToLNodeCluster (src f) True <$> (ob (src f))))++(setToList (diagObjToLNodeCluster (tgt f) False <$> (ob (tgt f))))) (setToList ((diagArToLEdgeCluster (src f) True <$> (genArrows (src f))))++(setToList (diagArToLEdgeCluster (tgt f) False <$> (genArrows (tgt f)))))
-    
-    -- | Export a functor with GraphViz such that the source category is in green, the target in blue, the objects mapped together are in the same cluster.
-    diagToDotCluster :: (Eq c1, Eq o1, PrettyPrint o1, PrettyPrint m1, Morphism m1 o1, FiniteCategory c1 m1 o1,
-                         Eq c2, Eq o2, PrettyPrint o2, PrettyPrint m2, Morphism m2 o2, FiniteCategory c2 m2 o2) =>
-                        Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
-    diagToDotCluster f@Diagram{src=s,tgt=t,omap=om,mmap=fm} path =  createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot Params {
-                                             isDirected = True
-                                            ,globalAttributes = []
-                                            ,clusterBy = (\(n,nl) -> if (n `mod` 2) == 0 then (C ((fromJust (elemIndex (om |!| ((setToList (ob s)) !! (n `div` 2))) (setToList (ob t))))) $ N (n,nl)) else (C (fromJust (elemIndex ((setToList (ob t)) !! (n `div` 2)) (setToList (ob t)))) $ N (n,nl)))
-                                            ,isDotCluster = const True
-                                            ,clusterID = Num . Int
-                                            ,fmtCluster = const []
-                                            ,fmtNode = \(n,label)-> [Label (StrLabel (L.pack label)), if (n `mod` 2) == 0 then color Green else color Blue]
-                                            ,fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label))]
-                                          } (diagToGraphCluster f)
-    
-    -- | Export a functor as a pdf with GraphViz such that the source category is in green, the target in blue, the objects mapped together are in the same cluster.
-    diagToPdfCluster :: (Eq c1, Eq o1, PrettyPrint o1, PrettyPrint m1, Morphism m1 o1, FiniteCategory c1 m1 o1,
-                         Eq c2, Eq o2, PrettyPrint o2, PrettyPrint m2, Morphism m2 o2, FiniteCategory c2 m2 o2) =>
-                        Diagram c1 m1 o1 c2 m2 o2 -> String -> IO ()
-    diagToPdfCluster f path =  dotToPdf (diagToDotCluster f path) path
-    
-    
-    -- __________________________________
-    -- __________________________________
-    --
-    -- Diagram representation with arrows between arrows
-    -- __________________________________
-    -- __________________________________
-    
-    indexAr :: (Morphism m o, FiniteCategory c m o, Eq o, Eq m) => c -> m -> Int
-    indexAr c m 
-        | isIn m (arrows c) = fromJust $ elemIndex m (setToList (arrows c))
-        | otherwise = error "indexAr of arrow not in category"
-    
-    indexOb :: (FiniteCategory c m o, Eq o) => c -> o -> Int
-    indexOb c o
-        | isIn o (ob c) = fromJust $ elemIndex o (setToList (ob c))
-        | otherwise = error "indexOb of object not in category"
-    
-    -- | If the node%4 == 0, then it is part of the source category, else if node%4 == 1 it is part of the target category.
-    diagObjToNode :: (Eq o, FiniteCategory c m o) => c -> Bool -> o -> Node
-    diagObjToNode c b o
-        | index == Nothing = error("Call diagObjToNode on an object not in the category.")
-        | otherwise = if b then 4*i else 4*i+1
-        where 
-            Just i = index
-            index = elemIndex o (setToList (ob c))
-    
-    diagObjToLNode :: (Eq o, PrettyPrint o, FiniteCategory c m o) => c -> Bool -> o -> LNode String
-    diagObjToLNode c b o = (diagObjToNode c b o, pprint o)
-            
-    -- Creates the invisible node associated to an arrow of the source category if the boolean is True, of the target category if the boolean is False.
-    invisNodeSrc :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1,
-                     Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2) =>
-                    (Diagram c1 m1 o1 c2 m2 o2) -> m1 -> LNode String
-    invisNodeSrc f@Diagram{src=s,tgt=t,mmap=_,omap=_} m = (4*(indexAr s m)+2, pprint m)
-    
-    invisNodeTgt :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1,
-                     Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2) =>
-                    (Diagram c1 m1 o1 c2 m2 o2) -> m2 -> LNode String
-    invisNodeTgt f@Diagram{src=s,tgt=t,mmap=_,omap=_} m = (4*(indexAr t m)+3, pprint m)
-    
-    diagArToLEdges :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1,
-                       Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2) =>
-                      (Diagram c1 m1 o1 c2 m2 o2) -> Either m1 m2 -> [LEdge String]
-    diagArToLEdges f@Diagram{src=s,tgt=t,omap=_,mmap=_} (Left m) = [((diagObjToNode s True). source $ m, fst.(invisNodeSrc f) $ m, ""),(fst.(invisNodeSrc f) $ m,(diagObjToNode s True). target $ m, "")]
-    diagArToLEdges f@Diagram{src=s,tgt=t,omap=_,mmap=_} (Right m) = [((diagObjToNode t False). source $ m, fst.(invisNodeTgt f) $ m, ""),(fst.(invisNodeTgt f) $ m,(diagObjToNode t False). target $ m, "")]
-    
-    linkArrows :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1,
-                   Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2) =>
-                  (Diagram c1 m1 o1 c2 m2 o2) -> [LEdge String]
-    linkArrows f@Diagram{src=s,tgt=t,omap=_,mmap=fm} = (\m->(fst(invisNodeSrc f m),fst(invisNodeTgt f (fm |!| m)),"")) <$> (setToList (arrows s))
-    
-    linkObjects :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1,
-                    Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2) =>
-                   (Diagram c1 m1 o1 c2 m2 o2) -> [LEdge String]
-    linkObjects f@Diagram{src=s,tgt=t,omap=om,mmap=_} = (\o->(diagObjToNode s True o,diagObjToNode t False (om |!| o),"")) <$> (setToList (ob s))
-    
-    diagToGraph :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                    Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                   (Diagram c1 m1 o1 c2 m2 o2) -> Gr String String
-    diagToGraph f = mkGraph ((diagObjToLNode (src f) True <$> (setToList (ob (src f))))++(diagObjToLNode (tgt f) False <$> (setToList (ob (tgt f))))++((invisNodeSrc f) <$> (setToList (arrows (src f))))++((invisNodeTgt f) <$> (setToList (arrows (tgt f)))))
-                             ((Prelude.concat ((diagArToLEdges f <$> (Left <$> (setToList (arrows (src f)))))++(diagArToLEdges f <$> (Right <$> (setToList (arrows (tgt f)))))))++(linkArrows f)++(linkObjects f))
-    
-    -- | Export a diagram with GraphViz such that the source category is in green, the target in blue, each morphism is represented by a node.
-    diagToDot :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                 (Diagram c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    diagToDot f@Diagram{src=s,tgt=t,omap=om,mmap=fm} path =  createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot Params {
-                                             isDirected = True
-                                            ,globalAttributes = []
-                                            ,clusterBy = (\(n,nl) -> case () of
-                                                                  _ | (n `mod` 2) == 0 -> (C 0 $ N (n,nl))
-                                                                    | (n `mod` 2) == 1 -> (C 1 $ N (n,nl)))
-                                            ,isDotCluster = const True
-                                            ,clusterID = Num . Int
-                                            ,fmtCluster = const []
-                                            ,fmtNode = \(n,label)-> [Label (StrLabel (L.pack label)), fmtColorN n]
-                                            ,fmtEdge= \e@(n1,n2,label)-> [Label (StrLabel (L.pack label)), fmtColorE e]
-                                          } (diagToGraph f)
-                    where
-                        fmtColorN n   | n `mod` 4 == 0 = color Green
-                                      | n `mod` 4 == 1 = color Blue
-                                      | n `mod` 4 == 2 = color Red
-                                      | n `mod` 4 == 3 = color Pink
-                        fmtColorE (s,t,_)   | s `mod ` 4 == 0 = if t `mod` 2 == 1 then color Red else color Green
-                                            | t `mod ` 4 == 0 = color Green
-                                            | s `mod ` 4 == 1 = color Blue
-                                            | t `mod ` 4 == 1 = color Blue
-                                            | otherwise = color Black
-            
-    -- | Export a diagram as a pdf with GraphViz such that the source category is in green, the target in blue, each morphism is represented by a node.
-    diagToPdf :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                 (Diagram c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    diagToPdf f path =  dotToPdf (diagToDot f path) path
-    
-    
-    -- __________________________________
-    -- __________________________________
-    --
-    -- Diagram representation as a selection of the target category
-    -- __________________________________
-    -- __________________________________
-    
-    -- | Export a diagram with GraphViz such that a node or an arrow is in orange if it is the target of the functor.
-    diagToDot2 :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                   Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                  (Diagram c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    diagToDot2 f@Diagram{src=s,tgt=t,omap=om,mmap=fm} path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label)), colorNode n],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)), colorEdge label]} (categoryToGraph t)
-                                                   where
-                                                        colorNode n = case () of
-                                                                        _ | countPredN == 0 -> color Black
-                                                                          | countPredN == 1 -> color Orange
-                                                                          | countPredN == 2 -> color Orange1
-                                                                          | countPredN == 3 -> color Orange2
-                                                                          | countPredN == 4 -> color Orange3
-                                                                          | countPredN == 5 -> color Orange4
-                                                                          | otherwise -> color OrangeRed4
-                                                                        
-                                                            where
-                                                                countPredN = Prelude.length [1 | o <- (setToList (ob s)), (objToNode t (om |!| o)) == n]
-                                                        colorEdge e = case () of
-                                                                        _ | countPredE == 0 -> color Black
-                                                                          | countPredE == 1 -> color Orange
-                                                                          | countPredE == 2 -> color Orange1
-                                                                          | countPredE == 3 -> color Orange2
-                                                                          | countPredE == 4 -> color Orange3
-                                                                          | countPredE == 5 -> color Orange4
-                                                                          | otherwise -> color OrangeRed4
-                                                            where
-                                                                countPredE = Prelude.length [1 | m <- (setToList (arrows s)), (pprint (fm |!| m)) == e]
-    
-    -- | Export a diagram as a pdf with GraphViz such that a node or an arrow is in orange if it is the target of the functor.
-    diagToPdf2 :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                 (Diagram c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    diagToPdf2 f path =  dotToPdf (diagToDot2 f path) path
-    
-    -- | Export a diagram with GraphViz such that a node or an arrow is in orange if it is the target of the functor.
-    --
-    -- Allows to format the name of the objects and of the morphisms.
-    diagToDot2Format :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                   Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                  (Diagram c1 m1 o1 c2 m2 o2) -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
-    diagToDot2Format f@Diagram{src=s,tgt=t,omap=om,mmap=fm} formatObj formatMorph path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label)), colorNode n],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)), colorEdge label]} (categoryToGraphFormat t formatObj formatMorph)
-                                                   where
-                                                        colorNode n = case () of
-                                                                        _ | countPredN == 0 -> color Black
-                                                                          | countPredN == 1 -> color Orange
-                                                                          | countPredN == 2 -> color Orange1
-                                                                          | countPredN == 3 -> color Orange2
-                                                                          | countPredN == 4 -> color Orange3
-                                                                          | countPredN == 5 -> color Orange4
-                                                                          | otherwise -> color OrangeRed4
-                                                                        
-                                                            where
-                                                                countPredN = Prelude.length [1 | o <- (setToList (ob s)), (objToNode t (om |!| o)) == n]
-                                                        colorEdge e = case () of
-                                                                        _ | countPredE == 0 -> color Black
-                                                                          | countPredE == 1 -> color Orange
-                                                                          | countPredE == 2 -> color Orange1
-                                                                          | countPredE == 3 -> color Orange2
-                                                                          | countPredE == 4 -> color Orange3
-                                                                          | countPredE == 5 -> color Orange4
-                                                                          | otherwise -> color OrangeRed4
-                                                            where
-                                                                countPredE = Prelude.length [1 | m <- (setToList (arrows s)), (pprint (fm |!| m)) == e]
-    
-    -- | Export a diagram as a pdf with GraphViz such that a node or an arrow is in orange if it is the target of the functor.
-    --
-    -- Allows to format the name of the objects and of the morphisms.
-    diagToPdf2Format :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, PrettyPrint m2, PrettyPrint o2) =>
-                 (Diagram c1 m1 o1 c2 m2 o2) -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
-    diagToPdf2Format f formatObj formatMorph path =  dotToPdf (diagToDot2Format f formatObj formatMorph path) path
-    
-   
-    -- __________________________________
-    -- __________________________________
-    --
-    -- Natural transformation representation as a translation in the target category.
-    -- __________________________________
-    -- __________________________________
-    
-    -- | Export a natural transformation with GraphViz such that the source diagram is in green, the target diagram is in blue and the translation is in yellow.
-    natToDot ::   (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1,
-                   Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) =>
-                  (NaturalTransformation c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    natToDot nt path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        s = source nt
-        t = target nt
-        c = components nt
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label)), colorNode n],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)), colorEdge label]} (categoryToGraph (tgt s))
-                                                   where
-                                                        colorNode n = case () of
-                                                                        _ | predNSrc && predNTgt -> color Turquoise
-                                                                          | predNSrc -> color Green
-                                                                          | predNTgt -> color Blue
-                                                                          | otherwise -> color Black      
-                                                            where
-                                                                predNSrc = Set.or [(objToNode (tgt s) ((omap s) |!| o)) == n | o <- (ob (src s))]
-                                                                predNTgt = Set.or [(objToNode (tgt t) ((omap t) |!| o)) == n | o <- (ob (src t))]
-                                                        colorEdge e = case () of
-                                                                        _ | predESrc && predETgt && predENat -> color Beige
-                                                                          | predESrc && predETgt -> color Turquoise
-                                                                          | predESrc && predENat -> color Orange
-                                                                          | predETgt && predENat -> color LightBlue
-                                                                          | predESrc -> color Green
-                                                                          | predETgt -> color Blue
-                                                                          | predENat -> color Yellow
-                                                                          | otherwise -> color Black
-                                                            where
-                                                                predESrc = Set.foldr (||) False [(pprint ((mmap s) |!| m)) == e | m <- (arrows (src s))]
-                                                                predETgt = Set.foldr (||) False [(pprint ((mmap t) |!| m)) == e | m <- (arrows (src t))]
-                                                                predENat = Set.foldr (||) False [(pprint (c |!| o)) == e | o <- (ob (src s))]
-              
-    -- | Export a natural transformation as pdf with GraphViz such that the source diagram is in green, the target diagram is in blue and the translation is in yellow.
-    natToPdf :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) =>
-                 (NaturalTransformation c1 m1 o1 c2 m2 o2) -> String -> IO ()
-    natToPdf nt path =  dotToPdf (natToDot nt path) path
-    
-    -- | Export a natural transformation with GraphViz such that the source diagram is in green, the target diagram is in blue and the translation is in yellow.
-    --
-    -- Allows to format the name of the objects and of the morphisms.
-    natToDotFormat ::   (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1,
-                   Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) =>
-                  (NaturalTransformation c1 m1 o1 c2 m2 o2) -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
-    natToDotFormat nt formatObj formatMorph path = createAndWriteFile path $ renderDot $ toDot dot_file where
-        s = source nt
-        t = target nt
-        c = components nt
-        dot_file = graphToDot nonClusteredParams { fmtNode= \(n,label)-> [Label (StrLabel (L.pack label)), colorNode n],
-                                                   fmtEdge= \(n1,n2,label)-> [Label (StrLabel (L.pack label)), colorEdge label]} (categoryToGraphFormat (tgt s) formatObj formatMorph)
-                                                   where
-                                                        colorNode n = case () of
-                                                                        _ | predNSrc && predNTgt -> color Turquoise
-                                                                          | predNSrc -> color Green
-                                                                          | predNTgt -> color Blue
-                                                                          | otherwise -> color Black      
-                                                            where
-                                                                predNSrc = Set.or [(objToNode (tgt s) ((omap s) |!| o)) == n | o <- (ob (src s))]
-                                                                predNTgt = Set.or [(objToNode (tgt t) ((omap t) |!| o)) == n | o <- (ob (src t))]
-                                                        colorEdge e = case () of
-                                                                        _ | predESrc && predETgt && predENat -> color Beige
-                                                                          | predESrc && predETgt -> color Turquoise
-                                                                          | predESrc && predENat -> color Orange
-                                                                          | predETgt && predENat -> color LightBlue
-                                                                          | predESrc -> color Green
-                                                                          | predETgt -> color Blue
-                                                                          | predENat -> color Yellow
-                                                                          | otherwise -> color Black
-                                                            where
-                                                                predESrc = Set.foldr (||) False [(pprint ((mmap s) |!| m)) == e | m <- (arrows (src s))]
-                                                                predETgt = Set.foldr (||) False [(pprint ((mmap t) |!| m)) == e | m <- (arrows (src t))]
-                                                                predENat = Set.foldr (||) False [(pprint (c |!| o)) == e | o <- (ob (src s))]
-              
-    -- | Export a natural transformation as pdf with GraphViz such that the source diagram is in green, the target diagram is in blue and the translation is in yellow.
-    --
-    -- Allows to format the name of the objects and of the morphisms.
-    natToPdfFormat :: (Morphism m1 o1, FiniteCategory c1 m1 o1, Eq o1, Eq m1, Eq c1, PrettyPrint m1, PrettyPrint o1,
-                  Morphism m2 o2, FiniteCategory c2 m2 o2, Eq o2, Eq m2, Eq c2, PrettyPrint m2, PrettyPrint o2) =>
-                 (NaturalTransformation c1 m1 o1 c2 m2 o2) -> (o2 -> String) -> (m2 -> String) -> String -> IO ()
-    natToPdfFormat nt formatObj formatMorph path =  dotToPdf (natToDotFormat nt formatObj formatMorph path) path