Encode for fair interleaving and better test case

This commit is contained in:
Max New 2014-03-05 13:30:41 -06:00
parent ccd9b2f2d8
commit a949f7b629
2 changed files with 107 additions and 43 deletions

View File

@ -225,55 +225,114 @@
(struct upper-bound (struct upper-bound
(total-bound ;; Nat (total-bound ;; Nat
individual-bound ;; Nat individual-bound ;; Nat
enumerators ;; Vectorof (Enum a) enumerators ;; Vectorof (Enum a, Nat)
) )
#:transparent) #:transparent)
;; layers : Listof Enum -> Listof Upper-Bound ;; layers : Listof Enum -> Listof Upper-Bound
(define/contract (mk-layers es [prev (upper-bound 0 0 (vector es))]) (define/contract (mk-layers es)
((listof enum?) . -> . (listof upper-bound?)) ((listof enum?) . -> . (listof upper-bound?))
(define non-emptys (filter (negate empty/e?) es)) (define (loop eis prev)
(match non-emptys (define non-emptys (filter (negate (compose empty/e? car)) eis))
['() '()] (match non-emptys
[_ ['() '()]
(define min-size [_
(apply exact-min (map size non-emptys))) (define min-size
(define (not-min-size? e) (apply exact-min (map (compose size car) non-emptys)))
(not (= (size e) min-size))) (define (not-min-size? e)
(define leftover (not (= (size (car e)) min-size)))
(filter not-min-size? non-emptys)) (define leftover
(define ves (filter not-min-size? non-emptys))
(apply vector non-emptys)) (define veis
(match-define (upper-bound prev-tb (apply vector non-emptys))
prev-ib (match-define (upper-bound prev-tb
prev-es) prev-ib
prev) prev-es)
(define diff-min-size prev)
(min-size . - . prev-ib)) (define diff-min-size
(define total-bound (min-size . - . prev-ib))
(prev-tb . + . (diff-min-size . * . (vector-length ves)))) (define total-bound
(define cur-layer (prev-tb . + . (diff-min-size . * . (vector-length veis))))
(upper-bound total-bound (define cur-layer
min-size (upper-bound total-bound
ves)) min-size
(define remaining-layers veis))
(mk-layers leftover cur-layer)) (define remaining-layers
(cons cur-layer (loop leftover cur-layer))
remaining-layers)])) (cons cur-layer
remaining-layers)]))
(define eis
(for/list [(i (in-naturals))
(e (in-list es))]
(cons e i)))
(loop eis
(upper-bound 0 0 eis))
)
;; find-layer : Nat, Nonempty-Listof Upper-bound -> Upper-bound, Upper-bound ;; find-layer : Nat, Nonempty-Listof Upper-bound -> Upper-bound, Upper-bound
;; Given an index, find the first layer ;; Given an index, find the first layer
(define/contract (find-layer i layers) (define/contract (find-dec-layer i layers)
(natural-number/c (listof upper-bound?) . -> . (values upper-bound? upper-bound?)) (natural-number/c (listof upper-bound?) . -> . (values upper-bound? upper-bound?))
(find-layer-by-size i upper-bound-total-bound layers))
(define/contract (find-index x e-ps [cur-index 0])
(->*
(any/c
(listof (cons/c enum?
(any/c . -> . boolean?))))
(natural-number/c)
(values natural-number/c
natural-number/c))
(match e-ps
['() (error "invalid term")]
[(cons (cons e in-e?)
more-e-ps)
(cond [(in-e? x)
(values (encode e x)
cur-index)]
[else
(find-index x more-e-ps (add1 cur-index))])]))
(define/contract (find-enc-layer i e-i layers)
(natural-number/c natural-number/c (listof upper-bound?)
. -> .
(values upper-bound? upper-bound? natural-number/c))
(define-values (prev cur)
(find-layer-by-size i
upper-bound-individual-bound
layers))
(define/match (find-e-index l e-i)
[((upper-bound tb ib eis) e-i)
(define (loop low hi)
(when (> low hi)
(error "bin search bug"))
(define mid
(quotient (low . + . hi) 2))
(define cur
(cdr (vector-ref eis mid)))
(cond [(low . = . mid)
(unless (cur . = . e-i)
(error "that's a bug, yo"))
mid]
[(cur . = . e-i) mid]
[(cur . < . e-i) (loop (add1 mid) hi)]
[else (loop low mid)]))
(loop 0 (vector-length eis))])
(values prev
cur
(find-e-index cur e-i)))
;; TODO: change from linear to binary search
(define (find-layer-by-size i get-size ls)
(define (loop prev ls) (define (loop prev ls)
(match ls (match ls
['() (error "internal error in find-layer: index out of range")] ['() (error "internal error in find-layer: index out of range")]
[(cons (and ub (upper-bound tb ib es)) [(cons ub tl)
tl) (cond [(i . < . (get-size ub))
(cond [(i . < . tb) (values prev ub)] (values prev ub)]
[else (loop ub tl)])])) [else (loop ub tl)])]))
(loop (upper-bound 0 0 (vector)) (loop (upper-bound 0 0 (vector)) ls))
layers))
;; fairly interleave a list of enumerations ;; fairly interleave a list of enumerations
(define (disj-sum/e . e-ps) (define (disj-sum/e . e-ps)
@ -287,18 +346,24 @@
[_ [_
(define (dec i) (define (dec i)
(define-values (prev-up-bound cur-up-bound) (define-values (prev-up-bound cur-up-bound)
(find-layer i layers)) (find-dec-layer i layers))
(match-define (upper-bound so-far prev-ib es1) prev-up-bound) (match-define (upper-bound so-far prev-ib es1) prev-up-bound)
(match-define (upper-bound ctb cib es) cur-up-bound) (match-define (upper-bound ctb cib es) cur-up-bound)
(define this-i (i . - . so-far)) (define this-i (i . - . so-far))
(define len (vector-length es)) (define len (vector-length es))
(define-values (q r) (quotient/remainder this-i len)) (define-values (q r) (quotient/remainder this-i len))
(define this-e (vector-ref es r)) (define this-e (car (vector-ref es r)))
(decode this-e (+ q prev-ib))) (decode this-e (+ q prev-ib)))
(define (enc x) (define (enc x)
0 (define-values (index which-e)
;; (error 'todo) (find-index x e-ps))
) (define-values (prev-up-bound cur-up-bound cur-e-index)
(find-enc-layer index which-e layers))
(match-define (upper-bound ptb pib pes) prev-up-bound)
(match-define (upper-bound ctb cib ces) cur-up-bound)
(+ ptb
cur-e-index
((vector-length ces) . * . (index . - . pib))))
(enum (apply + (map (compose size car) e-ps)) (enum (apply + (map (compose size car) e-ps))
dec dec
enc)])) enc)]))

View File

@ -157,8 +157,7 @@
8 (#f #t #t) 8 (#f #t #t)
9 (#t #f #t))) 9 (#t #f #t)))
(check-bijection? multi-layered) (check-bijection? multi-layered))
)
(test-begin (test-begin
(define bool-or-num (define bool-or-num