src/HOL/Data_Structures/AVL_Set_Code.thy
author nipkow
Thu, 23 Apr 2020 22:54:23 +0200
changeset 71795 8ad9b2d3dd81
child 71815 a86e37f4ad60
permissions -rw-r--r--
split AVL_Set.thy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71795
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     1
(*
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     2
Author:     Tobias Nipkow, Daniel Stüwe
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     3
Based on the AFP entry AVL.
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     4
*)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     5
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     6
section "AVL Tree Implementation of Sets"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     7
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     8
theory AVL_Set_Code
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
     9
imports
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    10
  Cmp
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    11
  Isin2
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    12
begin
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    13
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    14
subsection \<open>Code\<close>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    15
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    16
type_synonym 'a avl_tree = "('a*nat) tree"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    17
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    18
definition empty :: "'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    19
"empty = Leaf"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    20
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    21
fun ht :: "'a avl_tree \<Rightarrow> nat" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    22
"ht Leaf = 0" |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    23
"ht (Node l (a,n) r) = n"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    24
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    25
definition node :: "'a avl_tree \<Rightarrow> 'a \<Rightarrow> 'a avl_tree \<Rightarrow> 'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    26
"node l a r = Node l (a, max (ht l) (ht r) + 1) r"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    27
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    28
definition balL :: "'a avl_tree \<Rightarrow> 'a \<Rightarrow> 'a avl_tree \<Rightarrow> 'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    29
"balL AB b C =
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    30
  (if ht AB = ht C + 2 then
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    31
     case AB of 
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    32
       Node A (a, _) B \<Rightarrow>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    33
         if ht A \<ge> ht B then node A a (node B b C)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    34
         else
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    35
           case B of
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    36
             Node B\<^sub>1 (ab, _) B\<^sub>2 \<Rightarrow> node (node A a B\<^sub>1) ab (node B\<^sub>2 b C)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    37
   else node AB b C)"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    38
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    39
definition balR :: "'a avl_tree \<Rightarrow> 'a \<Rightarrow> 'a avl_tree \<Rightarrow> 'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    40
"balR A a BC =
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    41
   (if ht BC = ht A + 2 then
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    42
      case BC of
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    43
        Node B (b, _) C \<Rightarrow>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    44
          if ht B \<le> ht C then node (node A a B) b C
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    45
          else
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    46
            case B of
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    47
              Node B\<^sub>1 (ab, _) B\<^sub>2 \<Rightarrow> node (node A a B\<^sub>1) ab (node B\<^sub>2 b C)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    48
  else node A a BC)"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    49
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    50
fun insert :: "'a::linorder \<Rightarrow> 'a avl_tree \<Rightarrow> 'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    51
"insert x Leaf = Node Leaf (x, 1) Leaf" |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    52
"insert x (Node l (a, n) r) = (case cmp x a of
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    53
   EQ \<Rightarrow> Node l (a, n) r |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    54
   LT \<Rightarrow> balL (insert x l) a r |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    55
   GT \<Rightarrow> balR l a (insert x r))"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    56
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    57
fun split_max :: "'a avl_tree \<Rightarrow> 'a avl_tree * 'a" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    58
"split_max (Node l (a, _) r) =
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    59
  (if r = Leaf then (l,a) else let (r',a') = split_max r in (balL l a r', a'))"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    60
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    61
lemmas split_max_induct = split_max.induct[case_names Node Leaf]
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    62
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    63
fun delete :: "'a::linorder \<Rightarrow> 'a avl_tree \<Rightarrow> 'a avl_tree" where
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    64
"delete _ Leaf = Leaf" |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    65
"delete x (Node l (a, n) r) =
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    66
  (case cmp x a of
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    67
     EQ \<Rightarrow> if l = Leaf then r
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    68
           else let (l', a') = split_max l in balR l' a' r |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    69
     LT \<Rightarrow> balR (delete x l) a r |
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    70
     GT \<Rightarrow> balL l a (delete x r))"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    71
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    72
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    73
subsection \<open>Functional Correctness Proofs\<close>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    74
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    75
text\<open>Very different from the AFP/AVL proofs\<close>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    76
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    77
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    78
subsubsection "Proofs for insert"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    79
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    80
lemma inorder_balL:
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    81
  "inorder (balL l a r) = inorder l @ a # inorder r"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    82
by (auto simp: node_def balL_def split:tree.splits)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    83
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    84
lemma inorder_balR:
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    85
  "inorder (balR l a r) = inorder l @ a # inorder r"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    86
by (auto simp: node_def balR_def split:tree.splits)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    87
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    88
theorem inorder_insert:
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    89
  "sorted(inorder t) \<Longrightarrow> inorder(insert x t) = ins_list x (inorder t)"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    90
by (induct t) 
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    91
   (auto simp: ins_list_simps inorder_balL inorder_balR)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    92
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    93
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    94
subsubsection "Proofs for delete"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    95
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    96
lemma inorder_split_maxD:
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    97
  "\<lbrakk> split_max t = (t',a); t \<noteq> Leaf \<rbrakk> \<Longrightarrow>
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    98
   inorder t' @ [a] = inorder t"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
    99
by(induction t arbitrary: t' rule: split_max.induct)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   100
  (auto simp: inorder_balL split: if_splits prod.splits tree.split)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   101
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   102
theorem inorder_delete:
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   103
  "sorted(inorder t) \<Longrightarrow> inorder (delete x t) = del_list x (inorder t)"
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   104
by(induction t)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   105
  (auto simp: del_list_simps inorder_balL inorder_balR inorder_split_maxD split: prod.splits)
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   106
8ad9b2d3dd81 split AVL_Set.thy
nipkow
parents:
diff changeset
   107
end