I'm just learning how to use cl-unification. I have written some code that doesn't work the way I expect, but of course this probably means that my expectations are wrong.
Can one of the cl-unification gurus take a look, and let me know what I'm doing wrong?
Thanks,
-russ
(defpackage :unification-demo
(:use :cl :CL.EXT.DACF.UNIFICATION))
(in-package :unification-demo)
(declaim (optimize (debug 3) (speed 0)))
(defclass call-expr ()
((rator :reader rator)
(rands :reader rands)))
(defmethod initialize-instance :after ((call-expr call-expr) &key form)
(with-slots (rator rands) call-expr
(destructuring-bind (rator-form &rest rand-forms) form
(setf rator rator-form
rands (mapcar (lambda (rand-form) (parse-expr rand-form))
rand-forms)))))
(defclass var-ref ()
((var :initarg :var :reader var)))
(defclass let-binding ()
((var :reader let-binding-var :initarg :var)
(expr :reader let-binding-expr :initarg :expr)))
(defmethod initialize-instance :after ((let-binding let-binding) &key form)
(with-slots (var expr) let-binding
(destructuring-bind (var-form expr-form) form
(setf var var-form
expr (parse-expr expr-form)))))
(defclass let-expr ()
((bindings :reader bindings)
(body :reader body)))
(defmethod initialize-instance :after ((let-expr let-expr) &key form)
(with-slots (bindings body) let-expr
(destructuring-bind (binding-forms body-form) (cdr form)
(setf bindings (mapcar (lambda (form) (make-instance 'let-binding :form form))
binding-forms)
body (parse-expr body-form)))))
(defun parse-expr (form)
(flet ((car-match (indicator)
(and (consp form) (eql (car form) indicator)))
(constant-match ()
(or (stringp form)
(numberp form))))
(cond ((constant-match) form)
((car-match 'let) (make-instance 'let-expr :form form))
((car-match 'lambda) (make-instance 'lambda-expr :form form))
((consp form) (make-instance 'call-expr :form form))
((symbolp form) (make-instance 'var-ref :var form))
(t (error "unhandled form ~A" form)))))
;; this works
(find-variable-value '?bs (unify #T(let-expr bindings ?bs)
(parse-expr
'(let ((x 1) (y 2))
(+ x y)))))
;; this fails, why?
(find-variable-value '?b (unify #T(let-expr bindings (list ?b &rest ?bs))
(parse-expr
'(let ((x 1) (y 2))
(+ x y)))))