src/HOL/Data_Structures/Tries_Binary.thy
author nipkow
Thu, 09 May 2019 12:32:47 +0200
changeset 70250 20d819b0a29d
child 70267 9fa2cf7142b7
permissions -rw-r--r--
New version of tries
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
70250
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     1
(* Author: Tobias Nipkow *)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     2
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     3
section "Binary Tries and Patricia Tries"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     4
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     5
theory Tries_Binary
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     6
imports Set_Specs
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     7
begin
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     8
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
     9
hide_const (open) insert
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    10
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    11
declare Let_def[simp]
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    12
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    13
fun sel2 :: "bool \<Rightarrow> 'a * 'a \<Rightarrow> 'a" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    14
"sel2 b (a1,a2) = (if b then a2 else a1)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    15
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    16
fun mod2 :: "('a \<Rightarrow> 'a) \<Rightarrow> bool \<Rightarrow> 'a * 'a \<Rightarrow> 'a * 'a" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    17
"mod2 f b (a1,a2) = (if b then (a1,f a2) else (f a1,a2))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    18
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    19
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    20
subsection "Trie"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    21
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    22
datatype trie = Lf | Nd bool "trie * trie"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    23
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    24
fun isin :: "trie \<Rightarrow> bool list \<Rightarrow> bool" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    25
"isin Lf ks = False" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    26
"isin (Nd b lr) ks =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    27
   (case ks of
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    28
      [] \<Rightarrow> b |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    29
      k#ks \<Rightarrow> isin (sel2 k lr) ks)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    30
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    31
fun insert :: "bool list \<Rightarrow> trie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    32
"insert [] Lf = Nd True (Lf,Lf)" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    33
"insert [] (Nd b lr) = Nd True lr" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    34
"insert (k#ks) Lf = Nd False (mod2 (insert ks) k (Lf,Lf))" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    35
"insert (k#ks) (Nd b lr) = Nd b (mod2 (insert ks) k lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    36
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    37
lemma isin_insert: "isin (insert as t) bs = (as = bs \<or> isin t bs)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    38
apply(induction as t arbitrary: bs rule: insert.induct)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    39
apply (auto split: list.splits if_splits)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    40
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    41
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    42
text \<open>A simple implementation of delete; does not shrink the trie!\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    43
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    44
fun delete0 :: "bool list \<Rightarrow> trie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    45
"delete0 ks Lf = Lf" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    46
"delete0 ks (Nd b lr) =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    47
   (case ks of
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    48
      [] \<Rightarrow> Nd False lr |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    49
      k#ks' \<Rightarrow> Nd b (mod2 (delete0 ks') k lr))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    50
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    51
lemma isin_delete0: "isin (delete0 as t) bs = (as \<noteq> bs \<and> isin t bs)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    52
apply(induction as t arbitrary: bs rule: delete0.induct)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    53
apply (auto split: list.splits if_splits)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    54
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    55
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    56
text \<open>Now deletion with shrinking:\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    57
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    58
fun node :: "bool \<Rightarrow> trie * trie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    59
"node b lr = (if \<not> b \<and> lr = (Lf,Lf) then Lf else Nd b lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    60
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    61
fun delete :: "bool list \<Rightarrow> trie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    62
"delete ks Lf = Lf" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    63
"delete ks (Nd b lr) =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    64
   (case ks of
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    65
      [] \<Rightarrow> node False lr |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    66
      k#ks' \<Rightarrow> node b (mod2 (delete ks') k lr))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    67
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    68
lemma isin_delete: "isin (delete as t) bs = (as \<noteq> bs \<and> isin t bs)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    69
apply(induction as t arbitrary: bs rule: delete.induct)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    70
 apply simp
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    71
apply (auto split: list.splits if_splits)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    72
  apply (metis isin.simps(1))
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    73
 apply (metis isin.simps(1))
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    74
  done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    75
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    76
definition set_trie :: "trie \<Rightarrow> bool list set" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    77
"set_trie t = {xs. isin t xs}"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    78
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    79
lemma set_trie_insert: "set_trie(insert xs t) = set_trie t \<union> {xs}"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    80
by(auto simp add: isin_insert set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    81
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    82
interpretation S: Set
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    83
where empty = Lf and isin = isin and insert = insert and delete = delete
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    84
and set = set_trie and invar = "\<lambda>t. True"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    85
proof (standard, goal_cases)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    86
  case 1 show ?case by (simp add: set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    87
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    88
  case 2 thus ?case by(simp add: set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    89
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    90
  case 3 thus ?case by(auto simp: set_trie_insert)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    91
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    92
  case 4 thus ?case by(auto simp: isin_delete set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    93
qed (rule TrueI)+
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    94
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    95
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    96
subsection "Patricia Trie"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    97
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    98
datatype ptrie = LfP | NdP "bool list" bool "ptrie * ptrie"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
    99
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   100
fun isinP :: "ptrie \<Rightarrow> bool list \<Rightarrow> bool" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   101
"isinP LfP ks = False" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   102
"isinP (NdP ps b lr) ks =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   103
  (let n = length ps in
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   104
   if ps = take n ks
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   105
   then case drop n ks of [] \<Rightarrow> b | k#ks' \<Rightarrow> isinP (sel2 k lr) ks'
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   106
   else False)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   107
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   108
fun split where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   109
"split [] ys = ([],[],ys)" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   110
"split xs [] = ([],xs,[])" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   111
"split (x#xs) (y#ys) =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   112
  (if x\<noteq>y then ([],x#xs,y#ys)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   113
   else let (ps,xs',ys') = split xs ys in (x#ps,xs',ys'))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   114
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   115
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   116
lemma mod2_cong[fundef_cong]:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   117
  "\<lbrakk> lr = lr'; k = k'; \<And>a b. lr'=(a,b) \<Longrightarrow> f (a) = f' (a) ; \<And>a b. lr'=(a,b) \<Longrightarrow> f (b) = f' (b) \<rbrakk>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   118
  \<Longrightarrow> mod2 f k lr= mod2 f' k' lr'"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   119
by(cases lr, cases lr', auto)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   120
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   121
fun insertP :: "bool list \<Rightarrow> ptrie \<Rightarrow> ptrie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   122
"insertP ks LfP  = NdP ks True (LfP,LfP)" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   123
"insertP ks (NdP ps b lr) =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   124
  (case split ks ps of
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   125
     (qs,k#ks',p#ps') \<Rightarrow>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   126
       let tp = NdP ps' b lr; tk = NdP ks' True (LfP,LfP) in
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   127
       NdP qs False (if k then (tp,tk) else (tk,tp)) |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   128
     (qs,k#ks',[]) \<Rightarrow>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   129
       NdP ps b (mod2 (insertP ks') k lr) |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   130
     (qs,[],p#ps') \<Rightarrow>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   131
       let t = NdP ps' b lr in
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   132
       NdP qs True (if p then (LfP,t) else (t,LfP)) |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   133
     (qs,[],[]) \<Rightarrow> NdP ps True lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   134
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   135
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   136
fun nodeP :: "bool list \<Rightarrow> bool \<Rightarrow> ptrie * ptrie \<Rightarrow> ptrie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   137
"nodeP ps b lr = (if \<not> b \<and> lr = (LfP,LfP) then LfP else NdP ps b lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   138
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   139
fun deleteP :: "bool list \<Rightarrow> ptrie \<Rightarrow> ptrie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   140
"deleteP ks LfP  = LfP" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   141
"deleteP ks (NdP ps b lr) =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   142
  (case split ks ps of
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   143
     (qs,ks',p#ps') \<Rightarrow> NdP ps b lr |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   144
     (qs,k#ks',[]) \<Rightarrow> nodeP ps b (mod2 (deleteP ks') k lr) |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   145
     (qs,[],[]) \<Rightarrow> nodeP ps False lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   146
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   147
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   148
subsubsection \<open>Functional Correctness\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   149
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   150
text \<open>First step: @{typ ptrie} implements @{typ trie} via the abstraction function \<open>abs_ptrie\<close>:\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   151
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   152
fun prefix_trie :: "bool list \<Rightarrow> trie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   153
"prefix_trie [] t = t" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   154
"prefix_trie (k#ks) t =
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   155
  (let t' = prefix_trie ks t in Nd False (if k then (Lf,t') else (t',Lf)))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   156
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   157
fun abs_ptrie :: "ptrie \<Rightarrow> trie" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   158
"abs_ptrie LfP = Lf" |
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   159
"abs_ptrie (NdP ps b (l,r)) = prefix_trie ps (Nd b (abs_ptrie l, abs_ptrie r))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   160
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   161
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   162
text \<open>Correctness of @{const isinP}:\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   163
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   164
lemma isin_prefix_trie:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   165
  "isin (prefix_trie ps t) ks
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   166
   = (ps = take (length ps) ks \<and> isin t (drop (length ps) ks))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   167
apply(induction ps arbitrary: ks)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   168
apply(auto split: list.split)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   169
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   170
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   171
lemma isinP:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   172
  "isinP t ks = isin (abs_ptrie t) ks"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   173
apply(induction t arbitrary: ks rule: abs_ptrie.induct)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   174
 apply(auto simp: isin_prefix_trie split: list.split)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   175
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   176
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   177
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   178
text \<open>Correctness of @{const insertP}:\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   179
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   180
lemma prefix_trie_Lfs: "prefix_trie ks (Nd True (Lf,Lf)) = insert ks Lf"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   181
apply(induction ks)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   182
apply auto
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   183
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   184
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   185
lemma insert_prefix_trie_same:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   186
  "insert ps (prefix_trie ps (Nd b lr)) = prefix_trie ps (Nd True lr)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   187
apply(induction ps)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   188
apply auto
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   189
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   190
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   191
lemma insert_append: "insert (ks @ ks') (prefix_trie ks t) = prefix_trie ks (insert ks' t)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   192
apply(induction ks)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   193
apply auto
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   194
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   195
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   196
lemma prefix_trie_append: "prefix_trie (ps @ qs) t = prefix_trie ps (prefix_trie qs t)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   197
apply(induction ps)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   198
apply auto
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   199
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   200
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   201
lemma split_if: "split ks ps = (qs, ks', ps') \<Longrightarrow>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   202
  ks = qs @ ks' \<and> ps = qs @ ps' \<and> (ks' \<noteq> [] \<and> ps' \<noteq> [] \<longrightarrow> hd ks' \<noteq> hd ps')"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   203
apply(induction ks ps arbitrary: qs ks' ps' rule: split.induct)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   204
apply(auto split: prod.splits if_splits)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   205
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   206
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   207
lemma abs_ptrie_insertP:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   208
  "abs_ptrie (insertP ks t) = insert ks (abs_ptrie t)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   209
apply(induction t arbitrary: ks)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   210
apply(auto simp: prefix_trie_Lfs insert_prefix_trie_same insert_append prefix_trie_append
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   211
           dest!: split_if split: list.split prod.split if_splits)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   212
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   213
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   214
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   215
text \<open>Correctness of @{const deleteP}:\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   216
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   217
lemma prefix_trie_Lf: "prefix_trie xs t = Lf \<longleftrightarrow> xs = [] \<and> t = Lf"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   218
by(cases xs)(auto)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   219
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   220
lemma abs_ptrie_Lf: "abs_ptrie t = Lf \<longleftrightarrow> t = LfP"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   221
by(cases t) (auto simp: prefix_trie_Lf)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   222
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   223
lemma delete_prefix_trie:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   224
  "delete xs (prefix_trie xs (Nd b (l,r)))
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   225
   = (if (l,r) = (Lf,Lf) then Lf else prefix_trie xs (Nd False (l,r)))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   226
by(induction xs)(auto simp: prefix_trie_Lf)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   227
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   228
lemma delete_append_prefix_trie:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   229
  "delete (xs @ ys) (prefix_trie xs t)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   230
   = (if delete ys t = Lf then Lf else prefix_trie xs (delete ys t))"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   231
by(induction xs)(auto simp: prefix_trie_Lf)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   232
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   233
lemma delete_abs_ptrie:
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   234
  "delete ks (abs_ptrie t) = abs_ptrie (deleteP ks t)"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   235
apply(induction t arbitrary: ks)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   236
apply(auto simp: delete_prefix_trie delete_append_prefix_trie
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   237
        prefix_trie_append prefix_trie_Lf abs_ptrie_Lf
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   238
        dest!: split_if split: if_splits list.split prod.split)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   239
done
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   240
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   241
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   242
text \<open>The overall correctness proof. Simply composes correctness lemmas.\<close>
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   243
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   244
definition set_ptrie :: "ptrie \<Rightarrow> bool list set" where
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   245
"set_ptrie = set_trie o abs_ptrie"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   246
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   247
lemma set_ptrie_insertP: "set_ptrie (insertP xs t) = set_ptrie t \<union> {xs}"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   248
by(simp add: abs_ptrie_insertP set_trie_insert set_ptrie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   249
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   250
interpretation SP: Set
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   251
where empty = LfP and isin = isinP and insert = insertP and delete = deleteP
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   252
and set = set_ptrie and invar = "\<lambda>t. True"
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   253
proof (standard, goal_cases)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   254
  case 1 show ?case by (simp add: set_ptrie_def set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   255
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   256
  case 2 thus ?case by(simp add: isinP set_ptrie_def set_trie_def)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   257
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   258
  case 3 thus ?case by (auto simp: set_ptrie_insertP)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   259
next
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   260
  case 4 thus ?case
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   261
    by(auto simp: isin_delete set_ptrie_def set_trie_def simp flip: delete_abs_ptrie)
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   262
qed (rule TrueI)+
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   263
20d819b0a29d New version of tries
nipkow
parents:
diff changeset
   264
end