MathGroup Archive 1992

[Date Index] [Thread Index] [Author Index]

Search the Archive

Obtaining assigned symbols and values

  • To: mathgroup at yoda.physics.unc.edu
  • Subject: Obtaining assigned symbols and values
  • From: villegas
  • Date: Thu, 1 Oct 92 04:47:34 CDT

Hi John,

   Though there is not a built-in function which automatically figures
out what variables you've defined and gives a report of what they are
and how they're defined, you can write a few functions that will
accomplish about what you want, with fair generality.

   Generally, a user works in a context called "Global`", so all the
user's symbols are in that context.  The current context can be
abbreviated by a lone grave accent  `  , so unless you have changed your
context purposely, it will represent the global context.

Here's how to get a listing of all symbols in the global context, then:

In[1]:= globals = Names["`*"]

Out[1]= {args, ClearKernelHistory, context, ctx, Erase, expr, file, 
 
>    fileOrpipe, Form, globals, info, Info, InfoWild, instream, 
 
>    instream$, k, m, Modulo, name, PackageInfo, patt, PrintTime, 
 
>    readlist, readlist$, ReadOnce, result, result$, ShowDef, str, 
 
>    stream, stream$, StringReadList, SupportAges, sym, username}

(You'll probably have a different list than I do; this is a result of how
I've changed my start-up).

   If you wanted to remind yourself of what the "`*" means, you could
make the "Global" explicit; the result would be the same, and we can
have Mathematica verify that fact:

In[2]:= Names["Global`*"] === globals

Out[2]= True

   Mathematica creates a symbol in the symbol table of the current context
anytime you use a new symbol, and this goes for symbols you just use in
expressions, even when you aren't assigning values to them.  For instance:

In[3]:= Expand[(2 x - 5 y)^4]

            4        3          2  2           3        4
Out[3]= 16 x  - 160 x  y + 600 x  y  - 1000 x y  + 625 y

In[4]:= ? x
Global`x

In[4]:= ? y
Global`y

I didn't assign anything to 'x' and 'y', but now they "exist", and we
can see that Mathematica has put them in the context "Global`".  So
some of the symbols we got in the list we stored in 'globals' above might
be no-value symbols.  Presumably we don't care about those, so we want
to extract the ones which have values as constants or as functions, for
example (note that Mathematica has several different types of assignments):

a = 5

f[x_] := Sin[Tan[x]] + Tan[Sin[x]]

These assignments are stored in different ways, because the one for 'a'
means 'a' has a value by its own self, and 'f' produces a value only
when acting on something.  In Mathematica, the former are called
'OwnValues', and the latter 'DownValues'.  We can take a look at how
the kernel has stored them:

In[6]:= OwnValues[a]

Out[6]= {Literal[a] :> 5}

In[7]:= DownValues[f]

Out[7]= {Literal[f[x_]] :> Sin[Tan[x]] + Tan[Sin[x]]}

The symbol 'Literal' is there merely to prevent the left sides from
evaluating as they would ordinarily; it "freezes" the left sides so we can
see to what the definitions are made.

If we ask for some kind of *Values for a symbol which doesn't have the
type we request, then we'll get an empty list instead of one of the
form  { Literal[leftside] :> rightside } as we did above.

In[8]:= OwnValues[x]

Out[8]= {}

Now we can use this fact to check to see if a symbol has been assigned
some type of value.  The different types of values all end in "Values",
so we can generate all system names ending in that, and leave out the
one that is a linear algebra function (SingularValues) rather than
a function for looking up values.  Then we can define a function
to take a symbol and a type of value (like 'OwnValues') and give
us 'True' if the symbol has at least one assignment of that type,
'False' if it doesn't.  We allow the function to take the variable
name as a symbol or as a string, since the 'Names' function we used
above generates a list of strings like "x" instead of symbols like
 x  (without quotes).

In[1]:= $ValueTypes =
          ToExpression /@ Complement[Names["*Values"], {"SingularValues"}]

Out[1]= {DefaultValues, DownValues, FormatValues, NValues, OwnValues, 
 
>    SubValues, UpValues}

In[2]:= ValueTypes = Apply[Alternatives, $ValueTypes]

Out[2]= DefaultValues | DownValues | FormatValues | NValues | 
 
>    OwnValues | SubValues | UpValues

In[3]:= Attributes[HasValueQ] = HoldFirst

Out[3]= HoldFirst

In[4]:= HasValueQ[sym_Symbol, valtype:ValueTypes] :=
          Length[ valtype[sym] ] != 0

In[7]:= HasValueQ[name_String, valtype:ValueTypes] :=
          Length[valtype @@ ToHeldExpression[name]] != 0


   The function 'HasValueQ' tests any symbol for any type of value.  If
we're just interested in assigments like the ones we made to 'a' and 'f'
above, we can use 'HasValueQ' to get OwnValues and DownValues.

Now let's get a list of all global variables and see which ones have
assignments we're interested in (again, this is a different Mathematica
session, so the names will be different from the example given earlier):

