src/HOL/Data_Structures/Interval_Tree.thy
author nipkow
Tue, 04 Feb 2020 16:36:49 +0100
changeset 71416 6a1c1d1ce6ae
parent 71415 63b2789259e7
child 72586 e3ba2578ad9d
permissions -rw-r--r--
tuned
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     1
(* Author: Bohua Zhan, with modifications by Tobias Nipkow *)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     2
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     3
section \<open>Interval Trees\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     4
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     5
theory Interval_Tree
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     6
imports
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     7
  "HOL-Data_Structures.Cmp"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     8
  "HOL-Data_Structures.List_Ins_Del"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
     9
  "HOL-Data_Structures.Isin2"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    10
  "HOL-Data_Structures.Set_Specs"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    11
begin
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    12
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    13
subsection \<open>Intervals\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    14
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    15
text \<open>The following definition of intervals uses the \<^bold>\<open>typedef\<close> command
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    16
to define the type of non-empty intervals as a subset of the type of pairs \<open>p\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    17
where @{prop "fst p \<le> snd p"}:\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    18
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    19
typedef (overloaded) 'a::linorder ivl =
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    20
  "{p :: 'a \<times> 'a. fst p \<le> snd p}" by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    21
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    22
text \<open>More precisely, @{typ "'a ivl"} is isomorphic with that subset via the function
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    23
@{const Rep_ivl}. Hence the basic interval properties are not immediate but
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    24
need simple proofs:\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    25
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    26
definition low :: "'a::linorder ivl \<Rightarrow> 'a" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    27
"low p = fst (Rep_ivl p)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    28
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    29
definition high :: "'a::linorder ivl \<Rightarrow> 'a" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    30
"high p = snd (Rep_ivl p)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    31
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    32
lemma ivl_is_interval: "low p \<le> high p"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    33
by (metis Rep_ivl high_def low_def mem_Collect_eq)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    34
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    35
lemma ivl_inj: "low p = low q \<Longrightarrow> high p = high q \<Longrightarrow> p = q"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    36
by (metis Rep_ivl_inverse high_def low_def prod_eqI)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    37
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    38
text \<open>Now we can forget how exactly intervals were defined.\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    39
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    40
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    41
instantiation ivl :: (linorder) linorder begin
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    42
71415
nipkow
parents: 71414
diff changeset
    43
definition ivl_less: "(x < y) = (low x < low y | (low x = low y \<and> high x < high y))"
nipkow
parents: 71414
diff changeset
    44
definition ivl_less_eq: "(x \<le> y) = (low x < low y | (low x = low y \<and> high x \<le> high y))"
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    45
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    46
instance proof
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    47
  fix x y z :: "'a ivl"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    48
  show a: "(x < y) = (x \<le> y \<and> \<not> y \<le> x)"
71415
nipkow
parents: 71414
diff changeset
    49
    using ivl_less ivl_less_eq by force
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    50
  show b: "x \<le> x"
71415
nipkow
parents: 71414
diff changeset
    51
    by (simp add: ivl_less_eq)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    52
  show c: "x \<le> y \<Longrightarrow> y \<le> z \<Longrightarrow> x \<le> z"
71415
nipkow
parents: 71414
diff changeset
    53
    by (smt ivl_less_eq dual_order.trans less_trans)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    54
  show d: "x \<le> y \<Longrightarrow> y \<le> x \<Longrightarrow> x = y"
71415
nipkow
parents: 71414
diff changeset
    55
    using ivl_less_eq a ivl_inj ivl_less by fastforce
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    56
  show e: "x \<le> y \<or> y \<le> x"
71415
nipkow
parents: 71414
diff changeset
    57
    by (meson ivl_less_eq leI not_less_iff_gr_or_eq)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    58
