Theory Pair_Graph
theory Pair_Graph
imports
Main
Graph_Theory.Rtrancl_On
begin
section ‹A Basic Representation of Diraphs›
type_synonym 'v dgraph = "('v × 'v) set"
definition dVs::"('v × 'v) set ⇒ 'v set" where
"dVs G = ⋃ {{v1,v2} | v1 v2. (v1, v2) ∈ G}"
lemma induct_pcpl:
"⟦P []; ⋀x. P [x]; ⋀x y zs. P zs ⟹ P (x # y # zs)⟧ ⟹ P xs"
by induction_schema (pat_completeness, lexicographic_order)
lemma induct_pcpl_2:
"⟦P []; ⋀x. P [x]; ⋀x y. P [x,y]; ⋀x y z. P [x,y,z]; ⋀w x y z zs. P zs ⟹ P (w # x # y # z # zs)⟧ ⟹ P xs"
by induction_schema (pat_completeness, lexicographic_order)
lemma dVs_empty[simp]: "dVs {} = {}"
by (simp add: dVs_def)
lemma dVs_empty_iff[simp]: "dVs E = {} ⟷ E = {}"
unfolding dVs_def by auto
lemma dVsI[intro]:
assumes "(a, v) ∈ dG" shows "a ∈ dVs dG" and "v ∈ dVs dG"
using assms unfolding dVs_def by auto
lemma dVsI':
assumes "e ∈ dG" shows "fst e ∈ dVs dG" and "snd e ∈ dVs dG"
using assms
by (auto intro: dVsI[of "fst e" "snd e"])
lemma dVs_union_distr[simp]: "dVs (G ∪ H) = dVs G ∪ dVs H"
unfolding dVs_def by blast
lemma dVs_union_big_distr: "dVs (⋃G) = ⋃(dVs ` G)"
apply (induction G rule: infinite_finite_induct)
apply simp_all
by (auto simp add: dVs_def)
lemma dVs_eq: "dVs E = fst ` E ∪ snd ` E"
by (induction E rule: infinite_finite_induct)
(auto simp: dVs_def intro!: image_eqI, blast+)
lemma finite_vertices_iff: "finite (dVs E) ⟷ finite E" (is "?L ⟷ ?R")
proof
show "?R ⟹ ?L"
by (induction E rule: finite_induct)
(auto simp: dVs_eq)
show "?L ⟹ ?R"
proof (rule ccontr)
show "?L ⟹ ¬?R ⟹ False"
unfolding dVs_eq
using finite_subset subset_fst_snd by fastforce
qed
qed
abbreviation reachable1 :: "('v × 'v) set ⇒ 'v ⇒ 'v ⇒ bool" ("_ →⇧+ı _" [100,100] 40) where
"reachable1 E u v ≡ (u,v) ∈ E⇧+"
definition reachable :: "('v × 'v) set ⇒ 'v ⇒ 'v ⇒ bool" ("_ →⇧*ı _" [100,100] 40) where
"reachable E u v = ( (u,v) ∈ rtrancl_on (dVs E) E)"
lemma reachableE[elim?]:
assumes "(u,v) ∈ E"
obtains e where "e ∈ E" "e = (u, v)"
using assms by auto
lemma reachable_refl[intro!, Pure.intro!, simp]: "v ∈ dVs E ⟹ v →⇧*⇘E⇙ v"
unfolding reachable_def by auto
lemma reachable_trans[trans,intro]:
assumes "u →⇧*⇘E⇙ v" "v →⇧*⇘E⇙ w" shows "u →⇧*⇘E⇙ w"
using assms unfolding reachable_def by (rule rtrancl_on_trans)
lemma reachable_edge[dest,intro]: "(u,v) ∈ E ⟹ u →⇧*⇘E⇙ v"
unfolding reachable_def
by (auto intro!: rtrancl_consistent_rtrancl_on)
lemma reachable_induct[consumes 1, case_names base step]:
assumes major: "u →⇧*⇘E⇙ v"
and cases: "⟦u ∈ dVs E⟧ ⟹ P u"
"⋀x y. ⟦u →⇧*⇘E⇙ x; (x,y) ∈ E; P x⟧ ⟹ P y"
shows "P v"
using assms unfolding reachable_def by (rule rtrancl_on_induct)
lemma converse_reachable_induct[consumes 1, case_names base step, induct pred: reachable]:
assumes major: "u →⇧*⇘E⇙ v"
and cases: "v ∈ dVs E ⟹ P v"
"⋀x y. ⟦(x,y) ∈ E; y →⇧*⇘E⇙ v; P y⟧ ⟹ P x"
shows "P u"
using assms unfolding reachable_def by (rule converse_rtrancl_on_induct)
lemma reachable_in_dVs:
assumes "u →⇧*⇘E⇙ v"
shows "u ∈ dVs E" "v ∈ dVs E"
using assms by (induct) (simp_all add: dVsI)
lemma reachable1_in_dVs:
assumes "u →⇧+⇘E⇙ v"
shows "u ∈ dVs E" "v ∈ dVs E"
using assms by (induct) (simp_all add: dVsI)
lemma reachable1_reachable[intro]:
"v →⇧+⇘E⇙ w ⟹ v →⇧*⇘E⇙ w"
unfolding reachable_def
by (auto intro: rtrancl_consistent_rtrancl_on simp: dVsI reachable1_in_dVs)
lemmas reachable1_reachableE[elim] = reachable1_reachable[elim_format]
lemma reachable_neq_reachable1[intro]:
assumes reach: "v →⇧*⇘E⇙ w"
and neq: "v ≠ w"
shows "v →⇧+⇘E⇙ w"
using assms
unfolding reachable_def
by (auto dest: rtrancl_on_rtranclI rtranclD)
lemmas reachable_neq_reachable1E[elim] = reachable_neq_reachable1[elim_format]
lemma arc_implies_dominates: "e ∈ E ⟹ (fst e, snd e) ∈ E" by auto
definition neighbourhood::"('v × 'v) set ⇒ 'v ⇒ 'v set" where
"neighbourhood G u = {v. (u,v) ∈ G}"
lemma
neighbourhoodI[intro]: "v ∈ (neighbourhood G u) ⟹ (u,v) ∈ G" and
neighbourhoodD[dest]: "(u,v) ∈ G ⟹ v ∈ (neighbourhood G u)"
by (auto simp: neighbourhood_def)
definition "sources G = {u | u v . (u,v) ∈ G}"
definition "sinks G = {v | u v . (u,v) ∈ G}"
lemma dVs_subset: "G ⊆ G' ⟹ dVs G ⊆ dVs G'"
by (auto simp: dVs_def)
lemma dVs_insert[elim]:
"v∈ dVs (insert (x,y) G) ⟹ ⟦v = x ⟹ P; v = y ⟹ P; v ∈ dVs G ⟹ P⟧ ⟹ P"
by (auto simp: dVs_def)
lemma in_neighbourhood_dVs[simp, intro]:
"v ∈ neighbourhood G u ⟹ v ∈ dVs G"
by auto
lemma subset_neighbourhood_dVs[simp, intro]:
"neighbourhood G u ⊆ dVs G"
by auto
lemma in_dVsE: "v ∈ dVs G ⟹ ⟦(⋀u. (u, v) ∈ G ⟹ P); (⋀u. (v, u) ∈ G ⟹ P)⟧ ⟹ P"
"v ∉ dVs G ⟹ (⟦(⋀u. (u, v) ∉ G); (⋀u. (v, u) ∉ G)⟧ ⟹ P) ⟹ P"
by (auto simp: dVs_def)
lemma neighoubrhood_union[simp]: "neighbourhood (G ∪ G') u = neighbourhood G u ∪ neighbourhood G' u"
by (auto simp: neighbourhood_def)
lemma vs_are_gen: "dVs (set E_impl) = set (map prod.fst E_impl) ∪ set (map prod.snd E_impl)"
by(induction E_impl) auto
lemma dVs_swap: "dVs (prod.swap ` E) = dVs E"
by(auto simp add: dVs_def)
end