72 lines
2.8 KiB
Racket
72 lines
2.8 KiB
Racket
#lang racket
|
|
|
|
(require "unify.rkt")
|
|
|
|
(require rackunit)
|
|
|
|
(define (uc->v x)
|
|
(define-values (x1 env) (upper-case-symbols->variables x))
|
|
x1)
|
|
|
|
(define-syntax-rule (check-match expected pat)
|
|
(check-pred (lambda (v) (match v [pat #t] [_ #f])) expected))
|
|
|
|
(check-equal? (list->set (set-map (variables-in (uc->v '(a b c))) variable-info)) (set))
|
|
(check-equal? (list->set (set-map (variables-in (uc->v '(a B B))) variable-info)) (set 'B))
|
|
(check-equal? (list->set (set-map (variables-in (uc->v '(a B C))) variable-info)) (set 'B 'C))
|
|
|
|
(check-equal? (unify/vars '(a B c) '(a b c)) '((B . b)))
|
|
(check-equal? (unify/vars '(a B B) '(a b c)) #f)
|
|
(check-equal? (unify/vars '(a B B) '(a b B)) '((B . b)))
|
|
|
|
(check-match (unify/vars '(a b C) '(a b C)) `((C . ,(variable 'C))))
|
|
|
|
(check-equal? (unify/vars '#(A 2 3) '#(1 2 B)) '((B . 3) (A . 1)))
|
|
|
|
(check-equal? (unify-match/vars '#(A 2 3) '#(1 2 B)) '((A . 1)))
|
|
(check-equal? (unify-match/vars '#(1 2 B) '#(A 2 3)) '((B . 3)))
|
|
|
|
(check-equal? (unify-match/vars '(a B B) '(a b C)) '((B . b)))
|
|
(check-equal? (unify-match/vars '(a b C) '(a B B)) '((C . b)))
|
|
|
|
(check-equal? (unify-match/vars '(a C C) '(a b c)) #f)
|
|
(check-equal? (unify-match/vars '(a b c) '(a C C)) #f)
|
|
(check-match (unify-match/vars '(a b C) '(a D B)) `((C . ,(variable 'B))))
|
|
(check-match (unify-match/vars '(a C C) '(a D B)) `((C . ,(variable 'D))))
|
|
|
|
(check-equal? (mgu-canonical (uc->v '(a b C)) (uc->v '(a D B))) `(a b ,(canonical-variable 0)))
|
|
(check-equal? (canonicalize (uc->v `(A (B A) D)))
|
|
(canonicalize (uc->v `(E (F E) H))))
|
|
|
|
(check-equal? (upper-case-symbols->canonical '(A (B A) D))
|
|
(list (canonical-variable 0)
|
|
(list (canonical-variable 1) (canonical-variable 0))
|
|
(canonical-variable 2)))
|
|
|
|
(let* ((left (uc->v `(A (b A) D)))
|
|
(right (freshen left)))
|
|
(check-true (not (eq? (car left) (car right))))
|
|
(check-eq? (variable-info (car left)) (variable-info (car right)))
|
|
(check-equal? (canonicalize left) (list (canonical-variable 0)
|
|
(list 'b (canonical-variable 0))
|
|
(canonical-variable 1)))
|
|
(check-equal? (canonicalize left) (canonicalize right)))
|
|
|
|
(struct x (y) #:transparent)
|
|
(let ((A (variable 'A)))
|
|
(check-equal? (unify (x A) (x 123)) `((,A . 123))))
|
|
|
|
(struct x1 (y z) #:prefab)
|
|
(check-equal? (unify/vars (x1 'A 'a) (x1 'b 'a)) '((A . b)))
|
|
(let ((A (variable 'A)))
|
|
(check-equal? (apply-subst `((,A . b)) (x1 A 'a)) (x1 'b 'a)))
|
|
|
|
(check-true (specialization? (upper-case-symbols->canonical '(a A))
|
|
(upper-case-symbols->canonical '(B C))))
|
|
(check-false (specialization? (upper-case-symbols->canonical '(B C))
|
|
(upper-case-symbols->canonical '(a A))))
|
|
(check-true (specialization? (upper-case-symbols->canonical '(a A))
|
|
(upper-case-symbols->canonical '(a A))))
|
|
(check-false (specialization? (upper-case-symbols->canonical '(a A))
|
|
(upper-case-symbols->canonical '(A a))))
|