(*^ ::[ frontEndVersion = "Macintosh Mathematica Notebook Front End Version 2.1"; macintoshStandardFontEncoding; paletteColors = 128; automaticGrouping; currentKernel; fontset = title, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, center, M7, bold, e8, 24, "Palatino"; ; fontset = subtitle, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, center, M7, italic, e6, 18, "Palatino"; ; fontset = subsubtitle, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeTitle, grayBox, M21, a20, 18, "Palatino"; ; fontset = section, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, blackBox, bold, a14, e8, 14, "Palatino"; ; fontset = subsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, grayDot, a10, 14, "Palatino"; ; fontset = subsubsection, inactive, noPageBreakBelow, nohscroll, preserveAspect, groupLikeSection, whiteDot, M19, N26, bold, italic, a10, 12, "Palatino"; ; fontset = text, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M18, 12, "Times"; ; fontset = smalltext, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M18, 10, "Times"; ; fontset = input, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeInput, M27, N9, bold, L-5, 9, "Geneva"; ; fontset = output, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M28, N9, L-3, 10, "Courier"; ; fontset = message, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M28, N9, R65535, L-1, a2, e2, 9, "Courier"; ; fontset = print, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M28, N9, L-5, 10, "Courier"; ; fontset = info, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeOutput, M28, N9, B65535, L-5, 10, "Courier"; ; fontset = postscript, PostScript, formatAsPostScript, output, inactive, noPageBreakInGroup, nowordwrap, preserveAspect, groupLikeGraphics, M7, l34, w295, h300, 12, "Courier"; ; fontset = name, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, italic, 10, "Geneva"; ; fontset = header, inactive, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = leftheader, inactive, L2, 12, "Times"; ; fontset = footer, inactive, noKeepOnOnePage, preserveAspect, center, M7, 12, "Times"; ; fontset = leftfooter, inactive, L2, 12, "Times"; ; fontset = help, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 10, "Times"; ; fontset = clipboard, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = completions, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = special1, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M23, 14, "Times"; ; fontset = special2, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = special3, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = special4, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Times"; ; fontset = special5, inactive, nohscroll, noKeepOnOnePage, preserveAspect, M7, 12, "Palatino"; ; ] :[font = subsubtitle; inactive; preserveAspect; startGroup; ] CleanSlate Tests and Demonstration :[font = text; inactive; preserveAspect; ] For detailed information about how to use the CleanSlate.m package, and the workings of the code itself, see the separate documentation file. This notebook is intended to exercise the various capabilities, error messages, etc. Todd Gayley tgayley@wri.com May 1993 :[font = section; inactive; preserveAspect; startGroup; ] The Basic Functionality :[font = subsection; inactive; Cclosed; preserveAspect; startGroup; ] A Demonstration :[font = input; preserveAspect; startGroup; ] $Version :[font = output; output; inactive; preserveAspect; endGroup; ] "Macintosh 2.1 (June 17, 1992)" ;[o] Macintosh 2.1 (June 17, 1992) :[font = text; inactive; preserveAspect; ] First, define a variable in the Global` context before CleanSlate.m is read in. None of the CleanSlate functions should ever affect this variable or its value. :[font = input; preserveAspect; ] preCleanSlate = 1; :[font = text; inactive; preserveAspect; ] Also, read in a package before CleanSlate.m. This package context should also never be affected by any CleanSlate functions. :[font = input; preserveAspect; ] < (Algebra`SymbolicSum`Private`a^ Algebra`SymbolicSum`Private`b)^ Algebra`SymbolicSum`Private`k /; FreeQ[{Algebra`SymbolicSum`Private`a, Algebra`SymbolicSum`Private`b}, Algebra`SymbolicSum`Private`k], (Algebra`SymbolicSum`Private`a_)^Algebra`SymbolicSum`Private`k* (Algebra`SymbolicSum`Private`b_)^ Algebra`SymbolicSum`Private`k :> (Algebra`SymbolicSum`Private`a*Algebra`SymbolicSum`Private`b)^ Algebra`SymbolicSum`Private`k /; FreeQ[{Algebra`SymbolicSum`Private`a, Algebra`SymbolicSum`Private`b}, Algebra`SymbolicSum`Private`k]} /. {(-(Algebra`SymbolicSum`Private`a_))^ (Algebra`SymbolicSum`Private`b_) :> (-1)^Algebra`SymbolicSum`Private`b* Algebra`SymbolicSum`Private`a^Algebra`SymbolicSum`Private`b /; Algebra`SymbolicSum`Private`a =!= 1}, {Algebra`SymbolicSum`Private`k, Algebra`SymbolicSum`Private`min, Algebra`SymbolicSum`Private`max}]; If[!FreeQ[Algebra`SymbolicSum`Private`answer, Algebra`SymbolicSum`Private`Donor], While[!FreeQ[Algebra`SymbolicSum`Private`inter, Algebra`SymbolicSum`Private`FailSum], Algebra`SymbolicSum`Private`inter = Block[{Algebra`SymbolicSum`Private`FiniteSum}, Algebra`SymbolicSum`Private`Reduction[Algebra`SymbolicSum`Pr\ ivate`SumFloor[Algebra`SymbolicSum`Private`expr, {Algebra`SymbolicSum`Private`k, Algebra`SymbolicSum`Private`min, Algebra`SymbolicSum`Private`max}, Cases[Algebra`SymbolicSum`Private`p* Algebra`SymbolicSum`Private`answer, Algebra`SymbolicSum`Private`w_ /; !FreeQ[Algebra`SymbolicSum`Private`w, Algebra`SymbolicSum`Private`Donor]][[1]] /. (Algebra`SymbolicSum`Private`a_.)* Algebra`SymbolicSum`Private`Donor[Algebra`SymbolicSum\ `Private`x_, Algebra`SymbolicSum`Private`y_] :> Algebra`SymbolicSum`Private`x], Algebra`SymbolicSum`Private`FiniteSum]]; Algebra`SymbolicSum`Private`answer = If[Length[Algebra`SymbolicSum`Private`answer[[2]]] == 0, Algebra`SymbolicSum`Private`Donor[True, {}], Algebra`SymbolicSum`Private`Donor[Algebra`SymbolicSum`Privat\ e`answer[[2,1]], Complement[Rest[Algebra`SymbolicSum`Private`answer[[2]]]]]]; Algebra`SymbolicSum`Private`inter]; Algebra`SymbolicSum`Private`answer = Algebra`SymbolicSum`Private`inter, Algebra`SymbolicSum`Private`answer]; (Algebra`SymbolicSum`Private`answer //. Algebra`SymbolicSum`Private`complex) /; FreeQ[Algebra`SymbolicSum`Private`answer, Algebra`SymbolicSum`Private`FailSum]] /; FreeQ[Algebra`SymbolicSum`Private`min, Floor] && !FreeQ[Algebra`SymbolicSum`Private`max, Floor] Sum[Algebra`SymbolicSum`Private`expr_, {Algebra`SymbolicSum`Private`k_Symbol, Algebra`SymbolicSum`Private`min_, Algebra`SymbolicSum`Private`max_}] := Module[{Algebra`SymbolicSum`Private`answer}, Algebra`SymbolicSum`Private`answer = Algebra`SymbolicSum`Private`SymbolicSumD[Expand[Algebra`SymbolicSum\ `Private`expr //. {(Algebra`SymbolicSum`Private`a_)^ ((Algebra`SymbolicSum`Private`b_.)* Algebra`SymbolicSum`Private`k) :> (Algebra`SymbolicSum`Private`a^ Algebra`SymbolicSum`Private`b)^ Algebra`SymbolicSum`Private`k /; FreeQ[{Algebra`SymbolicSum`Private`a, Algebra`SymbolicSum`Private`b}, Algebra`SymbolicSum`Private`k], (Algebra`SymbolicSum`Private`a_)^ Algebra`SymbolicSum`Private`k* (Algebra`SymbolicSum`Private`b_)^ Algebra`SymbolicSum`Private`k :> (Algebra`SymbolicSum`Private`a* Algebra`SymbolicSum`Private`b)^ Algebra`SymbolicSum`Private`k /; FreeQ[{Algebra`SymbolicSum`Private`a, Algebra`SymbolicSum`Private`b}, Algebra`SymbolicSum`Private`k]} /. {(-(Algebra`SymbolicSum`Private`a_))^ (Algebra`SymbolicSum`Private`b_) :> (-1)^Algebra`SymbolicSum`Private`b* Algebra`SymbolicSum`Private`a^Algebra`SymbolicSum`Private`b /\ ; Algebra`SymbolicSum`Private`a =!= 1}], {Algebra`SymbolicSum`Private`k, Algebra`SymbolicSum`Private`min, Algebra`SymbolicSum`Private`max}]; If[FreeQ[{Algebra`SymbolicSum`Private`max, Algebra`SymbolicSum`Private`min}, DirectedInfinity], Factor[Algebra`SymbolicSum`Private`answer], Algebra`SymbolicSum`Private`answer] /; Apply[And, (FreeQ[Algebra`SymbolicSum`Private`answer, #1] & ) /@ {Algebra`SymbolicSum`Private`FailSum, Algebra`SymbolicSum`Private`Donor}]] /; FreeQ[{Algebra`SymbolicSum`Private`min, Algebra`SymbolicSum`Private`max}, Complex] && (!NumberQ[Algebra`SymbolicSum`Private`max] || !NumberQ[Algebra`SymbolicSum`Private`min]) :[font = text; inactive; preserveAspect; ] To make things more complicated, let's add a rule for Sum from the Global` context: :[font = input; preserveAspect; ] Unprotect[Sum]; Sum[x_] := "global rule" :[font = text; inactive; preserveAspect; ] Now, let's purge Algebra`SymbolicSum` only: :[font = input; preserveAspect; startGroup; ] CleanSlate["Algebra`SymbolicSum`"] :[font = print; inactive; preserveAspect; ] contexts purged: {Algebra`SymbolicSum`} approximate kernel memory recovered: 514 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = text; inactive; preserveAspect; ] Note that 516 Kb was freed (the other 240 Kb that disappeared when Algebra`SymbolicSum` was read in is tied up in the code for System`ComplexExpand`Private`. Check out Sum: :[font = input; preserveAspect; startGroup; ] ??Sum :[font = info; inactive; preserveAspect; endGroup; ] Sum[f, {i, imax}] evaluates the sum of f with i running from 1 to imax. Sum[f, {i, imin, imax}] starts with i = imin. Sum[f, {i, imin, imax, di}] uses steps di. Sum[f, {i, imin, imax}, {j, jmin, jmax}, ...] evaluates a multiple sum. Attributes[Sum] = {HoldAll} Sum[x_] := "global rule" :[font = text; inactive; preserveAspect; ] The global rule for Sum survived, and everything added in Algebra`SymbolicSum` has been purged. Further, let's check on the various other variables we defined earlier. :[font = input; preserveAspect; startGroup; ] {preCleanSlate, global, `sub`subglobal, lateral`var} :[font = output; output; inactive; preserveAspect; endGroup; ] {1, 2, 3, 4} ;[o] {1, 2, 3, 4} :[font = text; inactive; preserveAspect; ] As expected, all are still present. Only Algebra`SymbolicSum` has been removed from $ContextPath (which is the return value from the CleanSlate command above). :[font = text; inactive; preserveAspect; ] Now, purge everything that's purgeable: :[font = input; preserveAspect; startGroup; ] CleanSlate[] :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 0 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = text; inactive; preserveAspect; ] The Global` context was the only thing left that could be purged. Again, take a look at our user symbols: :[font = input; preserveAspect; startGroup; ] {preCleanSlate, global, `sub`subglobal, lateral`var} :[font = output; output; inactive; preserveAspect; endGroup; ] {1, global, Global`sub`subglobal, 4} ;[o] {1, global, Global`sub`subglobal, 4} :[font = text; inactive; preserveAspect; endGroup; ] As expected, global and `sub`subglobal are the only things that were purged. Recall, preCleanSlate was present when CleanSlate.m was read in, and lateral`var was left alone because its context (lateral`) is not on $ContextPath. :[font = subsection; inactive; Cclosed; preserveAspect; startGroup; ] UpValues, DownValues, FormatValues, and SubValues :[font = text; inactive; preserveAspect; ] When it removes added rules for system symbols (i.e., symbols in the System` context), CleanSlate only clears those that are among the UpValues, DownValues, FormatValues, and SubValues. This set of types of values will probably cover almost all cases, but there are some modifications that packages can make to system symbols that will not be removed by CleanSlate. Here is a somewhat fanciful example. :[font = input; preserveAspect; ] Unprotect[Log]; Log[a_ b_] := Log[a] + Log[b] (* a downvalue of Log *) Log /: Log[a_] - Log[b_] := Log[a/b] (* an upvalue of Log *) Log[a_][b_] := Log[a] Log[b] (* a subvalue of Log *) Format[Log[a_]] := ln[a] (* a formatvalue of Log*) Options[Log] = {Broken -> True}; (* an option of Log *) :[font = input; preserveAspect; startGroup; ] ??Log :[font = info; inactive; preserveAspect; endGroup; ] Log[z] gives the natural logarithm of z (logarithm to base E). Log[b, z] gives the logarithm to base b. Attributes[Log] = {Listable} Log[a_][b_] := Log[a]*Log[b] Log/: Log[a_] - Log[b_] := Log[a/b] Log[(a_)*(b_)] := Log[a] + Log[b] Format[Log[a_]] := ln[a] Options[Log] = {Broken -> True} :[font = input; preserveAspect; startGroup; ] CleanSlate[] :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 5 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; startGroup; ] ??Log :[font = info; inactive; preserveAspect; endGroup; ] Log[z] gives the natural logarithm of z (logarithm to base E). Log[b, z] gives the logarithm to base b. Attributes[Log] = {Listable} Options[Log] = {Removed["Broken"] -> True} :[font = text; inactive; preserveAspect; endGroup; endGroup; ] Note that the Option modification has not been cleared. (But the Broken symbol has been Removed....) :[font = section; inactive; Cclosed; preserveAspect; startGroup; ] Error-handling (Try to break it) ;[s] 2:0,0;15,1;33,-1; 2:1,17,12,Palatino,1,14,0,0,0;1,15,10,Palatino,0,12,0,0,0; :[font = subsubsection; inactive; preserveAspect; startGroup; ] Try to purge a context that was initally on $ContextPath :[font = input; preserveAspect; startGroup; ] CleanSlate["Graphics`PlotField`"] :[font = message; inactive; preserveAspect; ] CleanSlate::nopurge: The context Graphics`PlotField` cannot be purged, because it was present when the CleanSlate package was initally read in. :[font = output; output; inactive; preserveAspect; endGroup; endGroup; ] $Aborted ;[o] $Aborted :[font = subsubsection; inactive; preserveAspect; startGroup; ] Try to purge the CleanSlate` and/or System` contexts :[font = input; preserveAspect; startGroup; ] CleanSlate["CleanSlate`"] :[font = message; inactive; preserveAspect; ] CleanSlate::noself: CleanSlate cannot purge its own context. :[font = output; output; inactive; preserveAspect; endGroup; ] $Aborted ;[o] $Aborted :[font = input; preserveAspect; startGroup; ] CleanSlate["System`"] :[font = message; inactive; preserveAspect; ] CleanSlate::nopurge: The context System` cannot be purged, because it was present when the CleanSlate package was initally read in. :[font = output; output; inactive; preserveAspect; endGroup; endGroup; ] $Aborted ;[o] $Aborted :[font = subsubsection; inactive; preserveAspect; startGroup; ] Try to purge a context that does not exist, or is misspelled :[font = input; preserveAspect; startGroup; ] CleanSlate["Junk`"] :[font = message; inactive; preserveAspect; ] CleanSlate::notcntxt: A context you have given is either misspelled, incorrectly specified, or is not on $ContextPath. :[font = output; output; inactive; preserveAspect; endGroup; endGroup; ] $Aborted ;[o] $Aborted :[font = subsubsection; inactive; preserveAspect; startGroup; ] Try to purge a context that is not correctly specified (not a string ending in `) :[font = input; preserveAspect; startGroup; ] CleanSlate[Junk] :[font = message; inactive; preserveAspect; endGroup; endGroup; ] CleanSlate::syntax: CleanSlate takes arguments of the form "Context1`", "Context2`". :[font = subsubsection; inactive; preserveAspect; startGroup; ] Try to execute CleanSlate from within a package :[font = input; preserveAspect; startGroup; ] BeginPackage["Test`", "CleanSlate`"]; CleanSlate[] EndPackage[] :[font = message; inactive; preserveAspect; ] CleanSlate::cntxtpth: Error in $Contextpath. The $ContextPath is shorter than it was when the CleanSlate package was read in. CleanSlate cannot be run within a package (i.e., between BeginPackage..EndPackage pairs). :[font = output; output; inactive; preserveAspect; endGroup; endGroup; endGroup; ] $Aborted ;[o] $Aborted :[font = section; inactive; Cclosed; preserveAspect; startGroup; ] The Verbose option :[font = input; preserveAspect; startGroup; ] Options[CleanSlate] :[font = output; output; inactive; preserveAspect; endGroup; ] {Verbose -> True} ;[o] {Verbose -> True} :[font = text; inactive; preserveAspect; ] The Verbose->False option suppresses the printout: :[font = input; preserveAspect; startGroup; ] CleanSlate["Global`", Verbose->False] :[font = output; output; inactive; preserveAspect; endGroup; ] {"Test`", "CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {Test`, CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; startGroup; ] SetOptions[CleanSlate, Verbose->False]; CleanSlate["Global`"] :[font = output; output; inactive; preserveAspect; endGroup; ] {"Test`", "CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {Test`, CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; ] SetOptions[CleanSlate, Verbose->True]; :[font = text; inactive; preserveAspect; ] Supplying a bogus option triggers an error message, but does not abort: :[font = input; preserveAspect; startGroup; ] CleanSlate[Verbosse -> False] :[font = message; inactive; preserveAspect; ] General::spell1: Possible spelling error: new symbol name "Verbosse" is similar to existing symbol "Verbose". :[font = message; inactive; preserveAspect; ] CleanSlate::optx: Unknown option Verbosse in CleanSlate[Verbosse -> False]. :[font = print; inactive; preserveAspect; ] contexts purged: {Global`, Test`} approximate kernel memory recovered: 0 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = text; inactive; preserveAspect; ] Similarly, specifying an incorrect value for the Verbose option triggers an error, but no abort: :[font = input; preserveAspect; startGroup; ] CleanSlate[Verbose -> Automatic] :[font = message; inactive; preserveAspect; ] CleanSlate::opttf: Value of option Verbose -> Automatic should be True or False. :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 0 Kb :[font = output; output; inactive; preserveAspect; endGroup; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = section; inactive; preserveAspect; startGroup; ] Things that CleanSlate cannot do :[font = subsection; inactive; Cclosed; preserveAspect; startGroup; ] Rules for System` symbols must have named variables on the left-hand side :[font = text; inactive; preserveAspect; ] CleanSlate cannot remove added rules for system symbols unless there is a user-defined symbol on the left-hand side of the rule. In the example below, there is none: :[font = input; preserveAspect; ] Unprotect[Power]; Power[__] := "a silly rule" :[font = input; preserveAspect; startGroup; ] x^2 :[font = output; output; inactive; preserveAspect; endGroup; ] "a silly rule" ;[o] a silly rule :[font = input; preserveAspect; startGroup; ] CleanSlate[] :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 0 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; startGroup; ] x^2 :[font = output; output; inactive; preserveAspect; endGroup; ] "a silly rule" ;[o] a silly rule :[font = text; inactive; preserveAspect; ] The solution to this problem is to make sure there is always a named symbol on the left-hand side, even if its value is not used on the right-hand side: :[font = input; preserveAspect; ] Unprotect[Power]; Clear[Power] Power[x__] := "a silly rule" :[font = input; preserveAspect; startGroup; ] x^2 :[font = output; output; inactive; preserveAspect; endGroup; ] "a silly rule" ;[o] a silly rule :[font = input; preserveAspect; startGroup; ] CleanSlate[] :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 1 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; startGroup; ] x^2 :[font = output; output; inactive; preserveAspect; endGroup; ] x^2 ;[o] 2 x :[font = text; inactive; preserveAspect; endGroup; ] Note that we unprotected Power again above before adding the second rule, even though it was left uprotected from the last step. This is necessary because when CleanSlate runs, it clears its list of modified system symbols. Unless we unprotect Power again, CleanSlate will not know that it is being further modified. :[font = subsection; inactive; preserveAspect; startGroup; ] Locked symbols cannot be cleared :[font = text; inactive; preserveAspect; endGroup; ] Don't set the Locked attribute on a symbol if you want to use CleanSlate on its context. It is very unlikely that a user or package author would want to lock a symbol. No symbols are locked by any of the standard packages. :[font = subsection; inactive; Cclosed; preserveAspect; startGroup; ] Fails to count the memory occupied by the most recent output :[font = text; inactive; preserveAspect; ] For some reason that I do not understand, CleanSlate cannot count the memory occupied by the immediately previous output in its report of memory freed. This memory is if fact freed, it is just not reported by CleanSlate's internal call to MemoryInUse[]. This can cause confusion if CleanSlate is executed immediately after generating a large object, for example a 3D plot. Here is an example of this effect. :[font = input; preserveAspect; startGroup; ] MemoryInUse[] :[font = output; output; inactive; preserveAspect; endGroup; ] 798260 ;[o] 798260 :[font = input; preserveAspect; startGroup; ] Plot3D[Sin[x y], {x,0,Pi}, {y,0,Pi}, PlotPoints->50, DisplayFunction->Identity] :[font = output; output; inactive; preserveAspect; endGroup; ] The Unformatted text for this cell was not generated. Use options in the Actions Preferences dialog box to control when Unformatted text is generated. ;[o] -SurfaceGraphics- :[font = text; inactive; preserveAspect; ] The above plot occupies about 70 Kb. The DisplayFunction->Identity prevents it from being displayed, but has no effect on the kernel memory required to hold the Graphics object. We could see the 70 Kb missing if we did MemoryInUse[] at this point, but that would interfere with the demonstration, which requires that CleanSlate[] be run immediately after the plot command. :[font = input; preserveAspect; startGroup; ] CleanSlate[] :[font = print; inactive; preserveAspect; ] contexts purged: {Global`} approximate kernel memory recovered: 0 Kb :[font = output; output; inactive; preserveAspect; endGroup; ] {"CleanSlate`", "Graphics`PlotField`", "Utilities`FilterOptions`", "Geometry`Rotations`", "Graphics`Animation`", "Global`", "System`"} ;[o] {CleanSlate`, Graphics`PlotField`, Utilities`FilterOptions`, Geometry`Rotations`, Graphics`Animation`, Global`, System`} :[font = input; preserveAspect; startGroup; ] MemoryInUse[] :[font = output; output; inactive; preserveAspect; endGroup; ] 797892 ;[o] 797892 :[font = text; inactive; preserveAspect; endGroup; endGroup; endGroup; ] Thus, CleanSlate reports no memory freed, but it has in fact freed the memory occupied by the plot. ^*)