1 ! Copyright (C) 2010 Jon Harper.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays assocs combinators combinators.short-circuit
4 kernel math math.order quotations random sequences summary ;
7 : ifp ( p true false -- ) [ random-unit > ] 2dip if ; inline
9 : whenp ( p true -- ) [ ] ifp ; inline
11 : unlessp ( p false -- ) [ [ ] ] dip ifp ; inline
15 : with-drop ( quot -- quot' ) [ drop ] prepend ; inline
17 : prepare-pair ( pair -- pair' )
18 first2 [ [ [ - ] [ < ] 2bi ] curry ] [ with-drop ] bi* 2array ;
20 ERROR: bad-probabilities assoc ;
22 M: bad-probabilities summary
23 drop "The probabilities do not satisfy the rules stated in the docs." ;
25 : good-probabilities? ( assoc -- ? )
27 keys { [ sum 1 number= ] [ [ 0 1 between? ] all? ] } 1&&
29 but-last keys { [ sum 0 1 between? ] [ [ 0 1 between? ] all? ] } 1&&
32 ! Useful for unit-tests (no random part)
33 : (casep>quot) ( assoc -- quot )
34 dup good-probabilities? [
35 [ dup pair? [ prepare-pair ] [ with-drop ] if ] map
37 ] [ bad-probabilities ] if ;
39 MACRO: (casep) ( assoc -- quot ) (casep>quot) ;
41 : casep>quot ( assoc -- quot )
42 (casep>quot) [ random-unit ] prepend ;
44 : (conditional-probabilities) ( seq i -- p )
45 [ dup 0 > [ head [ 1 swap - ] [ * ] map-reduce ] [ 2drop 1 ] if ]
48 : conditional-probabilities ( seq -- seq' )
49 dup length <iota> [ (conditional-probabilities) ] with map ;
51 : (direct>conditional) ( assoc -- assoc' )
52 [ keys conditional-probabilities ] [ values ] bi zip ;
54 : direct>conditional ( assoc -- assoc' )
55 dup last pair? [ (direct>conditional) ] [
56 unclip-last [ (direct>conditional) ] [ suffix ] bi*
59 : call-random>casep ( seq -- assoc )
60 [ length recip ] keep [ 2array ] with map ;
64 MACRO: casep ( assoc -- quot ) casep>quot ;
66 MACRO: casep* ( assoc -- quot ) direct>conditional casep>quot ;
68 MACRO: call-random ( seq -- quot ) call-random>casep casep>quot ;
70 MACRO: execute-random ( seq -- quot )
71 [ 1quotation ] map call-random>casep casep>quot ;