# Why does GAP not know that $\mathbb{Q}[x] / (x^2 + 1)$ is a field?

## by Markus Pfeiffer

## A mildly confusing example

The following question from GAP users comes up frequently in different guises. Consider the following GAP interaction

1 2 3 4 5 6 7 | gap> x := Indeterminate(Rationals, "x");; gap> R := PolynomialRing(Rationals, [x]);; gap> f := x^2 + 1;; gap> F := R / Ideal(R, [f]); <ring Rationals, (1), (x)> gap> IsField(F); false |

Now, some undergrad algebra tells us that, since f is irreducible over \mathbb{Q}, the quotient \mathbb{Q}[x] / (x^2 + 1) should in fact be a field.

So GAP seems to be wrong. Except this is intentional, if a bit unfortunate.

## How GAP organises objects

In a previous post I introduced *filters*, *categories*,
and *properties* in GAP. *Filters* form a hierarchy on
objects, and for every given object a filter can be set, or not set.

*Categories*remember that GAP categories are
*NOT* categories in the sense of category theory
are implemented using filters, and these filters are
set at object creation and do not change during the lifetime of an
object. For algebraic structures it is best to think of the category
of an object as the signature of the structure:

- A magma is a structure with one binary operation
- A magma-with-one is a structure with one binary operation and a constant
- A magma-with-inverses is a structure with one binary operation and a unary inversion operation

GAP follows this paradigm, hence `IsMagma`

, `IsMagmaWithOne`

, and `IsMagmaWithInverses`

are *categories*. Now if we try to determine whether groups form a category,
we find out that they don’t

1 2 3 4 5 6 | gap> IsGroup <Filter "(IsMagmaWithInverses and IsAssociative)"> gap> IsMagmaWithInverses; <Category "IsMagmaWithInverses"> gap> IsAssociative <Property "IsAssociative"> |

A group in GAP is a magma with inverses (and a one) such that the binary operation is associative.

From algebra we also know that every group is a (simple) semigroup, even a monoid, yet

1 2 3 4 5 6 | gap> G := Semigroup(Transformation([2,3,1])); <commutative transformation semigroup of degree 3 with 1 generator> gap> IsGroup(G); false gap> IsMonoid(G); false |

We created the object `G`

as a semigroup, hence it is an associative
magma. Without proving that `G`

is a group and providing an isomorphism
to a group we can’t get GAP to treat `G`

as a group: the category must
not change!And one could and should consider this a feature:
It might be very expensive or impossible for GAP to figure out whether a
semigroup is a group

Loading the GAP package semigroups we get exactly this functionality:

1 2 3 4 5 6 7 8 9 10 11 | gap> LoadPackage("semigroups");; gap> S := Semigroup(Transformation([2,3,1])); <commutative transformation semigroup of degree 3 with 1 generator> gap> IsGroupAsSemigroup(S); true gap> IsomorphismPermGroup(S); MappingByFunction( <transformation group of degree 3 with 1 generator>, Group([ (1,2,3) ]), function( f ) ... end, function( x ) ... end ) gap> G := AsGroup(S); <group of size 3 with 1 generators> gap> IsGroup(G); true |

## More on the underlying problem

One reason for the confusion caused is that in GAP by
convention *almost all*There are things `CanEasilyCompareElements`

and `HasProperty`

filters have a name beginning with `Is`

, and
properties are implemented using filters, too.

It is easy to mistake a category for a property, and vice versa.

## What about the confusing introductory example?

The introductory example has exactly the same underlying causes, unfortunately there is as yet no function (that I know of) to turn a ring quotient into a field if it is easy to prove that this is possible. Maybe you want to provide a pull-request?

If you have further questions, feel free to ask us GAP people, either on the support mailing list github, or ask to be added to our Slack.