racket/collects/redex/tests/tl-test.ss

1851 lines
59 KiB
Scheme
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(module tl-test scheme
(require "../reduction-semantics.ss"
"test-util.ss"
(only-in "../private/matcher.ss" make-bindings make-bind)
scheme/match
"../private/struct.ss")
(reset-count)
;
;
; ;;
; ;
; ; ;;; ;; ;; ;; ;;;; ;; ;;; ;; ;; ;;;
; ; ; ; ;; ; ; ;; ; ; ; ; ; ;; ; ;
; ; ;;;; ; ; ; ; ; ; ;;;; ; ; ;;;;;
; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; ; ; ; ; ;; ; ; ; ; ;
; ;;;;; ;;;;;;;; ;;; ;;;; ;; ;; ;;;;; ;;;; ;;;;
; ; ;
; ;;; ;;;
;
;
(define-language empty-language)
(define-language grammar
(M (M M)
number)
(E hole
(E M)
(number E))
(X (number any)
(any number))
(Q (Q ...)
variable)
(UN (add1 UN)
zero))
(test (pair? (redex-match grammar M '(1 1))) #t)
(test (pair? (redex-match grammar M '(1 1 1))) #f)
(test (pair? (redex-match grammar
(side-condition (M_1 M_2) (equal? (term M_1) (term M_2)))
'(1 1)))
#t)
(test (pair? (redex-match grammar
(side-condition (M_1 M_2) (equal? (term M_1) (term M_2)))
'(1 2)))
#f)
(test (pair? ((redex-match grammar M) '(1 1)))
#t)
;; next 3: test naming of subscript-less non-terminals
(test (pair? (redex-match grammar (M M) (term (1 1)))) #t)
(test (pair? (redex-match grammar (M M) (term (1 2)))) #f)
(test (pair? (redex-match grammar (M_1 M_2) (term (1 2)))) #t)
(define-language base-grammar
(q 1)
(e (+ e e) number)
(x (variable-except +)))
(define-extended-language extended-grammar
base-grammar
(e .... (* e e))
(x (variable-except + *))
(r 2))
(test (pair? (redex-match extended-grammar e '(+ 1 1))) #t)
(test (pair? (redex-match extended-grammar e '(* 2 2))) #t)
(test (pair? (redex-match extended-grammar r '2)) #t)
(test (pair? (redex-match extended-grammar q '1)) #t)
(test (pair? (redex-match extended-grammar x '*)) #f)
(test (pair? (redex-match extended-grammar x '+)) #f)
(test (pair? (redex-match extended-grammar e '....)) #f)
;; make sure that `language' with a four period ellipses signals an error
(test (regexp-match #rx"[.][.][.][.]" (with-handlers ([exn? exn-message])
(let ()
(define-language x (e ....))
12)))
'("...."))
;; test multiple variable non-terminals
(let ()
(define-language lang
((l m) (l m) x)
(x variable-not-otherwise-mentioned))
(test (pair? (redex-match lang m (term x)))
#t))
;; test multiple variable non-terminals
(let ()
(define-language lang
((l m) (l m) x)
(x variable-not-otherwise-mentioned))
(test (pair? (redex-match lang l (term x)))
#t))
(let ()
(define-language lang
((x y) 1 2 3))
(define-extended-language lang2 lang
(x .... 4))
(test (pair? (redex-match lang2 x 4)) #t)
(test (pair? (redex-match lang2 y 4)) #t)
(test (pair? (redex-match lang2 x 1)) #t)
(test (pair? (redex-match lang2 y 2)) #t))
;; test that the variable "e" is not bound in the right-hand side of a side-condition
;; this one signaled an error at some point
(let ()
(define-language bad
(e 2 (side-condition (e) #t)))
(test (pair? (redex-match bad e '(2)))
#t))
;; test that the variable "e" is not bound in the right-hand side of a side-condition
;; this one tests to make sure it really isn't bound
(let ([x #f])
(define-language bad
(e 2 (side-condition (e) (set! x (term e)))))
(redex-match bad e '(2))
(test x 'e))
;; test multiple variable non-terminals being extended
(let ()
(define-language lang
((x y) 1 2 3))
(define-extended-language lang2 lang
(x .... 4))
(test (pair? (redex-match lang2 x 4)) #t)
(test (pair? (redex-match lang2 y 4)) #t)
(test (pair? (redex-match lang2 x 1)) #t)
(test (pair? (redex-match lang2 y 2)) #t))
;; test multiple variable non-terminals in an extended language
(let ()
(define-language lang
((x y) 1 2 3))
(define-extended-language lang2 lang
((z w) 5 6 7))
(test (pair? (redex-match lang2 z 5)) #t)
(test (pair? (redex-match lang2 w 6)) #t))
;; test cases that ensure that extending any one of a
;; multiply defined non-terminal gets extended properly
(let ()
(define-language iswim
((V U W) AA))
(define-extended-language iswim-cont
iswim
(W .... QQ))
(test (pair? (redex-match iswim-cont U (term QQ)))
#t))
(let ()
(define-language iswim
((V U W) AA))
(define-extended-language iswim-cont
iswim
(W .... QQ))
(test (pair? (redex-match iswim-cont V (term QQ)))
#t)
(test (pair? (redex-match iswim-cont U (term QQ)))
#t)
(test (pair? (redex-match iswim-cont W (term QQ)))
#t))
(let ()
(define-language iswim
((V U W) AA))
(define-extended-language iswim-cont
iswim
(V .... QQ))
(test (pair? (redex-match iswim-cont V (term QQ)))
#t)
(test (pair? (redex-match iswim-cont U (term QQ)))
#t)
(test (pair? (redex-match iswim-cont W (term QQ)))
#t))
(let ()
(define-language okay
[(X Y) z])
(define-extended-language replace-both
okay
[(X Y) q])
;; this test ran into an infinite loop in an earlier version of redex.
(test (redex-match replace-both X (term explode)) #f))
(test (with-handlers ([exn? exn-message])
(let ()
(define-language main
[(X Y) z])
(define-extended-language new
main
[(X Y Z) q])
(void)))
"extend-language: new language extends old non-terminal X and also adds new shortcut Z")
(test (with-handlers ([exn? exn-message])
(let ()
(define-language main
[(X Y) z]
[(P Q) w])
(define-extended-language new
main
[(X P) q])
(void)))
"extend-language: new language does not have the same non-terminal aliases as the old, non-terminal P was not in the same group as X in the old language")
;; test caching
(let ()
(define match? #t)
(define-language lang
(x (side-condition any match?)))
(test (pair? (redex-match lang x 1)) #t)
(set! match? #f)
(test (pair? (redex-match lang x 1)) #t)
(parameterize ([caching-enabled? #f])
(test (pair? (redex-match lang x 1)) #f)))
(let ()
(define sc-eval-count 0)
(define-language lang
(x (side-condition any (begin (set! sc-eval-count (+ sc-eval-count 1))
#t))))
(redex-match lang x 1)
(redex-match lang x 1)
(parameterize ([caching-enabled? #f])
(redex-match lang x 1))
(test sc-eval-count 2))
(let ()
(define rhs-eval-count 0)
(define-metafunction empty-language
[(f any) ,(begin (set! rhs-eval-count (+ rhs-eval-count 1))
1)])
(term (f 1))
(term (f 1))
(parameterize ([caching-enabled? #f])
(term (f 1)))
(test rhs-eval-count 2))
(define-namespace-anchor here)
(define ns (namespace-anchor->namespace here))
(let ([src 'bad-underscore])
(test
(parameterize ([current-namespace ns])
(syntax-error-sources
'(define-language L (n m_1))
src))
(list src)))
;
;
; ;;; ;
; ; ; ;
; ;;; ; ;;; ;;;;; ;;; ;;;;; ;; ;; ;; ;; ;;;; ;;;;; ;;; ;;; ;; ;; ;;;;
; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ;; ; ; ;
; ; ; ; ;;;;; ; ;;;; ; ; ; ; ; ; ; ; ; ; ; ; ;;;
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ;;;;;;; ;;;; ;;; ;;;;; ;;;;; ;; ;;;;; ;;; ;;; ;;; ;;;;; ;;; ;;; ;;; ;;;;
;
;
;
;
(define-metafunction grammar
[(f (side-condition (number_1 number_2)
(< (term number_1)
(term number_2))))
x]
[(f (number 1)) y]
[(f (number_1 2)) ,(+ (term number_1) 2)]
[(f (4 4)) q]
[(f (4 4)) r])
(define-metafunction grammar
[(g X) x])
(test (term (f (1 17))) 'x)
(test (term (f (11 1))) 'y)
(test (term (f (11 2))) 13)
;; match two clauess => take first one
(test (term (f (4 4))) 'q)
;; match one clause two ways => error
(let ()
(define-metafunction empty-language
[(ll (number_1 ... number_2 ...)) (number_1 ...)])
(test (with-handlers ((exn? (λ (x) 'exn-raised)))
(term (ll ()))
'no-exn)
'no-exn)
(test (with-handlers ((exn? (λ (x) 'exn-raised)))
(term (ll (4 4)))
'no-exn)
'exn-raised))
;; match no ways => error
(test (with-handlers ((exn? (λ (x) 'exn-raised))) (term (f mis-match)) 'no-exn)
'exn-raised)
(define-metafunction grammar
[(h (M_1 M_2)) ((h M_2) (h M_1))]
[(h number_1) ,(+ (term number_1) 1)])
(test (term (h ((1 2) 3)))
(term (4 (3 2))))
(define-metafunction grammar
[(h2 (Q_1 ...)) ((h2 Q_1) ...)]
[(h2 variable) z])
(test (term (h2 ((x y) a b c)))
(term ((z z) z z z)))
(let ()
(define-metafunction empty-language
[(f (1)) 1]
[(f (2)) 2]
[(f 3) 3])
(test (in-domain? (f 1)) #f)
(test (in-domain? (f (1))) #t)
(test (in-domain? (f ((1)))) #f)
(test (in-domain? (f 3)) #t)
(test (in-domain? (f 4)) #f))
(let ()
(define-metafunction empty-language
f : number -> number
[(f 1) 1])
(test (in-domain? (f 1)) #t)
(test (in-domain? (f 2)) #t)
(test (in-domain? (f x)) #f))
(let ()
(define-metafunction empty-language
[(f x) x])
(test
(term-let ((y 'x))
(in-domain? (f y)))
#t)
(test
(term-let ((y 'z))
(in-domain? (f y)))
#f))
;; mutually recursive metafunctions
(define-metafunction grammar
[(odd zero) #f]
[(odd (add1 UN_1)) (even UN_1)])
(define-metafunction grammar
[(even zero) #t]
[(even (add1 UN_1)) (odd UN_1)])
(test (term (odd (add1 (add1 (add1 (add1 zero))))))
(term #f))
(let ()
(define-metafunction empty-language
[(pRe xxx) 1])
(define-metafunction empty-language
[(Merge-Exns any_1) any_1])
(test (term (pRe (Merge-Exns xxx)))
1))
(let ()
(define-metafunction empty-language
[(f (x)) ,(term-let ([var-should-be-lookedup 'y]) (term (f var-should-be-lookedup)))]
[(f y) y]
[(f var-should-be-lookedup) var-should-be-lookedup]) ;; taking this case is bad!
(test (term (f (x))) (term y)))
(let ()
(define-metafunction empty-language
[(f (x)) (x ,@(term-let ([var-should-be-lookedup 'y]) (term (f var-should-be-lookedup))) x)]
[(f y) (y)]
[(f var-should-be-lookedup) (var-should-be-lookedup)]) ;; taking this case is bad!
(test (term (f (x))) (term (x y x))))
(let ()
(define-metafunction empty-language
[(f (any_1 any_2))
case1
(side-condition (not (equal? (term any_1) (term any_2))))
(side-condition (not (equal? (term any_1) 'x)))]
[(f (any_1 any_2))
case2
(side-condition (not (equal? (term any_1) (term any_2))))]
[(f (any_1 any_2))
case3])
(test (term (f (q r))) (term case1))
(test (term (f (x y))) (term case2))
(test (term (f (x x))) (term case3)))
(let ()
(define-metafunction empty-language
[(f (n number)) (n number)]
[(f (a any)) (a any)]
[(f (v variable)) (v variable)]
[(f (s string)) (s string)])
(test (term (f (n 1))) (term (n 1)))
(test (term (f (a (#f "x" whatever)))) (term (a (#f "x" whatever))))
(test (term (f (v x))) (term (v x)))
(test (term (f (s "x"))) (term (s "x"))))
;; test ..._1 patterns
(let ()
(define-metafunction empty-language
[(zip ((variable_id ..._1) (number_val ..._1)))
((variable_id number_val) ...)])
(test (term (zip ((a b) (1 2)))) (term ((a 1) (b 2)))))
(let ()
(define-metafunction empty-language
[(f any_1 any_2 any_3) (any_3 any_2 any_1)])
(test (term (f 1 2 3))
(term (3 2 1))))
(let ()
(define-metafunction empty-language
[(f (any_1 any_2 any_3)) 3])
(define-metafunction/extension f empty-language
[(g (any_1 any_2)) 2])
(define-metafunction/extension g empty-language
[(h (any_1)) 1])
(test (term (h (1))) 1)
(test (term (h (1 2))) 2)
(test (term (h (1 2 3))) 3))
(let ()
(define-metafunction empty-language
[(f any_1 any_2 any_3) 3])
(define-metafunction/extension f empty-language
[(g any_1 any_2) 2])
(define-metafunction/extension g empty-language
[(h any_1) 1])
(test (term (h 1)) 1)
(test (term (h 1 2)) 2)
(test (term (h 1 2 3)) 3))
(let ()
(define-metafunction empty-language
[(f number_1 number_2) (f number_1)])
(define-metafunction/extension f empty-language
[(g number_1) number_1])
(define-metafunction empty-language
[(h number_1 number_2) (h number_1)]
[(h number_1) number_1])
(test (term (g 11 17)) 11)
(test (term (h 11 17)) 11))
(let ()
(define-metafunction empty-language
[(f (number_1 number_2))
number_3
(where number_3 ,(+ (term number_1) (term number_2)))])
(test (term (f (11 17))) 28))
(let ()
(define-metafunction empty-language
[(f variable)
(any_x any_x)
(where any_x (variable variable))])
(test (term (f z))
(term ((z z) (z z)))))
(let ()
(define-metafunction empty-language
[(f number_1)
number_1
(where number_2 ,(add1 (term number_1)))
(where number_3 ,(add1 (term number_2)))
(side-condition (and (number? (term number_3))
(= (term number_3) 4)))]
[(f any) 0])
(test (term (f 2)) 2))
(let ()
(define-language x-lang
(x variable))
(define-metafunction x-lang
f : x x -> x
[(f x_1 x_2) x_1])
(test (term (f p q)) (term p))
(test (in-domain? (f p q)) #t))
(let ()
(define-metafunction empty-language
[(err number_1 ... number_2 ...) (number_1 ...)])
(test (term (err)) (term ()))
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
(term (err 1 2))
'no-exn)
'right-exn))
(let ()
(define-metafunction empty-language
err : number ... -> number
[(err number ...) 1])
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
(term (err #f #t))
'no-exn)
'right-exn))
(let ()
(define-metafunction empty-language
err : number ... -> number
[(err number ...) #f])
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
(term (err 1 2))
'no-exn)
'right-exn))
(let ()
(define-metafunction empty-language
err : number ... -> (number number)
[(err number ...) (number ...)])
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
(term (err 1 2))
'no-exn)
'no-exn)
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
(term (err 1 1))
'no-exn)
'no-exn))
(let ()
;; test that 'where' clauses can contain recursive calls.
(define-metafunction empty-language
[(f (any))
x
(where x (f any))]
[(f any) any])
(test (term (f ((((x))))))
(term x)))
(let ()
(define-language lamv
(z variable hole))
(define-metafunction lamv
foo : z -> any
[(foo hole) dontcare]
[(foo variable) docare])
(test (term (foo hole))
(term dontcare))
(test (term (foo y))
(term docare)))
(let ()
(define f-called? #f)
(define-metafunction empty-language
f : (side-condition any_1 (begin (set! f-called? #t) #t)) -> any
[(f any_1) any_1])
(test (term (f 1)) 1)
(test f-called? #t))
(let ()
(define g-called? #f)
(define-metafunction empty-language
g : any -> (side-condition any_1 (begin (set! g-called? #t) #t))
[(g any_1) any_1])
(test (term (g 1)) 1)
(test g-called? #t))
;; test that tracing works properly
;; note that caching comes into play here (which is why we don't see the recursive calls)
(let ()
(define-metafunction empty-language
[(f 0) 0]
[(f number) (f ,(- (term number) 1))])
(let ([sp (open-output-string)])
(parameterize ([current-output-port sp])
(term (f 1)))
(test (get-output-string sp) ""))
(let ([sp (open-output-string)])
(parameterize ([current-output-port sp]
[current-traced-metafunctions 'all])
(term (f 1)))
(test (get-output-string sp) ">(f 1)\n<0\n"))
(let ([sp (open-output-string)])
(parameterize ([current-output-port sp]
[current-traced-metafunctions '(f)])
(term (f 1)))
(test (get-output-string sp) ">(f 1)\n<0\n")))
(let ()
(define-language var-lang [(x y z w) variable])
;; this should produce the second case,
;; since the where clause (should) fail to match
;; in the first case.
(define-metafunction var-lang
[(f x)
first-case
(where (AnotherAtom y) (Atom x))]
[(f x)
second-case])
(test (term (f a)) (term second-case)))
(let ()
;; this is an ambiguous function
;; and should signal an error if it is ever called
;; with multiple different arguments, but if the
;; arguments are all the same, it will return
;; the same result for any parse, and thus should be allowed.
(define-metafunction empty-language
[(f any_x ... any_y any_z ...)
any_y])
(test (term (f 1 1 1 1 1)) (term 1)))
(let ()
(define-metafunction empty-language
[(ex variable_x)
variable_x
(where quote variable_x)])
(test (term (ex quote)) (term quote)))
(let ()
(define-metafunction empty-language
[(f any ...)
(any ...)
(where variable_1 x)
(side-condition #f)
(where (number ...) y)]
[(f any ...)
12345])
(test (term (f 8)) 12345))
;
;
;
;
;
;
; ;; ;;; ;; ;; ;; ;;
; ;; ;;; ;; ;; ;;; ;;
; ;;;;; ;;;; ;;;;; ;; ;; ;;; ;;;; ;;;; ;;;; ;; ;;;; ;;;;; ;; ;;;; ;; ;;;
; ;;;;;; ;; ;; ;;;; ;; ;;;;;; ;; ;; ;;;; ;; ;; ;; ;; ;; ;;;; ;; ;;;;;; ;;;;;;
; ;;; ;; ;;;;;;;; ;; ;; ;; ;; ;;;;;;;;;;;; ;; ;;;;;;;; ;; ;;;; ;;; ;; ;;; ;;; ;; ;;
; ;;; ;; ;;; ;; ;; ;; ;; ;;; ;;;; ;; ;;; ;; ;;; ;; ;;; ;; ;;; ;;; ;; ;;
; ;;;;;; ;;; ;; ;; ;; ;; ;; ;;; ;; ;; ;;; ;; ;; ;;; ;; ;;;; ;; ;;;;;; ;; ;;
; ;;;;; ;;;; ;; ;; ;; ;; ;;;; ;; ;;;; ;; ;;;;;; ;;; ;; ;;;; ;; ;;
;
;
;
(let ()
(define-relation empty-language
[(<: any any) #t])
(test (term (<: 1 1)) #t)
(test (term (<: 1 2)) #f))
(let ()
(define-relation empty-language
[(<: number_1 number_2) ,(< (term number_1) (term number_2))]
[(<: number_1 number_1) #t])
(test (term (<: 1 2)) #t)
(test (term (<: 1 1)) #t)
(test (term (<: 2 1)) #f))
(let ()
(define-relation empty-language
[(<: number_1 ... number_2 number_3 ... number_2 number_4 ...) #t])
(test (term (<: 1 2 3 4)) #f)
(test (term (<: 1 1 2 3 4)) #t)
(test (term (<: 1 2 1 3 4)) #t)
(test (term (<: 1 2 3 1 4)) #t)
(test (term (<: 1 2 3 4 1)) #t))
(let ()
(define-relation empty-language
[(<: number_1 number_1)])
(test (term (<: 1 1)) #t)
(test (term (<: 1 2)) #f))
(let ()
(define-relation empty-language
[(<: number_1 number_2 number_3)
,(= (term number_1) (term number_2))
,(= (term number_2) (term number_3))])
(test (term (<: 1 2 3)) #f)
(test (term (<: 1 1 2)) #f)
(test (term (<: 1 2 2)) #f)
(test (term (<: 1 1 1)) #t))
; ;; ; ;; ;
; ; ; ; ;
; ;; ;; ;;; ;; ; ;; ;; ;;;; ;;;;; ;;; ;;; ;; ;; ;; ;; ;;; ; ;;; ;;;;; ;;; ;;; ;; ;;
; ;; ; ; ; ;; ; ; ; ; ; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ;; ;
; ; ;;;;; ; ; ; ; ; ; ; ; ; ; ; ;;;;; ; ;;;;; ; ;;;; ; ; ; ; ; ;
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ;;;;; ;;;; ;;;;; ;; ;; ;;; ;;; ;;;;; ;;; ;;; ;;; ;;;;; ;;;; ;;;;; ;;;;; ;;; ;;;;; ;;; ;;; ;;;
;
;
;
;
(test (apply-reduction-relation
(reduction-relation
grammar
(--> (in-hole E_1 (number_1 number_2))
(in-hole E_1 ,(* (term number_1) (term number_2)))))
'((2 3) (4 5)))
(list '(6 (4 5))))
(test (apply-reduction-relation
(reduction-relation
grammar
(~~> (number_1 number_2)
,(* (term number_1) (term number_2)))
with
[(--> (in-hole E_1 a) (in-hole E_1 b)) (~~> a b)])
'((2 3) (4 5)))
(list '(6 (4 5))))
(test (apply-reduction-relation
(reduction-relation
grammar
(==> (number_1 number_2)
,(* (term number_1) (term number_2)))
with
[(--> (M_1 a) (M_1 b)) (~~> a b)]
[(~~> (M_1 a) (M_1 b)) (==> a b)])
'((1 2) ((2 3) (4 5))))
(list '((1 2) ((2 3) 20))))
(test (apply-reduction-relation
(reduction-relation
grammar
(~~> (number_1 number_2)
,(* (term number_1) (term number_2)))
(==> (number_1 number_2)
,(* (term number_1) (term number_2)))
with
[(--> (M_1 a) (M_1 b)) (~~> a b)]
[(--> (a M_1) (b M_1)) (==> a b)])
'((2 3) (4 5)))
(list '(6 (4 5))
'((2 3) 20)))
(test (apply-reduction-relation
(reduction-relation
grammar
(--> (M_1 (number_1 number_2))
(M_1 ,(* (term number_1) (term number_2))))
(==> (number_1 number_2)
,(* (term number_1) (term number_2)))
with
[(--> (a M_1) (b M_1)) (==> a b)])
'((2 3) (4 5)))
(list '((2 3) 20)
'(6 (4 5))))
; shortcuts like this fail if compilation fails to preserve
; lexical context for side-conditions expressions.
(test (let ([x #t])
(apply-reduction-relation
(reduction-relation
grammar
(==> variable variable)
with
[(--> (a (side-condition number x)) b)
(==> a b)])
'(x 4)))
'(x))
(test (apply-reduction-relation/tag-with-names
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mul))
'(4 5))
(list (list "mul" 20)))
(test (apply-reduction-relation/tag-with-names
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
"mul"))
'(4 5))
(list (list "mul" 20)))
(test (apply-reduction-relation/tag-with-names
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))))
'(4 5))
(list (list #f 20)))
(test (apply-reduction-relation/tag-with-names
(reduction-relation
grammar
(==> (number_1 number_2)
,(* (term number_1) (term number_2))
mult)
with
[(--> (M_1 a) (M_1 b)) (==> a b)])
'((2 3) (4 5)))
(list (list "mult" '((2 3) 20))))
(test (apply-reduction-relation
(union-reduction-relations
(reduction-relation empty-language
(--> x a)
(--> x b))
(reduction-relation empty-language
(--> x c)
(--> x d)))
'x)
(list 'a 'b 'c 'd))
(test (apply-reduction-relation
(union-reduction-relations
(reduction-relation empty-language (--> x a))
(reduction-relation empty-language (--> x b))
(reduction-relation empty-language (--> x c))
(reduction-relation empty-language (--> x d)))
'x)
(list 'a 'b 'c 'd))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> (number_1 number_2)
number_2
(side-condition (< (term number_1) (term number_2))))
(--> (number_1 number_2)
number_1
(side-condition (< (term number_2) (term number_1)))))
'(1 2))
(list 2))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> x #f))
(term x))
(list #f))
(define-language x-language
(x variable))
(test (apply-reduction-relation
(reduction-relation
x-language
(--> x (x x)))
'y)
(list '(y y)))
(test (apply-reduction-relation
(reduction-relation
x-language
(--> (x ...) ((x ...))))
'(p q r))
(list '((p q r))))
#;
(test (apply-reduction-relation
(reduction-relation
empty-language
#:main-arrow :->
(:-> 1 2))
1)
'(2))
(test (apply-reduction-relation
(reduction-relation
empty-language
#:domain number
(--> 1 2))
1)
'(2))
(test (let ([red
(reduction-relation
empty-language
#:domain number
(--> 1 2))])
(with-handlers ((exn? exn-message))
(apply-reduction-relation red 'x)
'no-exception-raised))
"reduction-relation: relation not defined for x")
(test (let ([red
(reduction-relation
empty-language
#:domain number
(--> 1 x))])
(with-handlers ((exn? exn-message))
(apply-reduction-relation red 1)
'no-exception-raised))
"reduction-relation: relation reduced to x via rule #0 (counting from 0), which is outside its domain")
(let* ([red1
(reduction-relation
empty-language
#:domain (side-condition number_1 (even? (term number_1)))
(--> number number))]
[red2
(reduction-relation
empty-language
#:domain (side-condition number_1 (odd? (term number_1)))
(--> number number))]
[red-c
(union-reduction-relations red1 red2)])
;; ensure first branch of 'union' is checked
(test (with-handlers ((exn? exn-message))
(apply-reduction-relation red-c 1)
'no-exception-raised)
"reduction-relation: relation not defined for 1")
;; ensure second branch of 'union' is checked
(test (with-handlers ((exn? exn-message))
(apply-reduction-relation red-c 2)
'no-exception-raised)
"reduction-relation: relation not defined for 2"))
(let ()
(define-language l1
(D 0 1 2))
(define r1
(reduction-relation
l1
#:domain D
(--> D D)))
(define-language l2
(D 0 1 2 3))
(define r2
(extend-reduction-relation r1 l2))
;; test that the domain is re-interpreted for the extended reduction-relation
(test (apply-reduction-relation r2 3)
'(3)))
(let ()
(define-language l1
(D 0 1 2))
(define r1
(reduction-relation
l1
#:domain (D D)
(--> (D_1 D_2) (D_2 D_1))))
;; test that duplicated identifiers in the domain contract do not have to be equal
(test (apply-reduction-relation r1 (term (1 2)))
(list (term (2 1)))))
;;test that #:arrow keyword works
(test (apply-reduction-relation
(reduction-relation
empty-language
#:arrow :->
(:-> 1 2))
1)
'(2))
(let ()
(define-language n-lang
[n number])
(test (apply-reduction-relation
(reduction-relation n-lang [--> any ,(length (redex-match n-lang n 1))])
11)
'(1)))
(parameterize ([current-namespace syn-err-test-namespace])
(eval (quote-syntax
(define-language grammar
(M (M M)
number)
(E hole
(E M)
(number E))
(X (number any)
(any number))
(Q (Q ...)
variable)
(UN (add1 UN)
zero)))))
(test-syn-err (reduction-relation
grammar
(~~> (number_1 number_2)
,(* (term number_1) (term number_2)))
with
[(--> (M a) (M b)) (~~> a b)]
[(~~> (M a) (M b)) (==> a b)])
#rx"no rules")
(test-syn-err (reduction-relation grammar)
#rx"no rules use -->")
(test-syn-err (reduction-relation
grammar
(~~> (number_1 number_2)
,(* (term number_1) (term number_2))))
#rx"~~> relation is not defined")
(test-syn-err (reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult)
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
#rx"same name on multiple rules")
(test-syn-err (reduction-relation
grammar
(--> 1 2)
(==> 3 4))
#rx"not defined.*==>")
(test-syn-err (reduction-relation
empty-language
(--> 1 2)
(==> 3 4)
with
[(~> a b) (==> a b)])
#rx"not defined.*~>")
(test-syn-err (define-language bad-lang1 (e name)) #rx"name")
(test-syn-err (define-language bad-lang2 (name x)) #rx"name")
(test-syn-err (define-language bad-lang3 (x_y x)) #rx"x_y")
(test-syn-err (define-language bad-lang4 (a 1 2) (b)) #rx"no productions")
(test-syn-err (let ()
(define-language good-lang (a 1 2))
(define-extended-language bad-lang5 good-lang (a) (b 2)))
#rx"no productions")
;; expect union with duplicate names to fail
(test (with-handlers ((exn? (λ (x) 'passed)))
(union-reduction-relations
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult)))
'failed)
'passed)
(test (with-handlers ((exn? (λ (x) 'passed)))
(union-reduction-relations
(union-reduction-relations
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult3)))
(union-reduction-relations
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult2))))
'passed)
'passed)
;; sorting in this test case is so that the results come out in a predictable manner.
(test (sort
(apply-reduction-relation
(compatible-closure
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
grammar
M)
'((2 3) (4 5)))
(λ (x y) (string<=? (format "~s" x) (format "~s" y))))
(list '((2 3) 20)
'(6 (4 5))))
(test (apply-reduction-relation
(compatible-closure
(reduction-relation
grammar
(--> (number_1 number_2)
,(* (term number_1) (term number_2))
mult))
grammar
M)
'(4 2))
(list '8))
(test (apply-reduction-relation
(context-closure
(context-closure
(reduction-relation grammar (--> 1 2))
grammar
(y hole))
grammar
(x hole))
'(x (y 1)))
(list '(x (y 2))))
(test (apply-reduction-relation
(reduction-relation
grammar
(--> (variable_1 variable_2)
(variable_1 variable_2 x)
mul
(fresh x)))
'(x x1))
(list '(x x1 x2)))
(test (apply-reduction-relation
(reduction-relation
grammar
(~~> number
x
(fresh x))
with
[(--> (variable_1 variable_2 a) (variable_1 variable_2 b)) (~~> a b)])
'(x x1 2))
(list '(x x1 x2)))
(test (apply-reduction-relation
(reduction-relation
x-language
(--> (x_1 ...)
(x ...)
(fresh ((x ...) (x_1 ...)))))
'(x y x1))
(list '(x2 x3 x4)))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> (variable_1 ...)
(x ... variable_1 ...)
(fresh ((x ...) (variable_1 ...) (variable_1 ...)))))
'(x y z))
(list '(x1 y1 z1 x y z)))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> any (any_y x)
(where any_y x)
(fresh x)))
(term junk))
(list '(x x1)))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> (variable ...) (variable_0 ... variable_1 ...)
(fresh ((variable_0 ...) (variable ...)))
(fresh ((variable_1 ...) (variable ...)))))
(term (x y)))
(list '(variable_0 variable_1 variable_2 variable_3)))
;; test that redex match can be used in a side-condition
;; with the same language that is used to define the
;; reduction relation.
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> any_1 3
(side-condition (redex-match empty-language (any_1 any_2) (term any_1)))))
'(a b))
'(3))
(test (apply-reduction-relation
(reduction-relation
empty-language
(--> variable_1
(x variable_1)
(fresh (x variable_1))))
'q)
(list '(q1 q)))
(test (apply-reduction-relation
(extend-reduction-relation (reduction-relation empty-language (--> 1 2))
empty-language
(--> 1 3))
1)
'(3 2))
(let ()
(define-language e1
(e 1))
(define-language e2
(e 2))
(define red1 (reduction-relation e1 (--> e (e e))))
(define red2 (extend-reduction-relation red1 e2 (--> ignoreme ignoreme)))
(test (apply-reduction-relation red1 1) '((1 1)))
(test (apply-reduction-relation red1 2) '())
(test (apply-reduction-relation red2 1) '())
(test (apply-reduction-relation red2 2) '((2 2))))
(let ()
(define red1 (reduction-relation empty-language
(--> a (a a)
a)
(--> b (b b)
b)
(--> q x)))
(define red2 (extend-reduction-relation red1
empty-language
(--> a (c c)
a)
(--> q z)))
(test (apply-reduction-relation red1 (term a)) (list (term (a a))))
(test (apply-reduction-relation red1 (term b)) (list (term (b b))))
(test (apply-reduction-relation red1 (term q)) (list (term x)))
(test (apply-reduction-relation red2 (term a)) (list (term (c c))))
(test (apply-reduction-relation red2 (term b)) (list (term (b b))))
(test (apply-reduction-relation red2 (term q)) (list (term z) (term x))))
(let ()
(define red1
(reduction-relation
empty-language
(==> a (a a)
a)
(==> b (b b)
b)
(==> q w)
with
[(--> (X a) (X b)) (==> a b)]))
(define red2
(extend-reduction-relation
red1
empty-language
(==> a (c c)
a)
(==> q z)
with
[(--> (X a) (X b)) (==> a b)]))
(test (apply-reduction-relation red1 (term (X a))) (list (term (X (a a)))))
(test (apply-reduction-relation red1 (term (X b))) (list (term (X (b b)))))
(test (apply-reduction-relation red1 (term (X q))) (list (term (X w))))
(test (apply-reduction-relation red2 (term (X a))) (list (term (X (c c)))))
(test (apply-reduction-relation red2 (term (X b))) (list (term (X (b b)))))
(test (apply-reduction-relation red2 (term (X q))) (list (term (X z))
(term (X w)))))
(test (reduction-relation->rule-names
(reduction-relation
empty-language
(--> x y a)))
'(a))
(test (reduction-relation->rule-names
(reduction-relation
empty-language
(--> x y a)
(--> y z b)
(--> z w c)))
'(a b c))
(test (reduction-relation->rule-names
(reduction-relation
empty-language
(--> x y a)
(--> y z b)
(--> z w c)
(--> p q z)
(--> q r y)
(--> r p x)))
'(a b c z y x))
(test (reduction-relation->rule-names
(extend-reduction-relation
(reduction-relation
empty-language
(--> x y a)
(--> y z b)
(--> z w c))
empty-language
(--> p q z)
(--> q r y)
(--> r p x)))
'(a b c z y x))
(test (reduction-relation->rule-names
(union-reduction-relations
(reduction-relation
empty-language
(--> x y a)
(--> y z b)
(--> z w c))
(reduction-relation
empty-language
(--> p q z)
(--> q r y)
(--> r p x))))
'(a b c z y x))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; examples from doc.txt
;;
(define-language lc-lang
(e (e e ...)
x
v)
(c (v ... c e ...)
hole)
(v (lambda (x ...) e))
(x variable-not-otherwise-mentioned))
(test (let ([m (redex-match lc-lang e (term (lambda (x) x)))])
(and m (length m)))
1)
(define-extended-language qabc-lang lc-lang (q a b c))
(test (redex-match qabc-lang
e
(term (lambda (a) a)))
#f)
(test (let ([m (redex-match qabc-lang
e
(term (lambda (z) z)))])
(and m (length m)))
1)
(require (lib "list.ss"))
(let ()
(define-metafunction lc-lang
free-vars : e -> (x ...)
[(free-vars (e_1 e_2 ...))
( (free-vars e_1) (free-vars e_2) ...)]
[(free-vars x) (x)]
[(free-vars (lambda (x ...) e))
(- (free-vars e) (x ...))])
(define-metafunction lc-lang
: (x ...) ... -> (x ...)
[( (x_1 ...) (x_2 ...) (x_3 ...) ...)
( (x_1 ... x_2 ...) (x_3 ...) ...)]
[( (x_1 ...))
(x_1 ...)]
[() ()])
(define-metafunction lc-lang
- : (x ...) (x ...) -> (x ...)
[(- (x ...) ()) (x ...)]
[(- (x_1 ... x_2 x_3 ...) (x_2 x_4 ...))
(- (x_1 ... x_3 ...) (x_2 x_4 ...))
(side-condition (not (memq (term x_2) (term (x_3 ...)))))]
[(- (x_1 ...) (x_2 x_3 ...))
(- (x_1 ...) (x_3 ...))])
(test (term ()) (term ()))
(test (term ( (x y) (z a) (b c))) (term (x y z a b c)))
(test (term (- (x y) ())) (term (x y)))
(test (term (- (x y) (x))) (term (y)))
(test (term (- (y x) (x))) (term (y)))
(test (term (- (x x x x x) (x))) (term ()))
(test (term (free-vars (lambda (x) (x y)))) (list 'y))
(test (term (free-vars (a (b (c (d e)))))) (term (a b c d e))))
(test (variable-not-in (term (x y z)) 'x)
(term x1))
(test (variable-not-in (term (y z)) 'x)
(term x))
(test (variable-not-in (term (x x1 x2 x3 x4 x5 x6 x7 x8 x9 x10)) 'x)
(term x11))
(test (variable-not-in (term (x x11)) 'x)
(term x1))
(test (variable-not-in (term (x x1 x2 x3)) 'x1)
(term x4))
(test (variable-not-in (term (x x1 x1 x2 x2)) 'x)
(term x3))
(test (variables-not-in (term (x y z)) '(x))
'(x1))
(test (variables-not-in (term (x2 y z)) '(x x x))
'(x x1 x3))
(test ((term-match/single empty-language
[(variable_x variable_y)
(cons (term variable_x)
(term variable_y))])
'(x y))
'(x . y))
(test ((term-match/single empty-language
[(side-condition (variable_x variable_y)
(eq? (term variable_x) 'x))
(cons (term variable_x)
(term variable_y))])
'(x y))
'(x . y))
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
((term-match/single empty-language
[(number_1 ... number_2 ...) 1])
'(1 2 3))
'no-exn)
'right-exn)
(test (with-handlers ((exn:fail:redex? (λ (x) 'right-exn))
((λ (x) #t) (λ (x) 'wrong-exn)))
((term-match/single empty-language
[(number_1 ... number_2 ...) 1])
'x)
'no-exn)
'right-exn)
(test ((term-match empty-language
[(number_1 ... number_2 ...) 1])
'x)
'())
(define-language x-is-1-language
[x 1])
(test ((term-match/single x-is-1-language
[(x x)
1])
'(1 1))
1)
(test (call-with-values
(λ ()
((term-match/single empty-language
[() (values 1 2)])
'()))
list)
'(1 2))
(test (let ([x 0])
(cons ((term-match empty-language
[(any_a ... number_1 any_b ...)
(begin (set! x (+ x 1))
(term number_1))])
'(1 2 3))
x))
'((3 2 1) . 3))
(test ((term-match empty-language
[number_1
(term number_1)]
[number_1
(term number_1)])
'1)
'(1 1))
(test (apply-reduction-relation
(reduction-relation
x-language
(--> (x_one x_!_one x_!_one x_!_one)
(x_one x_!_one)))
(term (a a b c)))
(list (term (a x_!_one))))
;; tests `where' clauses in reduction relation
(test (apply-reduction-relation
(reduction-relation empty-language
(--> number_1
any_y
(where any_y ,(+ 1 (term number_1)))))
3)
'(4))
;; tests `where' clauses scoping
(test (let ([x 5])
(apply-reduction-relation
(reduction-relation empty-language
(--> any
any_z
(where any_y ,x)
(where any_x 2)
(where any_z ,(+ (term any_y) (term any_x)))))
'whatever))
'(7))
;; tests `where' clauses bind in side-conditions
(test (let ([x 'unk])
(apply-reduction-relation
(reduction-relation empty-language
(--> any
the-result
(where any_y any)
(side-condition (eq? (term any_y) 'whatever))))
'whatever))
'(the-result))
;; test that where clauses bind in side-conditions that follow
(let ([save1 #f]
[save2 #f])
(term-let ([any_y (term outer-y)])
(test (begin (apply-reduction-relation
(reduction-relation empty-language
(--> number_1
any_y
(side-condition (set! save1 (term any_y)))
(where any_y inner-y)
(side-condition (set! save2 (term any_y)))))
3)
(list save1 save2))
(list 'outer-y 'inner-y))))
(test (apply-reduction-relation
(reduction-relation empty-language
(--> any
any_y
(fresh x)
(where any_y x)))
'x)
'(x1))
(let ()
;; tests where's ability to have redex patterns, not just syntax-case patterns
(define-language var-lang [(x y z w) variable])
(define red
(reduction-relation
var-lang
(--> (x ...)
(y ... z ...)
(where (y ... w z ...) (x ...)))))
(test (apply-reduction-relation red (term (a b c)))
(list (term (a b)) (term (a c)) (term (b c)))))
(let ([r (reduction-relation
grammar
(->1 1 2)
(->2 3 4)
(->4 5 6)
with
[(--> (side-condition (a number) (even? (term number))) b)
(->1 a b)]
[(--> (X
(number number)
(X_1 X_1)
(M_!_1 M_!_1)
(1 ..._1 1 ..._1)
(1 ..._!_1 1 ..._!_1))
b)
(->2 X b)]
[(--> (a 1) b)
(->3 a b)]
[(->3 (a 2) b)
(->4 a b)])])
; test that names are properly bound for side-conditions in shortcuts
(let* ([lhs ((rewrite-proc-lhs (first (reduction-relation-make-procs r))) grammar)]
[proc (third lhs)]
[name (cadadr lhs)]
[bind (λ (n) (make-bindings (list (make-bind name n))))])
(test (and (proc (bind 4)) (not (proc (bind 3)))) #t))
; test binder renaming
(let ([sym-mtch? (λ (rx) (λ (s) (and (symbol? s) (regexp-match? rx (symbol->string s)))))])
(match (rewrite-proc-lhs (second (reduction-relation-make-procs r)))
[`(3
(,(and n1 (? (sym-mtch? #px"^number_\\d+$"))) ,n1)
(,(and n2 (? (sym-mtch? #px"^X_1\\d+$"))) ,n2)
(,(and m1 (? (sym-mtch? #px"^M_!_1\\d+$"))) ,m1)
(1 ,(and ...1 (? (sym-mtch? #px"^\\.\\.\\._1\\d+$"))) 1 ,...1)
(1 ,(and ...!1 (? (sym-mtch? #px"^\\.\\.\\._!_1\\d+$"))) 1 ,...!1))
#t]
[else #f]))
; test shortcut in terms of shortcut
(test (match ((rewrite-proc-lhs (third (reduction-relation-make-procs r))) grammar)
[`(((side-condition 5 ,(? procedure?) ,_) 2) 1) #t]
[else #f])
#t))
(let ([< (λ (c d) (string<? (car c) (car d)))])
(let* ([R (reduction-relation
empty-language
(--> number (q ,(add1 (term number)))
(side-condition (odd? (term number)))
side-condition)
(--> 1 4 plain)
(==> 2 t
shortcut)
with
[(--> (q a) b)
(==> a b)])]
[c (make-coverage R)])
(parameterize ([relation-coverage (list c)])
(apply-reduction-relation R 4)
(test (sort (covered-cases c) <)
'(("plain" . 0) ("shortcut" . 0) ("side-condition" . 0)))
(apply-reduction-relation R 3)
(test (sort (covered-cases c) <)
'(("plain" . 0) ("shortcut" . 0) ("side-condition" . 1)))
(apply-reduction-relation* R 1)
(test (sort (covered-cases c) <)
'(("plain" . 1) ("shortcut" . 1) ("side-condition" . 2)))))
(let* ([S (reduction-relation
empty-language
(--> 1 1 uno))]
[S+ (extend-reduction-relation
S empty-language
(--> 2 2 dos))])
(let ([c (make-coverage S+)])
(parameterize ([relation-coverage (list c)])
(apply-reduction-relation S (term 1))
(test (sort (covered-cases c) <)
'(("dos" . 0) ("uno" . 1)))))
(let ([c (make-coverage S)])
(parameterize ([relation-coverage (list c)])
(apply-reduction-relation S+ (term 1))
(test (sort (covered-cases c) <)
'(("uno" . 1))))))
(let* ([T (reduction-relation empty-language (--> any any))]
[c (make-coverage T)])
(parameterize ([relation-coverage (list c)])
(apply-reduction-relation T (term q))
(test (and (regexp-match #px"tl-test.ss:\\d+:\\d+" (caar (covered-cases c))) #t)
#t))))
(let* ([R (reduction-relation
empty-language
(--> any any id))]
[c (make-coverage R)]
[c* (make-coverage R)])
(parameterize ([relation-coverage (list c c*)])
(apply-reduction-relation R 4)
(test (covered-cases c) '(("id" . 1)))
(test (covered-cases c*) '(("id" . 1)))))
(let* ([< (λ (c d)
(let ([line-no (compose
string->number
second
(curry regexp-match #px".*:(\\d+):\\d+"))])
(< (line-no (car c)) (line-no (car d)))))]
[src-ok? (curry regexp-match? #px"tl-test.ss:\\d+:\\d+")]
[sorted-counts (λ (cc) (map cdr (sort (covered-cases cc) <)))])
(define-metafunction empty-language
[(f 1) 1]
[(f 2) 2])
(define-metafunction/extension f empty-language
[(g 3) 3])
(define-relation empty-language
[(R number)
,(even? (term number))]
[(R number)
,(= 3 (term number))])
(let ([fc (make-coverage f)]
[rc (make-coverage (reduction-relation empty-language (--> any any)))])
(parameterize ([relation-coverage (list rc fc)])
(term (f 2))
(test (andmap (compose src-ok? car) (covered-cases fc))
#t)
(test (sorted-counts fc) '(0 1))
(term (f 1))
(term (f 1))
(test (sorted-counts fc) '(2 1))))
(let ([c (make-coverage f)])
(parameterize ([relation-coverage (list c)])
(term (g 1))
(test (sorted-counts c) '(1 0))))
(let ([c (make-coverage g)])
(parameterize ([relation-coverage (list c)])
(term (f 1))
(test (sorted-counts c) '(1 0 0))))
(let ([c (make-coverage R)])
(parameterize ([relation-coverage (list c)])
(term (R 2))
(term (R 3))
(term (R 5))
(test (sorted-counts c) '(1 1))))
(let ([c (make-coverage f)]
[c* (make-coverage f)])
(parameterize ([relation-coverage (list c* c)])
(term (f 1))
(test (sorted-counts c) '(1 0))
(test (sorted-counts c*) '(1 0)))))
;
;
;
;
; ;;;
; ;; ;; ; ;; ;;
; ;; ;; ; ;; ;;
; ;;;;; ;;; ;;; ;;;;; ;; ;;; ;;;; ;;;;
; ;; ;; ;; ;; ; ;; ;;;;;;;; ;; ;;; ;; ; ;; ;;
; ;; ;;;;; ;;; ;; ;;; ;; ; ;; ;; ;; ;;
; ;; ;; ;; ;; ;;; ;; ;;;; ;; ;; ;;
; ;; ;; ; ; ;; ;; ;; ;; ;; ;; ; ;; ;;
; ;;;; ;;; ;;; ;;;; ; ;;;;; ;; ;;;; ;;;;
;
;
;
(define-syntax-rule
(capture-output arg1 args ...)
(let ([p (open-output-string)])
(parameterize ([current-output-port p]
[current-error-port p])
arg1 args ...)
(get-output-string p)))
(let ()
(define red (reduction-relation empty-language (--> 1 2)))
(test (capture-output (test-->> red 1 2) (test-results))
"One test passed.\n")
(test (capture-output (test-->> red 2 3) (test-results))
#rx"FAILED tl-test.ss:[0-9.]+\nexpected: 3\n actual: 2\n1 test failed \\(out of 1 total\\).\n"))
(let ()
(define red-share (reduction-relation
empty-language
(--> a b)
(--> a c)
(--> c d)
(--> b d)))
(test (capture-output (test-->> red-share (term a) (term d)) (test-results))
"One test passed.\n"))
(let ()
(define red-cycle (reduction-relation
empty-language
(--> a a)))
(test (capture-output (test-->> red-cycle #:cycles-ok (term a)) (test-results))
"One test passed.\n")
(test (capture-output (test-->> red-cycle (term a)) (test-results))
#rx"FAILED tl-test.ss:[0-9.]+\nfound a cycle in the reduction graph\n1 test failed \\(out of 1 total\\).\n"))
(let ()
(define-metafunction empty-language [(f any) ((any))])
(test (capture-output (test-equal (term (f 1)) (term ((1))))
(test-results))
"One test passed.\n"))
(let ()
(test (capture-output (test-predicate odd? 1)
(test-results))
"One test passed.\n"))
(let ()
(define red (reduction-relation empty-language (--> any (any))))
(test (capture-output (test--> red (term (1 2 3)) (term ((1 2 3)))) (test-results))
"One test passed.\n"))
(let ()
(define red (reduction-relation empty-language
(--> any (any))
(--> (any) any)))
(test (capture-output (test--> red (term (x)) (term ((x))) (term x)) (test-results))
"One test passed.\n")
(test (capture-output (test--> red (term (x)) (term x) (term ((x)))) (test-results))
"One test passed.\n"))
(print-tests-passed 'tl-test.ss))