qed end
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    59
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    60
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    61
definition overlap :: "('a::linorder) ivl \<Rightarrow> 'a ivl \<Rightarrow> bool" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    62
"overlap x y \<longleftrightarrow> (high x \<ge> low y \<and> high y \<ge> low x)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    63
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    64
definition has_overlap :: "('a::linorder) ivl set \<Rightarrow> 'a ivl \<Rightarrow> bool" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    65
"has_overlap S y \<longleftrightarrow> (\<exists>x\<in>S. overlap x y)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    66
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    67
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    68
subsection \<open>Interval Trees\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    69
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    70
type_synonym 'a ivl_tree = "('a ivl * 'a) tree"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    71
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    72
fun max_hi :: "('a::order_bot) ivl_tree \<Rightarrow> 'a" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    73
"max_hi Leaf = bot" |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    74
"max_hi (Node _ (_,m) _) = m"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    75
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    76
definition max3 :: "('a::linorder) ivl \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> 'a" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    77
"max3 a m n = max (high a) (max m n)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    78
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    79
fun inv_max_hi :: "('a::{linorder,order_bot}) ivl_tree \<Rightarrow> bool" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    80
"inv_max_hi Leaf \<longleftrightarrow> True" |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    81
"inv_max_hi (Node l (a, m) r) \<longleftrightarrow> (inv_max_hi l \<and> inv_max_hi r \<and> m = max3 a (max_hi l) (max_hi r))"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    82
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    83
lemma max_hi_is_max:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    84
  "inv_max_hi t \<Longrightarrow> a \<in> set_tree t \<Longrightarrow> high a \<le> max_hi t"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    85
by (induct t, auto simp add: max3_def max_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    86
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    87
lemma max_hi_exists:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    88
  "inv_max_hi t \<Longrightarrow> t \<noteq> Leaf \<Longrightarrow> \<exists>a\<in>set_tree t. high a = max_hi t"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    89
proof (induction t rule: tree2_induct)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    90
  case Leaf
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    91
  then show ?case by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    92
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    93
  case N: (Node l v m r)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    94
  then show ?case
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    95
  proof (cases l rule: tree2_cases)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    96
    case Leaf
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    97
    then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    98
      using N.prems(1) N.IH(2) by (cases r, auto simp add: max3_def max_def le_bot)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
    99
  next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   100
    case Nl: Node
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   101
    then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   102
    proof (cases r rule: tree2_cases)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   103
      case Leaf
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   104
      then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   105
        using N.prems(1) N.IH(1) Nl by (auto simp add: max3_def max_def le_bot)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   106
    next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   107
      case Nr: Node
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   108
      obtain p1 where p1: "p1 \<in> set_tree l" "high p1 = max_hi l"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   109
        using N.IH(1) N.prems(1) Nl by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   110
      obtain p2 where p2: "p2 \<in> set_tree r" "high p2 = max_hi r"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   111
        using N.IH(2) N.prems(1) Nr by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   112
      then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   113
        using p1 p2 N.prems(1) by (auto simp add: max3_def max_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   114
    qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   115
  qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   116
qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   117
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   118
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   119
subsection \<open>Insertion and Deletion\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   120
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   121
definition node where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   122
[simp]: "node l a r = Node l (a, max3 a (max_hi l) (max_hi r)) r"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   123
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   124
fun insert :: "'a::{linorder,order_bot} ivl \<Rightarrow> 'a ivl_tree \<Rightarrow> 'a ivl_tree" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   125
"insert x Leaf = Node Leaf (x, high x) Leaf" |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   126
"insert x (Node l (a, m) r) =
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   127
  (case cmp x a of
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   128
     EQ \<Rightarrow> Node l (a, m) r |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   129
     LT \<Rightarrow> node (insert x l) a r |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   130
     GT \<Rightarrow> node l a (insert x r))"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   131
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   132
lemma inorder_insert:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   133
  "sorted (inorder t) \<Longrightarrow> inorder (insert x t) = ins_list x (inorder t)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   134
by (induct t rule: tree2_induct) (auto simp: ins_list_simps)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   135
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   136
lemma inv_max_hi_insert:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   137
  "inv_max_hi t \<Longrightarrow> inv_max_hi (insert x t)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   138
by (induct t rule: tree2_induct) (auto simp add: max3_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   139
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   140
fun split_min :: "'a::{linorder,order_bot} ivl_tree \<Rightarrow> 'a ivl \<times> 'a ivl_tree" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   141
"split_min (Node l (a, m) r) =
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   142
  (if l = Leaf then (a, r)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   143
   else let (x,l') = split_min l in (x, node l' a r))"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   144
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   145
fun delete :: "'a::{linorder,order_bot} ivl \<Rightarrow> 'a ivl_tree \<Rightarrow> 'a ivl_tree" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   146
"delete x Leaf = Leaf" |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   147
"delete x (Node l (a, m) r) =
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   148
  (case cmp x a of
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   149
     LT \<Rightarrow> node (delete x l) a r |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   150
     GT \<Rightarrow> node l a (delete x r) |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   151
     EQ \<Rightarrow> if r = Leaf then l else
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   152
           let (a', r') = split_min r in node l a' r')"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   153
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   154
lemma split_minD:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   155
  "split_min t = (x,t') \<Longrightarrow> t \<noteq> Leaf \<Longrightarrow> x # inorder t' = inorder t"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   156
by (induct t arbitrary: t' rule: split_min.induct)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   157
   (auto simp: sorted_lems split: prod.splits if_splits)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   158
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   159
lemma inorder_delete:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   160
  "sorted (inorder t) \<Longrightarrow> inorder (delete x t) = del_list x (inorder t)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   161
by (induct t)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   162
   (auto simp: del_list_simps split_minD Let_def split: prod.splits)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   163
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   164
lemma inv_max_hi_split_min:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   165
  "\<lbrakk> t \<noteq> Leaf;  inv_max_hi t \<rbrakk> \<Longrightarrow> inv_max_hi (snd (split_min t))"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   166
by (induct t) (auto split: prod.splits)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   167
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   168
lemma inv_max_hi_delete:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   169
  "inv_max_hi t \<Longrightarrow> inv_max_hi (delete x t)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   170
apply (induct t)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   171
 apply simp
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   172
using inv_max_hi_split_min by (fastforce simp add: Let_def split: prod.splits)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   173
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   174
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   175
subsection \<open>Search\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   176
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   177
text \<open>Does interval \<open>x\<close> overlap with any interval in the tree?\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   178
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   179
fun search :: "'a::{linorder,order_bot} ivl_tree \<Rightarrow> 'a ivl \<Rightarrow> bool" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   180
"search Leaf x = False" |
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   181
"search (Node l (a, m) r) x =
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   182
  (if overlap x a then True
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   183
   else if l \<noteq> Leaf \<and> max_hi l \<ge> low x then search l x
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   184
   else search r x)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   185
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   186
lemma search_correct:
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   187
  "inv_max_hi t \<Longrightarrow> sorted (inorder t) \<Longrightarrow> search t x = has_overlap (set_tree t) x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   188
proof (induction t rule: tree2_induct)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   189
  case Leaf
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   190
  then show ?case by (auto simp add: has_overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   191
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   192
  case (Node l a m r)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   193
  have search_l: "search l x = has_overlap (set_tree l) x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   194
    using Node.IH(1) Node.prems by (auto simp: sorted_wrt_append)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   195
  have search_r: "search r x = has_overlap (set_tree r) x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   196
    using Node.IH(2) Node.prems by (auto simp: sorted_wrt_append)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   197
  show ?case
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   198
  proof (cases "overlap a x")
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   199
    case True
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   200
    thus ?thesis by (auto simp: overlap_def has_overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   201
  next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   202
    case a_disjoint: False
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   203
    then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   204
    proof cases
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   205
      assume [simp]: "l = Leaf"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   206
      have search_eval: "search (Node l (a, m) r) x = search r x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   207
        using a_disjoint overlap_def by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   208
      show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   209
        unfolding search_eval search_r
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   210
        by (auto simp add: has_overlap_def a_disjoint)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   211
    next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   212
      assume "l \<noteq> Leaf"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   213
      then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   214
      proof (cases "max_hi l \<ge> low x")
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   215
        case max_hi_l_ge: True
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   216
        have "inv_max_hi l"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   217
          using Node.prems(1) by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   218
        then obtain p where p: "p \<in> set_tree l" "high p = max_hi l"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   219
          using \<open>l \<noteq> Leaf\<close> max_hi_exists by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   220
        have search_eval: "search (Node l (a, m) r) x = search l x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   221
          using a_disjoint \<open>l \<noteq> Leaf\<close> max_hi_l_ge by (auto simp: overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   222
        show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   223
        proof (cases "low p \<le> high x")
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   224
          case True
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   225
          have "overlap p x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   226
            unfolding overlap_def using True p(2) max_hi_l_ge by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   227
          then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   228
            unfolding search_eval search_l
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   229
            using p(1) by(auto simp: has_overlap_def overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   230
        next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   231
          case False
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   232
          have "\<not>overlap x rp" if asm: "rp \<in> set_tree r" for rp
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   233
          proof -
71416
nipkow
parents: 71415
diff changeset
   234
            have "low p \<le> low rp"
nipkow
parents: 71415
diff changeset
   235
              using asm p(1) Node(4) by(fastforce simp: sorted_wrt_append ivl_less)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   236
            then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   237
              using False by (auto simp: overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   238
          qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   239
          then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   240
            unfolding search_eval search_l
71416
nipkow
parents: 71415
diff changeset
   241
            using a_disjoint by (auto simp: has_overlap_def overlap_def)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   242
        qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   243
      next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   244
        case False
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   245
        have search_eval: "search (Node l (a, m) r) x = search r x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   246
          using a_disjoint False by (auto simp: overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   247
        have "\<not>overlap x lp" if asm: "lp \<in> set_tree l" for lp
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   248
          using asm False Node.prems(1) max_hi_is_max
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   249
          by (fastforce simp: overlap_def)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   250
        then show ?thesis
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   251
          unfolding search_eval search_r
71416
nipkow
parents: 71415
diff changeset
   252
          using a_disjoint by (auto simp: has_overlap_def overlap_def)
71414
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   253
      qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   254
    qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   255
  qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   256
qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   257
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   258
definition empty :: "'a ivl_tree" where
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   259
"empty = Leaf"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   260
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   261
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   262
subsection \<open>Specification\<close>
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   263
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   264
locale Interval_Set = Set +
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   265
  fixes has_overlap :: "'t \<Rightarrow> 'a::linorder ivl \<Rightarrow> bool"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   266
  assumes set_overlap: "invar s \<Longrightarrow> has_overlap s x = Interval_Tree.has_overlap (set s) x"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   267
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   268
interpretation S: Interval_Set
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   269
  where empty = Leaf and insert = insert and delete = delete
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   270
  and has_overlap = search and isin = isin and set = set_tree
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   271
  and invar = "\<lambda>t. inv_max_hi t \<and> sorted (inorder t)"
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   272
proof (standard, goal_cases)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   273
  case 1
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   274
  then show ?case by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   275
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   276
  case 2
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   277
  then show ?case by (simp add: isin_set_inorder)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   278
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   279
  case 3
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   280
  then show ?case by(simp add: inorder_insert set_ins_list flip: set_inorder)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   281
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   282
  case 4
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   283
  then show ?case by(simp add: inorder_delete set_del_list flip: set_inorder)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   284
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   285
  case 5
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   286
  then show ?case by auto
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   287
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   288
  case 6
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   289
  then show ?case by (simp add: inorder_insert inv_max_hi_insert sorted_ins_list)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   290
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   291
  case 7
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   292
  then show ?case by (simp add: inorder_delete inv_max_hi_delete sorted_del_list)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   293
next
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   294
  case 8
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   295
  then show ?case by (simp add: search_correct)
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   296
qed
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   297
c26de1bd7b00 added Interval_Tree.thy
nipkow
parents:
diff changeset
   298
end