haftmann@24999: (* ID: $Id$ haftmann@24999: Author: Florian Haftmann, TU Muenchen haftmann@24999: *) haftmann@24999: haftmann@24999: header {* Type of indices *} haftmann@24999: haftmann@24999: theory Code_Index haftmann@24999: imports PreList haftmann@24999: begin haftmann@24999: haftmann@24999: text {* haftmann@24999: Indices are isomorphic to HOL @{typ int} but haftmann@24999: mapped to target-language builtin integers haftmann@24999: *} haftmann@24999: haftmann@24999: subsection {* Datatype of indices *} haftmann@24999: haftmann@24999: datatype index = index_of_int int haftmann@24999: haftmann@24999: lemmas [code func del] = index.recs index.cases haftmann@24999: haftmann@24999: fun haftmann@24999: int_of_index :: "index \ int" haftmann@24999: where haftmann@24999: "int_of_index (index_of_int k) = k" haftmann@24999: lemmas [code func del] = int_of_index.simps haftmann@24999: haftmann@24999: lemma index_id [simp]: haftmann@24999: "index_of_int (int_of_index k) = k" haftmann@24999: by (cases k) simp_all haftmann@24999: haftmann@24999: lemma index: haftmann@24999: "(\k\index. PROP P k) \ (\k\int. PROP P (index_of_int k))" haftmann@24999: proof haftmann@24999: fix k :: int haftmann@24999: assume "\k\index. PROP P k" haftmann@24999: then show "PROP P (index_of_int k)" . haftmann@24999: next haftmann@24999: fix k :: index haftmann@24999: assume "\k\int. PROP P (index_of_int k)" haftmann@24999: then have "PROP P (index_of_int (int_of_index k))" . haftmann@24999: then show "PROP P k" by simp haftmann@24999: qed haftmann@24999: haftmann@24999: lemma [code func]: "size (k\index) = 0" haftmann@24999: by (cases k) simp_all haftmann@24999: haftmann@24999: haftmann@24999: subsection {* Built-in integers as datatype on numerals *} haftmann@24999: haftmann@24999: instance index :: number haftmann@24999: "number_of \ index_of_int" .. haftmann@24999: haftmann@24999: code_datatype "number_of \ int \ index" haftmann@24999: haftmann@24999: lemma number_of_index_id [simp]: haftmann@24999: "number_of (int_of_index k) = k" haftmann@24999: unfolding number_of_index_def by simp haftmann@24999: haftmann@24999: lemma number_of_index_shift: haftmann@24999: "number_of k = index_of_int (number_of k)" haftmann@24999: by (simp add: number_of_is_id number_of_index_def) haftmann@24999: haftmann@25335: lemma int_of_index_number_of [simp]: haftmann@25335: "int_of_index (number_of k) = number_of k" haftmann@25335: unfolding number_of_index_def number_of_is_id by simp haftmann@25335: haftmann@24999: haftmann@24999: subsection {* Basic arithmetic *} haftmann@24999: haftmann@24999: instance index :: zero haftmann@24999: [simp]: "0 \ index_of_int 0" .. haftmann@24999: lemmas [code func del] = zero_index_def haftmann@24999: haftmann@24999: instance index :: one haftmann@24999: [simp]: "1 \ index_of_int 1" .. haftmann@24999: lemmas [code func del] = one_index_def haftmann@24999: haftmann@24999: instance index :: plus haftmann@24999: [simp]: "k + l \ index_of_int (int_of_index k + int_of_index l)" .. haftmann@24999: lemmas [code func del] = plus_index_def haftmann@24999: lemma plus_index_code [code func]: haftmann@24999: "index_of_int k + index_of_int l = index_of_int (k + l)" haftmann@24999: unfolding plus_index_def by simp haftmann@24999: haftmann@24999: instance index :: minus haftmann@24999: [simp]: "- k \ index_of_int (- int_of_index k)" haftmann@24999: [simp]: "k - l \ index_of_int (int_of_index k - int_of_index l)" .. haftmann@24999: lemmas [code func del] = uminus_index_def minus_index_def haftmann@24999: lemma uminus_index_code [code func]: haftmann@24999: "- index_of_int k \ index_of_int (- k)" haftmann@24999: unfolding uminus_index_def by simp haftmann@24999: lemma minus_index_code [code func]: haftmann@24999: "index_of_int k - index_of_int l = index_of_int (k - l)" haftmann@24999: unfolding minus_index_def by simp haftmann@24999: haftmann@24999: instance index :: times haftmann@24999: [simp]: "k * l \ index_of_int (int_of_index k * int_of_index l)" .. haftmann@24999: lemmas [code func del] = times_index_def haftmann@24999: lemma times_index_code [code func]: haftmann@24999: "index_of_int k * index_of_int l = index_of_int (k * l)" haftmann@24999: unfolding times_index_def by simp haftmann@24999: haftmann@24999: instance index :: ord haftmann@24999: [simp]: "k \ l \ int_of_index k \ int_of_index l" haftmann@24999: [simp]: "k < l \ int_of_index k < int_of_index l" .. haftmann@24999: lemmas [code func del] = less_eq_index_def less_index_def haftmann@24999: lemma less_eq_index_code [code func]: haftmann@24999: "index_of_int k \ index_of_int l \ k \ l" haftmann@24999: unfolding less_eq_index_def by simp haftmann@24999: lemma less_index_code [code func]: haftmann@24999: "index_of_int k < index_of_int l \ k < l" haftmann@24999: unfolding less_index_def by simp haftmann@24999: haftmann@25335: instance index :: "Divides.div" haftmann@25335: [simp]: "k div l \ index_of_int (int_of_index k div int_of_index l)" haftmann@25335: [simp]: "k mod l \ index_of_int (int_of_index k mod int_of_index l)" .. haftmann@25335: haftmann@24999: instance index :: ring_1 haftmann@24999: by default (auto simp add: left_distrib right_distrib) haftmann@24999: haftmann@24999: lemma of_nat_index: "of_nat n = index_of_int (of_nat n)" haftmann@24999: proof (induct n) haftmann@24999: case 0 show ?case by simp haftmann@24999: next haftmann@24999: case (Suc n) haftmann@24999: then have "int_of_index (index_of_int (int n)) haftmann@24999: = int_of_index (of_nat n)" by simp haftmann@24999: then have "int n = int_of_index (of_nat n)" by simp haftmann@24999: then show ?case by simp haftmann@24999: qed haftmann@24999: haftmann@24999: instance index :: number_ring haftmann@24999: by default haftmann@24999: (simp_all add: left_distrib number_of_index_def of_int_of_nat of_nat_index) haftmann@24999: haftmann@24999: lemma zero_index_code [code inline, code func]: haftmann@24999: "(0\index) = Numeral0" haftmann@24999: by simp haftmann@24999: haftmann@24999: lemma one_index_code [code inline, code func]: haftmann@24999: "(1\index) = Numeral1" haftmann@24999: by simp haftmann@24999: haftmann@24999: instance index :: abs haftmann@24999: "\k\ \ if k < 0 then -k else k" .. haftmann@24999: haftmann@24999: lemma index_of_int [code func]: haftmann@24999: "index_of_int k = (if k = 0 then 0 haftmann@24999: else if k = -1 then -1 haftmann@24999: else let (l, m) = divAlg (k, 2) in 2 * index_of_int l + haftmann@24999: (if m = 0 then 0 else 1))" haftmann@24999: by (simp add: number_of_index_shift Let_def split_def divAlg_mod_div) arith haftmann@24999: haftmann@25335: lemma int_of_index [code func]: haftmann@25335: "int_of_index k = (if k = 0 then 0 haftmann@25335: else if k = -1 then -1 haftmann@25335: else let l = k div 2; m = k mod 2 in 2 * int_of_index l + haftmann@25335: (if m = 0 then 0 else 1))" haftmann@25335: by (auto simp add: number_of_index_shift Let_def split_def) arith haftmann@25335: haftmann@24999: haftmann@24999: subsection {* Conversion to and from @{typ nat} *} haftmann@24999: haftmann@24999: definition haftmann@24999: nat_of_index :: "index \ nat" haftmann@24999: where haftmann@24999: [code func del]: "nat_of_index = nat o int_of_index" haftmann@24999: haftmann@24999: definition haftmann@24999: nat_of_index_aux :: "index \ nat \ nat" where haftmann@24999: [code func del]: "nat_of_index_aux i n = nat_of_index i + n" haftmann@24999: haftmann@24999: lemma nat_of_index_aux_code [code]: haftmann@24999: "nat_of_index_aux i n = (if i \ 0 then n else nat_of_index_aux (i - 1) (Suc n))" haftmann@24999: by (auto simp add: nat_of_index_aux_def nat_of_index_def) haftmann@24999: haftmann@24999: lemma nat_of_index_code [code]: haftmann@24999: "nat_of_index i = nat_of_index_aux i 0" haftmann@24999: by (simp add: nat_of_index_aux_def) haftmann@24999: haftmann@24999: definition haftmann@24999: index_of_nat :: "nat \ index" haftmann@24999: where haftmann@24999: [code func del]: "index_of_nat = index_of_int o of_nat" haftmann@24999: haftmann@24999: lemma index_of_nat [code func]: haftmann@24999: "index_of_nat 0 = 0" haftmann@24999: "index_of_nat (Suc n) = index_of_nat n + 1" haftmann@24999: unfolding index_of_nat_def by simp_all haftmann@24999: haftmann@24999: lemma index_nat_id [simp]: haftmann@24999: "nat_of_index (index_of_nat n) = n" haftmann@24999: "index_of_nat (nat_of_index i) = (if i \ 0 then 0 else i)" haftmann@24999: unfolding index_of_nat_def nat_of_index_def by simp_all haftmann@24999: haftmann@24999: haftmann@24999: subsection {* ML interface *} haftmann@24999: haftmann@24999: ML {* haftmann@24999: structure Index = haftmann@24999: struct haftmann@24999: haftmann@24999: fun mk k = @{term index_of_int} $ HOLogic.mk_number @{typ index} k; haftmann@24999: haftmann@24999: end; haftmann@24999: *} haftmann@24999: haftmann@24999: haftmann@24999: subsection {* Code serialization *} haftmann@24999: haftmann@24999: code_type index haftmann@24999: (SML "int") haftmann@24999: (OCaml "int") haftmann@24999: (Haskell "Integer") haftmann@24999: haftmann@24999: code_instance index :: eq haftmann@24999: (Haskell -) haftmann@24999: haftmann@24999: setup {* haftmann@24999: fold (fn target => CodeTarget.add_pretty_numeral target true haftmann@24999: @{const_name number_index_inst.number_of_index} haftmann@24999: @{const_name Numeral.B0} @{const_name Numeral.B1} haftmann@24999: @{const_name Numeral.Pls} @{const_name Numeral.Min} haftmann@24999: @{const_name Numeral.Bit} haftmann@24999: ) ["SML", "OCaml", "Haskell"] haftmann@24999: *} haftmann@24999: haftmann@24999: code_reserved SML int haftmann@24999: code_reserved OCaml int haftmann@24999: haftmann@24999: code_const "op + \ index \ index \ index" haftmann@24999: (SML "Int.+ ((_), (_))") haftmann@24999: (OCaml "Pervasives.+") haftmann@24999: (Haskell infixl 6 "+") haftmann@24999: haftmann@24999: code_const "uminus \ index \ index" haftmann@24999: (SML "Int.~") haftmann@24999: (OCaml "Pervasives.~-") haftmann@24999: (Haskell "negate") haftmann@24999: haftmann@24999: code_const "op - \ index \ index \ index" haftmann@24999: (SML "Int.- ((_), (_))") haftmann@24999: (OCaml "Pervasives.-") haftmann@24999: (Haskell infixl 6 "-") haftmann@24999: haftmann@24999: code_const "op * \ index \ index \ index" haftmann@24999: (SML "Int.* ((_), (_))") haftmann@24999: (OCaml "Pervasives.*") haftmann@24999: (Haskell infixl 7 "*") haftmann@24999: haftmann@24999: code_const "op = \ index \ index \ bool" haftmann@24999: (SML "!((_ : Int.int) = _)") haftmann@24999: (OCaml "!((_ : Pervasives.int) = _)") haftmann@24999: (Haskell infixl 4 "==") haftmann@24999: haftmann@24999: code_const "op \ \ index \ index \ bool" haftmann@24999: (SML "Int.<= ((_), (_))") haftmann@24999: (OCaml "!((_ : Pervasives.int) <= _)") haftmann@24999: (Haskell infix 4 "<=") haftmann@24999: haftmann@24999: code_const "op < \ index \ index \ bool" haftmann@24999: (SML "Int.< ((_), (_))") haftmann@24999: (OCaml "!((_ : Pervasives.int) < _)") haftmann@24999: (Haskell infix 4 "<") haftmann@24999: haftmann@24999: code_reserved SML Int haftmann@24999: code_reserved OCaml Pervasives haftmann@24999: haftmann@24999: end