theory Lecture8
imports Main
begin
text{* An "abstract" notion of a finite graph *}
locale finitegraph =
fixes edges :: "('a\'a)set" and vertices::"'a set"
assumes finite_vertex_set : "finite vertices"
and is_graph : "(u, v) \ edges \ u \ vertices \ v \ vertices"
begin
(* Note that we can tell Isabelle's simplifier about 2 of the rules using [simp].
More on this later in the course. *)
inductive walk:: "'a list \ bool" where
Nil[simp] : "walk []"
|Singleton [simp] : "v \ vertices \ walk [v]"
|Cons : "(v,w)\edges \ walk(w#vs) \ walk(v#w#vs)"
lemma walk_edge: assumes "(v,w) \ edges" shows "walk [v,w]"
proof -
have "w \ vertices"
using assms is_graph by presburger
then show ?thesis
by (simp add: assms walk.Cons)
qed
definition connected :: "'a \ 'a \ bool" (infixl "\\<^sup>*" 60) where
"connected v w \ \xs. walk xs \ xs \ Nil \ hd xs = v \ last xs = w"
end
(* We can examine the definition of the locale and any lemma proven (whether explicitly or implicitly)
inside it. For example: *)
thm finitegraph_def
thm "finitegraph.walk_edge"
thm "finitegraph.walk.Singleton"
(* An induction principle was proven automatically for our finite graphs*)
thm "finitegraph.walk.induct"
text{* Extending the finite graphs locale to one about weighted finite graphs*}
locale weighted_finitegraph = finitegraph +
fixes weight :: "('a \ 'a) \ nat"
assumes edges_weighted: "\e\edges. \w. weight e = w"
thm finitegraph_def
thm weighted_finitegraph_def [unfolded weighted_finitegraph_axioms_def]
text{* We can define a concrete graph and show that it is an instance of our finite graph. In this
case, we just go for the graph with a single vertex "1" and an edge "(1,1)" to itself.
*}
interpretation singleton_finitegraph: finitegraph "{(1,1)}" "{1}"
proof
show "finite {1}" by simp
next fix u v assume "(u, v) \ {(1::'a, 1::'a)}" then show "u \ {1} \ v \ {1}" by blast
qed
(* We can "peek" into our instance: *)
term singleton_finitegraph.connected
term singleton_finitegraph.walk
(* The definitions and theorems are now available for the locale instance. For example: *)
thm singleton_finitegraph.connected_def
thm singleton_finitegraph.walk_edge
thm singleton_finitegraph.walk.Singleton
thm singleton_finitegraph.walk.induct
text{* We can make the concrete singleton_finitegraph an instance of the weighted_finitegraph locale
by providing a weight function e.g. the one that associates a weight "1" to any edge.
*}
interpretation singleton_finitegraph: weighted_finitegraph "{(1,1)}" "{1}" "\(u,v). 1"
by (unfold_locales) simp
(* The walk_edge theorem is still available *)
thm singleton_finitegraph.walk_edge
(* The weighted edges assumption instantiated with our single edge graph (yielding a trivial property)*)
thm singleton_finitegraph.edges_weighted