[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

*To*: clisp-list@ma2s2.mathematik.uni-karlsruhe.de (CLISP list forum)*Subject*: A question for DEFUN*From*: Chun-Yu Lee <d791013@ce.ntu.edu.tw>*Date*: Mon, 9 May 94 17:24:38 MDT*Mailer*: Elm [revision: 70.85]

Hello everybody, I wrote a simple equation solver in LISP (see below). If a function that uses the macro "equation" is defined before the file "eqsolver.lsp" is loaded, everything seems all right. For example, > (fmakunbound 'equation) EQUATION > (makunbound 'a) A > (makunbound 'b) B > (defun foo (a b) (equation a = b)) FOO > (load "eqsolver.lsp") ;; Loading file EQSOLVER.LSP ... ;; Loading of file EQSOLVER.LSP is finished. T > (setq a nil b 5) 5 > (foo a b) 5 ; A > (foo nil b) 5 ; A > (equation a = b) 5 ; A However, when the function is defined after, then the result becomes as follow: > (load "eqsolver.lsp") ;; Loading file EQSOLVER.LSP ... ;; Loading of file EQSOLVER.LSP is finished. T > (makunbound 'a) A > (makunbound 'b) B > (defun foo (a b) (equation a = b)) *** - EVAL: variable B has no value <--- Why does "defun" need to evaluate 1. Break> the arguments of a function. > (setq a nil b nil) NIL > (defun foo (a b) (equation a = b)) FOO <--- O.K. But, > (setq b 5) 5 > (foo a b) NIL ; <--- the output value is wrong. A > a NIL > b 5 > (equation a = b) 5 ; <--- It's correct. A What's wrong with it? Thanks in advance. Chun Yu Lee e-mail: d791013@ce.ntu.edu.tw =================File: EQSOLVER.LSP ============================= ;;; ;;; A Simple Equation Solver (SES) ;;; ;;; created: 18 April 1994 ;;; updated: 29 April 1994 ;;; author: Chun Yu Lee ; The following functions and macros serve to ; solve an equation that has less then one unknown and with three parts of ; expressions, the LHS, relationship, and RHS. No more than one unknown ; (variable) can be appeared in the LHS or RHS of the equation. ; A symbol name which is unbound or nil in the equation is an unknown. ; The operators or predicates used in expressions must be complyed with ; those specified in the exchanging rules depicted in global variable ; *X-operators*. However, any valid LISP forms other than specified in ; *X-operators* can be used in the expression which is on the opposite ; side to the one the unknown is stayed. ; ; The macro "symbol-equation" returns three values: the solved expression ; in symbolic form, the unknown variable, and the operater. But there is ; only one value will be returned, when the unknown cannot be found, to be ; true (T) or false (NIL) according to the evaluation of the equation. ; ; The macro "equation" returns two values: the evaluated result of solved ; equation and the unknown found. While the macro "nequation" is a ; destructive version of "equation" and returns only the evaluated result. ; The side effect of "nequation" is that the unbound (or nilled) variable ; will be bound to the result. ; ; SES can solve equations like followings: ; ; a * b = c + 4 -- (1), ; or b*x^2 + c = d -- (2). ; ; Eqn. (1) can be called as: ; ; ; > (setq a 3 b 4) ; 4 ; > (symbol-equation (* a b) = (+ c 4)) ; (- (* A B) 4) ; ; C ; ; = ; > (equation (* a b) = (+ c 4)) ; 8 ; ; C ; > (boundp 'c) ; NIL ; > (nequation (* a b) = (+ c 4)) ; 8 ; > c ; 8 ; ; In the similar way, eqn. (2) can be called as: ; ; > (setq x nil b 3 c 4 d 5) ; 5 ; > (symbol-equation (+ (* b (expt x 2)) c) = d) ; (EXPT (/ (- D C) B) (/ 1 2)) ; ; X ; ; = ; > ; ;;; Begining of the equation solver. (defvar *X-operators* '((+ . -) (* . /) (expt . expt) (exp . log) (sin . asin) (cos . acos) (tan . atan) (sinh . asinh) (cosh . acosh) (tanh . atanh) ) ) (defmacro equation (&body eqn) (multiple-value-bind (value var) (eval (cons 'symbol-equation eqn)) `(values ,(eval value) ',var) ) ) (defmacro nequation (&body eqn) ;destructive version (multiple-value-bind (value var) (eval (cons 'symbol-equation eqn)) (if var `(setq ,var ,(eval value)) value) ) ) (defmacro symbol-equation (lhs op rhs) (let* ((args (explode-list (list lhs rhs))) (var (nth (or (position-if-not #'(lambda (x) (or (numberp x) (boundp x) (fboundp x))) args) (position nil (mapcar #'(lambda (x) (if (or (numberp x) (fboundp x)) x (eval x))) args) ) (return-from symbol-equation `(,op ,lhs ,rhs)) ) args))) `(values ',(solve-linear-eqn lhs rhs var) ',var ',op) ) ) (defun solve-linear-eqn (lhs rhs var) (if (or (and (atom rhs) (equal rhs var)) (and (consp rhs) (member var (explode-list rhs)))) (solve-linear-eqn-r rhs lhs var) (solve-linear-eqn-r lhs rhs var) ) ) (defun solve-linear-eqn-r (lhs rhs var) (if (atom lhs) (if (equal lhs var) rhs nil) (let ((op (pop lhs)) (result nil) lhs1) (push (or (cdr (assoc op *X-operators*)) (car (rassoc op *X-operators*))) result) (push rhs result) (if (equal op 'expt) (setf (cadr lhs) `(/ 1 ,(cadr lhs)))) (dolist (ivar lhs) (if (or (and (atom ivar) (equal ivar var)) (and (consp ivar) (member var (explode-list ivar)))) (setq lhs1 ivar) (push ivar result)) ) (solve-linear-eqn-r lhs1 (reverse result) var) ) ) ) (defun explode-list (lst) (if (null lst) nil (if (atom lst) (list lst) (append (explode-list (car lst)) (explode-list (cdr lst))) ) ) ) ;;; End of equation solver.

**Follow-Ups**:**A question for DEFUN***From:*hoehle@inf-wiss.ivp.uni-konstanz.de (Joerg-Cyril Hoehle)

- Prev by Date:
**bug in prompting loops** - Next by Date:
**bug in prompting loops** - Previous by thread:
**Re: bug in prompting loops** - Next by thread:
**A question for DEFUN** - Index(es):