1 ;;; -*- Mode:Lisp; Package:CL-MAXIMA; Syntax:COMMON-LISP; Base:10 -*-
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ;;; Copyright (c) 1984 by William Schelter,University of Texas ;;;;;
5 ;;; All rights reserved ;;;;;
6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10 (defmacro iassert
(expr)
11 `(cond ((null ,expr
) (fsignal "The expression ~A was not true" ',expr
))))
13 (defun alphagreatp (x y
)
14 (and (not (alphalessp x y
)) (not (equal x y
))))
16 (defun $monomial_alphalessp
(x y
)
18 (cond ((atom y
) (alphalessp x y
))
19 ((null (cdr y
)) (alphalessp x
(car y
) ))
22 (t (alphalessp x
(cadr y
)))))
24 (cond ((null (cdr x
)) (alphalessp (car x
) y
)) ;x cannot be an atom here
25 (t (alphalessp (cadr x
) y
))))
27 (alphalessp (cdr x
) (cdr y
)))))
29 (defun $monomial_alphagreatp
(x y
)
30 (not (or (equal x y
) ($monomial_alphalessp x y
))))
32 (defun $power_series_monomial_alphalessp
(x y
)
33 (cond ((equal x y
) nil
)
35 (let ((x-deg ($nc_degree x
:order-weight
))(y-deg ($nc_degree y
:order-weight
)))
36 (cond ((eql x-deg y-deg
)($monomial_alphalessp x y
))
37 ((zerop y-deg
) (not (zerop x-deg
)))
42 (defun $polynomial_monomial_alphalessp
(x y
)
43 (cond ((equal x y
) nil
)
45 (let ((x-deg ($nc_degree x
:order-weight
))(y-deg ($nc_degree y
:order-weight
)))
46 (cond ((eql x-deg y-deg
)($monomial_alphalessp x y
))
47 ((zerop x-deg
) (not (zerop y-deg
)))
52 (defun fix-optional (args &aux
(tem (copy-list args
)))
55 when
(member (car v
) '(&optional
&key
))
56 do
(loop for w on
(cdr v
)
57 until
(and (atom (car w
)) (search "&" (string (car w
)) :test
#'char-equal
))
60 else do
(setq tem
(caar w
))
61 when
(eq (car v
) '&key
)
62 collecting
(intern (string-upcase (string tem
)) 'keyword
) into opts
63 collecting tem into opts
65 (setq args
(append (subseq args
0 i
) opts
(cdr w
)))(return 'done
))
69 (defun delete-from-&aux
(list)
72 when
(eq u
'&aux
) do
(return (subseq list
0 (1- i
)))
73 finally
(return list
)))
75 (defun clear-memory-function (f &aux tem
)
76 (cond ((setq tem
(get f
':memory-table
))
79 (defmacro defremember
(func-spec arglist
&rest body
80 &aux hash-args hash-put-args
(call-arglist (copy-list arglist
)))
81 "Like defun but defines function foo that remembers previous calls to
82 it it unless the calls were made while (disable-remember foo) until
83 (enable-remember foo) is done. To clear memory do (clear-hash (get 'foo
84 :memory-table)) . Redefining clears memory. The equal-hash table is
85 stored as the :memory-table property of foo. also it is useful to
86 use as optional arguments of global variables or other data not
87 included in the arguments upon which the function call depends. These
88 will then become part of the argument."
90 (cond ((get func-spec
:memory-table
)
91 (clrhash (get func-spec
:memory-table
))))
92 (remprop func-spec
:dont-remember
)
93 ;; (show call-arglist)
95 (setq call-arglist
(fix-optional(delete-from-&aux call-arglist
)))
96 (cond ((member '&aux call-arglist
:test
#'eq
)
97 (format t
"~%It is inadvisable to use &aux with defremember")))
98 ;; (show call-arglist)
99 (cond ((equal (length arglist
) 1)(setq hash-put-args
(setq hash-args
(car arglist
))))
100 ((equal (car arglist
) '&rest
) (setq hash-args
(second arglist
))
101 (setq hash-put-args
`(copy-list ,(second arglist
)))
102 (setq call-arglist
(second arglist
)))
103 ((member '&rest arglist
:test
#'eq
) (setq hash-args
`(list ,@ (DELETE '&rest call-arglist
)))
104 (setq hash-put-args
(copy-list hash-args
))
105 (setf (nth (1- (length hash-put-args
)) hash-put-args
)
106 `(copy-list ,(car (last hash-put-args
)))))
107 (t (setq hash-put-args
(setq hash-args
(cons 'list call-arglist
)))))
108 `(defun ,func-spec
,arglist
109 (cond ((null (get ',func-spec
:dont-remember
))
110 (let (hash-table ans
)
111 (cond ((setq hash-table
(get ',func-spec
:memory-table
))
112 (cond ((setq ans
(gethash ,hash-args hash-table
)) ans
)
113 (t (setq ans
(progn ,@ body
))
114 (setf (gethash ,hash-put-args hash-table
) ans
)
116 (t (setf (get ',func-spec
:memory-table
)
117 (make-hash-table :test
'equal
)
119 ,(cond ((member '&rest arglist
:test
#'eq
)
120 `(apply ',func-spec
,@
122 (copy-list call-arglist
))))
123 (t `(,func-spec
,@ call-arglist
)))))))
124 (t (progn ,@ body
)))))
126 (defmacro disable-remember
(f)
127 `(putprop ',f t
:dont-remember
))
129 (defmacro enable-remember
(f)
130 `(remprop ',f
:dont-remember
))
132 (defmacro function-let
(alist &body body
&aux sym
)
135 do
(setq sym
(gensym))
136 collecting sym into locals
137 collecting
`(setq ,sym
(symbol-function ',(first v
))) into initial
138 collecting
`(setf (symbol-function ',(first v
))
139 (symbol-function ',(second v
))) into initial
140 collecting
`(cond (,sym
(setf (symbol-function ',(first v
)) ,sym
))) into protects
141 finally
(return `(let ,locals
147 (defmacro with-no-query
(&rest body
)
148 `(function-let ((fquery no-query-aux
)) ,@body
))
150 (defmacro with-no-query-answer-no
(&rest body
)
151 `(function-let ((fquery (lambda (ignore ctrl
&rest args
) (apply 'format t ctrl args
) nil
))) ,@body
))
153 (defmacro find-minimal
(in-list ordering
&optional such-that ind
)
155 (cond ((functionp such-that
)(setq ind
'-ind-
)
156 (setq such-that
`(,such-that -ind-
)))
158 (check-arg ind
(not (null ind
)) "non nil. Must specify index")))
159 ` (loop for
,ind in
,in-list
163 (cond ((funcall ,ordering
,ind prev-min
)
164 (setq prev-min
,ind
))))
165 (t (setq prev-min
,ind
)))
166 finally
(return prev-min
)))
167 (t `(loop for v in
,in-list
170 (cond ((funcall , ordering v prev-min
)
172 (t (setq prev-min v
)))
173 finally
(return prev-min
)))))
175 (defmacro user-supply
(var)
176 `(setq ,var
(user-supply1 ',var
,var
)))
178 (defun user-supply1 (var val
)
179 (let ((*print-level
* 3)
183 (format t
"~%The value of ~A is ~A ." var val
)
184 (format t
"~%Supply a form to evaluate to use for ~A or hit return to keep same :" var
)
185 (setq .ch.
(read-char *standard-input
*))
186 (cond ((eql .ch.
#\newline
)
188 (t (unread-char .ch.
*standard-input
*)))
189 (setq .new.
(eval (read)))
190 (cond ((eq .new.
'keep
)
193 (format t
"~%Use ~A?" .new.
)
195 (return (setq var .new.
)))))))))
197 (defvar *timed-process-priority
* 1)
199 (defmacro tim
(&rest body
)
200 `(time (progn ,@body
)))
202 ;;Idea is that you have two function definitions possibly with the
203 ;;same name, and lots of places where the first one is called.
204 ;;you may want to replace the first function with the second one
205 ;;and think you have the definition correct. You want to compare
206 ;;the speed and whether they work the same. So wrap
207 ;;compare-functions around the two definitions, then it will compare
208 ;;them as to speed (and value) in the applications. It might be reasonable to implement
209 ;;this as an emacs macro wrapping it around a region.
211 (defmacro compare-functions
(defa defb
&rest assertions
)
214 (.assert.
(loop for v in assertions
215 collecting
`(iassert ,v
) into tem
217 (return (cons `(iassert (equal .ansa. .ansb.
)) tem
)))))
218 (check-arg defa
(eq (car defa
) 'defun
) "Should be a defun")
220 (setq defb
`(defun ,(string-append defb
(symbol-name '#:-compare
)) (&rest .l.
)
221 (apply ',defb .l.
)))))
222 (setq .fa.
(intern (string-append (second defa
) (symbol-name '#:-a
))))
223 (setq .fb.
(intern (string-append (second defb
) (symbol-name '#:-b
))))
224 (setq .boda.
(subst .fa.
(second defa
) (cdddr defa
)))
225 (setq .bodb.
(subst .fb.
(second defb
) (cdddr defb
)))
227 (defun , .fa.
,(third defa
)
229 (defun , .fb.
,(third defb
)
231 (defun ,(second defa
)
233 (declare (arglist ,.
(loop for v in
(third defa
)
234 until
(eq v
'&aux
) collecting v
)))
236 (format t
"~%Comparing the functions ~A and ~A " ', .fa.
', .fb.
)
238 (multiple-value-list (apply ', .fa.
(copy-list l
))))
239 (setq .ansb.
(multiple-value-list (apply ', .fb.
(copy-list l
))))
241 (apply 'values .ansa.
))))))
243 (defmacro compare-recursive-functions
(fn-a fn-b
&rest assertions
)
247 , `(compare-functions
248 (defun ,(intern (string-append (second fn-a
) (symbol-name '#:-compare
))) ,@ (cddr fn-a
))
249 (defun ,(intern (string-append (second fn-b
) (symbol-name '#:-compare
))) ,@ (cddr fn-b
))
252 ;;sample usage of compare-recursive-functions
253 ;(compare-recursive-functions
254 ; (defun my-pgcd (f g) ...
256 ; (my-pgcd (cof f) ..))
261 ;;then to invoke the comparison call
262 ;;(my-pgcd-compare u v) and it will calculate the gcd using the two methods check they
263 ;;are equal (or check other assertions you specify) and print the time spent
264 ;;in my-pgcd-compare-a and in my-pgcd-compare-b
267 ;(defun ff (u &optional v)
274 ;(defun ff (u &optional v)
275 ; (values (+ u v) u))
276 ;(defun ff (u &optional v)
277 ; (values (+ v u) v))
279 ;;then if you run some functions that call ff it will give the comparison
280 ;;note that ff and gg may have the same name
284 (defun write-object (filename obj
)
285 (with-open-file (st filename
:direction
:output
)
286 (format st
"~A" obj
)))
288 (defstruct (s-var (:type list
) :named
(:conc-name sv-
))
289 zopens
) ;; list of open sets
291 (defmacro set-slots
(struct conc-prefix
&rest alt-list
)
292 (loop for v on alt-list by
#'cddr
293 collecting
`(setf ( ,(intern (format nil
"~a~a" conc-prefix
(car v
))) ,struct
) ,(second v
))
295 finally
(return (cons 'progn tem
))))
297 ;; Note that ZL-COPY-STRUCTURE works only for structures which are
298 ;; represented by lists. The `ZL' is just for analogy with other private
299 ;; versions of list related functions in Maxima and no reference to any
300 ;; historical version of Lisp is intended.
301 (defmacro zl-copy-structure
(struct conc-prefix
&rest alt-list
)
302 ` (let (( .ans.
(copy-list ,struct
)))
303 (set-slots .ans.
,conc-prefix
,@ alt-list
)
306 ;(defstruct (s-var (:type list ) :named (:conc-name sv-))
307 ; zopens ;; list of open sets
308 ; ;; a list of opens each having its intersection slot specified
310 ; ;;glueing: for each element of the intersections will have a
311 ; ;;a list of maps between elements of intersections
312 ; ;;so that the map from that element to the reverse intersection
316 (defstruct (pre-ldata-sheaves (:type list
) :named
(:conc-name pls-
))
318 ;;for each open a list of ldata
321 (defstruct (ldata (:type list
) :named
(:conc-name ldata-
))
328 (defstruct (rmap (:type list
) :named
(:conc-name rmap-
))
332 (defstruct (zopen (:type list
) :named
(:conc-name zopen-
))
340 (defstruct (variable-correspondence :named
(:conc-name vc-
))
345 (defstruct (ideal :named
(:conc-name ideal-
))
349 variable-correspondence
)
351 (defstruct ( polynomial-vectors
:named
(:conc-name pv-
))
352 length-of-array-of-tables
354 (constants-column-number nil
)
356 (type-of-entries :integer
)
358 (verify-conversion nil
)
362 number-of-independent-terms
;;never occurs
363 solution-in-macsyma-format
370 (defstruct (poly-data :named
(:conc-name pd-
))
373 segments
;;beginning of each new group of monoms in big-monom-list
376 (defmacro gshow
(form)
377 `(progn (format t
"~%The value of ~A is" ',form
)
378 (grind-top-level ,form
)))
380 (defmacro mshow
(&rest l
)
382 collecting
`(format t
"~%The value of ~A is.. " ',v
) into tem
383 collecting
`(des ,v
) into tem
384 finally
(return (cons 'progn tem
))))
386 (defmacro ncmul
* (&rest factors
)
387 (cond ((= (length factors
) 2) `(ncmul2* .
,factors
))
388 (t `(ncmuln (list .
,factors
) nil
))))
390 (defstruct (matrix (:type list
) :named
(:conc-name matrix-
))
391 rows
) ;; list of open sets
393 ;(defmacro matrix-p (mat)
394 ; `(and (listp ,mat) (eq (car ,mat) 'matrix)))
396 (defvar *verbose-check-overlaps
* nil
)
398 (defmacro if-verbose
(&rest l
)
399 `(when *verbose-check-overlaps
* ,@l
))