@@ -274,9 +274,12 @@ fact (S n) = (S n) * fact n
274274-- Division and modulus
275275--------------------------------------------------------------------------------
276276
277−partial
278−modNat : Nat -> Nat -> Nat
279−modNat left (S right) = mod' left left right
277+SIsNotZ : {x: Nat} -> (S x = Z) -> Void
278+SIsNotZ Refl impossible
279+
280+modNatNZ : Nat -> (y: Nat) -> Not (y = Z) -> Nat
281+modNatNZ left Z p = void (p Refl)
282+modNatNZ left (S right) _ = mod' left left right
280283 where
281284 total mod' : Nat -> Nat -> Nat -> Nat
282285 mod' Z centre right = centre
@@ -287,8 +290,12 @@ modNat left (S right) = mod' left left right
287290 mod' left (centre - (S right)) right
288291
289292partial
290−divNat : Nat -> Nat -> Nat
291−divNat left (S right) = div' left left right
293+modNat : Nat -> Nat -> Nat
294+modNat left (S right) = modNatNZ left (S right) SIsNotZ
295+
296+divNatNZ : Nat -> (y: Nat) -> Not (y = Z) -> Nat
297+divNatNZ left Z p = void (p Refl)
298+divNatNZ left (S right) _ = div' left left right
292299 where
293300 total div' : Nat -> Nat -> Nat -> Nat
294301 div' Z centre right = Z
@@ -298,14 +305,31 @@ divNat left (S right) = div' left left right
298305 else
299306 S (div' left (centre - (S right)) right)
300307
308+partial
309+divNat : Nat -> Nat -> Nat
310+divNat left (S right) = divNatNZ left (S right) SIsNotZ
311+
312+divCeilNZ : Nat -> (y: Nat) -> Not (y = 0) -> Nat
313+divCeilNZ x y p = case (modNatNZ x y p) of
314+ Z => divNatNZ x y p
315+ S _ => S (divNatNZ x y p)
316+
317+partial
318+divCeil : Nat -> Nat -> Nat
319+divCeil x (S y) = divCeilNZ x (S y) SIsNotZ
320+
301321instance Integral Nat where
302322 div = divNat
303323 mod = modNat
304324
325+log2NZ : (x: Nat) -> Not (x = Z) -> Nat
326+log2NZ Z p = void (p Refl)
327+log2NZ (S Z) _ = Z
328+log2NZ (S (S n)) _ = S (log2NZ (assert_smaller (S (S n)) (S (divNatNZ n 2 SIsNotZ))) SIsNotZ)
329+
305330partial
306331log2 : Nat -> Nat
307−log2 (S Z) = Z
308−log2 n = S (log2 (assert_smaller n (n `divNat` 2)))
332+log2 (S n) = log2NZ (S n) SIsNotZ
309333
310334--------------------------------------------------------------------------------
311335-- GCD and LCM