Examples
User documentation
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:
- head -- a string starting with a letter followed by letters, digits and
_
s (note no other characters allowed) - subscripts -- a (possibly empty) vector of machine integers
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 useful for building (temporary) polynomial extensions of unknown coefficient rings (which may contain any symbol) to guarantee no name conflicts.
- head -- is the empty string
- subscripts -- exactly one subscript
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 sign followed by the
subscript: e.g. #[12]
Constructors
Let
head
be a std::string
,
ind
, ind1
, ind2
, n
machine integers,
inds
a std::vector<long>
.
symbol(head)
-- asymbol
with no subscriptssymbol(head, ind)
-- asymbol
with a single subscriptsymbol(head, ind1, ind2)
-- asymbol
with a two subscriptssymbol(head, inds)
-- asymbol
with the given subscriptsNewSymbol()
-- a new anonymous symbol (printed form is like this#[12]
)
Creating a vector of symbols
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(str)
-- create avector<symbol>
containing comma-separated symbols instr
SymbolRange(hd, lo, hi)
-- create vector ofhd[lo]
,hd[lo+1]
, ...hd[hi]
. Note that these symbols each have just a single subscriptSymbolRange(sym1, sym2)
-- create vector of cartesian product of the subscripts, e.g. givenx[1,3]
andx[2,4]
producesx[1,3]
,x[1,4]
,x[2,3]
,x[2,4]
NewSymbols(n)
-- create vector ofn
new anonymous symbols
Operations on symbols
Let sym
, sym1
, and sym2
be objects of type symbol
head(sym)
-- head ofsym
as a const ref tostd::string
NumSubscripts(sym)
-- number of subscriptssym
has (0 if sym has no subscripts)subscript(sym, n)
-- givesn
-th subscript ofsym
cmp(sym1, sym2)
-- <0, =0, >0 according assym1
< = >sym2
(for more info see Maintainer section)sym1 < sym2
-- comparisons defined in terms ofcmp
sym1 <= sym2
-- ...sym1 > sym2
-- ...sym1 >= sym2
-- ...sym1 == sym2
-- ...sym1 != sym2
-- ...out << sym
-- printsym
onout
in >> sym
-- read a symbol intosym
(but also see Bugs section) (expected format is x, y[1], z[2,3], etc.)
Operations on vectors of symbols
AreDistinct(vecsyms)
-- true iff all symbols are distinctAreArityConsistent(vecsyms)
-- true iff all symbols with the same head have the same arity
Other operations
symbol::IsValidHead(str)
-- determine whether thestring
is a valid headsymbol::IsValidFirstChar(ch)
-- determine whether thechar
is a valid first char of a head
Maintainer documentation for symbol
Note: I have used MachineInt
as the type for fn args containing
index values because it is safer, and I believe that the run-time
penalty is unimportant. This is a considered exception to the guideline
which says to use long
for indexes.
I have decided not to allow big integers as subscripts because I don't see when it could ever be genuinely useful.
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.
Bugs, Shortcomings and other ideas
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.
In redmine 747 there is a suggestion to allow symbol("x[1,2]")
;
we decided (2016-02-01) to postpone extending symbol
in this way.
It might be nice to have a function which returns the vector of subscripts of a name.
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).