src/HOL/Data_Structures/Splay_Map.thy
author wenzelm
Wed, 04 Nov 2015 23:27:00 +0100
changeset 61578 6623c81cb15a
parent 61525 87244a9cfe40
child 61581 00d9682e8dd7
permissions -rw-r--r--
avoid ligatures;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
61525
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     1
(* Author: Tobias Nipkow *)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     2
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     3
section "Splay Tree Implementation of Maps"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     4
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     5
theory Splay_Map
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     6
imports
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     7
  Splay_Set
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     8
  Map_by_Ordered
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
     9
begin
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    10
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    11
function splay :: "'a::linorder \<Rightarrow> ('a*'b) tree \<Rightarrow> ('a*'b) tree" where
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    12
"splay x Leaf = Leaf" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    13
"x = fst a \<Longrightarrow> splay x (Node t1 a t2) = Node t1 a t2" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    14
"x = fst a \<Longrightarrow> x < fst b \<Longrightarrow> splay x (Node (Node t1 a t2) b t3) = Node t1 a (Node t2 b t3)" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    15
"x < fst a \<Longrightarrow> splay x (Node Leaf a t) = Node Leaf a t" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    16
"x < fst a \<Longrightarrow> x < fst b \<Longrightarrow> splay x (Node (Node Leaf a t1) b t2) = Node Leaf a (Node t1 b t2)" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    17
"x < fst a \<Longrightarrow> x < fst b \<Longrightarrow> t1 \<noteq> Leaf \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    18
 splay x (Node (Node t1 a t2) b t3) =
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    19
 (case splay x t1 of Node t11 y t12 \<Rightarrow> Node t11 y (Node t12 a (Node t2 b t3)))" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    20
"fst a < x \<Longrightarrow> x < fst b \<Longrightarrow> splay x (Node (Node t1 a Leaf) b t2) = Node t1 a (Node Leaf b t2)" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    21
"fst a < x \<Longrightarrow> x < fst b \<Longrightarrow> t2 \<noteq> Leaf \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    22
 splay x (Node (Node t1 a t2) b t3) =
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    23
 (case splay x t2 of Node t21 y t22 \<Rightarrow> Node (Node t1 a t21) y (Node t22 b t3))" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    24
"fst a < x \<Longrightarrow> x = fst b \<Longrightarrow> splay x (Node t1 a (Node t2 b t3)) = Node (Node t1 a t2) b t3" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    25
"fst a < x \<Longrightarrow> splay x (Node t a Leaf) = Node t a Leaf" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    26
"fst a < x \<Longrightarrow> x < fst b \<Longrightarrow>  t2 \<noteq> Leaf \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    27
 splay x (Node t1 a (Node t2 b t3)) =
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    28
 (case splay x t2 of Node t21 y t22 \<Rightarrow> Node (Node t1 a t21) y (Node t22 b t3))" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    29
"fst a < x \<Longrightarrow> x < fst b \<Longrightarrow> splay x (Node t1 a (Node Leaf b t2)) = Node (Node t1 a Leaf) b t2" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    30
"fst a < x \<Longrightarrow> fst b < x \<Longrightarrow> splay x (Node t1 a (Node t2 b Leaf)) = Node (Node t1 a t2) b Leaf" |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    31
"fst a < x \<Longrightarrow> fst b < x \<Longrightarrow> t3 \<noteq> Leaf \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    32
 splay x (Node t1 a (Node t2 b t3)) =
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    33
 (case splay x t3 of Node t31 y t32 \<Rightarrow> Node (Node (Node t1 a t2) b t31) y t32)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    34
