@@ -5,129 +5,26 @@ Authors: David Wärn
55-/
66import combinatorics.quiver.subquiver
77import combinatorics.quiver.path
8- import data.sum.basic
9-
8+ import combinatorics.quiver.symmetric
109/-!
1110## Weakly connected components
1211
1312> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
1413> https://github.com/leanprover-community/mathlib4/pull/836
1514> Any changes to this file require a corresponding PR to mathlib4.
1615
17- For a quiver `V`, we build a quiver `symmetrify V` by adding a reversal of every edge.
18- Informally, a path in `symmetrify V` corresponds to a 'zigzag' in `V`. This lets us
19- define the type `weakly_connected_component V` as the quotient of `V` by the relation which
20- identifies `a` with `b` if there is a path from `a` to `b` in `symmetrify V`. (These
21- zigzags can be seen as a proof-relevant analogue of `eqv_gen`.)
16+
17+ For a quiver `V`, we define the type `weakly_connected_component V` as the quotient of `V`
18+ by the relation which identifies `a` with `b` if there is a path from `a` to `b` in `symmetrify V`.
19+ (These zigzags can be seen as a proof-relevant analogue of `eqv_gen`.)
2220
2321Strongly connected components have not yet been defined.
2422-/
25- universes v u
23+ universes u
2624
2725namespace quiver
2826
29- /-- A type synonym for the symmetrized quiver (with an arrow both ways for each original arrow).
30- NB: this does not work for `Prop`-valued quivers. It requires `[quiver.{v+1} V]`. -/
31- @[nolint has_nonempty_instance]
32- def symmetrify (V) : Type u := V
33-
34- instance symmetrify_quiver (V : Type u) [quiver V] : quiver (symmetrify V) :=
35- ⟨λ a b : V, (a ⟶ b) ⊕ (b ⟶ a)⟩
36-
37- variables (V : Type u) [quiver.{v+1 } V]
38-
39- /-- A quiver `has_reverse` if we can reverse an arrow `p` from `a` to `b` to get an arrow
40- `p.reverse` from `b` to `a`.-/
41- class has_reverse :=
42- (reverse' : Π {a b : V}, (a ⟶ b) → (b ⟶ a))
43-
44- /-- Reverse the direction of an arrow. -/
45- def reverse {V} [quiver.{v+1 } V] [has_reverse V] {a b : V} : (a ⟶ b) → (b ⟶ a) :=
46- has_reverse.reverse'
47-
48- /-- A quiver `has_involutive_reverse` if reversing twice is the identity.`-/
49- class has_involutive_reverse extends has_reverse V :=
50- (inv' : Π {a b : V} (f : a ⟶ b), reverse (reverse f) = f)
51-
52- @[simp] lemma reverse_reverse {V} [quiver.{v+1 } V] [h : has_involutive_reverse V]
53- {a b : V} (f : a ⟶ b) : reverse (reverse f) = f := by apply h.inv'
54-
55- variables {V}
56-
57- instance : has_reverse (symmetrify V) := ⟨λ a b e, e.swap⟩
58- instance : has_involutive_reverse (symmetrify V) :=
59- { to_has_reverse := ⟨λ a b e, e.swap⟩,
60- inv' := λ a b e, congr_fun sum.swap_swap_eq e }
61-
62-
63- /-- Reverse the direction of a path. -/
64- @[simp] def path.reverse [has_reverse V] {a : V} : Π {b}, path a b → path b a
65- | a path.nil := path.nil
66- | b (path.cons p e) := (reverse e).to_path.comp p.reverse
67-
68- @[simp] lemma path.reverse_to_path [has_reverse V] {a b : V} (f : a ⟶ b) :
69- f.to_path.reverse = (reverse f).to_path := rfl
70-
71- @[simp] lemma path.reverse_comp [has_reverse V] {a b c : V} (p : path a b) (q : path b c) :
72- (p.comp q).reverse = q.reverse.comp p.reverse := by
73- { induction q, { simp, }, { simp [q_ih], }, }
74-
75- @[simp] lemma path.reverse_reverse [h : has_involutive_reverse V] {a b : V} (p : path a b) :
76- p.reverse.reverse = p := by
77- { induction p,
78- { simp, },
79- { simp only [path.reverse, path.reverse_comp, path.reverse_to_path, reverse_reverse, p_ih],
80- refl, }, }
81-
82- /-- The inclusion of a quiver in its symmetrification -/
83- def symmetrify.of : prefunctor V (symmetrify V) :=
84- { obj := id,
85- map := λ X Y f, sum.inl f }
86-
87- /-- Given a quiver `V'` with reversible arrows, a prefunctor to `V'` can be lifted to one from
88- `symmetrify V` to `V'` -/
89- def symmetrify.lift {V' : Type *} [quiver V'] [has_reverse V'] (φ : prefunctor V V') :
90- prefunctor (symmetrify V) V' :=
91- { obj := φ.obj,
92- map := λ X Y f, sum.rec (λ fwd, φ.map fwd) (λ bwd, reverse (φ.map bwd)) f }
93-
94- lemma symmetrify.lift_spec (V' : Type *) [quiver V'] [has_reverse V'] (φ : prefunctor V V') :
95- symmetrify.of.comp (symmetrify.lift φ) = φ :=
96- begin
97- fapply prefunctor.ext,
98- { rintro X, refl, },
99- { rintros X Y f, refl, },
100- end
101-
102- lemma symmetrify.lift_reverse (V' : Type *) [quiver V'] [h : has_involutive_reverse V']
103- (φ : prefunctor V V')
104- {X Y : symmetrify V} (f : X ⟶ Y) :
105- (symmetrify.lift φ).map (quiver.reverse f) = quiver.reverse ((symmetrify.lift φ).map f) :=
106- begin
107- dsimp [symmetrify.lift], cases f,
108- { simp only, refl, },
109- { simp only, rw h.inv', refl, }
110- end
111-
112- /-- `lift φ` is the only prefunctor extending `φ` and preserving reverses. -/
113- lemma symmetrify.lift_unique (V' : Type *) [quiver V'] [has_reverse V']
114- (φ : prefunctor V V')
115- (Φ : prefunctor (symmetrify V) V')
116- (hΦ : symmetrify.of.comp Φ = φ)
117- (hΦinv : ∀ {X Y : V} (f : X ⟶ Y), Φ.map (reverse f) = reverse (Φ.map f)) :
118- Φ = symmetrify.lift φ :=
119- begin
120- subst_vars,
121- fapply prefunctor.ext,
122- { rintro X, refl, },
123- { rintros X Y f,
124- cases f,
125- { refl, },
126- { dsimp [symmetrify.lift,symmetrify.of],
127- convert hΦinv (sum.inl f), }, },
128- end
129-
130- variables (V)
27+ variables (V : Type *) [quiver.{u+1 } V]
13128
13229/-- Two vertices are related in the zigzag setoid if there is a
13330 zigzag of arrows from one to the other. -/
0 commit comments