author | wenzelm |
Mon Dec 28 17:43:30 2015 +0100 (2015-12-28) | |
changeset 61952 | 546958347e05 |
parent 61115 | 3a4400985780 |
child 63649 | e690d6f2185b |
permissions | -rw-r--r-- |
wenzelm@58881 | 1 |
section "Immutable Arrays with Code Generation" |
nipkow@50138 | 2 |
|
nipkow@50138 | 3 |
theory IArray |
haftmann@51094 | 4 |
imports Main |
nipkow@50138 | 5 |
begin |
nipkow@50138 | 6 |
|
wenzelm@60500 | 7 |
text\<open>Immutable arrays are lists wrapped up in an additional constructor. |
nipkow@50138 | 8 |
There are no update operations. Hence code generation can safely implement |
nipkow@50138 | 9 |
this type by efficient target language arrays. Currently only SML is |
nipkow@50138 | 10 |
provided. Should be extended to other target languages and more operations. |
nipkow@50138 | 11 |
|
nipkow@50138 | 12 |
Note that arrays cannot be printed directly but only by turning them into |
nipkow@50138 | 13 |
lists first. Arrays could be converted back into lists for printing if they |
wenzelm@60500 | 14 |
were wrapped up in an additional constructor.\<close> |
nipkow@50138 | 15 |
|
wenzelm@61115 | 16 |
context |
wenzelm@61115 | 17 |
begin |
wenzelm@61115 | 18 |
|
blanchet@58310 | 19 |
datatype 'a iarray = IArray "'a list" |
nipkow@50138 | 20 |
|
wenzelm@61115 | 21 |
qualified primrec list_of :: "'a iarray \<Rightarrow> 'a list" where |
nipkow@50138 | 22 |
"list_of (IArray xs) = xs" |
nipkow@50138 | 23 |
|
wenzelm@61115 | 24 |
qualified definition of_fun :: "(nat \<Rightarrow> 'a) \<Rightarrow> nat \<Rightarrow> 'a iarray" where |
haftmann@51094 | 25 |
[simp]: "of_fun f n = IArray (map f [0..<n])" |
haftmann@51094 | 26 |
|
wenzelm@61115 | 27 |
qualified definition sub :: "'a iarray \<Rightarrow> nat \<Rightarrow> 'a" (infixl "!!" 100) where |
haftmann@51094 | 28 |
[simp]: "as !! n = IArray.list_of as ! n" |
haftmann@51094 | 29 |
|
wenzelm@61115 | 30 |
qualified definition length :: "'a iarray \<Rightarrow> nat" where |
haftmann@51094 | 31 |
[simp]: "length as = List.length (IArray.list_of as)" |
haftmann@51094 | 32 |
|
wenzelm@61115 | 33 |
qualified fun all :: "('a \<Rightarrow> bool) \<Rightarrow> 'a iarray \<Rightarrow> bool" where |
nipkow@54459 | 34 |
"all p (IArray as) = (ALL a : set as. p a)" |
nipkow@54459 | 35 |
|
wenzelm@61115 | 36 |
qualified fun exists :: "('a \<Rightarrow> bool) \<Rightarrow> 'a iarray \<Rightarrow> bool" where |
nipkow@54459 | 37 |
"exists p (IArray as) = (EX a : set as. p a)" |
nipkow@54459 | 38 |
|
haftmann@51094 | 39 |
lemma list_of_code [code]: |
haftmann@51094 | 40 |
"IArray.list_of as = map (\<lambda>n. as !! n) [0 ..< IArray.length as]" |
haftmann@51094 | 41 |
by (cases as) (simp add: map_nth) |
haftmann@51094 | 42 |
|
wenzelm@61115 | 43 |
end |
wenzelm@61115 | 44 |
|
nipkow@50138 | 45 |
|
nipkow@50138 | 46 |
subsection "Code Generation" |
nipkow@50138 | 47 |
|
haftmann@51094 | 48 |
code_reserved SML Vector |
haftmann@51094 | 49 |
|
haftmann@52435 | 50 |
code_printing |
haftmann@52435 | 51 |
type_constructor iarray \<rightharpoonup> (SML) "_ Vector.vector" |
haftmann@52435 | 52 |
| constant IArray \<rightharpoonup> (SML) "Vector.fromList" |
nipkow@54459 | 53 |
| constant IArray.all \<rightharpoonup> (SML) "Vector.all" |
nipkow@54459 | 54 |
| constant IArray.exists \<rightharpoonup> (SML) "Vector.exists" |
haftmann@51094 | 55 |
|
haftmann@51161 | 56 |
lemma [code]: |
blanchet@58269 | 57 |
"size (as :: 'a iarray) = Suc (length (IArray.list_of as))" |
blanchet@58269 | 58 |
by (cases as) simp |
haftmann@51161 | 59 |
|
haftmann@51161 | 60 |
lemma [code]: |
blanchet@58269 | 61 |
"size_iarray f as = Suc (size_list f (IArray.list_of as))" |
blanchet@58269 | 62 |
by (cases as) simp |
blanchet@58269 | 63 |
|
blanchet@58269 | 64 |
lemma [code]: |
blanchet@58269 | 65 |
"rec_iarray f as = f (IArray.list_of as)" |
blanchet@58269 | 66 |
by (cases as) simp |
blanchet@58269 | 67 |
|
blanchet@58269 | 68 |
lemma [code]: |
blanchet@58269 | 69 |
"case_iarray f as = f (IArray.list_of as)" |
blanchet@58269 | 70 |
by (cases as) simp |
haftmann@51161 | 71 |
|
haftmann@51161 | 72 |
lemma [code]: |
blanchet@58269 | 73 |
"set_iarray as = set (IArray.list_of as)" |
blanchet@58269 | 74 |
by (case_tac as) auto |
blanchet@58269 | 75 |
|
blanchet@58269 | 76 |
lemma [code]: |
blanchet@58269 | 77 |
"map_iarray f as = IArray (map f (IArray.list_of as))" |
blanchet@58269 | 78 |
by (case_tac as) auto |
haftmann@51161 | 79 |
|
haftmann@51161 | 80 |
lemma [code]: |
blanchet@58269 | 81 |
"rel_iarray r as bs = list_all2 r (IArray.list_of as) (IArray.list_of bs)" |
blanchet@58269 | 82 |
by (case_tac as) (case_tac bs, auto) |
haftmann@51161 | 83 |
|
haftmann@51161 | 84 |
lemma [code]: |
blanchet@58269 | 85 |
"HOL.equal as bs \<longleftrightarrow> HOL.equal (IArray.list_of as) (IArray.list_of bs)" |
blanchet@58269 | 86 |
by (cases as, cases bs) (simp add: equal) |
haftmann@51161 | 87 |
|
wenzelm@61115 | 88 |
context |
wenzelm@61115 | 89 |
begin |
wenzelm@61115 | 90 |
|
wenzelm@61115 | 91 |
qualified primrec tabulate :: "integer \<times> (integer \<Rightarrow> 'a) \<Rightarrow> 'a iarray" where |
blanchet@58269 | 92 |
"tabulate (n, f) = IArray (map (f \<circ> integer_of_nat) [0..<nat_of_integer n])" |
blanchet@58269 | 93 |
|
wenzelm@61115 | 94 |
end |
haftmann@51094 | 95 |
|
haftmann@51094 | 96 |
lemma [code]: |
blanchet@58269 | 97 |
"IArray.of_fun f n = IArray.tabulate (integer_of_nat n, f \<circ> nat_of_integer)" |
blanchet@58269 | 98 |
by simp |
haftmann@51094 | 99 |
|
haftmann@52435 | 100 |
code_printing |
haftmann@52435 | 101 |
constant IArray.tabulate \<rightharpoonup> (SML) "Vector.tabulate" |
haftmann@51094 | 102 |
|
wenzelm@61115 | 103 |
context |
wenzelm@61115 | 104 |
begin |
wenzelm@61115 | 105 |
|
wenzelm@61115 | 106 |
qualified primrec sub' :: "'a iarray \<times> integer \<Rightarrow> 'a" where |
blanchet@58269 | 107 |
[code del]: "sub' (as, n) = IArray.list_of as ! nat_of_integer n" |
blanchet@58269 | 108 |
|
wenzelm@61115 | 109 |
end |
haftmann@51094 | 110 |
|
haftmann@51094 | 111 |
lemma [code]: |
haftmann@57117 | 112 |
"IArray.sub' (IArray as, n) = as ! nat_of_integer n" |
haftmann@57117 | 113 |
by simp |
haftmann@57117 | 114 |
|
haftmann@57117 | 115 |
lemma [code]: |
blanchet@58269 | 116 |
"as !! n = IArray.sub' (as, integer_of_nat n)" |
blanchet@58269 | 117 |
by simp |
haftmann@51094 | 118 |
|
haftmann@52435 | 119 |
code_printing |
haftmann@52435 | 120 |
constant IArray.sub' \<rightharpoonup> (SML) "Vector.sub" |
haftmann@51094 | 121 |
|
wenzelm@61115 | 122 |
context |
wenzelm@61115 | 123 |
begin |
wenzelm@61115 | 124 |
|
wenzelm@61115 | 125 |
qualified definition length' :: "'a iarray \<Rightarrow> integer" where |
blanchet@58269 | 126 |
[code del, simp]: "length' as = integer_of_nat (List.length (IArray.list_of as))" |
blanchet@58269 | 127 |
|
wenzelm@61115 | 128 |
end |
haftmann@51094 | 129 |
|
haftmann@51094 | 130 |
lemma [code]: |
haftmann@57117 | 131 |
"IArray.length' (IArray as) = integer_of_nat (List.length as)" |
haftmann@57117 | 132 |
by simp |
haftmann@57117 | 133 |
|
haftmann@57117 | 134 |
lemma [code]: |
blanchet@58269 | 135 |
"IArray.length as = nat_of_integer (IArray.length' as)" |
blanchet@58269 | 136 |
by simp |
haftmann@51094 | 137 |
|
haftmann@59457 | 138 |
context term_syntax |
haftmann@59457 | 139 |
begin |
haftmann@59457 | 140 |
|
haftmann@59457 | 141 |
lemma [code]: |
haftmann@59457 | 142 |
"Code_Evaluation.term_of (as :: 'a::typerep iarray) = |
haftmann@59457 | 143 |
Code_Evaluation.Const (STR ''IArray.iarray.IArray'') (TYPEREP('a list \<Rightarrow> 'a iarray)) <\<cdot>> (Code_Evaluation.term_of (IArray.list_of as))" |
haftmann@59457 | 144 |
by (subst term_of_anything) rule |
haftmann@59457 | 145 |
|
haftmann@59457 | 146 |
end |
haftmann@59457 | 147 |
|
haftmann@52435 | 148 |
code_printing |
haftmann@52435 | 149 |
constant IArray.length' \<rightharpoonup> (SML) "Vector.length" |
nipkow@50138 | 150 |
|
nipkow@50138 | 151 |
end |