Type cartesian-product/stream.
This commit is contained in:
parent
8cd75b0fa3
commit
10f0e0ab0c
2 changed files with 48 additions and 41 deletions
|
@ -447,6 +447,23 @@ element of @racket[s1] will be enumerated.
|
|||
(stream->list (stream-take (cartesian-product-2/stream '(a b) (in-naturals)) 10))
|
||||
]}
|
||||
|
||||
@defproc[(cartesian-product/stream [ss (Listof (Sequenceof a))])
|
||||
(Sequenceof (Listof a))]{
|
||||
|
||||
Generates a stream containing all the elements of the Cartesian product between
|
||||
the streams of @racket[ss].
|
||||
|
||||
This function relies on @racket[cartesian-product-2/stream] to build the
|
||||
Cartesian product, so it has the same properties with respect to the order in
|
||||
which the streams are enumerated.
|
||||
|
||||
Union types can be used to build the Cartesian product of streams containing
|
||||
values of different types.
|
||||
|
||||
@examples[#:eval utils-evaluator
|
||||
(stream->list (cartesian-product/stream (list (in-range 3) (in-range 4 6) '(a b))))
|
||||
]}
|
||||
|
||||
@section{Functions and procedures}
|
||||
|
||||
@section{Randomness}
|
||||
|
|
72
utils.rkt
72
utils.rkt
|
@ -24,7 +24,8 @@
|
|||
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
||||
update-vertices/unweighted update-graph dotit collect-by-key
|
||||
collect-by-key/sets ht-values/list->set hash->list/ordered
|
||||
multi-split-at lists-transpose in-random cartesian-product-2/stream)
|
||||
multi-split-at lists-transpose in-random cartesian-product-2/stream
|
||||
cartesian-product/stream)
|
||||
|
||||
(define-type Variable Symbol)
|
||||
(define-type (VariableMapping A) (Immutable-HashTable Variable A))
|
||||
|
@ -500,6 +501,31 @@
|
|||
(check-equal?
|
||||
(stream->list (stream-take (cartesian-product-2/stream '(a b) (in-naturals)) 10))
|
||||
'((a . 0) (a . 1) (a . 2) (a . 3) (a . 4) (a . 5) (a . 6) (a . 7) (a . 8) (a . 9)))))
|
||||
|
||||
(: cartesian-product/stream (All (a) (-> (Listof (Sequenceof a)) (Sequenceof (Listof a)))))
|
||||
(define (cartesian-product/stream ss)
|
||||
(for/foldr ([prod (stream (list))])
|
||||
([s (in-list ss)])
|
||||
(cartesian-product-2/stream s prod)))
|
||||
|
||||
(module+ test
|
||||
(test-case "cartesian-product/stream"
|
||||
(check-equal? (stream->list (cartesian-product/stream '())) '(()))
|
||||
(check-equal? (stream->list (cartesian-product/stream '((a b c))))
|
||||
'((a) (b) (c)))
|
||||
(check-equal? (stream->list (cartesian-product/stream (list (in-range 3) (in-range 4 6) '(a b))))
|
||||
'((0 4 a)
|
||||
(0 4 b)
|
||||
(0 5 a)
|
||||
(0 5 b)
|
||||
(1 4 a)
|
||||
(1 4 b)
|
||||
(1 5 a)
|
||||
(1 5 b)
|
||||
(2 4 a)
|
||||
(2 4 b)
|
||||
(2 5 a)
|
||||
(2 5 b)))))
|
||||
)
|
||||
|
||||
(require 'typed)
|
||||
|
@ -510,14 +536,14 @@
|
|||
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
||||
update-vertices/unweighted update-graph dotit collect-by-key
|
||||
collect-by-key/sets ht-values/list->set hash->list/ordered
|
||||
multi-split-at lists-transpose in-random cartesian-product-2/stream)
|
||||
multi-split-at lists-transpose in-random cartesian-product-2/stream
|
||||
cartesian-product/stream)
|
||||
|
||||
;;; Untyped section.
|
||||
|
||||
(provide
|
||||
;; Functions
|
||||
(contract-out [cartesian-product/stream (->* () #:rest (listof stream?) stream?)]
|
||||
[boolean-power (-> number? (listof (listof boolean?)))]
|
||||
(contract-out [boolean-power (-> number? (listof (listof boolean?)))]
|
||||
[boolean-power/stream (-> number? (stream/c (listof boolean?)))]
|
||||
[any->01 (-> any/c (or/c 0 1))]
|
||||
[01->boolean (-> (or/c 0 1) boolean?)])
|
||||
|
@ -541,42 +567,6 @@
|
|||
(cons/c key-contract val-contract)))
|
||||
|
||||
|
||||
;;; ===========================
|
||||
;;; Additional stream utilities
|
||||
;;; ===========================
|
||||
|
||||
|
||||
;;; Returns the Cartesian product of the given streams. The result is
|
||||
;;; a stream whose elements are the elements of the Cartesian product.
|
||||
;;;
|
||||
;;; The implementation is inspired from the implementation of
|
||||
;;; cartesian-product in racket/list.
|
||||
(define (cartesian-product/stream . ss)
|
||||
;; Cartesian product of two streams, produces an improper pair.
|
||||
(define (cp-2 ss1 ss2)
|
||||
(for*/stream ([s1 (in-stream ss1)] [s2 (in-stream ss2)]) (cons s1 s2)))
|
||||
;; Fold-right over the list of streams. The value for the fold is a
|
||||
;; 1-value stream containing the empty list, which makes all the
|
||||
;; lists proper.
|
||||
(foldr cp-2 (sequence->stream (in-value (list))) ss))
|
||||
|
||||
(module+ test
|
||||
(test-case "cartesian-product/stream"
|
||||
(check-equal? (stream->list (cartesian-product/stream (in-range 3) (in-range 4 6) '(a b)))
|
||||
'((0 4 a)
|
||||
(0 4 b)
|
||||
(0 5 a)
|
||||
(0 5 b)
|
||||
(1 4 a)
|
||||
(1 4 b)
|
||||
(1 5 a)
|
||||
(1 5 b)
|
||||
(2 4 a)
|
||||
(2 4 b)
|
||||
(2 5 a)
|
||||
(2 5 b)))))
|
||||
|
||||
|
||||
;;; ==================
|
||||
;;; Boolean operations
|
||||
;;; ==================
|
||||
|
@ -590,7 +580,7 @@
|
|||
|
||||
;;; Like boolean-power, but returns a stream whose elements the
|
||||
;;; elements of the Cartesian power.
|
||||
(define (boolean-power/stream n) (apply cartesian-product/stream (make-list n '(#f #t))))
|
||||
(define (boolean-power/stream n) (cartesian-product/stream (make-list n '(#f #t))))
|
||||
|
||||
(module+ test
|
||||
(test-case "boolean-power/stream"
|
||||
|
|
Loading…
Reference in a new issue