(DEFINE-FILE-INFO READTABLE "INTERLISP" PACKAGE "USER" BASE 10)
(IL:FILECREATED " 1-Mar-88 10:38:52" IL:{DSK}<LISPFILES>SIMPLELOGIC>UNIFIER.;7 9042   

      IL:changes IL:to%:  (IL:VARS IL:UNIFIERCOMS)
                          (IL:FUNCTIONS BUILD-NEW-ENV UNIFY)

      IL:previous IL:date%: "24-Feb-88 17:52:39" IL:{DSK}<LISPFILES>SIMPLELOGIC>UNIFIER.;6)


(IL:* "
Copyright (c) 1987, 1988 by Roberto Ghislanzoni.  All rights reserved.
")

(IL:PRETTYCOMPRINT IL:UNIFIERCOMS)

(IL:RPAQQ IL:UNIFIERCOMS ((IL:FUNCTIONS BINDING BUILD-NEW-ENV FIND-IF-MEMBER FIND-VALUES 
                                 FIND-VARIABLE-VALUE LOOKUP NULLP RENAME RENAME-VARS UNIFY VARIABLEP)
                          ))

(DEFUN BINDING (PREDICATE THEORY-NAME &OPTIONAL WINDOW) [COND
                                                           [(EQ THEORY-NAME '*BACKGROUND-THEORY*)
                                                            (COND
                                                               [(EQ (CHAR-CODE (CHAR (SYMBOL-NAME
                                                                                      PREDICATE)
                                                                                     0))
                                                                    33)
          
          (IL:* IL:;; "CUT is handled in a very particular way!! ")

                                                                (GETHASH '! (GET 'THEORY '
                                                                                 *BACKGROUND-THEORY*]
                                                               (T (GETHASH PREDICATE
                                                                         (GET 'THEORY '
                                                                              *BACKGROUND-THEORY*]
                                                           (T (GETHASH PREDICATE (GET-THEORY 
                                                                                        THEORY-NAME 
                                                                                        WINDOW])


(DEFUN BUILD-NEW-ENV (PAT DAT ENV) 
          
          (IL:* IL:;; " It is better to make a distinction between the null value of a variable  and the variables unbound")
 (COND
    ((NULL DAT)
     (ACONS PAT '*NULL* ENV))
    (T (ACONS PAT DAT ENV))))


(DEFUN FIND-IF-MEMBER (ELT LST) (COND
                                   ((NULL LST)
                                    NIL)
                                   [(LISTP LST)
                                    (OR (FIND-IF-MEMBER ELT (CAR LST))
                                        (FIND-IF-MEMBER ELT (CDR LST]
                                   ((ATOM LST)
                                    (EQ LST ELT))
                                   (T (MEMBER ELT LST))))


(DEFUN FIND-VALUES (ELT ENV) (COND
                                ((NULL ELT)
                                 NIL)
                                ((LISTP ELT)
                                 (CONS (FIND-VALUES (CAR ELT)
                                              ENV)
                                       (FIND-VALUES (CDR ELT)
                                              ENV)))
                                ((VARIABLEP ELT)
                                 (FIND-VARIABLE-VALUE ELT ENV))
                                (T ELT)))


(DEFUN FIND-VARIABLE-VALUE (VAR ENV) [LET [(VAL (CDR (ASSOC VAR ENV]
                                          (COND
                                             ((VARIABLEP VAL)
                                              (FIND-VARIABLE-VALUE VAL ENV))
                                             ((NULL VAL)
          
          (IL:* IL:;; "The variable is unbound, so the variable itself is returned")

                                              VAR)
                                             ((NULLP VAL)
          
          (IL:* IL:;; "NULLP checks is the value is *NULL*")

                                              NIL)
                                             (T 
          
          (IL:* IL:;; "This is the statement for a partial occur  check")

                                                (OR (AND (NOT (FIND-IF-MEMBER VAR VAL))
                                                         (FIND-VALUES VAL ENV))
                                                    VAL])


(DEFUN LOOKUP (EXPR ENV) [COND
                            ((NUMBERP EXPR)
                             EXPR)
                            ((SYMBOLP EXPR)
                             (FIND-VALUES EXPR ENV))
                            (T (CONS (FIND-VALUES (CAR EXPR)
                                            ENV)
                                     (FIND-VALUES (CDR EXPR)
                                            ENV])


(DEFMACRO NULLP (ATOM) `(EQ ,ATOM '*NULL*))


(DEFUN RENAME (EXPR) (LET ((VARSTABLE (MAKE-HASH-TABLE)))
                          (DECLARE (SPECIAL VARSTABLE))
                          (RENAME-VARS EXPR)))


(DEFUN RENAME-VARS (EXPR) (COND
                             ((NULL EXPR)
                              NIL)
                             [(LISTP EXPR)
                              (CONS (RENAME-VARS (CAR EXPR))
                                    (RENAME-VARS (CDR EXPR]
                             [(VARIABLEP EXPR)
                              (LET ((ALREADY-RENAMED (GETHASH EXPR VARSTABLE)))
                                   (COND
                                      (ALREADY-RENAMED ALREADY-RENAMED)
                                      (T (LET ((NEW (GENSYM "?")))
                                              (SETF (GETHASH EXPR VARSTABLE)
                                                    NEW)
                                              NEW]
                             (T EXPR)))


(DEFUN UNIFY (PATT DAT ENV &OPTIONAL WINDOW) 
          
          (IL:* IL:;; "This is a very fast implementation of unifier: no stack frames are generated. The tecnique used here is that of save-rest argument: the unifier is not a true-recursive procedure, in the sense that it does not require a full stack for its implementation: in fact, when failure occurs, the value FAILED must be immediately returned ")
 [PROG ([DEBUGFLG (AND WINDOW (TRACINGP WINDOW 'UNIFY]
        (REST-PAT)
        (REST-DAT)
        TEMP)
   HERE
       (AND DEBUGFLG (UNIFY-DEBUGGER PATT DAT ENV WINDOW))   (IL:* IL:; "debugging stuff")

       [COND
          [(AND (NULL PATT)
                (NULL DAT))
           (COND
              ((AND (NULL REST-DAT)
                    REST-PAT)
               (RETURN 'FAILED))
              ((AND (NULL REST-PAT)
                    REST-DAT)
               (RETURN 'FAILED))
              ((AND (NULL REST-PAT)
                    (NULL REST-DAT))
               (RETURN ENV))
              (T (SETF PATT (CAR REST-PAT))
                 (SETF DAT (CAR REST-DAT))
                 (SETF REST-PAT (CDR REST-PAT))
                 (SETF REST-DAT (CDR REST-DAT))
                 (GO HERE]
          ((EQ ENV 'FAILED)
           (RETURN 'FAILED))
          ((EQ PATT DAT)
           (GO OUT))
          [(VARIABLEP DAT)
           (SETF TEMP (CDR (ASSOC DAT ENV)))
           (COND
              ((NULL TEMP)
               (SETF ENV (BUILD-NEW-ENV DAT PATT ENV))
               (GO OUT))
              (T (SETF DAT TEMP)
                 (GO HERE]
          [(VARIABLEP PATT)
           (SETF TEMP (CDR (ASSOC PATT ENV)))
           (COND
              ((NULL TEMP)
               (SETF ENV (BUILD-NEW-ENV PATT DAT ENV))
               (GO OUT))
              (T (SETF PATT TEMP)
                 (GO HERE]
          [(NULL PATT)
           (COND
              ((NULLP DAT)
               (GO OUT))
              (T (RETURN 'FAILED]
          [(NULL DAT)
           (COND
              ((NULLP PATT)
               (GO OUT))
              (T (RETURN 'FAILED]
          [(LISTP PATT)
           (COND
              ((LISTP DAT)
               (SETF REST-PAT (CONS (REST PATT)
                                    REST-PAT))
               (SETF REST-DAT (CONS (REST DAT)
                                    REST-DAT))
               (SETF PATT (CAR PATT))
               (SETF DAT (CAR DAT))
               (GO HERE))
              (T (RETURN 'FAILED]
          (T (RETURN 'FAILED]
   OUT    
          (IL:* IL:;; "a check is made for the end of the procedure")

       (COND
          ((AND (NULL REST-PAT)
                (NULL REST-DAT))
           (RETURN ENV))
          (T (SETF DAT NIL)
             (SETF PATT NIL)
             (GO HERE])


(DEFMACRO VARIABLEP (ITEM) `(AND (SYMBOLP ,ITEM)
                                 (EQ (CHAR-CODE (CHAR (SYMBOL-NAME ,ITEM)
                                                      0))
                                     63)))

(IL:PUTPROPS IL:UNIFIER IL:COPYRIGHT ("Roberto Ghislanzoni" 1987 1988))
(IL:DECLARE%: IL:DONTCOPY
  (IL:FILEMAP (NIL)))
IL:STOP