GNU Free Documentation License, Version 1.2

`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]`

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 (printed form is like this`#[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(str)`

-- create a`vector<symbol>`

containing comma-separated symbols in`str`

`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)`

-- create vector of`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

**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.

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).