src/HOL/ex/Binary.thy
author krauss
Tue, 28 Sep 2010 09:54:07 +0200
changeset 39754 150f831ce4a3
parent 35275 3745987488b2
child 42290 b1f544c84040
permissions -rw-r--r--
no longer declare .psimps rules as [simp]. This regularly caused confusion (e.g., they show up in simp traces when the regular simp rules are disabled). In the few places where the rules are used, explicitly mentioning them actually clarifies the proof text.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     1
(*  Title:      HOL/ex/Binary.thy
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     3
*)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     4
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     5
header {* Simple and efficient binary numerals *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     6
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     7
theory Binary
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     8
imports Main
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
     9
begin
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    10
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    11
subsection {* Binary representation of natural numbers *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    12
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    13
definition
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    14
  bit :: "nat \<Rightarrow> bool \<Rightarrow> nat" where
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    15
  "bit n b = (if b then 2 * n + 1 else 2 * n)"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    16
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    17
lemma bit_simps:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    18
    "bit n False = 2 * n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    19
    "bit n True = 2 * n + 1"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    20
  unfolding bit_def by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    21
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    22
ML {*
26187
3e099fc47afd use more antiquotations;
wenzelm
parents: 24630
diff changeset
    23
  fun dest_bit (Const (@{const_name False}, _)) = 0
3e099fc47afd use more antiquotations;
wenzelm
parents: 24630
diff changeset
    24
    | dest_bit (Const (@{const_name True}, _)) = 1
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    25
    | dest_bit t = raise TERM ("dest_bit", [t]);
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    26
35267
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 35113
diff changeset
    27
  fun dest_binary (Const (@{const_name Groups.zero}, Type (@{type_name nat}, _))) = 0
8dfd816713c6 moved remaning class operations from Algebras.thy to Groups.thy
haftmann
parents: 35113
diff changeset
    28
    | dest_binary (Const (@{const_name Groups.one}, Type (@{type_name nat}, _))) = 1
26187
3e099fc47afd use more antiquotations;
wenzelm
parents: 24630
diff changeset
    29
    | dest_binary (Const (@{const_name bit}, _) $ bs $ b) = 2 * dest_binary bs + dest_bit b
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    30
    | dest_binary t = raise TERM ("dest_binary", [t]);
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    31
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    32
  fun mk_bit 0 = @{term False}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    33
    | mk_bit 1 = @{term True}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    34
    | mk_bit _ = raise TERM ("mk_bit", []);
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    35
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    36
  fun mk_binary 0 = @{term "0::nat"}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    37
    | mk_binary 1 = @{term "1::nat"}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    38
    | mk_binary n =
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    39
        if n < 0 then raise TERM ("mk_binary", [])
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    40
        else
24630
351a308ab58d simplified type int (eliminated IntInf.int, integer);
wenzelm
parents: 24227
diff changeset
    41
          let val (q, r) = Integer.div_mod n 2
351a308ab58d simplified type int (eliminated IntInf.int, integer);
wenzelm
parents: 24227
diff changeset
    42
          in @{term bit} $ mk_binary q $ mk_bit r end;
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    43
*}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
    44
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    45
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    46
subsection {* Direct operations -- plain normalization *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    47
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    48
lemma binary_norm:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    49
    "bit 0 False = 0"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    50
    "bit 0 True = 1"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    51
  unfolding bit_def by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    52
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    53
lemma binary_add:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    54
    "n + 0 = n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    55
    "0 + n = n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    56
    "1 + 1 = bit 1 False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    57
    "bit n False + 1 = bit n True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    58
    "bit n True + 1 = bit (n + 1) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    59
    "1 + bit n False = bit n True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    60
    "1 + bit n True = bit (n + 1) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    61
    "bit m False + bit n False = bit (m + n) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    62
    "bit m False + bit n True = bit (m + n) True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    63
    "bit m True + bit n False = bit (m + n) True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    64
    "bit m True + bit n True = bit ((m + n) + 1) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    65
  by (simp_all add: bit_simps)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    66
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    67
lemma binary_mult:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    68
    "n * 0 = 0"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    69
    "0 * n = 0"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    70
    "n * 1 = n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    71
    "1 * n = n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    72
    "bit m True * n = bit (m * n) False + n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    73
    "bit m False * n = bit (m * n) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    74
    "n * bit m True = bit (m * n) False + n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    75
    "n * bit m False = bit (m * n) False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    76
  by (simp_all add: bit_simps)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    77
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    78
lemmas binary_simps = binary_norm binary_add binary_mult
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    79
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    80
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    81
subsection {* Indirect operations -- ML will produce witnesses *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    82
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    83
lemma binary_less_eq:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    84
  fixes n :: nat
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    85
  shows "n \<equiv> m + k \<Longrightarrow> (m \<le> n) \<equiv> True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    86
    and "m \<equiv> n + k + 1 \<Longrightarrow> (m \<le> n) \<equiv> False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    87
  by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    88
  
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    89
lemma binary_less:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    90
  fixes n :: nat
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    91
  shows "m \<equiv> n + k \<Longrightarrow> (m < n) \<equiv> False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    92
    and "n \<equiv> m + k + 1 \<Longrightarrow> (m < n) \<equiv> True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    93
  by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    94
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    95
lemma binary_diff:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    96
  fixes n :: nat
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    97
  shows "m \<equiv> n + k \<Longrightarrow> m - n \<equiv> k"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    98
    and "n \<equiv> m + k \<Longrightarrow> m - n \<equiv> 0"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
    99
  by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   100
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   101
lemma binary_divmod:
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   102
  fixes n :: nat
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   103
  assumes "m \<equiv> n * k + l" and "0 < n" and "l < n"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   104
  shows "m div n \<equiv> k"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   105
    and "m mod n \<equiv> l"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   106
proof -
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   107
  from `m \<equiv> n * k + l` have "m = l + k * n" by simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   108
  with `0 < n` and `l < n` show "m div n \<equiv> k" and "m mod n \<equiv> l" by simp_all
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   109
qed
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   110
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   111
ML {*
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   112
local
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   113
  infix ==;
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   114
  val op == = Logic.mk_equals;
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   115
  fun plus m n = @{term "plus :: nat \<Rightarrow> nat \<Rightarrow> nat"} $ m $ n;
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   116
  fun mult m n = @{term "times :: nat \<Rightarrow> nat \<Rightarrow> nat"} $ m $ n;
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   117
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   118
  val binary_ss = HOL_basic_ss addsimps @{thms binary_simps};
22156
wenzelm
parents: 22153
diff changeset
   119
  fun prove ctxt prop =
wenzelm
parents: 22153
diff changeset
   120
    Goal.prove ctxt [] [] prop (fn _ => ALLGOALS (full_simp_tac binary_ss));
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   121
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   122
  fun binary_proc proc ss ct =
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   123
    (case Thm.term_of ct of
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   124
      _ $ t $ u =>
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   125
      (case try (pairself (`dest_binary)) (t, u) of
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   126
        SOME args => proc (Simplifier.the_context ss) args
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   127
      | NONE => NONE)
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   128
    | _ => NONE);
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   129
in
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   130
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   131
val less_eq_proc = binary_proc (fn ctxt => fn ((m, t), (n, u)) =>
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   132
  let val k = n - m in
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   133
    if k >= 0 then
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   134
      SOME (@{thm binary_less_eq(1)} OF [prove ctxt (u == plus t (mk_binary k))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   135
    else
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   136
      SOME (@{thm binary_less_eq(2)} OF
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   137
        [prove ctxt (t == plus (plus u (mk_binary (~ k - 1))) (mk_binary 1))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   138
  end);
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   139
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   140
val less_proc = binary_proc (fn ctxt => fn ((m, t), (n, u)) =>
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   141
  let val k = m - n in
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   142
    if k >= 0 then
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   143
      SOME (@{thm binary_less(1)} OF [prove ctxt (t == plus u (mk_binary k))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   144
    else
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   145
      SOME (@{thm binary_less(2)} OF
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   146
        [prove ctxt (u == plus (plus t (mk_binary (~ k - 1))) (mk_binary 1))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   147
  end);
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   148
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   149
val diff_proc = binary_proc (fn ctxt => fn ((m, t), (n, u)) =>
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   150
  let val k = m - n in
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   151
    if k >= 0 then
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   152
      SOME (@{thm binary_diff(1)} OF [prove ctxt (t == plus u (mk_binary k))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   153
    else
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   154
      SOME (@{thm binary_diff(2)} OF [prove ctxt (u == plus t (mk_binary (~ k)))])
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   155
  end);
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   156
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   157
fun divmod_proc rule = binary_proc (fn ctxt => fn ((m, t), (n, u)) =>
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   158
  if n = 0 then NONE
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   159
  else
24630
351a308ab58d simplified type int (eliminated IntInf.int, integer);
wenzelm
parents: 24227
diff changeset
   160
    let val (k, l) = Integer.div_mod m n
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   161
    in SOME (rule OF [prove ctxt (t == plus (mult u (mk_binary k)) (mk_binary l))]) end);
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   162
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   163
end;
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   164
*}
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   165
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   166
simproc_setup binary_nat_less_eq ("m <= (n::nat)") = {* K less_eq_proc *}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   167
simproc_setup binary_nat_less ("m < (n::nat)") = {* K less_proc *}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   168
simproc_setup binary_nat_diff ("m - (n::nat)") = {* K diff_proc *}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   169
simproc_setup binary_nat_div ("m div (n::nat)") = {* K (divmod_proc @{thm binary_divmod(1)}) *}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   170
simproc_setup binary_nat_mod ("m mod (n::nat)") = {* K (divmod_proc @{thm binary_divmod(2)}) *}
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   171
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   172
method_setup binary_simp = {*
30549
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
   173
  Scan.succeed (K (SIMPLE_METHOD'
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   174
    (full_simp_tac
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   175
      (HOL_basic_ss
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   176
        addsimps @{thms binary_simps}
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   177
        addsimprocs
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   178
         [@{simproc binary_nat_less_eq},
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   179
          @{simproc binary_nat_less},
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   180
          @{simproc binary_nat_diff},
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   181
          @{simproc binary_nat_div},
30549
d2d7874648bd simplified method setup;
wenzelm
parents: 30510
diff changeset
   182
          @{simproc binary_nat_mod}]))))
22205
23bd1ed32ac0 proper simproc_setup;
wenzelm
parents: 22156
diff changeset
   183
*} "binary simplification"
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   184
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   185
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   186
subsection {* Concrete syntax *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   187
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   188
syntax
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   189
  "_Binary" :: "num_const \<Rightarrow> 'a"    ("$_")
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   190
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   191
parse_translation {*
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   192
let
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   193
  val syntax_consts =
35262
9ea4445d2ccf slightly more abstract syntax mark/unmark operations;
wenzelm
parents: 35113
diff changeset
   194
    map_aterms (fn Const (c, T) => Const (Syntax.mark_const c, T) | a => a);
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   195
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   196
  fun binary_tr [Const (num, _)] =
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   197
        let
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   198
          val {leading_zeros = z, value = n, ...} = Syntax.read_xnum num;
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   199
          val _ = z = 0 andalso n >= 0 orelse error ("Bad binary number: " ^ num);
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   200
        in syntax_consts (mk_binary n) end
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   201
    | binary_tr ts = raise TERM ("binary_tr", ts);
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   202
35113
1a0c129bb2e0 modernized translations;
wenzelm
parents: 34974
diff changeset
   203
in [(@{syntax_const "_Binary"}, binary_tr)] end
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   204
*}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   205
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   206
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   207
subsection {* Examples *}
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   208
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   209
lemma "$6 = 6"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   210
  by (simp add: bit_simps)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   211
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   212
lemma "bit (bit (bit 0 False) False) True = 1"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   213
  by (simp add: bit_simps)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   214
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   215
lemma "bit (bit (bit 0 False) False) True = bit 0 True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   216
  by (simp add: bit_simps)
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   217
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   218
lemma "$5 + $3 = $8"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   219
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   220
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   221
lemma "$5 * $3 = $15"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   222
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   223
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   224
lemma "$5 - $3 = $2"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   225
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   226
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   227
lemma "$3 - $5 = 0"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   228
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   229
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   230
lemma "$123456789 - $123 = $123456666"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   231
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   232
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   233
lemma "$1111111111222222222233333333334444444444 - $998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   234
  $1111111111222222222232334455668900112233"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   235
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   236
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   237
lemma "(1111111111222222222233333333334444444444::nat) - 998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   238
  1111111111222222222232334455668900112233"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   239
  by simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   240
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   241
lemma "(1111111111222222222233333333334444444444::int) - 998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   242
  1111111111222222222232334455668900112233"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   243
  by simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   244
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   245
lemma "$1111111111222222222233333333334444444444 * $998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   246
    $1109864072938022197293802219729380221972383090160869185684"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   247
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   248
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   249
lemma "$1111111111222222222233333333334444444444 * $998877665544332211 -
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   250
      $5555555555666666666677777777778888888888 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   251
    $1109864072938022191738246664062713555294605312381980296796"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   252
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   253
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   254
lemma "$42 < $4 = False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   255
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   256
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   257
lemma "$4 < $42 = True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   258
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   259
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   260
lemma "$42 <= $4 = False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   261
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   262
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   263
lemma "$4 <= $42 = True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   264
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   265
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   266
lemma "$1111111111222222222233333333334444444444 < $998877665544332211 = False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   267
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   268
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   269
lemma "$998877665544332211 < $1111111111222222222233333333334444444444 = True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   270
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   271
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   272
lemma "$1111111111222222222233333333334444444444 <= $998877665544332211 = False"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   273
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   274
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   275
lemma "$998877665544332211 <= $1111111111222222222233333333334444444444 = True"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   276
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   277
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   278
lemma "$1234 div $23 = $53"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   279
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   280
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   281
lemma "$1234 mod $23 = $15"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   282
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   283
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   284
lemma "$1111111111222222222233333333334444444444 div $998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   285
    $1112359550673033707875"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   286
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   287
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   288
lemma "$1111111111222222222233333333334444444444 mod $998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   289
    $42245174317582819"
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   290
  by binary_simp
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   291
22153
649e1d769e15 tuned ML setup;
wenzelm
parents: 22148
diff changeset
   292
lemma "(1111111111222222222233333333334444444444::int) div 998877665544332211 =
649e1d769e15 tuned ML setup;
wenzelm
parents: 22148
diff changeset
   293
    1112359550673033707875"
649e1d769e15 tuned ML setup;
wenzelm
parents: 22148
diff changeset
   294
  by simp  -- {* legacy numerals: 30 times slower *}
649e1d769e15 tuned ML setup;
wenzelm
parents: 22148
diff changeset
   295
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   296
lemma "(1111111111222222222233333333334444444444::int) mod 998877665544332211 =
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   297
    42245174317582819"
22153
649e1d769e15 tuned ML setup;
wenzelm
parents: 22148
diff changeset
   298
  by simp  -- {* legacy numerals: 30 times slower *}
22141
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   299
a91334ece12a Simple and efficient binary numerals.
wenzelm
parents:
diff changeset
   300
end