This notebook is licenced under CC BY-SA 4.0.

Sources at Github.

In [1]:

```
)set message type off
)set output algebra off
setFormat!(FormatMathJax)$JFriCASSupport
)set message type on
```

In [2]:

```
)version
```

Having types available also means to be able to convert elements from one type to another explicitly or specify functions that come from a particular domain.

We have already seen that with `identifier: SomeType`

one can declare
an identifier to be of a particular type without actually assigning
a value to this identifier.

Suppose we have a value which is of type `SomeType`

.
The notation `value :: OtherType`

is used to convert a value of
`SomeType`

to `OtherType`

.
Of course this operation does not always succeed.
In fact, it only succeeds if FriCAS is able to find in its library
an appropriate function (usually called `coerce`

, `convert`

,
or `retract`

) of type $\text{SomeType} \to \text{OtherType}$
which does the job.

The FriCAS interpreter applies coercion function automatically.
For example, when FriCAS sees `x+5`

on the command line,
it figures out that `x`

is an identifier that has no value,
so it converts this to a variable.

In [2]:

```
x
```

Out[2]:

The number 5 is of type `PositiveInteger`

.

FriCAS knows that `+`

is in infix operator, so it looks for in
its library for a function `+: (Variable(x), PositiveInteger) -> ??`

.
The result type is not yet clear. Such a function does not exist.

Before FriCAS says that the expression does not make sense,
it tries harder. There is a coercion from `Variable(x)`

to
`Polynomial(??)`

where the coefficient ring would still be unknown.
The obvious idea would be to take `PositiveInteger`

as the
coefficient domain.
But wait, polynomials are defined over a ring and the positive
integers do not form a ring.
Next try is a superdomain of PositiveInteger that is a ring.
`Integer`

is a good candidate. So we arrive at `Polynomial(Integer)`

.

In `Polynomial(Integer)`

there is a function `+: (%, %) -> %`

defined, because FriCAS knows that integer polynomials form a ring.
Note that `%`

is FriCAS' abbreviation for "this type".

It remains to embed 5 into this polynomial ring.
This is done via the coercions `coerce: PositiveInteger -> Integer`

and `coerce: Integer -> Polynomial(Integer)`

.

Taking everything into account, we see that the resulting type
is `Polynomial(Integer)`

.

In [3]:

```
e1 := x+5
```

Out[3]:

You should not be surprised that subtracting `x`

from the above
expresssion is still a polynomial.

In [4]:

```
e2 := e1-x
```

Out[4]:

Of course, this result can be retracted to a more specific domain.
However, in general this is impossible and costs time, since the
representations of 5 as an element of `Polynomial(Integer)`

and 5
as an element of `Integer`

are different.

In [5]:

```
e2 :: Integer
```

Out[5]:

Typeless computer algebra systems internally store `a*b`

as an
expression tree.
Usually then it is concluded that this is the same as `b*a`

.
In FriCAS the meaning of the multiplication operator depends on the
context it is used in.
Non-commuting structures are easily representable in FriCAS.

In [8]:

```
p: Quaternion(Integer) := quatern(1,2,0,0)
q: Quaternion(Integer) := quatern(1,0,3,0)
p*q - q*p
```

Out[8]:

Out[8]:

Out[8]:

FriCAS has a simple way to ask for properties of domains.

In [9]:

```
Integer has Ring
```

Out[9]:

In [10]:

```
Integer has Field
```

Out[10]:

In [11]:

```
Fraction Integer has Field
```

Out[11]:

In [12]:

```
Polynomial Fraction Integer has Field
```

Out[12]:

FriCAS allows to assign types to variables.

In [14]:

```
Q := Fraction Integer
PQ := SparseUnivariatePolynomial Q
```

Out[14]:

Out[14]:

The name of the variable plays no role. FriCAS shows it by default with a question mark.

In [15]:

```
q1: PQ := 2*x+8
```

Out[15]:

The output routine decides how the variable is actually printed.

In [16]:

```
[outputForm(q1,x), outputForm(q1,z)]
```

Out[16]:

In [17]:

```
q2: PQ := x^2-16
```

Out[17]:

In [18]:

```
gcd(q1,q2)
```

Out[18]:

In [19]:

```
extendedEuclidean(q1,q2+1, 1)
```

Out[19]:

In [20]:

```
PZ := SparseUnivariatePolynomial Integer
```

Out[20]:

In [21]:

```
p1: PZ := 2*x+8
```

Out[21]:

In [22]:

```
p2:PZ := x^2-16
```

Out[22]:

In [23]:

```
gcd(p1, p2)
```

Out[23]:

Since polynomials with integers as coefficients do not form a euclidean domain, there is no euclidean algorithm available.

In [22]:

```
extendedEuclidean(p1,p2+1, 1)
```

In FriCAS everything has a type. Elements like numbers,
polynomials, array, have `domains`

as their types.
For example, the type of `-5`

is `Integer`

.
The type of a domain is called a `category`

.
The type of Integer is `IntegerNumberSystem`

.
The type of a category is the distinguished name `Category`

.

In [24]:

```
-5
```

Out[24]:

FriCAS does not normally show the names of the categories a
domain belongs to.
In fact, Integer does not only belong to `IntegerNumberSystem`

,
but also to `ConvertibleTo(String)`

, `LeftOreRing`

, `Canonical`

,
and `canonicalsClosed`

.

In [25]:

```
Integer
```

Out[25]:

In [26]:

```
Integer has IntegerNumberSystem
```

Out[26]:

In [27]:

```
Integer has LeftOreRing
```

Out[27]:

A category only describes the sigatures of functions that domains that belong to this category must provide.

Categories are organised in hierarchies. A category can inherit from several other categories. Multiple inheritance is not a problem since categories only describe the interface of domains but do not implement any function themselves.

A domain must provide all function signatures of the category it belongs to. Domains can only inherit code from one single other domain.

Neither domains nor categories are built into the SPAD language. They are all implemented in a library that comes with FriCAS as source code.

A user can easily write new domains and categories and compile them. There is no difference between user defined types and library defined types.

Like the domains `Polynomial(Integer)`

and `Complex(Integer)`

or the categories `Module(Integer)`

and `VectorSpace(PrimeField(5))`

,
domains and categories can be constructed as the result of a function,
a domain or category `constructor`

. This is the basis for parametrized
polymorphism.

Which functions a category exports may depend on a parameter,
for example, `SparseUnivariatePolynomial(R)`

is of type
`EuclideanDomain`

only if the domain `R`

that is given as a parameter
is of type `Field`

.

In [28]:

```
SparseUnivariatePolynomial Fraction Integer has EuclideanDomain
```

Out[28]:

In [29]:

```
SparseUnivariatePolynomial Integer has EuclideanDomain
```

Out[29]: