1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancements. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;; (c) Copyright 1982 Massachusetts Institute of Technology ;;;
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13 (macsyma-module matrun
)
15 ;;; TRANSLATION properties for the FSUBRs in this file
16 ;;; can be found in MAXSRC;TRANS5 >. Be sure to check on those
17 ;;; if any semantic changes are made.
19 ;; $MAXAPPLYDEPTH is the maximum depth within an expression to which
20 ;; APPLYi will delve. If $MAXAPPLYDEPTH is 0, it is applied only to
22 (defmvar $maxapplydepth
10000.
)
24 ;; If $MAXAPPLYHEIGHT is 0, only atoms are affected by $APPLYB1 and
26 (defmvar $maxapplyheight
10000.
)
28 (defmvar matchreverse nil
)
30 (defmspec $disprule
(l) (setq l
(cdr l
))
31 (if (and (eq (car l
) '$all
) (null (cdr l
)))
32 (disprule1 (cdr $rules
))
36 `((mlist simp
) ,@(loop for r in l collect
(cadr ($ldisp
(consrule r
))))))
39 (let ((rule (mget x
'$rule
)))
40 (if rule
(list '(msetq simp
) x
(cons '(marrow simp
) (cdr rule
)))
41 (merror (intl:gettext
"disprule: ~:M is not a user rule.") x
))))
43 (defmfun $remrule
(op rule
)
46 (cond ((not (eq rule
'$all
))
47 (removerule op rule
) (return (getop op
)))
48 ((null (setq rules
(mget op
'oldrules
)))
49 (merror (intl:gettext
"remrule: no rules known for operator ~:@M") op
)))
50 next
(cond ((or (null rules
) (null (cdr rules
)))
51 (mputprop op
1 'rulenum
) (return (getop op
)))
52 (t (removerule op
(car rules
))
53 (setq rules
(cdr rules
)) (go next
)))))
55 (defun removerule (op rule
)
56 (cond ((member rule
*builtin-$rules
* :test
#'eq
)
60 (oldrules old othrulename othrule
)
61 (setq oldrules
(mget op
'oldrules
))
62 (cond ((or (null rule
) (null (setq oldrules
(member rule oldrules
:test
#'equal
))))
63 (merror (intl:gettext
"remrule: no such rule: ~:M") rule
))
64 ((null (car (setq oldrules
(cdr oldrules
))))
65 (setq oldrules
(cdr oldrules
))
66 (setq othrulename nil
)
67 (setq othrule
#'(lambda (a bb c
) (declare (ignore bb
)) (simpargs a c
))))
68 (t (setq othrulename
(car oldrules
))
69 (setq othrule
(cadr (getl (car oldrules
) '(expr subr
))))))
70 (putprop-or-remprop rule othrule
'expr
)
71 (setq old
(cdr (member rule
(reverse (mget op
'oldrules
)) :test
#'equal
)))
72 (if old
(putprop-or-remprop (car old
)
73 (subst othrulename rule
(get (car old
) 'expr
))
75 (if (boundp rule
) (makunbound rule
))
76 (mremprop rule
'$rule
)
77 (mremprop rule
'$ruletype
)
78 (mremprop rule
'ruleof
)
80 (setq $rules
(delete rule $rules
:count
1 :test
#'eq
))
81 (putprop-or-remprop rule othrulename
'expr
)
82 (if (eq (get op
'operators
) rule
)
83 (putprop-or-remprop op othrulename
'operators
))
84 (let ((l (delete rule
(mget op
'oldrules
) :test
#'eq
)))
85 (if (equal l
'(nil)) (mremprop op
'oldrules
) (mputprop op l
'oldrules
))
88 (defun putprop-or-remprop (x y z
)
94 (cond ((equal e
1) '(1 .
0))
95 ((equal e
0) '(0 .
1))
97 ((eq (caar e
) 'mexpt
) (cons (cadr e
) (caddr e
)))
100 (defun findfun (e p c
)
102 (cond ((and (null (atom e
)) (eq (caar e
) p
)) (return e
))
103 ((or (atom e
) (not (eq (caar e
) c
))) (matcherr))
104 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
105 (setq e
(reverse (cdr e
))) (go b
)))
107 b
(cond ((null e
) (matcherr))
108 ((and (not (atom (car e
))) (eq (caaar e
) p
)) (return (car e
))))
111 (defun findexpon (e1 base
* c
)
114 (cond ((and (mexptp e
) (alike1 base
* (cadr e
)))
116 ((or (atom e
) (not (eq (caar e
) c
))) (go c
))
117 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
118 (setq e
(reverse (cdr e
))) (go b
)))
120 b
(cond ((null e
) (go c
))
121 ((and (mexptp (car e
)) (alike1 base
* (cadar e
)))
122 (return (caddar e
))))
124 c
(cond ((or (and (not (atom e1
)) (member c
'(mplus mtimes
) :test
#'eq
)
125 (eq c
(caar e1
)) (memalike base
* e1
))
127 (and (not (atom base
*)) (eq c
(caar base
*))))
129 ((eq c
'mexpt
) (matcherr))
132 (defun findbase (e expon c
)
134 (cond ((equal expon
0)
135 (if (and (eq c
'mexpt
) (not (equal 1 e
))) (matcherr))
137 ((equal expon
1) (return e
))
138 ((and (numberp expon
) (> expon
0) (equal e
0))
140 ((and (mexptp e
) (alike1 expon
(caddr e
)))
142 ((or (atom e
) (not (eq (caar e
) c
))) (matcherr))
143 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
144 (setq e
(reverse (cdr e
))) (go b
)))
147 (return (if (and (realp expon
) (minusp expon
)) 1 0)))
148 ((and (mexptp (car e
)) (alike1 expon
(caddar e
)))
152 (defun part+ (e p preds
)
153 (if (and (consp e
) (eq (caar e
) 'mplus
))
154 (part+-mplus e p preds
)
155 (part+-not-mplus e p preds
)))
157 (defun part+-not-mplus
(e p preds
)
158 (part+-mplus
(list '(mplus) 0 e
) p preds
))
160 (defun part+-mplus
(e p preds
)
161 (prog (flag saved val
)
162 (if (not (mplusp e
)) (matcherr))
163 (cond ((> (length p
) (length preds
))
165 (setq p
(nthkdr p
(- (length p
) (length preds
))))
166 (setq p
(nreverse p
))))
167 (setq e
(copy-tree e
)) ; PREVIOUSLY: (setq e ($ratexpand e))
169 a
(cond ((null p
) (cond ((null e
) (return t
)) (t (matcherr))))
170 ((and (cdr preds
) (member (car (caddar preds
)) '(msetq setq
) :test
#'eq
))
171 (cond (flag (merror (intl:gettext
"PART+: two or more pattern variables match anything.")))
172 (t (setq flag t p
(reverse p
) preds
(reverse preds
))
174 ((not (atom (car p
)))
177 loop
(cond ((null mye
) (matcherr)))
178 (setq val
(catch 'match
(mcall (car preds
) (car mye
))))
180 (setq mye
(cdr mye
)) (go loop
))
181 (t (return (setq e
(delete (car mye
) e
:count
1 :test
#'equal
))))))
183 (t (mset (car p
) 0)))
187 (cond ((null (setq val
(catch 'match
(mcall (car preds
) z
)))) nil
)
188 (t (setq saved
(add2* saved val
))
189 (setq e
(delete z e
:count
1 :test
#'equal
)))))
191 (cond ((and (equal saved
0)
192 (null (setq val
(catch 'match
(mcall (car preds
) 0)))))
195 b
(setq preds
(cdr preds
) p
(cdr p
))
198 (defun part* (e p preds
)
199 (if (and (consp e
) (eq (caar e
) 'mtimes
))
200 (part*-mtimes e p preds
)
201 (part*-not-mtimes e p preds
)))
203 (defun part*-not-mtimes
(e p preds
)
204 (part*-mtimes
(list '(mtimes) 1 e
) p preds
))
206 (defun part*-mtimes
(e p preds
)
207 (prog (flag saved val
)
208 (if (not (mtimesp e
)) (matcherr))
209 (cond ((> (length p
) (length preds
))
211 (setq p
(nthkdr p
(- (length p
) (length preds
))))
212 (setq p
(nreverse p
))))
213 (setq e
(copy-tree e
)) ; PREVIOUSLY: (setq e ($factor e))
215 a
(cond ((null p
) (cond ((null e
) (return t
)) (t (matcherr))))
216 ((and (cdr preds
) (member (car (caddar preds
)) '(msetq setq
) :test
#'eq
))
217 (cond (flag (merror (intl:gettext
"PART*: two or more pattern variables match anything.")))
218 (t (setq flag t p
(reverse p
) preds
(reverse preds
))
220 ((not (atom (car p
)))
223 loop
(cond ((null mye
) (matcherr)))
224 (setq val
(catch 'match
(mcall (car preds
) (car mye
))))
226 (setq mye
(cdr mye
)) (go loop
))
227 (t (return (setq e
(delete (car mye
) e
:count
1 :test
#'equal
))))))
229 (t (mset (car p
) 1)))
232 #'(lambda (z) (setq val
(catch 'match
(mcall (car preds
) z
)))
233 (cond ((null val
) nil
)
234 (t (setq saved
(mul2* saved val
))
235 (setq e
(delete z e
:count
1 :test
#'equal
)))))
237 (cond ((and (equal saved
1)
238 (null (setq val
(catch 'match
(mcall (car preds
) 1)))))
241 b
(setq preds
(cdr preds
) p
(cdr p
))
244 ;;; TRANSLATE property in MAXSRC;TRANS5 >
246 (defmspec $apply1
(l) (setq l
(cdr l
))
247 (let ((expr (meval (car l
))))
248 (mapc #'(lambda (z) (setq expr
(apply1 expr z
0))) (cdr l
))
251 (defun apply1 (expr *rule depth
)
253 ((> depth $maxapplydepth
) expr
)
257 (setq expr
(rule-apply *rule expr
))
259 ((or (atom expr
) (mnump expr
)) (return expr
))
260 ((eq (caar expr
) 'mrat
)
261 (setq expr
(ratdisrep expr
)) (go b
))
267 (mapcar #'(lambda (z) (apply1 z
*rule
(1+ depth
)))
271 (defmspec $applyb1
(l) (setq l
(cdr l
))
272 (let ((expr (meval (car l
))))
273 (mapc #'(lambda (z) (setq expr
(car (apply1hack expr z
)))) (cdr l
))
276 (defun apply1hack (expr *rule
)
281 ((atom expr
) (return (cons (multiple-value-bind (ans rule-hit
) (mcall *rule expr
) (if rule-hit ans expr
)) 0)))
282 ((specrepp expr
) (setq expr
(specdisrep expr
)) (go b
)))
283 (setq pairs
(mapcar #'(lambda (z) (apply1hack z
*rule
))
286 (mapc #'(lambda (l) (setq max
(max max
(cdr l
)))) pairs
)
287 (setq expr
(simplifya (cons (delsimp (car expr
))
288 (mapcar #'car pairs
))
290 (cond ((= max $maxapplyheight
) (return (cons expr max
))))
291 (setq expr
(rule-apply *rule expr
))
292 (return (cons expr
(1+ max
)))))
294 (defun *rulechk
(*rule
)
295 (if (and (symbolp *rule
) (not (fboundp *rule
)) (not (mfboundp *rule
)))
296 (merror (intl:gettext
"apply1: no such rule: ~:M") *rule
)))
298 (defun rule-apply (*rule expr
)
300 loop
(multiple-value-setq (ans rule-hit
) (mcall *rule expr
))
301 (cond ((and rule-hit
(not (alike1 ans expr
)))
302 (setq expr ans
) (go loop
)))
305 (defmspec $apply2
(l) (setq l
(cdr l
))
306 (let ((rulelist (cdr l
))) (apply2 rulelist
(meval (car l
)) 0)))
308 (defun apply2 (rulelist expr depth
)
310 ((> depth $maxapplydepth
) expr
)
312 (prog (ans ruleptr rule-hit
)
313 a
(setq ruleptr rulelist
)
317 ((atom expr
) (return expr
))
318 ((eq (caar expr
) 'mrat
)
319 (setq expr
(ratdisrep expr
)) (go b
))
325 (mapcar #'(lambda (z) (apply2 rulelist z
(1+ depth
)))
328 (cond ((progn (multiple-value-setq (ans rule-hit
) (mcall (car ruleptr
) expr
)) rule-hit
)
331 (t (setq ruleptr
(cdr ruleptr
)) (go b
)))))))
333 (defmspec $applyb2
(l) (setq l
(cdr l
))
334 (let ((rulelist (cdr l
))) (car (apply2hack rulelist
(meval (car l
))))))
336 (defun apply2hack (rulelist e
)
339 (cond ((atom e
) (return (cons (apply2 rulelist e -
1) 0)))
340 ((specrepp e
) (return (apply2hack rulelist
(specdisrep e
)))))
341 (setq pairs
(mapcar #'(lambda (x) (apply2hack rulelist x
)) (cdr e
)))
343 (mapc #'(lambda (l) (setq max
(max max
(cdr l
)))) pairs
)
344 (setq e
(simplifya (cons (delsimp (car e
)) (mapcar #'car pairs
)) t
))
345 (cond ((= max $maxapplyheight
) (return (cons e max
)))
346 (t (return (cons (apply2 rulelist e -
1) (1+ max
)))))))