Theory Union_Find_Impl
section ‹Implementation of union find›
theory Union_Find_Impl
imports SepAuto "../Functional/Union_Find"
begin
text ‹
Development follows theory Union\_Find in
\<^cite>‹"Separation_Logic_Imperative_HOL-AFP"› by Lammich and Meis.
›
type_synonym uf = "nat array × nat array"
definition is_uf :: "nat ⇒ (nat×nat) set ⇒ uf ⇒ assn" where [rewrite_ent]:
"is_uf n R u = (∃⇩Al szl. snd u ↦⇩a l * fst u ↦⇩a szl *
↑(ufa_invar l) * ↑(ufa_α l = R) * ↑(length l = n) * ↑(length szl = n))"
definition uf_init :: "nat ⇒ uf Heap" where
"uf_init n = do {
l ← Array.of_list [0..<n];
szl ← Array.new n (1::nat);
return (szl, l)
}"
text ‹Correctness of uf\_init.›
theorem uf_init_rule [hoare_triple]:
"<emp> uf_init n <is_uf n (uf_init_rel n)>" by auto2
partial_function (heap) uf_rep_of :: "nat array ⇒ nat ⇒ nat Heap" where
"uf_rep_of p i = do {
n ← Array.nth p i;
if n = i then return i else uf_rep_of p n
}"
lemma uf_rep_of_rule [hoare_triple]:
"ufa_invar l ⟹ i < length l ⟹
<p ↦⇩a l>
uf_rep_of p i
<λr. p ↦⇩a l * ↑(r = rep_of l i)>"
@proof @prop_induct "ufa_invar l ∧ i < length l" @qed
partial_function (heap) uf_compress :: "nat ⇒ nat ⇒ nat array ⇒ unit Heap" where
"uf_compress i ci p = (
if i = ci then return ()
else do {
ni ← Array.nth p i;
uf_compress ni ci p;
Array.upd i ci p;
return ()
})"
lemma uf_compress_rule [hoare_triple]:
"ufa_invar l ⟹ i < length l ⟹
<p ↦⇩a l>
uf_compress i (rep_of l i) p
<λ_. ∃⇩Al'. p ↦⇩a l' * ↑(ufa_invar l' ∧ length l' = length l ∧
(∀i<length l. rep_of l' i = rep_of l i))>"
@proof @prop_induct "ufa_invar l ∧ i < length l" @qed
definition uf_rep_of_c :: "nat array ⇒ nat ⇒ nat Heap" where
"uf_rep_of_c p i = do {
ci ← uf_rep_of p i;
uf_compress i ci p;
return ci
}"
lemma uf_rep_of_c_rule [hoare_triple]:
"ufa_invar l ⟹ i < length l ⟹
<p ↦⇩a l>
uf_rep_of_c p i
<λr. ∃⇩Al'. p ↦⇩a l' * ↑(r = rep_of l i ∧ ufa_invar l' ∧ length l' = length l ∧
(∀i<length l. rep_of l' i = rep_of l i))>"
by auto2
definition uf_cmp :: "uf ⇒ nat ⇒ nat ⇒ bool Heap" where
"uf_cmp u i j = do {
n ← Array.len (snd u);
if (i≥n ∨ j≥n) then return False
else do {
ci ← uf_rep_of_c (snd u) i;
cj ← uf_rep_of_c (snd u) j;
return (ci = cj)
}
}"
text ‹Correctness of compare.›
theorem uf_cmp_rule [hoare_triple]:
"<is_uf n R u>
uf_cmp u i j
<λr. is_uf n R u * ↑(r ⟷ (i,j)∈R)>" by auto2
definition uf_union :: "uf ⇒ nat ⇒ nat ⇒ uf Heap" where
"uf_union u i j = do {
ci ← uf_rep_of (snd u) i;
cj ← uf_rep_of (snd u) j;
if (ci = cj) then return u
else do {
si ← Array.nth (fst u) ci;
sj ← Array.nth (fst u) cj;
if si < sj then do {
Array.upd ci cj (snd u);
Array.upd cj (si+sj) (fst u);
return u
} else do {
Array.upd cj ci (snd u);
Array.upd ci (si+sj) (fst u);
return u
}
}
}"
text ‹Correctness of union.›
theorem uf_union_rule [hoare_triple]:
"i < n ⟹ j < n ⟹
<is_uf n R u>
uf_union u i j
<is_uf n (per_union R i j)>" by auto2
setup ‹del_prfstep_thm @{thm is_uf_def}›
end