1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
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 (declare-top (special $rules $maxapplyheight $maxapplydepth
))
21 ;; $MAXAPPLYDEPTH is the maximum depth within an expression to which
22 ;; APPLYi will delve. If $MAXAPPLYDEPTH is 0, it is applied only to
24 (defmvar $maxapplydepth
10000.
)
26 ;; If $MAXAPPLYHEIGHT is 0, only atoms are affected by $APPLYB1 and
28 (defmvar $maxapplyheight
10000.
)
30 (defmvar matchreverse nil
)
32 (defmspec $disprule
(l) (setq l
(cdr l
))
33 (if (and (eq (car l
) '$all
) (null (cdr l
)))
34 (disprule1 (cdr $rules
))
38 `((mlist simp
) ,@(loop for r in l collect
(cadr ($ldisp
(consrule r
))))))
41 (let ((rule (mget x
'$rule
)))
42 (if rule
(list '(msetq simp
) x
(cons '(marrow simp
) (cdr rule
)))
43 (merror (intl:gettext
"disprule: ~:M is not a user rule.") x
))))
45 (defmfun $remrule
(op rule
)
48 (cond ((not (eq rule
'$all
))
49 (removerule op rule
) (return (getop op
)))
50 ((null (setq rules
(mget op
'oldrules
)))
51 (merror (intl:gettext
"remrule: no rules known for operator ~:@M") op
)))
52 next
(cond ((or (null rules
) (null (cdr rules
)))
53 (mputprop op
1 'rulenum
) (return (getop op
)))
54 (t (removerule op
(car rules
))
55 (setq rules
(cdr rules
)) (go next
)))))
57 (defun removerule (op rule
)
58 (cond ((member rule
*builtin-$rules
* :test
#'eq
)
62 (oldrules old othrulename othrule
)
63 (setq oldrules
(mget op
'oldrules
))
64 (cond ((or (null rule
) (null (setq oldrules
(member rule oldrules
:test
#'equal
))))
65 (merror (intl:gettext
"remrule: no such rule: ~:M") rule
))
66 ((null (car (setq oldrules
(cdr oldrules
))))
67 (setq oldrules
(cdr oldrules
))
68 (setq othrulename nil
)
69 (setq othrule
#'(lambda (a bb c
) (declare (ignore bb
)) (simpargs a c
))))
70 (t (setq othrulename
(car oldrules
))
71 (setq othrule
(cadr (getl (car oldrules
) '(expr subr
))))))
72 (putprop-or-remprop rule othrule
'expr
)
73 (setq old
(cdr (member rule
(reverse (mget op
'oldrules
)) :test
#'equal
)))
74 (if old
(putprop-or-remprop (car old
)
75 (subst othrulename rule
(get (car old
) 'expr
))
77 (if (boundp rule
) (makunbound rule
))
78 (mremprop rule
'$rule
)
79 (mremprop rule
'$ruletype
)
80 (mremprop rule
'ruleof
)
82 (setq $rules
(delete rule $rules
:count
1 :test
#'eq
))
83 (putprop-or-remprop rule othrulename
'expr
)
84 (if (eq (get op
'operators
) rule
)
85 (putprop-or-remprop op othrulename
'operators
))
86 (let ((l (delete rule
(mget op
'oldrules
) :test
#'eq
)))
87 (if (equal l
'(nil)) (mremprop op
'oldrules
) (mputprop op l
'oldrules
))
90 (defun putprop-or-remprop (x y z
)
96 (cond ((equal e
1) '(1 .
0))
97 ((equal e
0) '(0 .
1))
99 ((eq (caar e
) 'mexpt
) (cons (cadr e
) (caddr e
)))
102 (defun findfun (e p c
)
104 (cond ((and (null (atom e
)) (eq (caar e
) p
)) (return e
))
105 ((or (atom e
) (not (eq (caar e
) c
))) (matcherr))
106 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
107 (setq e
(reverse (cdr e
))) (go b
)))
109 b
(cond ((null e
) (matcherr))
110 ((and (not (atom (car e
))) (eq (caaar e
) p
)) (return (car e
))))
113 (defun findexpon (e1 base
* c
)
116 (cond ((and (mexptp e
) (alike1 base
* (cadr e
)))
118 ((or (atom e
) (not (eq (caar e
) c
))) (go c
))
119 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
120 (setq e
(reverse (cdr e
))) (go b
)))
122 b
(cond ((null e
) (go c
))
123 ((and (mexptp (car e
)) (alike1 base
* (cadar e
)))
124 (return (caddar e
))))
126 c
(cond ((or (and (not (atom e1
)) (member c
'(mplus mtimes
) :test
#'eq
)
127 (eq c
(caar e1
)) (memalike base
* e1
))
129 (and (not (atom base
*)) (eq c
(caar base
*))))
131 ((eq c
'mexpt
) (matcherr))
134 (defun findbase (e expon c
)
136 (cond ((equal expon
0)
137 (if (and (eq c
'mexpt
) (not (equal 1 e
))) (matcherr))
139 ((equal expon
1) (return e
))
140 ((and (numberp expon
) (> expon
0) (equal e
0))
142 ((and (mexptp e
) (alike1 expon
(caddr e
)))
144 ((or (atom e
) (not (eq (caar e
) c
))) (matcherr))
145 ((and (null matchreverse
) (member c
'(mplus mtimes
) :test
#'eq
))
146 (setq e
(reverse (cdr e
))) (go b
)))
149 (return (if (and (realp expon
) (minusp expon
)) 1 0)))
150 ((and (mexptp (car e
)) (alike1 expon
(caddar e
)))
154 (defun part+ (e p preds
)
155 (if (and (consp e
) (eq (caar e
) 'mplus
))
156 (part+-mplus e p preds
)
157 (part+-not-mplus e p preds
)))
159 (defun part+-not-mplus
(e p preds
)
160 (part+-mplus
(list '(mplus) 0 e
) p preds
))
162 (defun part+-mplus
(e p preds
)
163 (prog (flag saved val
)
164 (if (not (mplusp e
)) (matcherr))
165 (cond ((> (length p
) (length preds
))
167 (setq p
(nthkdr p
(- (length p
) (length preds
))))
168 (setq p
(nreverse p
))))
169 (setq e
(copy-tree e
)) ; PREVIOUSLY: (setq e ($ratexpand e))
171 a
(cond ((null p
) (cond ((null e
) (return t
)) (t (matcherr))))
172 ((and (cdr preds
) (member (car (caddar preds
)) '(msetq setq
) :test
#'eq
))
173 (cond (flag (merror (intl:gettext
"PART+: two or more pattern variables match anything.")))
174 (t (setq flag t p
(reverse p
) preds
(reverse preds
))
176 ((not (atom (car p
)))
179 loop
(cond ((null mye
) (matcherr)))
180 (setq val
(catch 'match
(mcall (car preds
) (car mye
))))
182 (setq mye
(cdr mye
)) (go loop
))
183 (t (return (setq e
(delete (car mye
) e
:count
1 :test
#'equal
))))))
185 (t (mset (car p
) 0)))
189 (cond ((null (setq val
(catch 'match
(mcall (car preds
) z
)))) nil
)
190 (t (setq saved
(add2* saved val
))
191 (setq e
(delete z e
:count
1 :test
#'equal
)))))
193 (cond ((and (equal saved
0)
194 (null (setq val
(catch 'match
(mcall (car preds
) 0)))))
197 b
(setq preds
(cdr preds
) p
(cdr p
))
200 (defun part* (e p preds
)
201 (if (and (consp e
) (eq (caar e
) 'mtimes
))
202 (part*-mtimes e p preds
)
203 (part*-not-mtimes e p preds
)))
205 (defun part*-not-mtimes
(e p preds
)
206 (part*-mtimes
(list '(mtimes) 1 e
) p preds
))
208 (defun part*-mtimes
(e p preds
)
209 (prog (flag saved val
)
210 (if (not (mtimesp e
)) (matcherr))
211 (cond ((> (length p
) (length preds
))
213 (setq p
(nthkdr p
(- (length p
) (length preds
))))
214 (setq p
(nreverse p
))))
215 (setq e
(copy-tree e
)) ; PREVIOUSLY: (setq e ($factor e))
217 a
(cond ((null p
) (cond ((null e
) (return t
)) (t (matcherr))))
218 ((and (cdr preds
) (member (car (caddar preds
)) '(msetq setq
) :test
#'eq
))
219 (cond (flag (merror (intl:gettext
"PART*: two or more pattern variables match anything.")))
220 (t (setq flag t p
(reverse p
) preds
(reverse preds
))
222 ((not (atom (car p
)))
225 loop
(cond ((null mye
) (matcherr)))
226 (setq val
(catch 'match
(mcall (car preds
) (car mye
))))
228 (setq mye
(cdr mye
)) (go loop
))
229 (t (return (setq e
(delete (car mye
) e
:count
1 :test
#'equal
))))))
231 (t (mset (car p
) 1)))
234 #'(lambda (z) (setq val
(catch 'match
(mcall (car preds
) z
)))
235 (cond ((null val
) nil
)
236 (t (setq saved
(mul2* saved val
))
237 (setq e
(delete z e
:count
1 :test
#'equal
)))))
239 (cond ((and (equal saved
1)
240 (null (setq val
(catch 'match
(mcall (car preds
) 1)))))
243 b
(setq preds
(cdr preds
) p
(cdr p
))
246 ;;; TRANSLATE property in MAXSRC;TRANS5 >
248 (defmspec $apply1
(l) (setq l
(cdr l
))
249 (let ((expr (meval (car l
))))
250 (mapc #'(lambda (z) (setq expr
(apply1 expr z
0))) (cdr l
))
253 (defun apply1 (expr *rule depth
)
255 ((> depth $maxapplydepth
) expr
)
259 (setq expr
(rule-apply *rule expr
))
261 ((or (atom expr
) (mnump expr
)) (return expr
))
262 ((eq (caar expr
) 'mrat
)
263 (setq expr
(ratdisrep expr
)) (go b
))
269 (mapcar #'(lambda (z) (apply1 z
*rule
(1+ depth
)))
273 (defmspec $applyb1
(l) (setq l
(cdr l
))
274 (let ((expr (meval (car l
))))
275 (mapc #'(lambda (z) (setq expr
(car (apply1hack expr z
)))) (cdr l
))
278 (defun apply1hack (expr *rule
)
283 ((atom expr
) (return (cons (multiple-value-bind (ans rule-hit
) (mcall *rule expr
) (if rule-hit ans expr
)) 0)))
284 ((specrepp expr
) (setq expr
(specdisrep expr
)) (go b
)))
285 (setq pairs
(mapcar #'(lambda (z) (apply1hack z
*rule
))
288 (mapc #'(lambda (l) (setq max
(max max
(cdr l
)))) pairs
)
289 (setq expr
(simplifya (cons (delsimp (car expr
))
290 (mapcar #'car pairs
))
292 (cond ((= max $maxapplyheight
) (return (cons expr max
))))
293 (setq expr
(rule-apply *rule expr
))
294 (return (cons expr
(1+ max
)))))
296 (defun *rulechk
(*rule
)
297 (if (and (symbolp *rule
) (not (fboundp *rule
)) (not (mfboundp *rule
)))
298 (merror (intl:gettext
"apply1: no such rule: ~:M") *rule
)))
300 (defun rule-apply (*rule expr
)
302 loop
(multiple-value-setq (ans rule-hit
) (mcall *rule expr
))
303 (cond ((and rule-hit
(not (alike1 ans expr
)))
304 (setq expr ans
) (go loop
)))
307 (defmspec $apply2
(l) (setq l
(cdr l
))
308 (let ((rulelist (cdr l
))) (apply2 rulelist
(meval (car l
)) 0)))
310 (defun apply2 (rulelist expr depth
)
312 ((> depth $maxapplydepth
) expr
)
314 (prog (ans ruleptr rule-hit
)
315 a
(setq ruleptr rulelist
)
319 ((atom expr
) (return expr
))
320 ((eq (caar expr
) 'mrat
)
321 (setq expr
(ratdisrep expr
)) (go b
))
327 (mapcar #'(lambda (z) (apply2 rulelist z
(1+ depth
)))
330 (cond ((progn (multiple-value-setq (ans rule-hit
) (mcall (car ruleptr
) expr
)) rule-hit
)
333 (t (setq ruleptr
(cdr ruleptr
)) (go b
)))))))
335 (defmspec $applyb2
(l) (setq l
(cdr l
))
336 (let ((rulelist (cdr l
))) (car (apply2hack rulelist
(meval (car l
))))))
338 (defun apply2hack (rulelist e
)
341 (cond ((atom e
) (return (cons (apply2 rulelist e -
1) 0)))
342 ((specrepp e
) (return (apply2hack rulelist
(specdisrep e
)))))
343 (setq pairs
(mapcar #'(lambda (x) (apply2hack rulelist x
)) (cdr e
)))
345 (mapc #'(lambda (l) (setq max
(max max
(cdr l
)))) pairs
)
346 (setq e
(simplifya (cons (delsimp (car e
)) (mapcar #'car pairs
)) t
))
347 (cond ((= max $maxapplyheight
) (return (cons e max
)))
348 (t (return (cons (apply2 rulelist e -
1) (1+ max
)))))))