Theory Rect_Intersect_Impl
section ‹Implementation of rectangle intersection›
theory Rect_Intersect_Impl
imports "../Functional/Rect_Intersect" IntervalTree_Impl Quicksort_Impl
begin
text ‹Imperative version of rectangle-intersection algorithm.›
subsection ‹Operations›
fun operation_encode :: "('a::heap) operation ⇒ nat" where
"operation_encode oper =
(case oper of INS p i n ⇒ to_nat (is_INS oper, p, i, n)
| DEL p i n ⇒ to_nat (is_INS oper, p, i, n))"
instance operation :: (heap) heap
apply (rule heap_class.intro)
apply (rule countable_classI [of "operation_encode"])
apply (case_tac x, simp_all, case_tac y, simp_all)
apply (simp add: operation.case_eq_if)
..
subsection ‹Initial state›
definition rect_inter_init :: "nat rectangle list ⇒ nat operation array Heap" where
"rect_inter_init rects = do {
p ← Array.of_list (ins_ops rects @ del_ops rects);
quicksort_all p;
return p }"
setup ‹add_rewrite_rule @{thm all_ops_def}›
lemma rect_inter_init_rule [hoare_triple]:
"<emp> rect_inter_init rects <λp. p ↦⇩a all_ops rects>" by auto2
setup ‹del_prfstep_thm @{thm all_ops_def}›
definition rect_inter_next :: "nat operation array ⇒ int_tree ⇒ nat ⇒ int_tree Heap" where
"rect_inter_next a b k = do {
oper ← Array.nth a k;
if is_INS oper then
IntervalTree_Impl.insert_impl (IdxInterval (op_int oper) (op_idx oper)) b
else
IntervalTree_Impl.delete_impl (IdxInterval (op_int oper) (op_idx oper)) b }"
lemma op_int_is_interval:
"is_rect_list rects ⟹ ops = all_ops rects ⟹ k < length ops ⟹
is_interval (op_int (ops ! k))"
@proof @have "ops ! k ∈ set ops" @case "is_INS (ops ! k)" @qed
setup ‹add_forward_prfstep_cond @{thm op_int_is_interval} [with_term "op_int (?ops ! ?k)"]›
lemma rect_inter_next_rule [hoare_triple]:
"is_rect_list rects ⟹ k < length (all_ops rects) ⟹
<a ↦⇩a all_ops rects * int_tree_set S b>
rect_inter_next a b k
<λr. a ↦⇩a all_ops rects * int_tree_set (apply_ops_k_next rects S k) r>⇩t" by auto2
partial_function (heap) rect_inter_impl ::
"nat operation array ⇒ int_tree ⇒ nat ⇒ bool Heap" where
"rect_inter_impl a b k = do {
n ← Array.len a;
(if k ≥ n then return False
else do {
oper ← Array.nth a k;
(if is_INS oper then do {
overlap ← IntervalTree_Impl.search_impl (op_int oper) b;
if overlap then return True
else if k = n - 1 then return False
else do {
b' ← rect_inter_next a b k;
rect_inter_impl a b' (k + 1)}}
else
if k = n - 1 then return False
else do {
b' ← rect_inter_next a b k;
rect_inter_impl a b' (k + 1)})})}"
lemma rect_inter_to_fun_ind [hoare_triple]:
"is_rect_list rects ⟹ k < length (all_ops rects) ⟹
<a ↦⇩a all_ops rects * int_tree_set S b>
rect_inter_impl a b k
<λr. a ↦⇩a all_ops rects * ↑(r ⟷ rect_inter rects S k)>⇩t"
@proof
@let "d = length (all_ops rects) - k"
@strong_induct d arbitrary k S b
@case "k ≥ length (all_ops rects)"
@unfold "rect_inter rects S k"
@case "is_INS (all_ops rects ! k)" @with
@case "has_overlap S (op_int (all_ops rects ! k))"
@case "k = length (all_ops rects) - 1"
@apply_induct_hyp "length (all_ops rects) - (k + 1)" "k + 1"
@have "length (all_ops rects) - (k + 1) < d"
@end
@case "k = length (all_ops rects) - 1"
@apply_induct_hyp "length (all_ops rects) - (k + 1)" "k + 1"
@have "length (all_ops rects) - (k + 1) < d"
@qed
definition rect_inter_all :: "nat rectangle list ⇒ bool Heap" where
"rect_inter_all rects =
(if rects = [] then return False
else do {
a ← rect_inter_init rects;
b ← int_tree_empty;
rect_inter_impl a b 0 })"
text ‹Correctness of rectangle intersection algorithm.›
theorem rect_inter_all_correct:
"is_rect_list rects ⟹
<emp>
rect_inter_all rects
<λr. ↑(r = has_rect_overlap rects)>⇩t" by auto2
end