Browse Source

DOC: Consistent indentation in vignette about labeled graphs.

pull/579/head
Evan Patterson 3 days ago
parent
commit
8921332989
  1. 120
      docs/literate/graphs/graphs_label.jl

120
docs/literate/graphs/graphs_label.jl

@ -31,12 +31,12 @@ end
# We need to tell Catlab how to convert our `LGraph` type into the normal `Graph` type by taking just the edges and vertices. This could be computed with Functorial Data Migration, but that is left for another sketch.
to_graph(g::LGraph) = begin
h = Graphs.Graph(nparts(g,:V))
for e in edges(g)
add_edge!(h, g[e, :src], g[e,:tgt])
end
return h
h = Graphs.Graph(nparts(g,:V))
for e in edges(g)
add_edge!(h, g[e, :src], g[e,:tgt])
end
return h
end
# Graphviz doesn't automatically know how we want to draw the labels, so we have to explicitly provide code that converts them to colors on the vertices. Note that we aren't calling these colored graphs, because that would imply some connectivity constraints on which vertices are allowed to be colored with the same colors. These labels are arbitrary, but we use color to visually encode them.
GraphvizGraphs.to_graphviz(g::LGraph; kw...) =
@ -57,37 +57,31 @@ draw(G::LGraph) = to_graphviz(G, node_labels=true, edge_labels=true)
# Now we can start making some `LGraph` instances.
G = @acset LGraph begin
V = 4
E = 4
L = 4
src = [1,1,2,3]
tgt = [2,3,4,4]
label = [1,2,3,4]
V = 4
E = 4
L = 4
src = [1,1,2,3]
tgt = [2,3,4,4]
label = [1,2,3,4]
end
draw(G)
# The graph `G` has a 1-1 map between vertices and labels. That isn't necessary.
H = @acset LGraph begin
V = 4
E = 4
L = 3
src = [1,1,2,3]
tgt = [2,3,4,4]
label = [1,2,2,3]
V = 4
E = 4
L = 3
src = [1,1,2,3]
tgt = [2,3,4,4]
label = [1,2,2,3]
end
draw(H)
# We can look at some homomorphisms from G to H by their action on the labels or on the vertices.
homsᵥ(G,H) = map(homomorphisms(G, H)) do α
components(α).V
end
homsₗ(G,H) = map(homomorphisms(G, H)) do α
components(α).L
end
homsᵥ(G,H) = map(α -> α[:V], homomorphisms(G, H))
homsₗ(G,H) = map(α -> α[:L], homomorphisms(G, H))
# αₗ: G→ H
homsₗ(G,H)
@ -100,23 +94,23 @@ homsᵥ(H,G)
# We can build some bigger examples like A.
A = @acset LGraph begin
V = 6
E = 7
L = 3
src = [1,1,2,3,2,5,4]
tgt = [2,3,4,4,5,6,6]
label = [1,2,2,3,2,3]
V = 6
E = 7
L = 3
src = [1,1,2,3,2,5,4]
tgt = [2,3,4,4,5,6,6]
label = [1,2,2,3,2,3]
end
draw(A)
# and B.
B = @acset LGraph begin
V = 6
E = 7
L = 4
src = [1,1,2,3,2,5,4]
tgt = [2,3,4,4,5,6,6]
label = [1,2,4,3,2,3]
V = 6
E = 7
L = 4
src = [1,1,2,3,2,5,4]
tgt = [2,3,4,4,5,6,6]
label = [1,2,4,3,2,3]
end
draw(B)
@ -142,42 +136,44 @@ draw(apex(product(G,G)))
# The graph above looks weirdly disconnected and probably wasn't what you expected to see as the product. When we compose with products, we often want to add the reflexive edges in order to get the expected notion of product.
add_loops!(G::LGraph) = begin
for v in parts(G,:V)
add_edge!(G, v,v)
end
return G
for v in parts(G,:V)
add_edge!(G, v,v)
end
return G
end
add_loops(G::LGraph) = add_loops!(copy(G))
Gᵣ = add_loops(G)
P = apex(product(Gᵣ, G))
draw(apex(product(Gᵣ, G)))
# We can look at the shape of commuting triangle, which is our favorite 3-vertex graph.
T = @acset LGraph begin
V = 3
E = 3
L = 3
src = [1,1,2]
tgt = [2,3,3]
label = [1,2,3]
V = 3
E = 3
L = 3
src = [1,1,2]
tgt = [2,3,3]
label = [1,2,3]
end
Tᵣ = add_loops(T)
draw(Tᵣ)
E = @acset LGraph begin
V = 2
E = 1
L = 2
src = [1]
tgt = [2]
label = [1,2]
V = 2
E = 1
L = 2
src = [1]
tgt = [2]
label = [1,2]
end
Eᵣ = add_loops(E)
draw(Eᵣ)
# We can draw the product of the edge graph and the triangle graph to get the shape of a triangular prism. You can view this product as extruding `Tᵣ` along `Eᵣ`. Catlab provides a `ReflexiveGraph` as a type that handles these self-loops more intelligently than we are here. Graphviz struggles with the layout here because the product graph will include edges that are a step in both directions. This [blog post](https://www.algebraicjulia.org/blog/post/2021/04/cset-graphs-3/) does a good job explaining products in differnt kinds of graph categories.
draw(apex(product(Tᵣ,Eᵣ)))
components(legs(product(Tᵣ, Eᵣ))[1]).V |> collect
legs(product(Tᵣ, Eᵣ))[1][:V] |> collect
# Another limit is the pullback. If you have a cospan, which is a diagram of the shape `X ⟶ A ⟵ Y`, you can pull back one arrow along the other by solving a system of equations.
PB₂₂ = pullback(homomorphisms(Tᵣ,Eᵣ)[2],homomorphisms(Tᵣ,Eᵣ)[2]);
draw(apex(PB₂₂))
@ -194,10 +190,10 @@ homomorphisms(apex(PB₂₂), apex(product(Tᵣ,Tᵣ)), monic=true) |> length
# In order to illustrate this we will be gluing triangles together to make a mesh. We start by defining the point `X`, which is the shape of the boundary along which we will glue and the morphism `ℓ₁`, which is the place in `T` that we consider as the boundary.
X = @acset LGraph begin
E = 0
V = 1
L = 3
label=[2]
E = 0
V = 1
L = 3
label=[2]
end
ℓ₁ = ACSetTransformation(X,T, V=[2],L=1:3)
draw(X)
@ -209,9 +205,9 @@ draw(apex(P))
# Now we want to repeat the gluing process to get a bigger mesh. So we are going to need a bigger interface.
I = @acset LGraph begin
V = 2
L = 3
label = [1,1]
V = 2
L = 3
label = [1,1]
end
draw(I)
@ -221,4 +217,4 @@ is_natural(ll)
lr = ACSetTransformation(I, apex(P), V=[1,4], L =[1,3,2])
is_natural(lr)
P₂ = pushout(ll, lr);
draw(apex(P₂))
draw(apex(P₂))

Loading…
Cancel
Save