src/HOL/Word/Conversions.thy
author haftmann
Sun, 30 Aug 2020 15:15:28 +0000
changeset 72227 0f3d24dc197f
parent 72198 7ffa26f05c72
child 72240 bb88e31220af
permissions -rw-r--r--
more on conversions
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     1
(*  Author:  Florian Haftmann, TUM
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     2
*)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     3
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     4
section \<open>Proof of concept for conversions for algebraically founded bit word types\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     5
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
     6
theory Conversions
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     7
  imports
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     8
    Main
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
     9
    "HOL-Library.Type_Length"
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    10
    "HOL-Library.Bit_Operations"
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    11
    "HOL-Word.Word"
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    12
begin
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    13
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    14
hide_const (open) unat uint sint word_of_int ucast scast
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    15
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    16
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    17
subsection \<open>Conversions to word\<close>
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    18
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    19
abbreviation word_of_nat :: \<open>nat \<Rightarrow> 'a::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    20
  where \<open>word_of_nat \<equiv> of_nat\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    21
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    22
abbreviation word_of_int :: \<open>int \<Rightarrow> 'a::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    23
  where \<open>word_of_int \<equiv> of_int\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    24
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    25
lemma Word_eq_word_of_int [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    26
  \<open>Word.Word = word_of_int\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    27
  by (rule ext; transfer) simp
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    28
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    29
lemma word_of_nat_eq_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    30
  \<open>word_of_nat m = (word_of_nat n :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) m = take_bit LENGTH('a) n\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    31
  by transfer (simp add: take_bit_of_nat)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    32
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    33
lemma word_of_int_eq_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    34
  \<open>word_of_int k = (word_of_int l :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) k = take_bit LENGTH('a) l\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    35
  by transfer rule
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    36
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    37
lemma word_of_nat_less_eq_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    38
  \<open>word_of_nat m \<le> (word_of_nat n :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) m \<le> take_bit LENGTH('a) n\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    39
  by transfer (simp add: take_bit_of_nat)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    40
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    41
lemma word_of_int_less_eq_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    42
  \<open>word_of_int k \<le> (word_of_int l :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) k \<le> take_bit LENGTH('a) l\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    43
  by transfer rule
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    44
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    45
lemma word_of_nat_less_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    46
  \<open>word_of_nat m < (word_of_nat n :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) m < take_bit LENGTH('a) n\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    47
  by transfer (simp add: take_bit_of_nat)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    48
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    49
lemma word_of_int_less_iff:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    50
  \<open>word_of_int k < (word_of_int l :: 'a::len word) \<longleftrightarrow> take_bit LENGTH('a) k < take_bit LENGTH('a) l\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    51
  by transfer rule
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    52
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    53
lemma word_of_nat_eq_0_iff [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    54
  \<open>word_of_nat n = (0 :: 'a::len word) \<longleftrightarrow> 2 ^ LENGTH('a) dvd n\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    55
  using of_nat_word_eq_iff [where ?'a = 'a, of n 0] by (simp add: take_bit_eq_0_iff)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    56
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    57
lemma word_of_int_eq_0_iff [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    58
  \<open>word_of_int k = (0 :: 'a::len word) \<longleftrightarrow> 2 ^ LENGTH('a) dvd k\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    59
  using of_int_word_eq_iff [where ?'a = 'a, of k 0] by (simp add: take_bit_eq_0_iff)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    60
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    61
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    62
subsection \<open>Conversion from word\<close>
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    63
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    64
subsubsection \<open>Generic unsigned conversion\<close>
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
    65
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    66
context semiring_1
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    67
begin
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    68
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    69
lift_definition unsigned :: \<open>'b::len word \<Rightarrow> 'a\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    70
  is \<open>of_nat \<circ> nat \<circ> take_bit LENGTH('b)\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    71
  by simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    72
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    73
lemma unsigned_0 [simp]:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    74
  \<open>unsigned 0 = 0\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    75
  by transfer simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    76
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    77
lemma unsigned_1 [simp]:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    78
  \<open>unsigned 1 = 1\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    79
  by transfer simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    80
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    81
end
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    82
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    83
context semiring_char_0
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    84
begin
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    85
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    86
lemma unsigned_word_eqI:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    87
  \<open>v = w\<close> if \<open>unsigned v = unsigned w\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    88
  using that by transfer (simp add: eq_nat_nat_iff)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    89
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    90
lemma word_eq_iff_unsigned:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    91
  \<open>v = w \<longleftrightarrow> unsigned v = unsigned w\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    92
  by (auto intro: unsigned_word_eqI)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    93
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    94
end
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
    95
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    96
context semiring_bits
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    97
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    98
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
    99
lemma bit_unsigned_iff:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   100
  \<open>bit (unsigned w) n \<longleftrightarrow> 2 ^ n \<noteq> 0 \<and> bit w n\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   101
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   102
  by (transfer fixing: bit) (simp add: bit_of_nat_iff bit_nat_iff bit_take_bit_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   103
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   104
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   105
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   106
context semiring_bit_shifts
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   107
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   108
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   109
lemma unsigned_push_bit_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   110
  \<open>unsigned (push_bit n w) = take_bit LENGTH('b) (push_bit n (unsigned w))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   111
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   112
proof (rule bit_eqI)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   113
  fix m
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   114
  assume \<open>2 ^ m \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   115
  show \<open>bit (unsigned (push_bit n w)) m = bit (take_bit LENGTH('b) (push_bit n (unsigned w))) m\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   116
  proof (cases \<open>n \<le> m\<close>)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   117
    case True
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   118
    with \<open>2 ^ m \<noteq> 0\<close> have \<open>2 ^ (m - n) \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   119
      by (metis (full_types) diff_add exp_add_not_zero_imp)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   120
    with True show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   121
      by (simp add: bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff ac_simps exp_eq_zero_iff not_le)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   122
  next
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   123
    case False
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   124
    then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   125
      by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   126
  qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   127
qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   128
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   129
lemma unsigned_take_bit_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   130
  \<open>unsigned (take_bit n w) = take_bit n (unsigned w)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   131
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   132
  by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Parity.bit_take_bit_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   133
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   134
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   135
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   136
context semiring_bit_operations
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   137
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   138
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   139
lemma unsigned_and_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   140
  \<open>unsigned (v AND w) = unsigned v AND unsigned w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   141
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   142
  by (rule bit_eqI) (simp add: bit_unsigned_iff bit_and_iff Bit_Operations.bit_and_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   143
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   144
lemma unsigned_or_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   145
  \<open>unsigned (v OR w) = unsigned v OR unsigned w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   146
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   147
  by (rule bit_eqI) (simp add: bit_unsigned_iff bit_or_iff Bit_Operations.bit_or_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   148
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   149
lemma unsigned_xor_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   150
  \<open>unsigned (v XOR w) = unsigned v XOR unsigned w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   151
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   152
  by (rule bit_eqI) (simp add: bit_unsigned_iff bit_xor_iff Bit_Operations.bit_xor_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   153
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   154
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   155
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   156
context ring_bit_operations
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   157
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   158
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   159
lemma unsigned_not_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   160
  \<open>unsigned (NOT w) = take_bit LENGTH('b) (NOT (unsigned w))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   161
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   162
  by (rule bit_eqI)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   163
    (simp add: bit_unsigned_iff bit_take_bit_iff bit_not_iff Bit_Operations.bit_not_iff exp_eq_zero_iff not_le)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   164
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   165
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   166
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   167
lemma unsigned_of_nat [simp]:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   168
  \<open>unsigned (word_of_nat n :: 'a::len word) = of_nat (take_bit LENGTH('a) n)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   169
  by transfer (simp add: nat_eq_iff take_bit_of_nat)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   170
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   171
lemma unsigned_of_int [simp]:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   172
  \<open>unsigned (word_of_int n :: 'a::len word) = of_int (take_bit LENGTH('a) n)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   173
  by transfer (simp add: nat_eq_iff take_bit_of_nat)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   174
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   175
context unique_euclidean_semiring_numeral
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   176
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   177
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   178
lemma unsigned_greater_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   179
  \<open>0 \<le> unsigned w\<close> for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   180
  by (transfer fixing: less_eq) simp
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   181
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   182
lemma unsigned_less:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   183
  \<open>unsigned w < 2 ^ LENGTH('b)\<close> for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   184
  by (transfer fixing: less) (simp add: take_bit_int_less_exp)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   185
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   186
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   187
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   188
context linordered_semidom
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   189
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   190
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   191
lemma word_less_eq_iff_unsigned:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   192
  "a \<le> b \<longleftrightarrow> unsigned a \<le> unsigned b"
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   193
  by (transfer fixing: less_eq) (simp add: nat_le_eq_zle)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   194
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   195
lemma word_less_iff_unsigned:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   196
  "a < b \<longleftrightarrow> unsigned a < unsigned b"
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   197
  by (transfer fixing: less) (auto dest: preorder_class.le_less_trans [OF take_bit_nonnegative])
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   198
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   199
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   200
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   201
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   202
subsubsection \<open>Generic signed conversion\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   203
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   204
context ring_1
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   205
begin
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   206
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   207
lift_definition signed :: \<open>'b::len word \<Rightarrow> 'a\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   208
  is \<open>of_int \<circ> signed_take_bit (LENGTH('b) - 1)\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   209
  by (simp flip: signed_take_bit_decr_length_iff)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   210
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   211
lemma signed_0 [simp]:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   212
  \<open>signed 0 = 0\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   213
  by transfer simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   214
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   215
lemma signed_1 [simp]:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   216
  \<open>signed (1 :: 'b::len word) = (if LENGTH('b) = 1 then - 1 else 1)\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   217
  by (transfer fixing: uminus)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   218
    (simp_all add: signed_take_bit_eq not_le Suc_lessI)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   219
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   220
lemma signed_minus_1 [simp]:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   221
  \<open>signed (- 1 :: 'b::len word) = - 1\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   222
  by (transfer fixing: uminus) simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   223
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   224
end
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   225
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   226
context ring_char_0
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   227
begin
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   228
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   229
lemma signed_word_eqI:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   230
  \<open>v = w\<close> if \<open>signed v = signed w\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   231
  using that by transfer (simp flip: signed_take_bit_decr_length_iff)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   232
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   233
lemma word_eq_iff_signed:
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   234
  \<open>v = w \<longleftrightarrow> signed v = signed w\<close>
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   235
  by (auto intro: signed_word_eqI)
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   236
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   237
end
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   238
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   239
context ring_bit_operations
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   240
begin
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   241
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   242
lemma bit_signed_iff:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   243
  \<open>bit (signed w) n \<longleftrightarrow> 2 ^ n \<noteq> 0 \<and> bit w (min (LENGTH('b) - Suc 0) n)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   244
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   245
  by (transfer fixing: bit) (auto simp add: bit_of_int_iff bit_signed_take_bit_iff min_def)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   246
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   247
lemma signed_push_bit_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   248
  \<open>signed (push_bit n w) = take_bit (LENGTH('b) - Suc 0) (push_bit n (signed w))
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   249
    OR of_bool (n < LENGTH('b) \<and> bit w (LENGTH('b) - Suc n)) * NOT (mask (LENGTH('b) - Suc 0))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   250
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   251
proof (rule bit_eqI)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   252
  fix m
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   253
  assume \<open>2 ^ m \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   254
  define q where \<open>q = LENGTH('b) - Suc 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   255
  then have *: \<open>LENGTH('b) = Suc q\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   256
    by simp
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   257
  show \<open>bit (signed (push_bit n w)) m \<longleftrightarrow>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   258
    bit (take_bit (LENGTH('b) - Suc 0) (push_bit n (signed w)) OR
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   259
      of_bool (n < LENGTH('b) \<and> bit w (LENGTH('b) - Suc n)) * NOT (mask (LENGTH('b) - Suc 0))) m\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   260
  proof (cases \<open>n \<le> m\<close>)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   261
    case True
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   262
    with \<open>2 ^ m \<noteq> 0\<close> have \<open>2 ^ (m - n) \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   263
      by (metis (full_types) diff_add exp_add_not_zero_imp)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   264
    with True show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   265
      by (auto simp add: * bit_signed_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_or_iff bit_take_bit_iff bit_not_iff bit_mask_iff exp_eq_zero_iff min_def)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   266
  next
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   267
    case False
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   268
    then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   269
      by (simp add: * bit_signed_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_or_iff bit_take_bit_iff bit_not_iff bit_mask_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   270
  qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   271
qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   272
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   273
lemma signed_take_bit_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   274
  \<open>signed (take_bit n w) = (if n < LENGTH('b) then take_bit n (signed w) else signed w)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   275
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   276
  by (transfer fixing: take_bit; cases \<open>LENGTH('b)\<close>)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   277
    (auto simp add: signed_take_bit_take_bit take_bit_signed_take_bit take_bit_of_int min_def)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   278
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   279
lemma signed_not_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   280
  \<open>signed (NOT w) = take_bit LENGTH('b) (NOT (signed w)) OR of_bool (bit (NOT (signed w)) LENGTH('b)) * NOT (mask LENGTH('b))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   281
  for w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   282
proof (rule bit_eqI)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   283
  fix n
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   284
  assume \<open>2 ^ n \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   285
  show \<open>bit (signed (NOT w)) n \<longleftrightarrow>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   286
    bit (take_bit LENGTH('b) (NOT (signed w)) OR
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   287
    of_bool (bit (NOT (signed w)) LENGTH('b)) * NOT (mask LENGTH('b))) n\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   288
  proof (cases \<open>LENGTH('b) \<le> n\<close>)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   289
    case False
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   290
    then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   291
      by (auto simp add: bit_signed_iff bit_not_iff bit_or_iff bit_take_bit_iff bit_mask_iff Bit_Operations.bit_not_iff exp_eq_zero_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   292
  next
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   293
    case True
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   294
    moreover define q where \<open>q = n - LENGTH('b)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   295
    ultimately have \<open>n = LENGTH('b) + q\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   296
      by simp
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   297
    with \<open>2 ^ n \<noteq> 0\<close> have \<open>2 ^ q \<noteq> 0\<close> \<open>2 ^ LENGTH('b) \<noteq> 0\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   298
      by (simp_all add: power_add) (use mult_not_zero in blast)+
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   299
    then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   300
      by (simp add: bit_signed_iff bit_not_iff bit_or_iff bit_take_bit_iff bit_mask_iff Bit_Operations.bit_not_iff exp_eq_zero_iff min_def not_le not_less le_diff_conv le_Suc_eq)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   301
  qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   302
qed
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   303
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   304
lemma signed_and_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   305
  \<open>signed (v AND w) = signed v AND signed w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   306
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   307
  by (rule bit_eqI) (simp add: bit_signed_iff bit_and_iff Bit_Operations.bit_and_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   308
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   309
lemma signed_or_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   310
  \<open>signed (v OR w) = signed v OR signed w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   311
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   312
  by (rule bit_eqI) (simp add: bit_signed_iff bit_or_iff Bit_Operations.bit_or_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   313
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   314
lemma signed_xor_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   315
  \<open>signed (v XOR w) = signed v XOR signed w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   316
  for v w :: \<open>'b::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   317
  by (rule bit_eqI) (simp add: bit_signed_iff bit_xor_iff Bit_Operations.bit_xor_iff)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   318
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   319
end
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   320
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   321
lemma signed_of_nat [simp]:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   322
  \<open>signed (word_of_nat n :: 'a::len word) = of_int (signed_take_bit (LENGTH('a) - Suc 0) (int n))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   323
  by transfer simp
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   324
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   325
lemma signed_of_int [simp]:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   326
  \<open>signed (word_of_int n :: 'a::len word) = of_int (signed_take_bit (LENGTH('a) - Suc 0) n)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   327
  by transfer simp
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   328
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   329
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   330
subsubsection \<open>Important special cases\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   331
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   332
abbreviation unat :: \<open>'a::len word \<Rightarrow> nat\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   333
  where \<open>unat \<equiv> unsigned\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   334
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   335
abbreviation uint :: \<open>'a::len word \<Rightarrow> int\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   336
  where \<open>uint \<equiv> unsigned\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   337
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   338
abbreviation sint :: \<open>'a::len word \<Rightarrow> int\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   339
  where \<open>sint \<equiv> signed\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   340
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   341
abbreviation ucast :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   342
  where \<open>ucast \<equiv> unsigned\<close>
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   343
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   344
abbreviation scast :: \<open>'a::len word \<Rightarrow> 'b::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   345
  where \<open>scast \<equiv> signed\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   346
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   347
context
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   348
  includes lifting_syntax
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   349
begin
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   350
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   351
lemma [transfer_rule]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   352
  \<open>(pcr_word ===> (=)) (nat \<circ> take_bit LENGTH('a)) (unat :: 'a::len word \<Rightarrow> nat)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   353
  using unsigned.transfer [where ?'a = nat] by simp
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   354
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   355
lemma [transfer_rule]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   356
  \<open>(pcr_word ===> (=)) (take_bit LENGTH('a)) (uint :: 'a::len word \<Rightarrow> int)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   357
  using unsigned.transfer [where ?'a = int] by (simp add: comp_def)
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   358
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   359
lemma [transfer_rule]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   360
  \<open>(pcr_word ===> (=)) (signed_take_bit (LENGTH('a) - Suc 0)) (sint :: 'a::len word \<Rightarrow> int)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   361
  using signed.transfer [where ?'a = int] by simp
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   362
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   363
lemma [transfer_rule]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   364
  \<open>(pcr_word ===> pcr_word) (take_bit LENGTH('a)) (ucast :: 'a::len word \<Rightarrow> 'b::len word)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   365
proof (rule rel_funI)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   366
  fix k :: int and w :: \<open>'a word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   367
  assume \<open>pcr_word k w\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   368
  then have \<open>w = word_of_int k\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   369
    by (simp add: pcr_word_def cr_word_def relcompp_apply)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   370
  moreover have \<open>pcr_word (take_bit LENGTH('a) k) (ucast (word_of_int k :: 'a word))\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   371
    by transfer (simp add: pcr_word_def cr_word_def relcompp_apply)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   372
  ultimately show \<open>pcr_word (take_bit LENGTH('a) k) (ucast w)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   373
    by simp
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   374
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   375
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   376
lemma [transfer_rule]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   377
  \<open>(pcr_word ===> pcr_word) (signed_take_bit (LENGTH('a) - 1)) (scast :: 'a::len word \<Rightarrow> 'b::len word)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   378
proof (rule rel_funI)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   379
  fix k :: int and w :: \<open>'a word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   380
  assume \<open>pcr_word k w\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   381
  then have \<open>w = word_of_int k\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   382
    by (simp add: pcr_word_def cr_word_def relcompp_apply)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   383
  moreover have \<open>pcr_word (signed_take_bit (LENGTH('a) - 1) k) (scast (word_of_int k :: 'a word))\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   384
    by transfer (simp add: pcr_word_def cr_word_def relcompp_apply)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   385
  ultimately show \<open>pcr_word (signed_take_bit (LENGTH('a) - 1) k) (scast w)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   386
    by simp
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   387
qed
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   388
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   389
end
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   390
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   391
lemma of_nat_unat [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   392
  \<open>of_nat (unat w) = unsigned w\<close>
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   393
  by transfer simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   394
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   395
lemma of_int_uint [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   396
  \<open>of_int (uint w) = unsigned w\<close>
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   397
  by transfer simp
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   398
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   399
lemma unat_div_distrib:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   400
  \<open>unat (v div w) = unat v div unat w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   401
proof transfer
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   402
  fix k l
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   403
  have \<open>nat (take_bit LENGTH('a) k) div nat (take_bit LENGTH('a) l) \<le> nat (take_bit LENGTH('a) k)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   404
    by (rule div_le_dividend)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   405
  also have \<open>nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   406
    by (simp add: nat_less_iff take_bit_int_less_exp)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   407
  finally show \<open>(nat \<circ> take_bit LENGTH('a)) (take_bit LENGTH('a) k div take_bit LENGTH('a) l) =
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   408
    (nat \<circ> take_bit LENGTH('a)) k div (nat \<circ> take_bit LENGTH('a)) l\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   409
    by (simp add: nat_take_bit_eq div_int_pos_iff nat_div_distrib take_bit_eq_self)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   410
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   411
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   412
lemma unat_mod_distrib:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   413
  \<open>unat (v mod w) = unat v mod unat w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   414
proof transfer
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   415
  fix k l
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   416
  have \<open>nat (take_bit LENGTH('a) k) mod nat (take_bit LENGTH('a) l) \<le> nat (take_bit LENGTH('a) k)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   417
    by (rule mod_less_eq_dividend)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   418
  also have \<open>nat (take_bit LENGTH('a) k) < 2 ^ LENGTH('a)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   419
    by (simp add: nat_less_iff take_bit_int_less_exp)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   420
  finally show \<open>(nat \<circ> take_bit LENGTH('a)) (take_bit LENGTH('a) k mod take_bit LENGTH('a) l) =
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   421
    (nat \<circ> take_bit LENGTH('a)) k mod (nat \<circ> take_bit LENGTH('a)) l\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   422
    by (simp add: nat_take_bit_eq mod_int_pos_iff less_le nat_mod_distrib take_bit_eq_self)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   423
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   424
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   425
lemma uint_div_distrib:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   426
  \<open>uint (v div w) = uint v div uint w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   427
proof -
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   428
  have \<open>int (unat (v div w)) = int (unat v div unat w)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   429
    by (simp add: unat_div_distrib)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   430
  then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   431
    by (simp add: of_nat_div)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   432
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   433
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   434
lemma uint_mod_distrib:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   435
  \<open>uint (v mod w) = uint v mod uint w\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   436
proof -
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   437
  have \<open>int (unat (v mod w)) = int (unat v mod unat w)\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   438
    by (simp add: unat_mod_distrib)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   439
  then show ?thesis
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   440
    by (simp add: of_nat_mod)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   441
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   442
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   443
lemma of_int_sint [simp]:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   444
  \<open>of_int (sint a) = signed a\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   445
  by transfer (simp_all add: take_bit_signed_take_bit)
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   446
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   447
lemma sint_not_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   448
  \<open>sint (NOT w) = signed_take_bit LENGTH('a) (NOT (sint w))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   449
  for w :: \<open>'a::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   450
  by (simp add: signed_not_eq signed_take_bit_unfold)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   451
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   452
lemma sint_push_bit_eq:
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   453
  \<open>signed (push_bit n w) = signed_take_bit (LENGTH('a) - 1) (push_bit n (signed w))\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   454
  for w :: \<open>'a::len word\<close>
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   455
  by (transfer fixing: n; cases \<open>LENGTH('a)\<close>)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   456
     (auto simp add: signed_take_bit_def bit_concat_bit_iff bit_push_bit_iff bit_take_bit_iff bit_or_iff le_diff_conv2,
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   457
        auto simp add: take_bit_push_bit not_less concat_bit_eq_iff take_bit_concat_bit_eq le_diff_conv2)
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   458
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   459
lemma sint_greater_eq:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   460
  \<open>- (2 ^ (LENGTH('a) - 1)) \<le> sint w\<close> for w :: \<open>'a::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   461
proof (cases \<open>bit w (LENGTH('a) - 1)\<close>)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   462
  case True
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   463
  then show ?thesis
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   464
    by transfer (simp add: signed_take_bit_eq_or minus_exp_eq_not_mask or_greater_eq ac_simps)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   465
next
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   466
  have *: \<open>- (2 ^ (LENGTH('a) - Suc 0)) \<le> (0::int)\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   467
    by simp
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   468
  case False
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   469
  then show ?thesis
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   470
    by transfer (auto simp add: signed_take_bit_eq intro: order_trans *)
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   471
qed
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   472
72198
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   473
lemma sint_less:
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   474
  \<open>sint w < 2 ^ (LENGTH('a) - 1)\<close> for w :: \<open>'a::len word\<close>
7ffa26f05c72 a proof of concept for generic conversions
haftmann
parents: 72129
diff changeset
   475
  by (cases \<open>bit w (LENGTH('a) - 1)\<close>; transfer)
72227
0f3d24dc197f more on conversions
haftmann
parents: 72198
diff changeset
   476
    (simp_all add: signed_take_bit_eq signed_take_bit_unfold take_bit_int_less_exp not_eq_complement mask_eq_exp_minus_1 OR_upper)
72102
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   477
0b21b2beadb5 tailored towards remaining essence
haftmann
parents:
diff changeset
   478
end