Quivers #
This module defines quivers. A quiver on a type V of vertices assigns to every
pair a b : V of vertices a type a ⟶ b of arrows from a to b. This
is a very permissive notion of directed graph.
Implementation notes #
Currently quiver is defined with arrow : V → V → Sort v.
This is different from the category theory setup,
where we insist that morphisms live in some Type.
There's some balance here: it's nice to allow Prop to ensure there are no multiple arrows,
but it is also results in error-prone universe signatures when constraints require a Type.
- hom : V → V → Sort ?
A quiver G on a type V of vertices assigns to every pair a b : V of vertices
a type a ⟶ b of arrows from a to b.
For graphs with no repeated edges, one can use quiver.{0} V, which ensures
a ⟶ b : Prop. For multigraphs, one can use quiver.{v+1} V, which ensures
a ⟶ b : Type v.
Because category will later extend this class, we call the field hom.
Except when constructing instances, you should rarely see this, and use the ⟶ notation instead.
A morphism of quivers. As we will later have categorical functors extend this structure,
we call it a prefunctor.
The identity morphism between quivers.
Equations
- prefunctor.inhabited V = {default := prefunctor.id V _inst_1}
Composition of morphisms between quivers.
A wide subquiver H of G picks out a set H a b of arrows from a to b
for every pair of vertices a b.
NB: this does not work for Prop-valued quivers. It requires G : quiver.{v+1} V.
Equations
- wide_subquiver V = Π (a b : V), set (a ⟶ b)
A type synonym for V, when thought of as a quiver having only the arrows from
some wide_subquiver.
Equations
- wide_subquiver.to_Type V H = V
Equations
- wide_subquiver_has_coe_to_sort = {S := Type u, coe := λ (H : wide_subquiver V), wide_subquiver.to_Type V H}
Equations
- quiver.empty_quiver V = {hom := λ (a b : quiver.empty V), pempty}
Equations
- quiver.wide_subquiver.has_bot = {bot := λ (a b : V), ∅}
Equations
- quiver.wide_subquiver.has_top = {top := λ (a b : V), set.univ}
Equations
Vᵒᵖ reverses the direction of all arrows of V.
Equations
- quiver.opposite = {hom := λ (a b : Vᵒᵖ), opposite.unop b ⟶ opposite.unop a}
The opposite of an arrow in V.
Given an arrow in Vᵒᵖ, we can take the "unopposite" back in V.
A type synonym for the symmetrized quiver (with an arrow both ways for each original arrow).
NB: this does not work for Prop-valued quivers. It requires [quiver.{v+1} V].
Equations
- quiver.symmetrify V = V
A wide subquiver H of G.symmetrify determines a wide subquiver of G, containing an
an arrow e if either e or its reversal is in H.
Equations
- quiver.wide_subquiver_symmetrify = λ (H : wide_subquiver (quiver.symmetrify V)) (a b : V), {e : a ⟶ b | sum.inl e ∈ H a b ∨ sum.inr e ∈ H b a}
A wide subquiver of G can equivalently be viewed as a total set of arrows.
- nil : Π {V : Type u} [_inst_1 : quiver V] (a : V), quiver.path a a
- cons : Π {V : Type u} [_inst_1 : quiver V] (a : V) {b c : V}, quiver.path a b → (b ⟶ c) → quiver.path a c
G.path a b is the type of paths from a to b through the arrows of G.
An arrow viewed as a path of length one.
Equations
- e.to_path = quiver.path.nil.cons e
The length of a path is the number of arrows it uses.
Composition of paths.
The image of a path under a prefunctor.
Equations
- F.map_path (p.cons e) = (F.map_path p).cons (F.map e)
- F.map_path quiver.path.nil = quiver.path.nil
- root : V
- unique_path : Π (b : V), unique (quiver.path quiver.arborescence.root b)
A quiver is an arborescence when there is a unique path from the default vertex to every other vertex.
Instances
The root of an arborescence.
Equations
Equations
An L-labelling of a quiver assigns to every arrow an element of L.
Equations
- quiver.labelling V L = Π ⦃a b : V⦄, (a ⟶ b) → L
To show that [quiver V] is an arborescence with root r : V, it suffices to
- provide a height function
V → ℕsuch that every arrow goes from a lower vertex to a higher vertex, - show that every vertex has at most one arrow to it, and
- show that every vertex other than
rhas an arrow to it.
Equations
- quiver.arborescence_mk r height height_lt unique_arrow root_or_arrow = {root := r, unique_path := λ (b : V), {to_inhabited := classical.inhabited_of_nonempty _, uniq := _}}
- nonempty_path : ∀ (b : V), nonempty (quiver.path r b)
rooted_connected r means that there is a path from r to any other vertex.
Instances
A path from r of minimal length.
Equations
- quiver.shortest_path r b = _.min set.univ _
The length of a path is at least the length of the shortest path
A subquiver which by construction is an arborescence.
Equations
- quiver.geodesic_subtree r = λ (a b : V), {e : a ⟶ b | ∃ (p : quiver.path r a), quiver.shortest_path r b = p.cons e}
Equations
- quiver.geodesic_arborescence r = quiver.arborescence_mk r (λ (a : ↥(quiver.geodesic_subtree r)), (quiver.shortest_path r a).length) _ _ _
A quiver has_reverse if we can reverse an arrow p from a to b to get an arrow
p.reverse from b to a.
Instances
Equations
- quiver.symmetrify.has_reverse V = {reverse' := λ (a b : quiver.symmetrify V) (e : a ⟶ b), sum.swap e}
Reverse the direction of an arrow.
Equations
Reverse the direction of a path.
Equations
- (p.cons e).reverse = (quiver.reverse e).to_path.comp p.reverse
- quiver.path.nil.reverse = quiver.path.nil
Two vertices are related in the zigzag setoid if there is a zigzag of arrows from one to the other.
Equations
- quiver.zigzag_setoid V = {r := λ (a b : V), nonempty (quiver.path a b), iseqv := _}
The type of weakly connected components of a directed graph. Two vertices are in the same weakly connected component if there is a zigzag of arrows from one to the other.
Equations
The weakly connected component corresponding to a vertex.