123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- {-# OPTIONS --no-termination-check #-}
- module Data.Integer where
- import Prelude
- import Data.Nat as Nat
- import Data.Bool
- open Nat using (Nat; suc; zero)
- renaming ( _+_ to _+'_
- ; _*_ to _*'_
- ; _<_ to _<'_
- ; _-_ to _-'_
- ; _==_ to _=='_
- ; div to div'
- ; mod to mod'
- ; gcd to gcd'
- ; lcm to lcm'
- )
- open Data.Bool
- open Prelude
- data Int : Set where
- pos : Nat -> Int
- neg : Nat -> Int -- neg n = -(n + 1)
- infix 40 _==_ _<_ _>_ _≤_ _≥_
- infixl 60 _+_ _-_
- infixl 70 _*_
- infix 90 -_
- -_ : Int -> Int
- - pos zero = pos zero
- - pos (suc n) = neg n
- - neg n = pos (suc n)
- _+_ : Int -> Int -> Int
- pos n + pos m = pos (n +' m)
- neg n + neg m = neg (n +' m +' 1)
- pos n + neg m =
- ! m <' n => pos (n -' m -' 1)
- ! otherwise neg (m -' n)
- neg n + pos m = pos m + neg n
- _-_ : Int -> Int -> Int
- x - y = x + - y
- !_! : Int -> Nat
- ! pos n ! = n
- ! neg n ! = suc n
- _*_ : Int -> Int -> Int
- pos 0 * _ = pos 0
- _ * pos 0 = pos 0
- pos n * pos m = pos (n *' m)
- neg n * neg m = pos (suc n *' suc m)
- pos n * neg m = neg (n *' suc m -' 1)
- neg n * pos m = neg (suc n *' m -' 1)
- div : Int -> Int -> Int
- div _ (pos zero) = pos 0
- div (pos n) (pos m) = pos (div' n m)
- div (neg n) (neg m) = pos (div' (suc n) (suc m))
- div (pos zero) (neg _) = pos 0
- div (pos (suc n)) (neg m) = neg (div' n (suc m))
- div (neg n) (pos (suc m)) = div (pos (suc n)) (neg m)
- mod : Int -> Int -> Int
- mod _ (pos 0) = pos 0
- mod (pos n) (pos m) = pos (mod' n m)
- mod (neg n) (pos m) = adjust (mod' (suc n) m)
- where
- adjust : Nat -> Int
- adjust 0 = pos 0
- adjust n = pos (m -' n)
- mod n (neg m) = adjust (mod n (pos (suc m)))
- where
- adjust : Int -> Int
- adjust (pos 0) = pos 0
- adjust (neg n) = neg n -- impossible
- adjust x = x + neg m
- gcd : Int -> Int -> Int
- gcd a b = pos (gcd' ! a ! ! b !)
- lcm : Int -> Int -> Int
- lcm a b = pos (lcm' ! a ! ! b !)
- _==_ : Int -> Int -> Bool
- pos n == pos m = n ==' m
- neg n == neg m = n ==' m
- pos _ == neg _ = false
- neg _ == pos _ = false
- _<_ : Int -> Int -> Bool
- pos _ < neg _ = false
- neg _ < pos _ = true
- pos n < pos m = n <' m
- neg n < neg m = m <' n
- _≤_ : Int -> Int -> Bool
- x ≤ y = x == y || x < y
- _≥_ = flip _≤_
- _>_ = flip _<_
|