/// <summary> /// Gets paths /// </summary> /// <param name="v">Root object</param> /// <param name="ob">Current object</param> private void GetPaths(DigraphVertex v, DigraphVertex ob) { CategoryObjectPair pair = new CategoryObjectPair(v.Object as IAdvancedCategoryObject, ob.Object as IAdvancedCategoryObject); IAdvancedCategoryArrow theArrow = this[pair]; foreach (DigraphEdge edge in ob.OutcomingEdges) { DigraphVertex vo = edge.Target; IAdvancedCategoryArrow ar = edge.Object as IAdvancedCategoryArrow; CategoryObjectPair p = new CategoryObjectPair(v.Object as IAdvancedCategoryObject, ar.Target); IAdvancedCategoryArrow newArrow = ar.Compose(category, theArrow); if (arrows.ContainsKey(p)) { IAdvancedCategoryArrow prev = this[p]; IAdvancedCategoryArrow comp = ar.Compose(category, theArrow); if (!prev.Equals(newArrow)) { throw new CategoryException(CategoryException.NonCommutativePath); } continue; } arrows[p] = newArrow; IList <IAdvancedCategoryArrow> s = sources[p.Source as IAdvancedCategoryObject] as IList <IAdvancedCategoryArrow>; s.Add(newArrow); IList <IAdvancedCategoryArrow> t = targets[p.Target as IAdvancedCategoryObject] as IList <IAdvancedCategoryArrow>; t.Add(newArrow); GetPaths(v, vo); } }
/// <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 IAdvancedCategoryObject GetColim(ICategory category, IList <IAdvancedCategoryArrow> arrows, ref IAdvancedCategoryArrow coequalizer, ref IList <IAdvancedCategoryArrow> objectArrows, ref IList <IAdvancedCategoryArrow> productArrows) { IList <IAdvancedCategoryObject> objects = new List <IAdvancedCategoryObject>(); IList <IAdvancedCategoryObject> sources = new List <IAdvancedCategoryObject>(); IDirectSumCategory direct = category as IDirectSumCategory; ICoequalizerCategory coequ = category as ICoequalizerCategory; foreach (IAdvancedCategoryArrow arrow in arrows) { if (!objects.Contains(arrow.Source as IAdvancedCategoryObject)) { objects.Add(arrow.Source as IAdvancedCategoryObject); } if (!objects.Contains(arrow.Target as IAdvancedCategoryObject)) { objects.Add(arrow.Source as IAdvancedCategoryObject); } sources.Add(arrow.Source as IAdvancedCategoryObject); } IList <IAdvancedCategoryArrow> productSourceArrows = new List <IAdvancedCategoryArrow>(); productArrows = new List <IAdvancedCategoryArrow>(); IAdvancedCategoryObject product = direct.GetDirectSum(objects, productArrows); IAdvancedCategoryObject productSource = direct.GetDirectSum(sources, productSourceArrows); IList <IAdvancedCategoryArrow> coequList = new List <IAdvancedCategoryArrow>(); IList <IAdvancedCategoryArrow> arrList = new List <IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow arr in productArrows) { IAdvancedCategoryObject target = arr.Target as IAdvancedCategoryObject; foreach (IAdvancedCategoryObject t in sources) { if (t == target) { arrList.Add(arr); } } } IAdvancedCategoryArrow first = direct.GetArrowFromDirectSum(product, productSource, arrList); foreach (IAdvancedCategoryArrow arr in arrows) { int num = objects.IndexOf(arr.Target as IAdvancedCategoryObject); IAdvancedCategoryArrow pr = productArrows[num] as IAdvancedCategoryArrow; IAdvancedCategoryArrow eq = pr.Compose(category, arr); coequList.Add(eq); } IAdvancedCategoryArrow second = direct.GetArrowFromDirectSum(product, productSource, coequList); coequalizer = coequ.GetCoequalizer(first, second); objectArrows = new List <IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow arrow in productArrows) { IAdvancedCategoryArrow arr = coequalizer.Compose(category, arrow); objectArrows.Add(arr); } return(coequalizer.Target as IAdvancedCategoryObject); }
/// <summary> /// Calculates an arrow /// </summary> /// <param name="source">The source of the source arrow</param> /// <param name="target">The target of the source arrow</param> /// <param name="arrow">The source arrow</param> /// <returns>The target arrow</returns> public IAdvancedCategoryArrow CalculateArrow(IAdvancedCategoryObject source, IAdvancedCategoryObject target, IAdvancedCategoryArrow arrow) { IAdvancedCategoryObject s = next.CalculateObject(arrow.Source as IAdvancedCategoryObject); IAdvancedCategoryObject t = next.CalculateObject(arrow.Target as IAdvancedCategoryObject); IAdvancedCategoryArrow n = next.CalculateArrow(s, t, arrow); IAdvancedCategoryArrow ar = first.CalculateArrow(source, target, n); return(ar); }
/// <summary> /// Composition with identical morphism /// </summary> /// <param name="first">First morphism</param> /// <param name="second">Second morphism</param> /// <returns>The composition</returns> static public IAdvancedCategoryArrow CompositionWithId(IAdvancedCategoryArrow first, IAdvancedCategoryArrow second) { if (first == (first.Target as IAdvancedCategoryObject).Id) { return(second); } if (second == (second.Source as IAdvancedCategoryObject).Id) { return(first); } return(null); }
/// <summary> /// Composition of path arrows /// </summary> /// <param name="category">Category of arrows</param> /// <param name="path">The path</param> /// <returns>The composition</returns> static public IAdvancedCategoryArrow Composition(ICategory category, DigraphPath path) { IArrowLabel label = path[0].Object as IArrowLabel; IAdvancedCategoryArrow arrow = label.Arrow as IAdvancedCategoryArrow; for (int i = 1; i < path.Count; i++) { label = path[i].Object as IArrowLabel; arrow = (label.Arrow as IAdvancedCategoryArrow).Compose(category, arrow); } return(arrow); }
/// <summary> /// Gets arrow of this path /// </summary> /// <param name="category">Arrow category</param> /// <returns>The arrow</returns> public ICategoryArrow GetArrow(ICategory category) { int n = Count; IAdvancedCategoryArrow arrow = this[n - 1].Object as IAdvancedCategoryArrow; for (int i = n - 2; i >= 0; i++) { IAdvancedCategoryArrow a = this[i].Object as IAdvancedCategoryArrow; arrow = a.Compose(category, arrow); } return(arrow); }
IAdvancedCategoryArrow IFunctor.CalculateArrow(IAdvancedCategoryArrow arrow) { Func <IFunctor, IAdvancedCategoryArrow> func = (IFunctor f) => { if ((f as IFunctorAcceptor).Accept(arrow)) { return(f.CalculateArrow(arrow)); } return(null); }; return(GetObject <IAdvancedCategoryArrow>(func)); }
/// <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 IAdvancedCategoryArrow GetArrowFromCoequalizer(IAdvancedCategoryArrow coequalizer, IAdvancedCategoryArrow arrow) { IAdvancedCategoryObject s = arrow.Target as IAdvancedCategoryObject; IAdvancedCategoryObject t = coequalizer.Source as IAdvancedCategoryObject; IAdvancedCategoryArrow[,] arrows = new IAdvancedCategoryArrow[1, 3]; arrows[0, 0] = arrow; arrows[0, 1] = coequalizer; arrows[0, 2] = (arrow.Source as IAdvancedCategoryObject).Id; IDiagramRestoredObject r = s as IDiagramRestoredObject; FindResults res; return(r.RestoreArrow(s, arrows, out res)); }
/// <summary> /// Composition with identical arrow /// </summary> /// <param name="first">First arrow</param> /// <param name="next">Next arrow</param> /// <returns>Composition if one arrow is identical and null otherwise</returns> public static IAdvancedCategoryArrow IdenticalComposition(this IAdvancedCategoryArrow first, IAdvancedCategoryArrow next) { IAdvancedCategoryArrow[] arr = new IAdvancedCategoryArrow[] { first, next }; for (int i = 0; i < arr.Length; i++) { IAdvancedCategoryArrow a = arr[i]; if (!a.HasAttribute <IdenticalAtrribute>()) { continue; } return(arr[1 - i]); } return(null); }
/// <summary> /// Constructor /// </summary> /// <param name="graph">Graph</param> /// <param name="category">Category</param> public CategoryDiagram(Digraph graph, ICategory category) { this.graph = graph; this.category = category; for (int i = 0; i < graph.Count; i++) { IAdvancedCategoryObject o = graph[i].Object as IAdvancedCategoryObject; CategoryObjectPair idPair = new CategoryObjectPair(o, o); IAdvancedCategoryArrow id = o.Id; arrows[idPair] = id; objects.Add(o); IList <IAdvancedCategoryArrow> s = new List <IAdvancedCategoryArrow>(); s.Add(id); sources[o] = s; IList <IAdvancedCategoryArrow> t = new List <IAdvancedCategoryArrow>(); t.Add(id); targets[o] = t; } for (int i = 0; i < graph.Count; i++) { DigraphVertex o = graph[i]; GetPaths(o, o); } }
/// <summary> /// Calculates arrow /// </summary> /// <param name="arrow">The source arrow</param> /// <returns>The target arrow</returns> public IAdvancedCategoryArrow CalculateArrow(IAdvancedCategoryArrow arrow) { return(first.CalculateArrow(next.CalculateArrow(arrow))); }
IAdvancedCategoryArrow IBifunctor.CalculateArrow(IAdvancedCategoryArrow arrow1, IAdvancedCategoryArrow arrow2) { return(null); }
/// <summary> /// Creates limit /// </summary> private void CreateColim() { if (!(category is IDirectSumCategory)) { throw new CategoryException(CategoryException.DirectSumNotSupported); } if (!(category is IEqualizerCategory)) { throw new CategoryException(CategoryException.CoequalizerNotSupported); } IDirectSumCategory sumCategory = category as IDirectSumCategory; IList <IAdvancedCategoryArrow> firstArrows = new List <IAdvancedCategoryArrow>(); IAdvancedCategoryObject firstSum = sumCategory.GetDirectSum(objects, firstArrows); IList <IAdvancedCategoryObject> beginObjects = new List <IAdvancedCategoryObject>(); foreach (CategoryObjectPair o in arrows.Keys) { IAdvancedCategoryArrow a = arrows[o]; beginObjects.Add(a.Source as IAdvancedCategoryObject); } IList <IAdvancedCategoryArrow> secondArrows = new List <IAdvancedCategoryArrow>(); IAdvancedCategoryObject secondSum = sumCategory.GetDirectSum(beginObjects, secondArrows); colimIdArrows = new List <IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow sar in secondArrows) { IAdvancedCategoryObject s = sar.Source as IAdvancedCategoryObject; foreach (IAdvancedCategoryArrow proj in firstArrows) { if (proj.Source == s) { colimIdArrows.Add(proj); break; } } } colimIdArrow = sumCategory.GetArrowFromDirectSum(firstSum, secondSum, colimIdArrows); colimFuncArrows = new List <IAdvancedCategoryArrow>(); foreach (CategoryObjectPair o in arrows.Keys) { IAdvancedCategoryArrow sar = this[o]; foreach (IAdvancedCategoryArrow proj in firstArrows) { if (proj.Source == sar.Target) { IAdvancedCategoryArrow ar = proj.Compose(category, sar); colimFuncArrows.Add(ar); break; } } } colimFuncArrow = sumCategory.GetArrowFromDirectSum(firstSum, secondSum, colimFuncArrows); ICoequalizerCategory coequalizerCategory = category as ICoequalizerCategory; colimArrow = coequalizerCategory.GetCoequalizer(colimIdArrow, colimFuncArrow); colim = colimArrow.Target as IAdvancedCategoryObject; colimArrows = new Dictionary <IAdvancedCategoryObject, IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow proj in firstArrows) { IAdvancedCategoryObject s = proj.Source as IAdvancedCategoryObject; IAdvancedCategoryArrow ar = colimArrow.Compose(category, proj); colimArrows[s] = ar; } }
/// <summary> /// Creates limit /// </summary> private void CreateLim() { if (!(category is IDirectProductCategory)) { throw new CategoryException(CategoryException.DirectProductNotSupported); } if (!(category is IEqualizerCategory)) { throw new CategoryException(CategoryException.EqualizerNotSupported); } IDirectProductCategory productCategory = category as IDirectProductCategory; IList <IAdvancedCategoryArrow> firstArrows = new List <IAdvancedCategoryArrow>(); IAdvancedCategoryObject firstProduct = productCategory.GetDirectProduct(objects, firstArrows); IList <IAdvancedCategoryObject> endObjects = new List <IAdvancedCategoryObject>(); foreach (CategoryObjectPair o in arrows.Keys) { IAdvancedCategoryArrow a = arrows[o] as IAdvancedCategoryArrow; endObjects.Add(a.Target as IAdvancedCategoryObject); } IList <IAdvancedCategoryArrow> secondArrows = new List <IAdvancedCategoryArrow>(); IAdvancedCategoryObject secondProduct = productCategory.GetDirectProduct(endObjects, secondArrows); limIdArrows = new List <IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow tar in secondArrows) { IAdvancedCategoryObject t = tar.Target as IAdvancedCategoryObject; foreach (IAdvancedCategoryArrow proj in firstArrows) { if (proj.Target == t) { limIdArrows.Add(proj); break; } } } limIdArrow = productCategory.GetArrowToDirectProduct(firstProduct, secondProduct, limIdArrows); limFuncArrows = new List <IAdvancedCategoryArrow>(); foreach (CategoryObjectPair o in arrows.Keys) { IAdvancedCategoryArrow tar = this[o]; foreach (IAdvancedCategoryArrow proj in firstArrows) { if (proj.Target == tar.Source) { IAdvancedCategoryArrow ar = tar.Compose(category, proj); limFuncArrows.Add(ar); break; } } } limFuncArrow = productCategory.GetArrowToDirectProduct(firstProduct, secondProduct, limFuncArrows); IEqualizerCategory equalizerCategory = category as IEqualizerCategory; limArrow = equalizerCategory.GetEqualizer(limIdArrow, limFuncArrow); lim = limArrow.Source as IAdvancedCategoryObject; limArrows = new Dictionary <IAdvancedCategoryObject, IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow proj in firstArrows) { IAdvancedCategoryObject t = proj.Target as IAdvancedCategoryObject; IAdvancedCategoryArrow ar = proj.Compose(category, limArrow); limArrows[t] = ar; } }
/// <summary> /// Gets arrow from colim /// </summary> /// <param name="arrows">Arrows from objects</param> /// <returns>Arrow from colim</returns> public IAdvancedCategoryArrow GetArrowFromColim(IList <IAdvancedCategoryArrow> arrows) { Dictionary <ICategoryObject, ICategoryArrow> dictionary = new Dictionary <ICategoryObject, ICategoryArrow>(); IAdvancedCategoryObject target = null; foreach (IAdvancedCategoryArrow arrow in arrows) { if (target == null) { target = arrow.Target as IAdvancedCategoryObject; } if (target != arrow.Target) { throw new CategoryException(CategoryException.DifferentTargets, new IAdvancedCategoryObject[] { target, arrow.Target as IAdvancedCategoryObject }); } if (!objects.Contains(arrow.Source as IAdvancedCategoryObject)) { throw new CategoryException(ObjectOutOfDiagram, arrow.Source); } if (dictionary.ContainsKey(arrow.Source)) { throw new CategoryException(ExtraArrow, arrow); } dictionary[arrow.Source] = arrow; } foreach (object o in objects) { if (!dictionary.ContainsKey(o as ICategoryObject)) { throw new CategoryException(ArrowsShortage, o); } } foreach (CategoryObjectPair pair in Keys) { IAdvancedCategoryArrow ar = this[pair]; IAdvancedCategoryArrow first = dictionary[pair.Target] as IAdvancedCategoryArrow; IAdvancedCategoryArrow second = dictionary[pair.Source] as IAdvancedCategoryArrow; IAdvancedCategoryArrow composition = first.Compose(category, ar); if (!composition.Equals(second)) { throw new CategoryException(CategoryException.NonCommutativePath, ar); } } Dictionary <int, IAdvancedCategoryArrow> sortedTable = new Dictionary <int, IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow ar in arrows) { int i = objects.IndexOf(ar.Source as IAdvancedCategoryObject); sortedTable[i] = ar; } IList <IAdvancedCategoryArrow> sortedArrows = new List <IAdvancedCategoryArrow>(); for (int i = 0; i < sortedTable.Count; i++) { sortedArrows.Add(sortedTable[i]); } IDirectSumCategory sumCategory = category as IDirectSumCategory; IAdvancedCategoryArrow arrowFromSum = sumCategory.GetArrowFromDirectSum(target, colimIdArrow.Target as IAdvancedCategoryObject, sortedArrows); ICoequalizerCategory coequalizerCategory = category as ICoequalizerCategory; IAdvancedCategoryArrow res = coequalizerCategory.GetArrowFromCoequalizer(colimArrow, arrowFromSum, colimIdArrow, colimFuncArrow); return(res); }
/// <summary> /// Gets arrow to lim /// </summary> /// <param name="arrows">Arrows to objects</param> /// <returns>The arrow to lim</returns> public IAdvancedCategoryArrow GetArrowToLim(List <IAdvancedCategoryArrow> arrows) { Dictionary <ICategoryObject, ICategoryArrow> dictionary = new Dictionary <ICategoryObject, ICategoryArrow>(); IAdvancedCategoryObject source = null; foreach (IAdvancedCategoryArrow arrow in arrows) { if (source == null) { source = arrow.Source as IAdvancedCategoryObject; } if (source != arrow.Source) { throw new CategoryException(CategoryException.DifferentSources, new IAdvancedCategoryObject[] { source, arrow.Source as IAdvancedCategoryObject }); } if (!objects.Contains(arrow.Target as IAdvancedCategoryObject)) { throw new CategoryException(ObjectOutOfDiagram, arrow.Target); } if (dictionary.ContainsKey(arrow.Target)) { throw new CategoryException(ExtraArrow, arrow); } dictionary[arrow.Target] = arrow; } foreach (object o in objects) { if (!dictionary.ContainsKey(o as ICategoryObject)) { throw new CategoryException(ArrowsShortage, o); } } foreach (CategoryObjectPair pair in Keys) { IAdvancedCategoryArrow ar = this[pair]; IAdvancedCategoryArrow first = dictionary[pair.Source] as IAdvancedCategoryArrow; IAdvancedCategoryArrow second = dictionary[pair.Target] as IAdvancedCategoryArrow; IAdvancedCategoryArrow composition = ar.Compose(category, first); if (!composition.Equals(second)) { throw new CategoryException(CategoryException.NonCommutativePath, ar); } } Dictionary <int, IAdvancedCategoryArrow> sortedTable = new Dictionary <int, IAdvancedCategoryArrow>(); foreach (IAdvancedCategoryArrow ar in arrows) { int i = objects.IndexOf(ar.Target as IAdvancedCategoryObject); sortedTable[i] = ar; } IList <IAdvancedCategoryArrow> sortedArrows = new List <IAdvancedCategoryArrow>(); for (int i = 0; i < sortedTable.Count; i++) { sortedArrows.Add(sortedTable[i]); } IDirectProductCategory productCategory = category as IDirectProductCategory; IAdvancedCategoryArrow arrowToProduct = productCategory.GetArrowToDirectProduct(source, limIdArrow.Source as IAdvancedCategoryObject, sortedArrows); IEqualizerCategory equalizerCategory = category as IEqualizerCategory; IAdvancedCategoryArrow res = equalizerCategory.GetArrowToEqualizer(limArrow, arrowToProduct, limIdArrow, limFuncArrow); return(res); }
/// <summary> /// Composes this arrow "f" with next arrow "g" /// </summary> /// <param name="category"> The category of arrow</param> /// <param name="next"> The next arrow "g" </param> /// <returns>Composition "fg" </returns> public IAdvancedCategoryArrow Compose(ICategory category, IAdvancedCategoryArrow next) { IFunctor f = next as IFunctor; return(new FunctorComposition(this, f)); }
IAdvancedCategoryArrow IBifunctor.CalculateArrow(IAdvancedCategoryObject source, IAdvancedCategoryObject target, IAdvancedCategoryArrow arrow1, IAdvancedCategoryArrow arrow2) { throw new Exception("The method or operation is not implemented."); }
IAdvancedCategoryArrow IAdvancedCategoryArrow.Compose(ICategory category, IAdvancedCategoryArrow next) { throw new Exception("The method or operation is not implemented."); }
/// <summary> /// Composes this arrow "f" with next arrow "g" /// </summary> /// <param name="category"> The category of arrow</param> /// <param name="next"> The next arrow "g" </param> /// <returns>Composition "fg" </returns> public abstract IAdvancedCategoryArrow Compose(ICategory category, IAdvancedCategoryArrow next);