using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
namespace CategoryTheory
{
/// <summary>
/// Standard category operations
/// </summary>
public class CategoryOperations
{
/// <summary>
/// Gets arrow to equalizer
/// </summary>
/// <param name="equalizer">The qualizer</param>
/// <param name="arrow">Arrow to object</param>
/// <returns>Arrow to equalizer</returns>
public static ICategoryArrow GetArrowToEqualizer(ICategoryArrow equalizer, ICategoryArrow arrow)
{
ICategoryObject s = arrow.Source;
ICategoryObject t = equalizer.Source;
ICategoryArrow[,] arrows = new ICategoryArrow[1, 3];
arrows[0, 0] = arrow;
arrows[0, 1] = arrow.Source.Id;
arrows[0, 2] = equalizer;
IDiagramRestoredObject r = s as IDiagramRestoredObject;
FindResults res;
return r.RestoreArrow(t, arrows, out res);
}
/// <summary>
/// Gets arrow to coequalizer
/// </summary>
/// <param name="coequalizer">The qualizer</param>
/// <param name="arrow">Arrow to object</param>
/// <returns>Arrow from equalizer</returns>
public static ICategoryArrow GetArrowFromCoequalizer(ICategoryArrow coequalizer, ICategoryArrow arrow)
{
ICategoryObject s = arrow.Target;
ICategoryObject t = coequalizer.Source;
ICategoryArrow[,] arrows = new ICategoryArrow[1, 3];
arrows[0, 0] = arrow;
arrows[0, 1] = coequalizer;
arrows[0, 2] = arrow.Source.Id;
IDiagramRestoredObject r = s as IDiagramRestoredObject;
FindResults res;
return r.RestoreArrow(s, arrows, out res);
}
/// <summary>
/// Gets colimit
/// </summary>
/// <param name="category">The category</param>
/// <param name="arrows">Diagram arrows</param>
/// <param name="coequalizer">Coequalizer</param>
/// <param name="objectArrows">Arrows to colimit</param>
/// <param name="productArrows">Sum arrows</param>
/// <returns>The colimit</returns>
public static ICategoryObject GetColim(ICategory category, ArrayList arrows,
ref ICategoryArrow coequalizer, ref ArrayList objectArrows, ref ArrayList productArrows)
{
ArrayList objects = new ArrayList();
ArrayList sources = new ArrayList();
IDirectSumCategory direct = category as IDirectSumCategory;
ICoequalizerCategory coequ = category as ICoequalizerCategory;
foreach (ICategoryArrow arrow in arrows)
{
if (!objects.Contains(arrow.Source))
{
objects.Add(arrow.Source);
}
if (!objects.Contains(arrow.Target))
{
objects.Add(arrow.Source);
}
sources.Add(arrow.Source);
}
ArrayList productSourceArrows = new ArrayList();
productArrows = new ArrayList();
ICategoryObject product = direct.GetDirectSum(objects, productArrows);
ICategoryObject productSource = direct.GetDirectSum(sources, productSourceArrows);
ArrayList coequList = new ArrayList();
ArrayList arrList = new ArrayList();
foreach (ICategoryArrow arr in productArrows)
{
ICategoryObject target = arr.Target;
foreach (ICategoryObject t in sources)
{
if (t == target)
{
arrList.Add(arr);
}
}
}
ICategoryArrow first = direct.GetArrowFromDirectSum(product, productSource, arrList);
foreach (ICategoryArrow arr in arrows)
{
int num = objects.IndexOf(arr.Target);
ICategoryArrow pr = productArrows[num] as ICategoryArrow;
ICategoryArrow eq = pr.Compose(category, arr);
coequList.Add(eq);
}
ICategoryArrow second = direct.GetArrowFromDirectSum(product, productSource, coequList);
coequalizer = coequ.GetCoequalizer(first, second);
objectArrows = new ArrayList();
foreach (ICategoryArrow arrow in productArrows)
{
ICategoryArrow arr = coequalizer.Compose(category, arrow);
objectArrows.Add(arr);
}
return coequalizer.Target;
}
/// <summary>
/// Composition with identical morphism
/// </summary>
/// <param name="first">First morphism</param>
/// <param name="second">Second morphism</param>
/// <returns>The composition</returns>
static public ICategoryArrow CompositionWithId(ICategoryArrow first, ICategoryArrow second)
{
if (first == first.Target.Id)
{
return second;
}
if (second == second.Source.Id)
{
return first;
}
return null;
}
}
}