The set of protected names

The help page ?type/protected states:

The set of protected names in Maple can be computed with select(type, {unames(), anames(anything)}, protected).

However, the result of this computation is "time dependent". I.e. repeated execution of this command produce different sets. E.g. executed in a fresh session:

S1:=select(type,{unames(),anames(anything)},protected):
S2:=select(type,{unames(),anames(anything)},protected):
S3:=select(type,{unames(),anames(anything)},protected):
S4:=select(type,{unames(),anames(anything)},protected):
S5:=select(type,{unames(),anames(anything)},protected):

Each of these sets become larger than the previous one. In Maple 12 Classic:

map(nops,[S1,S2 minus S1,S3 minus S2,S4 minus S3,S5 minus S4]);
                       [362, 58, 138, 180, 96]

and in Maple 12 Standard:

map(nops,[S1,S2 minus S1,S3 minus S2,S4 minus S3,S5 minus S4]);
                           [361, 55, 136, 182, 97]

So, not only the result of these computation are larger and larger sets, but these sets are different, depending on the interface. I find this effect quite odd. I wonder about its cause.

Two mechanisms that could be at work are:

a. These names become protected in stages.

b. 'select' is "lazy" in detecting protected names.

Or a combination, or something else...

How many iterations are needed to get the complete set of protected names?

And how could it be that the output depends on the interface?

Comments

edgar's picture

examples?

What is the one name in the 362 not in the 361?
What are some examples in S2 but not S1?
---
G A Edgar

differences

In fact, I find several names different.

Four in S1 Classic but not in S1 Standard: `-`, fclose, fopen, fprintf

Three in S1 Standard but not in S1 Classic: currentdir, protect, unprotect

Names in S2 but not in S1 for Standard:

S2 minus S1;nops(%);
{Int, Sum, cot, csc, exp, sec, sum, tan, Expand, Limit, Normal, Product, 
  WARNING, algfun, algnum, arccosh, arccoth, arccsch, arcsech, arcsinh, 
  arctanh, ceil, collect, copy, evala, floor, freeze, index, invfunc, limit, 
  product, psqrt, round, scalar, sech, signum, subtype, tanh, testeq, thaw, 
  trig, unapply, Multiply, RealRange, argument, iperfpow, listlist, primpart, 
  radnormal, resultant, LinearAlgebra, VectorOptions, additionally, 
  rtable_elems, simplify/siderels}
                                     55

minus

Eg., in Standard GUI, `-` appears only in the fourth iteration. In a fresh session:

S1:=select(type,{unames(),anames(anything)},protected):
S2:=select(type,{unames(),anames(anything)},protected):
S3:=select(type,{unames(),anames(anything)},protected):
S4:=select(type,{unames(),anames(anything)},protected):
S5:=select(type,{unames(),anames(anything)},protected):

map(has,[S1,S2,S3,S4,S5],`-`);
                      [false, false, false, true, true]

But, it can be "forced" to be recognized earlier. Again in a fresh Standard session:

S1:=select(type,{unames(),anames(anything)},protected):
has(S1,`-`);
                                    false
type(`-`,protected);
                                    true
Sm:=select(type,{unames(),anames(anything)},protected):
has(Sm,`-`);
                                    true
JacquesC's picture

A potential explanation

The various Maple library files (.ind/.lib, or .mla) are described as a "persistent store" (see ?updates,Maple6,language about halfway through).  These are rather like a swap file for a virtual memory system.  There is an index to all that is in it, but the pieces are kept on disk as long as possible, to try to maintain the memory footprint of the kernel as small as possible [wish the GUI did the same!].  And what is shown above is the success of this.

In fact, even the index is not loaded into memory either, only those pieces that are needed.  This means that unames and anames actually only know about those names currently loaded, and not those that are in the "persistent store".  This is because a name gets looked up once (and essentially only once) in the store: the first time it is encountered (as 'simpl time' for the cognoscenti).  So if the name doesn't exist in Maple's current state, then neither unames nor anames will report it. In other words, that help page is wrong.

So why do things grow?  Well, when some name is mentionned, if it is assigned, whatever corresponds to it is loaded - which, as a side-effect, may create a lot of new names in Maple's memory (of both assigned and unassigned symbols).  The initial state of Maple contains quite a lot of pre-defined names - and way more so in the GUI.  Actually, you should redo your experiments in the TTY version, as I believe the numbers will be quite different again.  Also, the numbers will be quite different in older versions of Maple too.

The GUI actually pre-loads a number of packages, most notably the context-menu code [otherwise the first context menu, even in Classic, was too slow to come up].  I would guess that Standard preloads other stuff, like the Typesetting package, and so on.  Basically, the namespace of the kernel is much larger in a clean session under any GUI than under TTY.  Note that this is not a trivial issue (because of garbage collection): anytime there is more memory occupied by non-garbage which is fragmented, gc takes longer, which means that all computations that use memory (ie most) are slower.  In other words, for substantial computations, you can measure that running it under the GUI is slower than in TTY version, even if the GUI is otherwise not involved!  [The only way to avoid this would be to have the GUI start a separate kernel, which I don't think is yet the case].

Reading in the whole Maple library, so that one can get accurate statistics from it, is extremely tricky.  I have some code around which I believe does it accurately, and I will try to post it in a blog post later.

In Maple 12 TTY

Repeating the same iterations in Maple 12 console interface, I  get indeed different numbers but (surprisingly?)  the initial set is larger:

S1:=select(type,{unames(),anames(anything)},protected):
S2:=select(type,{unames(),anames(anything)},protected):
S3:=select(type,{unames(),anames(anything)},protected):
S4:=select(type,{unames(),anames(anything)},protected):
memory used=3.8MB, alloc=2.8MB, time=0.25
S5:=select(type,{unames(),anames(anything)},protected):
memory used=7.6MB, alloc=5.3MB, time=0.53

map(nops,[S1,S2 minus S1,S3 minus S2,S4 minus S3,S5 minus S4]);
                           [380, 59, 139, 180, 95]

And these numbers after S4 and S5 may be related to this permanent store issue (indeed I listen the disk working!)

So, if I understand correctly, is impossible to get a complete list of the protected names by the method stated in this help page?

JacquesC's picture

Puzzled

I am very puzzled to as to why the TTY version has a larger initial set of protected names!  I don't have an explanation for that either.

As far as I can tell, this method can not give all the protected names if there is a protected name which isn't reachable from the root set given by the initial names.  It is possible that that set is empty, though it would take a fair bit of work to determine that.

Method?

Then, which is the effective method to get the complete list of protected names?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}