Skip to content

Instantly share code, notes, and snippets.

@otac0n
Last active August 22, 2022 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otac0n/7d6cec07666815dcb2143a0552af1146 to your computer and use it in GitHub Desktop.
Save otac0n/7d6cec07666815dcb2143a0552af1146 to your computer and use it in GitHub Desktop.
// Note: Much of the descriptions are from https://en.wikipedia.org/
void Main()
{
var sb = new StringBuilder();
sb.AppendLine("digraph classes {");
sb.AppendLine("node [shape=none width=0 height=0 margin=0];");
Func<Type, string> id = null;
id = FuncUtils.Memoize((Type type) =>
{
if (type.IsConstructedGenericType)
{
return id(type.GetGenericTypeDefinition());
}
return type.ToString()
.Replace("_", "__")
.Replace("+", "_p_")
.Replace(",", "_s_")
.Replace("`", "_b_")
.Replace("[", "_o_")
.Replace("]", "_c_");
});
Func<Type, string> name;
name = FuncUtils.Memoize((Type type) =>
{
return type.ToCSharpString(
symbolDisplayFormat: new SymbolDisplayFormat(
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameOnly,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
});
var assembly = Assembly.GetExecutingAssembly();
var types = assembly.GetTypes().Except(new[] { typeof(UserQuery) });
var typeQueue = new Queue<Type>(types.Where(t => t.IsPublic || t.IsNestedPublic));
var visited = new HashSet<string>();
var markdown = new Markdown();
string ToHtml(string md)
{
var doc = new HtmlDocument { OptionWriteEmptyNodes = true };
doc.LoadHtml(markdown.Transform(md));
var root = doc.DocumentNode;
foreach (var p in root.SelectNodes("//p")?.ToArray() ?? Array.Empty<HtmlNode>())
{
foreach (var child in p.ChildNodes.ToList())
{
p.RemoveChild(child);
p.ParentNode.InsertBefore(child, p);
}
if (p.NextSibling != null)
{
var br = doc.CreateElement("br");
p.ParentNode.ReplaceChild(br, p);
}
else
{
p.Remove();
}
}
foreach (var code in root.SelectNodes("//code")?.ToArray() ?? Array.Empty<HtmlNode>())
{
code.Name = "font";
code.SetAttributeValue("face", "Consolas");
}
return root.OuterHtml;
}
while (typeQueue.Count > 0)
{
var type = typeQueue.Dequeue();
if (type.IsConstructedGenericType)
{
var genericType = type.GetGenericTypeDefinition();
typeQueue.Enqueue(genericType);
}
if (!visited.Add(id(type))) continue;
var description = type.GetCustomAttribute<DescriptionAttribute>();
sb.AppendLine($"{id(type)} [label=<<table border=\"1\" cellborder=\"0\" cellspacing=\"0\"><tr><td><font face=\"Segoe UI\">{HttpUtility.HtmlEncode(name(type))}</font></td></tr><tr><td><font face=\"Arial\" point-size=\"8\"> {ToHtml(description?.Description)}</font></td></tr></table>>];");
var baseType = type.BaseType;
if (baseType != null && baseType != typeof(object))
{
typeQueue.Enqueue(baseType);
sb.AppendLine($"{id(type)} -> {id(baseType)};");
}
var declared = type.GetInterfaces().ToSet();
declared.ExceptWith(declared.SelectMany(i => i.GetInterfaces()).ToSet());
foreach (var @interface in declared)
{
typeQueue.Enqueue(@interface);
if (@interface.IsConstructedGenericType && name(@interface) != name(@interface.GetGenericTypeDefinition()))
{
sb.AppendLine($"{id(type)} -> {id(@interface)} [label=\"{name(@interface)}\"];");
}
else
{
sb.AppendLine($"{id(type)} -> {id(@interface)};");
}
}
}
sb.AppendLine("}");
GraphvizUtils.Render(sb.ToString()).Dump();
}
[Description("A `RiemannianManifold` with additional structure provided by the Euclidian metric.")]
public interface EuclidianSpace : PseudoEuclidianSpace, RiemannianManifold
{
}
[Description("A `RealSpace` with a non-degenerate quadratic form.")]
public interface PseudoEuclidianSpace : RealSpace
{
}
[Description("A coordinate space over the real numbers.")]
public interface RealSpace : DifferentiableManifold
{
}
public interface SphereSpace
{
}
[Description("A `PseudoRiemannianManifold` with a smooth section of the positive-definite quadratic forms on the tangent bundle.")]
public interface RiemannianManifold : PseudoRiemannianManifold
{
}
[Description("A `TopologicalSpace` in which the points form a discontinuous sequence.")]
public interface DiscreteSpace : TopologicalSpace
{
}
[Description("A `LorentzianManifold` with constant zero curvature.")]
public interface MinkowskiSpace : LorentzianManifold
{
}
[Description("A `LorentzianManifold` with constant positive curvature.")]
public interface DeSitterSpace : LorentzianManifold
{
}
[Description("A `LorentzianManifold` with constant negative curvature.")]
public interface AntiDeSitterSpace : LorentzianManifold
{
}
[Description("A `PseudoRiemannianManifold` with structure provided by a Lorentzian metric.")]
public interface LorentzianManifold : PseudoRiemannianManifold
{
}
[Description("A `DifferentiableManifold` with a metric tensor that is everywhere nondegenerate.")]
public interface PseudoRiemannianManifold : DifferentiableManifold
{
}
[Description("A `Manifold` with a globally defined differentialble structure, i.e. one that can be described by a set of charts such that the transition from one chart to another is differentialble.")]
public interface DifferentiableManifold : Manifold
{
}
[Description("A `TopologicalManifold` with some additional structure.")]
public interface Manifold : TopologicalManifold
{
}
[Description("A locally Euclidean `HausdorffSpace`.")]
public interface TopologicalManifold : HausdorffSpace
{
}
[Description("A `TopologicalSpace` where for any two distinct points there exists a neighbourhood of each which is disjoint from the neighbourhood of the other.")]
public interface HausdorffSpace : TopologicalSpace
{
}
[Description("A `Set` of points.")]
public interface TopologicalSpace : Set<Point>
{
}
public interface Set<T>
{
}
public interface Point
{
}
public interface Atlas
{
}
public interface Chart<TPoint> : Homeomorphism<TPoint>
where TPoint : Point
{
}
public interface Map<in TFrom, out TTo>
{
}
public interface Diffeomorphism<TSpace> : Isomorphism<TSpace>
where TSpace : DifferentiableManifold
{
}
[Description("Homeomorphisms are the isomorphisms in the category of topological spaces.")]
public interface Homeomorphism<TPoint> : Isomorphism<TPoint>
where TPoint : Point
{
}
public interface Bijection<T1, T2> : Injection<T1, T2>, Surjection<T1, T2> /*, Map<T2, T1>*/
{
Bijection<T2, T1> Inverse { get; }
}
public interface Injection<T1, T2> : Map<T1, T2>
{
}
public interface Surjection<T1, T2> : Map<T1, T2>
{
}
public interface Function<in TFrom, out TTo> : Map<TFrom, TTo>
where TFrom : INumber<TFrom>, INumber<TTo>
where TTo : INumber<TTo>, INumber<TFrom>
{
}
[Description("An isometry is an `Isomorphism` of metric spaces.")]
public interface Isometry<T> : Isomorphism<T>
// TODO: "Metric Spaces"
{
}
[Description("A permutation is an `Automorphism` of a set.")]
public interface Permutation<T> : Automorphism<T>
// TODO: "of a set"
{
}
[Description("An automorphism is an `Isomorphism` between a mathematical object and itself that preserves all of its structure.")]
public interface Automorphism<T> : Isomorphism<T>
{
}
[Description("A homography is an `Isomorphism` of projective spaces.")]
public interface Homography<T> : Isomorphism<T>
// TODO: "of projective spaces"
{
}
[Description("An isomorphism is a mapping between two structures of the same type that can be reversed by an inverse mapping.")]
public interface Isomorphism<T> : Morphism<T>, Bijection<T, T>
{
}
[Description("A structure-preserving `Map` between two algebraic structures of the same type.")]
public interface Homomorphism<T> : Morphism<T>
{
}
[Description("A structure-preserving `Map` between two mathematical structures of the same type.")]
public interface Morphism<T> : Map<T, T>
{
}
// TODO: A diffeomorphism is an isomorphism of spaces equipped with a differential structure, typically differentiable manifolds.
// TODO: A metric space is a set together with a notion of distance between its elements, usually called points. The distance is measured by a function called a metric.
// TODO: Monad
// TODO: is
// TODO: a
// TODO: Monoid
// TODO: in
// TODO: the
// TODO: Category
// TODO: of
// TODO: Endofunctors
@otac0n
Copy link
Author

otac0n commented Aug 22, 2022

Result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment