src/HOL/Data_Structures/Height_Balanced_Tree.thy
author nipkow
Wed, 29 Apr 2020 13:18:32 +0200
changeset 71812 7c25e3467cf0
parent 71810 7567f73ef541
child 71818 986d5abbe77c
permissions -rw-r--r--
tuned
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71810
nipkow
parents: 71801
diff changeset
     1
(* Author: Tobias Nipkow *)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     2
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     3
section "Height-Balanced Trees"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     4
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     5
theory Height_Balanced_Tree
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     6
imports
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     7
  Cmp
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     8
  Isin2
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
     9
begin
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    10
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    11
text \<open>Height-balanced trees (HBTs) can be seen as a generalization of AVL trees.
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    12
The code and the proofs were obtained by small modifications of the AVL theories.
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    13
This is an implementation of sets via HBTs.\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    14
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    15
type_synonym 'a hbt = "('a*nat) tree"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    16
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    17
definition empty :: "'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    18
"empty = Leaf"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    19
71812
nipkow
parents: 71810
diff changeset
    20
text \<open>The maximal amount by which the height of two siblings may differ:\<close>
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    21
71812
nipkow
parents: 71810
diff changeset
    22
locale HBT =
nipkow
parents: 71810
diff changeset
    23
fixes m :: nat
nipkow
parents: 71810
diff changeset
    24
assumes [arith]: "m > 0"
nipkow
parents: 71810
diff changeset
    25
begin
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    26
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    27
text \<open>Invariant:\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    28
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    29
fun hbt :: "'a hbt \<Rightarrow> bool" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    30
"hbt Leaf = True" |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    31
"hbt (Node l (a,n) r) =
71812
nipkow
parents: 71810
diff changeset
    32
 (abs(int(height l) - int(height r)) \<le> int(m) \<and>
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    33
  n = max (height l) (height r) + 1 \<and> hbt l \<and> hbt r)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    34
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    35
fun ht :: "'a hbt \<Rightarrow> nat" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    36
"ht Leaf = 0" |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    37
"ht (Node l (a,n) r) = n"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    38
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    39
definition node :: "'a hbt \<Rightarrow> 'a \<Rightarrow> 'a hbt \<Rightarrow> 'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    40
"node l a r = Node l (a, max (ht l) (ht r) + 1) r"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    41
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    42
definition balL :: "'a hbt \<Rightarrow> 'a \<Rightarrow> 'a hbt \<Rightarrow> 'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    43
"balL AB b C =
71812
nipkow
parents: 71810
diff changeset
    44
  (if ht AB = ht C + m + 1 then
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    45
     case AB of 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    46
       Node A (a, _) B \<Rightarrow>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    47
         if ht A \<ge> ht B then node A a (node B b C)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    48
         else
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    49
           case B of
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    50
             Node B\<^sub>1 (ab, _) B\<^sub>2 \<Rightarrow> node (node A a B\<^sub>1) ab (node B\<^sub>2 b C)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    51
   else node AB b C)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    52
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    53
definition balR :: "'a hbt \<Rightarrow> 'a \<Rightarrow> 'a hbt \<Rightarrow> 'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    54
"balR A a BC =
71812
nipkow
parents: 71810
diff changeset
    55
   (if ht BC = ht A + m + 1 then
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    56
      case BC of
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    57
        Node B (b, _) C \<Rightarrow>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    58
          if ht B \<le> ht C then node (node A a B) b C
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    59
          else
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    60
            case B of
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    61
              Node B\<^sub>1 (ab, _) B\<^sub>2 \<Rightarrow> node (node A a B\<^sub>1) ab (node B\<^sub>2 b C)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    62
  else node A a BC)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    63
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    64
fun insert :: "'a::linorder \<Rightarrow> 'a hbt \<Rightarrow> 'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    65
"insert x Leaf = Node Leaf (x, 1) Leaf" |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    66
"insert x (Node l (a, n) r) = (case cmp x a of
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    67
   EQ \<Rightarrow> Node l (a, n) r |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    68
   LT \<Rightarrow> balL (insert x l) a r |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    69
   GT \<Rightarrow> balR l a (insert x r))"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    70
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    71
fun split_max :: "'a hbt \<Rightarrow> 'a hbt * 'a" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    72
"split_max (Node l (a, _) r) =
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    73
  (if r = Leaf then (l,a) else let (r',a') = split_max r in (balL l a r', a'))"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    74
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    75
lemmas split_max_induct = split_max.induct[case_names Node Leaf]
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    76
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    77
fun delete :: "'a::linorder \<Rightarrow> 'a hbt \<Rightarrow> 'a hbt" where
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    78
"delete _ Leaf = Leaf" |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    79
"delete x (Node l (a, n) r) =
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    80
  (case cmp x a of
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    81
     EQ \<Rightarrow> if l = Leaf then r
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    82
           else let (l', a') = split_max l in balR l' a' r |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    83
     LT \<Rightarrow> balR (delete x l) a r |
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    84
     GT \<Rightarrow> balL l a (delete x r))"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    85
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    86
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    87
subsection \<open>Functional Correctness Proofs\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    88
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    89
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    90
subsubsection "Proofs for insert"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    91
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    92
lemma inorder_balL:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    93
  "inorder (balL l a r) = inorder l @ a # inorder r"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    94
