association lists with distinct keys uses the quotient infrastructure to obtain code certificates;
authorbulwahn
Tue, 27 Mar 2012 14:14:46 +0200
changeset 47143 212f7a975d49
parent 47133 89b13238d7f2
child 47144 9bfc32fc7ced
association lists with distinct keys uses the quotient infrastructure to obtain code certificates; added remarks about further improvements
src/HOL/Library/DAList.thy
src/HOL/Library/Multiset.thy
--- a/src/HOL/Library/DAList.thy	Mon Mar 26 21:03:30 2012 +0200
+++ b/src/HOL/Library/DAList.thy	Tue Mar 27 14:14:46 2012 +0200
@@ -9,14 +9,22 @@
 
 text {* This was based on some existing fragments in the AFP-Collection framework. *}
 
+subsection {* Preliminaries *}
+
+lemma distinct_map_fst_filter:
+   "distinct (map fst xs) ==> distinct (map fst (List.filter P xs))"
+by (induct xs) auto
+
 subsection {* Type @{text "('key, 'value) alist" } *}
 
-typedef (open) ('key, 'value) alist = "{xs :: ('key \<times> 'value) list. distinct (map fst xs)}"
+typedef (open) ('key, 'value) alist = "{xs :: ('key \<times> 'value) list. (distinct o map fst) xs}"
   morphisms impl_of Alist
 proof
-  show "[] \<in> {xs. distinct (map fst xs)}" by simp
+  show "[] \<in> {xs. (distinct o map fst) xs}" by simp
 qed
 
+setup_lifting type_definition_alist
+
 lemma alist_ext: "impl_of xs = impl_of ys \<Longrightarrow> xs = ys"
 by(simp add: impl_of_inject)
 
@@ -31,55 +39,46 @@
 
 subsection {* Primitive operations *}
 
-definition lookup :: "('key, 'value) alist \<Rightarrow> 'key \<Rightarrow> 'value option"
-where [code]: "lookup xs = map_of (impl_of xs)" 
+(* FIXME: improve quotient_definition so that type annotations on the right hand sides can be removed *) 
+
+quotient_definition lookup :: "('key, 'value) alist \<Rightarrow> 'key \<Rightarrow> 'value option"
+where "lookup" is "map_of :: ('key * 'value) list \<Rightarrow> 'key \<Rightarrow> 'value option" ..
 
-definition empty :: "('key, 'value) alist"
-where [code del]: "empty = Alist []"
+quotient_definition empty :: "('key, 'value) alist"
+where "empty" is "[] :: ('key * 'value) list" by simp
 
-definition update :: "'key \<Rightarrow> 'value \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
-where [code del]: "update k v xs = Alist (AList.update k v (impl_of xs))"
+quotient_definition update :: "'key \<Rightarrow> 'value \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
+where "update" is "AList.update :: 'key \<Rightarrow> 'value \<Rightarrow> ('key * 'value) list \<Rightarrow> ('key * 'value) list"
+by (simp add: distinct_update)
 
 (* FIXME: we use an unoptimised delete operation. *)
-definition delete :: "'key \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
-where [code del]: "delete k xs = Alist (AList.delete k (impl_of xs))"
+quotient_definition delete :: "'key \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
+where "delete" is "AList.delete :: 'key \<Rightarrow> ('key * 'value) list \<Rightarrow> ('key * 'value) list"
+by (simp add: distinct_delete)
 
-definition map_entry :: "'key \<Rightarrow> ('value \<Rightarrow> 'value) \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
-where [code del]: "map_entry k f xs = Alist (AList.map_entry k f (impl_of xs))" 
+quotient_definition map_entry :: "'key \<Rightarrow> ('value \<Rightarrow> 'value) \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
+where "map_entry" is "AList.map_entry :: 'key \<Rightarrow> ('value \<Rightarrow> 'value) \<Rightarrow> ('key * 'value) list \<Rightarrow> ('key * 'value) list"
+by (simp add: distinct_map_entry)
 
-definition filter :: "('key \<times> 'value \<Rightarrow> bool) \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
-where [code del]: "filter P xs = Alist (List.filter P (impl_of xs))"
+quotient_definition filter :: "('key \<times> 'value \<Rightarrow> bool) \<Rightarrow> ('key, 'value) alist \<Rightarrow> ('key, 'value) alist"
+where "filter" is "List.filter :: ('key \<times> 'value \<Rightarrow> bool) \<Rightarrow> ('key * 'value) list \<Rightarrow> ('key * 'value) list"
+by (simp add: distinct_map_fst_filter)
 
-definition map_default :: "'key => 'value => ('value => 'value) => ('key, 'value) alist => ('key, 'value) alist"
-where
-  "map_default k v f xs = Alist (AList.map_default k v f (impl_of xs))"
+quotient_definition map_default :: "'key => 'value => ('value => 'value) => ('key, 'value) alist => ('key, 'value) alist"
+where "map_default" is "AList.map_default :: 'key => 'value => ('value => 'value) => ('key * 'value) list => ('key * 'value) list"
+by (simp add: distinct_map_default)
 
-lemma impl_of_empty [code abstract]: "impl_of empty = []"
+(* FIXME: theorems are still used in Multiset; make code certificates available to the user *)
+lemma impl_of_empty: "impl_of empty = []"
 by (simp add: empty_def Alist_inverse)
 
-lemma impl_of_update [code abstract]: "impl_of (update k v xs) = AList.update k v (impl_of xs)"
+lemma impl_of_update: "impl_of (update k v xs) = AList.update k v (impl_of xs)"
 by (simp add: update_def Alist_inverse distinct_update)
 
-lemma impl_of_delete [code abstract]:
-  "impl_of (delete k al) = AList.delete k (impl_of al)"
-unfolding delete_def by (simp add: Alist_inverse distinct_delete)
-
-lemma impl_of_map_entry [code abstract]:
-  "impl_of (map_entry k f xs) = AList.map_entry k f (impl_of xs)"
-unfolding map_entry_def by (simp add: Alist_inverse distinct_map_entry)
-
-lemma distinct_map_fst_filter:
-   "distinct (map fst xs) ==> distinct (map fst (List.filter P xs))"
-by (induct xs) auto
-
-lemma impl_of_filter [code abstract]:
+lemma impl_of_filter:
   "impl_of (filter P xs) = List.filter P (impl_of xs)"
 unfolding filter_def by (simp add: Alist_inverse distinct_map_fst_filter)
 
-lemma impl_of_map_default [code abstract]:
-  "impl_of (map_default k v f xs) = AList.map_default k v f (impl_of xs)"
-by (auto simp add: map_default_def Alist_inverse distinct_map_default)
-
 subsection {* Abstract operation properties *}
 
 (* FIXME: to be completed *)
--- a/src/HOL/Library/Multiset.thy	Mon Mar 26 21:03:30 2012 +0200
+++ b/src/HOL/Library/Multiset.thy	Tue Mar 27 14:14:46 2012 +0200
@@ -1189,7 +1189,7 @@
 lemma Mempty_Bag [code]:
   "{#} = Bag (DAList.empty)"
   by (simp add: multiset_eq_iff alist.Alist_inverse DAList.empty_def)
-  
+
 lemma single_Bag [code]:
   "{#x#} = Bag (DAList.update x 1 DAList.empty)"
   by (simp add: multiset_eq_iff alist.Alist_inverse impl_of_update impl_of_empty)