from trunk
[bpt/emacs.git] / lisp / calc / calc-rewr.el
index 51cffb7..8fc983a 100644 (file)
@@ -1,41 +1,41 @@
 ;;; calc-rewr.el --- rewriting functions for Calc
 
-;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
+;;   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 ;; Author: David Gillespie <daveg@synaptics.com>
-;; Maintainers: D. Goel <deego@gnufans.org>
-;;              Colin Walters <walters@debian.org>
+;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
 
 ;; This file is part of GNU Emacs.
 
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
 ;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY.  No author or distributor
-;; accepts responsibility to anyone for the consequences of using it
-;; or for whether it serves any particular purpose or works at all,
-;; unless he says so in writing.  Refer to the GNU Emacs General Public
-;; License for full details.
-
-;; Everyone is granted permission to copy, modify and redistribute
-;; GNU Emacs, but only under the conditions described in the
-;; GNU Emacs General Public License.   A copy of this license is
-;; supposed to have been given to you along with GNU Emacs so you
-;; can know your rights and responsibilities.  It should be in a
-;; file named COPYING.  Among other things, the copyright notice
-;; and this notice must be preserved on all copies.
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;;; Code:
 
 ;; This file is autoloaded from calc-ext.el.
-(require 'calc-ext)
 
+(require 'calc-ext)
 (require 'calc-macs)
 
-(defun calc-Need-calc-rewr () nil)
+(defvar math-rewrite-default-iters 100)
 
+;; The variable calc-rewr-sel is local to calc-rewrite-selection and 
+;; calc-rewrite, but is used by calc-locate-selection-marker.
+(defvar calc-rewr-sel)
 
-(defvar math-rewrite-default-iters 100)
 (defun calc-rewrite-selection (rules-str &optional many prefix)
   (interactive "sRewrite rule(s): \np")
   (calc-slow-wrapper
    (let* ((num (max 1 (calc-locate-cursor-element (point))))
          (reselect t)
          (pop-rules nil)
+          rules
          (entry (calc-top num 'entry))
          (expr (car entry))
-         (sel (calc-auto-selection entry))
+         (calc-rewr-sel (calc-auto-selection entry))
          (math-rewrite-selections t)
          (math-rewrite-default-iters 1))
      (if (or (null rules-str) (equal rules-str "") (equal rules-str "$"))
      (if (eq many 0)
         (setq many '(var inf var-inf))
        (if many (setq many (prefix-numeric-value many))))
-     (if sel
+     (if calc-rewr-sel
         (setq expr (calc-replace-sub-formula (car entry)
-                                             sel
-                                             (list 'calcFunc-select sel)))
+                                             calc-rewr-sel
+                                             (list 'calcFunc-select calc-rewr-sel)))
        (setq expr (car entry)
             reselect nil
             math-rewrite-selections nil))
                  (math-rewrite
                   (calc-normalize expr)
                   rules many)))
-          sel nil
+          calc-rewr-sel nil
           expr (calc-locate-select-marker expr))
-     (or (consp sel) (setq sel nil))
+     (or (consp calc-rewr-sel) (setq calc-rewr-sel nil))
      (if pop-rules (calc-pop-stack 1))
      (calc-pop-push-record-list 1 (or prefix "rwrt") (list expr)
                                (- num (if pop-rules 1 0))
-                               (list (and reselect sel))))
+                               (list (and reselect calc-rewr-sel))))
    (calc-handle-whys)))
 
-(defun calc-locate-select-marker (expr)    ; changes "sel"
+(defun calc-locate-select-marker (expr)
   (if (Math-primp expr)
       expr
     (if (and (eq (car expr) 'calcFunc-select)
             (= (length expr) 2))
        (progn
-         (setq sel (if sel t (nth 1 expr)))
+         (setq calc-rewr-sel (if calc-rewr-sel t (nth 1 expr)))
          (nth 1 expr))
       (cons (car expr)
            (mapcar 'calc-locate-select-marker (cdr expr))))))
         (setq many '(var inf var-inf))
        (if many (setq many (prefix-numeric-value many))))
      (setq expr (calc-normalize (math-rewrite expr rules many)))
-     (let (sel)
+     (let (calc-rewr-sel)
        (setq expr (calc-locate-select-marker expr)))
      (calc-pop-push-record-list n "rwrt" (list expr)))
    (calc-handle-whys)))
 
-(defun calc-match (pat)
-  (interactive "sPattern: \n")
+(defun calc-match (pat &optional interactive)
+  (interactive "sPattern: \np")
   (calc-slow-wrapper
    (let (n expr)
      (if (or (null pat) (equal pat "") (equal pat "$"))
         (setq expr (calc-top-n 2)
               pat (calc-top-n 1)
               n 2)
-       (if (interactive-p) (setq calc-previous-alg-entry pat))
        (setq pat (if (stringp pat) (math-read-expr pat) pat))
        (if (eq (car-safe pat) 'error)
           (error "Bad format in expression: %s" (nth 1 pat)))
        (calc-enter-result n "mtch" (math-match-patterns pat expr nil))))))
 
 
-
-(defun math-rewrite (whole-expr rules &optional mmt-many)
-  (let ((crules (math-compile-rewrites rules))
-       (heads (math-rewrite-heads whole-expr))
-       (trace-buffer (get-buffer "*Trace*"))
-       (calc-display-just 'center)
-       (calc-display-origin 39)
-       (calc-line-breaking 78)
-       (calc-line-numbering nil)
-       (calc-show-selections t)
-       (calc-why nil)
-       (mmt-func (function
-                  (lambda (x)
-                    (let ((result (math-apply-rewrites x (cdr crules)
-                                                       heads crules)))
-                      (if result
-                          (progn
-                            (if trace-buffer
-                                (let ((fmt (math-format-stack-value
-                                            (list result nil nil))))
-                                  (save-excursion
-                                    (set-buffer trace-buffer)
-                                    (insert "\nrewrite to\n" fmt "\n"))))
-                            (setq heads (math-rewrite-heads result heads t))))
-                      result)))))
+(defvar math-mt-many)
+
+;; The variable math-rewrite-whole-expr is local to math-rewrite,
+;; but is used by math-rewrite-phase
+(defvar math-rewrite-whole-expr)
+
+(defun math-rewrite (math-rewrite-whole-expr rules &optional math-mt-many)
+  (let* ((crules (math-compile-rewrites rules))
+         (heads (math-rewrite-heads math-rewrite-whole-expr))
+         (trace-buffer (get-buffer "*Trace*"))
+         (calc-display-just 'center)
+         (calc-display-origin 39)
+         (calc-line-breaking 78)
+         (calc-line-numbering nil)
+         (calc-show-selections t)
+         (calc-why nil)
+         (math-mt-func (function
+                        (lambda (x)
+                          (let ((result (math-apply-rewrites x (cdr crules)
+                                                             heads crules)))
+                            (if result
+                                (progn
+                                  (if trace-buffer
+                                      (let ((fmt (math-format-stack-value
+                                                  (list result nil nil))))
+                                        (with-current-buffer trace-buffer
+                                          (insert "\nrewrite to\n" fmt "\n"))))
+                                  (setq heads (math-rewrite-heads result heads t))))
+                            result)))))
     (if trace-buffer
-       (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
-         (save-excursion
-           (set-buffer trace-buffer)
+       (let ((fmt (math-format-stack-value (list math-rewrite-whole-expr nil nil))))
+         (with-current-buffer trace-buffer
            (setq truncate-lines t)
            (goto-char (point-max))
            (insert "\n\nBegin rewriting\n" fmt "\n"))))
-    (or mmt-many (setq mmt-many (or (nth 1 (car crules))
+    (or math-mt-many (setq math-mt-many (or (nth 1 (car crules))
                                    math-rewrite-default-iters)))
-    (if (equal mmt-many '(var inf var-inf)) (setq mmt-many 1000000))
-    (if (equal mmt-many '(neg (var inf var-inf))) (setq mmt-many -1000000))
+    (if (equal math-mt-many '(var inf var-inf)) (setq math-mt-many 1000000))
+    (if (equal math-mt-many '(neg (var inf var-inf))) (setq math-mt-many -1000000))
     (math-rewrite-phase (nth 3 (car crules)))
     (if trace-buffer
-       (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
-         (save-excursion
-           (set-buffer trace-buffer)
+       (let ((fmt (math-format-stack-value (list math-rewrite-whole-expr nil nil))))
+         (with-current-buffer trace-buffer
            (insert "\nDone rewriting"
-                   (if (= mmt-many 0) " (reached iteration limit)" "")
+                   (if (= math-mt-many 0) " (reached iteration limit)" "")
                    ":\n" fmt "\n"))))
-    whole-expr))
+    math-rewrite-whole-expr))
 
 (defun math-rewrite-phase (sched)
-  (while (and sched (/= mmt-many 0))
+  (while (and sched (/= math-mt-many 0))
     (if (listp (car sched))
-       (while (let ((save-expr whole-expr))
+       (while (let ((save-expr math-rewrite-whole-expr))
                 (math-rewrite-phase (car sched))
-                (not (equal whole-expr save-expr))))
+                (not (equal math-rewrite-whole-expr save-expr))))
       (if (symbolp (car sched))
          (progn
-           (setq whole-expr (math-normalize (list (car sched) whole-expr)))
+           (setq math-rewrite-whole-expr 
+                  (math-normalize (list (car sched) math-rewrite-whole-expr)))
            (if trace-buffer
                (let ((fmt (math-format-stack-value
-                           (list whole-expr nil nil))))
-                 (save-excursion
-                   (set-buffer trace-buffer)
+                           (list math-rewrite-whole-expr nil nil))))
+                 (with-current-buffer trace-buffer
                    (insert "\ncall "
                            (substring (symbol-name (car sched)) 9)
                            ":\n" fmt "\n")))))
        (let ((math-rewrite-phase (car sched)))
          (if trace-buffer
-             (save-excursion
-               (set-buffer trace-buffer)
+             (with-current-buffer trace-buffer
                (insert (format "\n(Phase %d)\n" math-rewrite-phase))))
-         (while (let ((save-expr whole-expr))
-                  (setq whole-expr (math-normalize
-                                    (math-map-tree-rec whole-expr)))
-                  (not (equal whole-expr save-expr)))))))
+         (while (let ((save-expr math-rewrite-whole-expr))
+                  (setq math-rewrite-whole-expr (math-normalize
+                                    (math-map-tree-rec math-rewrite-whole-expr)))
+                  (not (equal math-rewrite-whole-expr save-expr)))))))
     (setq sched (cdr sched))))
 
 (defun calcFunc-rewrite (expr rules &optional many)
 
 
 
-;;; A compiled rule set is an a-list of entries whose cars are functors,
-;;; and whose cdrs are lists of rules.  If there are rules with no
-;;; well-defined head functor, they are included on all lists and also
-;;; on an extra list whose car is nil.
-;;;
-;;; The first entry in the a-list is of the form (schedule A B C ...).
-;;;
-;;; Rule list entries take the form (regs prog head phases), where:
-;;;
-;;;   regs   is a vector of match registers.
-;;;
-;;;   prog   is a match program (see below).
-;;;
-;;;   head   is a rare function name appearing in the rule body (but not the
-;;;         head of the whole rule), or nil if none.
-;;;
-;;;   phases is a list of phase numbers for which the rule is enabled.
-;;;
-;;; A match program is a list of match instructions.
-;;;
-;;; In the following, "part" is a register number that contains the
-;;; subexpression to be operated on.
-;;;
-;;; Register 0 is the whole expression being matched.  The others are
-;;; meta-variables in the pattern, temporaries used for matching and
-;;; backtracking, and constant expressions.
-;;;
-;;; (same part reg)
-;;;         The selected part must be math-equal to the contents of "reg".
-;;;
-;;; (same-neg part reg)
-;;;         The selected part must be math-equal to the negative of "reg".
-;;;
-;;; (copy part reg)
-;;;        The selected part is copied into "reg".  (Rarely used.)
-;;;
-;;; (copy-neg part reg)
-;;;        The negative of the selected part is copied into "reg".
-;;;
-;;; (integer part)
-;;;         The selected part must be an integer.
-;;;
-;;; (real part)
-;;;         The selected part must be a real.
-;;;
-;;; (constant part)
-;;;         The selected part must be a constant.
-;;;
-;;; (negative part)
-;;;        The selected part must "look" negative.
-;;;
-;;; (rel part op reg)
-;;;         The selected part must satisfy "part op reg", where "op"
-;;;        is one of the 6 relational ops, and "reg" is a register.
-;;;
-;;; (mod part modulo value)
-;;;         The selected part must satisfy "part % modulo = value", where
-;;;         "modulo" and "value" are constants.
-;;;
-;;; (func part head reg1 reg2 ... regn)
-;;;         The selected part must be an n-ary call to function "head".
-;;;         The arguments are stored in "reg1" through "regn".
-;;;
-;;; (func-def part head defs reg1 reg2 ... regn)
-;;;        The selected part must be an n-ary call to function "head".
-;;;        "Defs" is a list of value/register number pairs for default args.
-;;;        If a match, assign default values to registers and then skip
-;;;        immediately over any following "func-def" instructions and
-;;;        the following "func" instruction.  If wrong number of arguments,
-;;;        proceed to the following "func-def" or "func" instruction.
-;;;
-;;; (func-opt part head defs reg1)
-;;;        Like func-def with "n=1", except that if the selected part is
-;;;        not a call to "head", then the part itself successfully matches
-;;;        "reg1" (and the defaults are assigned).
-;;;
-;;; (try part heads mark reg1 [def])
-;;;         The selected part must be a function of the correct type which is
-;;;         associative and/or commutative.  "Heads" is a list of acceptable
-;;;         types.  An initial assignment of arguments to "reg1" is tried.
-;;;        If the program later fails, it backtracks to this instruction
-;;;        and tries other assignments of arguments to "reg1".
-;;;        If "def" exists and normal matching fails, backtrack and assign
-;;;        "part" to "reg1", and "def" to "reg2" in the following "try2".
-;;;        The "mark" is a vector of size 5; only "mark[3-4]" are initialized.
-;;;        "mark[0]" points to the argument list; "mark[1]" points to the
-;;;        current argument; "mark[2]" is 0 if there are two arguments,
-;;;        1 if reg1 is matching single arguments, 2 if reg2 is matching
-;;;        single arguments (a+b+c+d is never split as (a+b)+(c+d)), or
-;;;         3 if reg2 is matching "def"; "mark[3]" is 0 if the function must
-;;;        have two arguments, 1 if phase-2 can be skipped, 2 if full
-;;;        backtracking is necessary; "mark[4]" is t if the arguments have
-;;;        been switched from the order given in the original pattern.
-;;;
-;;; (try2 try reg2)
-;;;         Every "try" will be followed by a "try2" whose "try" field is
-;;;        a pointer to the corresponding "try".  The arguments which were
-;;;        not stored in "reg1" by that "try" are now stored in "reg2".
-;;;
-;;; (alt instr nil mark)
-;;;        Basic backtracking.  Execute the instruction sequence "instr".
-;;;        If this fails, back up and execute following the "alt" instruction.
-;;;        The "mark" must be the vector "[nil nil 4]".  The "instr" sequence
-;;;        should execute "end-alt" at the end.
-;;;
-;;; (end-alt ptr)
-;;;        Register success of the first alternative of a previous "alt".
-;;;        "Ptr" is a pointer to the next instruction following that "alt".
-;;;
-;;; (apply part reg1 reg2)
-;;;         The selected part must be a function call.  The functor
-;;;        (as a variable name) is stored in "reg1"; the arguments
-;;;        (as a vector) are stored in "reg2".
-;;;
-;;; (cons part reg1 reg2)
-;;;        The selected part must be a nonempty vector.  The first element
-;;;        of the vector is stored in "reg1"; the rest of the vector
-;;;        (as another vector) is stored in "reg2".
-;;;
-;;; (rcons part reg1 reg2)
-;;;        The selected part must be a nonempty vector.  The last element
-;;;        of the vector is stored in "reg2"; the rest of the vector
-;;;        (as another vector) is stored in "reg1".
-;;;
-;;; (select part reg)
-;;;         If the selected part is a unary call to function "select", its
-;;;         argument is stored in "reg"; otherwise (provided this is an `a r'
-;;;         and not a `g r' command) the selected part is stored in "reg".
-;;;
-;;; (cond expr)
-;;;         The "expr", with registers substituted, must simplify to
-;;;         a non-zero value.
-;;;
-;;; (let reg expr)
-;;;         Evaluate "expr" and store the result in "reg".  Always succeeds.
-;;;
-;;; (done rhs remember)
-;;;         Rewrite the expression to "rhs", with register substituted.
-;;;        Normalize; if the result is different from the original
-;;;        expression, the match has succeeded.  This is the last
-;;;        instruction of every program.  If "remember" is non-nil,
-;;;         record the result of the match as a new literal rule.
-
-
-;;; Pseudo-functions related to rewrites:
-;;;
-;;;  In patterns:  quote, plain, condition, opt, apply, cons, select
-;;;
-;;;  In righthand sides:  quote, plain, eval, evalsimp, evalextsimp,
-;;;                       apply, cons, select
-;;;
-;;;  In conditions:  let + same as for righthand sides
-
-;;; Some optimizations that would be nice to have:
-;;;
-;;;  * Merge registers with disjoint lifetimes.
-;;;  * Merge constant registers with equivalent values.
-;;;
-;;;  * If an argument of a commutative op math-depends neither on the
-;;;    rest of the pattern nor on any of the conditions, then no backtracking
-;;;    should be done for that argument.  (This won't apply to very many
-;;;    cases.)
-;;;
-;;;  * If top functor is "select", and its argument is a unique function,
-;;;    add the rule to the lists for both "select" and that function.
-;;;    (Currently rules like this go on the "nil" list.)
-;;;    Same for "func-opt" functions.  (Though not urgent for these.)
-;;;
-;;;  * Shouldn't evaluate a "let" condition until the end, or until it
-;;;    would enable another condition to be evaluated.
-;;;
-
-;;; Some additional features to add / things to think about:
+;; A compiled rule set is an a-list of entries whose cars are functors,
+;; and whose cdrs are lists of rules.  If there are rules with no
+;; well-defined head functor, they are included on all lists and also
+;; on an extra list whose car is nil.
+;;
+;; The first entry in the a-list is of the form (schedule A B C ...).
+;;
+;; Rule list entries take the form (regs prog head phases), where:
+;;
+;;   regs   is a vector of match registers.
+;;
+;;   prog   is a match program (see below).
+;;
+;;   head   is a rare function name appearing in the rule body (but not the
+;;          head of the whole rule), or nil if none.
+;;
+;;   phases is a list of phase numbers for which the rule is enabled.
+;;
+;; A match program is a list of match instructions.
+;;
+;; In the following, "part" is a register number that contains the
+;; subexpression to be operated on.
+;;
+;; Register 0 is the whole expression being matched.  The others are
+;; meta-variables in the pattern, temporaries used for matching and
+;; backtracking, and constant expressions.
+;;
+;; (same part reg)
+;;         The selected part must be math-equal to the contents of "reg".
+;;
+;; (same-neg part reg)
+;;         The selected part must be math-equal to the negative of "reg".
+;;
+;; (copy part reg)
+;;         The selected part is copied into "reg".  (Rarely used.)
+;;
+;; (copy-neg part reg)
+;;         The negative of the selected part is copied into "reg".
+;;
+;; (integer part)
+;;         The selected part must be an integer.
+;;
+;; (real part)
+;;         The selected part must be a real.
+;;
+;; (constant part)
+;;         The selected part must be a constant.
+;;
+;; (negative part)
+;;         The selected part must "look" negative.
+;;
+;; (rel part op reg)
+;;         The selected part must satisfy "part op reg", where "op"
+;;         is one of the 6 relational ops, and "reg" is a register.
+;;
+;; (mod part modulo value)
+;;         The selected part must satisfy "part % modulo = value", where
+;;         "modulo" and "value" are constants.
+;;
+;; (func part head reg1 reg2 ... regn)
+;;         The selected part must be an n-ary call to function "head".
+;;         The arguments are stored in "reg1" through "regn".
+;;
+;; (func-def part head defs reg1 reg2 ... regn)
+;;         The selected part must be an n-ary call to function "head".
+;;         "Defs" is a list of value/register number pairs for default args.
+;;         If a match, assign default values to registers and then skip
+;;         immediately over any following "func-def" instructions and
+;;         the following "func" instruction.  If wrong number of arguments,
+;;         proceed to the following "func-def" or "func" instruction.
+;;
+;; (func-opt part head defs reg1)
+;;         Like func-def with "n=1", except that if the selected part is
+;;         not a call to "head", then the part itself successfully matches
+;;         "reg1" (and the defaults are assigned).
+;;
+;; (try part heads mark reg1 [def])
+;;         The selected part must be a function of the correct type which is
+;;         associative and/or commutative.  "Heads" is a list of acceptable
+;;         types.  An initial assignment of arguments to "reg1" is tried.
+;;         If the program later fails, it backtracks to this instruction
+;;         and tries other assignments of arguments to "reg1".
+;;         If "def" exists and normal matching fails, backtrack and assign
+;;         "part" to "reg1", and "def" to "reg2" in the following "try2".
+;;         The "mark" is a vector of size 5; only "mark[3-4]" are initialized.
+;;         "mark[0]" points to the argument list; "mark[1]" points to the
+;;         current argument; "mark[2]" is 0 if there are two arguments,
+;;         1 if reg1 is matching single arguments, 2 if reg2 is matching
+;;         single arguments (a+b+c+d is never split as (a+b)+(c+d)), or
+;;         3 if reg2 is matching "def"; "mark[3]" is 0 if the function must
+;;         have two arguments, 1 if phase-2 can be skipped, 2 if full
+;;         backtracking is necessary; "mark[4]" is t if the arguments have
+;;         been switched from the order given in the original pattern.
+;;
+;; (try2 try reg2)
+;;         Every "try" will be followed by a "try2" whose "try" field is
+;;         a pointer to the corresponding "try".  The arguments which were
+;;         not stored in "reg1" by that "try" are now stored in "reg2".
+;;
+;; (alt instr nil mark)
+;;         Basic backtracking.  Execute the instruction sequence "instr".
+;;         If this fails, back up and execute following the "alt" instruction.
+;;         The "mark" must be the vector "[nil nil 4]".  The "instr" sequence
+;;         should execute "end-alt" at the end.
+;;
+;; (end-alt ptr)
+;;         Register success of the first alternative of a previous "alt".
+;;         "Ptr" is a pointer to the next instruction following that "alt".
+;;
+;; (apply part reg1 reg2)
+;;         The selected part must be a function call.  The functor
+;;         (as a variable name) is stored in "reg1"; the arguments
+;;         (as a vector) are stored in "reg2".
+;;
+;; (cons part reg1 reg2)
+;;         The selected part must be a nonempty vector.  The first element
+;;         of the vector is stored in "reg1"; the rest of the vector
+;;         (as another vector) is stored in "reg2".
+;;
+;; (rcons part reg1 reg2)
+;;         The selected part must be a nonempty vector.  The last element
+;;         of the vector is stored in "reg2"; the rest of the vector
+;;         (as another vector) is stored in "reg1".
+;;
+;; (select part reg)
+;;         If the selected part is a unary call to function "select", its
+;;         argument is stored in "reg"; otherwise (provided this is an `a r'
+;;         and not a `g r' command) the selected part is stored in "reg".
+;;
+;; (cond expr)
+;;         The "expr", with registers substituted, must simplify to
+;;         a non-zero value.
+;;
+;; (let reg expr)
+;;         Evaluate "expr" and store the result in "reg".  Always succeeds.
+;;
+;; (done rhs remember)
+;;         Rewrite the expression to "rhs", with register substituted.
+;;         Normalize; if the result is different from the original
+;;         expression, the match has succeeded.  This is the last
+;;         instruction of every program.  If "remember" is non-nil,
+;;         record the result of the match as a new literal rule.
+
+
+;; Pseudo-functions related to rewrites:
+;;
+;;  In patterns:  quote, plain, condition, opt, apply, cons, select
+;;
+;;  In righthand sides:  quote, plain, eval, evalsimp, evalextsimp,
+;;                       apply, cons, select
+;;
+;;  In conditions:  let + same as for righthand sides
+
+;; Some optimizations that would be nice to have:
+;;
+;;  * Merge registers with disjoint lifetimes.
+;;  * Merge constant registers with equivalent values.
+;;
+;;  * If an argument of a commutative op math-depends neither on the
+;;    rest of the pattern nor on any of the conditions, then no backtracking
+;;    should be done for that argument.  (This won't apply to very many
+;;    cases.)
+;;
+;;  * If top functor is "select", and its argument is a unique function,
+;;    add the rule to the lists for both "select" and that function.
+;;    (Currently rules like this go on the "nil" list.)
+;;    Same for "func-opt" functions.  (Though not urgent for these.)
+;;
+;;  * Shouldn't evaluate a "let" condition until the end, or until it
+;;    would enable another condition to be evaluated.
+;;
+
+;; Some additional features to add / things to think about:
 ;;;
 ;;;  * Figure out what happens to "a +/- b" and "a +/- opt(b)".
 ;;;
 
 (defvar math-rewrite-whole nil)
 (defvar math-make-import-list nil)
+
+;; The variable math-import-list is local to part of math-compile-rewrites,
+;; but is also used in a different part, and so the local version could
+;; be affected by the non-local version when math-compile-rewrites calls itself. 
+(defvar math-import-list nil)
+
+;; The variables math-regs, math-num-regs, math-prog-last, math-bound-vars, 
+;; math-conds, math-copy-neg, math-rhs, math-pattern, math-remembering and
+;; math-aliased-vars are local to math-compile-rewrites, 
+;; but are used by many functions math-rwcomp-*, which are called by 
+;; math-compile-rewrites.
+(defvar math-regs)
+(defvar math-num-regs)
+(defvar math-prog-last)
+(defvar math-bound-vars)
+(defvar math-conds)
+(defvar math-copy-neg)
+(defvar math-rhs)
+(defvar math-pattern)
+(defvar math-remembering)
+(defvar math-aliased-vars)
+
 (defun math-compile-rewrites (rules &optional name)
   (if (eq (car-safe rules) 'var)
       (let ((prop (get (nth 2 rules) 'math-rewrite-cache))
              (math-flatten-lands (nth 2 expr)))
     (list expr)))
 
+;; The variables math-rewrite-heads-heads (i.e.; heads for math-rewrite-heads)
+;; math-rewrite-heads-blanks and math-rewrite-heads-skips are local to 
+;; math-rewrite-heads, but used by math-rewrite-heads-rec, which is called by 
+;; math-rewrite-heads.
+(defvar math-rewrite-heads-heads)
+(defvar math-rewrite-heads-skips)
+(defvar math-rewrite-heads-blanks)
+
 (defun math-rewrite-heads (expr &optional more all)
-  (let ((heads more)
-       (skips (and (not all)
+  (let ((math-rewrite-heads-heads more)
+       (math-rewrite-heads-skips (and (not all)
                    '(calcFunc-apply calcFunc-condition calcFunc-opt
                                     calcFunc-por calcFunc-pnot)))
-       (blanks (and (not all)
+       (math-rewrite-heads-blanks (and (not all)
                     '(calcFunc-quote calcFunc-plain calcFunc-select
                                      calcFunc-cons calcFunc-rcons
                                      calcFunc-pand))))
     (or (Math-primp expr)
        (math-rewrite-heads-rec expr))
-    heads))
+    math-rewrite-heads-heads))
 
 (defun math-rewrite-heads-rec (expr)
-  (or (memq (car expr) skips)
+  (or (memq (car expr) math-rewrite-heads-skips)
       (progn
-       (or (memq (car expr) heads)
-           (memq (car expr) blanks)
+       (or (memq (car expr) math-rewrite-heads-heads)
+           (memq (car expr) math-rewrite-heads-blanks)
            (memq 'algebraic (get (car expr) 'math-rewrite-props))
-           (setq heads (cons (car expr) heads)))
+           (setq math-rewrite-heads-heads (cons (car expr) math-rewrite-heads-heads)))
        (while (setq expr (cdr expr))
          (or (Math-primp (car expr))
              (math-rewrite-heads-rec (car expr)))))))
        (list 'neg (list 'calcFunc-register (nth 1 entry)))
       (list 'calcFunc-register (nth 1 entry)))))
 
-(defun math-rwcomp-substitute (expr old new)
-  (if (and (eq (car-safe old) 'var)
-          (memq (car-safe new) '(var calcFunc-lambda)))
-      (let ((old-func (math-var-to-calcFunc old))
-           (new-func (math-var-to-calcFunc new)))
+;; The variables math-rwcomp-subst-old, math-rwcomp-subst-new,
+;; math-rwcomp-subst-old-func and math-rwcomp-subst-new-func
+;; are local to math-rwcomp-substitute, but are used by
+;; math-rwcomp-subst-rec, which is called by math-rwcomp-substitute.
+(defvar math-rwcomp-subst-new)
+(defvar math-rwcomp-subst-old)
+(defvar math-rwcomp-subst-new-func)
+(defvar math-rwcomp-subst-old-func)
+
+(defun math-rwcomp-substitute (expr math-rwcomp-subst-old math-rwcomp-subst-new)
+  (if (and (eq (car-safe math-rwcomp-subst-old) 'var)
+          (memq (car-safe math-rwcomp-subst-new) '(var calcFunc-lambda)))
+      (let ((math-rwcomp-subst-old-func (math-var-to-calcFunc math-rwcomp-subst-old))
+           (math-rwcomp-subst-new-func (math-var-to-calcFunc math-rwcomp-subst-new)))
        (math-rwcomp-subst-rec expr))
-    (let ((old-func nil))
+    (let ((math-rwcomp-subst-old-func nil))
       (math-rwcomp-subst-rec expr))))
 
 (defun math-rwcomp-subst-rec (expr)
-  (cond ((equal expr old) new)
+  (cond ((equal expr math-rwcomp-subst-old) math-rwcomp-subst-new)
        ((Math-primp expr) expr)
-       (t (if (eq (car expr) old-func)
-              (math-build-call new-func (mapcar 'math-rwcomp-subst-rec
-                                                (cdr expr)))
+       (t (if (eq (car expr) math-rwcomp-subst-old-func)
+              (math-build-call math-rwcomp-subst-new-func 
+                                (mapcar 'math-rwcomp-subst-rec
+                                        (cdr expr)))
             (cons (car expr)
                   (mapcar 'math-rwcomp-subst-rec (cdr expr)))))))
 
 (defun math-rwcomp-assoc-args (expr)
   (if (and (eq (car-safe (nth 1 expr)) (car expr))
           (= (length (nth 1 expr)) 3))
-      (math-rwcomp-assoc-args (nth 1 expr))
-    (setq math-args (cons (nth 1 expr) math-args)))
+      (math-rwcomp-assoc-args (nth 1 expr)))
   (if (and (eq (car-safe (nth 2 expr)) (car expr))
           (= (length (nth 2 expr)) 3))
-      (math-rwcomp-assoc-args (nth 2 expr))
-    (setq math-args (cons (nth 2 expr) math-args))))
+      (math-rwcomp-assoc-args (nth 2 expr))))
 
 (defun math-rwcomp-addsub-args (expr)
   (if (memq (car-safe (nth 1 expr)) '(+ -))
-      (math-rwcomp-addsub-args (nth 1 expr))
-    (setq math-args (cons (nth 1 expr) math-args)))
+      (math-rwcomp-addsub-args (nth 1 expr)))
   (if (eq (car expr) '-)
-      (setq math-args (cons (math-rwcomp-neg (nth 2 expr)) math-args))
+      ()
     (if (eq (car-safe (nth 2 expr)) '+)
-       (math-rwcomp-addsub-args (nth 2 expr))
-      (setq math-args (cons (nth 2 expr) math-args)))))
+       (math-rwcomp-addsub-args (nth 2 expr)))))
 
 (defun math-rwcomp-order (a b)
   (< (math-rwcomp-priority (car a))
      (math-rwcomp-priority (car b))))
 
-;;; Order of priority:    0 Constants and other exact matches (first)
-;;;                      10 Functions (except below)
-;;;                     20 Meta-variables which occur more than once
-;;;                     30 Algebraic functions
-;;;                     40 Commutative/associative functions
-;;;                     50 Meta-variables which occur only once
-;;;                   +100 for every "!!!" (pnot) in the pattern
-;;;                  10000 Optional arguments (last)
+;; Order of priority:    0 Constants and other exact matches (first)
+;;                      10 Functions (except below)
+;;                      20 Meta-variables which occur more than once
+;;                      30 Algebraic functions
+;;                      40 Commutative/associative functions
+;;                      50 Meta-variables which occur only once
+;;                    +100 for every "!!!" (pnot) in the pattern
+;;                   10000 Optional arguments (last)
 
 (defun math-rwcomp-priority (expr)
   (+ (math-rwcomp-count-pnots expr)
          (setq count (+ count (math-rwcomp-count-pnots (car expr)))))
        count))))
 
-;;; In the current implementation, all associative functions must
-;;; also be commutative.
+;; In the current implementation, all associative functions must
+;; also be commutative.
 
 (put '+                     'math-rewrite-props '(algebraic assoc commut))
 (put '-                     'math-rewrite-props '(algebraic assoc commut)) ; see below
 (put 'calcFunc-vint  'math-rewrite-props '(assoc commut))
 (put 'calcFunc-vxor  'math-rewrite-props '(assoc commut))
 
-;;; Note: "*" is not commutative for matrix args, but we pretend it is.
-;;; Also, "-" is not commutative but the code tweaks things so that it is.
+;; Note: "*" is not commutative for matrix args, but we pretend it is.
+;; Also, "-" is not commutative but the code tweaks things so that it is.
 
 (put '+                     'math-rewrite-default  0)
 (put '-                     'math-rewrite-default  0)
                'btrack)
              ''((backtrack)))))
 
-;;; This monstrosity is necessary because the use of static vectors of
-;;; registers makes rewrite rules non-reentrant.  Yucko!
+;; This monstrosity is necessary because the use of static vectors of
+;; registers makes rewrite rules non-reentrant.  Yucko!
 (defmacro math-rweval (form)
   (list 'let '((orig (car rules)))
        '(setcar rules (quote (nil nil nil no-phase)))
              form
              '(setcar rules orig))))
 
-(setq math-rewrite-phase 1)
+(defvar math-rewrite-phase 1)
+
+;; The variable math-apply-rw-regs is local to math-apply-rewrites,
+;; but is used by math-rwapply-replace-regs and math-rwapply-reg-looks-negp
+;; which are called by math-apply-rewrites.
+(defvar math-apply-rw-regs)
 
-(defun math-apply-rewrites (expr rules &optional heads ruleset)
+;; The variable math-apply-rw-ruleset is local to math-apply-rewrites,
+;; but is used by math-rwapply-remember.
+(defvar math-apply-rw-ruleset)
+
+(defun math-apply-rewrites (expr rules &optional heads math-apply-rw-ruleset)
   (and
    (setq rules (cdr (or (assq (car-safe expr) rules)
                        (assq nil rules))))
    (let ((result nil)
-        op regs inst part pc mark btrack
+        op math-apply-rw-regs inst part pc mark btrack
         (tracing math-rwcomp-tracing)
         (phase math-rewrite-phase))
      (while rules
        (and (setq part (nth 3 (car rules)))
             (not (memq phase part)))
        (progn
-         (setq regs (car (car rules))
+         (setq math-apply-rw-regs (car (car rules))
                pc (nth 1 (car rules))
                btrack nil)
-         (aset regs 0 expr)
+         (aset math-apply-rw-regs 0 expr)
          (while pc
 
            (and tracing
                 (progn (terpri) (princ (car pc))
                        (if (and (natnump (nth 1 (car pc)))
-                                (< (nth 1 (car pc)) (length regs)))
-                           (princ (format "\n  part = %s"
-                                          (aref regs (nth 1 (car pc))))))))
+                                (< (nth 1 (car pc)) (length math-apply-rw-regs)))
+                           (princ 
+                             (format "\n  part = %s"
+                                     (aref math-apply-rw-regs (nth 1 (car pc))))))))
 
            (cond ((eq (setq op (car (setq inst (car pc)))) 'func)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
+                  (if (and (consp 
+                             (setq part (aref math-apply-rw-regs (car (cdr inst)))))
                            (eq (car part)
                                (car (setq inst (cdr (cdr inst)))))
                            (progn
                              (while (and (setq inst (cdr inst)
                                                part (cdr part))
                                          inst)
-                               (aset regs (car inst) (car part)))
+                               (aset math-apply-rw-regs (car inst) (car part)))
                              (not (or inst part))))
                       (setq pc (cdr pc))
                     (math-rwfail)))
 
                  ((eq op 'same)
-                  (if (or (equal (setq part (aref regs (nth 1 inst)))
-                                 (setq mark (aref regs (nth 2 inst))))
+                  (if (or (equal (setq part (aref math-apply-rw-regs (nth 1 inst)))
+                                 (setq mark (aref math-apply-rw-regs (nth 2 inst))))
                           (Math-equal part mark))
                       (setq pc (cdr pc))
                     (math-rwfail)))
                        calc-matrix-mode
                        (not (eq calc-matrix-mode 'scalar))
                        (eq (car (nth 2 inst)) '*)
-                       (consp (setq part (aref regs (car (cdr inst)))))
+                       (consp (setq part (aref math-apply-rw-regs (car (cdr inst)))))
                        (eq (car part) '*)
                        (not (math-known-scalarp part)))
                   (setq mark (nth 3 inst)
                         pc (cdr pc))
                   (if (aref mark 4)
                       (progn
-                        (aset regs (nth 4 inst) (nth 2 part))
+                        (aset math-apply-rw-regs (nth 4 inst) (nth 2 part))
                         (aset mark 1 (cdr (cdr part))))
-                    (aset regs (nth 4 inst) (nth 1 part))
+                    (aset math-apply-rw-regs (nth 4 inst) (nth 1 part))
                     (aset mark 1 (cdr part)))
                   (aset mark 0 (cdr part))
                   (aset mark 2 0))
 
                  ((eq op 'try)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
+                  (if (and (consp (setq part 
+                                         (aref math-apply-rw-regs (car (cdr inst)))))
                            (memq (car part) (nth 2 inst))
                            (= (length part) 3)
                            (or (not (eq (car part) '/))
                                              op))
                               btrack (cons pc btrack)
                               pc (cdr pc))
-                        (aset regs (nth 2 inst) (car op))
+                        (aset math-apply-rw-regs (nth 2 inst) (car op))
                         (aset mark 0 op)
                         (aset mark 1 op)
                         (aset mark 2 (if (cdr (cdr op)) 1 0)))
                             (progn
                               (setq mark (nth 3 inst)
                                     pc (cdr pc))
-                              (aset regs (nth 4 inst) (nth 1 part))
+                              (aset math-apply-rw-regs (nth 4 inst) (nth 1 part))
                               (aset mark 1 -1)
                               (aset mark 2 4))
                           (setq mark (nth 3 inst)
                                 pc (cdr pc))
-                          (aset regs (nth 4 inst) part)
+                          (aset math-apply-rw-regs (nth 4 inst) part)
                           (aset mark 2 3))
                       (math-rwfail))))
 
                         mark (nth 3 part)
                         op (aref mark 2)
                         pc (cdr pc))
-                  (aset regs (nth 2 inst)
+                  (aset math-apply-rw-regs (nth 2 inst)
                         (cond
                          ((eq op 0)
                           (if (eq (aref mark 0) (aref mark 1))
 
                  ((eq op 'select)
                   (setq pc (cdr pc))
-                  (if (and (consp (setq part (aref regs (nth 1 inst))))
+                  (if (and (consp (setq part (aref math-apply-rw-regs (nth 1 inst))))
                            (eq (car part) 'calcFunc-select))
-                      (aset regs (nth 2 inst) (nth 1 part))
+                      (aset math-apply-rw-regs (nth 2 inst) (nth 1 part))
                     (if math-rewrite-selections
                         (math-rwfail)
-                      (aset regs (nth 2 inst) part))))
+                      (aset math-apply-rw-regs (nth 2 inst) part))))
 
                  ((eq op 'same-neg)
-                  (if (or (equal (setq part (aref regs (nth 1 inst)))
+                  (if (or (equal (setq part (aref math-apply-rw-regs (nth 1 inst)))
                                  (setq mark (math-neg
-                                             (aref regs (nth 2 inst)))))
+                                             (aref math-apply-rw-regs (nth 2 inst)))))
                           (Math-equal part mark))
                       (setq pc (cdr pc))
                     (math-rwfail)))
                         op (aref mark 2))
                   (cond ((eq op 0)
                          (if (setq op (cdr (aref mark 1)))
-                             (aset regs (nth 4 inst) (car (aset mark 1 op)))
+                             (aset math-apply-rw-regs (nth 4 inst) 
+                                    (car (aset mark 1 op)))
                            (if (nth 5 inst)
                                (progn
                                  (aset mark 2 3)
-                                 (aset regs (nth 4 inst)
-                                       (aref regs (nth 1 inst))))
+                                 (aset math-apply-rw-regs (nth 4 inst)
+                                       (aref math-apply-rw-regs (nth 1 inst))))
                              (math-rwfail t))))
                         ((eq op 1)
                          (if (setq op (cdr (aref mark 1)))
-                             (aset regs (nth 4 inst) (car (aset mark 1 op)))
+                             (aset math-apply-rw-regs (nth 4 inst) 
+                                    (car (aset mark 1 op)))
                            (if (= (aref mark 3) 1)
                                (if (nth 5 inst)
                                    (progn
                                      (aset mark 2 3)
-                                     (aset regs (nth 4 inst)
-                                           (aref regs (nth 1 inst))))
+                                     (aset math-apply-rw-regs (nth 4 inst)
+                                           (aref math-apply-rw-regs (nth 1 inst))))
                                  (math-rwfail t))
                              (aset mark 2 2)
                              (aset mark 1 (cons nil (aref mark 0)))
                                                   (list '- part
                                                         (nth 1 (car mark)))
                                                 (list op part (car mark))))))
-                               (aset regs (nth 4 inst) part))
+                               (aset math-apply-rw-regs (nth 4 inst) part))
                            (if (nth 5 inst)
                                (progn
                                  (aset mark 2 3)
-                                 (aset regs (nth 4 inst)
-                                       (aref regs (nth 1 inst))))
+                                 (aset math-apply-rw-regs (nth 4 inst)
+                                       (aref math-apply-rw-regs (nth 1 inst))))
                              (math-rwfail t))))
                         ((eq op 4)
                          (setq btrack (cdr btrack)))
                         (t (math-rwfail t))))
 
                  ((eq op 'integer)
-                  (if (Math-integerp (setq part (aref regs (nth 1 inst))))
+                  (if (Math-integerp (setq part 
+                                            (aref math-apply-rw-regs (nth 1 inst))))
                       (setq pc (cdr pc))
                     (if (Math-primp part)
                         (math-rwfail)
                         (math-rwfail)))))
 
                  ((eq op 'real)
-                  (if (Math-realp (setq part (aref regs (nth 1 inst))))
+                  (if (Math-realp (setq part (aref math-apply-rw-regs (nth 1 inst))))
                       (setq pc (cdr pc))
                     (if (Math-primp part)
                         (math-rwfail)
                         (math-rwfail)))))
 
                  ((eq op 'constant)
-                  (if (math-constp (setq part (aref regs (nth 1 inst))))
+                  (if (math-constp (setq part (aref math-apply-rw-regs (nth 1 inst))))
                       (setq pc (cdr pc))
                     (if (Math-primp part)
                         (math-rwfail)
                         (math-rwfail)))))
 
                  ((eq op 'negative)
-                  (if (math-looks-negp (setq part (aref regs (nth 1 inst))))
+                  (if (math-looks-negp (setq part 
+                                              (aref math-apply-rw-regs (nth 1 inst))))
                       (setq pc (cdr pc))
                     (if (Math-primp part)
                         (math-rwfail)
                         (math-rwfail)))))
 
                  ((eq op 'rel)
-                  (setq part (math-compare (aref regs (nth 1 inst))
-                                           (aref regs (nth 3 inst)))
+                  (setq part (math-compare (aref math-apply-rw-regs (nth 1 inst))
+                                           (aref math-apply-rw-regs (nth 3 inst)))
                         op (nth 2 inst))
                   (if (= part 2)
                       (setq part (math-rweval
                                   (math-simplify
                                    (calcFunc-sign
-                                    (math-sub (aref regs (nth 1 inst))
-                                              (aref regs (nth 3 inst))))))))
+                                    (math-sub 
+                                      (aref math-apply-rw-regs (nth 1 inst))
+                                      (aref math-apply-rw-regs (nth 3 inst))))))))
                   (if (cond ((eq op 'calcFunc-eq)
                              (eq part 0))
                             ((eq op 'calcFunc-neq)
                     (math-rwfail)))
 
                  ((eq op 'func-def)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
-                           (eq (car part)
-                               (car (setq inst (cdr (cdr inst))))))
+                  (if (and 
+                        (consp (setq part (aref math-apply-rw-regs (car (cdr inst)))))
+                        (eq (car part)
+                            (car (setq inst (cdr (cdr inst))))))
                       (progn
                         (setq inst (cdr inst)
                               mark (car inst))
                         (while (and (setq inst (cdr inst)
                                           part (cdr part))
                                     inst)
-                          (aset regs (car inst) (car part)))
+                          (aset math-apply-rw-regs (car inst) (car part)))
                         (if (or inst part)
                             (setq pc (cdr pc))
                           (while (eq (car (car (setq pc (cdr pc))))
                                      'func-def))
                           (setq pc (cdr pc))   ; skip over "func"
                           (while mark
-                            (aset regs (cdr (car mark)) (car (car mark)))
+                            (aset math-apply-rw-regs (cdr (car mark)) (car (car mark)))
                             (setq mark (cdr mark)))))
                     (math-rwfail)))
 
                  ((eq op 'func-opt)
-                  (if (or (not (and (consp
-                                     (setq part (aref regs (car (cdr inst)))))
-                                    (eq (car part) (nth 2 inst))))
+                  (if (or (not 
+                            (and 
+                             (consp
+                              (setq part (aref math-apply-rw-regs (car (cdr inst)))))
+                             (eq (car part) (nth 2 inst))))
                           (and (= (length part) 2)
                                (setq part (nth 1 part))))
                       (progn
                         (setq mark (nth 3 inst))
-                        (aset regs (nth 4 inst) part)
+                        (aset math-apply-rw-regs (nth 4 inst) part)
                         (while (eq (car (car (setq pc (cdr pc)))) 'func-def))
                         (setq pc (cdr pc))   ; skip over "func"
                         (while mark
-                          (aset regs (cdr (car mark)) (car (car mark)))
+                          (aset math-apply-rw-regs (cdr (car mark)) (car (car mark)))
                           (setq mark (cdr mark))))
                     (setq pc (cdr pc))))
 
                  ((eq op 'mod)
-                  (if (if (Math-zerop (setq part (aref regs (nth 1 inst))))
+                  (if (if (Math-zerop 
+                            (setq part (aref math-apply-rw-regs (nth 1 inst))))
                           (Math-zerop (nth 3 inst))
                         (and (not (Math-zerop (nth 2 inst)))
                              (progn
                     (math-rwfail)))
 
                  ((eq op 'apply)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
+                  (if (and (consp 
+                             (setq part (aref math-apply-rw-regs (car (cdr inst)))))
                            (not (Math-objvecp part))
                            (not (eq (car part) 'var)))
                       (progn
-                        (aset regs (nth 2 inst)
+                        (aset math-apply-rw-regs (nth 2 inst)
                               (math-calcFunc-to-var (car part)))
-                        (aset regs (nth 3 inst)
+                        (aset math-apply-rw-regs (nth 3 inst)
                               (cons 'vec (cdr part)))
                         (setq pc (cdr pc)))
                     (math-rwfail)))
 
                  ((eq op 'cons)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
+                  (if (and (consp 
+                             (setq part (aref math-apply-rw-regs (car (cdr inst)))))
                            (eq (car part) 'vec)
                            (cdr part))
                       (progn
-                        (aset regs (nth 2 inst) (nth 1 part))
-                        (aset regs (nth 3 inst) (cons 'vec (cdr (cdr part))))
+                        (aset math-apply-rw-regs (nth 2 inst) (nth 1 part))
+                        (aset math-apply-rw-regs (nth 3 inst) 
+                               (cons 'vec (cdr (cdr part))))
                         (setq pc (cdr pc)))
                     (math-rwfail)))
 
                  ((eq op 'rcons)
-                  (if (and (consp (setq part (aref regs (car (cdr inst)))))
+                  (if (and (consp 
+                             (setq part (aref math-apply-rw-regs (car (cdr inst)))))
                            (eq (car part) 'vec)
                            (cdr part))
                       (progn
-                        (aset regs (nth 2 inst) (calcFunc-rhead part))
-                        (aset regs (nth 3 inst) (calcFunc-rtail part))
+                        (aset math-apply-rw-regs (nth 2 inst) (calcFunc-rhead part))
+                        (aset math-apply-rw-regs (nth 3 inst) (calcFunc-rtail part))
                         (setq pc (cdr pc)))
                     (math-rwfail)))
 
                     (math-rwfail)))
 
                  ((eq op 'let)
-                  (aset regs (nth 1 inst)
+                  (aset math-apply-rw-regs (nth 1 inst)
                         (math-rweval
                          (math-normalize
                           (math-rwapply-replace-regs (nth 2 inst)))))
                   (setq pc (cdr pc)))
 
                  ((eq op 'copy)
-                  (aset regs (nth 2 inst) (aref regs (nth 1 inst)))
+                  (aset math-apply-rw-regs (nth 2 inst) 
+                         (aref math-apply-rw-regs (nth 1 inst)))
                   (setq pc (cdr pc)))
 
                  ((eq op 'copy-neg)
-                  (aset regs (nth 2 inst)
-                        (math-rwapply-neg (aref regs (nth 1 inst))))
+                  (aset math-apply-rw-regs (nth 2 inst)
+                        (math-rwapply-neg (aref math-apply-rw-regs (nth 1 inst))))
                   (setq pc (cdr pc)))
 
                  ((eq op 'alt)
   (cond ((Math-primp expr)
         expr)
        ((eq (car expr) 'calcFunc-register)
-        (setq expr (aref regs (nth 1 expr)))
+        (setq expr (aref math-apply-rw-regs (nth 1 expr)))
         (if (eq (car-safe expr) '*)
             (if (eq (nth 1 expr) -1)
                 (math-neg (nth 2 expr))
         (math-rwapply-reg-neg (nth 1 expr)))
        ((and (eq (car expr) 'neg)
              (eq (car-safe (nth 1 expr)) 'calcFunc-register)
-             (math-scalarp (aref regs (nth 1 (nth 1 expr)))))
+             (math-scalarp (aref math-apply-rw-regs (nth 1 (nth 1 expr)))))
         (math-neg (math-rwapply-replace-regs (nth 1 expr))))
        ((and (eq (car expr) '+)
              (math-rwapply-reg-looks-negp (nth 1 expr)))
         (if (Math-primp (nth 1 expr))
             (nth 1 expr)
           (if (eq (car (nth 1 expr)) 'calcFunc-register)
-              (aref regs (nth 1 (nth 1 expr)))
+              (aref math-apply-rw-regs (nth 1 (nth 1 expr)))
             (cons (car (nth 1 expr)) (mapcar 'math-rwapply-replace-regs
                                              (cdr (nth 1 expr)))))))
        (t (cons (car expr) (mapcar 'math-rwapply-replace-regs (cdr expr))))))
 
 (defun math-rwapply-reg-looks-negp (expr)
   (if (eq (car-safe expr) 'calcFunc-register)
-      (math-looks-negp (aref regs (nth 1 expr)))
+      (math-looks-negp (aref math-apply-rw-regs (nth 1 expr)))
     (if (memq (car-safe expr) '(* /))
        (or (math-rwapply-reg-looks-negp (nth 1 expr))
            (math-rwapply-reg-looks-negp (nth 2 expr))))))
                                       (math-rwapply-reg-neg (nth 2 expr)))))))
 
 (defun math-rwapply-remember (old new)
-  (let ((varval (symbol-value (nth 2 (car ruleset))))
-       (rules (assq (car-safe old) ruleset)))
+  (let ((varval (symbol-value (nth 2 (car math-apply-rw-ruleset))))
+       (rules (assq (car-safe old) math-apply-rw-ruleset)))
     (if (and (eq (car-safe varval) 'vec)
             (not (memq (car-safe old) '(nil schedule + -)))
             rules)
                                    nil nil)
                              (cdr rules)))))))
 
-;;; arch-tag: ca8d7b7d-bff1-4535-90f3-e2241f5e786b
+(provide 'calc-rewr)
+
+;; arch-tag: ca8d7b7d-bff1-4535-90f3-e2241f5e786b
 ;;; calc-rewr.el ends here