home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / gnucalc / part24 < prev    next >
Encoding:
Text File  |  1991-10-31  |  55.3 KB  |  1,905 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@synaptics.com (David Gillespie)
  3. Subject:  v24i072:  gnucalc - GNU Emacs Calculator, v2.00, Part24/56
  4. Message-ID: <1991Oct31.072739.18175@sparky.imd.sterling.com>
  5. X-Md4-Signature: 73e94080579af1b29e16619cb5083d9d
  6. Date: Thu, 31 Oct 1991 07:27:39 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: daveg@synaptics.com (David Gillespie)
  10. Posting-number: Volume 24, Issue 72
  11. Archive-name: gnucalc/part24
  12. Environment: Emacs
  13. Supersedes: gmcalc: Volume 13, Issue 27-45
  14.  
  15. ---- Cut Here and unpack ----
  16. #!/bin/sh
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file calc-prog.el continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 24; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping calc-prog.el'
  34. else
  35. echo 'x - continuing file calc-prog.el'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'calc-prog.el' &&
  37. X           (assq (downcase key) (calc-user-key-map))
  38. X           (error "No command defined for that key")))
  39. X      (cmd (cdr def)))
  40. X     (if (symbolp cmd)
  41. X     (setq cmd (symbol-function cmd)))
  42. X     (cond ((stringp cmd)
  43. X        (message "Keyboard macro: %s" cmd))
  44. X       (t (let* ((func (calc-stack-command-p cmd))
  45. X             (defn (and func
  46. X                (symbolp func)
  47. X                (get func 'calc-user-defn))))
  48. X        (if defn
  49. X            (progn
  50. X              (and (calc-valid-formula-func func)
  51. X               (setq defn (append '(calcFunc-lambda)
  52. X                          (mapcar 'math-build-var-name
  53. X                              (nth 1 (symbol-function
  54. X                                  func)))
  55. X                          (list defn))))
  56. X              (calc-enter-result 0 "gdef" defn))
  57. X          (error "That command is not defined by a formula")))))))
  58. )
  59. X
  60. X
  61. (defun calc-user-define-permanent ()
  62. X  (interactive)
  63. X  (calc-wrapper
  64. X   (message "Record in %s the command: z-" calc-settings-file)
  65. X   (let* ((key (read-char))
  66. X      (def (or (assq key (calc-user-key-map))
  67. X           (assq (upcase key) (calc-user-key-map))
  68. X           (assq (downcase key) (calc-user-key-map))
  69. X           (and (eq key ?\') 
  70. X            (cons nil
  71. X                  (intern (completing-read
  72. X                       (format "Record in %s the function: "
  73. X                           calc-settings-file)
  74. X                       obarray 'fboundp nil "calcFunc-"))))
  75. X           (error "No command defined for that key"))))
  76. X     (set-buffer (find-file-noselect (substitute-in-file-name
  77. X                      calc-settings-file)))
  78. X     (goto-char (point-max))
  79. X     (let* ((cmd (cdr def))
  80. X        (fcmd (and cmd (symbolp cmd) (symbol-function cmd)))
  81. X        (func nil)
  82. X        (pt (point))
  83. X        (fill-column 70)
  84. X        (fill-prefix nil)
  85. X        str q-ok)
  86. X       (insert "\n;;; Definition stored by Calc on " (current-time-string)
  87. X           "\n(put 'calc-define '"
  88. X           (if (symbolp cmd) (symbol-name cmd) (format "key%d" key))
  89. X           " '(progn\n")
  90. X       (if (and fcmd
  91. X        (eq (car-safe fcmd) 'lambda)
  92. X        (get cmd 'calc-user-defn))
  93. X       (let ((pt (point)))
  94. X         (and (eq (car-safe (nth 3 fcmd)) 'calc-execute-kbd-macro)
  95. X          (vectorp (nth 1 (nth 3 fcmd)))
  96. X          (progn (and (fboundp 'edit-kbd-macro)
  97. X                  (edit-kbd-macro nil))
  98. X             (fboundp 'MacEdit-parse-keys))
  99. X          (setq q-ok t)
  100. X          (aset (nth 1 (nth 3 fcmd)) 1 nil))
  101. X         (insert (setq str (prin1-to-string
  102. X                (cons 'defun (cons cmd (cdr fcmd)))))
  103. X             "\n")
  104. X         (or (and (string-match "\"" str) (not q-ok))
  105. X         (fill-region pt (point)))
  106. X         (indent-rigidly pt (point) 2)
  107. X         (delete-region pt (1+ pt))
  108. X         (insert " (put '" (symbol-name cmd)
  109. X             " 'calc-user-defn '"
  110. X             (prin1-to-string (get cmd 'calc-user-defn))
  111. X             ")\n")
  112. X         (setq func (calc-stack-command-p cmd))
  113. X         (let ((ffunc (and func (symbolp func) (symbol-function func)))
  114. X           (pt (point)))
  115. X           (and ffunc
  116. X            (eq (car-safe ffunc) 'lambda)
  117. X            (get func 'calc-user-defn)
  118. X            (progn
  119. X              (insert (setq str (prin1-to-string
  120. X                     (cons 'defun (cons func
  121. X                                (cdr ffunc)))))
  122. X                  "\n")
  123. X              (or (and (string-match "\"" str) (not q-ok))
  124. X              (fill-region pt (point)))
  125. X              (indent-rigidly pt (point) 2)
  126. X              (delete-region pt (1+ pt))
  127. X              (setq pt (point))
  128. X              (insert "(put '" (symbol-name func)
  129. X                  " 'calc-user-defn '"
  130. X                  (prin1-to-string (get func 'calc-user-defn))
  131. X                  ")\n")
  132. X              (fill-region pt (point))
  133. X              (indent-rigidly pt (point) 2)
  134. X              (delete-region pt (1+ pt))))))
  135. X     (and (stringp fcmd)
  136. X          (insert " (fset '" (prin1-to-string cmd)
  137. X              " " (prin1-to-string fcmd) ")\n")))
  138. X       (or func (setq func (and cmd (symbolp cmd) (fboundp cmd) cmd)))
  139. X       (if (get func 'math-compose-forms)
  140. X       (let ((pt (point)))
  141. X         (insert "(put '" (symbol-name cmd)
  142. X             " 'math-compose-forms '"
  143. X             (prin1-to-string (get func 'math-compose-forms))
  144. X             ")\n")
  145. X         (fill-region pt (point))
  146. X         (indent-rigidly pt (point) 2)
  147. X         (delete-region pt (1+ pt))))
  148. X       (if (car def)
  149. X       (insert " (define-key calc-mode-map "
  150. X           (prin1-to-string (concat "z" (char-to-string key)))
  151. X           " '"
  152. X           (prin1-to-string cmd)
  153. X           ")\n")))
  154. X     (insert "))\n")
  155. X     (save-buffer)))
  156. )
  157. X
  158. (defun calc-stack-command-p (cmd)
  159. X  (if (and cmd (symbolp cmd))
  160. X      (and (fboundp cmd)
  161. X       (calc-stack-command-p (symbol-function cmd)))
  162. X    (and (consp cmd)
  163. X     (eq (car cmd) 'lambda)
  164. X     (setq cmd (or (assq 'calc-wrapper cmd)
  165. X               (assq 'calc-slow-wrapper cmd)))
  166. X     (setq cmd (assq 'calc-enter-result cmd))
  167. X     (memq (car (nth 3 cmd)) '(cons list))
  168. X     (eq (car (nth 1 (nth 3 cmd))) 'quote)
  169. X     (nth 1 (nth 1 (nth 3 cmd)))))
  170. )
  171. X
  172. X
  173. (defun calc-call-last-kbd-macro (arg)
  174. X  (interactive "P")
  175. X  (and defining-kbd-macro
  176. X       (error "Can't execute anonymous macro while defining one"))
  177. X  (or last-kbd-macro
  178. X      (error "No kbd macro has been defined"))
  179. X  (calc-execute-kbd-macro last-kbd-macro arg)
  180. )
  181. X
  182. (defun calc-execute-kbd-macro (mac arg &rest prefix)
  183. X  (if (vectorp mac)
  184. X      (setq mac (or (aref mac 1)
  185. X            (aset mac 1 (progn (and (fboundp 'edit-kbd-macro)
  186. X                        (edit-kbd-macro nil))
  187. X                       (MacEdit-parse-keys (aref mac 0)))))))
  188. X  (if (< (prefix-numeric-value arg) 0)
  189. X      (execute-kbd-macro mac (- (prefix-numeric-value arg)))
  190. X    (if calc-executing-macro
  191. X    (execute-kbd-macro mac arg)
  192. X      (calc-slow-wrapper
  193. X       (let ((old-stack-whole (copy-sequence calc-stack))
  194. X         (old-stack-top calc-stack-top)
  195. X         (old-buffer-size (buffer-size))
  196. X         (old-refresh-count calc-refresh-count))
  197. X     (unwind-protect
  198. X         (let ((calc-executing-macro mac))
  199. X           (execute-kbd-macro mac arg))
  200. X       (calc-select-buffer)
  201. X       (let ((new-stack (reverse calc-stack))
  202. X         (old-stack (reverse old-stack-whole)))
  203. X         (while (and new-stack old-stack
  204. X             (equal (car new-stack) (car old-stack)))
  205. X           (setq new-stack (cdr new-stack)
  206. X             old-stack (cdr old-stack)))
  207. X         (or (equal prefix '(nil))
  208. X         (calc-record-list (if (> (length new-stack) 1)
  209. X                       (mapcar 'car new-stack)
  210. X                     '(""))
  211. X                   (or (car prefix) "kmac")))
  212. X         (calc-record-undo (list 'set 'saved-stack-top old-stack-top))
  213. X         (and old-stack
  214. X          (calc-record-undo (list 'pop 1 (mapcar 'car old-stack))))
  215. X         (let ((calc-stack old-stack-whole)
  216. X           (calc-stack-top 0))
  217. X           (calc-cursor-stack-index (length old-stack)))
  218. X         (if (and (= old-buffer-size (buffer-size))
  219. X              (= old-refresh-count calc-refresh-count))
  220. X         (let ((buffer-read-only nil))
  221. X           (delete-region (point) (point-max))
  222. X           (while new-stack
  223. X             (calc-record-undo (list 'push 1))
  224. X             (insert (math-format-stack-value (car new-stack)) "\n")
  225. X             (setq new-stack (cdr new-stack)))
  226. X           (calc-renumber-stack))
  227. X           (while new-stack
  228. X         (calc-record-undo (list 'push 1))
  229. X         (setq new-stack (cdr new-stack)))
  230. X           (calc-refresh))
  231. X         (calc-record-undo (list 'set 'saved-stack-top 0))))))))
  232. )
  233. X
  234. (defun calc-push-list-in-macro (vals m sels)
  235. X  (let ((entry (list (car vals) 1 (car sels)))
  236. X    (mm (+ (or m 1) calc-stack-top)))
  237. X    (if (> mm 1)
  238. X    (setcdr (nthcdr (- mm 2) calc-stack)
  239. X        (cons entry (nthcdr (1- mm) calc-stack)))
  240. X      (setq calc-stack (cons entry calc-stack))))
  241. )
  242. X
  243. (defun calc-pop-stack-in-macro (n mm)
  244. X  (if (> mm 1)
  245. X      (setcdr (nthcdr (- mm 2) calc-stack)
  246. X          (nthcdr (+ n mm -1) calc-stack))
  247. X    (setq calc-stack (nthcdr n calc-stack)))
  248. )
  249. X
  250. X
  251. (defun calc-kbd-if ()
  252. X  (interactive)
  253. X  (calc-wrapper
  254. X   (let ((cond (calc-top-n 1)))
  255. X     (calc-pop-stack 1)
  256. X     (if (math-is-true cond)
  257. X     (if defining-kbd-macro
  258. X         (message "If true..."))
  259. X       (if defining-kbd-macro
  260. X       (message "Condition is false; skipping to Z: or Z] ..."))
  261. X       (calc-kbd-skip-to-else-if t))))
  262. )
  263. X
  264. (defun calc-kbd-else-if ()
  265. X  (interactive)
  266. X  (calc-kbd-if)
  267. )
  268. X
  269. (defun calc-kbd-skip-to-else-if (else-okay)
  270. X  (let ((count 0)
  271. X    ch)
  272. X    (while (>= count 0)
  273. X      (setq ch (read-char))
  274. X      (if (= ch -1)
  275. X      (error "Unterminated Z[ in keyboard macro"))
  276. X      (if (= ch ?Z)
  277. X      (progn
  278. X        (setq ch (read-char))
  279. X        (cond ((= ch ?\[)
  280. X           (setq count (1+ count)))
  281. X          ((= ch ?\])
  282. X           (setq count (1- count)))
  283. X          ((= ch ?\:)
  284. X           (and (= count 0)
  285. X            else-okay
  286. X            (setq count -1)))
  287. X          ((eq ch 7)
  288. X           (keyboard-quit))))))
  289. X    (and defining-kbd-macro
  290. X     (if (= ch ?\:)
  291. X         (message "Else...")
  292. X       (message "End-if..."))))
  293. )
  294. X
  295. (defun calc-kbd-end-if ()
  296. X  (interactive)
  297. X  (if defining-kbd-macro
  298. X      (message "End-if..."))
  299. )
  300. X
  301. (defun calc-kbd-else ()
  302. X  (interactive)
  303. X  (if defining-kbd-macro
  304. X      (message "Else; skipping to Z] ..."))
  305. X  (calc-kbd-skip-to-else-if nil)
  306. )
  307. X
  308. X
  309. (defun calc-kbd-repeat ()
  310. X  (interactive)
  311. X  (let (count)
  312. X    (calc-wrapper
  313. X     (setq count (math-trunc (calc-top-n 1)))
  314. X     (or (Math-integerp count)
  315. X     (error "Count must be an integer"))
  316. X     (if (Math-integer-negp count)
  317. X     (setq count 0))
  318. X     (or (integerp count)
  319. X     (setq count 1000000))
  320. X     (calc-pop-stack 1))
  321. X    (calc-kbd-loop count))
  322. )
  323. X
  324. (defun calc-kbd-for (dir)
  325. X  (interactive "P")
  326. X  (let (init final)
  327. X    (calc-wrapper
  328. X     (setq init (calc-top-n 2)
  329. X       final (calc-top-n 1))
  330. X     (or (and (math-anglep init) (math-anglep final))
  331. X     (error "Initial and final values must be real numbers"))
  332. X     (calc-pop-stack 2))
  333. X    (calc-kbd-loop nil init final (and dir (prefix-numeric-value dir))))
  334. )
  335. X
  336. (defun calc-kbd-loop (rpt-count &optional initial final dir)
  337. X  (interactive "P")
  338. X  (setq rpt-count (if rpt-count (prefix-numeric-value rpt-count) 1000000))
  339. X  (let* ((count 0)
  340. X     (parts nil)
  341. X     (body "")
  342. X     (open last-command-char)
  343. X     (counter initial)
  344. X     ch)
  345. X    (or executing-macro
  346. X    (message "Reading loop body..."))
  347. X    (while (>= count 0)
  348. X      (setq ch (read-char))
  349. X      (if (= ch -1)
  350. X      (error "Unterminated Z%c in keyboard macro" open))
  351. X      (if (= ch ?Z)
  352. X      (progn
  353. X        (setq ch (read-char)
  354. X          body (concat body "Z" (char-to-string ch)))
  355. X        (cond ((memq ch '(?\< ?\( ?\{))
  356. X           (setq count (1+ count)))
  357. X          ((memq ch '(?\> ?\) ?\}))
  358. X           (setq count (1- count)))
  359. X          ((and (= ch ?/)
  360. X            (= count 0))
  361. X           (setq parts (nconc parts (list (substring body 0 -2)))
  362. X             body ""))
  363. X          ((eq ch 7)
  364. X           (keyboard-quit))))
  365. X    (setq body (concat body (char-to-string ch)))))
  366. X    (if (/= ch (cdr (assq open '( (?\< . ?\>) (?\( . ?\)) (?\{ . ?\}) ))))
  367. X    (error "Mismatched Z%c and Z%c in keyboard macro" open ch))
  368. X    (or executing-macro
  369. X    (message "Looping..."))
  370. X    (setq body (substring body 0 -2))
  371. X    (and (not executing-macro)
  372. X     (= rpt-count 1000000)
  373. X     (null parts)
  374. X     (null counter)
  375. X     (progn
  376. X       (message "Warning: Infinite loop!  Not executing.")
  377. X       (setq rpt-count 0)))
  378. X    (or (not initial) dir
  379. X    (setq dir (math-compare final initial)))
  380. X    (calc-wrapper
  381. X     (while (> rpt-count 0)
  382. X       (let ((part parts))
  383. X     (if counter
  384. X         (if (cond ((eq dir 0) (Math-equal final counter))
  385. X               ((eq dir 1) (Math-lessp final counter))
  386. X               ((eq dir -1) (Math-lessp counter final)))
  387. X         (setq rpt-count 0)
  388. X           (calc-push counter)))
  389. X     (while (and part (> rpt-count 0))
  390. X       (execute-kbd-macro (car part))
  391. X       (if (math-is-true (calc-top-n 1))
  392. X           (setq rpt-count 0)
  393. X         (setq part (cdr part)))
  394. X       (calc-pop-stack 1))
  395. X     (if (> rpt-count 0)
  396. X         (progn
  397. X           (execute-kbd-macro body)
  398. X           (if counter
  399. X           (let ((step (calc-top-n 1)))
  400. X             (calc-pop-stack 1)
  401. X             (setq counter (calcFunc-add counter step)))
  402. X         (setq rpt-count (1- rpt-count))))))))
  403. X    (or executing-macro
  404. X    (message "Looping...done")))
  405. )
  406. X
  407. (defun calc-kbd-end-repeat ()
  408. X  (interactive)
  409. X  (error "Unbalanced Z> in keyboard macro")
  410. )
  411. X
  412. (defun calc-kbd-end-for ()
  413. X  (interactive)
  414. X  (error "Unbalanced Z) in keyboard macro")
  415. )
  416. X
  417. (defun calc-kbd-end-loop ()
  418. X  (interactive)
  419. X  (error "Unbalanced Z} in keyboard macro")
  420. )
  421. X
  422. (defun calc-kbd-break ()
  423. X  (interactive)
  424. X  (calc-wrapper
  425. X   (let ((cond (calc-top-n 1)))
  426. X     (calc-pop-stack 1)
  427. X     (if (math-is-true cond)
  428. X     (error "Keyboard macro aborted."))))
  429. )
  430. X
  431. X
  432. (defun calc-kbd-push (arg)
  433. X  (interactive "P")
  434. X  (calc-wrapper
  435. X   (let* ((defs (and arg (> (prefix-numeric-value arg) 0)))
  436. X      (var-q0 (and (boundp 'var-q0) var-q0))
  437. X      (var-q1 (and (boundp 'var-q1) var-q1))
  438. X      (var-q2 (and (boundp 'var-q2) var-q2))
  439. X      (var-q3 (and (boundp 'var-q3) var-q3))
  440. X      (var-q4 (and (boundp 'var-q4) var-q4))
  441. X      (var-q5 (and (boundp 'var-q5) var-q5))
  442. X      (var-q6 (and (boundp 'var-q6) var-q6))
  443. X      (var-q7 (and (boundp 'var-q7) var-q7))
  444. X      (var-q8 (and (boundp 'var-q8) var-q8))
  445. X      (var-q9 (and (boundp 'var-q9) var-q9))
  446. X      (calc-internal-prec (if defs 12 calc-internal-prec))
  447. X      (calc-word-size (if defs 32 calc-word-size))
  448. X      (calc-angle-mode (if defs 'deg calc-angle-mode))
  449. X      (calc-simplify-mode (if defs nil calc-simplify-mode))
  450. X      (calc-algebraic-mode (if arg nil calc-algebraic-mode))
  451. X      (calc-incomplete-algebraic-mode (if arg nil
  452. X                        calc-incomplete-algebraic-mode))
  453. X      (calc-symbolic-mode (if defs nil calc-symbolic-mode))
  454. X      (calc-matrix-mode (if defs nil calc-matrix-mode))
  455. X      (calc-prefer-frac (if defs nil calc-prefer-frac))
  456. X      (calc-complex-mode (if defs nil calc-complex-mode))
  457. X      (calc-infinite-mode (if defs nil calc-infinite-mode))
  458. X      (count 0)
  459. X      (body "")
  460. X      ch)
  461. X     (if (or executing-macro defining-kbd-macro)
  462. X     (progn
  463. X       (if defining-kbd-macro
  464. X           (message "Reading body..."))
  465. X       (while (>= count 0)
  466. X         (setq ch (read-char))
  467. X         (if (= ch -1)
  468. X         (error "Unterminated Z` in keyboard macro"))
  469. X         (if (= ch ?Z)
  470. X         (progn
  471. X           (setq ch (read-char)
  472. X             body (concat body "Z" (char-to-string ch)))
  473. X           (cond ((eq ch ?\`)
  474. X              (setq count (1+ count)))
  475. X             ((eq ch ?\')
  476. X              (setq count (1- count)))
  477. X             ((eq ch 7)
  478. X              (keyboard-quit))))
  479. X           (setq body (concat body (char-to-string ch)))))
  480. X       (if defining-kbd-macro
  481. X           (message "Reading body...done"))
  482. X       (let ((calc-kbd-push-level 0))
  483. X         (execute-kbd-macro (substring body 0 -2))))
  484. X       (let ((calc-kbd-push-level (1+ calc-kbd-push-level)))
  485. X     (message "Saving modes; type Z' to restore")
  486. X     (recursive-edit)))))
  487. )
  488. (setq calc-kbd-push-level 0)
  489. X
  490. (defun calc-kbd-pop ()
  491. X  (interactive)
  492. X  (if (> calc-kbd-push-level 0)
  493. X      (progn
  494. X    (message "Mode settings restored")
  495. X    (exit-recursive-edit))
  496. X    (error "Unbalanced Z' in keyboard macro"))
  497. )
  498. X
  499. X
  500. (defun calc-kbd-report (msg)
  501. X  (interactive "sMessage: ")
  502. X  (calc-wrapper
  503. X   (let ((executing-macro nil)
  504. X     (defining-kbd-macro nil))
  505. X     (math-working msg (calc-top-n 1))))
  506. )
  507. X
  508. (defun calc-kbd-query (msg)
  509. X  (interactive "sPrompt: ")
  510. X  (calc-wrapper
  511. X   (let ((executing-macro nil)
  512. X     (defining-kbd-macro nil))
  513. X     (calc-alg-entry nil (and (not (equal msg "")) msg))))
  514. )
  515. X
  516. X
  517. X
  518. X
  519. X
  520. X
  521. X
  522. ;;;; Logical operations.
  523. X
  524. (defun calcFunc-eq (a b &rest more)
  525. X  (if more
  526. X      (let* ((args (cons a (cons b (copy-sequence more))))
  527. X         (res 1)
  528. X         (p args)
  529. X         p2)
  530. X    (while (and (cdr p) (not (eq res 0)))
  531. X      (setq p2 p)
  532. X      (while (and (setq p2 (cdr p2)) (not (eq res 0)))
  533. X        (setq res (math-two-eq (car p) (car p2)))
  534. X        (if (eq res 1)
  535. X        (setcdr p (delq (car p2) (cdr p)))))
  536. X      (setq p (cdr p)))
  537. X    (if (eq res 0)
  538. X        0
  539. X      (if (cdr args)
  540. X          (cons 'calcFunc-eq args)
  541. X        1)))
  542. X    (or (math-two-eq a b)
  543. X    (if (and (or (math-looks-negp a) (math-zerop a))
  544. X         (or (math-looks-negp b) (math-zerop b)))
  545. X        (list 'calcFunc-eq (math-neg a) (math-neg b))
  546. X      (list 'calcFunc-eq a b))))
  547. )
  548. X
  549. (defun calcFunc-neq (a b &rest more)
  550. X  (if more
  551. X      (let* ((args (cons a (cons b more)))
  552. X         (res 0)
  553. X         (all t)
  554. X         (p args)
  555. X         p2)
  556. X    (while (and (cdr p) (not (eq res 1)))
  557. X      (setq p2 p)
  558. X      (while (and (setq p2 (cdr p2)) (not (eq res 1)))
  559. X        (setq res (math-two-eq (car p) (car p2)))
  560. X        (or res (setq all nil)))
  561. X      (setq p (cdr p)))
  562. X    (if (eq res 1)
  563. X        0
  564. X      (if all
  565. X          1
  566. X        (cons 'calcFunc-neq args))))
  567. X    (or (cdr (assq (math-two-eq a b) '((0 . 1) (1 . 0))))
  568. X    (if (and (or (math-looks-negp a) (math-zerop a))
  569. X         (or (math-looks-negp b) (math-zerop b)))
  570. X        (list 'calcFunc-neq (math-neg a) (math-neg b))
  571. X      (list 'calcFunc-neq a b))))
  572. )
  573. X
  574. (defun math-two-eq (a b)
  575. X  (if (eq (car-safe a) 'vec)
  576. X      (if (eq (car-safe b) 'vec)
  577. X      (if (= (length a) (length b))
  578. X          (let ((res 1))
  579. X        (while (and (setq a (cdr a) b (cdr b)) (not (eq res 0)))
  580. X          (if res
  581. X              (setq res (math-two-eq (car a) (car b)))
  582. X            (if (eq (math-two-eq (car a) (car b)) 0)
  583. X            (setq res 0))))
  584. X        res)
  585. X        0)
  586. X    (if (Math-objectp b)
  587. X        0
  588. X      nil))
  589. X    (if (eq (car-safe b) 'vec)
  590. X    (if (Math-objectp a)
  591. X        0
  592. X      nil)
  593. X      (let ((res (math-compare a b)))
  594. X    (if (= res 0)
  595. X        1
  596. X      (if (and (= res 2) (not (and (Math-scalarp a) (Math-scalarp b))))
  597. X          nil
  598. X        0)))))
  599. )
  600. X
  601. (defun calcFunc-lt (a b)
  602. X  (let ((res (math-compare a b)))
  603. X    (if (= res -1)
  604. X    1
  605. X      (if (= res 2)
  606. X      (if (and (or (math-looks-negp a) (math-zerop a))
  607. X           (or (math-looks-negp b) (math-zerop b)))
  608. X          (list 'calcFunc-gt (math-neg a) (math-neg b))
  609. X        (list 'calcFunc-lt a b))
  610. X    0)))
  611. )
  612. X
  613. (defun calcFunc-gt (a b)
  614. X  (let ((res (math-compare a b)))
  615. X    (if (= res 1)
  616. X    1
  617. X      (if (= res 2)
  618. X      (if (and (or (math-looks-negp a) (math-zerop a))
  619. X           (or (math-looks-negp b) (math-zerop b)))
  620. X          (list 'calcFunc-lt (math-neg a) (math-neg b))
  621. X        (list 'calcFunc-gt a b))
  622. X    0)))
  623. )
  624. X
  625. (defun calcFunc-leq (a b)
  626. X  (let ((res (math-compare a b)))
  627. X    (if (= res 1)
  628. X    0
  629. X      (if (= res 2)
  630. X      (if (and (or (math-looks-negp a) (math-zerop a))
  631. X           (or (math-looks-negp b) (math-zerop b)))
  632. X          (list 'calcFunc-geq (math-neg a) (math-neg b))
  633. X        (list 'calcFunc-leq a b))
  634. X    1)))
  635. )
  636. X
  637. (defun calcFunc-geq (a b)
  638. X  (let ((res (math-compare a b)))
  639. X    (if (= res -1)
  640. X    0
  641. X      (if (= res 2)
  642. X      (if (and (or (math-looks-negp a) (math-zerop a))
  643. X           (or (math-looks-negp b) (math-zerop b)))
  644. X          (list 'calcFunc-leq (math-neg a) (math-neg b))
  645. X        (list 'calcFunc-geq a b))
  646. X    1)))
  647. )
  648. X
  649. (defun calcFunc-rmeq (a)
  650. X  (if (math-vectorp a)
  651. X      (math-map-vec 'calcFunc-rmeq a)
  652. X    (if (assq (car-safe a) calc-tweak-eqn-table)
  653. X    (if (and (eq (car-safe (nth 2 a)) 'var)
  654. X         (math-objectp (nth 1 a)))
  655. X        (nth 1 a)
  656. X      (nth 2 a))
  657. X      (if (eq (car-safe a) 'calcFunc-assign)
  658. X      (nth 2 a)
  659. X    (if (eq (car-safe a) 'calcFunc-evalto)
  660. X        (nth 1 a)
  661. X      (list 'calcFunc-rmeq a)))))
  662. )
  663. X
  664. (defun calcFunc-land (a b)
  665. X  (cond ((Math-zerop a)
  666. X     a)
  667. X    ((Math-zerop b)
  668. X     b)
  669. X    ((math-is-true a)
  670. X     b)
  671. X    ((math-is-true b)
  672. X     a)
  673. X    (t (list 'calcFunc-land a b)))
  674. )
  675. X
  676. (defun calcFunc-lor (a b)
  677. X  (cond ((Math-zerop a)
  678. X     b)
  679. X    ((Math-zerop b)
  680. X     a)
  681. X    ((math-is-true a)
  682. X     a)
  683. X    ((math-is-true b)
  684. X     b)
  685. X    (t (list 'calcFunc-lor a b)))
  686. )
  687. X
  688. (defun calcFunc-lnot (a)
  689. X  (if (Math-zerop a)
  690. X      1
  691. X    (if (math-is-true a)
  692. X    0
  693. X      (let ((op (and (= (length a) 3)
  694. X             (assq (car a) calc-tweak-eqn-table))))
  695. X    (if op
  696. X        (cons (nth 2 op) (cdr a))
  697. X      (list 'calcFunc-lnot a)))))
  698. )
  699. X
  700. (defun calcFunc-if (c e1 e2)
  701. X  (if (Math-zerop c)
  702. X      e2
  703. X    (if (and (math-is-true c) (not (Math-vectorp c)))
  704. X    e1
  705. X      (or (and (Math-vectorp c)
  706. X           (math-constp c)
  707. X           (let ((ee1 (if (Math-vectorp e1)
  708. X                  (if (= (length c) (length e1))
  709. X                  (cdr e1)
  710. X                (calc-record-why "*Dimension error" e1))
  711. X                (list e1)))
  712. X             (ee2 (if (Math-vectorp e2)
  713. X                  (if (= (length c) (length e2))
  714. X                  (cdr e2)
  715. X                (calc-record-why "*Dimension error" e2))
  716. X                (list e2))))
  717. X         (and ee1 ee2
  718. X              (cons 'vec (math-if-vector (cdr c) ee1 ee2)))))
  719. X      (list 'calcFunc-if c e1 e2))))
  720. )
  721. X
  722. (defun math-if-vector (c e1 e2)
  723. X  (and c
  724. X       (cons (if (Math-zerop (car c)) (car e2) (car e1))
  725. X         (math-if-vector (cdr c)
  726. X                 (or (cdr e1) e1)
  727. X                 (or (cdr e2) e2))))
  728. )
  729. X
  730. (defun math-normalize-logical-op (a)
  731. X  (or (and (eq (car a) 'calcFunc-if)
  732. X       (= (length a) 4)
  733. X       (let ((a1 (math-normalize (nth 1 a))))
  734. X         (if (Math-zerop a1)
  735. X         (math-normalize (nth 3 a))
  736. X           (if (Math-numberp a1)
  737. X           (math-normalize (nth 2 a))
  738. X         (if (and (Math-vectorp (nth 1 a))
  739. X              (math-constp (nth 1 a)))
  740. X             (calcFunc-if (nth 1 a)
  741. X                  (math-normalize (nth 2 a))
  742. X                  (math-normalize (nth 3 a)))
  743. X           (let ((calc-simplify-mode 'none))
  744. X             (list 'calcFunc-if a1
  745. X               (math-normalize (nth 2 a))
  746. X               (math-normalize (nth 3 a)))))))))
  747. X      a)
  748. )
  749. X
  750. (defun calcFunc-in (a b)
  751. X  (or (and (eq (car-safe b) 'vec)
  752. X       (let ((bb b))
  753. X         (while (and (setq bb (cdr bb))
  754. X             (not (if (memq (car-safe (car bb)) '(vec intv))
  755. X                  (eq (calcFunc-in a (car bb)) 1)
  756. X                (Math-equal a (car bb))))))
  757. X         (if bb 1 (and (math-constp a) (math-constp bb) 0))))
  758. X      (and (eq (car-safe b) 'intv)
  759. X       (let ((res (math-compare a (nth 2 b))) res2)
  760. X         (cond ((= res -1)
  761. X            0)
  762. X           ((and (= res 0)
  763. X             (or (/= (nth 1 b) 2)
  764. X                 (Math-lessp (nth 2 b) (nth 3 b))))
  765. X            (if (memq (nth 1 b) '(2 3)) 1 0))
  766. X           ((= (setq res2 (math-compare a (nth 3 b))) 1)
  767. X            0)
  768. X           ((and (= res2 0)
  769. X             (or (/= (nth 1 b) 1)
  770. X                 (Math-lessp (nth 2 b) (nth 3 b))))
  771. X            (if (memq (nth 1 b) '(1 3)) 1 0))
  772. X           ((/= res 1)
  773. X            nil)
  774. X           ((/= res2 -1)
  775. X            nil)
  776. X           (t 1))))
  777. X      (and (Math-equal a b)
  778. X       1)
  779. X      (and (math-constp a) (math-constp b)
  780. X       0)
  781. X      (list 'calcFunc-in a b))
  782. )
  783. X
  784. (defun calcFunc-typeof (a)
  785. X  (cond ((Math-integerp a) 1)
  786. X    ((eq (car a) 'frac) 2)
  787. X    ((eq (car a) 'float) 3)
  788. X    ((eq (car a) 'hms) 4)
  789. X    ((eq (car a) 'cplx) 5)
  790. X    ((eq (car a) 'polar) 6)
  791. X    ((eq (car a) 'sdev) 7)
  792. X    ((eq (car a) 'intv) 8)
  793. X    ((eq (car a) 'mod) 9)
  794. X    ((eq (car a) 'date) (if (Math-integerp (nth 1 a)) 10 11))
  795. X    ((eq (car a) 'var)
  796. X     (if (memq (nth 2 a) '(var-inf var-uinf var-nan)) 12 100))
  797. X    ((eq (car a) 'vec) (if (math-matrixp a) 102 101))
  798. X    (t (math-calcFunc-to-var func)))
  799. )
  800. X
  801. (defun calcFunc-integer (a)
  802. X  (if (Math-integerp a)
  803. X      1
  804. X    (if (Math-objvecp a)
  805. X    0
  806. X      (list 'calcFunc-integer a)))
  807. )
  808. X
  809. (defun calcFunc-real (a)
  810. X  (if (Math-realp a)
  811. X      1
  812. X    (if (Math-objvecp a)
  813. X    0
  814. X      (list 'calcFunc-real a)))
  815. )
  816. X
  817. (defun calcFunc-constant (a)
  818. X  (if (math-constp a)
  819. X      1
  820. X    (if (Math-objvecp a)
  821. X    0
  822. X      (list 'calcFunc-constant a)))
  823. )
  824. X
  825. (defun calcFunc-refers (a b)
  826. X  (if (math-expr-contains a b)
  827. X      1
  828. X    (if (eq (car-safe a) 'var)
  829. X    (list 'calcFunc-refers a b)
  830. X      0))
  831. )
  832. X
  833. (defun calcFunc-negative (a)
  834. X  (if (math-looks-negp a)
  835. X      1
  836. X    (if (or (math-zerop a)
  837. X        (math-posp a))
  838. X    0
  839. X      (list 'calcFunc-negative a)))
  840. )
  841. X
  842. (defun calcFunc-variable (a)
  843. X  (if (eq (car-safe a) 'var)
  844. X      1
  845. X    (if (Math-objvecp a)
  846. X    0
  847. X      (list 'calcFunc-variable a)))
  848. )
  849. X
  850. (defun calcFunc-nonvar (a)
  851. X  (if (eq (car-safe a) 'var)
  852. X      (list 'calcFunc-nonvar a)
  853. X    1)
  854. )
  855. X
  856. (defun calcFunc-istrue (a)
  857. X  (if (math-is-true a)
  858. X      1
  859. X    0)
  860. )
  861. X
  862. X
  863. X
  864. X
  865. ;;;; User-programmability.
  866. X
  867. ;;; Compiling Lisp-like forms to use the math library.
  868. X
  869. (defun math-do-defmath (func args body)
  870. X  (calc-need-macros)
  871. X  (let* ((fname (intern (concat "calcFunc-" (symbol-name func))))
  872. X     (doc (if (stringp (car body)) (list (car body))))
  873. X     (clargs (mapcar 'math-clean-arg args))
  874. X     (body (math-define-function-body
  875. X        (if (stringp (car body)) (cdr body) body)
  876. X        clargs)))
  877. X    (list 'progn
  878. X      (if (and (consp (car body))
  879. X           (eq (car (car body)) 'interactive))
  880. X          (let ((inter (car body)))
  881. X        (setq body (cdr body))
  882. X        (if (or (> (length inter) 2)
  883. X            (integerp (nth 1 inter)))
  884. X            (let ((hasprefix nil) (hasmulti nil))
  885. X              (if (stringp (nth 1 inter))
  886. X              (progn
  887. X                (cond ((equal (nth 1 inter) "p")
  888. X                   (setq hasprefix t))
  889. X                  ((equal (nth 1 inter) "m")
  890. X                   (setq hasmulti t))
  891. X                  (t (error
  892. X                      "Can't handle interactive code string \"%s\""
  893. X                      (nth 1 inter))))
  894. X                (setq inter (cdr inter))))
  895. X              (if (not (integerp (nth 1 inter)))
  896. X              (error
  897. X               "Expected an integer in interactive specification"))
  898. X              (append (list 'defun
  899. X                    (intern (concat "calc-"
  900. X                            (symbol-name func)))
  901. X                    (if (or hasprefix hasmulti)
  902. X                    '(&optional n)
  903. X                      ()))
  904. X                  doc
  905. X                  (if (or hasprefix hasmulti)
  906. X                  '((interactive "P"))
  907. X                '((interactive)))
  908. X                  (list
  909. X                   (append
  910. X                '(calc-slow-wrapper)
  911. X                (and hasmulti
  912. X                     (list
  913. X                      (list 'setq
  914. X                        'n
  915. X                        (list 'if
  916. X                          'n
  917. X                          (list 'prefix-numeric-value
  918. X                            'n)
  919. X                          (nth 1 inter)))))
  920. X                (list
  921. X                 (list 'calc-enter-result
  922. X                       (if hasmulti 'n (nth 1 inter))
  923. X                       (nth 2 inter)
  924. X                       (if hasprefix
  925. X                       (list 'append
  926. X                         (list 'quote (list fname))
  927. X                         (list 'calc-top-list-n
  928. X                               (nth 1 inter))
  929. X                         (list 'and
  930. X                               'n
  931. X                               (list
  932. X                            'list
  933. X                            (list
  934. X                             'math-normalize
  935. X                             (list
  936. X                              'prefix-numeric-value
  937. X                              'n)))))
  938. X                     (list 'cons
  939. X                           (list 'quote fname)
  940. X                           (list 'calc-top-list-n
  941. X                             (if hasmulti
  942. X                             'n
  943. X                               (nth 1 inter)))))))))))
  944. X          (append (list 'defun
  945. X                (intern (concat "calc-" (symbol-name func)))
  946. X                args)
  947. X              doc
  948. X              (list
  949. X               inter
  950. X               (cons 'calc-wrapper body))))))
  951. X      (append (list 'defun fname clargs)
  952. X          doc
  953. X          (math-do-arg-list-check args nil nil)
  954. X          body)))
  955. )
  956. X
  957. (defun math-clean-arg (arg)
  958. X  (if (consp arg)
  959. X      (math-clean-arg (nth 1 arg))
  960. X    arg)
  961. )
  962. X
  963. (defun math-do-arg-check (arg var is-opt is-rest)
  964. X  (if is-opt
  965. X      (let ((chk (math-do-arg-check arg var nil nil)))
  966. X    (list (cons 'and
  967. X            (cons var
  968. X              (if (cdr chk)
  969. X                  (setq chk (list (cons 'progn chk)))
  970. X                chk)))))
  971. X    (and (consp arg)
  972. X     (let* ((rest (math-do-arg-check (nth 1 arg) var is-opt is-rest))
  973. X        (qual (car arg))
  974. X        (qqual (list 'quote qual))
  975. X        (qual-name (symbol-name qual))
  976. X        (chk (intern (concat "math-check-" qual-name))))
  977. X       (if (fboundp chk)
  978. X           (append rest
  979. X               (list
  980. X            (if is-rest
  981. X                (list 'setq var
  982. X                  (list 'mapcar (list 'quote chk) var))
  983. X              (list 'setq var (list chk var)))))
  984. X         (if (fboundp (setq chk (intern (concat "math-" qual-name))))
  985. X         (append rest
  986. X             (list
  987. X              (if is-rest
  988. X                  (list 'mapcar
  989. X                    (list 'function
  990. X                      (list 'lambda '(x)
  991. X                        (list 'or
  992. X                              (list chk 'x)
  993. X                              (list 'math-reject-arg
  994. X                                'x qqual))))
  995. X                    var)
  996. X                (list 'or
  997. X                  (list chk var)
  998. X                  (list 'math-reject-arg var qqual)))))
  999. X           (if (and (string-match "\\`not-\\(.*\\)\\'" qual-name)
  1000. X            (fboundp (setq chk (intern
  1001. X                        (concat "math-"
  1002. X                            (math-match-substring
  1003. X                             qual-name 1))))))
  1004. X           (append rest
  1005. X               (list
  1006. X                (if is-rest
  1007. X                (list 'mapcar
  1008. X                      (list 'function
  1009. X                        (list 'lambda '(x)
  1010. X                          (list 'and
  1011. X                            (list chk 'x)
  1012. X                            (list 'math-reject-arg
  1013. X                                  'x qqual))))
  1014. X                      var)
  1015. X                  (list 'and
  1016. X                    (list chk var)
  1017. X                    (list 'math-reject-arg var qqual)))))
  1018. X         (error "Unknown qualifier `%s'" qual-name)))))))
  1019. )
  1020. X
  1021. (defun math-do-arg-list-check (args is-opt is-rest)
  1022. X  (cond ((null args) nil)
  1023. X    ((consp (car args))
  1024. X     (append (math-do-arg-check (car args)
  1025. X                    (math-clean-arg (car args))
  1026. X                    is-opt is-rest)
  1027. X         (math-do-arg-list-check (cdr args) is-opt is-rest)))
  1028. X    ((eq (car args) '&optional)
  1029. X     (math-do-arg-list-check (cdr args) t nil))
  1030. X    ((eq (car args) '&rest)
  1031. X     (math-do-arg-list-check (cdr args) nil t))
  1032. X    (t (math-do-arg-list-check (cdr args) is-opt is-rest)))
  1033. )
  1034. X
  1035. (defconst math-prim-funcs
  1036. X  '( (~= . math-nearly-equal)
  1037. X     (% . math-mod)
  1038. X     (lsh . calcFunc-lsh)
  1039. X     (ash . calcFunc-ash)
  1040. X     (logand . calcFunc-and)
  1041. X     (logandc2 . calcFunc-diff)
  1042. X     (logior . calcFunc-or)
  1043. X     (logxor . calcFunc-xor)
  1044. X     (lognot . calcFunc-not)
  1045. X     (equal . equal)   ; need to leave these ones alone!
  1046. X     (eq . eq)
  1047. X     (and . and)
  1048. X     (or . or)
  1049. X     (if . if)
  1050. X     (^ . math-pow)
  1051. X     (expt . math-pow)
  1052. X   )
  1053. )
  1054. X
  1055. (defconst math-prim-vars
  1056. X  '( (nil . nil)
  1057. X     (t . t)
  1058. X     (&optional . &optional)
  1059. X     (&rest . &rest)
  1060. X   )
  1061. )
  1062. X
  1063. (defun math-define-function-body (body env)
  1064. X  (let ((body (math-define-body body env)))
  1065. X    (if (math-body-refers-to body 'math-return)
  1066. X    (list (cons 'catch (cons '(quote math-return) body)))
  1067. X      body))
  1068. )
  1069. X
  1070. (defun math-define-body (body exp-env)
  1071. X  (math-define-list body)
  1072. )
  1073. X
  1074. (defun math-define-list (body &optional quote)
  1075. X  (cond ((null body)
  1076. X     nil)
  1077. X    ((and (eq (car body) ':)
  1078. X          (stringp (nth 1 body)))
  1079. X     (cons (let* ((math-read-expr-quotes t)
  1080. X              (exp (math-read-plain-expr (nth 1 body) t)))
  1081. X         (math-define-exp exp))
  1082. X           (math-define-list (cdr (cdr body)))))
  1083. X    (quote
  1084. X     (cons (cond ((consp (car body))
  1085. X              (math-define-list (cdr body) t))
  1086. X             (t
  1087. X              (car body)))
  1088. X           (math-define-list (cdr body))))
  1089. X    (t
  1090. X     (cons (math-define-exp (car body))
  1091. X           (math-define-list (cdr body)))))
  1092. )
  1093. X
  1094. (defun math-define-exp (exp)
  1095. X  (cond ((consp exp)
  1096. X     (let ((func (car exp)))
  1097. X       (cond ((memq func '(quote function))
  1098. X          (if (and (consp (nth 1 exp))
  1099. X               (eq (car (nth 1 exp)) 'lambda))
  1100. X              (cons 'quote
  1101. X                (math-define-lambda (nth 1 exp) exp-env))
  1102. X            exp))
  1103. X         ((memq func '(let let* for foreach))
  1104. X          (let ((head (nth 1 exp))
  1105. X            (body (cdr (cdr exp))))
  1106. X            (if (memq func '(let let*))
  1107. X            ()
  1108. X              (setq func (cdr (assq func '((for . math-for)
  1109. X                           (foreach . math-foreach)))))
  1110. X              (if (not (listp (car head)))
  1111. X              (setq head (list head))))
  1112. X            (macroexpand
  1113. X             (cons func
  1114. X               (cons (math-define-let head)
  1115. X                 (math-define-body body
  1116. X                           (nconc
  1117. X                            (math-define-let-env head)
  1118. X                            exp-env)))))))
  1119. X         ((and (memq func '(setq setf))
  1120. X               (math-complicated-lhs (cdr exp)))
  1121. X          (if (> (length exp) 3)
  1122. X              (cons 'progn (math-define-setf-list (cdr exp)))
  1123. X            (math-define-setf (nth 1 exp) (nth 2 exp))))
  1124. X         ((eq func 'condition-case)
  1125. X          (cons func
  1126. X            (cons (nth 1 exp)
  1127. X                  (math-define-body (cdr (cdr exp))
  1128. X                        (cons (nth 1 exp)
  1129. X                              exp-env)))))
  1130. X         ((eq func 'cond)
  1131. X          (cons func
  1132. X            (math-define-cond (cdr exp))))
  1133. X         ((and (consp func)   ; ('spam a b) == force use of plain spam
  1134. X               (eq (car func) 'quote))
  1135. X          (cons func (math-define-list (cdr exp))))
  1136. X         ((symbolp func)
  1137. X          (let ((args (math-define-list (cdr exp)))
  1138. X            (prim (assq func math-prim-funcs)))
  1139. X            (cond (prim
  1140. X               (cons (cdr prim) args))
  1141. X              ((eq func 'floatp)
  1142. X               (list 'eq (car args) '(quote float)))
  1143. X              ((eq func '+)
  1144. X               (math-define-binop 'math-add 0
  1145. X                          (car args) (cdr args)))
  1146. X              ((eq func '-)
  1147. X               (if (= (length args) 1)
  1148. X                   (cons 'math-neg args)
  1149. X                 (math-define-binop 'math-sub 0
  1150. X                        (car args) (cdr args))))
  1151. X              ((eq func '*)
  1152. X               (math-define-binop 'math-mul 1
  1153. X                          (car args) (cdr args)))
  1154. X              ((eq func '/)
  1155. X               (math-define-binop 'math-div 1
  1156. X                          (car args) (cdr args)))
  1157. X              ((eq func 'min)
  1158. X               (math-define-binop 'math-min 0
  1159. X                          (car args) (cdr args)))
  1160. X              ((eq func 'max)
  1161. X               (math-define-binop 'math-max 0
  1162. X                          (car args) (cdr args)))
  1163. X              ((eq func '<)
  1164. X               (if (and (math-numberp (nth 1 args))
  1165. X                    (math-zerop (nth 1 args)))
  1166. X                   (list 'math-negp (car args))
  1167. X                 (cons 'math-lessp args)))
  1168. X              ((eq func '>)
  1169. X               (if (and (math-numberp (nth 1 args))
  1170. X                    (math-zerop (nth 1 args)))
  1171. X                   (list 'math-posp (car args))
  1172. X                 (list 'math-lessp (nth 1 args) (nth 0 args))))
  1173. X              ((eq func '<=)
  1174. X               (list 'not
  1175. X                 (if (and (math-numberp (nth 1 args))
  1176. X                      (math-zerop (nth 1 args)))
  1177. X                     (list 'math-posp (car args))
  1178. X                   (cons 'math-lessp args))))
  1179. X              ((eq func '>=)
  1180. X               (list 'not
  1181. X                 (if (and (math-numberp (nth 1 args))
  1182. X                      (math-zerop (nth 1 args)))
  1183. X                     (list 'math-negp (car args))
  1184. X                   (list 'math-lessp
  1185. X                     (nth 1 args) (nth 0 args)))))
  1186. X              ((eq func '=)
  1187. X               (if (and (math-numberp (nth 1 args))
  1188. X                    (math-zerop (nth 1 args)))
  1189. X                   (list 'math-zerop (nth 0 args))
  1190. X                 (if (and (integerp (nth 1 args))
  1191. X                      (/= (% (nth 1 args) 10) 0))
  1192. X                 (cons 'math-equal-int args)
  1193. X                   (cons 'math-equal args))))
  1194. X              ((eq func '/=)
  1195. X               (list 'not
  1196. X                 (if (and (math-numberp (nth 1 args))
  1197. X                      (math-zerop (nth 1 args)))
  1198. X                     (list 'math-zerop (nth 0 args))
  1199. X                   (if (and (integerp (nth 1 args))
  1200. X                        (/= (% (nth 1 args) 10) 0))
  1201. X                       (cons 'math-equal-int args)
  1202. X                     (cons 'math-equal args)))))
  1203. X              ((eq func '1+)
  1204. X               (list 'math-add (car args) 1))
  1205. X              ((eq func '1-)
  1206. X               (list 'math-add (car args) -1))
  1207. X              ((eq func 'not)   ; optimize (not (not x)) => x
  1208. X               (if (eq (car-safe args) func)
  1209. X                   (car (nth 1 args))
  1210. X                 (cons func args)))
  1211. X              ((and (eq func 'elt) (cdr (cdr args)))
  1212. X               (math-define-elt (car args) (cdr args)))
  1213. X              (t
  1214. X               (macroexpand
  1215. X                (let* ((name (symbol-name func))
  1216. X                   (cfunc (intern (concat "calcFunc-" name)))
  1217. X                   (mfunc (intern (concat "math-" name))))
  1218. X                  (cond ((fboundp cfunc)
  1219. X                     (cons cfunc args))
  1220. X                    ((fboundp mfunc)
  1221. X                     (cons mfunc args))
  1222. X                    ((or (fboundp func)
  1223. X                     (string-match "\\`calcFunc-.*" name))
  1224. X                     (cons func args))
  1225. X                    (t
  1226. X                     (cons cfunc args)))))))))
  1227. X         (t (cons func args)))))
  1228. X    ((symbolp exp)
  1229. X     (let ((prim (assq exp math-prim-vars))
  1230. X           (name (symbol-name exp)))
  1231. X       (cond (prim
  1232. X          (cdr prim))
  1233. X         ((memq exp exp-env)
  1234. X          exp)
  1235. X         ((string-match "-" name)
  1236. X          exp)
  1237. X         (t
  1238. X          (intern (concat "var-" name))))))
  1239. X    ((integerp exp)
  1240. X     (if (or (<= exp -1000000) (>= exp 1000000))
  1241. X         (list 'quote (math-normalize exp))
  1242. X       exp))
  1243. X    (t exp))
  1244. )
  1245. X
  1246. (defun math-define-cond (forms)
  1247. X  (and forms
  1248. X       (cons (math-define-list (car forms))
  1249. X         (math-define-cond (cdr forms))))
  1250. )
  1251. X
  1252. (defun math-complicated-lhs (body)
  1253. X  (and body
  1254. X       (or (not (symbolp (car body)))
  1255. X       (math-complicated-lhs (cdr (cdr body)))))
  1256. )
  1257. X
  1258. (defun math-define-setf-list (body)
  1259. X  (and body
  1260. X       (cons (math-define-setf (nth 0 body) (nth 1 body))
  1261. X         (math-define-setf-list (cdr (cdr body)))))
  1262. )
  1263. X
  1264. (defun math-define-setf (place value)
  1265. X  (setq place (math-define-exp place)
  1266. X    value (math-define-exp value))
  1267. X  (cond ((symbolp place)
  1268. X     (list 'setq place value))
  1269. X    ((eq (car-safe place) 'nth)
  1270. X     (list 'setcar (list 'nthcdr (nth 1 place) (nth 2 place)) value))
  1271. X    ((eq (car-safe place) 'elt)
  1272. X     (list 'setcar (list 'nthcdr (nth 2 place) (nth 1 place)) value))
  1273. X    ((eq (car-safe place) 'car)
  1274. X     (list 'setcar (nth 1 place) value))
  1275. X    ((eq (car-safe place) 'cdr)
  1276. X     (list 'setcdr (nth 1 place) value))
  1277. X    (t
  1278. X     (error "Bad place form for setf: %s" place)))
  1279. )
  1280. X
  1281. (defun math-define-binop (op ident arg1 rest)
  1282. X  (if rest
  1283. X      (math-define-binop op ident
  1284. X             (list op arg1 (car rest))
  1285. X             (cdr rest))
  1286. X    (or arg1 ident))
  1287. )
  1288. X
  1289. (defun math-define-let (vlist)
  1290. X  (and vlist
  1291. X       (cons (if (consp (car vlist))
  1292. X         (cons (car (car vlist))
  1293. X               (math-define-list (cdr (car vlist))))
  1294. X           (car vlist))
  1295. X         (math-define-let (cdr vlist))))
  1296. )
  1297. X
  1298. (defun math-define-let-env (vlist)
  1299. X  (and vlist
  1300. X       (cons (if (consp (car vlist))
  1301. X         (car (car vlist))
  1302. X           (car vlist))
  1303. X         (math-define-let-env (cdr vlist))))
  1304. )
  1305. X
  1306. (defun math-define-lambda (exp exp-env)
  1307. X  (nconc (list (nth 0 exp)   ; 'lambda
  1308. X           (nth 1 exp))  ; arg list
  1309. X     (math-define-function-body (cdr (cdr exp))
  1310. X                    (append (nth 1 exp) exp-env)))
  1311. )
  1312. X
  1313. (defun math-define-elt (seq idx)
  1314. X  (if idx
  1315. X      (math-define-elt (list 'elt seq (car idx)) (cdr idx))
  1316. X    seq)
  1317. )
  1318. X
  1319. X
  1320. X
  1321. ;;; Useful programming macros.
  1322. X
  1323. (defmacro math-while (head &rest body)
  1324. X  (let ((body (cons 'while (cons head body))))
  1325. X    (if (math-body-refers-to body 'math-break)
  1326. X    (cons 'catch (cons '(quote math-break) (list body)))
  1327. X      body))
  1328. )
  1329. X
  1330. X
  1331. (defmacro math-for (head &rest body)
  1332. X  (let ((body (if head
  1333. X          (math-handle-for head body)
  1334. X        (cons 'while (cons t body)))))
  1335. X    (if (math-body-refers-to body 'math-break)
  1336. X    (cons 'catch (cons '(quote math-break) (list body)))
  1337. X      body))
  1338. )
  1339. X
  1340. (defun math-handle-for (head body)
  1341. X  (let* ((var (nth 0 (car head)))
  1342. X     (init (nth 1 (car head)))
  1343. X     (limit (nth 2 (car head)))
  1344. X     (step (or (nth 3 (car head)) 1))
  1345. X     (body (if (cdr head)
  1346. X           (list (math-handle-for (cdr head) body))
  1347. X         body))
  1348. X     (all-ints (and (integerp init) (integerp limit) (integerp step)))
  1349. X     (const-limit (or (integerp limit)
  1350. X              (and (eq (car-safe limit) 'quote)
  1351. X                   (math-realp (nth 1 limit)))))
  1352. X     (const-step (or (integerp step)
  1353. X             (and (eq (car-safe step) 'quote)
  1354. X                  (math-realp (nth 1 step)))))
  1355. X     (save-limit (if const-limit limit (make-symbol "<limit>")))
  1356. X     (save-step (if const-step step (make-symbol "<step>"))))
  1357. X    (cons 'let
  1358. X      (cons (append (if const-limit nil (list (list save-limit limit)))
  1359. X            (if const-step nil (list (list save-step step)))
  1360. X            (list (list var init)))
  1361. X        (list
  1362. X         (cons 'while
  1363. X               (cons (if all-ints
  1364. X                 (if (> step 0)
  1365. X                     (list '<= var save-limit)
  1366. X                   (list '>= var save-limit))
  1367. X                   (list 'not
  1368. X                     (if const-step
  1369. X                     (if (or (math-posp step)
  1370. X                         (math-posp
  1371. X                          (cdr-safe step)))
  1372. X                         (list 'math-lessp
  1373. X                           save-limit
  1374. X                           var)
  1375. X                       (list 'math-lessp
  1376. X                         var
  1377. X                         save-limit))
  1378. X                       (list 'if
  1379. X                         (list 'math-posp
  1380. X                           save-step)
  1381. X                         (list 'math-lessp
  1382. X                           save-limit
  1383. X                           var)
  1384. X                         (list 'math-lessp
  1385. X                           var
  1386. X                           save-limit)))))
  1387. X                 (append body
  1388. X                     (list (list 'setq
  1389. X                         var
  1390. X                         (list (if all-ints
  1391. X                               '+
  1392. X                             'math-add)
  1393. X                               var
  1394. X                               save-step))))))))))
  1395. )
  1396. X
  1397. X
  1398. (defmacro math-foreach (head &rest body)
  1399. X  (let ((body (math-handle-foreach head body)))
  1400. X    (if (math-body-refers-to body 'math-break)
  1401. X    (cons 'catch (cons '(quote math-break) (list body)))
  1402. X      body))
  1403. )
  1404. X
  1405. X
  1406. (defun math-handle-foreach (head body)
  1407. X  (let ((var (nth 0 (car head)))
  1408. X    (data (nth 1 (car head)))
  1409. X    (body (if (cdr head)
  1410. X          (list (math-handle-foreach (cdr head) body))
  1411. X        body)))
  1412. X    (cons 'let
  1413. X      (cons (list (list var data))
  1414. X        (list
  1415. X         (cons 'while
  1416. X               (cons var
  1417. X                 (append body
  1418. X                     (list (list 'setq
  1419. X                         var
  1420. X                         (list 'cdr var))))))))))
  1421. )
  1422. X
  1423. X
  1424. (defun math-body-refers-to (body thing)
  1425. X  (or (equal body thing)
  1426. X      (and (consp body)
  1427. X       (or (math-body-refers-to (car body) thing)
  1428. X           (math-body-refers-to (cdr body) thing))))
  1429. )
  1430. X
  1431. (defun math-break (&optional value)
  1432. X  (throw 'math-break value)
  1433. )
  1434. X
  1435. (defun math-return (&optional value)
  1436. X  (throw 'math-return value)
  1437. )
  1438. X
  1439. X
  1440. X
  1441. X
  1442. X
  1443. (defun math-composite-inequalities (x op)
  1444. X  (if (memq (nth 1 op) '(calcFunc-eq calcFunc-neq))
  1445. X      (if (eq (car x) (nth 1 op))
  1446. X      (append x (list (math-read-expr-level (nth 3 op))))
  1447. X    (throw 'syntax "Syntax error"))
  1448. X    (list 'calcFunc-in
  1449. X      (nth 2 x)
  1450. X      (if (memq (nth 1 op) '(calcFunc-lt calcFunc-leq))
  1451. X          (if (memq (car x) '(calcFunc-lt calcFunc-leq))
  1452. X          (math-make-intv
  1453. X           (+ (if (eq (car x) 'calcFunc-leq) 2 0)
  1454. X              (if (eq (nth 1 op) 'calcFunc-leq) 1 0))
  1455. X           (nth 1 x) (math-read-expr-level (nth 3 op)))
  1456. X        (throw 'syntax "Syntax error"))
  1457. X        (if (memq (car x) '(calcFunc-gt calcFunc-geq))
  1458. X        (math-make-intv
  1459. X         (+ (if (eq (nth 1 op) 'calcFunc-geq) 2 0)
  1460. X            (if (eq (car x) 'calcFunc-geq) 1 0))
  1461. X         (math-read-expr-level (nth 3 op)) (nth 1 x))
  1462. X          (throw 'syntax "Syntax error")))))
  1463. )
  1464. X
  1465. SHAR_EOF
  1466. echo 'File calc-prog.el is complete' &&
  1467. chmod 0644 calc-prog.el ||
  1468. echo 'restore of calc-prog.el failed'
  1469. Wc_c="`wc -c < 'calc-prog.el'`"
  1470. test 60998 -eq "$Wc_c" ||
  1471.     echo 'calc-prog.el: original size 60998, current size' "$Wc_c"
  1472. rm -f _shar_wnt_.tmp
  1473. fi
  1474. # ============= calc-rewr.el ==============
  1475. if test -f 'calc-rewr.el' -a X"$1" != X"-c"; then
  1476.     echo 'x - skipping calc-rewr.el (File already exists)'
  1477.     rm -f _shar_wnt_.tmp
  1478. else
  1479. > _shar_wnt_.tmp
  1480. echo 'x - extracting calc-rewr.el (Text)'
  1481. sed 's/^X//' << 'SHAR_EOF' > 'calc-rewr.el' &&
  1482. ;; Calculator for GNU Emacs, part II [calc-rewr.el]
  1483. ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
  1484. ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
  1485. X
  1486. ;; This file is part of GNU Emacs.
  1487. X
  1488. ;; GNU Emacs is distributed in the hope that it will be useful,
  1489. ;; but WITHOUT ANY WARRANTY.  No author or distributor
  1490. ;; accepts responsibility to anyone for the consequences of using it
  1491. ;; or for whether it serves any particular purpose or works at all,
  1492. ;; unless he says so in writing.  Refer to the GNU Emacs General Public
  1493. ;; License for full details.
  1494. X
  1495. ;; Everyone is granted permission to copy, modify and redistribute
  1496. ;; GNU Emacs, but only under the conditions described in the
  1497. ;; GNU Emacs General Public License.   A copy of this license is
  1498. ;; supposed to have been given to you along with GNU Emacs so you
  1499. ;; can know your rights and responsibilities.  It should be in a
  1500. ;; file named COPYING.  Among other things, the copyright notice
  1501. ;; and this notice must be preserved on all copies.
  1502. X
  1503. X
  1504. X
  1505. ;; This file is autoloaded from calc-ext.el.
  1506. (require 'calc-ext)
  1507. X
  1508. (require 'calc-macs)
  1509. X
  1510. (defun calc-Need-calc-rewr () nil)
  1511. X
  1512. X
  1513. (defun calc-rewrite-selection (rules-str &optional many prefix)
  1514. X  (interactive "sRewrite rule(s): \np")
  1515. X  (calc-slow-wrapper
  1516. X   (calc-preserve-point)
  1517. X   (let* ((num (max 1 (calc-locate-cursor-element (point))))
  1518. X      (reselect t)
  1519. X      (pop-rules nil)
  1520. X      (entry (calc-top num 'entry))
  1521. X      (expr (car entry))
  1522. X      (sel (calc-auto-selection entry))
  1523. X      (math-rewrite-selections t)
  1524. X      (math-rewrite-default-iters 1))
  1525. X     (if (or (null rules-str) (equal rules-str "") (equal rules-str "$"))
  1526. X     (if (= num 1)
  1527. X         (error "Can't use same stack entry for formula and rules.")
  1528. X       (setq rules (calc-top-n 1 t)
  1529. X         pop-rules t))
  1530. X       (setq rules (if (stringp rules-str)
  1531. X               (math-read-exprs rules-str) rules-str))
  1532. X       (if (eq (car-safe rules) 'error)
  1533. X       (error "Bad format in expression: %s" (nth 1 rules)))
  1534. X       (if (= (length rules) 1)
  1535. X       (setq rules (car rules))
  1536. X     (setq rules (cons 'vec rules)))
  1537. X       (or (memq (car-safe rules) '(vec var calcFunc-assign
  1538. X                    calcFunc-condition))
  1539. X       (let ((rhs (math-read-expr
  1540. X               (read-string (concat "Rewrite from:    " rules-str
  1541. X                        "  to: ")))))
  1542. X         (if (eq (car-safe rhs) 'error)
  1543. X         (error "Bad format in expression: %s" (nth 1 rhs)))
  1544. X         (setq rules (list 'calcFunc-assign rules rhs))))
  1545. X       (or (eq (car-safe rules) 'var)
  1546. X       (calc-record rules "rule")))
  1547. X     (if (eq many 0)
  1548. X     (setq many '(var inf var-inf))
  1549. X       (if many (setq many (prefix-numeric-value many))))
  1550. X     (if sel
  1551. X     (setq expr (calc-replace-sub-formula (car entry)
  1552. X                          sel
  1553. X                          (list 'calcFunc-select sel)))
  1554. X       (setq expr (car entry)
  1555. X         reselect nil
  1556. X         math-rewrite-selections nil))
  1557. X     (setq expr (calc-encase-atoms
  1558. X         (calc-normalize
  1559. X          (math-rewrite
  1560. X           (calc-normalize expr)
  1561. X           rules many)))
  1562. X       sel nil
  1563. X       expr (calc-locate-select-marker expr))
  1564. X     (or (consp sel) (setq sel nil))
  1565. X     (if pop-rules (calc-pop-stack 1))
  1566. X     (calc-pop-push-record-list 1 (or prefix "rwrt") (list expr)
  1567. X                (- num (if pop-rules 1 0))
  1568. X                (list (and reselect sel))))
  1569. X   (calc-handle-whys))
  1570. )
  1571. X
  1572. (defun calc-locate-select-marker (expr)    ; changes "sel"
  1573. X  (if (Math-primp expr)
  1574. X      expr
  1575. X    (if (and (eq (car expr) 'calcFunc-select)
  1576. X         (= (length expr) 2))
  1577. X    (progn
  1578. X      (setq sel (if sel t (nth 1 expr)))
  1579. X      (nth 1 expr))
  1580. X      (cons (car expr)
  1581. X        (mapcar 'calc-locate-select-marker (cdr expr)))))
  1582. )
  1583. X
  1584. X
  1585. X
  1586. (defun calc-rewrite (rules-str many)
  1587. X  (interactive "sRewrite rule(s): \nP")
  1588. X  (calc-slow-wrapper
  1589. X   (let (n rules expr)
  1590. X     (if (or (null rules-str) (equal rules-str "") (equal rules-str "$"))
  1591. X     (setq expr (calc-top-n 2)
  1592. X           rules (calc-top-n 1 t)
  1593. X           n 2)
  1594. X       (setq rules (if (stringp rules-str)
  1595. X               (math-read-exprs rules-str) rules-str))
  1596. X       (if (eq (car-safe rules) 'error)
  1597. X       (error "Bad format in expression: %s" (nth 1 rules)))
  1598. X       (if (= (length rules) 1)
  1599. X       (setq rules (car rules))
  1600. X     (setq rules (cons 'vec rules)))
  1601. X       (or (memq (car-safe rules) '(vec var calcFunc-assign
  1602. X                    calcFunc-condition))
  1603. X       (let ((rhs (math-read-expr
  1604. X               (read-string (concat "Rewrite from:    " rules-str
  1605. X                        " to: ")))))
  1606. X         (if (eq (car-safe rhs) 'error)
  1607. X         (error "Bad format in expression: %s" (nth 1 rhs)))
  1608. X         (setq rules (list 'calcFunc-assign rules rhs))))
  1609. X       (or (eq (car-safe rules) 'var)
  1610. X       (calc-record rules "rule"))
  1611. X       (setq expr (calc-top-n 1)
  1612. X         n 1))
  1613. X     (if (eq many 0)
  1614. X     (setq many '(var inf var-inf))
  1615. X       (if many (setq many (prefix-numeric-value many))))
  1616. X     (setq expr (calc-normalize (math-rewrite expr rules many)))
  1617. X     (let (sel)
  1618. X       (setq expr (calc-locate-select-marker expr)))
  1619. X     (calc-pop-push-record-list n "rwrt" (list expr)))
  1620. X   (calc-handle-whys))
  1621. )
  1622. X
  1623. (defun calc-match (pat)
  1624. X  (interactive "sPattern: \n")
  1625. X  (calc-slow-wrapper
  1626. X   (let (n expr)
  1627. X     (if (or (null pat) (equal pat "") (equal pat "$"))
  1628. X     (setq expr (calc-top-n 2)
  1629. X           pat (calc-top-n 1)
  1630. X           n 2)
  1631. X       (if (interactive-p) (setq calc-previous-alg-entry pat))
  1632. X       (setq pat (if (stringp pat) (math-read-expr pat) pat))
  1633. X       (if (eq (car-safe pat) 'error)
  1634. X       (error "Bad format in expression: %s" (nth 1 pat)))
  1635. X       (if (not (eq (car-safe pat) 'var))
  1636. X       (calc-record pat "pat"))
  1637. X       (setq expr (calc-top-n 1)
  1638. X         n 1))
  1639. X     (or (math-vectorp expr) (error "Argument must be a vector"))
  1640. X     (if (calc-is-inverse)
  1641. X     (calc-enter-result n "mtcn" (math-match-patterns pat expr t))
  1642. X       (calc-enter-result n "mtch" (math-match-patterns pat expr nil)))))
  1643. )
  1644. X
  1645. X
  1646. X
  1647. (defun math-rewrite (whole-expr rules &optional mmt-many)
  1648. X  (let ((crules (math-compile-rewrites rules))
  1649. X    (heads (math-rewrite-heads whole-expr))
  1650. X    (trace-buffer (get-buffer "*Trace*"))
  1651. X    (calc-display-just 'center)
  1652. X    (calc-display-origin 39)
  1653. X    (calc-line-breaking 78)
  1654. X    (calc-line-numbering nil)
  1655. X    (calc-show-selections t)
  1656. X    (calc-why nil)
  1657. X    (mmt-func (function
  1658. X           (lambda (x)
  1659. X             (let ((result (math-apply-rewrites x (cdr crules)
  1660. X                            heads crules)))
  1661. X               (if result
  1662. X               (progn
  1663. X                 (if trace-buffer
  1664. X                 (let ((fmt (math-format-stack-value
  1665. X                         (list result nil nil))))
  1666. X                   (save-excursion
  1667. X                     (set-buffer trace-buffer)
  1668. X                     (insert "\nrewrite to\n" fmt "\n"))))
  1669. X                 (setq heads (math-rewrite-heads result heads t))))
  1670. X               result)))))
  1671. X    (if trace-buffer
  1672. X    (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
  1673. X      (save-excursion
  1674. X        (set-buffer trace-buffer)
  1675. X        (setq truncate-lines t)
  1676. X        (goto-char (point-max))
  1677. X        (insert "\n\nBegin rewriting\n" fmt "\n"))))
  1678. X    (or mmt-many (setq mmt-many (or (nth 1 (car crules))
  1679. X                    math-rewrite-default-iters)))
  1680. X    (if (equal mmt-many '(var inf var-inf)) (setq mmt-many 1000000))
  1681. X    (if (equal mmt-many '(neg (var inf var-inf))) (setq mmt-many -1000000))
  1682. X    (math-rewrite-phase (nth 3 (car crules)))
  1683. X    (if trace-buffer
  1684. X    (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
  1685. X      (save-excursion
  1686. X        (set-buffer trace-buffer)
  1687. X        (insert "\nDone rewriting"
  1688. X            (if (= mmt-many 0) " (reached iteration limit)" "")
  1689. X            ":\n" fmt "\n"))))
  1690. X    whole-expr)
  1691. )
  1692. (setq math-rewrite-default-iters 100)
  1693. X
  1694. (defun math-rewrite-phase (sched)
  1695. X  (while (and sched (/= mmt-many 0))
  1696. X    (if (listp (car sched))
  1697. X    (while (let ((save-expr whole-expr))
  1698. X         (math-rewrite-phase (car sched))
  1699. X         (not (equal whole-expr save-expr))))
  1700. X      (if (symbolp (car sched))
  1701. X      (progn
  1702. X        (setq whole-expr (math-normalize (list (car sched) whole-expr)))
  1703. X        (if trace-buffer
  1704. X        (let ((fmt (math-format-stack-value
  1705. X                (list whole-expr nil nil))))
  1706. X          (save-excursion
  1707. X            (set-buffer trace-buffer)
  1708. X            (insert "\ncall "
  1709. X                (substring (symbol-name (car sched)) 9)
  1710. X                ":\n" fmt "\n")))))
  1711. X    (let ((math-rewrite-phase (car sched)))
  1712. X      (if trace-buffer
  1713. X          (save-excursion
  1714. X        (set-buffer trace-buffer)
  1715. X        (insert (format "\n(Phase %d)\n" math-rewrite-phase))))
  1716. X      (while (let ((save-expr whole-expr))
  1717. X           (setq whole-expr (math-normalize
  1718. X                     (math-map-tree-rec whole-expr)))
  1719. X           (not (equal whole-expr save-expr)))))))
  1720. X    (setq sched (cdr sched)))
  1721. )
  1722. X
  1723. (defun calcFunc-rewrite (expr rules &optional many)
  1724. X  (or (null many) (integerp many)
  1725. X      (equal many '(var inf var-inf)) (equal many '(neg (var inf var-inf)))
  1726. X      (math-reject-arg many 'fixnump))
  1727. X  (condition-case err
  1728. X      (math-rewrite expr rules (or many 1))
  1729. X    (error (math-reject-arg rules (nth 1 err))))
  1730. )
  1731. X
  1732. (defun calcFunc-match (pat vec)
  1733. X  (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
  1734. X  (condition-case err
  1735. X      (math-match-patterns pat vec nil)
  1736. X    (error (math-reject-arg pat (nth 1 err))))
  1737. )
  1738. X
  1739. (defun calcFunc-matchnot (pat vec)
  1740. X  (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
  1741. X  (condition-case err
  1742. X      (math-match-patterns pat vec t)
  1743. X    (error (math-reject-arg pat (nth 1 err))))
  1744. )
  1745. X
  1746. (defun math-match-patterns (pat vec &optional not-flag)
  1747. X  (let ((newvec nil)
  1748. X    (crules (math-compile-patterns pat)))
  1749. X    (while (setq vec (cdr vec))
  1750. X      (if (eq (not (math-apply-rewrites (car vec) crules))
  1751. X          not-flag)
  1752. X      (setq newvec (cons (car vec) newvec))))
  1753. X    (cons 'vec (nreverse newvec)))
  1754. )
  1755. X
  1756. (defun calcFunc-matches (expr pat)
  1757. X  (condition-case err
  1758. X      (if (math-apply-rewrites expr (math-compile-patterns pat))
  1759. X      1
  1760. X    0)
  1761. X    (error (math-reject-arg pat (nth 1 err))))
  1762. )
  1763. X
  1764. X
  1765. X
  1766. ;;; A compiled rule set is an a-list of entries whose cars are functors,
  1767. ;;; and whose cdrs are lists of rules.  If there are rules with no
  1768. ;;; well-defined head functor, they are included on all lists and also
  1769. ;;; on an extra list whose car is nil.
  1770. ;;;
  1771. ;;; The first entry in the a-list is of the form (schedule A B C ...).
  1772. ;;;
  1773. ;;; Rule list entries take the form (regs prog head phases), where:
  1774. ;;;
  1775. ;;;   regs   is a vector of match registers.
  1776. ;;;
  1777. ;;;   prog   is a match program (see below).
  1778. ;;;
  1779. ;;;   head   is a rare function name appearing in the rule body (but not the
  1780. ;;;         head of the whole rule), or nil if none.
  1781. ;;;
  1782. ;;;   phases is a list of phase numbers for which the rule is enabled.
  1783. ;;;
  1784. ;;; A match program is a list of match instructions.
  1785. ;;;
  1786. ;;; In the following, "part" is a register number that contains the
  1787. ;;; subexpression to be operated on.
  1788. ;;;
  1789. ;;; Register 0 is the whole expression being matched.  The others are
  1790. ;;; meta-variables in the pattern, temporaries used for matching and
  1791. ;;; backtracking, and constant expressions.
  1792. ;;;
  1793. ;;; (same part reg)
  1794. ;;;         The selected part must be math-equal to the contents of "reg".
  1795. ;;;
  1796. ;;; (same-neg part reg)
  1797. ;;;         The selected part must be math-equal to the negative of "reg".
  1798. ;;;
  1799. ;;; (copy part reg)
  1800. ;;;        The selected part is copied into "reg".  (Rarely used.)
  1801. ;;;
  1802. ;;; (copy-neg part reg)
  1803. ;;;        The negative of the selected part is copied into "reg".
  1804. ;;;
  1805. ;;; (integer part)
  1806. ;;;         The selected part must be an integer.
  1807. ;;;
  1808. ;;; (real part)
  1809. ;;;         The selected part must be a real.
  1810. ;;;
  1811. ;;; (constant part)
  1812. ;;;         The selected part must be a constant.
  1813. ;;;
  1814. ;;; (negative part)
  1815. ;;;        The selected part must "look" negative.
  1816. ;;;
  1817. ;;; (rel part op reg)
  1818. ;;;         The selected part must satisfy "part op reg", where "op"
  1819. ;;;        is one of the 6 relational ops, and "reg" is a register.
  1820. ;;;
  1821. ;;; (mod part modulo value)
  1822. ;;;         The selected part must satisfy "part % modulo = value", where
  1823. ;;;         "modulo" and "value" are constants.
  1824. ;;;
  1825. ;;; (func part head reg1 reg2 ... regn)
  1826. ;;;         The selected part must be an n-ary call to function "head".
  1827. ;;;         The arguments are stored in "reg1" through "regn".
  1828. ;;;
  1829. ;;; (func-def part head defs reg1 reg2 ... regn)
  1830. ;;;        The selected part must be an n-ary call to function "head".
  1831. ;;;        "Defs" is a list of value/register number pairs for default args.
  1832. ;;;        If a match, assign default values to registers and then skip
  1833. ;;;        immediately over any following "func-def" instructions and
  1834. ;;;        the following "func" instruction.  If wrong number of arguments,
  1835. ;;;        proceed to the following "func-def" or "func" instruction.
  1836. ;;;
  1837. ;;; (func-opt part head defs reg1)
  1838. ;;;        Like func-def with "n=1", except that if the selected part is
  1839. ;;;        not a call to "head", then the part itself successfully matches
  1840. ;;;        "reg1" (and the defaults are assigned).
  1841. ;;;
  1842. ;;; (try part heads mark reg1 [def])
  1843. ;;;         The selected part must be a function of the correct type which is
  1844. ;;;         associative and/or commutative.  "Heads" is a list of acceptable
  1845. ;;;         types.  An initial assignment of arguments to "reg1" is tried.
  1846. ;;;        If the program later fails, it backtracks to this instruction
  1847. ;;;        and tries other assignments of arguments to "reg1".
  1848. ;;;        If "def" exists and normal matching fails, backtrack and assign
  1849. ;;;        "part" to "reg1", and "def" to "reg2" in the following "try2".
  1850. ;;;        The "mark" is a vector of size 5; only "mark[3-4]" are initialized.
  1851. ;;;        "mark[0]" points to the argument list; "mark[1]" points to the
  1852. ;;;        current argument; "mark[2]" is 0 if there are two arguments,
  1853. ;;;        1 if reg1 is matching single arguments, 2 if reg2 is matching
  1854. ;;;        single arguments (a+b+c+d is never split as (a+b)+(c+d)), or
  1855. ;;;         3 if reg2 is matching "def"; "mark[3]" is 0 if the function must
  1856. ;;;        have two arguments, 1 if phase-2 can be skipped, 2 if full
  1857. ;;;        backtracking is necessary; "mark[4]" is t if the arguments have
  1858. ;;;        been switched from the order given in the original pattern.
  1859. ;;;
  1860. ;;; (try2 try reg2)
  1861. ;;;         Every "try" will be followed by a "try2" whose "try" field is
  1862. ;;;        a pointer to the corresponding "try".  The arguments which were
  1863. ;;;        not stored in "reg1" by that "try" are now stored in "reg2".
  1864. ;;;
  1865. ;;; (alt instr nil mark)
  1866. ;;;        Basic backtracking.  Execute the instruction sequence "instr".
  1867. ;;;        If this fails, back up and execute following the "alt" instruction.
  1868. ;;;        The "mark" must be the vector "[nil nil 4]".  The "instr" sequence
  1869. ;;;        should execute "end-alt" at the end.
  1870. ;;;
  1871. ;;; (end-alt ptr)
  1872. ;;;         Register success of the first alternative of a previous "alt".
  1873. ;;;        "Ptr" is a pointer to the next instruction following that "alt".
  1874. ;;;
  1875. ;;; (apply part reg1 reg2)
  1876. ;;;         The selected part must be a function call.  The functor
  1877. ;;;        (as a variable name) is stored in "reg1"; the arguments
  1878. ;;;        (as a vector) are stored in "reg2".
  1879. ;;;
  1880. ;;; (cons part reg1 reg2)
  1881. ;;;        The selected part must be a nonempty vector.  The first element
  1882. ;;;        of the vector is stored in "reg1"; the rest of the vector
  1883. ;;;        (as another vector) is stored in "reg2".
  1884. ;;;
  1885. ;;; (rcons part reg1 reg2)
  1886. ;;;        The selected part must be a nonempty vector.  The last element
  1887. ;;;        of the vector is stored in "reg2"; the rest of the vector
  1888. ;;;        (as another vector) is stored in "reg1".
  1889. ;;;
  1890. ;;; (select part reg)
  1891. ;;;         If the selected part is a unary call to function "select", its
  1892. SHAR_EOF
  1893. true || echo 'restore of calc-rewr.el failed'
  1894. fi
  1895. echo 'End of  part 24'
  1896. echo 'File calc-rewr.el is continued in part 25'
  1897. echo 25 > _shar_seq_.tmp
  1898. exit 0
  1899. exit 0 # Just in case...
  1900. -- 
  1901. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1902. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1903. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1904. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1905.