diff --git a/metadata/entries/Undirected_Graph_Theory.toml b/metadata/entries/Undirected_Graph_Theory.toml
--- a/metadata/entries/Undirected_Graph_Theory.toml
+++ b/metadata/entries/Undirected_Graph_Theory.toml
@@ -1,44 +1,45 @@
title = "Undirected Graph Theory"
date = 2022-09-29
topics = [
"Mathematics/Graph theory",
]
abstract = """
This entry presents a general library for undirected graph theory -
enabling reasoning on simple graphs and undirected graphs with loops.
It primarily is inspired by Noschinski's basic ugraph definition
in the Girth Chromatic Entry,
however generalises it in a number of
ways and significantly expands on the range of basic graph theory
definitions formalised. Notably, this library removes the constraint
of vertices being a type synonym with the natural numbers which causes
issues in more complex mathematical reasoning using graphs, such as
the Balog Szemeredi Gowers theorem which this library is used for.
Secondly this library also presents a locale-centric approach,
enabling more concise, flexible, and reusable modelling of different
types of graphs. Using this approach enables easy links to be made
with more expansive formalisations of other combinatorial structures,
such as incidence systems, as well as various types of formal
representations of graphs. Further inspiration is also taken from
Noschinski's Directed Graph library for some proofs and
definitions on walks, paths and cycles, however these are much
simplified using the set based representation of graphs, and also
extended on in this formalisation."""
license = "bsd"
note = ""
[authors]
[authors.edmonds]
homepage = "edmonds_homepage"
[contributors]
[notify]
edmonds = "edmonds_email"
[history]
+2023-08-18 = "Renamed incident to vincident (vertex incident) and order to gorder to enable inheritance from design theory library"
[extra]
[related]
diff --git a/thys/Undirected_Graph_Theory/Graph_Theory_Relations.thy b/thys/Undirected_Graph_Theory/Graph_Theory_Relations.thy
--- a/thys/Undirected_Graph_Theory/Graph_Theory_Relations.thy
+++ b/thys/Undirected_Graph_Theory/Graph_Theory_Relations.thy
@@ -1,246 +1,246 @@
section \Graph Theory Inheritance\
text \ This theory aims to demonstrate the use of locales to transfer theorems between different
graph/combinatorial structure representations \
theory Graph_Theory_Relations imports Undirected_Graph_Basics Bipartite_Graphs
"Design_Theory.Block_Designs" "Design_Theory.Group_Divisible_Designs"
begin
subsection \ Design Inheritance \
text \A graph is a type of incidence system, and more specifically a type of combinatorial design.
This section demonstrates the correspondence between designs and graphs \
sublocale graph_system \ inc: incidence_system V "mset_set E"
by (unfold_locales) (metis wellformed elem_mset_set ex_in_conv infinite_set_mset_mset_set)
sublocale fin_graph_system \ finc: finite_incidence_system V "mset_set E"
using finV by unfold_locales
sublocale fin_ulgraph \ d: design V "mset_set E"
using edge_size empty_not_edge fin_edges by unfold_locales auto
sublocale fin_ulgraph \ d: simple_design V "mset_set E"
by unfold_locales (simp add: fin_edges)
locale graph_has_edges = graph_system +
assumes edges_nempty: "E \ {}"
locale fin_sgraph_wedges = fin_sgraph + graph_has_edges
text \The simple graph definition of degree overlaps with the definition of a point replication number \
sublocale fin_sgraph_wedges \ bd: block_design V "mset_set E" 2
rewrites "point_replication_number (mset_set E) x = degree x"
and "points_index (mset_set E) vs = degree_set vs"
proof (unfold_locales)
show "inc.\ \ 0" by (simp add: edges_nempty fin_edges)
show "\bl. bl \# mset_set E \ card bl = 2" by (simp add: fin_edges two_edges)
show "mset_set E index vs = degree_set vs"
unfolding degree_set_def points_index_def by (simp add: fin_edges)
next
have "size {#b \# (mset_set E) . x \ b#} = card (incident_edges x)"
- unfolding incident_edges_def incident_def
+ unfolding incident_edges_def vincident_def
by (simp add: fin_edges)
then show "mset_set E rep x = degree x" using alt_degree_def point_replication_number_def
by metis
qed
locale fin_bipartite_graph_wedges = fin_bipartite_graph + fin_sgraph_wedges
sublocale fin_bipartite_graph_wedges \ group_design V "mset_set E" "{X, Y}"
by unfold_locales (simp_all add: partition ne)
subsection \Adjacency Relation Definition \
text \ Another common formal representation of graphs is as a vertex set and an adjacency relation
This is a useful representation in some contexts - we use locales to enable the transfer of
results between the two representations, specifically the mutual sublocales approach \
locale graph_rel =
fixes vertices :: "'a set" ("V")
fixes adj_rel :: "'a rel"
assumes wf: "\ u v. (u, v) \ adj_rel \ u \ V \ v \ V"
begin
abbreviation "adj u v \ (u, v) \ adj_rel"
lemma wf_alt: "adj u v \ (u, v) \ V \ V"
using wf by blast
end
locale ulgraph_rel = graph_rel +
assumes sym_adj: "sym adj_rel"
begin
text \ This definition makes sense in the context of an undirected graph \
definition edge_set:: "'a edge set" where
"edge_set \ {{u, v} | u v. adj u v}"
lemma obtain_edge_pair_adj:
assumes "e \ edge_set"
obtains u v where "e = {u, v}" and "adj u v"
using assms edge_set_def mem_Collect_eq
by fastforce
lemma adj_to_edge_set_card:
assumes "e \ edge_set"
shows "card e = 1 \ card e = 2"
proof -
obtain u v where "e = {u, v}" and "adj u v" using obtain_edge_pair_adj assms by blast
then show ?thesis by (cases "u = v", simp_all)
qed
lemma adj_to_edge_set_card_lim:
assumes "e \ edge_set"
shows "card e > 0 \ card e \ 2"
proof -
obtain u v where "e = {u, v}" and "adj u v" using obtain_edge_pair_adj assms by blast
then show ?thesis by (cases "u = v", simp_all)
qed
lemma edge_set_wf: "e \ edge_set \ e \ V"
using obtain_edge_pair_adj wf by (metis insert_iff singletonD subsetI)
lemma is_graph_system: "graph_system V edge_set"
by (unfold_locales) (simp add: edge_set_wf)
lemma sym_alt: "adj u v \ adj v u"
using sym_adj by (meson symE)
lemma is_ulgraph: "ulgraph V edge_set"
using ulgraph_axioms_def is_graph_system adj_to_edge_set_card_lim
by (intro_locales) auto
end
context ulgraph
begin
definition adj_relation :: "'a rel" where
"adj_relation \ {(u, v) | u v . vert_adj u v}"
lemma adj_relation_wf: "(u, v) \ adj_relation \ {u, v} \ V"
unfolding adj_relation_def using vert_adj_imp_inV by auto
lemma adj_relation_sym: "sym adj_relation"
unfolding adj_relation_def sym_def using vert_adj_sym by auto
lemma is_ulgraph_rel: "ulgraph_rel V adj_relation"
using adj_relation_wf adj_relation_sym by (unfold_locales) auto
text \ Temporary interpretation - mutual sublocale setup \
interpretation ulgraph_rel V adj_relation by (rule is_ulgraph_rel)
lemma vert_adj_rel_iff:
assumes "u \ V" "v \ V"
shows "vert_adj u v \ adj u v"
using adj_relation_def by auto
lemma edges_rel_is: "E = edge_set"
proof -
have "E = {{u, v} | u v . vert_adj u v}"
proof (intro subset_antisym subsetI)
show "\x. x \ {{u, v} |u v. vert_adj u v} \ x \ E"
using vert_adj_def by fastforce
next
fix x assume "x \ E"
then have "x \ V" and "card x > 0" and "card x \ 2" using wellformed edge_size by auto
then obtain u v where "x = {u, v}" and "{u, v} \ E"
by (metis \x \ E\ alt_edge_size card_1_singletonE card_2_iff insert_absorb2)
then show "x \ {{u, v} |u v. vert_adj u v}" unfolding vert_adj_def by blast
qed
then have "E = {{u, v} | u v . adj u v}" using vert_adj_rel_iff Collect_cong
by (smt (verit) local.wf vert_adj_imp_inV)
thus ?thesis using edge_set_def by simp
qed
end
context ulgraph_rel
begin
text \ Temporary interpretation - mutual sublocale setup \
interpretation ulgraph V edge_set by (rule is_ulgraph)
lemma rel_vert_adj_iff: "vert_adj u v \ adj u v"
proof (intro iffI)
assume "vert_adj u v"
then have "{u, v} \ edge_set" by (simp add: vert_adj_def)
then show "adj u v" using edge_set_def
by (metis (no_types, lifting) doubleton_eq_iff obtain_edge_pair_adj sym_alt)
next
assume "adj u v"
then have "{u, v} \ edge_set" using edge_set_def by auto
then show "vert_adj u v" by (simp add: vert_adj_def)
qed
lemma rel_item_is: "(u, v) \ adj_rel \ (u, v) \ adj_relation"
unfolding adj_relation_def using rel_vert_adj_iff by auto
lemma rel_edges_is: "adj_rel = adj_relation"
using rel_item_is by auto
end
sublocale ulgraph_rel \ ulgraph "V" "edge_set"
rewrites "ulgraph.adj_relation edge_set = adj_rel"
using local.is_ulgraph rel_edges_is by simp_all
sublocale ulgraph \ ulgraph_rel "V" "adj_relation"
rewrites "ulgraph_rel.edge_set adj_relation = E"
using is_ulgraph_rel edges_rel_is by simp_all
locale sgraph_rel = ulgraph_rel +
assumes irrefl_adj: "irrefl adj_rel"
begin
lemma irrefl_alt: "adj u v \ u \ v"
using irrefl_adj irrefl_def by fastforce
lemma edge_is_card2:
assumes "e \ edge_set"
shows "card e = 2"
proof -
obtain u v where eq: "e = {u, v}" and "adj u v" using assms edge_set_def by blast
then have "u \ v" using irrefl_alt by simp
thus ?thesis using eq by simp
qed
lemma is_sgraph: "sgraph V edge_set"
using is_graph_system edge_is_card2 sgraph_axioms_def by (intro_locales) auto
end
context sgraph
begin
lemma is_rel_irrefl_alt:
assumes "(u, v) \ adj_relation"
shows "u \ v"
proof -
have "vert_adj u v" using adj_relation_def assms by blast
then have "{u, v} \ E" using vert_adj_def by simp
then have "card {u, v} = 2" using two_edges by simp
thus ?thesis by auto
qed
lemma is_rel_irrefl: "irrefl adj_relation"
using irrefl_def is_rel_irrefl_alt by auto
lemma is_sgraph_rel: "sgraph_rel V adj_relation"
by (unfold_locales) (simp add: is_rel_irrefl)
end
sublocale sgraph_rel \ sgraph V "edge_set"
rewrites "ulgraph.adj_relation edge_set = adj_rel"
using is_sgraph rel_edges_is by simp_all
sublocale sgraph \ sgraph_rel V "adj_relation"
rewrites "ulgraph_rel.edge_set adj_relation = E"
using is_sgraph_rel edges_rel_is by simp_all
end
\ No newline at end of file
diff --git a/thys/Undirected_Graph_Theory/Undirected_Graph_Basics.thy b/thys/Undirected_Graph_Theory/Undirected_Graph_Basics.thy
--- a/thys/Undirected_Graph_Theory/Undirected_Graph_Basics.thy
+++ b/thys/Undirected_Graph_Theory/Undirected_Graph_Basics.thy
@@ -1,987 +1,987 @@
(* Graph Theory Library Base
Theory: Undirected_Graph_Basics
Author: Chelsea Edmonds
*)
text \ This library aims to present a general theory for undirected graphs. The formalisation
approach models edges as sets with two elements, and is inspired in part by the graph theory
basics defined by Lars Noschinski in \<^cite>\"noschinski_2012"\ which are used in \<^cite>\"edmonds_szemeredis" and "edmonds_roths"\.
Crucially this library makes the definition more flexible by removing the type synonym from vertices
to natural numbers. This is limiting in more advanced mathematical applications, where it is common
for vertices to represent elements of some other set. It additionally extends significantly on basic
graph definitions.
The approach taken in this formalisation is the "locale-centric" approach for modelling different
graph properties, which has been successfully used in other combinatorial structure formalisations. \
section \ Undirected Graph Theory Basics \
text \This first theory focuses on the basics of graph theory (vertices, edges, degree, incidence,
neighbours etc), as well as defining a number of different types of basic graphs.
This theory draws inspiration from \<^cite>\"noschinski_2012" and "edmonds_szemeredis" and "edmonds_roths"\ \
theory Undirected_Graph_Basics imports Main "HOL-Library.Multiset" "HOL-Library.Disjoint_Sets"
"HOL-Library.Extended_Real" "Girth_Chromatic.Girth_Chromatic_Misc"
begin
subsection \ Miscellaneous Extras \
text \ Useful concepts on lists and sets \
lemma distinct_tl_rev:
assumes "hd xs = last xs"
shows "distinct (tl xs) \ distinct (tl (rev xs))"
using assms
proof (induct xs)
case Nil
then show ?case by simp
next
case (Cons a xs)
then show ?case proof (cases "xs = []")
case True
then show ?thesis by simp
next
case False
then have "a = last xs"
using Cons.prems by auto
then obtain xs' where "xs = xs' @ [last xs]"
by (metis False append_butlast_last_id)
then have tleq: "tl (rev xs) = rev (xs')"
by (metis butlast_rev butlast_snoc rev_rev_ident)
have "distinct (tl (a # xs)) \ distinct xs" by simp
also have "... \ distinct (rev xs') \ a \ set (rev xs')"
by (metis False Nil_is_rev_conv \a = last xs\ distinct.simps(2) distinct_rev hd_rev list.exhaust_sel tleq)
finally show "distinct (tl (a # xs)) \ distinct (tl (rev (a # xs)))"
using tleq by (simp add: False)
qed
qed
lemma last_in_list_set: "length xs \ 1 \ last xs \ set (xs)"
using dual_order.strict_trans1 last_in_set by blast
lemma last_in_list_tl_set:
assumes "length xs \ 2"
shows "last xs \ set (tl xs)"
using assms by (induct xs) auto
lemma length_list_decomp_lt: "ys \ [] \ length (xs @zs) < length (xs@ys@zs)"
using length_append by simp
lemma obtains_Max:
assumes "finite A" and "A \ {}"
obtains x where "x \ A" and "Max A = x"
using assms Max_in by blast
lemma obtains_MAX:
assumes "finite A" and "A \ {}"
obtains x where "x \ A" and "Max (f ` A) = f x"
using obtains_Max
by (metis (mono_tags, opaque_lifting) assms(1) assms(2) empty_is_image finite_imageI image_iff)
lemma obtains_Min:
assumes "finite A" and "A \ {}"
obtains x where "x \ A" and "Min A = x"
using assms Min_in by blast
lemma obtains_MIN:
assumes "finite A" and "A \ {}"
obtains x where "x \ A" and "Min (f ` A) = f x"
using obtains_Min assms empty_is_image finite_imageI image_iff
by (metis (mono_tags, opaque_lifting))
subsection \ Initial Set up \
text \For convenience and readability, some functions and type synonyms are defined outside locale context \
fun mk_triangle_set :: "('a \ 'a \ 'a) \ 'a set"
where "mk_triangle_set (x, y, z) = {x,y,z}"
type_synonym 'a edge = "'a set"
(* This is preferably not needed, but may be a helpful abbreviation when working outside a locale context *)
type_synonym 'a pregraph = "('a set) \ ('a edge set)"
abbreviation gverts :: "'a pregraph \ 'a set" where
"gverts H \ fst H"
abbreviation gedges :: "'a pregraph \ 'a edge set" where
"gedges H \ snd H"
fun mk_edge :: "'a \ 'a \ 'a edge" where
"mk_edge (u,v) = {u,v}"
text \All edges is simply the set of subsets of a set S of size 2\
definition "all_edges S \ {e . e \ S \ card e = 2}"
text \ Note, this is a different definition to Noschinski's \<^cite>\"noschinski_2012"\ ugraph which uses
the @{term "mk_edge"} function unnecessarily \
text \ Basic properties of these functions \
lemma all_edges_mono:
"vs \ ws \ all_edges vs \ all_edges ws"
unfolding all_edges_def by auto
lemma all_edges_alt: "all_edges S = {{x, y} | x y . x \ S \ y \ S \ x \ y}"
unfolding all_edges_def
proof (intro subset_antisym subsetI)
fix x assume "x \ {e. e \ S \ card e = 2}"
then obtain u v where "x = {u, v}" and "card {u, v} = 2" and "{u, v} \ S"
by (metis (mono_tags, lifting) card_2_iff mem_Collect_eq)
then show "x \ {{x, y} |x y. x \ S \ y \ S \ x \ y}"
by fastforce
next
show "\x. x \ {{x, y} |x y. x \ S \ y \ S \ x \ y} \ x \ {e. e \ S \ card e = 2}"
by auto
qed
lemma all_edges_alt_pairs: "all_edges S = mk_edge ` {uv \ S \ S. fst uv \ snd uv}"
unfolding all_edges_alt
proof (intro subset_antisym)
have img: "mk_edge ` {uv \ S \ S. fst uv \ snd uv} = {mk_edge (u, v) | u v. (u, v) \ S \ S \ u \v}"
by (smt (z3) Collect_cong fst_conv prod.collapse setcompr_eq_image snd_conv)
then show " mk_edge ` {uv \ S \ S. fst uv \ snd uv} \ {{x, y} |x y. x \ S \ y \ S \ x \ y}"
by auto
show "{{x, y} |x y. x \ S \ y \ S \ x \ y} \ mk_edge ` {uv \ S \ S. fst uv \ snd uv}"
using img by simp
qed
lemma all_edges_subset_Pow: "all_edges A \ Pow A"
by (auto simp: all_edges_def)
lemma all_edges_disjoint: "S \ T = {} \ all_edges S \ all_edges T = {}"
by (auto simp add: all_edges_def disjoint_iff subset_eq)
lemma card_all_edges: "finite A \ card (all_edges A) = card A choose 2"
using all_edges_def by (metis (full_types) n_subsets)
lemma finite_all_edges: "finite S \ finite (all_edges S)"
by (meson all_edges_subset_Pow finite_Pow_iff finite_subset)
lemma in_mk_edge_img: "(a,b) \ A \ (b,a) \ A \ {a,b} \ mk_edge ` A"
by (auto intro: rev_image_eqI)
thm in_mk_edge_img
lemma in_mk_uedge_img_iff: "{a,b} \ mk_edge ` A \ (a,b) \ A \ (b,a) \ A"
by (auto simp: doubleton_eq_iff intro: rev_image_eqI)
lemma inj_on_mk_edge: "X \ Y = {} \ inj_on mk_edge (X \ Y)"
by (auto simp: inj_on_def doubleton_eq_iff)
definition complete_graph :: "'a set \ 'a pregraph" where
"complete_graph S \ (S, all_edges S)"
definition all_edges_loops:: "'a set \ 'a edge set"where
"all_edges_loops S \ all_edges S \ {{v} | v. v \ S}"
lemma all_edges_loops_alt: "all_edges_loops S = {e . e \ S \ (card e = 2 \ card e = 1)}"
proof -
have 1: " {{v} | v. v \ S} = {e . e \ S \ card e = 1}"
by (metis One_nat_def card.empty card_Suc_eq empty_iff empty_subsetI insert_subset is_singleton_altdef is_singleton_the_elem )
have "{e . e \ S \ (card e = 2 \ card e = 1)} = {e . e \ S \ card e = 2} \ {e . e \ S \ card e = 1}"
by auto
then have "{e . e \ S \ (card e = 2 \