egison-3.5.2: lib/core/random.egi
;;;;;
;;;;; Random
;;;;;
(define $pure-rand
(lambda [$s $e]
(io (rand s e))))
(define $randomize
(lambda [$xs]
(letrec {[$randomize'
(lambda [$xs $n]
(if (eq? n 0)
{}
(let {[$r (pure-rand 1 n)]}
(let {[$x (nth r xs)]}
{x @(randomize' (delete-first x xs) (- n 1))}))))]}
(randomize' xs (length xs)))))
(define $R.between
(lambda [$s $e]
(randomize (between s e))))
(define $R.multiset
(lambda [$a]
(matcher
{[<nil> []
{[{} {[]}]
[_ {}]}]
[<cons $ $> [a (R.multiset a)]
{[$tgt (map (lambda [$i]
(match tgt (list a)
{[(loop $j [1 (- i 1)] <cons $xa_j ...> <cons $x $ts>)
[x {@(map (lambda [$j] xa_j) (between 1 (- i 1))) @ts}]]}))
(R.between 1 (length tgt)))]}]
[$ [something]
{[$tgt {tgt}]}]
})))
(define $R.uncons
(lambda [$xs]
(car (match-all xs (R.multiset something)
[<cons $x $rs> [x rs]]))))
(define $R.car
(lambda [$xs]
(car (match-all xs (R.multiset something)
[<cons $x $rs> x]))))
(define $R.cdr
(lambda [$xs]
(car (match-all xs (R.multiset something)
[<cons $x $rs> rs]))))
(define $R.set
(lambda [$a]
(matcher
{[<nil> []
{[{} {[]}]
[_ {}]}]
[<cons $ $> [a (R.multiset a)]
{[$tgt (map (lambda [$i]
(match tgt (list a)
{[(loop $j [1 (- i 1)] <cons _ ...> <cons $x _>)
[x tgt]]}))
(R.between 1 (length tgt)))]}]
[$ [something]
{[$tgt {tgt}]}]
})))