apply(atomize_elim)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    35
apply(auto)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    36
(* 1 subgoal *)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    37
apply (subst (asm) neq_Leaf_iff)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    38
apply(auto)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    39
apply (metis tree.exhaust surj_pair less_linear)+
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    40
done
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    41
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    42
termination splay
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    43
by lexicographic_order
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    44
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    45
lemma splay_code: "splay x t = (case t of Leaf \<Rightarrow> Leaf |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    46
  Node al a ar \<Rightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    47
  (if x = fst a then t else
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    48
   if x < fst a then
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    49
     case al of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    50
       Leaf \<Rightarrow> t |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    51
       Node bl b br \<Rightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    52
         (if x = fst b then Node bl b (Node br a ar) else
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    53
          if x < fst b then
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    54
            if bl = Leaf then Node bl b (Node br a ar)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    55
            else case splay x bl of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    56
                   Node bll y blr \<Rightarrow> Node bll y (Node blr b (Node br a ar))
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    57
          else
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    58
          if br = Leaf then Node bl b (Node br a ar)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    59
          else case splay x br of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    60
                 Node brl y brr \<Rightarrow> Node (Node bl b brl) y (Node brr a ar))
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    61
   else
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    62
   case ar of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    63
     Leaf \<Rightarrow> t |
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    64
     Node bl b br \<Rightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    65
       (if x = fst b then Node (Node al a bl) b br else
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    66
        if x < fst b then
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    67
          if bl = Leaf then Node (Node al a bl) b br
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    68
          else case splay x bl of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    69
                 Node bll y blr \<Rightarrow> Node (Node al a bll) y (Node blr b br)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    70
        else if br=Leaf then Node (Node al a bl) b br
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    71
             else case splay x br of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    72
                    Node bll y blr \<Rightarrow> Node (Node (Node al a bl) b bll) y blr)))"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    73
by(auto split: tree.split)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    74
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    75
definition lookup :: "('a*'b)tree \<Rightarrow> 'a::linorder \<Rightarrow> 'b option" where "lookup t x =
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    76
  (case splay x t of Leaf \<Rightarrow> None | Node _ (a,b) _ \<Rightarrow> if x=a then Some b else None)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    77
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    78
hide_const (open) insert
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    79
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    80
fun update :: "'a::linorder \<Rightarrow> 'b \<Rightarrow> ('a*'b) tree \<Rightarrow> ('a*'b) tree" where
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    81
"update x y t =  (if t = Leaf then Node Leaf (x,y) Leaf
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    82
  else case splay x t of
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    83
    Node l a r \<Rightarrow> if x = fst a then Node l (x,y) r
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    84
      else if x < fst a then Node l (x,y) (Node Leaf a r) else Node (Node l a Leaf) (x,y) r)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    85
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    86
definition delete :: "'a::linorder \<Rightarrow> ('a*'b) tree \<Rightarrow> ('a*'b) tree" where
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    87
"delete x t = (if t = Leaf then Leaf
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    88
  else case splay x t of Node l a r \<Rightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    89
    if x = fst a
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    90
    then if l = Leaf then r else case splay_max l of Node l' m r' \<Rightarrow> Node l' m r
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    91
    else Node l a r)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    92
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    93
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    94
subsection "Functional Correctness Proofs"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    95
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    96
lemma splay_Leaf_iff: "(splay x t = Leaf) = (t = Leaf)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    97
by(induction x t rule: splay.induct) (auto split: tree.splits)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    98
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
    99
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   100
subsubsection "Proofs for lookup"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   101
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   102
lemma splay_map_of_inorder:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   103
  "splay x t = Node l a r \<Longrightarrow> sorted1(inorder t) \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   104
   map_of (inorder t) x = (if x = fst a then Some(snd a) else None)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   105
by(induction x t arbitrary: l a r rule: splay.induct)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   106
  (auto simp: map_of_simps splay_Leaf_iff split: tree.splits)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   107
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   108
lemma lookup_eq:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   109
  "sorted1(inorder t) \<Longrightarrow> lookup t x = map_of (inorder t) x"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   110
