src/HOL/Library/Array.thy
changeset 26182 8262ec0e8782
parent 26170 66e6b967ccf1
child 26719 a259d259c797
equal deleted inserted replaced
26181:fedc257417fc 26182:8262ec0e8782
     4 *)
     4 *)
     5 
     5 
     6 header {* Monadic arrays *}
     6 header {* Monadic arrays *}
     7 
     7 
     8 theory Array
     8 theory Array
     9 imports Heap_Monad
     9 imports Heap_Monad Code_Index
    10 begin
    10 begin
    11 
    11 
    12 subsection {* Primitives *}
    12 subsection {* Primitives *}
    13 
    13 
    14 definition
    14 definition
    97    done)"
    97    done)"
    98 
    98 
    99 hide (open) const new map -- {* avoid clashed with some popular names *}
    99 hide (open) const new map -- {* avoid clashed with some popular names *}
   100 
   100 
   101 
   101 
   102 subsection {* Converting arrays to lists *}
       
   103 
       
   104 primrec list_of_aux :: "nat \<Rightarrow> ('a\<Colon>heap) array \<Rightarrow> 'a list \<Rightarrow> 'a list Heap" where
       
   105   "list_of_aux 0 a xs = return xs"
       
   106   | "list_of_aux (Suc n) a xs = (do
       
   107         x \<leftarrow> Array.nth a n;
       
   108         list_of_aux n a (x#xs)
       
   109      done)"
       
   110 
       
   111 definition list_of :: "('a\<Colon>heap) array \<Rightarrow> 'a list Heap" where
       
   112   "list_of a = (do n \<leftarrow> Array.length a;
       
   113                    list_of_aux n a []
       
   114                 done)"
       
   115 
       
   116 
       
   117 subsection {* Properties *}
   102 subsection {* Properties *}
   118 
   103 
   119 lemma array_make [code func]:
   104 lemma array_make [code func]:
   120   "Array.new n x = make n (\<lambda>_. x)"
   105   "Array.new n x = make n (\<lambda>_. x)"
   121   by (induct n) (simp_all add: make_def new_def Heap_Monad.heap_def
   106   by (induct n) (simp_all add: make_def new_def Heap_Monad.heap_def
   125 
   110 
   126 lemma array_of_list_make [code func]:
   111 lemma array_of_list_make [code func]:
   127   "of_list xs = make (List.length xs) (\<lambda>n. xs ! n)"
   112   "of_list xs = make (List.length xs) (\<lambda>n. xs ! n)"
   128   unfolding make_def map_nth ..
   113   unfolding make_def map_nth ..
   129 
   114 
       
   115 
       
   116 subsection {* Code generator setup *}
       
   117 
       
   118 subsubsection {* Logical intermediate layer *}
       
   119 
       
   120 definition new' where
       
   121   [code del]: "new' = Array.new o nat_of_index"
       
   122 hide (open) const new'
       
   123 lemma [code func]:
       
   124   "Array.new = Array.new' o index_of_nat"
       
   125   by (simp add: new'_def o_def)
       
   126 
       
   127 definition of_list' where
       
   128   [code del]: "of_list' i xs = Array.of_list (take (nat_of_index i) xs)"
       
   129 hide (open) const of_list'
       
   130 lemma [code func]:
       
   131   "Array.of_list xs = Array.of_list' (index_of_nat (List.length xs)) xs"
       
   132   by (simp add: of_list'_def)
       
   133 
       
   134 definition make' where
       
   135   [code del]: "make' i f = Array.make (nat_of_index i) (f o index_of_nat)"
       
   136 hide (open) const make'
       
   137 lemma [code func]:
       
   138   "Array.make n f = Array.make' (index_of_nat n) (f o nat_of_index)"
       
   139   by (simp add: make'_def o_def)
       
   140 
       
   141 definition length' where
       
   142   [code del]: "length' = Array.length \<guillemotright>== liftM index_of_nat"
       
   143 hide (open) const length'
       
   144 lemma [code func]:
       
   145   "Array.length = Array.length' \<guillemotright>== liftM nat_of_index"
       
   146   by (simp add: length'_def monad_simp',
       
   147     simp add: liftM_def comp_def monad_simp,
       
   148     simp add: monad_simp')
       
   149 
       
   150 definition nth' where
       
   151   [code del]: "nth' a = Array.nth a o nat_of_index"
       
   152 hide (open) const nth'
       
   153 lemma [code func]:
       
   154   "Array.nth a n = Array.nth' a (index_of_nat n)"
       
   155   by (simp add: nth'_def)
       
   156 
       
   157 definition upd' where
       
   158   [code del]: "upd' a i x = Array.upd (nat_of_index i) x a \<guillemotright> return ()"
       
   159 hide (open) const upd'
       
   160 lemma [code func]:
       
   161   "Array.upd i x a = Array.upd' a (index_of_nat i) x \<guillemotright> return a"
       
   162   by (simp add: upd'_def monad_simp upd_return)
       
   163 
       
   164 
       
   165 subsubsection {* SML *}
       
   166 
       
   167 code_type array (SML "_/ array")
       
   168 code_const Array (SML "raise/ (Fail/ \"bare Array\")")
       
   169 code_const Array.new' (SML "Array.array ((_), (_))")
       
   170 code_const Array.of_list (SML "Array.fromList")
       
   171 code_const Array.make' (SML "Array.tabulate ((_), (_))")
       
   172 code_const Array.length' (SML "Array.length")
       
   173 code_const Array.nth' (SML "Array.sub ((_), (_))")
       
   174 code_const Array.upd' (SML "Array.update ((_), (_), (_))")
       
   175 
       
   176 code_reserved SML Array
       
   177 
       
   178 
       
   179 subsubsection {* OCaml *}
       
   180 
       
   181 code_type array (OCaml "_/ array")
       
   182 code_const Array (OCaml "failwith/ \"bare Array\"")
       
   183 code_const Array.new' (OCaml "Array.make")
       
   184 code_const Array.of_list (OCaml "Array.of_list")
       
   185 code_const Array.make' (OCaml "Array.init")
       
   186 code_const Array.length' (OCaml "Array.length")
       
   187 code_const Array.nth' (OCaml "Array.get")
       
   188 code_const Array.upd' (OCaml "Array.set")
       
   189 
       
   190 code_reserved OCaml Array
       
   191 
       
   192 
       
   193 subsubsection {* Haskell *}
       
   194 
       
   195 code_type array (Haskell "STArray '_s _")
       
   196 code_const Array (Haskell "error/ \"bare Array\"")
       
   197 code_const Array.new' (Haskell "newArray/ (0,/ _)")
       
   198 code_const Array.of_list' (Haskell "newListArray/ (0,/ _)")
       
   199 code_const Array.length' (Haskell "length")
       
   200 code_const Array.nth' (Haskell "readArray")
       
   201 code_const Array.upd' (Haskell "writeArray")
       
   202 
       
   203 
   130 end
   204 end