author | wenzelm |
Sat, 06 Oct 2001 00:02:46 +0200 | |
changeset 11704 | 3c50a2cd6f00 |
parent 11701 | 3d51fbf81c17 |
child 11868 | 56db9f3a6b3e |
permissions | -rw-r--r-- |
6917 | 1 |
(* Title: HOL/IntDiv.thy |
2 |
ID: $Id$ |
|
3 |
Author: Lawrence C Paulson, Cambridge University Computer Laboratory |
|
4 |
Copyright 1999 University of Cambridge |
|
5 |
||
6 |
The division operators div, mod and the divides relation "dvd" |
|
7 |
*) |
|
8 |
||
7706 | 9 |
IntDiv = IntArith + Recdef + |
6917 | 10 |
|
11 |
constdefs |
|
12 |
quorem :: "(int*int) * (int*int) => bool" |
|
13 |
"quorem == %((a,b), (q,r)). |
|
14 |
a = b*q + r & |
|
11701
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
15 |
(if Numeral0 < b then Numeral0<=r & r<b else b<r & r <= Numeral0)" |
6917 | 16 |
|
17 |
adjust :: "[int, int, int*int] => int*int" |
|
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
18 |
"adjust a b == %(q,r). if Numeral0 <= r-b then (2*q + Numeral1, r-b) |
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
19 |
else (2*q, r)" |
6917 | 20 |
|
21 |
(** the division algorithm **) |
|
22 |
||
23 |
(*for the case a>=0, b>0*) |
|
24 |
consts posDivAlg :: "int*int => int*int" |
|
11701
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
25 |
recdef posDivAlg "inv_image less_than (%(a,b). nat(a - b + Numeral1))" |
6917 | 26 |
"posDivAlg (a,b) = |
11701
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
27 |
(if (a<b | b<=Numeral0) then (Numeral0,a) |
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
28 |
else adjust a b (posDivAlg(a, 2*b)))" |
6917 | 29 |
|
30 |
(*for the case a<0, b>0*) |
|
31 |
consts negDivAlg :: "int*int => int*int" |
|
32 |
recdef negDivAlg "inv_image less_than (%(a,b). nat(- a - b))" |
|
33 |
"negDivAlg (a,b) = |
|
11704
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
34 |
(if (Numeral0<=a+b | b<=Numeral0) then (-1,a+b) |
3c50a2cd6f00
* sane numerals (stage 2): plain "num" syntax (removed "#");
wenzelm
parents:
11701
diff
changeset
|
35 |
else adjust a b (negDivAlg(a, 2*b)))" |
6917 | 36 |
|
37 |
(*for the general case b~=0*) |
|
38 |
||
39 |
constdefs |
|
40 |
negateSnd :: "int*int => int*int" |
|
41 |
"negateSnd == %(q,r). (q,-r)" |
|
42 |
||
43 |
(*The full division algorithm considers all possible signs for a, b |
|
44 |
including the special case a=0, b<0, because negDivAlg requires a<0*) |
|
45 |
divAlg :: "int*int => int*int" |
|
46 |
"divAlg == |
|
11701
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
47 |
%(a,b). if Numeral0<=a then |
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
48 |
if Numeral0<=b then posDivAlg (a,b) |
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
49 |
else if a=Numeral0 then (Numeral0,Numeral0) |
6917 | 50 |
else negateSnd (negDivAlg (-a,-b)) |
51 |
else |
|
11701
3d51fbf81c17
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
wenzelm
parents:
8902
diff
changeset
|
52 |
if Numeral0<b then negDivAlg (a,b) |
6917 | 53 |
else negateSnd (posDivAlg (-a,-b))" |
54 |
||
55 |
instance |
|
8902 | 56 |
int :: "Divides.div" (*avoid clash with 'div' token*) |
6917 | 57 |
|
58 |
defs |
|
59 |
div_def "a div b == fst (divAlg (a,b))" |
|
60 |
mod_def "a mod b == snd (divAlg (a,b))" |
|
61 |
||
62 |
||
63 |
end |