;;;; -*- Mode: LISP; Syntax: Common-Lisp; Base: 10 -*- ;;;; --------------------------------------------------------------------------- ;;;; File name: unify.lsp ;;;; System: FIRE ;;;; Author: Jesse Alama ;;;; Created: November 27, 2001 ;;;; Purpose: Unification ;;;; --------------------------------------------------------------------------- (in-package :fire) (defun unify (a b &optional (bindings nil)) (cond ((equal a b) bindings) ((variable? a) (unify-variable a b bindings)) ((variable? b) (unify-variable b a bindings)) ((or (not (consp a)) (not (consp b))) :fail) ((not (eq :fail (setq bindings (unify (car a) (car b) bindings)))) (unify (cdr a) (cdr b) bindings)) (t :fail))) (defun unify-variable (var exp bindings &aux val) ;; Must distinguish no value from value of nil (setq val (assoc var bindings)) (cond (val (unify (cdr val) exp bindings)) ;; If safe, bind to ((free-in? var exp bindings) (cons (cons var exp) bindings)) (t :fail))) (defun free-in? (var exp bindings) ;; Returns nil if occurs in , assuming . (cond ((null exp) t) ((equal var exp) nil) ((variable? exp) (let ((val (assoc exp bindings))) (if val (free-in? var (cdr val) bindings) t))) ((not (listp exp)) t) ((free-in? var (car exp) bindings) (free-in? var (cdr exp) bindings))))