Skip to content

Instantly share code, notes, and snippets.

@cpetzold
Created December 11, 2012 19:21
Show Gist options
  • Save cpetzold/4261224 to your computer and use it in GitHub Desktop.
Save cpetzold/4261224 to your computer and use it in GitHub Desktop.
#lang r5rs
(define-syntax var
(syntax-rules ()
((_ x) (vector x))))
(define-syntax var?
(syntax-rules ()
((_ x) (vector? x))))
(define empty-s '())
(define ext-s-no-check
(lambda (x v s)
(cons `(,x . ,v) s)))
(define lhs car)
(define rhs cdr)
(define walk
(lambda (v s)
(cond
((var? v) (let ((a (assq v s)))
(cond
(a (walk (rhs a) s))
(else v))))
(else v))))
(define occurs?
(lambda (x v s)
(let ((v (walk v s)))
(cond
((var? v) (eq? x v))
((pair? v) (or (occurs? x (car v) s)
(occurs? x (cdr v) s)))
(else #f)))))
(define ext-s
(lambda (x v s)
(cond
((occurs? x v s) #f)
(else (ext-s-no-check x v s)))))
(define unify
(lambda (u v s)
(let ((u (walk u s))
(v (walk v s)))
(cond
((eq? u v) s)
((var? u)
(cond
((var? v) (ext-s-no-check u v s))
(else (ext-s u v s))))
((var? v) (ext-s u v s))
((and (pair? u) (pair? v))
(let ((s (unify (car u) (car v) s)))
(and s (unify (cdr u) (cdr v) s))))
((equal? u v) s)
(else #f)))))
(define walk*
(lambda (v s)
(let ((v (walk v s)))
(cond
((pair? v) (cons (walk* (car v) s) (walk* (cdr v) s)))
(else v)))))
(define reify
(lambda (v s)
(let ((v (walk* v s)))
(walk* v (reify-s v empty-s)))))
(define reify-name
(lambda (n)
(string->symbol (string-append "_." (number->string n)))))
(define reify-s
(lambda (v s)
(let ((v (walk v s)))
(cond
((var? v) (ext-s v (reify-name (length s)) s))
((pair? v) (reify-s (cdr v) (reify-s (car v) s)))
(else s)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment