Integer.agda 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. {-# OPTIONS --no-termination-check #-}
  2. module Data.Integer where
  3. import Prelude
  4. import Data.Nat as Nat
  5. import Data.Bool
  6. open Nat using (Nat; suc; zero)
  7. renaming ( _+_ to _+'_
  8. ; _*_ to _*'_
  9. ; _<_ to _<'_
  10. ; _-_ to _-'_
  11. ; _==_ to _=='_
  12. ; div to div'
  13. ; mod to mod'
  14. ; gcd to gcd'
  15. ; lcm to lcm'
  16. )
  17. open Data.Bool
  18. open Prelude
  19. data Int : Set where
  20. pos : Nat -> Int
  21. neg : Nat -> Int -- neg n = -(n + 1)
  22. infix 40 _==_ _<_ _>_ _≤_ _≥_
  23. infixl 60 _+_ _-_
  24. infixl 70 _*_
  25. infix 90 -_
  26. -_ : Int -> Int
  27. - pos zero = pos zero
  28. - pos (suc n) = neg n
  29. - neg n = pos (suc n)
  30. _+_ : Int -> Int -> Int
  31. pos n + pos m = pos (n +' m)
  32. neg n + neg m = neg (n +' m +' 1)
  33. pos n + neg m =
  34. ! m <' n => pos (n -' m -' 1)
  35. ! otherwise neg (m -' n)
  36. neg n + pos m = pos m + neg n
  37. _-_ : Int -> Int -> Int
  38. x - y = x + - y
  39. !_! : Int -> Nat
  40. ! pos n ! = n
  41. ! neg n ! = suc n
  42. _*_ : Int -> Int -> Int
  43. pos 0 * _ = pos 0
  44. _ * pos 0 = pos 0
  45. pos n * pos m = pos (n *' m)
  46. neg n * neg m = pos (suc n *' suc m)
  47. pos n * neg m = neg (n *' suc m -' 1)
  48. neg n * pos m = neg (suc n *' m -' 1)
  49. div : Int -> Int -> Int
  50. div _ (pos zero) = pos 0
  51. div (pos n) (pos m) = pos (div' n m)
  52. div (neg n) (neg m) = pos (div' (suc n) (suc m))
  53. div (pos zero) (neg _) = pos 0
  54. div (pos (suc n)) (neg m) = neg (div' n (suc m))
  55. div (neg n) (pos (suc m)) = div (pos (suc n)) (neg m)
  56. mod : Int -> Int -> Int
  57. mod _ (pos 0) = pos 0
  58. mod (pos n) (pos m) = pos (mod' n m)
  59. mod (neg n) (pos m) = adjust (mod' (suc n) m)
  60. where
  61. adjust : Nat -> Int
  62. adjust 0 = pos 0
  63. adjust n = pos (m -' n)
  64. mod n (neg m) = adjust (mod n (pos (suc m)))
  65. where
  66. adjust : Int -> Int
  67. adjust (pos 0) = pos 0
  68. adjust (neg n) = neg n -- impossible
  69. adjust x = x + neg m
  70. gcd : Int -> Int -> Int
  71. gcd a b = pos (gcd' ! a ! ! b !)
  72. lcm : Int -> Int -> Int
  73. lcm a b = pos (lcm' ! a ! ! b !)
  74. _==_ : Int -> Int -> Bool
  75. pos n == pos m = n ==' m
  76. neg n == neg m = n ==' m
  77. pos _ == neg _ = false
  78. neg _ == pos _ = false
  79. _<_ : Int -> Int -> Bool
  80. pos _ < neg _ = false
  81. neg _ < pos _ = true
  82. pos n < pos m = n <' m
  83. neg n < neg m = m <' n
  84. _≤_ : Int -> Int -> Bool
  85. x ≤ y = x == y || x < y
  86. _≥_ = flip _≤_
  87. _>_ = flip _<_