The REDUCE environment consists of all let rules, assignments to algebraic variables, operators and switches. In working with a complicated metric it may be the case that a number of different, sometimes contradictory let rules and assignments may be used. Recalling which variables and let rules have been used, and properly clearing them can require more concentration than the task at hand. Thus, REDTEN has an enhancement to help the user in saving, restoring, and altering the REDUCE environment.
Each time the user makes an algebraic assignment, or declares a new operator, the name of the variable or operator is added to a global lisp list (!*reduce!-environment); this is done through a redefinition of certain REDUCE functions. The function addtoenv() also does this, adding each argument to the REDUCE environment list; with no arguments addtoenv() shows what names are included in the environment list. REDUCE stores let rules on certain lisp variables that are already in the environment list. Indexed objects are not considered to be part of the REDUCE environment, since it would be pointless to have their values restored to an original state after switching to an old environment. The user can, however, use addtoenv() to add an indexed object to the environment, presumably after it has reached some checkpoint state in simplification. Similarly, other objects created in REDUCE by means other than an assignment or operator command (eg. arrays) will not automatically be included in the environment, but can be added with addtoenv().
As a general rule, the portion of the environment that changes with calls to restorenv() should involve secondary variables: those which are part of some larger expression plus let rules, and not the primary expression(s) being worked upon. Otherwise, as with indexed objects, it would defeat the purpose of having different environments. For reasons explained below, rather than providing a means to remove a symbol from the environment list, REDTEN allows the user to flag a variable so that its value will remain intact during environment switches. The flag keep prevents the system from saving or altering the value of a variable, it can be set via the command
#: lisp flag ('(var1, {var2}, ...), 'keep);Certain variables are already flagged keep and retain their values and property lists despite changing environments. Among these are currentmetric and reduce!-environment. Aside from the problem of losing a value if the environment is switched and the work variable is not flagged keep, it may well be that storing the values for this variable several times for the saved environments could lead to memory problems.
To save an environment requires that the property lists and lisp values of each symbol in the reduce environment be copied to some location, so that they can later be restored. The location used is based on the user-given name for the environment being saved. The restoration of a named environment copies back this information and overwrites the current property lists and values, thus changing the current set of assignments, operators and let rules. If the current environment is required for future use it must be saved first. If an environment is being restored in which a new operator etc. was not defined, that operator etc. will dissappear from the restored environment, but of course can returned if the current environment was saved. A named environment cannot be changed in any way, but it can always be restored, changed, and re-saved.
The primary functions that handle the saving and restoring of the REDUCE environment are savenv() and restorenv(). With no arguments, savenv() prints a list of the currently saved environments. When REDTEN is started, it saves the current environment as ``initial'' (note that the environment name is an id, not a string). With a name as its single argument, savenv() saves the current environment with that name. The same name may be used to have restorenv() restore the environment. restorenv() will also save the current environment with the name ``current'', but note that this will be overwritten with each new restore. With no argument, restorenv() restores the last saved environment. If the argument given to restorenv() is not that of a valid environment, an error results.
Other useful functions are newenv(), swapenv(), delenv(), and renamenv(). newenv() saves the current environment as either ``current'' or named by its single argument, then restores the ``initial'' environment. It is equivalent to savenv(<name>); restorenv(initial). swapenv() allows the user to quickly flip back and forth between two environments. Calling swapenv() with a single argument switches to that environment. Calling swapenv() again, with a different argument switches to the new environment. Thereafter, calling swapenv() with no arguments switches between the two environments. At any time, the user can begin switching to a different environment by calling swapenv() with a name. The swapping pair can be set up more quickly by giving two arguments, the first is made the current environment. Note that any changes made to the current environment will be temporarily saved under ``current'' when the environment changes, but will be lost after repeated switches. delenv() deletes the environment associated with the given argument, its main use is to clean up the system. renamenv() can be used to grab the current environment as saved by restorenv() and move it to a safe name.
When the switch promptenv is turned on, the REDUCE prompt is changed to indicate the currently named environment. If changes have been made then the prompt also includes a '+' symbol. At system start-up the current environment is ``initial'':
#: on promptenv; (initial) #: a:=34; a := 34 (initial)+ #: savenv(adef); adef (adef) #: