src/HOL/Quotient_Examples/Lift_RBT.thy
changeset 47097 987cb55cac44
parent 47093 0516a6c1ea59
child 47308 9caab698dbe4
equal deleted inserted replaced
47096:3ea48c19673e 47097:987cb55cac44
     4 
     4 
     5 theory Lift_RBT 
     5 theory Lift_RBT 
     6 imports Main "~~/src/HOL/Library/RBT_Impl"
     6 imports Main "~~/src/HOL/Library/RBT_Impl"
     7 begin
     7 begin
     8 
     8 
     9 definition inv :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" 
       
    10   where [simp]: "inv R = (\<lambda>x y. R x \<and> x = y)"
       
    11 
       
    12 subsection {* Type definition *}
     9 subsection {* Type definition *}
    13 
    10 
    14 quotient_type ('a, 'b) rbt = "('a\<Colon>linorder, 'b) RBT_Impl.rbt" / "inv is_rbt" morphisms impl_of RBT
    11 typedef (open) ('a, 'b) rbt = "{t :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt. is_rbt t}"
    15 sorry
    12   morphisms impl_of RBT
       
    13 proof -
       
    14   have "RBT_Impl.Empty \<in> ?rbt" by simp
       
    15   then show ?thesis ..
       
    16 qed
    16 
    17 
    17 (*
       
    18 lemma rbt_eq_iff:
    18 lemma rbt_eq_iff:
    19   "t1 = t2 \<longleftrightarrow> impl_of t1 = impl_of t2"
    19   "t1 = t2 \<longleftrightarrow> impl_of t1 = impl_of t2"
    20   by (simp add: impl_of_inject)
    20   by (simp add: impl_of_inject)
    21 
    21 
    22 lemma rbt_eqI:
    22 lemma rbt_eqI:
    28   using impl_of [of t] by simp
    28   using impl_of [of t] by simp
    29 
    29 
    30 lemma RBT_impl_of [simp, code abstype]:
    30 lemma RBT_impl_of [simp, code abstype]:
    31   "RBT (impl_of t) = t"
    31   "RBT (impl_of t) = t"
    32   by (simp add: impl_of_inverse)
    32   by (simp add: impl_of_inverse)
    33 *)
       
    34 
    33 
    35 subsection {* Primitive operations *}
    34 subsection {* Primitive operations *}
    36 
    35 
       
    36 setup_lifting type_definition_rbt
       
    37 
    37 quotient_definition lookup where "lookup :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a \<rightharpoonup> 'b" is "RBT_Impl.lookup"
    38 quotient_definition lookup where "lookup :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a \<rightharpoonup> 'b" is "RBT_Impl.lookup"
    38 by simp
    39 by simp
    39 
       
    40 declare lookup_def[unfolded map_fun_def comp_def id_def, code]
       
    41 
    40 
    42 (* FIXME: quotient_definition at the moment requires that types variables match exactly,
    41 (* FIXME: quotient_definition at the moment requires that types variables match exactly,
    43 i.e., sort constraints must be annotated to the constant being lifted.
    42 i.e., sort constraints must be annotated to the constant being lifted.
    44 But, it should be possible to infer the necessary sort constraints, making the explicit
    43 But, it should be possible to infer the necessary sort constraints, making the explicit
    45 sort constraints unnecessary.
    44 sort constraints unnecessary.
    51 
    50 
    52 Similar issue for quotient_definition for entries, keys, map, and fold.
    51 Similar issue for quotient_definition for entries, keys, map, and fold.
    53 *)
    52 *)
    54 
    53 
    55 quotient_definition empty where "empty :: ('a\<Colon>linorder, 'b) rbt"
    54 quotient_definition empty where "empty :: ('a\<Colon>linorder, 'b) rbt"
    56 is "(RBT_Impl.Empty :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt)" done
    55 is "(RBT_Impl.Empty :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt)" by (simp add: empty_def)
    57 
       
    58 lemma impl_of_empty [code abstract]:
       
    59   "impl_of empty = RBT_Impl.Empty"
       
    60   by (simp add: empty_def RBT_inverse)
       
    61 
    56 
    62 quotient_definition insert where "insert :: 'a\<Colon>linorder \<Rightarrow> 'b \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    57 quotient_definition insert where "insert :: 'a\<Colon>linorder \<Rightarrow> 'b \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    63 is "RBT_Impl.insert" done
    58 is "RBT_Impl.insert" by simp
    64 
       
    65 lemma impl_of_insert [code abstract]:
       
    66   "impl_of (insert k v t) = RBT_Impl.insert k v (impl_of t)"
       
    67   by (simp add: insert_def RBT_inverse)
       
    68 
    59 
    69 quotient_definition delete where "delete :: 'a\<Colon>linorder \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    60 quotient_definition delete where "delete :: 'a\<Colon>linorder \<Rightarrow> ('a, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    70 is "RBT_Impl.delete" done
    61 is "RBT_Impl.delete" by simp
    71 
       
    72 lemma impl_of_delete [code abstract]:
       
    73   "impl_of (delete k t) = RBT_Impl.delete k (impl_of t)"
       
    74   by (simp add: delete_def RBT_inverse)
       
    75 
    62 
    76 (* FIXME: unnecessary type annotations *)
    63 (* FIXME: unnecessary type annotations *)
    77 quotient_definition "entries :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a \<times> 'b) list"
    64 quotient_definition "entries :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a \<times> 'b) list"
    78 is "RBT_Impl.entries :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> ('a \<times> 'b) list" done
    65 is "RBT_Impl.entries :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> ('a \<times> 'b) list" by simp
    79 
       
    80 lemma [code]: "entries t = RBT_Impl.entries (impl_of t)"
       
    81 unfolding entries_def map_fun_def comp_def id_def ..
       
    82 
    66 
    83 (* FIXME: unnecessary type annotations *)
    67 (* FIXME: unnecessary type annotations *)
    84 quotient_definition "keys :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a list"
    68 quotient_definition "keys :: ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'a list"
    85 is "RBT_Impl.keys :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> 'a list" done
    69 is "RBT_Impl.keys :: ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> 'a list" by simp
    86 
    70 
    87 quotient_definition "bulkload :: ('a\<Colon>linorder \<times> 'b) list \<Rightarrow> ('a, 'b) rbt"
    71 quotient_definition "bulkload :: ('a\<Colon>linorder \<times> 'b) list \<Rightarrow> ('a, 'b) rbt"
    88 is "RBT_Impl.bulkload" done
    72 is "RBT_Impl.bulkload" by simp
    89 
       
    90 lemma impl_of_bulkload [code abstract]:
       
    91   "impl_of (bulkload xs) = RBT_Impl.bulkload xs"
       
    92   by (simp add: bulkload_def RBT_inverse)
       
    93 
    73 
    94 quotient_definition "map_entry :: 'a \<Rightarrow> ('b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    74 quotient_definition "map_entry :: 'a \<Rightarrow> ('b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    95 is "RBT_Impl.map_entry" done
    75 is "RBT_Impl.map_entry" by simp
    96 
       
    97 lemma impl_of_map_entry [code abstract]:
       
    98   "impl_of (map_entry k f t) = RBT_Impl.map_entry k f (impl_of t)"
       
    99   by (simp add: map_entry_def RBT_inverse)
       
   100 
    76 
   101 (* FIXME: unnecesary type annotations *)
    77 (* FIXME: unnecesary type annotations *)
   102 quotient_definition map where "map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
    78 quotient_definition map where "map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> ('a, 'b) rbt"
   103 is "RBT_Impl.map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> ('a, 'b) RBT_Impl.rbt"
    79 is "RBT_Impl.map :: ('a \<Rightarrow> 'b \<Rightarrow> 'b) \<Rightarrow> ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> ('a, 'b) RBT_Impl.rbt"
   104 done
    80 by simp
   105 
       
   106 lemma impl_of_map [code abstract]:
       
   107   "impl_of (map f t) = RBT_Impl.map f (impl_of t)"
       
   108   by (simp add: map_def RBT_inverse)
       
   109 
    81 
   110 (* FIXME: unnecessary type annotations *)
    82 (* FIXME: unnecessary type annotations *)
   111 quotient_definition fold where "fold :: ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'c \<Rightarrow> 'c" 
    83 quotient_definition fold where "fold :: ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) rbt \<Rightarrow> 'c \<Rightarrow> 'c" 
   112 is "RBT_Impl.fold :: ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> 'c \<Rightarrow> 'c" done
    84 is "RBT_Impl.fold :: ('a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'c) \<Rightarrow> ('a\<Colon>linorder, 'b) RBT_Impl.rbt \<Rightarrow> 'c \<Rightarrow> 'c" by simp
   113 
    85 
   114 lemma [code]: "fold f t = RBT_Impl.fold f (impl_of t)"
    86 export_code lookup empty insert delete entries keys bulkload map_entry map fold in SML
   115 unfolding fold_def map_fun_def comp_def id_def ..
       
   116 
       
   117 
    87 
   118 subsection {* Derived operations *}
    88 subsection {* Derived operations *}
   119 
    89 
   120 definition is_empty :: "('a\<Colon>linorder, 'b) rbt \<Rightarrow> bool" where
    90 definition is_empty :: "('a\<Colon>linorder, 'b) rbt \<Rightarrow> bool" where
   121   [code]: "is_empty t = (case impl_of t of RBT_Impl.Empty \<Rightarrow> True | _ \<Rightarrow> False)"
    91   [code]: "is_empty t = (case impl_of t of RBT_Impl.Empty \<Rightarrow> True | _ \<Rightarrow> False)"
   175 
   145 
   176 lemma fold_fold:
   146 lemma fold_fold:
   177   "fold f t = List.fold (prod_case f) (entries t)"
   147   "fold f t = List.fold (prod_case f) (entries t)"
   178   by (simp add: fold_def fun_eq_iff RBT_Impl.fold_def entries_impl_of)
   148   by (simp add: fold_def fun_eq_iff RBT_Impl.fold_def entries_impl_of)
   179 
   149 
       
   150 lemma impl_of_empty:
       
   151   "impl_of empty = RBT_Impl.Empty"
       
   152   by (simp add: empty_def RBT_inverse)
       
   153 
   180 lemma is_empty_empty [simp]:
   154 lemma is_empty_empty [simp]:
   181   "is_empty t \<longleftrightarrow> t = empty"
   155   "is_empty t \<longleftrightarrow> t = empty"
   182   by (simp add: rbt_eq_iff is_empty_def impl_of_empty split: rbt.split)
   156   by (simp add: rbt_eq_iff is_empty_def impl_of_empty split: rbt.split)
   183 
   157 
   184 lemma RBT_lookup_empty [simp]: (*FIXME*)
   158 lemma RBT_lookup_empty [simp]: (*FIXME*)
   196 lemma distinct_keys [iff]:
   170 lemma distinct_keys [iff]:
   197   "distinct (keys t)"
   171   "distinct (keys t)"
   198   by (simp add: keys_def RBT_Impl.keys_def distinct_entries)
   172   by (simp add: keys_def RBT_Impl.keys_def distinct_entries)
   199 
   173 
   200 
   174 
   201 
       
   202 end
   175 end