author | nipkow |
Thu, 30 May 2002 10:12:52 +0200 | |
changeset 13187 | e5434b822a96 |
parent 12613 | 279facb4253a |
child 13192 | e961c197f141 |
permissions | -rw-r--r-- |
paulson@5545 | 1 |
(* Title: HOL/ex/BinEx.thy |
paulson@5545 | 2 |
ID: $Id$ |
paulson@5545 | 3 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
paulson@5545 | 4 |
Copyright 1998 University of Cambridge |
paulson@5545 | 5 |
*) |
paulson@5545 | 6 |
|
wenzelm@11024 | 7 |
header {* Binary arithmetic examples *} |
paulson@5545 | 8 |
|
wenzelm@11024 | 9 |
theory BinEx = Main: |
wenzelm@11024 | 10 |
|
wenzelm@11024 | 11 |
subsection {* The Integers *} |
wenzelm@11024 | 12 |
|
wenzelm@11024 | 13 |
text {* Addition *} |
wenzelm@11024 | 14 |
|
wenzelm@11704 | 15 |
lemma "(13::int) + 19 = 32" |
wenzelm@11024 | 16 |
by simp |
wenzelm@11024 | 17 |
|
wenzelm@11704 | 18 |
lemma "(1234::int) + 5678 = 6912" |
wenzelm@11024 | 19 |
by simp |
wenzelm@11024 | 20 |
|
wenzelm@11704 | 21 |
lemma "(1359::int) + -2468 = -1109" |
wenzelm@11024 | 22 |
by simp |
wenzelm@11024 | 23 |
|
wenzelm@11704 | 24 |
lemma "(93746::int) + -46375 = 47371" |
wenzelm@11024 | 25 |
by simp |
wenzelm@11024 | 26 |
|
wenzelm@11024 | 27 |
|
wenzelm@11024 | 28 |
text {* \medskip Negation *} |
wenzelm@11024 | 29 |
|
wenzelm@11704 | 30 |
lemma "- (65745::int) = -65745" |
wenzelm@11024 | 31 |
by simp |
wenzelm@11024 | 32 |
|
wenzelm@11704 | 33 |
lemma "- (-54321::int) = 54321" |
wenzelm@11024 | 34 |
by simp |
wenzelm@11024 | 35 |
|
wenzelm@11024 | 36 |
|
wenzelm@11024 | 37 |
text {* \medskip Multiplication *} |
wenzelm@11024 | 38 |
|
wenzelm@11704 | 39 |
lemma "(13::int) * 19 = 247" |
wenzelm@11024 | 40 |
by simp |
wenzelm@11024 | 41 |
|
wenzelm@11704 | 42 |
lemma "(-84::int) * 51 = -4284" |
wenzelm@11024 | 43 |
by simp |
wenzelm@11024 | 44 |
|
wenzelm@11704 | 45 |
lemma "(255::int) * 255 = 65025" |
wenzelm@11024 | 46 |
by simp |
wenzelm@11024 | 47 |
|
wenzelm@11704 | 48 |
lemma "(1359::int) * -2468 = -3354012" |
wenzelm@11024 | 49 |
by simp |
wenzelm@11024 | 50 |
|
wenzelm@11704 | 51 |
lemma "(89::int) * 10 \<noteq> 889" |
wenzelm@11024 | 52 |
by simp |
wenzelm@11024 | 53 |
|
wenzelm@11704 | 54 |
lemma "(13::int) < 18 - 4" |
wenzelm@11024 | 55 |
by simp |
wenzelm@11024 | 56 |
|
wenzelm@11704 | 57 |
lemma "(-345::int) < -242 + -100" |
wenzelm@11024 | 58 |
by simp |
wenzelm@11024 | 59 |
|
wenzelm@11704 | 60 |
lemma "(13557456::int) < 18678654" |
wenzelm@11024 | 61 |
by simp |
wenzelm@11024 | 62 |
|
paulson@11868 | 63 |
lemma "(999999::int) \<le> (1000001 + 1) - 2" |
wenzelm@11024 | 64 |
by simp |
wenzelm@11024 | 65 |
|
wenzelm@11704 | 66 |
lemma "(1234567::int) \<le> 1234567" |
wenzelm@11024 | 67 |
by simp |
wenzelm@11024 | 68 |
|
wenzelm@11024 | 69 |
|
wenzelm@11024 | 70 |
text {* \medskip Quotient and Remainder *} |
wenzelm@11024 | 71 |
|
wenzelm@11704 | 72 |
lemma "(10::int) div 3 = 3" |
wenzelm@11024 | 73 |
by simp |
wenzelm@11024 | 74 |
|
paulson@11868 | 75 |
lemma "(10::int) mod 3 = 1" |
wenzelm@11024 | 76 |
by simp |
wenzelm@11024 | 77 |
|
wenzelm@11024 | 78 |
text {* A negative divisor *} |
wenzelm@11024 | 79 |
|
wenzelm@11704 | 80 |
lemma "(10::int) div -3 = -4" |
wenzelm@11024 | 81 |
by simp |
wenzelm@11024 | 82 |
|
wenzelm@11704 | 83 |
lemma "(10::int) mod -3 = -2" |
wenzelm@11024 | 84 |
by simp |
wenzelm@11024 | 85 |
|
wenzelm@11024 | 86 |
text {* |
wenzelm@11024 | 87 |
A negative dividend\footnote{The definition agrees with mathematical |
wenzelm@11024 | 88 |
convention but not with the hardware of most computers} |
wenzelm@11024 | 89 |
*} |
wenzelm@11024 | 90 |
|
wenzelm@11704 | 91 |
lemma "(-10::int) div 3 = -4" |
wenzelm@11024 | 92 |
by simp |
wenzelm@11024 | 93 |
|
wenzelm@11704 | 94 |
lemma "(-10::int) mod 3 = 2" |
wenzelm@11024 | 95 |
by simp |
wenzelm@11024 | 96 |
|
wenzelm@11024 | 97 |
text {* A negative dividend \emph{and} divisor *} |
wenzelm@11024 | 98 |
|
wenzelm@11704 | 99 |
lemma "(-10::int) div -3 = 3" |
wenzelm@11024 | 100 |
by simp |
wenzelm@11024 | 101 |
|
wenzelm@11704 | 102 |
lemma "(-10::int) mod -3 = -1" |
wenzelm@11024 | 103 |
by simp |
wenzelm@11024 | 104 |
|
wenzelm@11024 | 105 |
text {* A few bigger examples *} |
wenzelm@11024 | 106 |
|
paulson@11868 | 107 |
lemma "(8452::int) mod 3 = 1" |
wenzelm@11024 | 108 |
by simp |
wenzelm@11024 | 109 |
|
wenzelm@11704 | 110 |
lemma "(59485::int) div 434 = 137" |
wenzelm@11024 | 111 |
by simp |
wenzelm@11024 | 112 |
|
wenzelm@11704 | 113 |
lemma "(1000006::int) mod 10 = 6" |
wenzelm@11024 | 114 |
by simp |
wenzelm@11024 | 115 |
|
wenzelm@11024 | 116 |
|
wenzelm@11024 | 117 |
text {* \medskip Division by shifting *} |
wenzelm@11024 | 118 |
|
wenzelm@11704 | 119 |
lemma "10000000 div 2 = (5000000::int)" |
wenzelm@11024 | 120 |
by simp |
wenzelm@11024 | 121 |
|
paulson@11868 | 122 |
lemma "10000001 mod 2 = (1::int)" |
wenzelm@11024 | 123 |
by simp |
wenzelm@11024 | 124 |
|
wenzelm@11704 | 125 |
lemma "10000055 div 32 = (312501::int)" |
wenzelm@11024 | 126 |
by simp |
wenzelm@11024 | 127 |
|
wenzelm@11704 | 128 |
lemma "10000055 mod 32 = (23::int)" |
wenzelm@11024 | 129 |
by simp |
wenzelm@11024 | 130 |
|
wenzelm@11704 | 131 |
lemma "100094 div 144 = (695::int)" |
wenzelm@11024 | 132 |
by simp |
wenzelm@11024 | 133 |
|
wenzelm@11704 | 134 |
lemma "100094 mod 144 = (14::int)" |
wenzelm@11024 | 135 |
by simp |
wenzelm@11024 | 136 |
|
wenzelm@11024 | 137 |
|
paulson@12613 | 138 |
text {* \medskip Powers *} |
paulson@12613 | 139 |
|
paulson@12613 | 140 |
lemma "2 ^ 10 = (1024::int)" |
paulson@12613 | 141 |
by simp |
paulson@12613 | 142 |
|
paulson@12613 | 143 |
lemma "-3 ^ 7 = (-2187::int)" |
paulson@12613 | 144 |
by simp |
paulson@12613 | 145 |
|
paulson@12613 | 146 |
lemma "13 ^ 7 = (62748517::int)" |
paulson@12613 | 147 |
by simp |
paulson@12613 | 148 |
|
paulson@12613 | 149 |
lemma "3 ^ 15 = (14348907::int)" |
paulson@12613 | 150 |
by simp |
paulson@12613 | 151 |
|
paulson@12613 | 152 |
lemma "-5 ^ 11 = (-48828125::int)" |
paulson@12613 | 153 |
by simp |
paulson@12613 | 154 |
|
paulson@12613 | 155 |
|
wenzelm@11024 | 156 |
subsection {* The Natural Numbers *} |
wenzelm@11024 | 157 |
|
wenzelm@11024 | 158 |
text {* Successor *} |
wenzelm@11024 | 159 |
|
wenzelm@11704 | 160 |
lemma "Suc 99999 = 100000" |
wenzelm@11024 | 161 |
by (simp add: Suc_nat_number_of) |
wenzelm@11024 | 162 |
-- {* not a default rewrite since sometimes we want to have @{text "Suc #nnn"} *} |
wenzelm@11024 | 163 |
|
wenzelm@11024 | 164 |
|
wenzelm@11024 | 165 |
text {* \medskip Addition *} |
wenzelm@11024 | 166 |
|
wenzelm@11704 | 167 |
lemma "(13::nat) + 19 = 32" |
wenzelm@11024 | 168 |
by simp |
wenzelm@11024 | 169 |
|
wenzelm@11704 | 170 |
lemma "(1234::nat) + 5678 = 6912" |
wenzelm@11024 | 171 |
by simp |
wenzelm@11024 | 172 |
|
wenzelm@11704 | 173 |
lemma "(973646::nat) + 6475 = 980121" |
wenzelm@11024 | 174 |
by simp |
wenzelm@11024 | 175 |
|
wenzelm@11024 | 176 |
|
wenzelm@11024 | 177 |
text {* \medskip Subtraction *} |
wenzelm@11024 | 178 |
|
wenzelm@11704 | 179 |
lemma "(32::nat) - 14 = 18" |
wenzelm@11024 | 180 |
by simp |
wenzelm@11024 | 181 |
|
paulson@11868 | 182 |
lemma "(14::nat) - 15 = 0" |
wenzelm@11024 | 183 |
by simp |
wenzelm@11024 | 184 |
|
paulson@11868 | 185 |
lemma "(14::nat) - 1576644 = 0" |
wenzelm@11024 | 186 |
by simp |
wenzelm@11024 | 187 |
|
wenzelm@11704 | 188 |
lemma "(48273776::nat) - 3873737 = 44400039" |
wenzelm@11024 | 189 |
by simp |
wenzelm@11024 | 190 |
|
wenzelm@11024 | 191 |
|
wenzelm@11024 | 192 |
text {* \medskip Multiplication *} |
wenzelm@11024 | 193 |
|
wenzelm@11704 | 194 |
lemma "(12::nat) * 11 = 132" |
wenzelm@11024 | 195 |
by simp |
wenzelm@11024 | 196 |
|
wenzelm@11704 | 197 |
lemma "(647::nat) * 3643 = 2357021" |
wenzelm@11024 | 198 |
by simp |
wenzelm@11024 | 199 |
|
wenzelm@11024 | 200 |
|
wenzelm@11024 | 201 |
text {* \medskip Quotient and Remainder *} |
wenzelm@11024 | 202 |
|
wenzelm@11704 | 203 |
lemma "(10::nat) div 3 = 3" |
wenzelm@11024 | 204 |
by simp |
wenzelm@11024 | 205 |
|
paulson@11868 | 206 |
lemma "(10::nat) mod 3 = 1" |
wenzelm@11024 | 207 |
by simp |
wenzelm@11024 | 208 |
|
wenzelm@11704 | 209 |
lemma "(10000::nat) div 9 = 1111" |
wenzelm@11024 | 210 |
by simp |
wenzelm@11024 | 211 |
|
paulson@11868 | 212 |
lemma "(10000::nat) mod 9 = 1" |
wenzelm@11024 | 213 |
by simp |
wenzelm@11024 | 214 |
|
wenzelm@11704 | 215 |
lemma "(10000::nat) div 16 = 625" |
wenzelm@11024 | 216 |
by simp |
wenzelm@11024 | 217 |
|
paulson@11868 | 218 |
lemma "(10000::nat) mod 16 = 0" |
wenzelm@11024 | 219 |
by simp |
wenzelm@11024 | 220 |
|
wenzelm@11024 | 221 |
|
paulson@12613 | 222 |
text {* \medskip Powers *} |
paulson@12613 | 223 |
|
paulson@12613 | 224 |
lemma "2 ^ 12 = (4096::nat)" |
paulson@12613 | 225 |
by simp |
paulson@12613 | 226 |
|
paulson@12613 | 227 |
lemma "3 ^ 10 = (59049::nat)" |
paulson@12613 | 228 |
by simp |
paulson@12613 | 229 |
|
paulson@12613 | 230 |
lemma "12 ^ 7 = (35831808::nat)" |
paulson@12613 | 231 |
by simp |
paulson@12613 | 232 |
|
paulson@12613 | 233 |
lemma "3 ^ 14 = (4782969::nat)" |
paulson@12613 | 234 |
by simp |
paulson@12613 | 235 |
|
paulson@12613 | 236 |
lemma "5 ^ 11 = (48828125::nat)" |
paulson@12613 | 237 |
by simp |
paulson@12613 | 238 |
|
paulson@12613 | 239 |
|
wenzelm@11024 | 240 |
text {* \medskip Testing the cancellation of complementary terms *} |
wenzelm@11024 | 241 |
|
paulson@11868 | 242 |
lemma "y + (x + -x) = (0::int) + y" |
wenzelm@11024 | 243 |
by simp |
wenzelm@11024 | 244 |
|
paulson@11868 | 245 |
lemma "y + (-x + (- y + x)) = (0::int)" |
wenzelm@11024 | 246 |
by simp |
wenzelm@11024 | 247 |
|
paulson@11868 | 248 |
lemma "-x + (y + (- y + x)) = (0::int)" |
wenzelm@11024 | 249 |
by simp |
wenzelm@11024 | 250 |
|
paulson@11868 | 251 |
lemma "x + (x + (- x + (- x + (- y + - z)))) = (0::int) - y - z" |
wenzelm@11024 | 252 |
by simp |
wenzelm@11024 | 253 |
|
paulson@11868 | 254 |
lemma "x + x - x - x - y - z = (0::int) - y - z" |
wenzelm@11024 | 255 |
by simp |
wenzelm@11024 | 256 |
|
paulson@11868 | 257 |
lemma "x + y + z - (x + z) = y - (0::int)" |
wenzelm@11024 | 258 |
by simp |
wenzelm@11024 | 259 |
|
paulson@11868 | 260 |
lemma "x + (y + (y + (y + (-x + -x)))) = (0::int) + y - x + y + y" |
wenzelm@11024 | 261 |
by simp |
wenzelm@11024 | 262 |
|
paulson@11868 | 263 |
lemma "x + (y + (y + (y + (-y + -x)))) = y + (0::int) + y" |
wenzelm@11024 | 264 |
by simp |
wenzelm@11024 | 265 |
|
paulson@11868 | 266 |
lemma "x + y - x + z - x - y - z + x < (1::int)" |
wenzelm@11024 | 267 |
by simp |
wenzelm@11024 | 268 |
|
wenzelm@11024 | 269 |
|
wenzelm@11024 | 270 |
subsection {* Normal form of bit strings *} |
wenzelm@11024 | 271 |
|
wenzelm@11024 | 272 |
text {* |
wenzelm@11024 | 273 |
Definition of normal form for proving that binary arithmetic on |
wenzelm@11024 | 274 |
normalized operands yields normalized results. Normal means no |
wenzelm@11024 | 275 |
leading 0s on positive numbers and no leading 1s on negatives. |
wenzelm@11024 | 276 |
*} |
wenzelm@11024 | 277 |
|
wenzelm@11024 | 278 |
consts normal :: "bin set" |
wenzelm@11637 | 279 |
inductive normal |
wenzelm@11637 | 280 |
intros |
wenzelm@11637 | 281 |
Pls [simp]: "Pls: normal" |
wenzelm@11637 | 282 |
Min [simp]: "Min: normal" |
wenzelm@11637 | 283 |
BIT_F [simp]: "w: normal ==> w \<noteq> Pls ==> w BIT False : normal" |
wenzelm@11637 | 284 |
BIT_T [simp]: "w: normal ==> w \<noteq> Min ==> w BIT True : normal" |
paulson@5545 | 285 |
|
wenzelm@11024 | 286 |
text {* |
wenzelm@11024 | 287 |
\medskip Binary arithmetic on normalized operands yields normalized |
wenzelm@11024 | 288 |
results. |
wenzelm@11024 | 289 |
*} |
paulson@5545 | 290 |
|
wenzelm@11024 | 291 |
lemma normal_BIT_I [simp]: "w BIT b \<in> normal ==> w BIT b BIT c \<in> normal" |
wenzelm@11024 | 292 |
apply (case_tac c) |
wenzelm@11024 | 293 |
apply auto |
wenzelm@11024 | 294 |
done |
paulson@5545 | 295 |
|
wenzelm@11024 | 296 |
lemma normal_BIT_D: "w BIT b \<in> normal ==> w \<in> normal" |
wenzelm@11024 | 297 |
apply (erule normal.cases) |
wenzelm@11024 | 298 |
apply auto |
wenzelm@11024 | 299 |
done |
paulson@5545 | 300 |
|
wenzelm@11024 | 301 |
lemma NCons_normal [simp]: "w \<in> normal ==> NCons w b \<in> normal" |
wenzelm@11024 | 302 |
apply (induct w) |
wenzelm@11024 | 303 |
apply (auto simp add: NCons_Pls NCons_Min) |
wenzelm@11024 | 304 |
done |
wenzelm@11024 | 305 |
|
wenzelm@11024 | 306 |
lemma NCons_True: "NCons w True \<noteq> Pls" |
wenzelm@11024 | 307 |
apply (induct w) |
wenzelm@11024 | 308 |
apply auto |
wenzelm@11024 | 309 |
done |
wenzelm@11024 | 310 |
|
wenzelm@11024 | 311 |
lemma NCons_False: "NCons w False \<noteq> Min" |
wenzelm@11024 | 312 |
apply (induct w) |
wenzelm@11024 | 313 |
apply auto |
wenzelm@11024 | 314 |
done |
wenzelm@11024 | 315 |
|
wenzelm@11024 | 316 |
lemma bin_succ_normal [simp]: "w \<in> normal ==> bin_succ w \<in> normal" |
wenzelm@11024 | 317 |
apply (erule normal.induct) |
wenzelm@11024 | 318 |
apply (case_tac [4] w) |
wenzelm@11024 | 319 |
apply (auto simp add: NCons_True bin_succ_BIT) |
wenzelm@11024 | 320 |
done |
wenzelm@11024 | 321 |
|
wenzelm@11024 | 322 |
lemma bin_pred_normal [simp]: "w \<in> normal ==> bin_pred w \<in> normal" |
wenzelm@11024 | 323 |
apply (erule normal.induct) |
wenzelm@11024 | 324 |
apply (case_tac [3] w) |
wenzelm@11024 | 325 |
apply (auto simp add: NCons_False bin_pred_BIT) |
wenzelm@11024 | 326 |
done |
wenzelm@11024 | 327 |
|
wenzelm@11024 | 328 |
lemma bin_add_normal [rule_format]: |
wenzelm@11024 | 329 |
"w \<in> normal --> (\<forall>z. z \<in> normal --> bin_add w z \<in> normal)" |
wenzelm@11024 | 330 |
apply (induct w) |
wenzelm@11024 | 331 |
apply simp |
wenzelm@11024 | 332 |
apply simp |
wenzelm@11024 | 333 |
apply (rule impI) |
wenzelm@11024 | 334 |
apply (rule allI) |
wenzelm@11024 | 335 |
apply (induct_tac z) |
wenzelm@11024 | 336 |
apply (simp_all add: bin_add_BIT) |
wenzelm@11024 | 337 |
apply (safe dest!: normal_BIT_D) |
wenzelm@11024 | 338 |
apply simp_all |
wenzelm@11024 | 339 |
done |
wenzelm@11024 | 340 |
|
paulson@11868 | 341 |
lemma normal_Pls_eq_0: "w \<in> normal ==> (w = Pls) = (number_of w = (0::int))" |
wenzelm@11024 | 342 |
apply (erule normal.induct) |
wenzelm@11024 | 343 |
apply auto |
wenzelm@11024 | 344 |
done |
nipkow@13187 | 345 |
(* |
wenzelm@11024 | 346 |
lemma bin_minus_normal: "w \<in> normal ==> bin_minus w \<in> normal" |
wenzelm@11024 | 347 |
apply (erule normal.induct) |
wenzelm@11024 | 348 |
apply (simp_all add: bin_minus_BIT) |
wenzelm@11024 | 349 |
apply (rule normal.intros) |
nipkow@13187 | 350 |
apply assumption |
wenzelm@11024 | 351 |
apply (simp add: normal_Pls_eq_0) |
paulson@11868 | 352 |
apply (simp only: number_of_minus iszero_def zminus_equation [of _ "0"]) |
nipkow@13187 | 353 |
|
nipkow@13187 | 354 |
The previous command should have finished the proof but the lin-arith |
nipkow@13187 | 355 |
procedure at the end of simplificatioon fails. |
nipkow@13187 | 356 |
Problem: lin-arith correctly derives the contradictory thm |
nipkow@13187 | 357 |
"number_of w + 1 + - 0 \<le> 0 + number_of w" [..] |
nipkow@13187 | 358 |
which its local simplification setup should turn into False. |
nipkow@13187 | 359 |
But on the way we get |
nipkow@13187 | 360 |
|
nipkow@13187 | 361 |
Procedure "int_add_eval_numerals" produced rewrite rule: |
nipkow@13187 | 362 |
number_of ?v3 + 1 \<equiv> number_of (bin_add ?v3 (Pls BIT True)) |
nipkow@13187 | 363 |
|
nipkow@13187 | 364 |
and eventually we arrive not at false but at |
nipkow@13187 | 365 |
|
nipkow@13187 | 366 |
"\<not> neg (number_of (bin_add w (bin_minus (bin_add w (Pls BIT True)))))" |
nipkow@13187 | 367 |
|
nipkow@13187 | 368 |
The next 2 commands should now be obsolete: |
wenzelm@11024 | 369 |
apply (rule not_sym) |
wenzelm@11024 | 370 |
apply simp |
wenzelm@11024 | 371 |
done |
wenzelm@11024 | 372 |
|
nipkow@13187 | 373 |
needs the previous thm: |
wenzelm@11024 | 374 |
lemma bin_mult_normal [rule_format]: |
wenzelm@11024 | 375 |
"w \<in> normal ==> z \<in> normal --> bin_mult w z \<in> normal" |
wenzelm@11024 | 376 |
apply (erule normal.induct) |
wenzelm@11024 | 377 |
apply (simp_all add: bin_minus_normal bin_mult_BIT) |
wenzelm@11024 | 378 |
apply (safe dest!: normal_BIT_D) |
wenzelm@11024 | 379 |
apply (simp add: bin_add_normal) |
wenzelm@11024 | 380 |
done |
nipkow@13187 | 381 |
*) |
paulson@5545 | 382 |
end |