src/HOL/Imperative_HOL/Array.thy
changeset 37758 bf86a65403a8
parent 37756 59caa6180fff
child 37771 1bec64044b5e
equal deleted inserted replaced
37756:59caa6180fff 37758:bf86a65403a8
    54 
    54 
    55 definition make :: "nat \<Rightarrow> (nat \<Rightarrow> 'a\<Colon>heap) \<Rightarrow> 'a array Heap" where
    55 definition make :: "nat \<Rightarrow> (nat \<Rightarrow> 'a\<Colon>heap) \<Rightarrow> 'a array Heap" where
    56   [code del]: "make n f = Heap_Monad.heap (array (map f [0 ..< n]))"
    56   [code del]: "make n f = Heap_Monad.heap (array (map f [0 ..< n]))"
    57 
    57 
    58 definition len :: "'a\<Colon>heap array \<Rightarrow> nat Heap" where
    58 definition len :: "'a\<Colon>heap array \<Rightarrow> nat Heap" where
    59   [code del]: "len a = Heap_Monad.heap (\<lambda>h. (length a h, h))"
    59   [code del]: "len a = Heap_Monad.tap (\<lambda>h. length a h)"
    60 
    60 
    61 definition nth :: "'a\<Colon>heap array \<Rightarrow> nat \<Rightarrow> 'a Heap" where
    61 definition nth :: "'a\<Colon>heap array \<Rightarrow> nat \<Rightarrow> 'a Heap" where
    62   [code del]: "nth a i = Heap_Monad.guard (\<lambda>h. i < length a h)
    62   [code del]: "nth a i = Heap_Monad.guard (\<lambda>h. i < length a h)
    63     (\<lambda>h. (get_array a h ! i, h))"
    63     (\<lambda>h. (get_array a h ! i, h))"
    64 
    64 
    73 definition swap :: "nat \<Rightarrow> 'a \<Rightarrow> 'a\<Colon>heap array \<Rightarrow> 'a Heap" where
    73 definition swap :: "nat \<Rightarrow> 'a \<Rightarrow> 'a\<Colon>heap array \<Rightarrow> 'a Heap" where
    74   [code del]: "swap i x a = Heap_Monad.guard (\<lambda>h. i < length a h)
    74   [code del]: "swap i x a = Heap_Monad.guard (\<lambda>h. i < length a h)
    75     (\<lambda>h. (get_array a h ! i, change a i x h))"
    75     (\<lambda>h. (get_array a h ! i, change a i x h))"
    76 
    76 
    77 definition freeze :: "'a\<Colon>heap array \<Rightarrow> 'a list Heap" where
    77 definition freeze :: "'a\<Colon>heap array \<Rightarrow> 'a list Heap" where
    78   [code del]: "freeze a = Heap_Monad.heap (\<lambda>h. (get_array a h, h))"
    78   [code del]: "freeze a = Heap_Monad.tap (\<lambda>h. get_array a h)"
    79 
    79 
    80 
    80 
    81 subsection {* Properties *}
    81 subsection {* Properties *}
    82 
    82 
    83 text {* FIXME: Does there exist a "canonical" array axiomatisation in
    83 text {* FIXME: Does there exist a "canonical" array axiomatisation in
    84 the literature?  *}
    84 the literature?  *}
       
    85 
       
    86 text {* Primitives *}
    85 
    87 
    86 lemma noteq_arrs_sym: "a =!!= b \<Longrightarrow> b =!!= a"
    88 lemma noteq_arrs_sym: "a =!!= b \<Longrightarrow> b =!!= a"
    87   and unequal_arrs [simp]: "a \<noteq> a' \<longleftrightarrow> a =!!= a'"
    89   and unequal_arrs [simp]: "a \<noteq> a' \<longleftrightarrow> a =!!= a'"
    88   unfolding noteq_arrs_def by auto
    90   unfolding noteq_arrs_def by auto
    89 
    91 
   151 
   153 
   152 lemma array_present_change [simp]: 
   154 lemma array_present_change [simp]: 
   153   "array_present a (change b i v h) = array_present a h"
   155   "array_present a (change b i v h) = array_present a h"
   154   by (simp add: change_def array_present_def set_array_def get_array_def)
   156   by (simp add: change_def array_present_def set_array_def get_array_def)
   155 
   157 
   156 lemma execute_new [simp]:
   158 
   157   "Heap_Monad.execute (new n x) h = Some (array (replicate n x) h)"
   159 text {* Monad operations *}
       
   160 
       
   161 lemma execute_new [simp, execute_simps]:
       
   162   "execute (new n x) h = Some (array (replicate n x) h)"
   158   by (simp add: new_def)
   163   by (simp add: new_def)
   159 
   164 
   160 lemma execute_of_list [simp]:
   165 lemma success_newI [iff, success_intros]:
   161   "Heap_Monad.execute (of_list xs) h = Some (array xs h)"
   166   "success (new n x) h"
       
   167   by (simp add: new_def)
       
   168 
       
   169 lemma execute_of_list [simp, execute_simps]:
       
   170   "execute (of_list xs) h = Some (array xs h)"
   162   by (simp add: of_list_def)
   171   by (simp add: of_list_def)
   163 
   172 
   164 lemma execute_make [simp]:
   173 lemma success_of_listI [iff, success_intros]:
   165   "Heap_Monad.execute (make n f) h = Some (array (map f [0 ..< n]) h)"
   174   "success (of_list xs) h"
       
   175   by (simp add: of_list_def)
       
   176 
       
   177 lemma execute_make [simp, execute_simps]:
       
   178   "execute (make n f) h = Some (array (map f [0 ..< n]) h)"
   166   by (simp add: make_def)
   179   by (simp add: make_def)
   167 
   180 
   168 lemma execute_len [simp]:
   181 lemma success_makeI [iff, success_intros]:
   169   "Heap_Monad.execute (len a) h = Some (length a h, h)"
   182   "success (make n f) h"
       
   183   by (simp add: make_def)
       
   184 
       
   185 lemma execute_len [simp, execute_simps]:
       
   186   "execute (len a) h = Some (length a h, h)"
   170   by (simp add: len_def)
   187   by (simp add: len_def)
   171 
   188 
   172 lemma execute_nth [simp]:
   189 lemma success_lenI [iff, success_intros]:
       
   190   "success (len a) h"
       
   191   by (simp add: len_def)
       
   192 
       
   193 lemma execute_nth [execute_simps]:
   173   "i < length a h \<Longrightarrow>
   194   "i < length a h \<Longrightarrow>
   174     Heap_Monad.execute (nth a i) h = Some (get_array a h ! i, h)"
   195     execute (nth a i) h = Some (get_array a h ! i, h)"
   175   "i \<ge> length a h \<Longrightarrow> Heap_Monad.execute (nth a i) h = None"
   196   "i \<ge> length a h \<Longrightarrow> execute (nth a i) h = None"
   176   by (simp_all add: nth_def)
   197   by (simp_all add: nth_def execute_simps)
   177 
   198 
   178 lemma execute_upd [simp]:
   199 lemma success_nthI [success_intros]:
       
   200   "i < length a h \<Longrightarrow> success (nth a i) h"
       
   201   by (auto intro: success_intros simp add: nth_def)
       
   202 
       
   203 lemma execute_upd [execute_simps]:
   179   "i < length a h \<Longrightarrow>
   204   "i < length a h \<Longrightarrow>
   180     Heap_Monad.execute (upd i x a) h = Some (a, change a i x h)"
   205     execute (upd i x a) h = Some (a, change a i x h)"
   181   "i \<ge> length a h \<Longrightarrow> Heap_Monad.execute (nth a i) h = None"
   206   "i \<ge> length a h \<Longrightarrow> execute (nth a i) h = None"
   182   by (simp_all add: upd_def)
   207   by (simp_all add: upd_def execute_simps)
   183 
   208 
   184 lemma execute_map_entry [simp]:
   209 lemma success_updI [success_intros]:
       
   210   "i < length a h \<Longrightarrow> success (upd i x a) h"
       
   211   by (auto intro: success_intros simp add: upd_def)
       
   212 
       
   213 lemma execute_map_entry [execute_simps]:
   185   "i < length a h \<Longrightarrow>
   214   "i < length a h \<Longrightarrow>
   186    Heap_Monad.execute (map_entry i f a) h =
   215    execute (map_entry i f a) h =
   187       Some (a, change a i (f (get_array a h ! i)) h)"
   216       Some (a, change a i (f (get_array a h ! i)) h)"
   188   "i \<ge> length a h \<Longrightarrow> Heap_Monad.execute (nth a i) h = None"
   217   "i \<ge> length a h \<Longrightarrow> execute (nth a i) h = None"
   189   by (simp_all add: map_entry_def)
   218   by (simp_all add: map_entry_def execute_simps)
   190 
   219 
   191 lemma execute_swap [simp]:
   220 lemma success_map_entryI [success_intros]:
       
   221   "i < length a h \<Longrightarrow> success (map_entry i f a) h"
       
   222   by (auto intro: success_intros simp add: map_entry_def)
       
   223 
       
   224 lemma execute_swap [execute_simps]:
   192   "i < length a h \<Longrightarrow>
   225   "i < length a h \<Longrightarrow>
   193    Heap_Monad.execute (swap i x a) h =
   226    execute (swap i x a) h =
   194       Some (get_array a h ! i, change a i x h)"
   227       Some (get_array a h ! i, change a i x h)"
   195   "i \<ge> length a h \<Longrightarrow> Heap_Monad.execute (nth a i) h = None"
   228   "i \<ge> length a h \<Longrightarrow> execute (nth a i) h = None"
   196   by (simp_all add: swap_def)
   229   by (simp_all add: swap_def execute_simps)
   197 
   230 
   198 lemma execute_freeze [simp]:
   231 lemma success_swapI [success_intros]:
   199   "Heap_Monad.execute (freeze a) h = Some (get_array a h, h)"
   232   "i < length a h \<Longrightarrow> success (swap i x a) h"
       
   233   by (auto intro: success_intros simp add: swap_def)
       
   234 
       
   235 lemma execute_freeze [simp, execute_simps]:
       
   236   "execute (freeze a) h = Some (get_array a h, h)"
       
   237   by (simp add: freeze_def)
       
   238 
       
   239 lemma success_freezeI [iff, success_intros]:
       
   240   "success (freeze a) h"
   200   by (simp add: freeze_def)
   241   by (simp add: freeze_def)
   201 
   242 
   202 lemma upd_return:
   243 lemma upd_return:
   203   "upd i x a \<guillemotright> return a = upd i x a"
   244   "upd i x a \<guillemotright> return a = upd i x a"
   204   by (rule Heap_eqI) (simp add: bind_def guard_def upd_def)
   245   by (rule Heap_eqI) (simp add: bind_def guard_def upd_def)
   263 lemma [code]:
   304 lemma [code]:
   264   "map_entry i f a = (do
   305   "map_entry i f a = (do
   265      x \<leftarrow> nth a i;
   306      x \<leftarrow> nth a i;
   266      upd i (f x) a
   307      upd i (f x) a
   267    done)"
   308    done)"
   268   by (rule Heap_eqI) (simp add: bind_def guard_def map_entry_def)
   309   by (rule Heap_eqI) (simp add: bind_def guard_def map_entry_def execute_simps)
   269 
   310 
   270 lemma [code]:
   311 lemma [code]:
   271   "swap i x a = (do
   312   "swap i x a = (do
   272      y \<leftarrow> nth a i;
   313      y \<leftarrow> nth a i;
   273      upd i x a;
   314      upd i x a;
   274      return y
   315      return y
   275    done)"
   316    done)"
   276   by (rule Heap_eqI) (simp add: bind_def guard_def swap_def)
   317   by (rule Heap_eqI) (simp add: bind_def guard_def swap_def execute_simps)
   277 
   318 
   278 lemma [code]:
   319 lemma [code]:
   279   "freeze a = (do
   320   "freeze a = (do
   280      n \<leftarrow> len a;
   321      n \<leftarrow> len a;
   281      Heap_Monad.fold_map (\<lambda>i. nth a i) [0..<n]
   322      Heap_Monad.fold_map (\<lambda>i. nth a i) [0..<n]
   286      (\<lambda>x. fst (the (if x < length a h
   327      (\<lambda>x. fst (the (if x < length a h
   287                     then Some (get_array a h ! x, h) else None)))
   328                     then Some (get_array a h ! x, h) else None)))
   288      [0..<length a h] =
   329      [0..<length a h] =
   289        List.map (List.nth (get_array a h)) [0..<length a h]"
   330        List.map (List.nth (get_array a h)) [0..<length a h]"
   290     by simp
   331     by simp
   291   have "Heap_Monad.execute (Heap_Monad.fold_map (Array.nth a) [0..<length a h]) h =
   332   have "execute (Heap_Monad.fold_map (Array.nth a) [0..<length a h]) h =
   292     Some (get_array a h, h)"
   333     Some (get_array a h, h)"
   293     apply (subst execute_fold_map_unchanged_heap)
   334     apply (subst execute_fold_map_unchanged_heap)
   294     apply (simp_all add: nth_def guard_def *)
   335     apply (simp_all add: nth_def guard_def *)
   295     apply (simp add: length_def map_nth)
   336     apply (simp add: length_def map_nth)
   296     done
   337     done
   297   then have "Heap_Monad.execute (do
   338   then have "execute (do
   298       n \<leftarrow> len a;
   339       n \<leftarrow> len a;
   299       Heap_Monad.fold_map (Array.nth a) [0..<n]
   340       Heap_Monad.fold_map (Array.nth a) [0..<n]
   300     done) h = Some (get_array a h, h)"
   341     done) h = Some (get_array a h, h)"
   301     by (auto intro: execute_eq_SomeI)
   342     by (auto intro: execute_eq_SomeI)
   302   then show "Heap_Monad.execute (freeze a) h = Heap_Monad.execute (do
   343   then show "execute (freeze a) h = execute (do
   303       n \<leftarrow> len a;
   344       n \<leftarrow> len a;
   304       Heap_Monad.fold_map (Array.nth a) [0..<n]
   345       Heap_Monad.fold_map (Array.nth a) [0..<n]
   305     done) h" by simp
   346     done) h" by simp
   306 qed
   347 qed
   307 
   348