racket/collects/redex/private/tl-test.ss
2008-08-18 21:23:56 +00:00

1098 lines
35 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 mzscheme
(require "../reduction-semantics.ss"
"test-util.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))
;
;
; ;;; ;
; ; ; ;
; ;;; ; ;;; ;;;;; ;;; ;;;;; ;; ;; ;; ;; ;;;; ;;;;; ;;; ;;; ;; ;; ;;;;
; ; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ;; ; ; ;
; ; ; ; ;;;;; ; ;;;; ; ; ; ; ; ; ; ; ; ; ; ; ;;;
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; ; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ;;;;;;; ;;;; ;;; ;;;;; ;;;;; ;; ;;;;; ;;; ;;; ;;; ;;;;; ;;; ;;; ;;; ;;;;
;
;
;
;
(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 ...)) 4])
(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])
(test (term (g (1 2))) 2)
(test (term (g (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])
(test (term (g 1 2)) 2)
(test (term (g 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)
(x x)
(where x (variable variable))])
(test (term (f z))
(term ((z z) (z z)))))
(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 ...) 1])
(test (term (err)) 1)
(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))
;
;
; ;; ; ;; ;
; ; ; ; ;
; ;; ;; ;;; ;; ; ;; ;; ;;;; ;;;;; ;;; ;;; ;; ;; ;; ;; ;;; ; ;;; ;;;;; ;;; ;;; ;; ;;
; ;; ; ; ; ;; ; ; ; ; ; ; ; ; ;; ; ;; ; ; ; ; ; ; ; ; ; ;; ;
; ; ;;;;; ; ; ; ; ; ; ; ; ; ; ; ;;;;; ; ;;;;; ; ;;;; ; ; ; ; ; ;
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ; ; ; ; ; ;; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
; ;;;;; ;;;; ;;;;; ;; ;; ;;; ;;; ;;;;; ;;; ;;; ;;; ;;;;; ;;;; ;;;;; ;;;;; ;;; ;;;;; ;;; ;;; ;;;
;
;
;
;
(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))))
(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))))
(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")
;; 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
(--> 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)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 (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
y
(where y ,(+ 1 (term number_1)))))
3)
'(4))
;; tests `where' clauses scoping
(test (let ([x 5])
(apply-reduction-relation
(reduction-relation empty-language
(--> any
z
(where y ,x)
(where x 2)
(where z ,(+ (term y) (term x)))))
'whatever))
'(7))
;; test that where clauses bind in side-conditions that follow
(let ([save1 #f]
[save2 #f])
(term-let ([y (term outer-y)])
(test (begin (apply-reduction-relation
(reduction-relation empty-language
(--> number_1
y
(side-condition (set! save1 (term y)))
(where y inner-y)
(side-condition (set! save2 (term y)))))
3)
(list save1 save2))
(list 'outer-y 'inner-y))))
(test (apply-reduction-relation
(reduction-relation empty-language
(--> any
y
(fresh x)
(where y x)))
'x)
'(x1))
(print-tests-passed 'tl-test.ss))