#lang racket
(require rackunit
"4-3-3-amb-repl-program.rkt")
;; The same as 4-1-7-repl-test.rkt only new test cases for amb were added.
;; Note that we can't check the 'try-again functionality because that only works with
;; the repl.
;; default succeed and fail continuations used in calls to ambeval
(define dsc (lambda (val fail) val))
(define dfc (lambda () 'failed))
(test-case "self-evaluating expression"
(check-equal? (ambeval "x" the-global-environment dsc dfc)
"x")
(check-equal? (ambeval 23 the-global-environment dsc dfc)
23)
)
(test-case "quotation"
(define quote-expr '(quote ("x" 23 a)))
(check-equal? (ambeval quote-expr the-global-environment dsc dfc)
'("x" 23 a))
)
(test-case "variable definition"
(define def-expr '(define a 42))
(check-equal? (ambeval def-expr the-global-environment dsc dfc)
'ok)
(check-equal? (ambeval 'a the-global-environment dsc dfc)
42)
)
(test-case "procedure definition"
(define proc-expr '(define (multiply x y) (* x y)))
(check-equal? (ambeval proc-expr the-global-environment dsc dfc)
'ok)
)
(test-case "procedure application"
(define application-expr '(multiply 3 4))
(check-equal? (ambeval application-expr the-global-environment dsc dfc)
12)
(check-equal? (ambeval '(car (cons 1 (cons 2 '())))
the-global-environment
dsc
dfc)
1)
)
(test-case "assignment"
(define assign-expr '(set! a 23))
(check-equal? (ambeval assign-expr the-global-environment dsc dfc)
'ok)
(check-equal? (ambeval 'a the-global-environment dsc dfc)
23)
)
(test-case "predicate"
(check-true (true? (ambeval 'a the-global-environment dsc dfc)))
(check-true (true? (ambeval "false" the-global-environment dsc dfc)))
(check-false (true? (ambeval 'false the-global-environment dsc dfc)))
(check-true (false? (ambeval 'false the-global-environment dsc dfc)))
)
(test-case "if statement"
(define ie '(if true 1 2))
(check-equal? (ambeval ie the-global-environment dsc dfc)
1)
(define ie2 '(if false 1 2))
(check-equal? (ambeval ie2 the-global-environment dsc dfc)
2)
)
(test-case "cond statement"
(define ce '(cond ("a" 1 2) ("b" 3)))
(check-equal? (ambeval ce the-global-environment dsc dfc)
2)
(define alt-ce '(cond ((cons 1 (cons 2 '())) => car) (else 87)))
(check-equal? (ambeval alt-ce the-global-environment dsc dfc)
1)
)
(test-case "begin statement"
(define be '(begin "a" "b" 1 2 (* 3 4)))
(check-equal? (ambeval be the-global-environment dsc dfc)
12)
)
(test-case "boolean operator"
(ambeval '(define c 38) the-global-environment dsc dfc)
(check-equal? (ambeval '(and 1 "a" c) the-global-environment dsc dfc)
38)
(check-equal? (ambeval '(and 1 1 false) the-global-environment dsc dfc)
false)
(check-equal? (ambeval '(or false false 1)
the-global-environment
dsc
dfc)
1)
(check-equal? (ambeval '(or false false false)
the-global-environment
dsc
dfc)
false)
)
(test-case "let"
(define le '(let ((x 1) (y 2) (z 3)) 'side-effect (+ x y z)))
(check-equal? (ambeval le the-global-environment dsc dfc)
6)
(define le2 '(let ((x 1) (y 2)) (+ x y)))
(check-equal? (ambeval le2 the-global-environment dsc dfc)
3)
(define le3 '(let ((x 1)) 'side-effect (+ x 2)))
(check-equal? (ambeval le3 the-global-environment dsc dfc)
3)
(define le4 '(let () 'side-effect (+ 3 2)))
(check-equal? (ambeval le4 the-global-environment dsc dfc)
5)
(define le5 '(let () (+ 3 2)))
(check-equal? (ambeval le5 the-global-environment dsc dfc)
5)
; let with internal defines
(define le6 '(let ([x 1])
(define y 2)
(+ x y)))
(check-equal? (ambeval le6 the-global-environment dsc dfc)
3)
(define le7 '(let* ([x 1]
[y (+ x 1)])
(define z (+ x y))
(define w (+ z 1))
(+ x y z w)))
(check-equal? (ambeval le7 the-global-environment dsc dfc)
10)
)
(test-case "named-let"
(ambeval '(define (fib n)
(let fib-iter ((a 1)
(b 0)
(my-count n))
(if (= my-count 0)
b
(fib-iter (+ a b) a (+ my-count -1)))))
the-global-environment
dsc
dfc)
(check-equal? (ambeval '(fib 0) the-global-environment dsc dfc)
0)
(check-equal? (ambeval '(fib 1) the-global-environment dsc dfc)
1)
(check-equal? (ambeval '(fib 10) the-global-environment dsc dfc)
55)
)
(test-case "let*"
(define lse '(let* ((x 1) (y (+ x 1)) (z (+ y 1))) (+ x y z)))
(check-equal? (ambeval lse the-global-environment dsc dfc)
6)
(define lse2 '(let* ((a 1) (b 2)) 'side-effect (+ a b)))
(check-equal? (ambeval lse2 the-global-environment dsc dfc)
3)
(define lse3 '(let* ((a 1)) 'side-effect (+ a 2)))
(check-equal? (ambeval lse3 the-global-environment dsc dfc)
3)
(define lse4 '(let* ((a 1)) (+ a 2)))
(check-equal? (ambeval lse4 the-global-environment dsc dfc)
3)
)
(test-case "letrec"
(ambeval '(define (my-even? x)
(letrec ((ev? (lambda (n)
(if (= n 0)
true
(od? (- n 1)))))
(od? (lambda (n)
(if (= n 0)
false
(ev? (- n 1))))))
(ev? x)))
the-global-environment
dsc
dfc)
(check-equal? (ambeval '(my-even? 11) the-global-environment dsc dfc)
false)
(check-equal? (ambeval '(my-even? 12) the-global-environment dsc dfc)
true)
)
(test-case "multiple-dwelling"
(ambeval '(define (multiple-dwelling)
(let ([baker (an-element-of (list 1 2 3 4 5))])
(my-require (not (= baker 5)))
(let ([cooper (amb 1 2 3 4 5)])
(my-require (not (= cooper 1)))
(let ([fletcher (amb 1 2 3 4 5)])
(my-require (not (= fletcher 5)))
(my-require (not (= fletcher 1)))
(my-require (not (= (abs (- fletcher cooper)) 1)))
(let ([miller (amb 1 2 3 4 5)])
(my-require (> miller cooper))
(let ([smith (amb 1 2 3 4 5)])
(my-require (distinct? (list baker
cooper
fletcher
miller
smith)))
(my-require (not (= (abs (- smith fletcher)) 1)))
(list (list 'baker baker)
(list 'cooper cooper)
(list 'fletcher fletcher)
(list 'miller miller)
(list 'smith smith))))))))
the-global-environment
dsc
dfc)
(check-equal? (ambeval '(multiple-dwelling)
the-global-environment
dsc
dfc)
'((baker 3)
(cooper 2)
(fletcher 4)
(miller 5)
(smith 1)))
)
(test-case "fathers-daughters-and-yachts"
(ambeval '(define (fathers-daughters-and-yachts)
(define names '(mary-ann gabrielle lorna rosalind melissa))
(let ([parker-daughter (an-element-of names)]
[parker-yacht (an-element-of names)]
[hood-daughter 'melissa]
[hood-yacht 'gabrielle]
[moore-daughter (an-element-of names)]
[moore-yacht 'lorna]
[downing-daughter (an-element-of names)]
[downing-yacht 'melissa]
[hall-daughter (an-element-of names)]
[hall-yacht 'rosalind])
(my-require (distinct?
(list moore-daughter
downing-daughter
hall-daughter
hood-daughter
parker-daughter)))
(my-require (distinct?
(list moore-yacht
downing-yacht
hall-yacht
hood-yacht
parker-yacht)))
(my-require (eq? moore-daughter 'mary-ann))
(my-require (not (eq? moore-daughter moore-yacht)))
(my-require (not (eq? downing-daughter downing-yacht)))
(my-require (not (eq? hall-daughter hall-yacht)))
(my-require (not (eq? hood-daughter hood-yacht)))
(my-require (not (eq? parker-daughter parker-yacht)))
(my-require (or (not (eq? moore-daughter 'gabrielle))
(eq? moore-yacht parker-daughter)))
(my-require (or (not (eq? downing-daughter 'gabrielle))
(eq? downing-yacht parker-daughter)))
(my-require (or (not (eq? hall-daughter 'gabrielle))
(eq? hall-yacht parker-daughter)))
(my-require (or (not (eq? hood-daughter 'gabrielle))
(eq? hood-yacht parker-daughter)))
(my-require (or (not (eq? parker-daughter 'gabrielle))
(eq? parker-yacht parker-daughter)))
(list (list 'moore moore-daughter)
(list 'downing downing-daughter)
(list 'hall hall-daughter)
(list 'hood hood-daughter)
(list 'parker parker-daughter))))
the-global-environment
dsc
dfc)
(check-equal? (ambeval '(fathers-daughters-and-yachts)
the-global-environment
dsc
dfc)
'((moore mary-ann)
(downing lorna)
(hall gabrielle)
(hood melissa)
(parker rosalind)))
)
Comments
0 B
|👍
/👎
0 B
|👍
/👎