
also, fix a bug where continuations in thunks returned by redex-generator weren't being shuffled
570 lines
15 KiB
Racket
570 lines
15 KiB
Racket
#lang racket
|
|
|
|
(require "../reduction-semantics.rkt"
|
|
"../private/jdg-gen.rkt"
|
|
"../private/generate-term.rkt"
|
|
"test-util.rkt"
|
|
(only-in "../private/pat-unify.rkt"
|
|
bound
|
|
lvar))
|
|
|
|
(let ()
|
|
(define-language L0)
|
|
|
|
(test-equal (check-dq `a `a (make-hash) L0 (hash))
|
|
#f)
|
|
(test-equal (check-dq `a `b (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list a) `(list a) (make-hash) L0 (hash))
|
|
#f)
|
|
(test-equal (check-dq `(list a) `(list b) (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list number) `(list variable) (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list a) `(list number) (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list 2) `(list variable-not-otherwise-mentioned) (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list a b) `(list a number) (make-hash) L0 (hash))
|
|
#t)
|
|
(test-equal (check-dq `(list a b) `(list a b) (make-hash) L0 (hash))
|
|
#f)
|
|
(test-equal (check-dq `(list (name a ,(bound)))
|
|
`(list (name a ,(bound)))
|
|
(make-hash)
|
|
L0
|
|
(hash (lvar 'a) 'number))
|
|
#f)
|
|
(test-equal (check-dq `(name a ,(bound))
|
|
`(name b ,(bound))
|
|
(make-hash (list (cons (lvar 'a) '(1 2 3))
|
|
(cons (lvar 'b) '(1 2 3))))
|
|
L0
|
|
(hash (lvar 'a) 'any (lvar 'b) 'any))
|
|
#f)
|
|
)
|
|
|
|
(let ()
|
|
|
|
(define-language nats
|
|
(n z (s n)))
|
|
|
|
(define-judgment-form nats
|
|
#:mode (sum I I O)
|
|
#:contract (sum n n n)
|
|
[(sum z n n)]
|
|
[(sum (s n_1) n_2 (s n_3))
|
|
(sum n_1 n_2 n_3)])
|
|
|
|
(define-relation nats
|
|
[(r-sum z n n)]
|
|
[(r-sum (s n_1) n_2 (s n_3))
|
|
(r-sum n_1 n_2 n_3)])
|
|
|
|
(test-equal (judgment-holds (sum z (s z) (s z)))
|
|
#t)
|
|
|
|
(test-equal (judgment-holds (sum (s z) (s z) (s (s z))))
|
|
#t)
|
|
|
|
(test-equal (generate-term nats #:satisfying (sum z (s z) n) +inf.0)
|
|
'(sum z (s z) (s z)))
|
|
|
|
(test-equal (generate-term nats #:satisfying (sum (s z) (s z) n) +inf.0)
|
|
'(sum (s z) (s z) (s (s z))))
|
|
|
|
(test-equal (generate-term nats #:satisfying (sum z z (s z)) 5)
|
|
#f)
|
|
|
|
(for ([_ 100])
|
|
(match (generate-term nats #:satisfying (sum n_1 n_2 n_3) 5)
|
|
[`(sum ,l ,r ,res)
|
|
(test-equal (judgment-holds (sum ,l ,r n) n)
|
|
`(,res))])
|
|
(match (generate-term nats #:satisfying (r-sum n_1 n_2 n_3) 5)
|
|
[`(r-sum ,l ,r ,res)
|
|
(test-equal (term (r-sum ,l ,r ,res))
|
|
#t)])))
|
|
|
|
(let ()
|
|
|
|
(define-language lists
|
|
(l (x l)
|
|
())
|
|
(x variable-not-otherwise-mentioned))
|
|
|
|
(define-judgment-form lists
|
|
#:mode (not-in I I)
|
|
[(not-in x_0 ())]
|
|
[(not-in x_0 (x_1 l_0))
|
|
(different x_0 x_1) ;; this line has to go first or this won't terminate
|
|
(not-in x_0 l_0)])
|
|
|
|
(define-judgment-form lists
|
|
#:mode (different I I)
|
|
[(different x_!_1 x_!_1)])
|
|
|
|
(test
|
|
(judgment-holds (not-in a (b (c (d (e (f ())))))))
|
|
#t)
|
|
|
|
(test
|
|
(judgment-holds (not-in a (b (c (d (a (f ())))))))
|
|
#f)
|
|
|
|
(test
|
|
(generate-term lists #:satisfying (not-in a (b (a (c l)))) 5)
|
|
#f)
|
|
|
|
(test
|
|
(not (generate-term lists #:satisfying (not-in a (b (c (d (e (f ())))))) +inf.0))
|
|
#f)
|
|
|
|
(for/and ([_ 100])
|
|
(match (generate-term lists #:satisfying (not-in a l) 5)
|
|
[`(not-in a ,l)
|
|
(unless (judgment-holds (not-in a ,l)) (printf "l: ~s\n" l))
|
|
(test-equal (judgment-holds (not-in a ,l))
|
|
#t)]
|
|
[#f
|
|
(void)])))
|
|
|
|
(let ()
|
|
|
|
(define-language TL
|
|
(T (N T T)
|
|
(L number)))
|
|
|
|
(define-relation TL
|
|
[(tree (N T_1 T_2))
|
|
(tree T_1)
|
|
(tree T_2)]
|
|
[(tree (L number))])
|
|
|
|
(test-equal
|
|
(not
|
|
(empty?
|
|
(filter
|
|
values
|
|
(for/list ([_ 100])
|
|
(generate-term TL #:satisfying (tree T) 2)))))
|
|
#t)
|
|
)
|
|
|
|
(let ()
|
|
(define-language STLC
|
|
(τ int
|
|
(τ → τ))
|
|
(Γ ([x τ] Γ)
|
|
•)
|
|
(x variable-not-otherwise-mentioned))
|
|
|
|
(define-metafunction STLC
|
|
[(lookup x ([x τ] Γ))
|
|
τ]
|
|
[(lookup x ([x_1 τ] Γ))
|
|
(lookup x Γ)])
|
|
|
|
(test-equal (generate-term STLC
|
|
#:satisfying
|
|
(lookup x ([x int] ([x (int → int)] •))) = (int → int)
|
|
6)
|
|
#f))
|
|
|
|
(let ()
|
|
|
|
(define-language simple
|
|
(e (+ e e)
|
|
(+ e e e)
|
|
number))
|
|
|
|
(define-judgment-form simple
|
|
#:mode (double I I)
|
|
[(double (+ e_1 e_2) e_3)
|
|
(where e_3 (+ (+ e_1 e_1) (+ e_2 e_2)))])
|
|
|
|
(for ([_ 100])
|
|
(define t (generate-term simple #:satisfying (double e_1 e_2) +inf.0))
|
|
(match t
|
|
[`(double ,e1 ,e2)
|
|
(test-equal (judgment-holds (double ,e1 ,e2))
|
|
#t)]
|
|
[#f
|
|
(void)]))
|
|
|
|
(define-metafunction simple
|
|
[(duplicate e_1 e_1)
|
|
(+ e_1 e_1 e_1)]
|
|
[(duplicate e_1 e_2)
|
|
(+ e_3 e_4)
|
|
(where e_31 e_1)
|
|
(where e_3 (+ e_31 e_31))
|
|
(where e_42 e_2)
|
|
(where e_4 (+ e_42 e_42))]
|
|
[(duplicate e_1)
|
|
(duplicate e_1 e_1)])
|
|
|
|
(define-judgment-form simple
|
|
#:mode (double2 I I)
|
|
[(double2 (+ e_1 e_2) e_3)
|
|
(where e_3 (duplicate e_1 e_2))]
|
|
[(double2 e_1 e_2)
|
|
(where e_2 (duplicate e_1))])
|
|
|
|
(test-equal (term (duplicate 1 2))
|
|
'(+ (+ 1 1) (+ 2 2)))
|
|
|
|
(test-equal (term (duplicate 1))
|
|
'(+ 1 1 1))
|
|
|
|
(test-equal (term (duplicate 2 2))
|
|
'(+ 2 2 2))
|
|
|
|
(test-equal (judgment-holds (double2 (+ 1 2) (+ (+ 1 1) (+ 2 2))))
|
|
#t)
|
|
|
|
(test-equal (judgment-holds (double2 1 (+ 1 1 1)))
|
|
#t)
|
|
|
|
(test-equal (judgment-holds (double2 (+ 2 2) (+ 2 2 2)))
|
|
#t)
|
|
|
|
(for ([_ 100])
|
|
(define t (generate-term simple #:satisfying (double2 e_1 e_2) +inf.0))
|
|
(match t
|
|
[`(double2 ,e1 ,e2)
|
|
(test-equal (judgment-holds (double2 ,e1 ,e2))
|
|
#t)]
|
|
[#f
|
|
(void)])))
|
|
|
|
(let ()
|
|
(define-language STLC
|
|
(e (λ (x τ) e)
|
|
(e e)
|
|
x
|
|
i
|
|
add1)
|
|
(τ int
|
|
(τ → τ))
|
|
(Γ ([x τ] Γ)
|
|
•)
|
|
(i integer)
|
|
(x variable-not-otherwise-mentioned))
|
|
|
|
(define-judgment-form STLC
|
|
#:mode (typeof I I O)
|
|
#:contract (typeof Γ e τ)
|
|
[(typeof Γ i int)]
|
|
[(typeof Γ x (lookup x Γ))]
|
|
[(typeof Γ add1 (int → int))]
|
|
[(typeof Γ (λ (x τ_1) e) (τ_1 → τ_2))
|
|
(typeof ([x τ_1] Γ) e τ_2)]
|
|
[(typeof Γ (e_1 e_2) τ)
|
|
(typeof Γ e_1 (τ_2 → τ))
|
|
(typeof Γ e_2 τ_2)])
|
|
|
|
(define-metafunction STLC
|
|
[(lookup x ([x τ] Γ))
|
|
τ]
|
|
[(lookup x ([x_1 τ] Γ))
|
|
(lookup x Γ)])
|
|
|
|
(define-extended-language if-l STLC
|
|
(e (if0 e e e)
|
|
....))
|
|
|
|
(define-extended-judgment-form if-l typeof
|
|
#:mode (typ-if I I O)
|
|
[(typ-if Γ (if0 e_1 e_2 e_3) τ)
|
|
(typ-if Γ e_1 int)
|
|
(typ-if Γ e_2 τ)
|
|
(typ-if Γ e_3 τ)])
|
|
|
|
(test-equal (judgment-holds (typeof ([x_1 int] ([x_1 (int → int)] •)) (x_1 5) int))
|
|
#f)
|
|
(test-equal (judgment-holds (typeof ([x_2 int] ([x_1 (int → int)] •)) (x_1 5) int))
|
|
#t)
|
|
|
|
(for ([_ 100])
|
|
(define term (generate-term STLC #:satisfying (typeof Γ e τ) 6))
|
|
(match term
|
|
[`(typeof ,g ,e ,t)
|
|
(define tp (judgment-holds (typeof ,g ,e τ) τ))
|
|
(test-equal tp `(,t))]
|
|
[#f
|
|
(void)]))
|
|
|
|
(for ([_ 100])
|
|
(define term (generate-term if-l #:satisfying (typ-if Γ e τ) 5))
|
|
(match term
|
|
[`(typ-if ,g ,e ,t)
|
|
(define tp (judgment-holds (typ-if ,g ,e τ) τ))
|
|
(test-equal tp `(,t))]
|
|
[#f
|
|
(void)]))
|
|
|
|
(define g (redex-generator STLC (typeof • e τ) 5))
|
|
(define terms (filter values (for/list ([_ 400]) (g))))
|
|
(test-equal (length terms)
|
|
(length (remove-duplicates terms)))
|
|
(map (match-lambda
|
|
[`(typeof ,g ,e ,t)
|
|
(define tp (judgment-holds (typeof ,g ,e τ) τ))
|
|
(test-equal tp `(,t))])
|
|
terms)
|
|
(void)
|
|
)
|
|
|
|
(let ()
|
|
(define-language l
|
|
(e (n e)
|
|
•)
|
|
(n number))
|
|
|
|
(define-metafunction l
|
|
fltr : n e -> e
|
|
[(fltr n •)
|
|
•]
|
|
[(fltr n (n e))
|
|
(fltr n e)]
|
|
[(fltr n (n_0 e))
|
|
(n_0 (fltr n e))])
|
|
|
|
(define-judgment-form l
|
|
#:mode (filtered I I O)
|
|
[(filtered e n (fltr n e))])
|
|
|
|
(test-equal (generate-term l #:satisfying (filtered (1 (2 (3 (4 •)))) 3 (1 (2 (4 •)))) +inf.0)
|
|
'(filtered (1 (2 (3 (4 •)))) 3 (1 (2 (4 •)))))
|
|
(test-equal (generate-term l #:satisfying (filtered (1 (2 (3 (4 •)))) 5 (1 (2 (4 •)))) +inf.0)
|
|
#f)
|
|
|
|
(for ([_ 50])
|
|
(define term (generate-term l #:satisfying (filtered e_1 n e_2) 5))
|
|
(match term
|
|
[`(filtered ,e1 ,n ,e2)
|
|
(define tp (judgment-holds (filtered ,e1 ,n e_2) e_2))
|
|
(test-equal tp `(,e2))]
|
|
[#f
|
|
(void)]))
|
|
|
|
(for ([_ 50])
|
|
(define t (generate-term l #:satisfying (fltr n e) = e_1 5))
|
|
(match t
|
|
[`((fltr ,n ,e) = ,e1)
|
|
(test-equal (term (fltr ,n ,e)) e1)]
|
|
[#f
|
|
(void)]))
|
|
|
|
(define g (redex-generator l (fltr n e_1) = e_2 5))
|
|
(define terms (filter values (for/list ([_ 50]) (g))))
|
|
(test-equal (length terms)
|
|
(length (remove-duplicates terms)))
|
|
(map (match-lambda
|
|
[`((fltr ,n ,e) = ,e1)
|
|
(test-equal (term (fltr ,n ,e)) e1)])
|
|
terms)
|
|
(void))
|
|
|
|
(let ()
|
|
|
|
(define-language L
|
|
(v a
|
|
b
|
|
c
|
|
d
|
|
e
|
|
f)
|
|
(bool T F))
|
|
|
|
(define-metafunction L
|
|
[(is-a? a) T]
|
|
[(is-a? v) F])
|
|
|
|
(define-metafunction/extension is-a? L
|
|
[(is-a/b? b) T])
|
|
|
|
(define-metafunction/extension is-a/b? L
|
|
[(is-a/b/c/d/e? c) T]
|
|
[(is-a/b/c/d/e? d) T]
|
|
[(is-a/b/c/d/e? e) T])
|
|
|
|
|
|
(test-equal (generate-term L #:satisfying (is-a? a) = any +inf.0)
|
|
'((is-a? a) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a? b) = any +inf.0)
|
|
'((is-a? b) = F))
|
|
(test-equal (generate-term L #:satisfying (is-a? c) = any +inf.0)
|
|
'((is-a? c) = F))
|
|
(test-equal (generate-term L #:satisfying (is-a/b? a) = any +inf.0)
|
|
'((is-a/b? a) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b? b) = any +inf.0)
|
|
'((is-a/b? b) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b? c) = any +inf.0)
|
|
'((is-a/b? c) = F))
|
|
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? a) = any +inf.0)
|
|
'((is-a/b/c/d/e? a) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? b) = any +inf.0)
|
|
'((is-a/b/c/d/e? b) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? c) = any +inf.0)
|
|
'((is-a/b/c/d/e? c) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? d) = any +inf.0)
|
|
'((is-a/b/c/d/e? d) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? e) = any +inf.0)
|
|
'((is-a/b/c/d/e? e) = T))
|
|
(test-equal (generate-term L #:satisfying (is-a/b/c/d/e? f) = any +inf.0)
|
|
'((is-a/b/c/d/e? f) = F)))
|
|
|
|
;; errors for unsupprted pats
|
|
(let ()
|
|
(define-language L (n any))
|
|
(define-metafunction L
|
|
[(g (side-condition any #f)) any])
|
|
(define-metafunction L
|
|
[(f n) (g n)])
|
|
(test (with-handlers ((exn:fail? exn-message))
|
|
(generate-term L #:satisfying (f any) = any +inf.0)
|
|
"didn't raise an exception")
|
|
#rx".*generate-term:.*side-condition.*"))
|
|
(let ()
|
|
(define-language L (n any))
|
|
(define-metafunction L
|
|
[(g any_1 ...) (any_1 ...)])
|
|
(define-metafunction L
|
|
[(f n) (g n)])
|
|
(test (with-handlers ((exn:fail? exn-message))
|
|
(generate-term L #:satisfying (f any) = any +inf.0)
|
|
"didn't raise an exception")
|
|
#rx".*generate-term:.*repeat.*"))
|
|
|
|
(let ()
|
|
(define-language L
|
|
(n 1))
|
|
|
|
(define-judgment-form L
|
|
#:mode (jf I)
|
|
[(jf (n_0 n_1 ...))
|
|
(jf n_0)
|
|
(where (n_2 ...) (n_1 ...))
|
|
(jf (n_1 ...))]
|
|
[(jf 1)]
|
|
[(jf 2)]
|
|
[(jf 3)])
|
|
|
|
(test (with-handlers ([exn:fail? exn-message])
|
|
(generate-term L #:satisfying (jf n_1 n_2 n_3) +inf.0))
|
|
#rx".*generate-term:.*repeat.*"))
|
|
|
|
(let ()
|
|
(define-language L
|
|
(q any)
|
|
(r number))
|
|
|
|
(define-metafunction L
|
|
[(f r_1)
|
|
r_2
|
|
(where r_2 ,(+ (term r) (term r)))]
|
|
[(f (q_1 q_2))
|
|
q_3
|
|
(where q_3 (f q_1))
|
|
(where q_3 (f q_2))])
|
|
|
|
(test (with-handlers ([exn:fail? exn-message])
|
|
(generate-term L #:satisfying (f r_1) = r_2 +inf.0))
|
|
#rx".*generate-term:.*undatum.*"))
|
|
|
|
|
|
(let ()
|
|
(define-language L (n 2))
|
|
(define-metafunction L
|
|
[(n any) any])
|
|
(define-metafunction L
|
|
[(f n) (n 1)])
|
|
(test-equal (generate-term L #:satisfying (f any_1) = any_2 +inf.0)
|
|
'((f 2) = (2 1))))
|
|
|
|
(let ()
|
|
(define-language L (n 2))
|
|
(define-metafunction L
|
|
[(n any) any])
|
|
(define-metafunction L
|
|
[(f n) n])
|
|
(test-equal (generate-term L #:satisfying (f any_1) = any_2 +inf.0)
|
|
'((f 2) = 2)))
|
|
|
|
(let ()
|
|
|
|
(define-language l (n number))
|
|
|
|
(define-metafunction l
|
|
[(t n n)
|
|
1]
|
|
[(t n 2)
|
|
2]
|
|
[(t 1 n)
|
|
3]
|
|
[(t n_1 n_2)
|
|
4])
|
|
|
|
(test-equal (generate-term l #:satisfying (t 1 1) = 1 +inf.0)
|
|
'((t 1 1) = 1))
|
|
(test-equal (generate-term l #:satisfying (t 1 1) = 2 +inf.0)
|
|
#f)
|
|
(test-equal (generate-term l #:satisfying (t 1 2) = 2 +inf.0)
|
|
'((t 1 2) = 2))
|
|
(test-equal (generate-term l #:satisfying (t 1 2) = 3 +inf.0)
|
|
#f)
|
|
(test-equal (generate-term l #:satisfying (t 1 3) = 3 +inf.0)
|
|
'((t 1 3) = 3))
|
|
(test-equal (generate-term l #:satisfying (t 1 3) = 4 +inf.0)
|
|
#f)
|
|
(test-equal (generate-term l #:satisfying (t 6 7) = 4 +inf.0)
|
|
'((t 6 7) = 4))
|
|
(test-equal (generate-term l #:satisfying (t 6 7) = 3 +inf.0)
|
|
#f)
|
|
(test-equal (generate-term l #:satisfying (t 6 7) = 2 +inf.0)
|
|
#f)
|
|
(test-equal (generate-term l #:satisfying (t 6 7) = 1 +inf.0)
|
|
#f))
|
|
|
|
|
|
(let ()
|
|
(define-language L
|
|
(e (or e e) b)
|
|
(b T F))
|
|
|
|
(define-relation L
|
|
[(or-eval T)]
|
|
[(or-eval (or T e_2))]
|
|
[(or-eval (or (or e_1 e_2) e_3)) (or-eval (or e_1 (or e_2 e_3)))]
|
|
[(or-eval (or F e)) (or-eval e)])
|
|
|
|
(test-equal (generate-term L #:satisfying (or-eval F) +inf.0)
|
|
#f)
|
|
(test-equal (generate-term L #:satisfying (or-eval T) +inf.0)
|
|
'(or-eval T))
|
|
(test-equal (generate-term L #:satisfying (or-eval (or (or F F) T)) +inf.0)
|
|
'(or-eval (or (or F F) T))))
|
|
|
|
(let ()
|
|
(define-language wrong-nums
|
|
(n z (s z)))
|
|
|
|
(define-relation wrong-nums
|
|
[(sum z n n)]
|
|
[(sum (s n_1) n_2 (s n_3))
|
|
(sum n_1 n_2 n_3)])
|
|
|
|
(for ([n 10])
|
|
(define r (random 100000))
|
|
(random-seed r)
|
|
(define g (redex-generator wrong-nums (sum n_1 n_2 n_3) 1))
|
|
(with-handlers
|
|
([exn? (λ (e)
|
|
(printf "random seed: ~s\n" r)
|
|
(raise e))])
|
|
(for ([n 10])
|
|
(g)))))
|