In[24]:= globals = Names["`*"]

Out[24]= {args, ClearKernelHistory, context, ctx, downvalues, Erase, 
 
>    expr, file, fileOrpipe, Form, globals, HasValueQ, hh, info, Info, 
 
>    InfoWild, instream, instream$, k, left, lit, m, Modulo, name, 
 
>    ownvalues, PackageInfo, patt, PrintTime, PrintValue, readlist, 
 
>    readlist$, ReadOnce, result, result$, right, ShowDef, str, stream, 
 
>    stream$, StringReadList, SupportAges, sym, u, username, valtype, 
 
>    $ValueTypes, Valuetypes, ValueTypes, WantedValuesQ}

In[29]:= ownvalues = Select[globals, HasValueQ[#, OwnValues]& ]

Out[29]= {downvalues, globals, ownvalues, SupportAges, $ValueTypes, 
 
>    ValueTypes}

In[30]:= downvalues = Select[globals, HasValueQ[#, DownValues]& ]

Out[30]= {Erase, HasValueQ, info, Info, InfoWild, Modulo, PackageInfo, 
 
>    PrintTime, PrintValue, ReadOnce, ShowDef, StringReadList, 
 
>    WantedValuesQ}


Earlier in this session I defined a function that will take the
kinds of rules we saw stored:  Literal[left] :> right, and display
it in something like the form "left = right", without evaluating
'left' or 'right'.  The 'HoldForm' prevents the evaluation, but
doesn't display itself.

In[20]:= PrintValue[(lit:Literal)[left_] :> right_] :=
         StringForm["`1`  -is-  `2`", HoldForm[left], HoldForm[right] ]

I chose " -is ", but could have chosen "=".  Values can be assigned with
"=" or ":=", and I don't know (tell me, someone) how to get this information
out of 'DownValues' and such, though it does get displayed when you use
"?? f" to print out info.  You could use "--->", or whatever you like, to
"equate" the left and right sides.

Now you can generate the DownValues and OwnValues of symbols and use this
function on them.  Instead of applying this to 'ownvalues' and 'downvalues'
above, which generates a lot of output (I haven't figured out how to make
output look nice in complicated cases yet), I'll try it on some simpler
definitions:

In[33]:= {a, b, c} = {7, 2 - x, 3 + y}

Out[33]= {7, 2 - x, 3 + y}

In[34]:= f[x_] := Sin[Tan[x]] + Tan[Sin[x]]

In[37]:= g[x_] := Integrate[1/t, {t, 1, x}]


In[44]:= Apply[PrintValue, simpledown, {1}] //TableForm

Out[44]//TableForm= f[x_]  -is-  Sin[Tan[x]] + Tan[Sin[x]]

                                           1
                    g[x_]  -is-  Integrate[-, {t, 1, x}]
                                           t

In[45]:= Apply[PrintValue, simpleown, {1}] //TableForm

Out[45]//TableForm= a  -is-  7

                    b  -is-  2 - x

                    b  -is-  2 - x


   The general idea would be to use this on the lists we made earlier,
'ownvalues' and 'downvalues', but the output can be somewhat hard to read.
I used:

In[32]:= Map[PrintValue, 
           Apply[DownValues, ToHeldExpression /@ downvalues, {1}],
         {2}]

to get a listing of the things that have DownValues.

   The general ideas are there, and this technique could probably be
modified to return better-looking output.


   Since a similar question came to me from someone else one time, I'll
append most of the answer (along with a summary of the questions) to this
email.  Some of it is about the same as above, but I think there are some
extra things in it.

Robby Villegas
Wolfram Research

************************************************************************

The user asked two questions:

(1) How do I get some kind of listing of all the commands entered in the
    current session?

(2) How do I get a listing of all the variables I've assigned values to
    (functions, constants, etc.) in the current session?

========================================================================

     (1) Commands entered in the current session.

Mathematica has several variables that comprise a kernel history for
the current session.  The familiar "%" usage to refer to previous
_output_ is a shorthand for Out[n], where n is the line number.  "%"
is short for Out[-1], which means the immediately previous output; "%%"
refers to Out[-2], etc.  And "%n" is an absolute reference to Out[n],
which means the result of evaluation of the nth input line.  Just as
output is stored, so is input, in the variable 'In'.  In[-1] refers to
the immediately previous input expression, and using it will cause it
to be evaluated again.  In[n] means evaluate the nth input statement
again.

If you just want to see the input statements as they were, without
evaluating them over again, another variable is 'InString':  InString[n]
is the string which was the literal input of the user for the nth
line.  So to get a complete list of commands entered in the current
session, in a nice format, you could use:

Table[InString[n], {n, $Line - 1}] //TableForm

This will display a list of all the commands entered so far, except for
the Table command itself (that is why '$Line - 1' is used instead of just
'$Line').

Another kernel record is MessageList, which maintains a list of the names
of error messages generated by input statements.  MessageList[n] is a
list of the message names generate by In[n].  The names are wrapped in
the symbol 'HoldForm' which "freezes" them, so they don't produce
message output on the screen anymore.

If you do just want a tabular display of In, for instance, and don't
care about putting the input strings into a list that you can later
use (i.e. you just want to look at them yourself, not have a program
analyze them) you could type '?? In', and along with a short
description of what 'In' is about, there would follow a list of
n's for which In[n] has been assigned.

     (2) Variables used or assigned in the current session.

For a table of variables that have been used in the current session, you
could type:

? `*

Notice the _context mark_ ` which is a grave accent, not an apostrophe
like '.  This will give you only a list of symbols in the currently
active _context_, which will always be Global` unless you modify it
yourself.  So if you don't alter your context, this will list all
variables _you_ have used.

As with In and its relatives, you can get your result in
a list that you can actually use as a Mathematica expression:

globalnames = Names["Global`*"];

The list will be the same as with "? `* ", but 'globalnames' will
contain a list like {"x", "y", "f", ...} which you could use further
Mathematica commands on if you needed to.

Any time you use a symbol like 'x' in Mathematica, it gets
created in a symbol table, whether you assign any values to it or not.
So the above won't tell you what symbols have been _assigned_, say as
functions or as constants.  If you want to know which ones have values
associated with them, here's a little program, called 'AssignedNames',
to generate the subset of global names which have had assignments
made to them.  It defines auxiliary functions NonEmptyQ, which simply
decides if a list is empty, and TagQ, the important one which decides
if an individual symbol or name has had any assignments tagged to it.


$ValueTypes = 
   ToExpression /@ Complement[Names["*Values"], {"SingularValues"}]

NonEmptyQ[list_List] := Length[list] != 0

Attributes[TagQ] = HoldFirst

TagQ[name_Symbol] :=
   NonEmptyQ @ Apply[Union, Map[#[name]&, $ValueTypes]]

TagQ[name_String] := Apply[TagQ, ToHeldExpression[name]]

AssignedNames[] := Select[Names["`*"], TagQ]


The variable $ValueTypes is a list of all the symbols like 'OwnValues',
'DownValues', and 'NValues' that store the various kinds of assignments
you can make to a symbol.  For instance,

x = 3     - - - - - - - - - - - - ->     stores an entry in OwnValues[x]

f[x_] := Tanh[1/x]    - - - - - - ->     stores an entry in DownValues[f]

N[c, n_] :=                   - - ->     stores an entry in NValues[c]
  NSum[1/k^2, {k, Infinity},
    WorkingPrecision->n + 15,
    PrecisionGoal->n ]

Currently its value is

In[17]:= $ValueTypes =
   ToExpression /@ Complement[Names["*Values"], {"SingularValues"}]
         
Out[17]= {DefaultValues, DownValues, FormatValues, NValues, OwnValues, 
 
>    SubValues, UpValues}

but it might well need to be updated for future versions if more or fewer
types of assignments exist, or if other symbols whose names end in
"Values" are added that, like 'SingularValues', do not represent value
types for assignments.






  • Prev by Date: Summary- Testing for Unevaluated Functions
  • Next by Date: Re: Econometrics
  • Previous by thread: Summary- Testing for Unevaluated Functions
  • Next by thread: Re: Econometrics