Theory Undirected_Graph_Specs
section ‹Abstract Graph Datatype›
theory Undirected_Graph_Specs
imports Undirected_Graph
begin
subsection ‹Abstract Weighted Graph›
locale adt_wgraph =
fixes αw :: "'g ⇒ 'v set ⇒ nat" and αg :: "'g ⇒ 'v ugraph"
and invar :: "'g ⇒ bool"
and adj :: "'g ⇒ 'v ⇒ ('v×nat) list"
and empty :: 'g
and add_edge :: "'v×'v ⇒ nat ⇒ 'g ⇒ 'g"
assumes adj_correct: "invar g
⟹ set (adj g u) = {(v,d). (u,v)∈edges (αg g) ∧ αw g {u,v} = d}"
assumes empty_correct:
"invar empty"
"αg empty = graph_empty"
"αw empty = (λ_. 0)"
assumes add_edge_correct:
"⟦invar g; (u,v)∉edges (αg g); u≠v⟧ ⟹ invar (add_edge (u,v) d g)"
"⟦invar g; (u,v)∉edges (αg g); u≠v⟧
⟹ αg (add_edge (u,v) d g) = ins_edge (u,v) (αg g)"
"⟦invar g; (u,v)∉edges (αg g); u≠v⟧
⟹ αw (add_edge (u,v) d g) = (αw g)({u,v}:=d)"
begin
lemmas wgraph_specs = adj_correct empty_correct add_edge_correct
lemma empty_spec_presentation:
"invar empty ∧ αg empty = graph {} {} ∧ αw empty = (λ_. 0)"
by (auto simp: wgraph_specs)
lemma add_edge_spec_presentation:
"⟦invar g; (u,v)∉edges (αg g); u≠v⟧ ⟹
invar (add_edge (u,v) d g)
∧ αg (add_edge (u,v) d g) = ins_edge (u,v) (αg g)
∧ αw (add_edge (u,v) d g) = (αw g)({u,v}:=d)"
by (auto simp: wgraph_specs)
end
subsection ‹Generic From-List Algorithm›
definition valid_graph_repr :: "('v×'v) list ⇒ bool"
where "valid_graph_repr l ⟷ (∀(u,v)∈set l. u≠v)"
definition graph_from_list :: "('v×'v) list ⇒ 'v ugraph"
where "graph_from_list l = foldr ins_edge l graph_empty"
lemma graph_from_list_foldl: "graph_from_list l = fold ins_edge l graph_empty"
unfolding graph_from_list_def
apply (rule foldr_fold[THEN fun_cong])
by (auto simp: fun_eq_iff graph_eq_iff edges_ins_edge)
lemma nodes_of_graph_from_list: "nodes (graph_from_list l) = fst`set l ∪ snd`set l"
apply (induction l)
unfolding graph_from_list_def
by auto
lemma edges_of_graph_from_list:
assumes valid: "valid_graph_repr l"
shows "edges (graph_from_list l) = set l ∪ (set l)¯"
using valid apply (induction l)
unfolding graph_from_list_def valid_graph_repr_def
by auto
definition "valid_weight_repr l ≡ distinct (map (uedge o fst) l)"
definition weight_from_list :: "(('v×'v)×nat) list ⇒ 'v set ⇒ nat" where
"weight_from_list l ≡ foldr (λ((u,v),d) w. w({u,v}:=d)) l (λ_. 0)"
lemma graph_from_list_simps:
"graph_from_list [] = graph_empty"
"graph_from_list ((u,v)#l) = ins_edge (u,v) (graph_from_list l)"
by (auto simp: graph_from_list_def)
lemma weight_from_list_simps:
"weight_from_list [] = (λ_. 0)"
"weight_from_list (((u,v),d)#xs) = (weight_from_list xs)({u,v}:=d)"
by (auto simp: weight_from_list_def)
lemma valid_graph_repr_simps:
"valid_graph_repr []"
"valid_graph_repr ((u,v)#xs) ⟷ u≠v ∧ valid_graph_repr xs"
unfolding valid_graph_repr_def by auto
lemma valid_weight_repr_simps:
"valid_weight_repr []"
"valid_weight_repr (((u,v),w)#xs)
⟷ uedge (u,v)∉uedge`fst`set xs ∧ valid_weight_repr xs"
unfolding valid_weight_repr_def
by (force simp: uedge_def doubleton_eq_iff)+
lemma weight_from_list_correct:
assumes "valid_weight_repr l"
assumes "((u,v),d)∈set l"
shows "weight_from_list l {u,v} = d"
proof -
from assms show ?thesis
apply (induction l)
unfolding valid_weight_repr_def weight_from_list_def
subgoal by simp
by (force simp: doubleton_eq_iff)
qed
context adt_wgraph
begin
definition "valid_wgraph_repr l
⟷ valid_graph_repr (map fst l) ∧ valid_weight_repr l"
definition "from_list l = foldr (λ(e,d). add_edge e d) l empty"
lemma from_list_refine: "valid_wgraph_repr l ⟹
invar (from_list l)
∧ αg (from_list l) = graph_from_list (map fst l)
∧ αw (from_list l) = weight_from_list l"
unfolding from_list_def valid_wgraph_repr_def
supply [simp] = wgraph_specs graph_from_list_simps weight_from_list_simps
apply (induction l)
subgoal by auto
subgoal by (
intro conjI;
clarsimp
simp: uedge_def valid_graph_repr_simps valid_weight_repr_simps
split: prod.splits;
subst wgraph_specs;
auto simp: edges_of_graph_from_list
)
done
lemma from_list_correct:
assumes "valid_wgraph_repr l"
shows
"invar (from_list l)"
"nodes (αg (from_list l)) = fst`fst`set l ∪ snd`fst`set l"
"edges (αg (from_list l)) = (fst`set l) ∪ (fst`set l)¯"
"((u,v),d)∈set l ⟹ αw (from_list l) {u,v} = d"
apply (simp_all add: from_list_refine[OF assms])
using assms unfolding valid_wgraph_repr_def
apply (simp_all add:
edges_of_graph_from_list nodes_of_graph_from_list weight_from_list_correct)
done
lemma valid_wgraph_repr_presentation: "valid_wgraph_repr l ⟷
(∀((u,v),d)∈set l. u≠v) ∧ distinct [ {u,v}. ((u,v),d)←l ]"
proof -
have [simp]: "uedge ∘ fst = (λ((u, v), w). {u, v})"
unfolding uedge_def by auto
show ?thesis
unfolding valid_wgraph_repr_def valid_graph_repr_def valid_weight_repr_def
by (auto split: prod.splits)
qed
lemma from_list_correct_presentation:
assumes "valid_wgraph_repr l"
shows "let gi=from_list l; g=αg gi; w=αw gi in
invar gi
∧ nodes g = ⋃{{u,v} | u v. ∃d. ((u,v),d)∈set l}
∧ edges g = ⋃{{(u,v),(v,u)} | u v. ∃d. ((u,v),d)∈set l}
∧ (∀((u,v),d)∈set l. w {u,v}=d)
"
unfolding Let_def from_list_correct(2-3)[OF assms]
apply (intro conjI)
subgoal by (simp add: from_list_correct(1)[OF assms])
subgoal by (auto 0 0 simp: in_set_conv_decomp; blast)
subgoal by (auto 0 0 simp: in_set_conv_decomp; blast)
subgoal using from_list_correct(4)[OF assms] by auto
done
end
end