src/HOL/Library/Numeral_Type.thy
changeset 60500 903bb1495239
parent 58881 b9556a055632
child 60679 ade12ef2773c
equal deleted inserted replaced
60499:54a3db2ed201 60500:903bb1495239
     1 (*  Title:      HOL/Library/Numeral_Type.thy
     1 (*  Title:      HOL/Library/Numeral_Type.thy
     2     Author:     Brian Huffman
     2     Author:     Brian Huffman
     3 *)
     3 *)
     4 
     4 
     5 section {* Numeral Syntax for Types *}
     5 section \<open>Numeral Syntax for Types\<close>
     6 
     6 
     7 theory Numeral_Type
     7 theory Numeral_Type
     8 imports Cardinality
     8 imports Cardinality
     9 begin
     9 begin
    10 
    10 
    11 subsection {* Numeral Types *}
    11 subsection \<open>Numeral Types\<close>
    12 
    12 
    13 typedef num0 = "UNIV :: nat set" ..
    13 typedef num0 = "UNIV :: nat set" ..
    14 typedef num1 = "UNIV :: unit set" ..
    14 typedef num1 = "UNIV :: unit set" ..
    15 
    15 
    16 typedef 'a bit0 = "{0 ..< 2 * int CARD('a::finite)}"
    16 typedef 'a bit0 = "{0 ..< 2 * int CARD('a::finite)}"
    68     by simp
    68     by simp
    69   show "2 \<le> CARD('a bit1)"
    69   show "2 \<le> CARD('a bit1)"
    70     by simp
    70     by simp
    71 qed
    71 qed
    72 
    72 
    73 subsection {* Locales for for modular arithmetic subtypes *}
    73 subsection \<open>Locales for for modular arithmetic subtypes\<close>
    74 
    74 
    75 locale mod_type =
    75 locale mod_type =
    76   fixes n :: int
    76   fixes n :: int
    77   and Rep :: "'a::{zero,one,plus,times,uminus,minus} \<Rightarrow> int"
    77   and Rep :: "'a::{zero,one,plus,times,uminus,minus} \<Rightarrow> int"
    78   and Abs :: "int \<Rightarrow> 'a::{zero,one,plus,times,uminus,minus}"
    78   and Abs :: "int \<Rightarrow> 'a::{zero,one,plus,times,uminus,minus}"
   177 by (cases x rule: cases) simp
   177 by (cases x rule: cases) simp
   178 
   178 
   179 end
   179 end
   180 
   180 
   181 
   181 
   182 subsection {* Ring class instances *}
   182 subsection \<open>Ring class instances\<close>
   183 
   183 
   184 text {*
   184 text \<open>
   185   Unfortunately @{text ring_1} instance is not possible for
   185   Unfortunately @{text ring_1} instance is not possible for
   186   @{typ num1}, since 0 and 1 are not distinct.
   186   @{typ num1}, since 0 and 1 are not distinct.
   187 *}
   187 \<close>
   188 
   188 
   189 instantiation num1 :: "{comm_ring,comm_monoid_mult,numeral}"
   189 instantiation num1 :: "{comm_ring,comm_monoid_mult,numeral}"
   190 begin
   190 begin
   191 
   191 
   192 lemma num1_eq_iff: "(x::num1) = (y::num1) \<longleftrightarrow> True"
   192 lemma num1_eq_iff: "(x::num1) = (y::num1) \<longleftrightarrow> True"
   271   mod_ring "int CARD('a::finite bit1)"
   271   mod_ring "int CARD('a::finite bit1)"
   272            "Rep_bit1 :: 'a::finite bit1 \<Rightarrow> int"
   272            "Rep_bit1 :: 'a::finite bit1 \<Rightarrow> int"
   273            "Abs_bit1 :: int \<Rightarrow> 'a::finite bit1"
   273            "Abs_bit1 :: int \<Rightarrow> 'a::finite bit1"
   274   ..
   274   ..
   275 
   275 
   276 text {* Set up cases, induction, and arithmetic *}
   276 text \<open>Set up cases, induction, and arithmetic\<close>
   277 
   277 
   278 lemmas bit0_cases [case_names of_int, cases type: bit0] = bit0.cases
   278 lemmas bit0_cases [case_names of_int, cases type: bit0] = bit0.cases
   279 lemmas bit1_cases [case_names of_int, cases type: bit1] = bit1.cases
   279 lemmas bit1_cases [case_names of_int, cases type: bit1] = bit1.cases
   280 
   280 
   281 lemmas bit0_induct [case_names of_int, induct type: bit0] = bit0.induct
   281 lemmas bit0_induct [case_names of_int, induct type: bit0] = bit0.induct
   285 lemmas bit1_iszero_numeral [simp] = bit1.iszero_numeral
   285 lemmas bit1_iszero_numeral [simp] = bit1.iszero_numeral
   286 
   286 
   287 lemmas [simp] = eq_numeral_iff_iszero [where 'a="'a bit0"] for dummy :: "'a::finite"
   287 lemmas [simp] = eq_numeral_iff_iszero [where 'a="'a bit0"] for dummy :: "'a::finite"
   288 lemmas [simp] = eq_numeral_iff_iszero [where 'a="'a bit1"] for dummy :: "'a::finite"
   288 lemmas [simp] = eq_numeral_iff_iszero [where 'a="'a bit1"] for dummy :: "'a::finite"
   289 
   289 
   290 subsection {* Order instances *}
   290 subsection \<open>Order instances\<close>
   291 
   291 
   292 instantiation bit0 and bit1 :: (finite) linorder begin
   292 instantiation bit0 and bit1 :: (finite) linorder begin
   293 definition "a < b \<longleftrightarrow> Rep_bit0 a < Rep_bit0 b"
   293 definition "a < b \<longleftrightarrow> Rep_bit0 a < Rep_bit0 b"
   294 definition "a \<le> b \<longleftrightarrow> Rep_bit0 a \<le> Rep_bit0 b"
   294 definition "a \<le> b \<longleftrightarrow> Rep_bit0 a \<le> Rep_bit0 b"
   295 definition "a < b \<longleftrightarrow> Rep_bit1 a < Rep_bit1 b"
   295 definition "a < b \<longleftrightarrow> Rep_bit1 a < Rep_bit1 b"
   314     by(auto simp add: trancl_def tranclp_less intro!: finite_acyclic_wf acyclicI)
   314     by(auto simp add: trancl_def tranclp_less intro!: finite_acyclic_wf acyclicI)
   315   thus "OFCLASS('a bit1, wellorder_class)"
   315   thus "OFCLASS('a bit1, wellorder_class)"
   316     by(rule wf_wellorderI) intro_classes
   316     by(rule wf_wellorderI) intro_classes
   317 qed
   317 qed
   318 
   318 
   319 subsection {* Code setup and type classes for code generation *}
   319 subsection \<open>Code setup and type classes for code generation\<close>
   320 
   320 
   321 text {* Code setup for @{typ num0} and @{typ num1} *}
   321 text \<open>Code setup for @{typ num0} and @{typ num1}\<close>
   322 
   322 
   323 definition Num0 :: num0 where "Num0 = Abs_num0 0"
   323 definition Num0 :: num0 where "Num0 = Abs_num0 0"
   324 code_datatype Num0
   324 code_datatype Num0
   325 
   325 
   326 instantiation num0 :: equal begin
   326 instantiation num0 :: equal begin
   364   by intro_classes
   364   by intro_classes
   365      (simp_all add: finite_UNIV_num0_def card_UNIV_num0_def infinite_num0 finite_UNIV_num1_def card_UNIV_num1_def)
   365      (simp_all add: finite_UNIV_num0_def card_UNIV_num0_def infinite_num0 finite_UNIV_num1_def card_UNIV_num1_def)
   366 end
   366 end
   367 
   367 
   368 
   368 
   369 text {* Code setup for @{typ "'a bit0"} and @{typ "'a bit1"} *}
   369 text \<open>Code setup for @{typ "'a bit0"} and @{typ "'a bit1"}\<close>
   370 
   370 
   371 declare
   371 declare
   372   bit0.Rep_inverse[code abstype]
   372   bit0.Rep_inverse[code abstype]
   373   bit0.Rep_0[code abstract]
   373   bit0.Rep_0[code abstract]
   374   bit0.Rep_1[code abstract]
   374   bit0.Rep_1[code abstract]
   463 definition "card_UNIV = Phantom('a bit0) (2 * of_phantom (card_UNIV :: 'a card_UNIV))"
   463 definition "card_UNIV = Phantom('a bit0) (2 * of_phantom (card_UNIV :: 'a card_UNIV))"
   464 definition "card_UNIV = Phantom('a bit1) (1 + 2 * of_phantom (card_UNIV :: 'a card_UNIV))"
   464 definition "card_UNIV = Phantom('a bit1) (1 + 2 * of_phantom (card_UNIV :: 'a card_UNIV))"
   465 instance by intro_classes (simp_all add: card_UNIV_bit0_def card_UNIV_bit1_def card_UNIV)
   465 instance by intro_classes (simp_all add: card_UNIV_bit0_def card_UNIV_bit1_def card_UNIV)
   466 end
   466 end
   467 
   467 
   468 subsection {* Syntax *}
   468 subsection \<open>Syntax\<close>
   469 
   469 
   470 syntax
   470 syntax
   471   "_NumeralType" :: "num_token => type"  ("_")
   471   "_NumeralType" :: "num_token => type"  ("_")
   472   "_NumeralType0" :: type ("0")
   472   "_NumeralType0" :: type ("0")
   473   "_NumeralType1" :: type ("1")
   473   "_NumeralType1" :: type ("1")
   474 
   474 
   475 translations
   475 translations
   476   (type) "1" == (type) "num1"
   476   (type) "1" == (type) "num1"
   477   (type) "0" == (type) "num0"
   477   (type) "0" == (type) "num0"
   478 
   478 
   479 parse_translation {*
   479 parse_translation \<open>
   480   let
   480   let
   481     fun mk_bintype n =
   481     fun mk_bintype n =
   482       let
   482       let
   483         fun mk_bit 0 = Syntax.const @{type_syntax bit0}
   483         fun mk_bit 0 = Syntax.const @{type_syntax bit0}
   484           | mk_bit 1 = Syntax.const @{type_syntax bit1};
   484           | mk_bit 1 = Syntax.const @{type_syntax bit1};
   493 
   493 
   494     fun numeral_tr [Free (str, _)] = mk_bintype (the (Int.fromString str))
   494     fun numeral_tr [Free (str, _)] = mk_bintype (the (Int.fromString str))
   495       | numeral_tr ts = raise TERM ("numeral_tr", ts);
   495       | numeral_tr ts = raise TERM ("numeral_tr", ts);
   496 
   496 
   497   in [(@{syntax_const "_NumeralType"}, K numeral_tr)] end;
   497   in [(@{syntax_const "_NumeralType"}, K numeral_tr)] end;
   498 *}
   498 \<close>
   499 
   499 
   500 print_translation {*
   500 print_translation \<open>
   501   let
   501   let
   502     fun int_of [] = 0
   502     fun int_of [] = 0
   503       | int_of (b :: bs) = b + 2 * int_of bs;
   503       | int_of (b :: bs) = b + 2 * int_of bs;
   504 
   504 
   505     fun bin_of (Const (@{type_syntax num0}, _)) = []
   505     fun bin_of (Const (@{type_syntax num0}, _)) = []
   519       | bit_tr' b _ = raise Match;
   519       | bit_tr' b _ = raise Match;
   520   in
   520   in
   521    [(@{type_syntax bit0}, K (bit_tr' 0)),
   521    [(@{type_syntax bit0}, K (bit_tr' 0)),
   522     (@{type_syntax bit1}, K (bit_tr' 1))]
   522     (@{type_syntax bit1}, K (bit_tr' 1))]
   523   end;
   523   end;
   524 *}
   524 \<close>
   525 
   525 
   526 subsection {* Examples *}
   526 subsection \<open>Examples\<close>
   527 
   527 
   528 lemma "CARD(0) = 0" by simp
   528 lemma "CARD(0) = 0" by simp
   529 lemma "CARD(17) = 17" by simp
   529 lemma "CARD(17) = 17" by simp
   530 lemma "8 * 11 ^ 3 - 6 = (2::5)" by simp
   530 lemma "8 * 11 ^ 3 - 6 = (2::5)" by simp
   531 
   531