diff --git a/pkgs/data-pkgs/data-doc/data/scribblings/enumerate.scrbl b/pkgs/data-pkgs/data-doc/data/scribblings/enumerate.scrbl index edc603a6f6..000eb195ee 100644 --- a/pkgs/data-pkgs/data-doc/data/scribblings/enumerate.scrbl +++ b/pkgs/data-pkgs/data-doc/data/scribblings/enumerate.scrbl @@ -672,6 +672,19 @@ An @tech{enumeration} of S-expressions. This library defines some library @tech{enumerations} built on @racketmodname[data/enumerate]. +@defproc[(random-index [e enum?]) + exact-nonnegative-integer?]{ + +Returns a random index into @racket[e]. This works regardless of the +size of @racket[e], unlike @racket[(random (size e))]. + +@examples[#:eval the-eval +(random (size nat/e)) +(random (size (below/e 5000000000))) +(random-index nat/e) +(random-index (below/e 5000000000)) +]} + @defproc[(permutations-of-n/e [n exact-nonnegative-integer?]) enum?]{ diff --git a/pkgs/data-pkgs/data-enumerate-lib/data/enumerate.rkt b/pkgs/data-pkgs/data-enumerate-lib/data/enumerate.rkt index 13e3a69f9b..9f0fb432a7 100644 --- a/pkgs/data-pkgs/data-enumerate-lib/data/enumerate.rkt +++ b/pkgs/data-pkgs/data-enumerate-lib/data/enumerate.rkt @@ -106,7 +106,7 @@ (-> enum? (-> any/c enum?) enum?)] [dep2/e - (-> nat? enum? (-> any/c enum?) + (-> extended-nat/c enum? (-> any/c enum?) enum?)] [fold-enum (-> (-> list? any/c enum?) diff --git a/pkgs/data-pkgs/data-enumerate-lib/data/enumerate/lib.rkt b/pkgs/data-pkgs/data-enumerate-lib/data/enumerate/lib.rkt index cd8b8137e8..492754b4d4 100644 --- a/pkgs/data-pkgs/data-enumerate-lib/data/enumerate/lib.rkt +++ b/pkgs/data-pkgs/data-enumerate-lib/data/enumerate/lib.rkt @@ -1,9 +1,30 @@ #lang racket/base (require racket/contract/base data/enumerate + math/base + math/distributions math/number-theory racket/generator) +;; pick-an-index : ([0,1] -> Nat) ∩ (-> Nat) +(define (random-natural-w/o-limit [prob-of-zero 0.01]) + (max (random-natural/no-mean prob-of-zero) + (random-natural/no-mean prob-of-zero) + (random-natural/no-mean prob-of-zero))) + +;; random-natural/no-mean : [0,1] -> Nat +(define (random-natural/no-mean prob-of-zero) + (define x (sample (geometric-dist prob-of-zero))) + (define m1 (expt 2 (exact-floor x))) + (define m0 (quotient m1 2)) + (random-integer m0 m1)) + +(define (random-index e) + (define k (size e)) + (if (infinite? k) + (random-natural-w/o-limit) + (random-natural k))) + (define (BPP-digits N) (let loop ([8Pi -8]) (define 8i @@ -168,6 +189,8 @@ (provide (contract-out + [random-index + (-> enum? exact-nonnegative-integer?)] [infinite-sequence/e (-> enum? enum?)] [permutations/e