symbol
is short for Symbolic Name. A value of type symbol
represents a variable name possibly with some integer subscripts
attached. Its primary use is for input and output of polynomials: the
name of each indeterminate in a PolyRing
is a symbol
, similarly
for a PPMonoid
.
A symbol
value has two components:
_
s
(note no digits or other characters allowed)
Examples of symbol
s are: (in standard printed forms)
x , X , alpha , z_alpha , x[2] , gamma[-2,3,-9] |
It is also possible to create anonymous symbols: they are used for building temporary polynomial extensions on unknown coefficient rings (which may contain any symbol).
Each newly created anonymous symbol has a subscript strictly greater
than that of any previous anonymous symbol. For better readability,
an anonymous symbol prints out as a hash followed by the
subscript: e.g. #[12]
Let
head
be a std::string
,
ind
, ind1
, ind2
, n
machine integers,
inds
a std::vector<long>
.
symbol(head)
-- a symbol
with no subscripts
symbol(head, ind)
-- a symbol
with a single subscript
symbol(head, ind1, ind2)
-- a symbol
with a two subscripts
symbol(head, inds)
-- a symbol
with the given subscripts
NewSymbol()
-- a new anonymous symbol (prints as, for example, #[12]
)
Several polynomial ring pseudo-constructors expect a vector
of
symbol
s to specify the names of the indeterminates. There are
several convenience functions for constructing commonly used
collections of symbol
s.
symbols(hd1)
-- create vector of length 1 containing symbol(hd1)
symbols(hd1,hd2)
-- ... length 2...
symbols(hd1,hd2,hd3)
-- ... length 3...
symbols(hd1,hd2,hd3,hd4)
-- ... length 4...
SymbolRange(hd, lo, hi)
-- create vector of
hd[lo]
, hd[lo+1]
, ... hd[hi]
.
Note that these symbols each have just a single subscript
SymbolRange(sym1, sym2)
-- create vector of cartesian product of the
subscripts, e.g. given x[1,3]
and x[2,4]
produces
x[1,3]
, x[1,4]
, x[2,3]
, x[2,4]
NewSymbols(n)
-- n
new anonymous symbols
Let sym
, sym1
, and sym2
be objects of type symbol
head(sym)
-- head of sym
as a const ref to std::string
NumSubscripts(sym)
-- number of subscripts sym
has (0 if sym has no subscripts)
subscript(sym, n)
-- gives n
-th subscript of sym
cmp(sym1, sym2)
-- <0, =0, >0 according as sym1
< = > sym2
(for more info see Maintainer section)
sym1 < sym2
-- comparisons defined in terms of cmp
sym1 <= sym2
-- ...
sym1 > sym2
-- ...
sym1 >= sym2
-- ...
sym1 == sym2
-- ...
sym1 != sym2
-- ...
out << sym
-- print sym
on out
in >> sym
-- read a symbol into sym
(but also see Bugs section)
(expected format is x, y[1], z[2,3], etc.)
AreDistinct(vecsyms)
-- true iff all symbols are distinct
AreArityConsistent(vecsyms)
-- true iff all symbols with the same head
have the same arity
The implementation is extremely simple. Efficiency does not seem to be
important (e.g. symbols
and SymbolRange
copy the vector upon returning).
The implementation of SymbolRange
is mildly delicate when we have to make
checks to avoid integer overflow -- see comments in the code.
To make "anonymous" symbols I opted to use a private ctor which
accepts just a single subscript; this ctor is called only by NewSymbol
and NewSymbols
.
The printing fn (myOutputSelf
) has to check for an empty head, and if
found it prints the string in AnonHead
.
We believe a total ordering on symbol
s could be useful; for instance,
if someone wants to make a std::map
using symbol
s. Currently the
total order is Lex on the heads then lex on the subscript vectors; this
is simple, and is probably fast enough.
The function symbol::myInput
is a stop-gap implementation.
The member function myInput
handles white space wrongly. For CoCoALib
whitespace is space, TAB, or backslash-newline; newline without
backslash is not considered white space.
It might be nice to have a function which returns the vector of subscripts of a name.
Decided not to permit big integers as subscripts; I don't see when it could ever really be useful.
I wonder what sending a symbol
on an OpenMath channel would mean
(given that OpenMath is supposed to preserve semantics, and a symbolic
name is by definition devoid of semantics).