by(auto simp: lookup_def splay_Leaf_iff splay_map_of_inorder split: tree.split)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   111
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   112
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   113
subsubsection "Proofs for update"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   114
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   115
lemma inorder_splay: "inorder(splay x t) = inorder t"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   116
by(induction x t rule: splay.induct)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   117
  (auto simp: neq_Leaf_iff split: tree.split)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   118
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   119
lemma sorted_splay:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   120
  "sorted1(inorder t) \<Longrightarrow> splay x t = Node l a r \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   121
  sorted(map fst (inorder l) @ x # map fst (inorder r))"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   122
unfolding inorder_splay[of x t, symmetric]
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   123
by(induction x t arbitrary: l a r rule: splay.induct)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   124
  (auto simp: sorted_lems sorted_Cons_le sorted_snoc_le splay_Leaf_iff split: tree.splits)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   125
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   126
(* more upd_list lemmas; unify with basic set? *)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   127
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   128
lemma upd_list_Cons:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   129
  "sorted1 ((x,y) # xs) \<Longrightarrow> upd_list x y xs = (x,y) # xs"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   130
by (induction xs) auto
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   131
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   132
lemma upd_list_snoc:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   133
  "sorted1 (xs @ [(x,y)]) \<Longrightarrow> upd_list x y xs = xs @ [(x,y)]"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   134
by(induction xs) (auto simp add: sorted_mid_iff2)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   135
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   136
lemma inorder_update:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   137
  "sorted1(inorder t) \<Longrightarrow> inorder(update x y t) = upd_list x y (inorder t)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   138
using inorder_splay[of x t, symmetric] sorted_splay[of t x]
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   139
by(auto simp: upd_list_simps upd_list_Cons upd_list_snoc neq_Leaf_iff split: tree.split)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   140
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   141
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   142
subsubsection "Proofs for delete"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   143
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   144
(* more del_simp lemmas; unify with basic set? *)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   145
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   146
lemma del_list_notin_Cons: "sorted (x # map fst xs) \<Longrightarrow> del_list x xs = xs"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   147
by(induction xs)(auto simp: sorted_Cons_iff)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   148
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   149
lemma del_list_sorted_app:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   150
  "sorted(map fst xs @ [x]) \<Longrightarrow> del_list x (xs @ ys) = xs @ del_list x ys"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   151
by (induction xs) (auto simp: sorted_mid_iff2)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   152
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   153
lemma inorder_splay_maxD:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   154
  "splay_max t = Node l a r \<Longrightarrow> sorted1(inorder t) \<Longrightarrow>
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   155
  inorder l @ [a] = inorder t \<and> r = Leaf"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   156
by(induction t arbitrary: l a r rule: splay_max.induct)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   157
  (auto simp: sorted_lems splay_max_Leaf_iff split: tree.splits if_splits)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   158
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   159
lemma inorder_delete:
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   160
  "sorted1(inorder t) \<Longrightarrow> inorder(delete x t) = del_list x (inorder t)"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   161
using inorder_splay[of x t, symmetric] sorted_splay[of t x]
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   162
by (auto simp: del_list_simps del_list_sorted_app delete_def
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   163
  del_list_notin_Cons inorder_splay_maxD splay_Leaf_iff splay_max_Leaf_iff
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   164
  split: tree.splits)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   165
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   166
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   167
subsubsection "Overall Correctness"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   168
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   169
interpretation Map_by_Ordered
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   170
where empty = Leaf and lookup = lookup and update = update
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   171
and delete = delete and inorder = inorder and wf = "\<lambda>_. True"
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   172
proof (standard, goal_cases)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   173
  case 2 thus ?case by(simp add: lookup_eq)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   174
next
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   175
  case 3 thus ?case by(simp add: inorder_update del: update.simps)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   176
next
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   177
  case 4 thus ?case by(simp add: inorder_delete)
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   178
qed auto
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   179
87244a9cfe40 added splay trees
nipkow
parents:
diff changeset
   180
end