Theory GraphSpec
section "Graph Interface"
theory GraphSpec
imports Main Graph
Collections.Collections
begin
text ‹
This theory defines an ICF-style interface for graphs.
›
type_synonym ('V,'W,'G) graph_α = "'G ⇒ ('V,'W) graph"
locale graph =
fixes α :: "'G ⇒ ('V,'W) graph"
fixes invar :: "'G ⇒ bool"
assumes finite[simp, intro!]:
"invar g ⟹ finite (nodes (α g))"
"invar g ⟹ finite (edges (α g))"
assumes valid: "invar g ⟹ valid_graph (α g)"
type_synonym ('V,'W,'G) graph_empty = "unit ⇒ 'G"
locale graph_empty = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes empty :: "unit ⇒ 'G"
assumes empty_correct:
"α (empty ()) = Graph.empty"
"invar (empty ())"
type_synonym ('V,'W,'G) graph_add_node = "'V ⇒ 'G ⇒ 'G"
locale graph_add_node = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes add_node :: "'V ⇒ 'G ⇒ 'G"
assumes add_node_correct:
"invar g ⟹ invar (add_node v g)"
"invar g ⟹ α (add_node v g) = Graph.add_node v (α g)"
type_synonym ('V,'W,'G) graph_delete_node = "'V ⇒ 'G ⇒ 'G"
locale graph_delete_node = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes delete_node :: "'V ⇒ 'G ⇒ 'G"
assumes delete_node_correct:
"invar g ⟹ invar (delete_node v g)"
"invar g ⟹ α (delete_node v g) = Graph.delete_node v (α g)"
type_synonym ('V,'W,'G) graph_add_edge = "'V ⇒'W ⇒ 'V ⇒ 'G ⇒ 'G"
locale graph_add_edge = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes add_edge :: "'V ⇒ 'W ⇒ 'V ⇒ 'G ⇒ 'G"
assumes add_edge_correct:
"invar g ⟹ invar (add_edge v e v' g)"
"invar g ⟹ α (add_edge v e v' g) = Graph.add_edge v e v' (α g)"
type_synonym ('V,'W,'G) graph_delete_edge = "'V ⇒'W ⇒ 'V ⇒ 'G ⇒ 'G"
locale graph_delete_edge = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes delete_edge :: "'V ⇒ 'W ⇒ 'V ⇒ 'G ⇒ 'G"
assumes delete_edge_correct:
"invar g ⟹ invar (delete_edge v e v' g)"
"invar g ⟹ α (delete_edge v e v' g) = Graph.delete_edge v e v' (α g)"
type_synonym ('V,'W,'σ,'G) graph_nodes_it = "'G ⇒ ('V,'σ) set_iterator"
locale graph_nodes_it_defs =
fixes nodes_list_it :: "'G ⇒ ('V,'V list) set_iterator"
begin
definition "nodes_it g ≡ it_to_it (nodes_list_it g)"
end
locale graph_nodes_it = graph α invar + graph_nodes_it_defs nodes_list_it
for α :: "'G ⇒ ('V,'W) graph" and invar and
nodes_list_it :: "'G ⇒ ('V,'V list) set_iterator"
+
assumes nodes_list_it_correct:
"invar g ⟹ set_iterator (nodes_list_it g) (Graph.nodes (α g))"
begin
lemma nodes_it_correct:
"invar g ⟹ set_iterator (nodes_it g) (Graph.nodes (α g))"
unfolding nodes_it_def
apply (rule it_to_it_correct)
by (rule nodes_list_it_correct)
lemma pi_nodes_it[icf_proper_iteratorI]:
"proper_it (nodes_it S) (nodes_it S)"
unfolding nodes_it_def
by (intro icf_proper_iteratorI)
lemma nodes_it_proper[proper_it]:
"proper_it' nodes_it nodes_it"
apply (rule proper_it'I)
by (rule pi_nodes_it)
end
type_synonym ('V,'W,'σ,'G) graph_edges_it
= "'G ⇒ (('V×'W×'V),'σ) set_iterator"
locale graph_edges_it_defs =
fixes edges_list_it :: "('V,'W,('V×'W×'V) list,'G) graph_edges_it"
begin
definition "edges_it g ≡ it_to_it (edges_list_it g)"
end
locale graph_edges_it = graph α invar + graph_edges_it_defs edges_list_it
for α :: "'G ⇒ ('V,'W) graph" and invar and
edges_list_it :: "('V,'W,('V×'W×'V) list,'G) graph_edges_it"
+
assumes edges_list_it_correct:
"invar g ⟹ set_iterator (edges_list_it g) (Graph.edges (α g))"
begin
lemma edges_it_correct:
"invar g ⟹ set_iterator (edges_it g) (Graph.edges (α g))"
unfolding edges_it_def
apply (rule it_to_it_correct)
by (rule edges_list_it_correct)
lemma pi_edges_it[icf_proper_iteratorI]:
"proper_it (edges_it S) (edges_it S)"
unfolding edges_it_def
by (intro icf_proper_iteratorI)
lemma edges_it_proper[proper_it]:
"proper_it' edges_it edges_it"
apply (rule proper_it'I)
by (rule pi_edges_it)
end
type_synonym ('V,'W,'σ,'G) graph_succ_it =
"'G ⇒ 'V ⇒ ('W×'V,'σ) set_iterator"
locale graph_succ_it_defs =
fixes succ_list_it :: "'G ⇒ 'V ⇒ ('W×'V,('W×'V) list) set_iterator"
begin
definition "succ_it g v ≡ it_to_it (succ_list_it g v)"
end
locale graph_succ_it = graph α invar + graph_succ_it_defs succ_list_it
for α :: "'G ⇒ ('V,'W) graph" and invar and
succ_list_it :: "'G ⇒ 'V ⇒ ('W×'V,('W×'V) list) set_iterator" +
assumes succ_list_it_correct:
"invar g ⟹ set_iterator (succ_list_it g v) (Graph.succ (α g) v)"
begin
lemma succ_it_correct:
"invar g ⟹ set_iterator (succ_it g v) (Graph.succ (α g) v)"
unfolding succ_it_def
apply (rule it_to_it_correct)
by (rule succ_list_it_correct)
lemma pi_succ_it[icf_proper_iteratorI]:
"proper_it (succ_it S v) (succ_it S v)"
unfolding succ_it_def
by (intro icf_proper_iteratorI)
lemma succ_it_proper[proper_it]:
"proper_it' (λS. succ_it S v) (λS. succ_it S v)"
apply (rule proper_it'I)
by (rule pi_succ_it)
end
subsection "Adjacency Lists"
type_synonym ('V,'W) adj_list = "'V list × ('V×'W×'V) list"
definition adjl_α :: "('V,'W) adj_list ⇒ ('V,'W) graph" where
"adjl_α l ≡ let (nl,el) = l in ⦇
nodes = set nl ∪ fst`set el ∪ snd`snd`set el,
edges = set el
⦈"
lemma adjl_is_graph: "graph adjl_α (λ_. True)"
apply (unfold_locales)
unfolding adjl_α_def
by force+
type_synonym ('V,'W,'G) graph_from_list = "('V,'W) adj_list ⇒ 'G"
locale graph_from_list = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes from_list :: "('V,'W) adj_list ⇒ 'G"
assumes from_list_correct:
"invar (from_list l)"
"α (from_list l) = adjl_α l"
type_synonym ('V,'W,'G) graph_to_list = "'G ⇒ ('V,'W) adj_list"
locale graph_to_list = graph +
constrains α :: "'G ⇒ ('V,'W) graph"
fixes to_list :: "'G ⇒ ('V,'W) adj_list"
assumes to_list_correct:
"invar g ⟹ adjl_α (to_list g) = α g"
subsection ‹Record Based Interface›