# Types, Category Names, and Structures

The following functions deal with *types* or *category names* and general structures. Magma has two levels of granularity when referring to types. In most cases, the coarser grained types (of type `Cat`) are used. Examples of these kinds of types are “polynomial rings” (`RngUPol`) and “finite fields” (`FldFin`). However, sometimes more specific typing information is sometimes useful. For instance, the algorithm used to factorize polynomials differs significantly, depending on the coefficient ring. Hence, we might wish to implement a specialized factorization algorithm polynomials over some particular ring type. Due to this need, Magma also supports *extended types*.

An extended type (of type `ECat`) can be thought of as a type taking a parameter. Using extended types, we can talk about “polynomial rings over the integers” (`RngUPol[RngInt]`), or “maps from the integers to the rationals” (`Map[RngInt, FldRat]`). Extended types can interact with normal types in all ways, and thus generally only need to be used when the extra level of information is required.

## `Type(x): Elt -> Cat`

## `Category(x): Elt -> Cat`

Given any object $x$, return the type (or category name) of $x$.

## `ExtendedType(x): Elt -> ECat`

## `ExtendedCategory(x): Elt -> ECat`

Given any object $x$, return the extended type (or category name) of $x$.

## `ISA(T, U): Cat, Cat -> BoolElt`

## `ISA(T, U): Cat, ECat -> BoolElt`

## `ISA(T, U): ECat, Cat -> BoolElt`

## `ISA(T, U): ECat, ECat -> BoolElt`

Given types (or extended types) $T$ and $U$, return whether $T$ ISA $U$, i.e., whether objects of type $T$ inherit properties of type $U$. For example, `ISA(RngInt, Rng)` is true, because the ring of integers ${\mathbb{Z}}$ is a ring.

## `BaseType(T): ECat -> Cat`

Returns the underlying base type of the extended type $T$.

## `# T: ECat -> RngIntElt`

Returns the number of parametrizing objects for the extended type $T$.

## `T[i]: ECat, RngIntElt -> .`

The $i$-th parametrizing object of the extended type $T$. Although this will usually be another extended type, as the example below shows it may not be.

## `Example: Extended Type Accessors (ex-1892d6)`

We show some of the possibilities of the extended types. First we define some simple objects and show their extended types.

```magma
> Z := Integers();
> Zx<x> := PolynomialRing(Z);
> S := [ x ];
> f1 := map<Zx -> Z | f :-> Evaluate(f, 1)>;
> D := CremonaDatabase();
>
> ExtendedType(Z);
RngInt
> ExtendedType(Zx);
RngUPol[RngInt]
> ExtendedType(S);
SeqEnum[RngUPolElt[RngInt]]
> ExtendedType(f1);
Map[RngUPol[RngInt], RngInt]
> ExtendedType(D);
DB["CrvEll"]

```

We can see a few points of note from the above. If the type is not parameterized at all, like `Z`, then the extended type prints as just the base type. The printing for `S` shows that extended types may themselves be further parameterized. The printing for `f1` shows that there may be more than one parametrizing object. The printing for `D` shows that parametrizing objects are not necessarily extended types.

We can use further investigate these with the intrinsics `BaseType`, `’#’`, and indexing.

```magma
> tS := ExtendedType(S);
> BaseType(tS);
SeqEnum
> #tS;
1
> tS[1];
RngUPolElt[RngInt]
> #tS[1];
1
> tS[1][1];
RngInt
> Type(tS[1][1]);
ECat
>
> tD := ExtendedType(D);
> BaseType(tD);
DB
> #tD;
1
> tD[1];
CrvEll
> Type(tD[1]);
MonStgElt

```

This information could be put together to generate a tree of the type information (represented as a list).

```magma
> function tree(t)
>     if Type(t) ne ECat then
>         return [* t *];
>     end if;
>     return [* BaseType(t) *] cat [* $$(t[i]) : i in [1..#t] *];
> end function;
> function type_tree(object)
>     return tree(ExtendedType(object));
> end function;
>
> type_tree(Z);
[* RngInt *]
> type_tree(Zx);
[* RngUPol, [* RngInt *] *]
> type_tree(S);
[* SeqEnum, [* RngUPolElt, [* RngInt *] *] *]
> type_tree(f1);
[* Map, [* RngUPol, [* RngInt *] *], [* RngInt *] *]
> type_tree(D);
[* DB, [* CrvEll *] *]

```

Remember that the “CrvEll” in the last tree is a string, not a type.

```magma
> Type($1[2][1]);
MonStgElt

```

## `MakeType(S): MonStgElt -> Cat`

Given a string $S$ specifying a type return the actual type corresponding to $S$. This is useful when some intrinsic name hides the symbol which normally refers to the actual type.

## `ElementType(S): Str -> Cat`

Given any structure $S$, return the type of the elements of $S$. For example, the element type of the ring of integers ${\mathbb{Z}}$ is `RngIntElt` since that is the type of the integers which lie in ${\mathbb{Z}}$.

## `CoveringStructure(S, T): Str, Str -> Str`

Given structures $S$ and $T$, return a covering structure $C$ for $S$ and $T$, so that $S$ and $T$ both embed into $C$. An error results if no such covering structure exists.

## `ExistsCoveringStructure(S, T): Str, Str -> BoolElt, Str`

Given structures $S$ and $T$, return whether a covering structure $C$ for $S$ and $T$ exists, and if so, return such a $C$, so that $S$ and $T$ both embed into $C$.

## `Example: Type Structures (ex-55c1aa)`

We demonstrate the type and structure functions.

```magma
> Type(3);
RngIntElt
> t := MakeType("RngIntElt");
> t;
RngIntElt
> Type(3) eq t;
true
> Z := IntegerRing();
> Type(Z);
RngInt
> ElementType(Z);
RngIntElt
> ISA(RngIntElt, RngElt);
true
> ISA(RngIntElt, GrpElt);
false
> ISA(FldRat, Fld);
true

```

The following give examples of when covering structures exist or do not exist.

```magma
> Q := RationalField();
> CoveringStructure(Z, Q);
Rational Field
> ExistsCoveringStructure(Z, DihedralGroup(3));
false
> ExistsCoveringStructure(Z, CyclotomicField(5));
true Cyclotomic Field of order 5 and degree 4
> ExistsCoveringStructure(CyclotomicField(3), CyclotomicField(5));
true Cyclotomic Field of order 15 and degree 8
> ExistsCoveringStructure(GF(2), GF(3));
false
> ExistsCoveringStructure(GF(2^6), GF(2, 15));
true Finite field of size 2^30

```

Our last example demonstrates the use of extended types:

```magma
> R<x> := PolynomialRing(Integers());
> ExtendedType(R);
RngUPol[RngInt]
> ISA(RngUPol[RngInt], RngUPol);
true
> f := x + 1;
> ExtendedType(f);
RngUPolElt[RngInt]
> ISA(RngUPolElt[RngInt], RngUPolElt);
true

```
