Theory Graph_Lemma
theory Graph_Lemma
imports Combinatorics_Words.Submonoids Glued_Codes
begin
chapter ‹Graph Lemma›
text‹The Graph Lemma is an important tool for gaining information about systems of word equations.
It yields an upper bound on the rank of the solution, that is, on the number of factors into all images of unknowns can be factorized.
The most straightforward application is showing that a system of equations admits periodic solutions only, which
in particular holds for any nontrivial equation over two words.
The name refers to a graph whose vertices are the unknowns of the system, and edges connect front letters of the left- and right-
hand sides of equations. The bound mentioned above is then the number of connected components of the graph.
We formalize the algebraic proof from @{cite Berstel1979}. Key ingredients of the proof are in the @{theory "Combinatorics_Words_Graph_Lemma.Glued_Codes"}.›
section ‹Graph lemma›
theorem graph_lemma_last: "𝔅⇩F G = {last (Dec (𝔅⇩F G) g) | g. g ∈ G ∧ g ≠ ε}"
proof
interpret code "𝔅⇩F G"
using free_basis_code.
show "𝔅⇩F G ⊆ {last (Dec 𝔅⇩F G g) |g. g ∈ G ∧ g ≠ ε}"
proof (rule ccontr)
assume "¬ 𝔅⇩F G ⊆ {last (Dec 𝔅⇩F G g) |g. g ∈ G ∧ g ≠ ε}"
then obtain w
where "w ∈ 𝔅⇩F G"
and hd_dec_neq: "⋀g. g ∈ G ⟹ g ≠ ε ⟹ last (Dec (𝔅⇩F G) g) ≠ w"
by blast
have "G ⊆ ⟨glued_gens w (𝔅⇩F G)⟩"
by (blast intro!: gen_in_free_hull hd_dec_neq del: notI)
then have "⟨𝔅⇩F G⟩ ⊆ ⟨glued_gens w (𝔅⇩F G)⟩"
unfolding basis_gen_hull_free
by (intro code.free_hull_min glued_gens_code ‹w ∈ 𝔅⇩F G›)
then show False
using ‹w ∈ 𝔅⇩F G› glued_not_in_glued_hull by blast
qed
show "{last (Dec 𝔅⇩F G g) |g. g ∈ G ∧ g ≠ ε} ⊆ 𝔅⇩F G"
by (auto intro!: dec_in_lists lists_hd_in_set[reversed] gen_in_free_hull del: notI)
qed
theorem graph_lemma: "𝔅⇩F G = {hd (Dec (𝔅⇩F G) g) | g. g ∈ G ∧ g ≠ ε}"
proof -
have *: "rev u = last (Dec rev ` (𝔅⇩F G) (rev g)) ∧ g ∈ G ∧ g ≠ ε
⟷ u = hd (Dec (𝔅⇩F G) g) ∧ g ∈ G ∧ g ≠ ε" for u g
by (cases "g ∈ G ∧ g ≠ ε") (simp add: gen_in_free_hull last_rev hd_map code.dec_rev, blast)
show ?thesis
using graph_lemma_last[reversed, of G] unfolding *.
qed
section ‹Binary code›
text ‹We illustrate the use of the Graph Lemma in an alternative proof of the fact that two non-commuting words form a code.
See also @{thm no_comm_bin_code [no_vars]} in @{theory "Combinatorics_Words.CoWBasic"}.
First, we prove a lemma which is the core of the alternative proof.›
lemma non_comm_hds_neq: assumes "u ⋅ v ≠ v ⋅ u" shows "hd (Dec 𝔅⇩F {u,v} u) ≠ hd (Dec 𝔅⇩F {u,v} v)"
using assms proof (rule contrapos_nn)
assume hds_eq: "hd (Dec 𝔅⇩F {u,v} u) = hd (Dec 𝔅⇩F {u,v} v)"
have **: "𝔅⇩F {u,v} = {hd (Dec 𝔅⇩F {u,v} u)}"
using graph_lemma by (rule trans) (use assms in ‹auto intro: hds_eq[symmetric]›)
show "u ⋅ v = v ⋅ u"
by (intro comm_rootI[of _ "hd (Dec 𝔅⇩F {u,v} u)"] sing_gen)
(simp_all add: **[symmetric] gen_in_free_hull)
qed
theorem assumes "u ⋅ v ≠ v ⋅ u" shows "code {u, v}"
proof
have *: "w ∈ {u, v} ⟹ w ≠ ε" for w
using ‹u ⋅ v ≠ v ⋅ u› by blast
fix xs ys
show "xs ∈ lists {u, v} ⟹ ys ∈ lists {u, v} ⟹ concat xs = concat ys ⟹ xs = ys"
proof (induction xs ys rule: list_induct2')
case (4 x xs y ys)
have **: "hd (Dec 𝔅⇩F {u,v} (concat (z # zs))) = hd (Dec 𝔅⇩F {u,v} z)"
if "z # zs ∈ lists {u, v}" for z zs
using that by (elim listsE) (simp del: insert_iff
add: concat_in_hull' gen_in set_mp[OF hull_sub_free_hull]
free_basis_dec_morph * basis_gen_hull_free)
have "hd (Dec 𝔅⇩F {u,v} x) = hd (Dec 𝔅⇩F {u,v} y)"
using "4.prems" by (simp only: **[symmetric])
then have "x = y"
using "4.prems"(1-2) non_comm_hds_neq[OF ‹u ⋅ v ≠ v ⋅ u›]
by (elim listsE insertE emptyE) simp_all
with 4 show "x # xs = y # ys" by simp
qed (simp_all add: *)
qed
end