egison-3.3.16: lib/core/number.egi
;;;;;
;;;;;
;;;;; Number
;;;;;
;;;;;
;;;
;;; Natural Numbers
;;;
(define $nat
(matcher
{[,$n []
{[$tgt (if (eq? tgt n) {[]} {})]}]
[<o> []
{[0 {[]}]
[_ {}]}]
[<s $> nat
{[$tgt (match (compare tgt 0) ordering
{[<greater> {(- tgt 1)}]
[_ {}]})]}]
[$ [something]
{[$tgt {tgt}]}]
}))
(define $fib
(lambda [$n]
(letrec {[$fib1 (lambda [$n $ret1 $ret2]
(match n nat
{[<o> ret2]
[<s <o>> ret1]
[<s $n1> (fib1 (- n 1) (+ ret1 ret2) ret1)]
}))]}
(fib1 n 1 1))))
(define $divisor?
(lambda [$n $d]
(eq? 0 (remainder n d))))
(define $gcd
(lambda [$ns]
(match ns (multiset integer)
{[<cons $n <nil>> n]
[<cons (& ,(min ns) $m) $rs>
(gcd {m @((remove-all integer) (map (lambda [$r] (modulo r m)) rs)
0)})]})))
(define $nats {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 @(map (+ 100 $) nats)})
(define $nats0 {0 @nats})
(define $primes
(letrec {[$next-primes
(lambda [$primes1 $k]
(let {[$primes2 (while (lte? $ (floor (sqrt (itof (* 6 (+ k 1)))))) primes1)]}
(match [(any (lambda [$p] (eq? (remainder (+ (* 6 k) 1) p) 0)) primes2)
(any (lambda [$p] (eq? (remainder (+ (* 6 k) 5) p) 0)) primes2)]
[bool bool]
{[[,#f ,#f] {(+ (* 6 k) 1) (+ (* 6 k) 5) @(next-primes {@primes1 (+ (* 6 k) 1) (+ (* 6 k) 5)} (+ k 1))}]
[[,#f ,#t] {(+ (* 6 k) 1) @(next-primes {@primes1 (+ (* 6 k) 1)} (+ k 1))}]
[[,#t ,#f] {(+ (* 6 k) 5) @(next-primes {@primes1 (+ (* 6 k) 5)} (+ k 1))}]
[[,#t ,#t] (next-primes primes1 (+ k 1))]
})))]}
{2 3 5 @(next-primes {2 3 5} 1)}))
(define $find-factor
(lambda [$n]
(match primes (list integer)
{[<join _ <cons (& ?(divisor? n $) $x) _>> x]})))
(define $prime-factorization
(match-lambda integer
{[,1 {}]
[$n (let {[$p (find-factor n)]}
{p @(prime-factorization (quotient n p))})]}))
(define $p-f prime-factorization)
(define $pfs (map (lambda [$n] [n (p-f n)]) nats))
(define $pfs-n
(lambda [$n]
(match-all p-fs (list [integer (list integer)])
[<join _ <cons [$m (loop $i [1 n] <cons $p_i ...> <nil>)] _>> [m (map (lambda [$i] p_i) (between 1 n))]])))
(define $prime?
(lambda [$n]
(if (eq? n 1)
#f
(eq? (rac (while (lte? $ n) primes)) n))))
;;;
;;; Integers
;;;
(define $integer builtin-data-matcher)
(define $power
(lambda [$x $n]
(foldl * 1 (take n (repeat1 x)))))
(define $mod
(lambda [$m]
(matcher
{[,$n []
{[$tgt (if (eq? (modulo tgt m) (modulo n m))
{[]}
{})]}]
[$ [something]
{[$tgt {tgt}]}]
})))
(define $even?
(lambda [$n]
(eq? 0 (modulo n 2))))
(define $odd?
(lambda [$n]
(eq? 1 (modulo n 2))))
(define $between?
(lambda [$m $n $x]
(and (lte? m x) (lte? x n))))
(define $sum
(lambda [$xs]
(foldl' + 0 xs)))
;;;
;;; Float Numbers
;;;
(define $float builtin-data-matcher)