src/HOL/Integ/IntDiv.thy
author wenzelm
Fri, 05 Oct 2001 21:52:39 +0200
changeset 11701 3d51fbf81c17
parent 8902 a705822f4e2a
child 11704 3c50a2cd6f00
permissions -rw-r--r--
sane numerals (stage 1): added generic 1, removed 1' and 2 on nat,
"num" syntax (still with "#"), Numeral0, Numeral1;
     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 
     9 IntDiv = IntArith + Recdef + 
    10 
    11 constdefs
    12   quorem :: "(int*int) * (int*int) => bool"
    13     "quorem == %((a,b), (q,r)).
    14                       a = b*q + r &
    15                       (if Numeral0 < b then Numeral0<=r & r<b else b<r & r <= Numeral0)"
    16 
    17   adjust :: "[int, int, int*int] => int*int"
    18     "adjust a b == %(q,r). if Numeral0 <= r-b then (# 2*q + Numeral1, r-b)
    19                            else (# 2*q, r)"
    20 
    21 (** the division algorithm **)
    22 
    23 (*for the case a>=0, b>0*)
    24 consts posDivAlg :: "int*int => int*int"
    25 recdef posDivAlg "inv_image less_than (%(a,b). nat(a - b + Numeral1))"
    26     "posDivAlg (a,b) =
    27        (if (a<b | b<=Numeral0) then (Numeral0,a)
    28         else adjust a b (posDivAlg(a, # 2*b)))"
    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) =
    34        (if (Numeral0<=a+b | b<=Numeral0) then (# -1,a+b)
    35         else adjust a b (negDivAlg(a, # 2*b)))"
    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 ==
    47        %(a,b). if Numeral0<=a then
    48                   if Numeral0<=b then posDivAlg (a,b)
    49                   else if a=Numeral0 then (Numeral0,Numeral0)
    50                        else negateSnd (negDivAlg (-a,-b))
    51                else 
    52                   if Numeral0<b then negDivAlg (a,b)
    53                   else         negateSnd (posDivAlg (-a,-b))"
    54 
    55 instance
    56   int :: "Divides.div"        (*avoid clash with 'div' token*)
    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