Redex generator supports mismatched names.

Also added mismatched name tests.
This commit is contained in:
Max New 2013-05-20 01:11:04 -05:00
parent f67b1ca06c
commit 797f7f7bd2
3 changed files with 567 additions and 361 deletions

View File

@ -19,11 +19,19 @@
[enum? (-> any/c boolean?)]))
(struct lang-enum (enums))
(struct decomposition (ctx term))
(struct named (name val))
(struct named-t (val term))
(struct name (name) #:transparent)
(struct unimplemented (msg))
(struct repeat (n terms) #:transparent)
(struct decomposition (ctx term) #:transparent)
(struct named (name val) #:transparent)
(struct named-t (val term) #:transparent)
(struct mismatch (name val) #:transparent)
(struct mismatch-t (vals term) #:transparent)
(struct name-ref (name) #:transparent)
(struct mismatch-ref (name) #:transparent)
(struct unimplemented (msg) #:transparent)
(struct named-pats (names map) #:transparent
) ;; listof symbol and hash symbol -o> (or named, mismatched, named-repeat, mismatch-repeat)
(define enum-ith decode)
@ -265,10 +273,10 @@
(sep-names pat)
l-enums))
;; sep-names : single-pattern lang -> (assoclist symbol pattern)
;; sep-names : single-pattern lang -> named-pats
(define (sep-names pat)
(let loop ([pat pat]
[named-pats '()])
[named-pats empty-named-pats])
(match-a-pattern
pat
[`any named-pats]
@ -285,11 +293,12 @@
[`hole named-pats]
;; names inside nts are separate
[`(nt ,id) named-pats]
[`(name ,name ,pat)
[`(name ,n ,pat)
(loop pat
(add-if-new name pat named-pats))]
[`(mismatch-name ,name ,pat)
(loop pat (cons (unimplemented "mismatch") named-pats))]
(add-named n pat named-pats))]
[`(mismatch-name ,n ,pat)
(loop pat
(add-mismatch n pat named-pats))]
[`(in-hole ,p1 ,p2)
(loop p2
(loop p1 named-pats))]
@ -304,16 +313,84 @@
[`(repeat ,pat #f #f)
(loop pat named-pats)]
[`(repeat ,pat ,name ,mismatch)
(loop pat (cons (unimplemented "named/mismatched repeat") named-pats))]
(loop pat
(add-unimplemented name "named/mismatched repeat" named-pats))]
[else (loop sub-pat named-pats)]))
named-pats
sub-pats)]
[(? (compose not pair?))
named-pats])))
(define (add-if-new k v l)
(cond [(assoc-named k l) l]
[else (cons (named k v) l)]))
;; named-pats combinators
(define empty-named-pats
(named-pats '() (hash)))
(define (empty-named-pats? nps)
(null? (named-pats-names nps)))
(define (next-named-pats nps)
(hash-ref (named-pats-map nps)
(car (named-pats-names nps))))
(define (rest-named-pats nps)
(named-pats (cdr (named-pats-names nps))
(named-pats-map nps)))
(define (member-named-pats name nps)
(member name (named-pats-names nps)))
(define (add-named name pat nps)
(cond [(member-named-pats name nps)
nps]
[else
(add-named-pats name (named name pat) nps)]))
(define (add-unimplemented name msg nps)
(add-named-pats name
(unimplemented msg)
nps))
(define (add-mismatch n pat nps)
(cond [(member-named-pats n nps)
(named-pats-set n
(mismatch
n
(cons pat
(mismatch-val
(hash-ref (named-pats-map nps)
n))))
nps)]
[else
(add-named-pats n
(mismatch n (list pat))
nps)]))
(define (named-pats-set n val nps)
(named-pats
(named-pats-names nps)
(hash-set (named-pats-map nps)
n val)))
(define (add-named-pats n val nps)
(named-pats (cons n (named-pats-names nps))
(hash-set (named-pats-map nps) n val)))
(define (reverse-named-pats nps)
(named-pats (named-pats-names nps)
(foldl
(λ (kv m)
(let ([key (car kv)]
[val (cdr kv)])
(hash-set m key
(cond [(named? val)
val]
[(mismatch? val)
(mismatch (mismatch-name val)
(reverse
(mismatch-val val)))]
[(unimplemented? val)
val]))))
(hash)
(hash->list (named-pats-map nps)))))
(define (assoc-named n l)
(cond [(null? l) #f]
@ -324,14 +401,14 @@
n)))
(assoc-named n (cdr l)))]))
(define (enum-names pat named-pats nt-enums)
(let rec ([named-pats named-pats]
(define (enum-names pat nps nt-enums)
(let rec ([nps nps]
[env (hash)])
(cond [(null? named-pats)
(cond [(empty-named-pats? nps)
(pat/enum-with-names pat nt-enums env)]
[else
(let ([cur (car named-pats)])
(cond ([named? cur]
(let ([cur (next-named-pats nps)])
(cond [(named? cur)
(let ([name (named-name cur)]
[pat (named-val cur)])
(map/enum
@ -352,12 +429,47 @@
(dep/enum
(pat/enum-with-names pat nt-enums env)
(λ (term)
(rec (cdr named-pats)
(rec (rest-named-pats nps)
(hash-set env
name
term)))))))
[else (error/enum 'unimplemented
(unimplemented-msg cur))]))])))
term))))))]
[(mismatch? cur)
(let ([name (mismatch-name cur)])
(map/enum
(λ (ts)
(mismatch name
(mismatch-t (car ts)
(cdr ts))))
(λ (n)
(if (equal? (mismatch-name n)
name)
(let ([val (mismatch-val n)])
(cons (mismatch-t-vals val)
(mismatch-t-term val)))
(error 'wrong-name
"expected ~a, got ~a"
name
(named-name n))))
(dep/enum
(fold-enum
(λ (excepts pat)
(except/enum
(pat/enum-with-names pat
nt-enums
(hash-set env
(mismatch-name cur)
excepts))
excepts))
(mismatch-val cur))
(λ (terms)
(rec (rest-named-pats nps)
(hash-set env
name
terms))))))]
[(unimplemented? cur)
(error/enum 'unimplemented
(unimplemented-msg cur))]
[else (error 'unexpected "expected name, mismatch or unimplemented, got: ~a in ~a" cur nps)]))])))
(define (pat/enum-with-names pat nt-enums named-terms)
(let loop ([pat pat])
@ -375,7 +487,7 @@
[`boolean bool/enum]
[`variable var/enum]
[`(variable-except ,s ...)
(apply except/enum var/enum s)]
(except/enum var/enum s)]
[`(variable-prefix ,s)
;; todo
(error/enum 'unimplemented "var-prefix")]
@ -386,9 +498,9 @@
[`(nt ,id)
(hash-ref nt-enums id)]
[`(name ,n ,pat)
(const/enum (name n))]
[`(mismatch-name ,name ,pat)
(error/enum 'unimplemented "mismatch-name")]
(const/enum (name-ref n))]
[`(mismatch-name ,n ,pat)
(const/enum (mismatch-ref n))]
[`(in-hole ,p1 ,p2) ;; untested
(map/enum
(λ (ts)
@ -408,33 +520,29 @@
(unsupported/enum pat)]
[`(list ,sub-pats ...)
;; enum-list
(map/enum
flatten-1
identity
(list/enum
(map
(λ (sub-pat)
(match sub-pat
[`(repeat ,pat #f #f)
(map/enum
cdr
(λ (ts)
(cons (length ts)
ts))
(dep/enum
nats
(λ (n)
(list/enum
(build-list n (const (loop pat)))))))]
[`(repeat ,pat ,name #f)
(error/enum 'unimplemented "named-repeat")]
[`(repeat ,pat #f ,mismatch)
(error/enum 'unimplemented "mismatch-repeat")]
[else (map/enum
list
car
(loop sub-pat))]))
sub-pats)))]
(list/enum
(map
(λ (sub-pat)
(match sub-pat
[`(repeat ,pat #f #f)
(map/enum
(λ (n-ts)
(repeat (car n-ts)
(cdr n-ts)))
(λ (rep)
(cons (repeat-n rep)
(repeat-terms rep)))
(dep/enum
nats
(λ (n)
(list/enum
(build-list n (const (loop pat)))))))]
[`(repeat ,pat ,name #f)
(error/enum 'unimplemented "named-repeat")]
[`(repeat ,pat #f ,mismatch)
(error/enum 'unimplemented "mismatch-repeat")]
[else (loop sub-pat)]))
sub-pats))]
[(? (compose not pair?))
(const/enum pat)])))
@ -475,10 +583,9 @@
(λ (n) (- (- n) 1))
nats)))
(define real/enum (from-list/enum '(0.0 1.5 123.112354)))
(define real/enum (from-list/enum '(0.5 1.5 123.112354)))
(define num/enum
(sum/enum natural/enum
integer/enum
(sum/enum integer/enum
real/enum))
(define bool/enum
@ -499,10 +606,27 @@
(define (to-term aug)
(cond [(named? aug)
(rep-name aug)]
[(mismatch? aug)
(rep-mismatches aug)]
[(decomposition? aug)
(plug-hole aug)]
[(repeat? aug)
(map-repeat to-term
aug)]
[(list? aug)
(expand-repeats
(map to-term aug))]
[else aug]))
(define (expand-repeats sub-terms)
(append*
(map
(λ (t)
(cond [(repeat? t)
(repeat-terms t)]
[else (list t)]))
sub-terms)))
(define (rep-name s)
(to-term
(let* ([n (named-name s)]
@ -510,10 +634,10 @@
[val (named-t-val v)]
[term (named-t-term v)])
(let loop ([term term])
(cond [(and (name? term)
(equal? (name-name term) n))
(cond [(and (name-ref? term)
(equal? (name-ref-name term) n))
val]
[(cons? term)
[(list? term)
(map loop term)]
[(named? term)
(map-named loop
@ -521,13 +645,48 @@
[(decomposition? term)
(map-decomp loop
term)]
[(mismatch? term)
(map-mismatch loop
term)]
[(repeat? term)
(map-repeat loop
term)]
[else term])))))
(define (rep-mismatches m)
(to-term
(let* ([name (mismatch-name m)]
[v (mismatch-val m)]
[vals (mismatch-t-vals v)]
[term (mismatch-t-term v)])
(let ([vals vals])
(let loop ([term term])
(cond [(and (mismatch-ref? term)
(equal? (mismatch-ref-name term) name))
(begin0
(car vals)
(set! vals (cdr vals)))]
[(list? term)
(map loop term)]
[(named? term)
(map-named loop
term)]
[(decomposition? term)
(map-decomp loop
term)]
[(mismatch? term)
(map-mismatch loop
term)]
[(repeat? term)
(map-repeat loop
term)]
[else term]))))))
(define (plug-hole ctx term)
(to-term
(let loop ([ctx ctx])
(cond [(hole? ctx) term]
[(cons? ctx) (map loop ctx)]
[(list? ctx) (map loop ctx)]
[(named? )])
(match
ctx
@ -544,7 +703,18 @@
(define (map-named f n)
(let ([v (named-val n)])
(named (named-name n)
(named-t
(named-t-val v)
(f (named-t-term v))))))
(named (named-name n)
(named-t
(named-t-val v)
(f (named-t-term v))))))
(define (map-mismatch f m)
(let ([v (mismatch-val m)])
(mismatch (mismatch-name m)
(mismatch-t
(mismatch-t-vals v)
(f (mismatch-t-term v))))))
(define (map-repeat f r)
(repeat (repeat-n r)
(map f (repeat-terms r))))

View File

@ -26,7 +26,7 @@
to-list
take/enum
drop/enum
foldl-enum
fold-enum
display-enum
nats
@ -80,28 +80,24 @@
(λ (x) (encode e x))))
;; except/enum : enum a, a -> enum a
(define except/enum
(case-lambda
[(e) e]
[(e a . rest)
(let ([excepted
(begin
(unless (> (size e) 0)
(error 'empty-enum))
(with-handlers ([exn:fail? (λ (_)
(apply except/enum e rest))])
(let ([m (encode e a)])
(enum (- (size e) 1)
(λ (n)
(if (< n m)
(decode e n)
(decode e (+ n 1))))
(λ (x)
(let ([n (encode e x)])
(cond [(< n m) n]
[(> n m) (- n 1)]
[else (error 'excepted)])))))))])
(apply except/enum excepted rest))]))
(define (except/enum e excepts)
(cond [(empty? excepts) e]
[else
(except/enum
(begin
(with-handlers ([exn:fail? (λ (_) e)])
(let ([m (encode e (car excepts))])
(enum (- (size e) 1)
(λ (n)
(if (< n m)
(decode e n)
(decode e (+ n 1))))
(λ (x)
(let ([n (encode e x)])
(cond [(< n m) n]
[(> n m) (- n 1)]
[else (error 'excepted)])))))))
(cdr excepts))]))
;; to-list : enum a -> listof a
;; better be finite
@ -141,11 +137,6 @@
(λ (x)
(- (encode e x) n))))
;; foldl-enum : enum a, b, (a,b -> b) -> b
;; better be a finite enum
(define (foldl-enum f id e)
(foldl f id (to-list e)))
;; display-enum : enum a, Nat -> void
(define (display-enum e n)
(for ([i (range n)])
@ -509,7 +500,32 @@
[else ;; both infinite, same as prod/enum
(dep/enum e f)]))
;; fold-enum : ((listof a), b -> enum a), (listof b) -> enum (listof a)
(define (fold-enum f l)
(map/enum
reverse
reverse
(let loop ([l l]
[acc (const/enum '())])
(cond [(empty? l) acc]
[else
(loop
(cdr l)
(flip-dep/enum
acc
(λ (xs)
(f xs (car l)))))]))))
;; flip-dep/enum : enum a (a -> enum b) -> enum (b,a)
(define (flip-dep/enum e f)
(map/enum
(λ (ab)
(cons (cdr ab)
(car ab)))
(λ (ba)
(cons (cdr ba)
(car ba)))
(dep/enum e f)))
;; more utility enums
;; nats of course
@ -585,305 +601,312 @@
(module+
test
(require rackunit)
(provide check-bijection?)
(define confidence 1000)
(define nums (build-list confidence identity))
(define-simple-check (check-bijection? e)
(let ([nums (build-list (if (<= (enum-size e) confidence)
(enum-size e)
confidence)
identity)])
(andmap =
nums
(map (λ (n)
(encode e (decode e n)))
nums))))
test
(require rackunit)
(provide check-bijection?)
(define confidence 1000)
(define nums (build-list confidence identity))
(define-simple-check (check-bijection? e)
(let ([nums (build-list (if (<= (enum-size e) confidence)
(enum-size e)
confidence)
identity)])
(andmap =
nums
(map (λ (n)
(encode e (decode e n)))
nums))))
;; const/enum tests
(let ([e (const/enum 17)])
(test-begin
(check-eq? (decode e 0) 17)
(check-exn exn:fail?
(λ ()
(decode e 1)))
(check-eq? (encode e 17) 0)
(check-exn exn:fail?
(λ ()
(encode e 0)))
(check-bijection? e)))
;; const/enum tests
(let ([e (const/enum 17)])
(test-begin
(check-eq? (decode e 0) 17)
(check-exn exn:fail?
(λ ()
(decode e 1)))
(check-eq? (encode e 17) 0)
(check-exn exn:fail?
(λ ()
(encode e 0)))
(check-bijection? e)))
;; from-list/enum tests
(let ([e (from-list/enum '(5 4 1 8))])
(test-begin
(check-eq? (decode e 0) 5)
(check-eq? (decode e 3) 8)
(check-exn exn:fail?
(λ () (decode e 4)))
(check-eq? (encode e 5) 0)
(check-eq? (encode e 8) 3)
(check-exn exn:fail?
(λ ()
(encode e 17)))
(check-bijection? e)))
;; from-list/enum tests
(let ([e (from-list/enum '(5 4 1 8))])
(test-begin
(check-eq? (decode e 0) 5)
(check-eq? (decode e 3) 8)
(check-exn exn:fail?
(λ () (decode e 4)))
(check-eq? (encode e 5) 0)
(check-eq? (encode e 8) 3)
(check-exn exn:fail?
(λ ()
(encode e 17)))
(check-bijection? e)))
;; map test
(define nats+1 (nats+/enum 1))
;; map test
(define nats+1 (nats+/enum 1))
(test-begin
(check-equal? (size nats+1) +inf.f)
(check-equal? (decode nats+1 0) 1)
(check-equal? (decode nats+1 1) 2)
(check-bijection? nats+1))
;; encode check
(test-begin
(check-exn exn:fail?
(λ ()
(decode nats -1))))
(test-begin
(check-equal? (size nats+1) +inf.f)
(check-equal? (decode nats+1 0) 1)
(check-equal? (decode nats+1 1) 2)
(check-bijection? nats+1))
;; encode check
(test-begin
(check-exn exn:fail?
(λ ()
(decode nats -1))))
;; ints checks
(test-begin
(check-eq? (decode ints 0) 0) ; 0 -> 0
(check-eq? (decode ints 1) 1) ; 1 -> 1
(check-eq? (decode ints 2) -1) ; 2 -> 1
(check-eq? (encode ints 0) 0)
(check-eq? (encode ints 1) 1)
(check-eq? (encode ints -1) 2)
(check-bijection? ints)) ; -1 -> 2, -3 -> 4
;; ints checks
(test-begin
(check-eq? (decode ints 0) 0) ; 0 -> 0
(check-eq? (decode ints 1) 1) ; 1 -> 1
(check-eq? (decode ints 2) -1) ; 2 -> 1
(check-eq? (encode ints 0) 0)
(check-eq? (encode ints 1) 1)
(check-eq? (encode ints -1) 2)
(check-bijection? ints)) ; -1 -> 2, -3 -> 4
;; sum tests
(test-begin
(let ([bool-or-num (sum/enum bools
(from-list/enum '(0 1 2)))]
[bool-or-nat (sum/enum bools
nats)]
[nat-or-bool (sum/enum nats
bools)]
[odd-or-even (sum/enum evens
odds)])
(check-equal? (enum-size bool-or-num)
5)
(check-equal? (decode bool-or-num 0) #t)
(check-equal? (decode bool-or-num 1) #f)
(check-equal? (decode bool-or-num 2) 0)
(check-exn exn:fail?
(λ ()
(decode bool-or-num 5)))
(check-equal? (encode bool-or-num #f) 1)
(check-equal? (encode bool-or-num 2) 4)
(check-bijection? bool-or-num)
;; sum tests
(test-begin
(let ([bool-or-num (sum/enum bools
(from-list/enum '(0 1 2)))]
[bool-or-nat (sum/enum bools
nats)]
[nat-or-bool (sum/enum nats
bools)]
[odd-or-even (sum/enum evens
odds)])
(check-equal? (enum-size bool-or-num)
5)
(check-equal? (decode bool-or-num 0) #t)
(check-equal? (decode bool-or-num 1) #f)
(check-equal? (decode bool-or-num 2) 0)
(check-exn exn:fail?
(λ ()
(decode bool-or-num 5)))
(check-equal? (encode bool-or-num #f) 1)
(check-equal? (encode bool-or-num 2) 4)
(check-bijection? bool-or-num)
(check-equal? (enum-size bool-or-nat)
+inf.f)
(check-equal? (decode bool-or-nat 0) #t)
(check-equal? (decode bool-or-nat 2) 0)
(check-bijection? bool-or-nat)
(check-equal? (enum-size bool-or-nat)
+inf.f)
(check-equal? (decode bool-or-nat 0) #t)
(check-equal? (decode bool-or-nat 2) 0)
(check-bijection? bool-or-nat)
(check-equal? (encode bool-or-num #f) 1)
(check-equal? (encode bool-or-num 2) 4)
(check-equal? (encode bool-or-num #f) 1)
(check-equal? (encode bool-or-num 2) 4)
(check-equal? (enum-size odd-or-even)
+inf.f)
(check-equal? (decode odd-or-even 0) 0)
(check-equal? (decode odd-or-even 1) 1)
(check-equal? (decode odd-or-even 2) 2)
(check-exn exn:fail?
(λ ()
(decode odd-or-even -1)))
(check-equal? (encode odd-or-even 0) 0)
(check-equal? (encode odd-or-even 1) 1)
(check-equal? (encode odd-or-even 2) 2)
(check-equal? (encode odd-or-even 3) 3)
(check-bijection? odd-or-even)))
(check-equal? (enum-size odd-or-even)
+inf.f)
(check-equal? (decode odd-or-even 0) 0)
(check-equal? (decode odd-or-even 1) 1)
(check-equal? (decode odd-or-even 2) 2)
(check-exn exn:fail?
(λ ()
(decode odd-or-even -1)))
(check-equal? (encode odd-or-even 0) 0)
(check-equal? (encode odd-or-even 1) 1)
(check-equal? (encode odd-or-even 2) 2)
(check-equal? (encode odd-or-even 3) 3)
(check-bijection? odd-or-even)))
;; prod/enum tests
(define bool*bool (prod/enum bools bools))
(define 1*b (prod/enum (const/enum 1) bools))
(define bool*nats (prod/enum bools nats))
(define nats*bool (prod/enum nats bools))
(define nats*nats (prod/enum nats nats))
(define ns-equal? (λ (ns ms)
(and (= (car ns)
(car ms))
(= (cdr ns)
(cdr ms)))))
;; prod/enum tests
(define bool*bool (prod/enum bools bools))
(define 1*b (prod/enum (const/enum 1) bools))
(define bool*nats (prod/enum bools nats))
(define nats*bool (prod/enum nats bools))
(define nats*nats (prod/enum nats nats))
(define ns-equal? (λ (ns ms)
(and (= (car ns)
(car ms))
(= (cdr ns)
(cdr ms)))))
;; prod tests
(test-begin
;; prod tests
(test-begin
(check-equal? (size 1*b) 2)
(check-equal? (decode 1*b 0) (cons 1 #t))
(check-equal? (decode 1*b 1) (cons 1 #f))
(check-bijection? 1*b)
(check-equal? (enum-size bool*bool) 4)
(check-equal? (decode bool*bool 0)
(cons #t #t))
(check-equal? (decode bool*bool 1)
(cons #t #f))
(check-equal? (decode bool*bool 2)
(cons #f #t))
(check-equal? (decode bool*bool 3)
(cons #f #f))
(check-bijection? bool*bool)
(check-equal? (size 1*b) 2)
(check-equal? (decode 1*b 0) (cons 1 #t))
(check-equal? (decode 1*b 1) (cons 1 #f))
(check-bijection? 1*b)
(check-equal? (enum-size bool*bool) 4)
(check-equal? (decode bool*bool 0)
(cons #t #t))
(check-equal? (decode bool*bool 1)
(cons #t #f))
(check-equal? (decode bool*bool 2)
(cons #f #t))
(check-equal? (decode bool*bool 3)
(cons #f #f))
(check-bijection? bool*bool)
(check-equal? (enum-size bool*nats) +inf.f)
(check-equal? (decode bool*nats 0)
(cons #t 0))
(check-equal? (decode bool*nats 1)
(cons #f 0))
(check-equal? (decode bool*nats 2)
(cons #t 1))
(check-equal? (decode bool*nats 3)
(cons #f 1))
(check-bijection? bool*nats)
(check-equal? (enum-size bool*nats) +inf.f)
(check-equal? (decode bool*nats 0)
(cons #t 0))
(check-equal? (decode bool*nats 1)
(cons #f 0))
(check-equal? (decode bool*nats 2)
(cons #t 1))
(check-equal? (decode bool*nats 3)
(cons #f 1))
(check-bijection? bool*nats)
(check-equal? (enum-size nats*bool) +inf.f)
(check-equal? (decode nats*bool 0)
(cons 0 #t))
(check-equal? (decode nats*bool 1)
(cons 0 #f))
(check-equal? (decode nats*bool 2)
(cons 1 #t))
(check-equal? (decode nats*bool 3)
(cons 1 #f))
(check-bijection? nats*bool)
(check-equal? (enum-size nats*bool) +inf.f)
(check-equal? (decode nats*bool 0)
(cons 0 #t))
(check-equal? (decode nats*bool 1)
(cons 0 #f))
(check-equal? (decode nats*bool 2)
(cons 1 #t))
(check-equal? (decode nats*bool 3)
(cons 1 #f))
(check-bijection? nats*bool)
(check-equal? (enum-size nats*nats) +inf.f)
(check ns-equal?
(decode nats*nats 0)
(cons 0 0))
(check ns-equal?
(decode nats*nats 1)
(cons 0 1))
(check ns-equal?
(decode nats*nats 2)
(cons 1 0))
(check ns-equal?
(decode nats*nats 3)
(cons 0 2))
(check ns-equal?
(decode nats*nats 4)
(cons 1 1))
(check-bijection? nats*nats))
(check-equal? (enum-size nats*nats) +inf.f)
(check ns-equal?
(decode nats*nats 0)
(cons 0 0))
(check ns-equal?
(decode nats*nats 1)
(cons 0 1))
(check ns-equal?
(decode nats*nats 2)
(cons 1 0))
(check ns-equal?
(decode nats*nats 3)
(cons 0 2))
(check ns-equal?
(decode nats*nats 4)
(cons 1 1))
(check-bijection? nats*nats))
;; dep/enum tests
(define (up-to n)
(take/enum nats (+ n 1)))
;; dep/enum tests
(define (up-to n)
(take/enum nats (+ n 1)))
(define 3-up
(dep/enum
(from-list/enum '(0 1 2))
up-to))
(define 3-up
(dep/enum
(from-list/enum '(0 1 2))
up-to))
(define from-3
(dep/enum
(from-list/enum '(0 1 2))
nats+/enum))
(define from-3
(dep/enum
(from-list/enum '(0 1 2))
nats+/enum))
(define nats-to
(dep/enum nats up-to))
(define nats-to
(dep/enum nats up-to))
(define nats-up
(dep/enum nats nats+/enum))
(define nats-up
(dep/enum nats nats+/enum))
(test-begin
(check-equal? (size 3-up) 6)
(check-equal? (decode 3-up 0) (cons 0 0))
(check-equal? (decode 3-up 1) (cons 1 0))
(check-equal? (decode 3-up 2) (cons 1 1))
(check-equal? (decode 3-up 3) (cons 2 0))
(check-equal? (decode 3-up 4) (cons 2 1))
(check-equal? (decode 3-up 5) (cons 2 2))
(check-bijection? 3-up)
(test-begin
(check-equal? (size 3-up) 6)
(check-equal? (decode 3-up 0) (cons 0 0))
(check-equal? (decode 3-up 1) (cons 1 0))
(check-equal? (decode 3-up 2) (cons 1 1))
(check-equal? (decode 3-up 3) (cons 2 0))
(check-equal? (decode 3-up 4) (cons 2 1))
(check-equal? (decode 3-up 5) (cons 2 2))
(check-bijection? 3-up)
(check-equal? (size from-3) +inf.f)
(check-equal? (decode from-3 0) (cons 0 0))
(check-equal? (decode from-3 1) (cons 1 1))
(check-equal? (decode from-3 2) (cons 2 2))
(check-equal? (decode from-3 3) (cons 0 1))
(check-equal? (decode from-3 4) (cons 1 2))
(check-equal? (decode from-3 5) (cons 2 3))
(check-equal? (decode from-3 6) (cons 0 2))
(check-bijection? from-3)
(check-equal? (size from-3) +inf.f)
(check-equal? (decode from-3 0) (cons 0 0))
(check-equal? (decode from-3 1) (cons 1 1))
(check-equal? (decode from-3 2) (cons 2 2))
(check-equal? (decode from-3 3) (cons 0 1))
(check-equal? (decode from-3 4) (cons 1 2))
(check-equal? (decode from-3 5) (cons 2 3))
(check-equal? (decode from-3 6) (cons 0 2))
(check-bijection? from-3)
(check-equal? (size nats-to) +inf.f)
(check-equal? (decode nats-to 0) (cons 0 0))
(check-equal? (decode nats-to 1) (cons 1 0))
(check-equal? (decode nats-to 2) (cons 1 1))
(check-equal? (decode nats-to 3) (cons 2 0))
(check-equal? (decode nats-to 4) (cons 2 1))
(check-equal? (decode nats-to 5) (cons 2 2))
(check-equal? (decode nats-to 6) (cons 3 0))
(check-bijection? nats-to)
(check-equal? (size nats-to) +inf.f)
(check-equal? (decode nats-to 0) (cons 0 0))
(check-equal? (decode nats-to 1) (cons 1 0))
(check-equal? (decode nats-to 2) (cons 1 1))
(check-equal? (decode nats-to 3) (cons 2 0))
(check-equal? (decode nats-to 4) (cons 2 1))
(check-equal? (decode nats-to 5) (cons 2 2))
(check-equal? (decode nats-to 6) (cons 3 0))
(check-bijection? nats-to)
(check-equal? (size nats-up) +inf.f)
(check-equal? (decode nats-up 0) (cons 0 0))
(check-equal? (decode nats-up 1) (cons 0 1))
(check-equal? (decode nats-up 2) (cons 1 1))
(check-equal? (decode nats-up 3) (cons 0 2))
(check-equal? (decode nats-up 4) (cons 1 2))
(check-equal? (decode nats-up 5) (cons 2 2))
(check-equal? (decode nats-up 6) (cons 0 3))
(check-equal? (decode nats-up 7) (cons 1 3))
(check-equal? (size nats-up) +inf.f)
(check-equal? (decode nats-up 0) (cons 0 0))
(check-equal? (decode nats-up 1) (cons 0 1))
(check-equal? (decode nats-up 2) (cons 1 1))
(check-equal? (decode nats-up 3) (cons 0 2))
(check-equal? (decode nats-up 4) (cons 1 2))
(check-equal? (decode nats-up 5) (cons 2 2))
(check-equal? (decode nats-up 6) (cons 0 3))
(check-equal? (decode nats-up 7) (cons 1 3))
(check-bijection? nats-up))
(check-bijection? nats-up))
;; dep2/enum tests
;; same as dep unless the right side is finite
(define 3-up-2
(dep2/enum
(from-list/enum '(0 1 2))
up-to))
;; dep2/enum tests
;; same as dep unless the right side is finite
(define 3-up-2
(dep2/enum
(from-list/enum '(0 1 2))
up-to))
(define nats-to-2
(dep2/enum nats up-to))
(define nats-to-2
(dep2/enum nats up-to))
(test-begin
(check-equal? (size 3-up-2) 6)
(check-equal? (decode 3-up-2 0) (cons 0 0))
(check-equal? (decode 3-up-2 1) (cons 1 0))
(check-equal? (decode 3-up-2 2) (cons 1 1))
(check-equal? (decode 3-up-2 3) (cons 2 0))
(check-equal? (decode 3-up-2 4) (cons 2 1))
(check-equal? (decode 3-up-2 5) (cons 2 2))
(check-bijection? 3-up-2)
(test-begin
(check-equal? (size 3-up-2) 6)
(check-equal? (decode 3-up-2 0) (cons 0 0))
(check-equal? (decode 3-up-2 1) (cons 1 0))
(check-equal? (decode 3-up-2 2) (cons 1 1))
(check-equal? (decode 3-up-2 3) (cons 2 0))
(check-equal? (decode 3-up-2 4) (cons 2 1))
(check-equal? (decode 3-up-2 5) (cons 2 2))
(check-bijection? 3-up-2)
(check-equal? (size nats-to-2) +inf.f)
(check-equal? (decode nats-to-2 0) (cons 0 0))
(check-equal? (decode nats-to-2 1) (cons 1 0))
(check-equal? (decode nats-to-2 2) (cons 1 1))
(check-equal? (decode nats-to-2 3) (cons 2 0))
(check-equal? (decode nats-to-2 4) (cons 2 1))
(check-equal? (decode nats-to-2 5) (cons 2 2))
(check-equal? (decode nats-to-2 6) (cons 3 0))
(check-bijection? nats-to-2)
)
(check-equal? (size nats-to-2) +inf.f)
(check-equal? (decode nats-to-2 0) (cons 0 0))
(check-equal? (decode nats-to-2 1) (cons 1 0))
(check-equal? (decode nats-to-2 2) (cons 1 1))
(check-equal? (decode nats-to-2 3) (cons 2 0))
(check-equal? (decode nats-to-2 4) (cons 2 1))
(check-equal? (decode nats-to-2 5) (cons 2 2))
(check-equal? (decode nats-to-2 6) (cons 3 0))
(check-bijection? nats-to-2)
)
;; take/enum test
(define to-2 (up-to 2))
(test-begin
(check-equal? (size to-2) 3)
(check-equal? (decode to-2 0) 0)
(check-equal? (decode to-2 1) 1)
(check-equal? (decode to-2 2) 2)
(check-bijection? to-2))
;; take/enum test
(define to-2 (up-to 2))
(test-begin
(check-equal? (size to-2) 3)
(check-equal? (decode to-2 0) 0)
(check-equal? (decode to-2 1) 1)
(check-equal? (decode to-2 2) 2)
(check-bijection? to-2))
;; to-list test
(test-begin
(check-equal? (to-list (up-to 3))
'(0 1 2 3)))
;; to-list, foldl test
(test-begin
(check-equal? (to-list (up-to 3))
'(0 1 2 3))
(check-equal? (foldl-enum cons '() (up-to 3))
'(3 2 1 0)))
;; except/enum test
(define not-3 (except/enum nats '(3)))
(test-begin
(check-equal? (decode not-3 0) 0)
(check-equal? (decode not-3 3) 4)
(check-bijection? not-3))
(define not-a (except/enum nats '(a)))
(test-begin
(check-equal? (decode not-a 0) 0)
(check-bijection? not-a))
;; except/enum test
(define not-3 (except/enum nats 3))
(test-begin
(check-equal? (decode not-3 0) 0)
(check-equal? (decode not-3 3) 4))
(define not-a (except/enum nats 'a))
(test-begin
(check-equal? (decode not-a 0) 0)))
;; fold-enum tests
(define complicated
(fold-enum
(λ (excepts n)
(except/enum (up-to n) excepts))
'(2 4 6)))
(check-bijection? complicated))

View File

@ -63,4 +63,17 @@
hole)
(x (variable-except λ + if0)))
(try-it 100 λv e)
(try-it 100 λv v)
(try-it 100 λv E)
(try-it 25 λv x)
(define-language M
(m (x_!_1 x_!_1))
(p (number_!_1 number_!_1))
(n (p_!_1 p_!_1))
(x number))
(try-it 100 M m)
(try-it 100 M n)
(try-it 100 M p)