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))
|
(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{Functions and procedures}
|
||||||
|
|
||||||
@section{Randomness}
|
@section{Randomness}
|
||||||
|
|
72
utils.rkt
72
utils.rkt
|
@ -24,7 +24,8 @@
|
||||||
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
||||||
update-vertices/unweighted update-graph dotit collect-by-key
|
update-vertices/unweighted update-graph dotit collect-by-key
|
||||||
collect-by-key/sets ht-values/list->set hash->list/ordered
|
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 Variable Symbol)
|
||||||
(define-type (VariableMapping A) (Immutable-HashTable Variable A))
|
(define-type (VariableMapping A) (Immutable-HashTable Variable A))
|
||||||
|
@ -500,6 +501,31 @@
|
||||||
(check-equal?
|
(check-equal?
|
||||||
(stream->list (stream-take (cartesian-product-2/stream '(a b) (in-naturals)) 10))
|
(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)))))
|
'((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)
|
(require 'typed)
|
||||||
|
@ -510,14 +536,14 @@
|
||||||
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
list-sets->list-strings pretty-print-set pretty-print-set-sets
|
||||||
update-vertices/unweighted update-graph dotit collect-by-key
|
update-vertices/unweighted update-graph dotit collect-by-key
|
||||||
collect-by-key/sets ht-values/list->set hash->list/ordered
|
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.
|
;;; Untyped section.
|
||||||
|
|
||||||
(provide
|
(provide
|
||||||
;; Functions
|
;; Functions
|
||||||
(contract-out [cartesian-product/stream (->* () #:rest (listof stream?) stream?)]
|
(contract-out [boolean-power (-> number? (listof (listof boolean?)))]
|
||||||
[boolean-power (-> number? (listof (listof boolean?)))]
|
|
||||||
[boolean-power/stream (-> number? (stream/c (listof boolean?)))]
|
[boolean-power/stream (-> number? (stream/c (listof boolean?)))]
|
||||||
[any->01 (-> any/c (or/c 0 1))]
|
[any->01 (-> any/c (or/c 0 1))]
|
||||||
[01->boolean (-> (or/c 0 1) boolean?)])
|
[01->boolean (-> (or/c 0 1) boolean?)])
|
||||||
|
@ -541,42 +567,6 @@
|
||||||
(cons/c key-contract val-contract)))
|
(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
|
;;; Boolean operations
|
||||||
;;; ==================
|
;;; ==================
|
||||||
|
@ -590,7 +580,7 @@
|
||||||
|
|
||||||
;;; Like boolean-power, but returns a stream whose elements the
|
;;; Like boolean-power, but returns a stream whose elements the
|
||||||
;;; elements of the Cartesian power.
|
;;; 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
|
(module+ test
|
||||||
(test-case "boolean-power/stream"
|
(test-case "boolean-power/stream"
|
||||||
|
|
Loading…
Reference in a new issue