by (auto simp: node_def balL_def split:tree.splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    95
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    96
lemma inorder_balR:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    97
  "inorder (balR l a r) = inorder l @ a # inorder r"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    98
by (auto simp: node_def balR_def split:tree.splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
    99
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   100
theorem inorder_insert:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   101
  "sorted(inorder t) \<Longrightarrow> inorder(insert x t) = ins_list x (inorder t)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   102
by (induct t) 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   103
   (auto simp: ins_list_simps inorder_balL inorder_balR)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   104
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   105
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   106
subsubsection "Proofs for delete"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   107
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   108
lemma inorder_split_maxD:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   109
  "\<lbrakk> split_max t = (t',a); t \<noteq> Leaf \<rbrakk> \<Longrightarrow>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   110
   inorder t' @ [a] = inorder t"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   111
by(induction t arbitrary: t' rule: split_max.induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   112
  (auto simp: inorder_balL split: if_splits prod.splits tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   113
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   114
theorem inorder_delete:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   115
  "sorted(inorder t) \<Longrightarrow> inorder (delete x t) = del_list x (inorder t)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   116
by(induction t)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   117
  (auto simp: del_list_simps inorder_balL inorder_balR inorder_split_maxD split: prod.splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   118
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   119
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   120
subsection \<open>Invariant preservation\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   121
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   122
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   123
subsubsection \<open>Insertion maintains balance\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   124
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   125
declare Let_def [simp]
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   126
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   127
lemma ht_height[simp]: "hbt t \<Longrightarrow> ht t = height t"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   128
by (cases t rule: tree2_cases) simp_all
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   129
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   130
text \<open>First, a fast but relatively manual proof with many lemmas:\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   131
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   132
lemma height_balL:
71812
nipkow
parents: 71810
diff changeset
   133
  "\<lbrakk> hbt l; hbt r; height l = height r + m + 1 \<rbrakk> \<Longrightarrow>
nipkow
parents: 71810
diff changeset
   134
   height (balL l a r) \<in> {height r + m + 1, height r + m + 2}"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   135
apply (cases l)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   136
 apply (auto simp:node_def balL_def split:tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   137
 by arith+
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   138
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   139
lemma height_balR:
71812
nipkow
parents: 71810
diff changeset
   140
  "\<lbrakk> hbt l; hbt r; height r = height l + m + 1 \<rbrakk> \<Longrightarrow>
nipkow
parents: 71810
diff changeset
   141
   height (balR l a r) \<in> {height l + m + 1, height l + m + 2}"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   142
apply (cases r)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   143
 apply(auto simp add:node_def balR_def split:tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   144
 by arith+
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   145
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   146
lemma height_node[simp]: "height(node l a r) = max (height l) (height r) + 1"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   147
by (simp add: node_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   148
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   149
lemma height_balL2:
71812
nipkow
parents: 71810
diff changeset
   150
  "\<lbrakk> hbt l; hbt r; height l \<noteq> height r + m + 1 \<rbrakk> \<Longrightarrow>
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   151
   height (balL l a r) = 1 + max (height l) (height r)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   152
by (cases l, cases r) (simp_all add: balL_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   153
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   154
lemma height_balR2:
71812
nipkow
parents: 71810
diff changeset
   155
  "\<lbrakk> hbt l;  hbt r;  height r \<noteq> height l + m + 1 \<rbrakk> \<Longrightarrow>
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   156
   height (balR l a r) = 1 + max (height l) (height r)"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   157
by (cases l, cases r) (simp_all add: balR_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   158
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   159
lemma hbt_balL: 
71812
nipkow
parents: 71810
diff changeset
   160
  "\<lbrakk> hbt l; hbt r; height r - m \<le> height l \<and> height l \<le> height r + m + 1 \<rbrakk> \<Longrightarrow> hbt(balL l a r)"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   161
by(cases l, cases r)
71812
nipkow
parents: 71810
diff changeset
   162
  (auto simp: balL_def node_def max_def split!: if_splits tree.split)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   163
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   164
lemma hbt_balR: 
71812
nipkow
parents: 71810
diff changeset
   165
  "\<lbrakk> hbt l; hbt r; height l - m \<le> height r \<and> height r \<le> height l + m + 1 \<rbrakk> \<Longrightarrow> hbt(balR l a r)"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   166
by(cases r, cases l)
71812
nipkow
parents: 71810
diff changeset
   167
  (auto simp: balR_def node_def max_def split!: if_splits tree.split)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   168
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   169
text\<open>Insertion maintains @{const hbt}. Requires simultaneous proof.\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   170
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   171
theorem hbt_insert:
71812
nipkow
parents: 71810
diff changeset
   172
  "hbt t \<Longrightarrow> hbt(insert x t)"
nipkow
parents: 71810
diff changeset
   173
  "hbt t \<Longrightarrow> height (insert x t) \<in> {height t, height t + 1}"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   174
proof (induction t rule: tree2_induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   175
  case (Node l a _ r)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   176
  case 1
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   177
  show ?case
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   178
  proof(cases "x = a")
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   179
    case True with Node 1 show ?thesis by simp
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   180
  next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   181
    case False
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   182
    show ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   183
    proof(cases "x<a")
71810
nipkow
parents: 71801
diff changeset
   184
      case True with 1 Node(1,2) show ?thesis by (auto intro!: hbt_balL)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   185
    next
71810
nipkow
parents: 71801
diff changeset
   186
      case False with 1 Node(3,4) \<open>x\<noteq>a\<close> show ?thesis by (auto intro!: hbt_balR)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   187
    qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   188
  qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   189
  case 2
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   190
  show ?case
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   191
  proof(cases "x = a")
71810
nipkow
parents: 71801
diff changeset
   192
    case True with 2 show ?thesis by simp
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   193
  next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   194
    case False
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   195
    show ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   196
    proof(cases "x<a")
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   197
      case True
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   198
      show ?thesis
71812
nipkow
parents: 71810
diff changeset
   199
      proof(cases "height (insert x l) = height r + m + 1")
71810
nipkow
parents: 71801
diff changeset
   200
        case False with 2 Node(1,2) \<open>x < a\<close> show ?thesis by (auto simp: height_balL2)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   201
      next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   202
        case True 
71812
nipkow
parents: 71810
diff changeset
   203
        hence "(height (balL (insert x l) a r) = height r + m + 1) \<or>
nipkow
parents: 71810
diff changeset
   204
          (height (balL (insert x l) a r) = height r + m + 2)" (is "?A \<or> ?B")
71810
nipkow
parents: 71801
diff changeset
   205
          using 2 Node(1,2) height_balL[OF _ _ True] by simp
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   206
        thus ?thesis
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   207
        proof
71810
nipkow
parents: 71801
diff changeset
   208
          assume ?A with 2 Node(2) True \<open>x < a\<close> show ?thesis by (auto)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   209
        next
71810
nipkow
parents: 71801
diff changeset
   210
          assume ?B with 2 Node(2) True \<open>x < a\<close> show ?thesis by (simp) arith
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   211
        qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   212
      qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   213
    next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   214
      case False
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   215
      show ?thesis 
71812
nipkow
parents: 71810
diff changeset
   216
      proof(cases "height (insert x r) = height l + m + 1")
71810
nipkow
parents: 71801
diff changeset
   217
        case False with 2 Node(3,4) \<open>\<not>x < a\<close> show ?thesis by (auto simp: height_balR2)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   218
      next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   219
        case True 
71812
nipkow
parents: 71810
diff changeset
   220
        hence "(height (balR l a (insert x r)) = height l + m + 1) \<or>
nipkow
parents: 71810
diff changeset
   221
          (height (balR l a (insert x r)) = height l + m + 2)"  (is "?A \<or> ?B")
71810
nipkow
parents: 71801
diff changeset
   222
          using Node 2 height_balR[OF _ _ True] by simp
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   223
        thus ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   224
        proof
71810
nipkow
parents: 71801
diff changeset
   225
          assume ?A with 2 Node(4) True \<open>\<not>x < a\<close> show ?thesis by (auto)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   226
        next
71810
nipkow
parents: 71801
diff changeset
   227
          assume ?B with 2 Node(4) True \<open>\<not>x < a\<close> show ?thesis by (simp) arith
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   228
        qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   229
      qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   230
    qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   231
  qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   232
qed simp_all
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   233
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   234
text \<open>Now an automatic proof without lemmas:\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   235
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   236
theorem hbt_insert_auto: "hbt t \<Longrightarrow>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   237
  hbt(insert x t) \<and> height (insert x t) \<in> {height t, height t + 1}"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   238
apply (induction t rule: tree2_induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   239
 (* if you want to save a few secs: apply (auto split!: if_split) *)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   240
 apply (auto simp: balL_def balR_def node_def max_absorb1 max_absorb2 split!: if_split tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   241
done
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   242
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   243
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   244
subsubsection \<open>Deletion maintains balance\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   245
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   246
lemma hbt_split_max:
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   247
  "\<lbrakk> hbt t; t \<noteq> Leaf \<rbrakk> \<Longrightarrow>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   248
  hbt (fst (split_max t)) \<and>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   249
  height t \<in> {height(fst (split_max t)), height(fst (split_max t)) + 1}"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   250
by(induct t rule: split_max_induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   251
  (auto simp: balL_def node_def max_absorb2 split!: prod.split if_split tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   252
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   253
text\<open>Deletion maintains @{const hbt}:\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   254
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   255
theorem hbt_delete:
71810
nipkow
parents: 71801
diff changeset
   256
  "hbt t \<Longrightarrow> hbt(delete x t)"
nipkow
parents: 71801
diff changeset
   257
  "hbt t \<Longrightarrow> height t \<in> {height (delete x t), height (delete x t) + 1}"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   258
proof (induct t rule: tree2_induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   259
  case (Node l a n r)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   260
  case 1
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   261
  thus ?case
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   262
    using Node hbt_split_max[of l] by (auto intro!: hbt_balL hbt_balR split: prod.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   263
  case 2
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   264
  show ?case
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   265
  proof(cases "x = a")
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   266
    case True then show ?thesis using 1 hbt_split_max[of l]
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   267
      by(auto simp: balR_def max_absorb2 split!: if_splits prod.split tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   268
  next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   269
    case False
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   270
    show ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   271
    proof(cases "x<a")
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   272
      case True
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   273
      show ?thesis
71812
nipkow
parents: 71810
diff changeset
   274
      proof(cases "height r = height (delete x l) + m + 1")
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   275
        case False with Node 1 \<open>x < a\<close> show ?thesis by(auto simp: balR_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   276
      next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   277
        case True 
71812
nipkow
parents: 71810
diff changeset
   278
        hence "(height (balR (delete x l) a r) = height (delete x l) + m + 1) \<or>
nipkow
parents: 71810
diff changeset
   279
          height (balR (delete x l) a r) = height (delete x l) + m + 2" (is "?A \<or> ?B")
71810
nipkow
parents: 71801
diff changeset
   280
          using Node 2height_balR[OF _ _ True] by simp
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   281
        thus ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   282
        proof
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   283
          assume ?A with \<open>x < a\<close> Node 2 show ?thesis by(auto simp: balR_def split!: if_splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   284
        next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   285
          assume ?B with \<open>x < a\<close> Node 2 show ?thesis by(auto simp: balR_def split!: if_splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   286
        qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   287
      qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   288
    next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   289
      case False
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   290
      show ?thesis
71812
nipkow
parents: 71810
diff changeset
   291
      proof(cases "height l = height (delete x r) + m + 1")
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   292
        case False with Node 1 \<open>\<not>x < a\<close> \<open>x \<noteq> a\<close> show ?thesis by(auto simp: balL_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   293
      next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   294
        case True 
71812
nipkow
parents: 71810
diff changeset
   295
        hence "(height (balL l a (delete x r)) = height (delete x r) + m + 1) \<or>
nipkow
parents: 71810
diff changeset
   296
          height (balL l a (delete x r)) = height (delete x r) + m + 2" (is "?A \<or> ?B")
71810
nipkow
parents: 71801
diff changeset
   297
          using Node 2 height_balL[OF _ _ True] by simp
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   298
        thus ?thesis 
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   299
        proof
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   300
          assume ?A with \<open>\<not>x < a\<close> \<open>x \<noteq> a\<close> Node 2 show ?thesis by(auto simp: balL_def split: if_splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   301
        next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   302
          assume ?B with \<open>\<not>x < a\<close> \<open>x \<noteq> a\<close> Node 2 show ?thesis by(auto simp: balL_def split: if_splits)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   303
        qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   304
      qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   305
    qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   306
  qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   307
qed simp_all
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   308
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   309
text \<open>A more automatic proof.
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   310
Complete automation as for insertion seems hard due to resource requirements.\<close>
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   311
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   312
theorem hbt_delete_auto:
71810
nipkow
parents: 71801
diff changeset
   313
  "hbt t \<Longrightarrow> hbt(delete x t)"
nipkow
parents: 71801
diff changeset
   314
  "hbt t \<Longrightarrow> height t \<in> {height (delete x t), height (delete x t) + 1}"
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   315
proof (induct t rule: tree2_induct)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   316
  case (Node l a n r)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   317
  case 1
71810
nipkow
parents: 71801
diff changeset
   318
  thus ?case
nipkow
parents: 71801
diff changeset
   319
    using Node hbt_split_max[of l] by (auto intro!: hbt_balL hbt_balR split: prod.split)
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   320
  case 2
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   321
  show ?case
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   322
  proof(cases "x = a")
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   323
    case True thus ?thesis
71810
nipkow
parents: 71801
diff changeset
   324
      using 2 hbt_split_max[of l]
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   325
      by(auto simp: balR_def max_absorb2 split!: if_splits prod.split tree.split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   326
  next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   327
    case False thus ?thesis 
71810
nipkow
parents: 71801
diff changeset
   328
      using height_balL[of l "delete x r" a] height_balR[of "delete x l" r a] 2 Node
71801
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   329
        by(auto simp: balL_def balR_def split!: if_split)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   330
  qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   331
qed simp_all
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   332
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   333
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   334
subsection "Overall correctness"
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   335
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   336
interpretation S: Set_by_Ordered
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   337
where empty = empty and isin = isin and insert = insert and delete = delete
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   338
and inorder = inorder and inv = hbt
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   339
proof (standard, goal_cases)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   340
  case 1 show ?case by (simp add: empty_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   341
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   342
  case 2 thus ?case by(simp add: isin_set_inorder)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   343
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   344
  case 3 thus ?case by(simp add: inorder_insert)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   345
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   346
  case 4 thus ?case by(simp add: inorder_delete)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   347
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   348
  case 5 thus ?case by (simp add: empty_def)
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   349
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   350
  case 6 thus ?case by (simp add: hbt_insert(1))
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   351
next
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   352
  case 7 thus ?case by (simp add: hbt_delete(1))
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   353
qed
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   354
49d8d8ad7e43 added Height_Balanced_Trees
nipkow
parents:
diff changeset
   355
end
71812
nipkow
parents: 71810
diff changeset
   356
nipkow
parents: 71810
diff changeset
   357
end