1 (* Author: Lukas Bulwahn, TU Muenchen *)
3 header {* Lifting operations of RBT trees *}
6 imports Main "~~/src/HOL/Library/RBT_Impl"
9 subsection {* Type definition *}
11 typedef (open) ('a, 'b) rbt = "{t :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt. is_rbt t}"
14 have "RBT_Impl.Empty \<in> ?rbt" by simp
18 local_setup {* fn lthy =>
20 val quotients = {qtyp = @{typ "('a, 'b) rbt"}, rtyp = @{typ "('a, 'b) RBT_Impl.rbt"},
21 equiv_rel = @{term "dummy"}, equiv_thm = @{thm refl}}
22 val qty_full_name = @{type_name "rbt"}
24 fun qinfo phi = Quotient_Info.transform_quotients phi quotients
26 |> Local_Theory.declaration {syntax = false, pervasive = true}
27 (fn phi => Quotient_Info.update_quotients qty_full_name (qinfo phi)
28 #> Quotient_Info.update_abs_rep qty_full_name (Quotient_Info.transform_abs_rep phi
29 {abs = @{term "RBT"}, rep = @{term "impl_of"}}))
34 "t1 = t2 \<longleftrightarrow> impl_of t1 = impl_of t2"
35 by (simp add: impl_of_inject)
38 "impl_of t1 = impl_of t2 \<Longrightarrow> t1 = t2"
39 by (simp add: rbt_eq_iff)
41 lemma is_rbt_impl_of [simp, intro]:
43 using impl_of [of t] by simp
45 lemma RBT_impl_of [simp, code abstype]:
47 by (simp add: impl_of_inverse)
50 subsection {* Primitive operations *}
52 quotient_definition lookup where "lookup :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a \<rightharpoonup> 'b" is "RBT_Impl.lookup"
54 declare lookup_def[unfolded map_fun_def comp_def id_def, code]
56 (* FIXME: some bug in quotient?*)
58 quotient_definition empty where "empty :: ('a\<Colon>linorder, 'b) rbt"
62 definition empty :: "('a\<Colon>linorder, 'b) rbt" where
63 "empty = RBT RBT_Impl.Empty"
65 lemma impl_of_empty [code abstract]:
66 "impl_of empty = RBT_Impl.Empty"
67 by (simp add: empty_def RBT_inverse)
69 quotient_definition insert where "insert :: 'a\<Colon>linorder \<Rightarrow> 'b \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
72 lemma impl_of_insert [code abstract]:
73 "impl_of (insert k v t) = RBT_Impl.insert k v (impl_of t)"
74 by (simp add: insert_def RBT_inverse)
76 quotient_definition delete where "delete :: 'a\<Colon>linorder \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
79 lemma impl_of_delete [code abstract]:
80 "impl_of (delete k t) = RBT_Impl.delete k (impl_of t)"
81 by (simp add: delete_def RBT_inverse)
83 (* FIXME: bug in quotient? *)
85 quotient_definition entries where "entries :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a \<times> 'b) list"
88 definition entries :: "('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a \<times> 'b) list" where
89 [code]: "entries t = RBT_Impl.entries (impl_of t)"
91 (* FIXME: bug in quotient? *)
93 quotient_definition keys where "keys :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a list"
97 quotient_definition "bulkload :: ('a\<Colon>linorder \<times> 'b) list \<Rightarrow> ('a, 'b) rbt"
98 is "RBT_Impl.bulkload"
100 lemma impl_of_bulkload [code abstract]:
101 "impl_of (bulkload xs) = RBT_Impl.bulkload xs"
102 by (simp add: bulkload_def RBT_inverse)
104 quotient_definition "map_entry :: 'a \<Rightarrow> ('b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
105 is "RBT_Impl.map_entry"
107 lemma impl_of_map_entry [code abstract]:
108 "impl_of (map_entry k f t) = RBT_Impl.map_entry k f (impl_of t)"
109 by (simp add: map_entry_def RBT_inverse)
111 (* Another bug: map is supposed to be a new definition, not using the old one.
112 quotient_definition "map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
115 (* But this works, and then shows the other bug... *)
117 quotient_definition map where "map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
120 definition map :: "('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt" where
121 "map f t = RBT (RBT_Impl.map f (impl_of t))"
123 lemma impl_of_map [code abstract]:
124 "impl_of (map f t) = RBT_Impl.map f (impl_of t)"
125 by (simp add: map_def RBT_inverse)
127 quotient_definition fold where "fold :: ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'c \<Rightarrow> 'c" is "RBT_Impl.fold"
129 (*FIXME: definition of fold should have the code attribute. *)
131 definition fold :: "('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'c \<Rightarrow> 'c" where
132 [code]: "fold f t = RBT_Impl.fold f (impl_of t)"