home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / weyl / weyl_lsp.lha / general.lisp < prev    next >
Encoding:
Text File  |  1991-10-19  |  30.8 KB  |  1,003 lines

  1. ;; -*- Mode:Lisp; Package:Weyli; Base:10; Lowercase:T; Syntax:Common-Lisp -*-
  2. ;;; ===========================================================================
  3. ;;;                  General Representation
  4. ;;; ===========================================================================
  5. ;;; (c) Copyright 1989, 1991 Cornell University
  6.  
  7. ;;; $Id: general.lisp,v 1.21 1991/10/19 03:40:53 rz Exp $
  8.  
  9. (in-package "WEYLI")
  10.  
  11. (defclass has-memoization ()
  12.      ((memos :initform (make-hash-table :test #'eq))))
  13.  
  14. (defmethod set-memoization ((domain has-memoization) key value)
  15.   (with-slots (memos) domain
  16.     (setf (gethash key memos) value)
  17.     value))
  18.  
  19. (defmethod get-memoization ((domain has-memoization) key)
  20.   (with-slots (memos) domain
  21.     (gethash key memos)))
  22.  
  23. (defsetf get-memoization set-memoization)
  24.  
  25. (defmacro memoize (domain expression &body body)
  26.   `(let ((.expr. ,expression))
  27.     (with-slots (memos) ,domain
  28.        (multiple-value-bind (value found?) (gethash .expr. memos)
  29.      (if found? value
  30.          (setf (get-memoization ,domain .expr.) (progn ,@body)))))))
  31.  
  32. (defclass general-expressions (domain has-memoization)
  33.      ((variables :initform ()
  34.          :accessor ge-variables)
  35.       (context :initform ()
  36.            :accessor ge-context)))
  37.  
  38. (defvar *general* ()
  39.   "The general representation domain")
  40.  
  41. (defmethod domain-of ((element symbol))
  42.   *general*)
  43.  
  44. (defmethod domain-of ((x list))
  45.   *general*)
  46.  
  47. ;; Variables and contexts
  48.  
  49. ;; A variable is a list that starts with the atom VARIABLE.  Atoms are
  50. ;; canonicalized to this form
  51.  
  52. (defun make-variable (var)
  53.   (setq var 
  54.     (cond ((atom var)
  55.            (list 'variable :symbol var))
  56.           (t
  57.            (list 'variable :symbol var))))
  58.   (setf (getf (rest var) :string) (create-variable-string var))
  59.   var)
  60.  
  61. (defun create-variable-string (var)
  62.   (let ((string (cond ((atom (getf (rest var) :symbol))
  63.                (string-downcase (getf (rest var) :symbol)))
  64.               (t (format nil "[~A]" (getf (rest var) :symbol)))))
  65.     temp)
  66.     (when (setq temp (getf (rest var) :subscripts))
  67.       (setq string 
  68.         (format nil "~A(~S~{,~S~})"
  69.             string (first temp) (rest temp))))
  70.     string))
  71.  
  72.  
  73. ;; This function is only to be applied to general expressions. 
  74. (defsubst ge-variable? (x)
  75.   (and (not (atom x)) (eql (first x) 'variable)))
  76.  
  77. (defmethod add-subscripts ((var symbol) &rest subscripts)
  78.   (%apply #'add-subscripts (coerce var *general*) subscripts))
  79.  
  80. (defmethod add-subscripts ((var list) &rest subscripts)
  81.   (setq var (coerce var *general*))
  82.   (let* ((symbol (getf (rest var) :symbol))
  83.      (subscripts (append (getf (rest var) :subscripts) 
  84.                  #+Genera (copy-list subscripts)
  85.                  #-Genera subscripts))
  86.      (canonical-var 
  87.       (member symbol (ge-variables *general*)
  88.           :test (lambda (a b)
  89.               (and (equal a (getf (rest b) :symbol))
  90.                    (equal subscripts
  91.                       (getf (rest b) :subscripts)))))))
  92.     (cond (canonical-var
  93.        (first canonical-var))
  94.       (t (setq var (list 'variable :symbol symbol
  95.                  :subscripts subscripts))
  96.          (setf (getf (rest var) :string) (create-variable-string var))
  97.          (push var (ge-variables *general*))
  98.          var))))
  99.  
  100. (defun initialize-contexts ()
  101.   (setq *general* (make-instance 'general-expressions)))
  102.  
  103. (defmacro with-new-context (&body body)
  104.   `(let ((*general* (make-instance 'general-expressions)))
  105.      ,@body))
  106.  
  107. (defmacro check-point-context (&body body)
  108.   `(let ((.old-variables. (ge-variables *general*))
  109.      (.old-context. (ge-context *general*)))
  110.      (unwind-protect (progn ,@body)
  111.        (setf .old-variables. (ge-variables *general*))
  112.        (setf .old-context. (ge-context *general*)))))
  113.  
  114. (defmethod coerce ((var number) (domain general-expressions))
  115.   var)
  116.  
  117. (defmethod coerce ((var symbol) (domain general-expressions))
  118.   (let ((canonical-var
  119.      (member var (ge-variables domain)
  120.          :test (lambda (a b)
  121.              (and (equal a (getf (rest b) :symbol))
  122.                   (null (getf (rest b) :subscripts)))))))
  123.     (if canonical-var
  124.     (first canonical-var)
  125.     (first 
  126.      (push (make-variable var) (ge-variables domain))))))
  127.  
  128. (defmethod coerce ((var list) (domain general-expressions))
  129.   (cond ((eql (first var) 'variable)
  130.      (let ((canonical-var
  131.         (member var (ge-variables domain) :test #'eql)))
  132.        (first 
  133.         (if canonical-var canonical-var
  134.         (push var (ge-variables domain))))))
  135.     ((get (first var) :ge-coerce)
  136.      (%funcall (get (first var) :ge-coerce) var domain))
  137.     ((get (first var) :ge-operator)
  138.      `(,(get (first var) :ge-operator) 
  139.         ,@(loop for x in (rest var) collect (coerce x domain))))
  140.     (t 
  141.      `(,(first var) 
  142.         ,@(loop for x in (rest var) collect (coerce x domain))))))
  143.  
  144. (defmethod get-variable-property ((domain general-expressions) var key)
  145.   (setq var (coerce var domain))
  146.   (loop for var-prop in (ge-context domain)
  147.     do (when (eql (first var-prop) var)
  148.          (return (getf (rest var-prop) key)))
  149.     finally (progn 
  150.           (push (list var) (ge-context domain))
  151.           (return nil))))
  152.  
  153. (defmethod set-variable-property ((domain general-expressions) var key value)
  154.   (setq var (coerce var domain))
  155.   (loop for var-prop in (ge-context domain)
  156.     do (when (eql (first var-prop) var)
  157.          (setf (getf (rest var-prop) key) value)
  158.          (return value))    
  159.     finally (progn 
  160.           (push (list var key value) (ge-context domain))
  161.           (return value))))
  162.  
  163. (defsetf get-variable-property set-variable-property)
  164.  
  165. (defmethod declare-dependencies ((var (or symbol list)) &rest vars)
  166.   (setq var (coerce var *general*))
  167.   (let ((depends (get-variable-property *general* var :dependencies)))
  168.     (loop for v in vars
  169.       do (setq v (coerce v *general*))
  170.          (unless (member v depends :test #'ge-equal)
  171.            (push v depends)))
  172.     (setf (get-variable-property *general* var :dependencies)
  173.       depends)))
  174.  
  175. (defmethod depends-on? ((exp number) &rest vars)
  176.   (declare (ignore vars))
  177.   nil)
  178.  
  179. (defmethod depends-on? ((exp (or symbol list)) &rest vars)
  180.   (setq exp (coerce exp *general*))
  181.   (setq vars (loop for v in vars
  182.            collect (coerce v *general*)))
  183.   (labels ((depends (exp v)
  184.          (cond ((number? exp) nil)
  185.            ((ge-variable? exp) 
  186.             (let ((depends (get-variable-property
  187.                     *general* exp :dependencies)))
  188.               (if (or (ge-equal v exp)
  189.                   (member v depends :test #'ge-equal))
  190.               t nil)))
  191.            ((member (first exp) '(deriv))
  192.             (depends (second exp) v))
  193.            (t;; (member (first exp) '(plus times expt))
  194.             (loop for x in (rest exp)
  195.               do (when (depends x v)
  196.                    (return t))
  197.               finally (return nil))))))
  198.     (loop for v in vars
  199.       do (unless (depends exp v)
  200.            (return nil))
  201.       finally (return t))))
  202.  
  203. (defmethod different-kernels ((exp number) (kernels list))
  204.   nil)
  205.  
  206. (defmethod different-kernels ((exp symbol) (kernels list))
  207.   (setq exp (coerce exp *general*))
  208.   (setq kernels (loop for k in kernels collect (coerce k *general*)))
  209.   (unless (member exp kernels :test #'ge-equal)
  210.     (list exp)))
  211.  
  212. (defmethod different-kernels ((exp list) (kernels list))
  213.   (setq exp (coerce exp *general*))
  214.   (setq kernels (loop for k in kernels collect (coerce k *general*)))
  215.   (let ((new ()))
  216.     (labels ((check-kernel (x)
  217.            (unless (or (number? x)
  218.                (member x kernels :test #'ge-equal))
  219.          (pushnew x new :test #'ge-equal)))
  220.          (new-kernel (x)
  221.            (cond ((ge-variable? x)
  222.               (check-kernel x))
  223.              ((or (ge-plus? x) (ge-times? x))
  224.               (loop for exp in (rest x)
  225.                 do (new-kernel exp)))
  226.              ((ge-expt? x)
  227.               (if (lisp::integerp (third x))
  228.               (new-kernel (second x))
  229.               (check-kernel x)))
  230.              (t (check-kernel x)))))
  231.       (new-kernel exp)
  232.       new)))
  233. (defun print-variable (variable &optional (stream *standard-output*))
  234.   (setq variable (coerce variable *general*))
  235.   (let ((sym (getf (rest variable) :string)))
  236.     (cond ((and (not (null sym)) (atom sym))
  237.        #+Genera
  238.        (format stream "~'i~A~" sym)
  239.        #-Genera
  240.        (princ sym stream))
  241.       (t (princ (getf (rest variable) :symbol) stream)))))
  242.  
  243. (defmethod display ((expr number) &optional (stream *standard-output*)
  244.             &rest ignore)
  245.   (declare (ignore ignore))
  246.   (princ expr stream)
  247.   (values))
  248.  
  249. (defmethod display ((expr symbol) &optional (stream *standard-output*)
  250.             &rest ignore)
  251.   (declare (ignore ignore))
  252.   (setq expr (coerce expr *general*))
  253.   (display expr stream))
  254.  
  255. (defmacro def-display-fn (op arglist &body body)
  256.   (let ((fun-name (intern (format nil "DISPLAY-~A" op))))
  257.     (unless (lisp::= 2 (length arglist))
  258.       (error "Wrong number of arguments for DISPLAY function: ~S" op))
  259.     `(progn (setf (get ',op 'display-function) ',fun-name)
  260.         (defun ,fun-name ,arglist ,@body (values)))))
  261.  
  262. (defmethod display ((expr list) &optional (stream *standard-output*)
  263.             &rest ignore)
  264.   (declare (ignore ignore))
  265.   (let (fun)
  266.     (cond ((eql 'variable (first expr))
  267.        (print-variable expr stream))
  268.       ((setq fun (get (first expr) 'display-function))
  269.        (%funcall fun expr stream))
  270.       (t (format stream "~A{" (string-downcase (first expr)))
  271.          (display-list (rest expr) stream)
  272.          (princ "}" stream))))
  273.   (values))
  274.  
  275. (defun parenthesized-display (expr stream)
  276.   (princ "(" stream)
  277.   (display expr stream)
  278.   (princ ")" stream))
  279.  
  280. (defun safe-display (expr stream)
  281.   (if (or (number? expr) 
  282.       (ge-variable? expr)
  283.       (ge-expt? expr))
  284.       (display expr stream)      
  285.       (parenthesized-display expr stream)))
  286.  
  287. ;; Display a list of objects, paying attention to *print-length*.  No
  288. ;; surrounding delimiters.   This is a method so that we can define
  289. ;; similar functions for sets of objects embedded in arrays.
  290. (defmethod display-list
  291.     ((objects list) &optional (stream *standard-output*))
  292.   (when objects
  293.     (let ((cnt (or *print-length* -1)))
  294.       (declare (fixnum cnt))
  295.       (display (first objects) stream)
  296.       (lisp:decf cnt)
  297.       (loop for var in (rest objects)
  298.         do (princ ", " stream)
  299.            (when (lisp:zerop cnt)
  300.          (princ "..." stream)
  301.          (return))
  302.            (display var stream)
  303.            (lisp:decf cnt)))))
  304.  
  305. (defmethod 0? ((element t)) nil)
  306. (defmethod 1? ((element t)) nil)
  307.  
  308. ;; Ordering functions for general expressions
  309.  
  310. ;; Some operators may choose to ignore various parameters here.
  311. (defun ge-equal (x y)
  312.   (cond ((number? x) (and (number? y) (= x y)))
  313.     ((ge-variable? x) (eql x y))
  314.     ((ge-variable? y) nil)
  315.     ((and (eql (first x) (first y)))
  316.      (let ((equal-func (get (first x) :ge-equal)))
  317.        (if equal-func
  318.            (%funcall equal-func x y)
  319.            (ge-lequal (rest x) (rest y)))))))
  320.  
  321. (defun ge-lequal (x y)
  322.   (loop
  323.     (when (and (null x) (null y))
  324.       (return-from ge-lequal t))
  325.     (when (or (null x) (null y)
  326.           (not (ge-equal (first x) (first y))))
  327.       (return-from ge-lequal nil))
  328.     (pop x) (pop y)))
  329.  
  330. (defun ge-lgreat (x y)
  331.   (loop 
  332.     (cond ((null x)
  333.        (return nil))
  334.       ((null y)
  335.        (return t))
  336.       ((ge-equal (first x) (first y)))
  337.       ((ge-great (first x) (first y))
  338.        (return t))
  339.       (t (return nil)))
  340.     (pop x) (pop y)))
  341.  
  342. (defun ge-great (x y)
  343.   (cond ((number? x)
  344.      (and (number? y) (> x y)))
  345.     ((number? y) t)
  346.     ((ge-variable? x)
  347.      (ge-variable-great x y))
  348.     ((ge-variable? y)
  349.      (not (ge-variable-great y x)))
  350.     ((eql (first x) (first y))
  351.      (cond ((get (first x) :ge-great)
  352.         (%funcall (get (first x) :ge-great) x y))
  353.            (t (ge-lgreat (rest x) (rest y)))))
  354.     (t (string-lessp (string (first x)) (string (first y))))))
  355.  
  356. ;; x is assumed to be a variable
  357. (defun ge-variable-great (x y)
  358.   (cond ((ge-variable? y)
  359.      (string-greaterp (getf (rest x) :string) (getf (rest y) :string)))
  360.     ((or (ge-plus? y) 
  361.          (ge-times? y))
  362.      (loop for w in (rest y)
  363.            unless (ge-great x w)
  364.          do (return nil)
  365.            finally (return t)))
  366.     (t nil)))
  367.  
  368. (defun real? (x)
  369.   (or (and (numberp x) (not (lisp:complexp x)))
  370.       (bigfloatp x)))
  371.  
  372. (defmethod minus? ((x t))
  373.   nil)
  374.  
  375. (defmethod plus? ((x t))
  376.   (and (not (0? x)) (not (minus? x))))
  377.  
  378. ;; For compatibility with Common Lisp
  379. (defun minusp (x) (minus? x))
  380. (defun plusp (x) (plus? x))
  381. (defun zerop (x) (0? x))
  382.  
  383. (defun ge-minus? (x)
  384.   (cond ((and (number? x) (real? x)) (minus? x))
  385.     ((ge-times? x)
  386.      (and (real? (second x))
  387.           (minus? (second x))))
  388.     (t nil)))
  389.  
  390. (defmacro def-ge-operator (op &rest args)
  391.   (macrolet ((decode-operator (keyword string &body body) 
  392.            `(when (getf args ,keyword)
  393.           (let* ((fun-name (intern (format nil ,string op)))
  394.              (function (getf args ,keyword))
  395.              arglist body)
  396.             (when (eql (first function) 'function)
  397.               (setq function (second function)))
  398.             (unless (eql (first function) 'lambda)
  399.               (error "Invalid function supplied for ~S operator: ~A"
  400.                  ,keyword op))
  401.             (setq arglist (second function)
  402.               body (rest (rest function)))
  403.             ,@body))))
  404.     (let ((pred-name (intern (format nil "GE-~A?" op))))
  405.       `(progn
  406.      (setf (get ',op :ge-operator) ',op)
  407.      (defsubst ,pred-name (x) 
  408.        (and (not (atom x)) (eql (first x) ',op)))
  409.      ,@(when (getf args :alias)
  410.          `((setf (get ',(getf args :alias) :ge-operator) ',op)))
  411.      ,@(when (getf args :num-arguments)
  412.          `((setf (get ',op :num-arguments) ,(getf args :num-arguments))))
  413.      ,@(decode-operator :coerce "GE-~A-COERCE"
  414.          (unless (lisp::= 2 (length arglist))
  415.            (error "Wrong number of arguments for COERCE function: ~S"
  416.               op))
  417.          `((defun ,fun-name ,arglist ,@body)
  418.            (setf (get ',op :ge-coerce) ',fun-name)))
  419.      ,@(decode-operator :equal "GE-~A-EQUAL"
  420.          (unless (lisp::= 2 (length arglist))
  421.            (error "Wrong number of arguments for EQUAL function: ~S"
  422.               op))
  423.          `((defun ,fun-name ,arglist ,@body)
  424.            (setf (get ',op :ge-equal) ',fun-name)))
  425.      ,@(decode-operator :great "GE-~A-GREAT"
  426.          (unless (lisp::= 2 (length arglist))
  427.            (error "Wrong number of arguments for GREAT function: ~S"
  428.               op))
  429.          `((defun ,fun-name ,arglist ,@body)
  430.            (setf (get ',op :ge-great) ',fun-name)))
  431.      ,@(decode-operator :display "DISPLAY-~A"
  432.          (unless (lisp::= 2 (length arglist))
  433.            (error "Wrong number of arguments for DISPLAY function: ~S"
  434.               op))
  435.          `((setf (get ',op 'display-function) ',fun-name)
  436.            (defun ,fun-name ,arglist ,@body (values))))
  437.      ,@(decode-operator :simplify "SIMPLIFY-~A"
  438.                 `((setf (get ',op 'simplify-function) ',fun-name)
  439.                   (defun ,fun-name ,arglist ,@body))))))) 
  440.  
  441. (def-ge-operator PLUS
  442.   :alias +
  443.   :display (lambda (expr stream)
  444.          (display (second expr) stream)
  445.          (loop for x in (rest (rest expr))
  446.            do (cond ((and (number? x) (real? x))
  447.                  (if (plus? x)
  448.                  (format stream " + ~S" x)
  449.                  (format stream " - ~S" (minus x))))
  450.                 ((ge-minus? x)
  451.                  (princ " - " stream)
  452.                  (display (simplify `(times ,(minus (second x))
  453.                             ,@(rest (rest x))))))
  454.                 (t (princ " + " stream)
  455.                    (display x stream))))))
  456.  
  457. (def-ge-operator TIMES
  458.   :alias *
  459.   :display (lambda (expr stream)
  460.          (safe-display (second  expr) stream)
  461.          (loop for x in (rest (rest expr))
  462.            do (princ " " stream)
  463.               (safe-display x stream))))
  464.  
  465. (def-ge-operator EXPT
  466.   :num-arguments 2
  467.   :display (lambda (expr stream)
  468.          (safe-display (second expr) stream)
  469.          (princ "^" stream)
  470.          (safe-display (third expr) stream)))
  471.  
  472. (def-ge-operator COS :num-arguments 1)
  473. (def-ge-operator SIN :num-arguments 1)
  474. (def-ge-operator TAN :num-arguments 1)
  475. (def-ge-operator ACOS :num-arguments 1)
  476. (def-ge-operator ASIN :num-arguments 1)
  477. (def-ge-operator ATAN :num-arguments 1)
  478. (def-ge-operator COSH :num-arguments 1)
  479. (def-ge-operator SINH :num-arguments 1)
  480. (def-ge-operator TANH :num-arguments 1)
  481. (def-ge-operator ACOSH :num-arguments 1)
  482. (def-ge-operator ASINH :num-arguments 1)
  483. (def-ge-operator ATANH :num-arguments 1)
  484.  
  485. (def-ge-operator DERIV 
  486.   :num-arguments 2
  487.   :coerce (lambda (x domain)
  488.         (let ((derivs (if (or (symbolp (third x)) 
  489.                   (ge-variable? (third x))
  490.                   (rest (rest (rest x))))
  491.                   (rest (rest x))
  492.                   (third x))))
  493.           `(deriv ,(coerce (second x) domain)
  494.               ,(loop for w in derivs
  495.                  collect (cond ((or (atom w) (ge-variable? w))
  496.                         (list (coerce w domain) 1))
  497.                        (t (list (coerce (first w) domain)
  498.                             (coerce (second w) domain))))))))
  499.   :display (lambda (expr stream)
  500.          (princ "D{" stream)
  501.          (display (second expr) stream)
  502.          (let ((derivs (third expr)))
  503.            (cond ((numberp derivs)
  504.               (format stream ", ~D}" derivs))
  505.              ((and (null (rest derivs))
  506.                (eql 1 (second (first derivs))))
  507.               (princ ", " stream)
  508.               (display (first (first derivs)) stream)
  509.               (princ "}" stream))
  510.              (t (princ ", {" stream)
  511.             (loop for (var order) in derivs 
  512.                   and first? = t then nil do 
  513.                 (unless first?
  514.                   (princ ", " stream))
  515.                 (cond ((eql order 1)
  516.                        (display var stream))
  517.                       (t (display var stream)
  518.                      (format stream "^~D" order))))
  519.             (princ "}}" stream)))))
  520.   :equal (lambda (x y)
  521.        (let ((x-vars (third x))
  522.          (y-vars (third y)))
  523.          (and (ge-equal (second x) (second y))
  524.           (equal (length x-vars) (length y-vars))
  525.           (loop for (x-var x-order) in x-vars
  526.             and (y-var y-order) in y-vars
  527.             unless (and (ge-equal x-var y-var)
  528.                     (ge-equal x-order y-order))
  529.               do (return nil)
  530.             finally (return t)))))
  531.   :great (lambda (x y)
  532.        (let ((x-vars (third x))
  533.          (y-vars (third y)))
  534.          (cond ((ge-great (second x) (second y)) t)
  535.            ((ge-great (second y) (second x)) nil)
  536.            (t (loop for (x-var x-order) in x-vars
  537.                 and (y-var y-order) in y-vars
  538.                 do (cond ((ge-great x-var y-var) (return t))
  539.                      ((ge-equal x-var y-var)
  540.                       (cond ((ge-great x-order y-order)
  541.                          (return t))
  542.                         ((ge-great y-order x-order)
  543.                          (return nil))))
  544.                      (t (return nil)))))))))
  545.  
  546. (def-ge-operator DERIVATION
  547.   :num-arguments 2
  548.   :display (lambda (expr stream)
  549.          (let ((base (second expr))
  550.            (order (third expr)))
  551.            (cond ((< order 3)
  552.               (display base stream)
  553.               (cond ((= order 0))
  554.                 ((= order 1) (princ #\' stream))
  555.                 ((= order 2) (princ #\" stream))
  556.                 (t (format stream "(~D)" order))))
  557.              (t (princ "d{" stream)
  558.             (display base stream)
  559.             (format stream ", ~D}" order)))))
  560.   :equal (lambda (x y)
  561.        (and (ge-equal (second x) (second y))
  562.         (ge-equal (third x) (third y))))
  563.   :great (lambda (x y)
  564.        (cond ((ge-great (second x) (second y)) t)
  565.          ((ge-great (second y) (second x)) nil)
  566.          (t (ge-great (third x) (third y))))))
  567.  
  568. ;; Simplify
  569.  
  570. (defmethod simplify ((x symbol))
  571.   (coerce x *general*))
  572.  
  573. (defmethod simplify ((x number)) 
  574.   x)
  575.  
  576. ;; This works by converting the sum into a list of dotted pairs.  The
  577. ;; first element of the list is a number, while the second is a list
  578. ;; of product terms.  This makes combining new elements quite easy.
  579. ;; After the combination, everything is converted back to the standard
  580. ;; representation. 
  581.  
  582. (defmacro merge-terms-in-sum (terms &body body)
  583.   `(let ((,terms (list nil)))
  584.      (labels ((add-term (base order) 
  585.         (loop with terms = ,terms do
  586.           (cond ((or (null (rest terms))
  587.                  (ge-lgreat base (rest (second terms))))
  588.              (push (cons order base) (rest terms))
  589.              (return t))
  590.             ((ge-lequal base (rest (second terms)))
  591.              (incf (first (second terms)) order)
  592.              (when (0? (first (second terms)))
  593.                (setf (rest terms) (rest (rest terms))))
  594.              (return t)))
  595.           (pop terms))))
  596.        ,@body)))
  597.  
  598. (defmethod simplify ((x list))
  599.   (let ((key (first x))
  600.     simplifier)
  601.     (cond ((eql key 'variable) x)
  602.       ((setq simplifier (get key 'simplify-function))
  603.        (%funcall simplifier x))
  604.       (t x))))
  605.  
  606. (setf (get 'plus 'simplify-function) 'simplify-plus)
  607.  
  608. (defun simplify-plus (x)
  609.   (merge-terms-in-sum terms
  610.     (let ((const 0))
  611.       (labels ((loop-over-terms (terms)
  612.          (loop for term in terms
  613.                do (setq term (simplify term))
  614.               (cond ((number? term) 
  615.                  (setq const (+ const term)))
  616.                 ((ge-plus? term)
  617.                  (loop-over-terms (rest term)))
  618.                 ((ge-times? term)
  619.                  (cond ((number? (second term))
  620.                     (add-term (rest (rest term)) 
  621.                           (second term)))
  622.                        (t (add-term (rest term) 1))))
  623.                 (t (add-term (list term) 1))))))
  624.     (loop-over-terms (rest x))
  625.     (setq terms (loop for (c . term-l) in (rest terms)
  626.               collect
  627.               (if (or (eql c 1) (eql c 1.0))
  628.                   (if (null (rest term-l))
  629.                   (first term-l)
  630.                   `(times ,@term-l))
  631.                   `(times ,c ,@term-l)))) 
  632.     (cond ((not (0? const))
  633.            (if (null terms) const
  634.            `(plus ,const ,@terms)))
  635.           ((null terms)
  636.            0)
  637.           ((null (rest terms))
  638.            (first terms))
  639.           (t `(plus ,@terms)))))))
  640.  
  641.  
  642. (setf (get 'times 'simplify-function) 'simplify-times)
  643.  
  644. (defun simplify-times (x)
  645.   (merge-terms-in-sum terms
  646.     (let ((const 1))
  647.       (labels ((loop-over-terms (terms)
  648.          (loop for term in terms
  649.                do (setq term (simplify term))
  650.               (cond ((number? term)
  651.                  (when (0? term)
  652.                    (return-from simplify-times 0))
  653.                  (setq const (lisp::* const term)))
  654.                 ((ge-times? term)
  655.                  (loop-over-terms (rest term)))
  656.                 ((ge-expt? term)
  657.                  (cond ((number? (third term))
  658.                     (add-term (list (second term)) (third term)))
  659.                        (t (add-term (list (second term)) 1))))
  660.                 (t (add-term (list term) 1))))))
  661.     (loop-over-terms (rest x))
  662.     (setq terms (loop for (exp base) in (rest terms)
  663.               collect
  664.               (if (eql exp 1) base
  665.                   `(expt ,base ,exp)))) 
  666.     (cond ((not (or (eql const 1) (eql const 1.0)))
  667.            (if (null terms) const
  668.            `(times ,const ,@terms)))
  669.           ((null terms) 1)
  670.           ((null (rest terms))
  671.            (first terms))
  672.           (t `(times ,@terms)))))))
  673.  
  674.  
  675. (setf (get 'expt 'simplify) 'simplify-expt)
  676.  
  677. (defun simplify-expt (x)
  678.   (let ((exp (simplify (third x))))
  679.     (cond ((0? exp) 1)
  680.       ((eql 1 exp) (simplify (second x)))
  681.       (t `(expt ,(simplify (second x)) ,exp)))))
  682.  
  683. (setf (get 'log 'simplify-function) 'simplify-log)
  684. (defun simplify-log (x)
  685.   (let ((exp (simplify (second x))))
  686.     (cond ((lisp::floatp exp) (lisp:log exp))
  687.       ((ge-expt? exp)
  688.        (simplify
  689.         `(times ,(third exp) (log ,(second exp)))))
  690.       (t `(log ,exp)))))
  691.  
  692. (setf (get 'sin 'simplify-function) 'simplify-sin)
  693. (defun simplify-sin (x)
  694.   (let ((exp (simplify (second x))))
  695.     (cond ((lisp::floatp exp) (lisp:sin exp))
  696.       ((and (number? exp) (0? exp))
  697.        0)
  698.       ((ge-minus? exp)
  699.        `(times -1
  700.            (sin ,(simplify `(times ,(minus (second exp))
  701.                        ,@(rest (rest exp)))))))
  702.       (t `(sin ,exp)))))
  703.  
  704. (setf (get 'cos 'simplify-function) 'simplify-cos)
  705. (defun simplify-cos (x)
  706.   (let ((exp (simplify (second x))))
  707.     (cond ((lisp::floatp exp) (lisp:cos exp))
  708.       ((and (number? exp) (0? exp)) 1)
  709.       ((ge-minus? exp)
  710.        `(cos ,(simplify `(times ,(minus (second exp))
  711.                     ,@(rest (rest exp))))))
  712.       (t `(cos ,exp)))))
  713.  
  714. (setf (get 'tan 'simplify-function) 'simplify-tan)
  715. (defun simplify-tan (x)
  716.   (let ((exp (simplify (second x))))
  717.     (cond ((lisp::floatp exp) (lisp:tan exp))
  718.       ((and (number? exp) (0? exp))
  719.        0)
  720.       ((ge-minus? exp)
  721.        `(times -1
  722.            (tan ,(simplify `(times ,(minus (second exp))
  723.                        ,@(rest (rest exp)))))))
  724.       (t `(tan ,exp)))))
  725.  
  726. (setf (get 'asin 'simplify-function) 'simplify-asin)
  727. (defun simplify-asin (x)
  728.   (let ((exp (simplify (second x))))
  729.     (cond ((lisp:floatp exp) (lisp:asin exp))
  730.       ((and (number? exp) (0? exp))
  731.        0)
  732.       ((ge-minus? exp)
  733.        `(times -1
  734.            (asin ,(simplify `(times ,(minus (second exp))
  735.                         ,@(rest (rest exp)))))))
  736.       (t `(asin ,exp)))))
  737.  
  738. (setf (get 'acos 'simplify-function) 'simplify-acos)
  739. (defun simplify-acos (x)
  740.   (let ((exp (simplify (second x))))
  741.     (cond ((lisp::floatp exp) (lisp:acos exp))
  742.       (t `(acos ,exp)))))
  743.  
  744. (setf (get 'atan 'simplify-function) 'simplify-atan)
  745. (defun simplify-atan (x)
  746.   (let ((exp (simplify (second x))))
  747.     (cond ((lisp::floatp exp) (lisp:atan exp))
  748.       (t `(atan ,exp)))))
  749.  
  750. (setf (get 'sinh 'simplify-function) 'simplify-sinh)
  751. (defun simplify-sinh (x)
  752.   (let ((exp (simplify (second x))))
  753.     (cond ((lisp::floatp exp) (lisp:sinh exp))
  754.       ((and (number? exp) (0? exp))
  755.        0)
  756.       ((ge-minus? exp)
  757.        `(times -1
  758.            (sinh ,(simplify `(times ,(minus (second exp))
  759.                         ,@(rest (rest exp)))))))
  760.       (t `(sinh ,exp)))))
  761.  
  762. (setf (get 'cosh 'simplify-function) 'simplify-cosh)
  763. (defun simplify-cosh (x)
  764.   (let ((exp (simplify (second x))))
  765.     (cond ((lisp::floatp exp) (lisp:cosh exp))
  766.       ((and (number? exp) (0? exp)) 1)
  767.       ((ge-minus? exp)
  768.        `(cosh ,(simplify `(times ,(minus (second exp))
  769.                      ,@(rest (rest exp))))))
  770.       (t `(cosh ,exp)))))
  771.  
  772. (setf (get 'tanh 'simplify-function) 'simplify-tanh)
  773. (defun simplify-tanh (x)
  774.   (let ((exp (simplify (second x))))
  775.     (cond ((lisp::floatp exp) (lisp:tanh exp))
  776.       ((and (number? exp) (0? exp))
  777.        0)
  778.       ((ge-minus? exp)
  779.        `(times -1
  780.            (tanh ,(simplify `(times ,(minus (second exp))
  781.                         ,@(rest (rest exp)))))))
  782.       (t `(tanh ,exp)))))
  783.  
  784. (setf (get 'asinh 'simplify-function) 'simplify-asinh)
  785. (defun simplify-asinh (x)
  786.   (let ((exp (simplify (second x))))
  787.     (cond ((lisp:floatp exp) (lisp:asinh exp))
  788.       ((and (number? exp) (0? exp))
  789.        0)
  790.       ((ge-minus? exp)
  791.        `(times -1
  792.            (asinh ,(simplify `(times ,(minus (second exp))
  793.                          ,@(rest (rest exp)))))))
  794.       (t `(asinh ,exp)))))
  795.  
  796. (setf (get 'acosh 'simplify-function) 'simplify-acosh)
  797. (defun simplify-acosh (x)
  798.   (let ((exp (simplify (second x))))
  799.     (cond ((lisp::floatp exp) (lisp:acosh exp))
  800.       (t `(acosh ,exp)))))
  801.  
  802. (setf (get 'atanh 'simplify-function) 'simplify-atanh)
  803. (defun simplify-atanh (x)
  804.   (let ((exp (simplify (second x))))
  805.     (cond ((lisp::floatp exp) (lisp:atanh exp))
  806.       (t `(atanh ,exp)))))
  807.  
  808. (setf (get 'deriv 'simplify) 'simplify-deriv)
  809. (defun simplify-deriv (x)
  810.   (let ((arg (simplify (second x))))
  811.     (merge-terms-in-sum derivs
  812.       (loop for (var order) in (third x) do
  813.     (add-term (list var) order))
  814.       (when (ge-deriv? arg)
  815.     (loop for (var order) in (third arg) do
  816.       (add-term (list var) order))             
  817.     (setq arg (second arg)))
  818.       `(deriv ,arg 
  819.           ;; Really don't need dot below...
  820.           ,(loop for (order base) in (rest derivs)
  821.              collect (list base order))))))
  822.  
  823. ;; The following transforming characterizes one of the very common
  824. ;; control structures used in symbolic computation.  It needs  great
  825. ;; deal of refinement still.
  826. (defmacro ge-transform ((transform form) forms &body body)
  827.   (let (temp)
  828.     `(labels
  829.      ((,transform (,form)
  830.         (cond ((ge-variable? ,form)
  831.            ,@(if (null (setq temp (assoc :variable forms)))
  832.              `((error "Don't know how to transform ~S" ,form))
  833.              (rest temp)))
  834.           ((ge-plus? ,form)
  835.            ,@(if (null (setq temp (assoc :plus forms)))
  836.              `((loop with ans = (,transform (second ,form))
  837.                    for x in (rest (rest ,form))
  838.                    do (setq ans (+ ans (,transform x)))
  839.                    finally (return ans)))
  840.              (rest temp)))
  841.           ((ge-times? ,form)
  842.            ,@(if (null (setq temp (assoc :times forms)))
  843.              `((loop with ans = (,transform (second ,form))
  844.                    for x in (rest (rest ,form))
  845.                    do (setq ans (* ans (,transform x)))
  846.                    finally (return ans)))
  847.              (rest temp)))
  848.           ((ge-expt? ,form)
  849.            ,@(if (null (setq temp (assoc :expt forms)))
  850.              `((expt (,transform (second ,form)) (third ,form)))
  851.              (rest temp)))
  852.           ,@(loop for (pred . exprs) in forms
  853.               unless (member pred '(:variable :plus :times :expt 
  854.                         :otherwise))
  855.                 collect `(,pred ,@ exprs))
  856.           ,@(when (setq temp (assoc :otherwise forms))
  857.               `((t ,@(rest temp)))))))
  858.        ,@body)))                     
  859.  
  860. (defmethod plus ((x (or list symbol integer number))
  861.          (y (or list symbol)))
  862.   (simplify `(plus ,(coerce x *general*) ,(coerce y *general*))))
  863.  
  864. (defmethod plus ((x (or list symbol)) (y (or integer number)))
  865.   (simplify `(plus ,(coerce x *general*) ,(coerce y *general*))))
  866.  
  867. (defmethod difference ((x (or list symbol integer number))
  868.                (y (or list symbol)))
  869.   (simplify `(plus ,(coerce x *general*) (times -1 ,(coerce y *general*)))))
  870.  
  871. (defmethod difference ((x (or list symbol)) (y (or integer number)))
  872.   (simplify `(plus ,(coerce x *general*) (times -1 ,(coerce y *general*)))))
  873.  
  874. (defmethod minus ((x (or symbol list)))
  875.   (simplify `(times -1 ,(coerce x *general*))))
  876.  
  877. (defmethod times ((x (or list symbol integer number))
  878.           (y (or list symbol)))
  879.   (simplify `(times ,(coerce x *general*) ,(coerce y *general*))))
  880.  
  881. (defmethod times ((x (or list symbol)) (y (or integer number)))
  882.   (simplify `(times ,(coerce x *general*) ,(coerce y *general*))))
  883.  
  884. (defmethod expt ((x (or list symbol integer number))
  885.           (y (or list symbol)))
  886.   (simplify `(expt ,(coerce x *general*) ,(coerce y *general*))))
  887.  
  888. (defmethod expt ((x (or list symbol)) (y (or integer number)))
  889.   (simplify `(expt ,(coerce x *general*) ,(coerce y *general*))))
  890.  
  891. (defmethod sin ((x (or symbol list)))
  892.   (simplify `(sin ,(coerce x *general*))))
  893.  
  894. (defmethod cos ((x (or symbol list)))
  895.   (simplify `(cos ,(coerce x *general*))))
  896.  
  897. (defmethod tan ((x (or symbol list)))
  898.   (simplify `(tan ,(coerce x *general*))))
  899.  
  900. (defmethod log ((x (or symbol list)))
  901.   (simplify `(log ,(coerce x *general*))))
  902.  
  903. (defmethod deriv ((exp (or number symbol list)) &rest vars)
  904.   (setq exp (coerce exp *general*))
  905.   (loop for v in vars
  906.     do (setq exp (ge-deriv exp (coerce v *general*))))
  907.   exp)
  908.  
  909. (defmacro declare-derivative  (func args var &body body)
  910.   `(setf (get ',func 'derivative-function)
  911.     (lambda (.arg. ,var)
  912.       (let ,args
  913.         ,@(loop for arg in args collect
  914.           `(setq ,arg (pop .arg.)))
  915.         (simplify (progn ,@body))))))
  916.  
  917. (declare-derivative sin (x) var
  918.   (* (deriv x var) (cos x)))
  919.  
  920. (declare-derivative cos (x) var
  921.   (* (- (deriv x var)) (sin x)))
  922.  
  923. (declare-derivative log (x) var
  924.   (* (deriv x var) (expt x -1)))
  925.  
  926. (defun ge-deriv (exp var)
  927.   (cond ((number? exp) 0)
  928.     ((ge-variable? exp)
  929.      (cond ((ge-equal exp var) 1)
  930.            ((depends-on? exp var)
  931.         `(deriv ,exp ((,var 1))))
  932.            (t 0)))
  933.     ((eql (first exp) 'plus)
  934.      (simplify
  935.       `(plus ,@(loop for x in (rest exp)
  936.              collect (ge-deriv x var)))))    
  937.     ((eql (first exp) 'times)
  938.      (simplify
  939.       `(plus ,@(loop for x in (rest exp)
  940.              collect
  941.               (simplify
  942.                 `(times ,(ge-deriv x var)
  943.                     ,@(remove x (rest exp))))))))
  944.     ((eql (first exp) 'expt)
  945.      (let ((base (second exp))
  946.            (power (third exp)))
  947.      (cond ((depends-on? power var)
  948.         (error "Not implemented yet"))
  949.            ((and (number? power) (= power 2))
  950.         (* 2 base (ge-deriv base var)))
  951.            (t (* power (expt base (- power 1)))))))
  952.     ((eql (first exp) 'deriv)
  953.      (labels ((deriv (l)
  954.             (cond ((null l) nil)
  955.               ((ge-equal var (first (first l)))
  956.                (cons (list var (1+ (second (first l))))
  957.                  (rest l)))
  958.               (t (cons (first l)
  959.                    (deriv (second l)))))))
  960.        `(deriv ,(second exp) ,(deriv (third exp)))))
  961.     (t (let ((func (get (first exp) 'derivative-function)))
  962.          (if func
  963.          (%funcall func (rest exp) var)
  964.          (error "Don't know how to take derivative of ~S" exp))))))
  965.  
  966. (defmacro map-over-expressions (exp (comps type . options) &body body)
  967.   (if (null options)
  968.       `(%map-over-expressions ,exp (lambda (,comps ,type) ,@body))
  969.       `(apply #'%map-over-expressions ,exp (lambda (,comps ,type) ,@body)
  970.           options)))
  971.  
  972. (defmethod %map-over-expressions ((exp (or symbol list)) func &rest options)
  973.   (declare (ignore options))
  974.   (labels ((moe (exp)
  975.          (cond ((number? exp)
  976.             (prog1
  977.               (funcall func exp :number)))
  978.            ((ge-variable? exp)
  979.             (prog1
  980.               (funcall func exp :variable)))
  981.            ((ge-plus? exp)
  982.             (multiple-value-bind (value recurse?)
  983.             (funcall func exp :plus)
  984.               (when recurse? 
  985.             (loop for e in (rest exp) do (moe e)))
  986.               value))
  987.            ((ge-times? exp)
  988.             (multiple-value-bind (value recurse?)
  989.             (funcall func exp :times)
  990.               (when recurse?
  991.             (loop for e in (rest exp) do (moe e)))
  992.               value))
  993.            ((ge-expt? exp)
  994.             (multiple-value-bind (value recurse?)
  995.             (funcall func exp :expt)
  996.               (when recurse?
  997.             (moe (second exp))
  998.             (moe (third exp)))
  999.               value))
  1000.            (t (funcall func exp (first exp))))))
  1001.     (moe exp)))
  1002.   
  1003.