% generated by GAPDoc2LaTeX from XML source (Frank Luebeck)
\documentclass[a4paper,11pt]{report}
\usepackage{a4wide}
\sloppy
\pagestyle{myheadings}
\usepackage{amssymb}
\usepackage[latin1]{inputenc}
\usepackage{makeidx}
\makeindex
\usepackage{color}
\definecolor{DarkOlive}{rgb}{0.1047,0.2412,0.0064}
\definecolor{FireBrick}{rgb}{0.5812,0.0074,0.0083}
\definecolor{RoyalBlue}{rgb}{0.0236,0.0894,0.6179}
\definecolor{RoyalGreen}{rgb}{0.0236,0.6179,0.0894}
\definecolor{RoyalRed}{rgb}{0.6179,0.0236,0.0894}
\definecolor{LightBlue}{rgb}{0.8544,0.9511,1.0000}
\definecolor{Black}{rgb}{0.0,0.0,0.0}
\definecolor{FuncColor}{rgb}{1.0,0.0,0.0}
%% strange name because of pdflatex bug:
\definecolor{Chapter }{rgb}{0.0,0.0,1.0}

\usepackage{fancyvrb}

\usepackage{pslatex}

\usepackage[pdftex=true,
        a4paper=true,bookmarks=false,pdftitle={Written with GAPDoc},
        pdfcreator={LaTeX with hyperref package / GAPDoc},
        colorlinks=true,backref=page,breaklinks=true,linkcolor=RoyalBlue,
        citecolor=RoyalGreen,filecolor=RoyalRed,
        urlcolor=RoyalRed,pagecolor=RoyalBlue]{hyperref}

% write page numbers to a .pnr log file for online help
\newwrite\pagenrlog
\immediate\openout\pagenrlog =\jobname.pnr
\immediate\write\pagenrlog{PAGENRS := [}
\newcommand{\logpage}[1]{\protect\write\pagenrlog{#1, \thepage,}}
%% were never documented, give conflicts with some additional packages


\newcommand{\GAP}{\textsf{GAP}}

\begin{document}

\logpage{[ 0, 0, 0 ]}
\begin{titlepage}
\begin{center}{\Huge \textbf{\textsf{Circle}\mbox{}}}\\[1cm]
\hypersetup{pdftitle=\textsf{Circle}}
\markright{\scriptsize \mbox{}\hfill \textsf{Circle} \hfill\mbox{}}
{\Large \textbf{Adjoint groups of finite rings\mbox{}}}\\[1cm]
{Version 1.3.1\mbox{}}\\[1cm]
{January 2008\mbox{}}\\[1cm]
\mbox{}\\[2cm]
{\large \textbf{Alexander Konovalov    \mbox{}}}\\
{\large \textbf{Panagiotis Soules   \mbox{}}}\\
\hypersetup{pdfauthor=Alexander Konovalov    ; Panagiotis Soules   }
\end{center}\vfill

\mbox{}\\
{\mbox{}\\
\small \noindent \textbf{Alexander Konovalov    } --- Email: \href{mailto://konovalov@member.ams.org} {\texttt{konovalov@member.ams.org}}\\
 --- Homepage: \href{http://www.cs.st-andrews.ac.uk/~alexk/} {\texttt{http://www.cs.st-andrews.ac.uk/\texttt{\symbol{126}}alexk/}}\\
 --- Address: \begin{minipage}[t]{8cm}\noindent
 School of Computer Science\\
 University of St Andrews\\
 Jack Cole Building, North Haugh,\\
 St Andrews, Fife, KY16 9SX, Scotland \end{minipage}
}\\
{\mbox{}\\
\small \noindent \textbf{Panagiotis Soules   } --- Email: \href{mailto://psoules@math.uoa.gr} {\texttt{psoules@math.uoa.gr}}\\
 --- Address: \begin{minipage}[t]{8cm}\noindent
 Department of Mathematics\\
 National and Capodistrian University of Athens\\
 Panepistimioupolis, GR-15784, Athens, Greece \end{minipage}
}\\
\end{titlepage}

\newpage\setcounter{page}{2}
{\small 
\section*{Abstract}
\logpage{[ 0, 0, 1 ]}
 \index{Circle package@\textsf{Circle} package} The \textsf{GAP}4 package \textsf{Circle} extends the \textsf{GAP} functionality for computations in adjoint groups of associative rings. It
provides functionality to construct circle objects that will respect the
circle multiplication $ r \cdot s = r + s + rs $, and to compute adjoint semigroups and adjoint groups of finite rings. 

 \mbox{}}\\[1cm]
{\small 
\section*{Copyright}
\logpage{[ 0, 0, 2 ]}
 {\copyright} 2006-2008 by Alexander Konovalov and Panagiotis Soules 

 \textsf{Circle} is free software; you can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version. For
details, see the FSF's own site \href{http://www.gnu.org/licenses/gpl.html} {\texttt{http://www.gnu.org/licenses/gpl.html}}. 

 If you obtained \textsf{Circle}, we would be grateful for a short notification sent to one of the authors. 

 If you publish a result which was partially obtained with the usage of \textsf{Circle}, please cite it in the following form: 

 A. Konovalov, P. Soules. \emph{Circle --- Adjoint groups of finite rings, Version 1.3.1;} 2008 (\href{http://www.cs.st-andrews.ac.uk/~alexk/circle.htm} {\texttt{http://www.cs.st-andrews.ac.uk/\texttt{\symbol{126}}alexk/circle.htm}}). \mbox{}}\\[1cm]
{\small 
\section*{Acknowledgements}
\logpage{[ 0, 0, 3 ]}
 We acknowledge very much Alexander Hulpke and James Mitchell for their helpful
comments and advices, and the referee for testing the package and useful
suggestions. 

 \mbox{}}\\[1cm]
\newpage

\def\contentsname{Contents\logpage{[ 0, 0, 4 ]}}

\tableofcontents
\newpage

  
\chapter{\textcolor{Chapter }{Introduction}}\label{Intro}
\logpage{[ 1, 0, 0 ]}
\hyperdef{L}{X7DFB63A97E67C0A1}{}
{
  
\section{\textcolor{Chapter }{General aims}}\label{IntroAbstract}
\logpage{[ 1, 1, 0 ]}
\hyperdef{L}{X8557083378F2A3B2}{}
{
  Let $R$ be an associative ring, not necessarily with one. The set of all elements of $R$ forms a monoid with the neutral element $0$ from $R$ under the operation $ r \cdot s = r + s + rs $ defined for all $r$ and $s$ of $R$. This operation is called the \emph{circle multiplication}, and it is also known as the \emph{star multiplication}. The monoid of elements of $R$ under the circle multiplication is called the adjoint semigroup of $R$ and is denoted by $R^{ad}$. The group of all invertible elements of this monoid is called the adjoint
group of $R$ and is denoted by $R^{*}$. 

 These notions naturally lead to a number of questions about the connection
between a ring and its adjoint group, for example, how the ring properties
will determine properties of the adjoint group; which groups can appear as
adjoint groups of rings; which rings can have adjoint groups with prescribed
properties, etc. 

 For example, V. O. Gorlov in \cite{Gorlov-1995} gives a full list of finite nilpotent algebras $R$, such that $R^2 \ne 0$ and the adjoint group of $R$ is metacyclic (but not cyclic). 

 S. V. Popovich and Ya. P. Sysak in \cite{Popovich-Sysak-1997} characterize all quasiregular algebras such that all subgroups of their
adjoint group are their subalgebras. In particular, they show that all
algebras of such type are nilpotent with nilpotency index at most three. 

 Various connections between properties of a ring and its adjoint group were
considered by O. D. Artemovych and Yu. B. Ishchuk in \cite{Artemovych-Ishchuk-1997}. 

 B. Amberg and L. S. Kazarin in \cite{Amberg-Kazarin-2000} give the description of all nonisomorphic finite $p$-groups that can occur as the adjoint group of some nilpotent $p$-algebra of the dimension at most 5. 

 In \cite{Amberg-Sysak-2001} B. Amberg and Ya. P. Sysak give a survey of results on adjoint groups of
radical rings, including such topics as subgroups of the adjoint group;
nilpotent groups which are isomorphic to the adjoint group of some radical
ring; adjoint groups of finite nilpotent \$p\$-algebras. The authors continued
their investigations in further papers \cite{Amberg-Sysak-2002} and \cite{Amberg-Sysak-2004}. 

 In \cite{Kazarin-Soules-2004} L. S. Kazarin and P. Soules study associative nilpotent algebras over a field
of positive characteristic whose adjoint group has a small number of
generators. 

 The main objective of the proposed \textsf{GAP}4 package \textsf{Circle} is to extend the \textsf{GAP} functionality for computations in adjoint groups of associative rings to make
it possible to use the \textsf{GAP} system for the investigation of the above described questions. 

 \textsf{Circle} provides functionality to construct circle objects that will respect the
circle multiplication $ r \cdot s = r + s + rs $, create multiplicative structures, generated by such objects, and compute
adjoint semigroups and adjoint groups of finite rings. 

 Also we hope that the package will be useful as an example of extending the \textsf{GAP} system with new multiplicative objects. Relevant details are explained in the
next chapter of the manual. }

  
\section{\textcolor{Chapter }{Installation and system requirements}}\label{IntroInstall}
\logpage{[ 1, 2, 0 ]}
\hyperdef{L}{X7DB566D5785B7DBC}{}
{
  \textsf{Circle} does not use external binaries and, therefore, works without restrictions on
the type of the operating system. It is designed for \textsf{GAP}4.4 and no compatibility with previous releases of \textsf{GAP}4 is guaranteed. 

 To use the \textsf{Circle} online help it is necessary to install the \textsf{GAP}4 package \textsf{GAPDoc} by Frank L\texttt{\symbol{92}}"ubeck and Max Neunh\texttt{\symbol{92}}"offer,
which is available from the \textsf{GAP} site or from \href{http://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc/} {\texttt{http://www.math.rwth-aachen.de/\texttt{\symbol{126}}Frank.Luebeck/GAPDoc/}}. 

 \textsf{Circle} is distributed in standard formats (\texttt{zoo}, \texttt{tar.gz}, \texttt{tar.bz2}, \texttt{-win.zip}) and can be obtained from \href{http://www.cs.st-andrews.ac.uk/~alexk/circle.htm} {\texttt{http://www.cs.st-andrews.ac.uk/\texttt{\symbol{126}}alexk/circle.htm}}. To unpack the archive \texttt{circle-1.3.1.zoo} you need the program \texttt{unzoo}, which can be obtained from the \textsf{GAP} homepage \href{http://www.gap-system.org/} {\texttt{http://www.gap-system.org/}} (see section `Distribution'). To install \textsf{Circle}, copy this archive into the \texttt{pkg} subdirectory of your \textsf{GAP}4.4 installation. The subdirectory \texttt{circle} will be created in the \texttt{pkg} directory after the following command: 

 \texttt{unzoo -x circle-1.3.1.zoo} 

 Installation using other archive formats is performed in a similar way. }

 }

  
\chapter{\textcolor{Chapter }{Implementing circle objects}}\label{Objects}
\logpage{[ 2, 0, 0 ]}
\hyperdef{L}{X8404D6997A466953}{}
{
  In this chapter we explain how the \textsf{GAP} system may be extended with new objects using the circle multiplication as an
example. We follow the guidelines given in the last two chapters of the \textsf{GAP} Programming Tutorial and refer to them for more details. 
\section{\textcolor{Chapter }{First attempts}}\label{ObjectsFirst}
\logpage{[ 2, 1, 0 ]}
\hyperdef{L}{X86492955868108EC}{}
{
  Of course, having two ring elements, you can straightforwardly compute their
circle product defined as $ r \cdot s = r + s + rs $. You can do this in a command line, and it is a trivial task to write a
simplest function of two arguments that will do this: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> CircleMultiplication := function(a,b)
  >      return a+b+a*b;
  >    end;
  function( a, b ) ... end
  gap> CircleMultiplication(2,3); 
  11
  gap> CircleMultiplication( ZmodnZObj(2,8), ZmodnZObj(5,8) );      
  ZmodnZObj( 1, 8 )
  
\end{Verbatim}
 However, there is no check whether both arguments belong to the same ring and
whether they are ring elements at all, so it is easy to obtain some
meaningless results: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> CircleMultiplication( 3, ZmodnZObj(3,8) );
  ZmodnZObj( 7, 8 )
  gap> CircleMultiplication( [1], [2,3] );
  [ 5, 5 ]
  
\end{Verbatim}
 You can include some tests for arguments, and maybe the best way of doing this
would be declaring a new operation for two ring elements, and installing the
previous function as a method for this operation. This will check
automatically if the arguments are ring elements from the common ring: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareOperation( "BetterCircleMultiplication",                             
  >      [IsRingElement,IsRingElement] );
  gap> InstallMethod( BetterCircleMultiplication,
  >      IsIdenticalObj,
  >      [IsRingElement,IsRingElement],  
  >      CircleMultiplication );
  gap> BetterCircleMultiplication(2,3);
  11
  gap> BetterCircleMultiplication( ZmodnZObj(2,8), ZmodnZObj(5,8) );
  ZmodnZObj( 1, 8 )
  
\end{Verbatim}
 Nevertheless, the functionality gained from such operation would be rather
limited. You will not be able to compute circle product via the infix operator \texttt{*}, and, moreover, you will not be able to create higher level objects such as
semigroups and groups with respect to the circle multiplication.

 In order to "integrate" the circle multiplication into the \textsf{GAP} library properly, instead of defining \emph{new} operations for existing objects, we should define \emph{new} objects for which the infix operator \texttt{*} will perform the circle multiplication. This approach is explained in the next
two sections. }

 
\section{\textcolor{Chapter }{Defining circle objects}}\label{ObjectsDefining}
\logpage{[ 2, 2, 0 ]}
\hyperdef{L}{X852C1F3281137DD6}{}
{
  Thus, we are going to implement \emph{circle objects}, for which we can envisage the following functionality: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> CircleObject( 2 ) * CircleObject( 3 );                       
  CircleObject( 11 )
  
\end{Verbatim}
 First we need to distinguish these new objects from other \textsf{GAP} objects. This is done via the \emph{type} of the objects, that is mainly determined by their \emph{category}, \emph{representation} and \emph{family}. 

 We start with declaring the category \texttt{IsCircleObject} as a subcategory of \texttt{IsMultiplicativeElementWithInverse}. Thus, each circle object will "know" that it is \texttt{IsMultiplicativeElementWithInverse}, and this will make it possible to apply to circle objects such operations as \texttt{One} and \texttt{Inverse} (the latter is allowed to return \texttt{fail} for a given circle object). 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareCategory( "IsCircleObject", IsMultiplicativeElementWithInverse );
  
\end{Verbatim}
 Further we would like to create semigroups and groups generated by circle
objects. Such structures will be \emph{collections} of circle objects, so they will be in the category \texttt{CategoryCollections( IsCircleObject )}. This is why immediately after we declare the underlying category of circle
objects, we need also to declare the category of their collections: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareCategoryCollections( "IsCircleObject" );
  
\end{Verbatim}
 On the next step we should think about the internal representation of circle
objects. A natural way would be to store the underlying ring element in a
list-like structure at its first position. We do not foresee any other data
that we need to store internally in the circle object. This is quite common
situation, so we may define first \texttt{IsPositionalObjectOneSlotRep} that is the list-like representation with only one position in the list, and
then declare a synonym \texttt{IsDefaultCircleObject} that means that we are dealing with a circle object in one-slot
representation: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareRepresentation( "IsPositionalObjectOneSlotRep",
  >     IsPositionalObjectRep, [ 1 ] );
  gap> DeclareSynonym( "IsDefaultCircleObject",
  >     IsCircleObject and IsPositionalObjectOneSlotRep );
  
\end{Verbatim}
 Until now we are still unable to create circle objects, because we did not
specify to which family they will belong. Naturally, having a ring, we want to
have all circle objects for elements of this ring in the same family to be
able to multiply them, and we expect circle objects for elements of different
rings to be placed in different families. Thus, it would be nice to establish
one-to-one correspondence between the family of ring elements and a family of
circle elements for this ring. We can store the corresponding circle family as
an attribute of the ring elements family. To do this first we declare an
attribute \texttt{CircleFamily} for families: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareAttribute( "CircleFamily", IsFamily );
  
\end{Verbatim}
 Now we install the method that stores the corresponding circle family in this
attribute: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( CircleFamily,
  >     "for a family",
  >     [ IsFamily ],
  >     function( Fam )
  >     local F;
  >   # create the family of circle elements
  >   F:= NewFamily( "CircleFamily(...)", IsCircleObject );
  >   if HasCharacteristic( Fam ) then
  >     SetCharacteristic( F, Characteristic( Fam ) );
  >   fi;
  >   # store the type of objects in the output
  >   F!.CircleType:= NewType( F, IsDefaultCircleObject );
  >   # Return the circle family
  >   return F;
  > end );
  
\end{Verbatim}
 Similarly, we want one-to-one correspondence between circle elements and
underlying ring elements. We declare an attribute \texttt{CircleObject} for a ring element, and then install the method to create new circle object
from the ring element. This method takes the family of the ring element, finds
corresponding circle family, extracts from it the type of circle objects and
finally creates the new circle object of that type: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareAttribute( "CircleObject", IsRingElement );
  gap> InstallMethod( CircleObject,
  >     "for a ring element",
  >     [ IsRingElement ],
  >     obj -> Objectify( CircleFamily( FamilyObj( obj ) )!.CircleType,
  >                       [ Immutable( obj ) ] ) );
  
\end{Verbatim}
 Only after entering all code above we are able to create some circle object.
However, it is displayed just as \texttt{{\textless}object{\textgreater}}, though we can get the underlying ring element using the "!" operator: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> a:=CircleObject(2);
  <object>
  gap> a![1];
  2
  
\end{Verbatim}
 We can check that the intended relation between families holds: 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> FamilyObj( CircleObject ( 2 ) ) = CircleFamily( FamilyObj( 2 ) );
  true
  
\end{Verbatim}
 We can not multiply circle objects yet. But before implementing this, first
let us improve the output by installing the method for \texttt{PrintObj}: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( PrintObj,
  >     "for object in `IsCircleObject'",
  >     [ IsDefaultCircleObject ],
  >     function( obj )
  >     Print( "CircleObject( ", obj![1], " )" );
  >     end );
  
\end{Verbatim}
 This method will be used by \texttt{Print} function, and also by \texttt{View}, since we did not install special method for \texttt{ViewObj} for circle objects. As a result of this installation, the output became more
meaningful: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> a;
  CircleObject( 2 )
  
\end{Verbatim}
 We need to avoid the usage of "!" operator, which, in general, is not
recommended to the user (for example, if \textsf{GAP} developers will change the internal representation of some object, all \textsf{GAP} functions that deal with it must be adjusted appropriately, while if the
user's code had direct access to that representation via "!", an error may
occur). To do this, we wrap getting the first component of a circle object in
the following operation: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> DeclareOperation("UnderlyingRingElement", [ IsCircleObject] );
  gap> InstallMethod( UnderlyingRingElement,
  >     "for a circle object", 
  >     [ IsCircleObject],
  >     obj -> obj![1] );
  gap> UnderlyingRingElement(a);
  2
  
\end{Verbatim}
 }

 
\section{\textcolor{Chapter }{Installing operations for circle objects}}\label{ObjectsOperations}
\logpage{[ 2, 3, 0 ]}
\hyperdef{L}{X85B1413E7FBC8ACB}{}
{
  Now we are finally able to install circle multiplication as a default method
for the multiplication of circle objects, and perform the computation that we
envisaged in the beginning: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( \*,
  >     "for two objects in `IsCircleObject'",
  >     IsIdenticalObj,
  >     [ IsDefaultCircleObject, IsDefaultCircleObject ],
  >     function( a, b )
  >     return CircleObject( a![1] + b![1] + a![1]*b![1] );
  >     end );
  gap> CircleObject(2)*CircleObject(3);
  CircleObject( 11 )
  
\end{Verbatim}
 However, this functionality is not enough to form semigroups or groups
generated by circle elements. We need to be able to check whether two circle
objects are equal, and we need to define ordering for them (for example, to be
able to form sets of circle elements). Since we already have both operations
for underlying ring elements, this can be implemented in a straightforward
way: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( \=,
  >     "for two objects in `IsCircleObject'",
  >     IsIdenticalObj,
  >     [ IsDefaultCircleObject, IsDefaultCircleObject ],
  >     function( a, b )
  >     return a![1] = b![1];
  >     end );
  gap> InstallMethod( \<,
  >     "for two objects in `IsCircleObject'",
  >     IsIdenticalObj,
  >     [ IsDefaultCircleObject, IsDefaultCircleObject ],
  >     function( a, b )
  >     return a![1] < b![1];
  >     end );
  
\end{Verbatim}
 Further, zero element of the ring plays a role of the neutral element for the
circle multiplication, and we add this knowledge to our code in a form of a
method for \texttt{OneOp} that returns circle object for the corresponding zero object: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( OneOp,
  >     "for an object in `IsCircleObject'",
  >     [ IsDefaultCircleObject ],
  >     a -> CircleObject( Zero( a![1] ) ) );
  gap> One(a);
  CircleObject( 0 )
  
\end{Verbatim}
 Now we are already able to create monoids generated by circle objects: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> S:=Monoid(a);
  <monoid with 1 generator>
  gap> One(S);
  CircleObject( 0 )
  gap> S:=Monoid( CircleObject( ZmodnZObj( 2,8) ) );
  <monoid with 1 generator>
  gap> Size(S);
  2
  gap> AsList(S);
  [ CircleObject( ZmodnZObj( 0, 8 ) ), CircleObject( ZmodnZObj( 2, 8 ) ) ]
  
\end{Verbatim}
 Finally, to generate groups using circle objects, we need to add a method for
the \texttt{InverseOp}. In our implementation we will assume that the underlying ring is a subring
of the ring with one, thus, if the circle inverse for an element $x$ exists, than it can be computed as $-x(1+x)^{-1}$: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> InstallMethod( InverseOp,
  >     "for an object in `IsCircleObject'",
  >     [ IsDefaultCircleObject ],
  >     function( a )
  >     local x;
  >     x := Inverse( One( a![1] ) + a![1] );
  >     if x = fail then
  >       return fail;
  >     else
  >       return CircleObject( -a![1] * x );
  >     fi;
  >     end );
  gap> CircleObject(-2)^-1;                
  CircleObject( -2 )
  gap> CircleObject(2)^-1; 
  CircleObject( -2/3 )
  
\end{Verbatim}
 The last method already makes it possible to create groups generated by circle
objects (the warning may be ignored): 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> Group( CircleObject(2) );                       
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( 2 ) ]
  <group with 1 generators>
  gap> G:=Group( [CircleObject( ZmodnZObj( 2,8 ) )  ]);
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 2, 8 ) ) ]
  <group with 1 generators>
  gap> Size(G);
  2
  gap> AsList(G);
  [ CircleObject( ZmodnZObj( 0, 8 ) ), CircleObject( ZmodnZObj( 2, 8 ) ) ]
  
\end{Verbatim}
 The \textsf{GAP} code used in this Chapter, is contained in the files \texttt{circle/lib/circle.gd} and \texttt{circle/lib/circle.gi}. We also refer to last two chapters of the \textsf{GAP} Programming Tutorial for another examples of implementing new \textsf{GAP} objects and further details. }

 }

  
\chapter{\textcolor{Chapter }{\textsf{Circle} functions}}\label{Funct}
\logpage{[ 3, 0, 0 ]}
\hyperdef{L}{X81CE94FA8343B1D8}{}
{
  To use the \textsf{Circle} package first you need to load it as follows: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> LoadPackage("circle");
  -----------------------------------------------------------------------------
  Loading  Circle 1.3.1 (Adjoint groups of finite rings)
  by Alexander Konovalov (http://www.cs.st-andrews.ac.uk/~alexk/) and
     Panagiotis Soules (psoules@math.uoa.gr).
  -----------------------------------------------------------------------------
  true
  gap>
  
\end{Verbatim}
 Note that if you entered examples from the previous chapter, you need to
restart \textsf{GAP} before loading the \textsf{Circle} package. 
\section{\textcolor{Chapter }{Circle objects}}\label{CircleObjects}
\logpage{[ 3, 1, 0 ]}
\hyperdef{L}{X7E25EF1786B5F87C}{}
{
  Because for elements of the ring $R$ the ordinary multiplication is already denoted by \texttt{*}, for the implementation of the circle multiplication in the adjoint semigroup
we need to wrap up ring elements as CircleObjects, for which \texttt{*} is defined to be the circle multiplication. 

\subsection{\textcolor{Chapter }{CircleObject}}
\logpage{[ 3, 1, 1 ]}\nobreak
\hyperdef{L}{X7F5C18AA7B433BDD}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{CircleObject({\slshape x})\index{CircleObject@\texttt{CircleObject}}
\label{CircleObject}
}\hfill{\scriptsize (attribute)}}\\


 Let \mbox{\texttt{\slshape x}} be a ring element. Then \texttt{CircleObject(x)} returns the corresponding circle object. If \mbox{\texttt{\slshape x}} lies in the family \texttt{fam}, then \texttt{CircleObject(x)} lies in the family \texttt{CircleFamily} (\ref{CircleFamily}), corresponding to the family \texttt{fam}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> a := CircleObject( 2 );
  CircleObject( 2 )
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{UnderlyingRingElement}}
\logpage{[ 3, 1, 2 ]}\nobreak
\hyperdef{L}{X874B2B2A7F5A9A78}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{UnderlyingRingElement({\slshape x})\index{UnderlyingRingElement@\texttt{UnderlyingRingElement}}
\label{UnderlyingRingElement}
}\hfill{\scriptsize (operation)}}\\


 Returns the corresponding ring element for the circle object \mbox{\texttt{\slshape x}}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> a := CircleObject( 2 );
  CircleObject( 2 )
  gap> UnderlyingRingElement( a );    
  2
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{IsCircleObject}}
\logpage{[ 3, 1, 3 ]}\nobreak
\hyperdef{L}{X810FB77F860F888D}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsCircleObject({\slshape x})\index{IsCircleObject@\texttt{IsCircleObject}}
\label{IsCircleObject}
}\hfill{\scriptsize (Category)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsCircleObjectCollection({\slshape x})\index{IsCircleObjectCollection@\texttt{IsCircleObjectCollection}}
\label{IsCircleObjectCollection}
}\hfill{\scriptsize (Category)}}\\


 An object \mbox{\texttt{\slshape x}} lies in the category \texttt{IsCircleObject} if and only if it lies in a family constructed by \texttt{CircleFamily} (\ref{CircleFamily}). Since circle objects can be multiplied via \texttt{*} with elements in their family, and we need operations \texttt{One} and \texttt{Inverse} to deal with groups they generate, circle objects are implemented in the
category \texttt{IsMultiplicativeElementWithInverse}. A collection of circle objects (e.g. adjoint semigroup or adjoint group)
will lie in the category \texttt{IsCircleObjectCollection}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsCircleObject( 2 ); IsCircleObject( CircleObject( 2 ) );            
  false
  true
  gap> IsMultiplicativeElementWithInverse( CircleObject( 2 ) );
  true
  gap> IsCircleObjectCollection( [ CircleObject(0), CircleObject(2) ] );
  true
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{IsPositionalObjectOneSlotRep}}
\logpage{[ 3, 1, 4 ]}\nobreak
\hyperdef{L}{X8469C7F67A8864B3}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsPositionalObjectOneSlotRep({\slshape x})\index{IsPositionalObjectOneSlotRep@\texttt{IsPositionalObjectOneSlotRep}}
\label{IsPositionalObjectOneSlotRep}
}\hfill{\scriptsize (Representation)}}\\
\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsDefaultCircleObject({\slshape x})\index{IsDefaultCircleObject@\texttt{IsDefaultCircleObject}}
\label{IsDefaultCircleObject}
}\hfill{\scriptsize (Representation)}}\\


 To store the corresponding circle object, we need only to store the underlying
ring element. Since this is quite common situation, we defined the
representation \texttt{IsPositionalObjectOneSlotRep} for a more general case. Then we defined \texttt{IsDefaultCircleObject} as a synonym of \texttt{IsPositionalObjectOneSlotRep} for objects in \texttt{IsCircleObject} (\ref{IsCircleObject}). 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsPositionalObjectOneSlotRep( CircleObject( 2 ) );
  true
  gap> IsDefaultCircleObject( CircleObject( 2 ) );                          
  true
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{CircleFamily}}
\logpage{[ 3, 1, 5 ]}\nobreak
\hyperdef{L}{X7F88A0017DC2E878}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{CircleFamily({\slshape fam})\index{CircleFamily@\texttt{CircleFamily}}
\label{CircleFamily}
}\hfill{\scriptsize (attribute)}}\\


 \texttt{CircleFamily(fam)} is a family, elements of which are in one-to-one correspondence with elements
of the family \mbox{\texttt{\slshape fam}}, but with the circle multiplication as an infix multiplication. That is, for $x$, $y$ in \mbox{\texttt{\slshape fam}}, the product of their images in the \texttt{CircleFamily(fam)} will be the image of $ x + y + x y $. The relation between these families is demonstrated by the following
equality: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> FamilyObj( CircleObject ( 2 ) ) = CircleFamily( FamilyObj( 2 ) );
  true
  
\end{Verbatim}
 }

 }

 
\section{\textcolor{Chapter }{Operations with circle objects}}\label{CircleOperations}
\logpage{[ 3, 2, 0 ]}
\hyperdef{L}{X85ECB0B482AB3170}{}
{
  

\subsection{\textcolor{Chapter }{One}}
\logpage{[ 3, 2, 1 ]}\nobreak
\hyperdef{L}{X8129A6877FFD804B}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{One({\slshape x})\index{One@\texttt{One}}
\label{One}
}\hfill{\scriptsize (operation)}}\\


 This operation returns the multiplicative neutral element for the circle
object \mbox{\texttt{\slshape x}}. The result is the circle object corresponding to the additive neutral
element of the appropriate ring. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> One( CircleObject( 5 ) );
  CircleObject( 0 )
  gap> One( CircleObject( 5 ) ) = CircleObject( Zero( 5 ) );
  true
  gap> One( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );
  CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{InverseOp}}
\logpage{[ 3, 2, 2 ]}\nobreak
\hyperdef{L}{X82EC4F49877D6EB1}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{InverseOp({\slshape x})\index{InverseOp@\texttt{InverseOp}}
\label{InverseOp}
}\hfill{\scriptsize (operation)}}\\


 For a circle object \mbox{\texttt{\slshape x}}, returns the multiplicative inverse of \mbox{\texttt{\slshape x}} with respect to the circle multiplication; if such one does not exist then \texttt{fail} is returned.

 In our implementation we assume that the underlying ring is a subring of the
ring with one, thus, if the circle inverse for an element $x$ exists, than it can be computed as $-x(1+x)^{-1}$. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> CircleObject( -2 )^-1;                        
  CircleObject( -2 )
  gap> CircleObject( 2 )^-1; 
  CircleObject( -2/3 )
  gap> CircleObject( -2 )*CircleObject( -2 )^-1;
  CircleObject( 0 )
  
\end{Verbatim}
 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> m := CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] );   
  CircleObject( [ [ 1, 1 ], [ 0, 1 ] ] )
  gap> m^-1;    
  CircleObject( [ [ -1/2, -1/4 ], [ 0, -1/2 ] ] )
  gap> m * m^-1;
  CircleObject( [ [ 0, 0 ], [ 0, 0 ] ] )
  gap> CircleObject( [ [ 0, 1 ], [ 1, 0 ] ] )^-1; 
  fail
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{IsUnit}}
\logpage{[ 3, 2, 3 ]}\nobreak
\hyperdef{L}{X85CBFBAE78DE72E8}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsUnit({\slshape [R, ]x})\index{IsUnit@\texttt{IsUnit}}
\label{IsUnit}
}\hfill{\scriptsize (operation)}}\\


 Let \mbox{\texttt{\slshape x}} be a circle object corresponding to an element of the ring \mbox{\texttt{\slshape R}}. Then the operation \texttt{IsUnit} returns \texttt{true}, if \mbox{\texttt{\slshape x}} is invertible in \mbox{\texttt{\slshape R}} with respect to the circle multiplication, and \texttt{false} otherwise. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsUnit( Integers, CircleObject( -2 ) );
  true
  gap> IsUnit( Integers, CircleObject( 2 ) ); 
  false
  gap> IsUnit( Rationals, CircleObject( 2 ) );        
  true
  gap> IsUnit( ZmodnZ(8), CircleObject( ZmodnZObj(2,8) ) );
  true
  gap> m := CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] );;
  gap> IsUnit( FullMatrixAlgebra( Rationals, 2 ), m );
  true
  
\end{Verbatim}
 If the first argument is omitted, the result will be returned with respect to
the default ring of the circle object \mbox{\texttt{\slshape x}}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsUnit( CircleObject( -2 ) );
  true
  gap> IsUnit( CircleObject( 2 ) ); 
  false
  gap> IsUnit( CircleObject( ZmodnZObj(2,8) ) );
  true
  gap> IsUnit( CircleObject( [ [ 1, 1 ],[ 0, 1 ] ] ) );                                    
  true
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{IsCircleUnit}}
\logpage{[ 3, 2, 4 ]}\nobreak
\hyperdef{L}{X7CE7866F7CD00709}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{IsCircleUnit({\slshape [R, ]x})\index{IsCircleUnit@\texttt{IsCircleUnit}}
\label{IsCircleUnit}
}\hfill{\scriptsize (operation)}}\\


 Let \mbox{\texttt{\slshape x}} be an element of the ring \mbox{\texttt{\slshape R}}. Then \texttt{IsCircleUnit( R, x )} determines whether \mbox{\texttt{\slshape x}} is invertible in \mbox{\texttt{\slshape R}} with respect to the circle multilpication. This is equivalent to the condition
that 1+\mbox{\texttt{\slshape x}} is a unit in \mbox{\texttt{\slshape R}} with respect to the ordinary multiplication. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsCircleUnit( Integers, -2 );
  true
  gap> IsCircleUnit( Integers, 2 ); 
  false
  gap> IsCircleUnit( Rationals, 2 );          
  true
  gap> IsCircleUnit( ZmodnZ(8), ZmodnZObj(2,8) ); 
  true
  gap> m := [ [ 1, 1 ],[ 0, 1 ] ];                
  [ [ 1, 1 ], [ 0, 1 ] ]
  gap> IsCircleUnit( FullMatrixAlgebra(Rationals,2), m );
  true
  
\end{Verbatim}
 If the first argument is omitted, the result will be returned with respect to
the default ring of \mbox{\texttt{\slshape x}}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> IsCircleUnit( -2 );                               
  true
  gap> IsCircleUnit( 2 ); 
  false
  gap> IsCircleUnit( ZmodnZObj(2,8) );           
  true
  gap> IsCircleUnit( [ [ 1, 1 ],[ 0, 1 ] ] ); 
  true
  
\end{Verbatim}
 }

 }

 
\section{\textcolor{Chapter }{Construction of the adjoint semigroup and adjoint group}}\label{CircleAdjointGroups}
\logpage{[ 3, 3, 0 ]}
\hyperdef{L}{X86F80DD8823966F7}{}
{
  

\subsection{\textcolor{Chapter }{AdjointSemigroup}}
\logpage{[ 3, 3, 1 ]}\nobreak
\hyperdef{L}{X83993FD0848D0C80}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{AdjointSemigroup({\slshape R})\index{AdjointSemigroup@\texttt{AdjointSemigroup}}
\label{AdjointSemigroup}
}\hfill{\scriptsize (attribute)}}\\


 If \mbox{\texttt{\slshape R}} is a finite ring then \texttt{AdjointSemigroup(\mbox{\texttt{\slshape R}})} will return the monoid which is formed by all elements of \mbox{\texttt{\slshape R}} with respect to the circle multiplication. 

 The implementation is rather straightforward and was added to provide a link
to the \textsf{GAP} functionality for semigroups. It assumes that the enumaration of all elements
of the ring \mbox{\texttt{\slshape R}} is feasible. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R:=Ring( [ ZmodnZObj(2,8) ] );
  <ring with 1 generators>
  gap> S:=AdjointSemigroup(R);
  <monoid with 4 generators>
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{AdjointGroup}}
\logpage{[ 3, 3, 2 ]}\nobreak
\hyperdef{L}{X868FAC7E87D11137}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{AdjointGroup({\slshape R})\index{AdjointGroup@\texttt{AdjointGroup}}
\label{AdjointGroup}
}\hfill{\scriptsize (attribute)}}\\


 If \mbox{\texttt{\slshape R}} is a finite radical algebra then \texttt{AdjointGroup(\mbox{\texttt{\slshape R}})} will return the adjoint group of \mbox{\texttt{\slshape R}}, given as a group generated by a set of circle objects. 

 To compute the adjoint group of a finite radical algebra, \textsf{Circle} uses the fact that all elements of a radical algebra form a group with respect
to the circle multiplication. Thus, the adjoint group of \mbox{\texttt{\slshape R}} coincides with \mbox{\texttt{\slshape R}} elementwise, and we can randomly select an appropriate set of generators for
the adjoint group. 

 The warning is displayed by \texttt{IsGeneratorsOfMagmaWithInverses} method defined in \texttt{gap4r4/lib/grp.gi} and may be ignored. 

 \textsc{WARNINGS:} 

 1. The set of generators of the returned group is not required to be a
generating set of minimal possible order. 

 2. \texttt{AdjointGroup} is stored as an attribute of \mbox{\texttt{\slshape R}}, so for the same copy of \mbox{\texttt{\slshape R}} calling it again you will get the same result. But if you will create another
copy of \mbox{\texttt{\slshape R}} in the future, the output may differ because of the random selection of
generators. If you want to have the same generating set, next time you should
construct a group immediately specifying circle objects that generate it. 

 3. In most cases, to investigate some properties of the adjoint group, it is
necessary first to convert it to an isomorphic permutation group or to a
PcGroup. 

 For example, we can create the following commutative 2-dimensional radical
algebra of order 4 over the field of two elements, and show that its adjoint
group is a cyclic group of order 4: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> x:=[ [ 0, 1, 0 ],
  >         [ 0, 0, 1 ],
  >         [ 0, 0, 0 ] ];;
  gap> R := Algebra( GF(2), [ One(GF(2))*x ] );  
  <algebra over GF(2), with 1 generators>
  gap> RadicalOfAlgebra( R ) = R;
  true
  gap> Dimension(R);
  2
  gap> G := AdjointGroup( R );    
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( [ [ 0*Z(2), 0*Z(2), Z(2)^0 ], [ 0*Z(2), 0*Z(2), 0*Z(2) ], 
        [ 0*Z(2), 0*Z(2), 0*Z(2) ] ] ) ]
  <group of size 4 with 2 generators>
  gap> Size( R ) = Size( G );
  true
  gap> StructureDescription( G );
  "C4"
  
\end{Verbatim}
 In the following example we construct a non-commutative 3-dimensional radical
algebra of order 8 over the field of two elements, and demonstrate that its
adjoint group is the dihedral group of order 8: \pagebreak 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> x:=[ [ 0, 1, 0 ],
  >         [ 0, 0, 0 ],     
  >         [ 0, 0, 0 ] ];;
  gap> y:=[ [ 0, 0, 0 ],     
  >         [ 0, 0, 1 ],  
  >         [ 0, 0, 0 ] ];;
  gap> R := Algebra( GF(2), One(GF(2))*[x,y] );  
  <algebra over GF(2), with 2 generators>
  gap> RadicalOfAlgebra(R) = R;                
  true
  gap> Dimension(R);
  3
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( [ [ 0*Z(2), Z(2)^0, Z(2)^0 ], [ 0*Z(2), 0*Z(2), Z(2)^0 ], 
        [ 0*Z(2), 0*Z(2), 0*Z(2) ] ] ) ]
  <group of size 8 with 2 generators>
  gap> StructureDescription( G );
  "D8"
  
\end{Verbatim}
 If the ring \mbox{\texttt{\slshape R}} is not a radical algebra, then \textsf{Circle} will use another approach. We will enumerate all elements of the ring \mbox{\texttt{\slshape R}} and select those that are units with respect to the circle multiplication.
Then we will use a random approach similar to the case of the radical algebra,
to find some generating set of the adjoint group. Again, all warnings 1-3
above refer also to this case. 

 Of course, enumeration of all elements of \mbox{\texttt{\slshape R}} should be feasible for this computation. In the following example we
demonstrate how it works for rings, generated by residue classes: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R := Ring( [ ZmodnZObj(2,8) ] );
  <ring with 1 generators>
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 2, 8 ) ) ]
  <group of size 4 with 2 generators>
  gap> StructureDescription( G );
  "C2 x C2"
  gap> R := Ring( [ ZmodnZObj(2,256) ] );   
  <ring with 1 generators>
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 234, 256 ) ) ]
  <group of size 128 with 2 generators>
  gap> StructureDescription( G );
  "C64 x C2"
  
\end{Verbatim}
 Due to the \texttt{AdjointSemigroup} (\ref{AdjointSemigroup}), there is also another way to compute the adjoint group of a ring $R$ by means of the computation of its adjoint semigroup $S(R)$ and taking the Green's $H$-class of the multiplicative neutral element of $S(R)$. Let us repeat the last example in this way: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R := Ring( [ ZmodnZObj(2,256) ] );  
  <ring with 1 generators>
  gap> S := AdjointSemigroup( R );
  <monoid with 128 generators>
  gap> H := GreensHClassOfElement(S,One(S));
  {CircleObject( ZmodnZObj( 0, 256 ) )}
  gap> G:=AsGroup(H);
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 0, 256 ) ), CircleObject( ZmodnZObj( 2, 256 ) ), 
    ... 
    CircleObject( ZmodnZObj( 250, 256 ) ), CircleObject( ZmodnZObj( 252, 256 ) )
      , CircleObject( ZmodnZObj( 254, 256 ) ) ]
  <group of size 128 with 2 generators>
  gap> StructureDescription(G);
  "C64 x C2"
  
\end{Verbatim}
 However, the conversion of the Green's $H$-class to the group may take some time which may vary dependently on the
particular ring in question, and will also display a lot of warnings about the
default \texttt{IsGeneratorsOfMagmaWithInverses} method, so we did not implemented this as as standard method. In the following
example the method based on Green's $H$-class is about 50 times slower than an application of earlier described
random approach: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R := Ring( [ ZmodnZObj(2,1024) ] );   
  <ring with 1 generators>
  gap> AdjointGroup(R); time;
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 136, 1024 ) ) ]
  <group of size 512 with 3 generators>
  109
  gap> R := Ring( [ ZmodnZObj(2,1024) ] );
  <ring with 1 generators>
  gap> S:=AdjointSemigroup(R); AsGroup(GreensHClassOfElement(S,One(S))); time;
  <monoid with 512 generators>
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 0, 1024 ) ), CircleObject( ZmodnZObj( 2, 1024 ) ), 
    CircleObject( ZmodnZObj( 4, 1024 ) ), CircleObject( ZmodnZObj( 6, 1024 ) ), 
    ...
    CircleObject( ZmodnZObj( 1018, 1024 ) ), 
    CircleObject( ZmodnZObj( 1020, 1024 ) ), 
    CircleObject( ZmodnZObj( 1022, 1024 ) ) ]
  <group of size 512 with 2 generators>
  5474
  
\end{Verbatim}
 Finally, note that if \mbox{\texttt{\slshape R}} has a unity $1$, then the set $1+R^{ad}$, where $R^{ad}$ is the adjoint semigroup of \mbox{\texttt{\slshape R}}, coincides with the multiplicative semigroup $R^{mult}$ of $R$, and the map $ r \mapsto (1+r) $ for $r$ in $R$ is an isomorphism from $R^{ad}$ onto $R^{mult}$. 

 Similarly, the set $1+R^*$, where $R^{*}$ is the adjoint group of \mbox{\texttt{\slshape R}}, coincides with the unit group of $R$, which we denote $U(R)$, and the map $r \mapsto (1+r)$ for $r$ in $R$ is an isomorphism from $R^*$ onto $U(R)$. 

 We demonstrate this isomorphism using the following example. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> FG := GroupRing( GF(2), DihedralGroup(8) );
  <algebra-with-one over GF(2), with 3 generators>
  gap> R := AugmentationIdeal( FG );
  <two-sided ideal in <algebra-with-one over GF(2), with 3 generators>, 
    (dimension 7)>
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( (Z(2)^0)*f2+(Z(2)^0)*f1*f2 ) ]
  <group of size 128 with 4 generators>
  gap> IdGroup( G );
  [ 128, 170 ]
  gap> IdGroup( Units( FG ) );
  #I  LAGUNA package: Computing the unit group ...
  [ 128, 170 ]
  
\end{Verbatim}
 Thus, dependently on the ring \texttt{R} in question, it might be possible that you can compute much faster its unit
group using \texttt{Units(R)} than its adjoint group using \texttt{AdjointGroup(R)}. This is why in an attempt of computation of the adjoint group of the ring
with one a warning message will be displayed: 

 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> AdjointGroup( GroupRing( GF(2), DihedralGroup(8) ) );
  
  WARNING: usage of AdjointGroup for associative ring <R> with one!!! 
  In this case the adjoint group is isomorphic to the unit group 
  Units(<R>), which possibly may be computed faster!!! 
  
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( (Z(2)^0)*<identity> of ...+(Z(2)^0)*f1+(Z(2)^0)*f1*f2+(Z(2)^
      0)*f1*f3 ) ]
  <group of size 128 with 4 generators>
  gap> AdjointGroup( Integers mod 11 );                  
  
  WARNING: usage of AdjointGroup for associative ring <R> with one!!! 
  In this case the adjoint group is isomorphic to the unit group 
  Units(<R>), which possibly may be computed faster!!! 
  
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( Z(11)^0 ) ]
  <group of size 10 with 1 generators>
  
\end{Verbatim}
 If \mbox{\texttt{\slshape R}} is infinite, an error message will appear, telling that \textsf{Circle} does not provide methods to deal with infinite rings. }

 }

  
\section{\textcolor{Chapter }{Service functions}}\label{Service}
\logpage{[ 3, 4, 0 ]}
\hyperdef{L}{X80DFB24F8289C323}{}
{
  

\subsection{\textcolor{Chapter }{InfoCircle}}
\logpage{[ 3, 4, 1 ]}\nobreak
\hyperdef{L}{X7A24C0997AC7C6A3}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{InfoCircle\index{InfoCircle@\texttt{InfoCircle}}
\label{InfoCircle}
}\hfill{\scriptsize (info class)}}\\


 \texttt{InfoCircle} is a special Info class for \textsf{Circle} algorithms. It has 2 levels: 0 (default) and 1. To change info level to \texttt{k}, use command \texttt{SetInfoLevel(InfoCircle, k)}. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> SetInfoLevel( InfoCircle, 1 );
  gap> SetInfoLevel(InfoCircle,1);
  gap> R := Ring( [ ZmodnZObj(2,8) ]);
  <ring with 1 generators>
  gap> G := AdjointGroup( R );
  #I  Circle : <R> is not a radical algebra, computing circle units ...
  #I  Circle : searching generators for adjoint group ...
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( ZmodnZObj( 6, 8 ) ) ]
  <group of size 4 with 2 generators>
  gap> SetInfoLevel( InfoCircle, 0 );
  
\end{Verbatim}
 }

 

\subsection{\textcolor{Chapter }{CIRCLEBuildManual}}
\logpage{[ 3, 4, 2 ]}\nobreak
\hyperdef{L}{X7D74CBE0787AC1B1}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{CIRCLEBuildManual({\slshape })\index{CIRCLEBuildManual@\texttt{CIRCLEBuildManual}}
\label{CIRCLEBuildManual}
}\hfill{\scriptsize (function)}}\\


 This function is used to build the manual in the following formats: DVI, PDF,
PS, HTML and text for online help. We recommend that the user should have a
recent and fairly complete {\TeX} distribution. Since \textsf{Circle} is distributed together with its manual, it is not necessary for the user to
use this function. Normally it is intended to be used by the developers only.
This is the only function of \textsf{Circle} which requires UNIX/Linux environment. }

 

\subsection{\textcolor{Chapter }{CIRCLEBuildManualHTML}}
\logpage{[ 3, 4, 3 ]}\nobreak
\hyperdef{L}{X7B286B3985877CCE}{}
{\noindent\textcolor{FuncColor}{$\Diamond$\ \texttt{CIRCLEBuildManualHTML({\slshape })\index{CIRCLEBuildManualHTML@\texttt{CIRCLEBuildManualHTML}}
\label{CIRCLEBuildManualHTML}
}\hfill{\scriptsize (function)}}\\


 This fuction is used to build the manual only in HTML format. This does not
depend on the availability of the {\TeX} installation and works under Windows and MacOS as well. Since \textsf{Circle} is distributed together with its manual, it is not necessary for the user to
use this function. Normally it is intended to be used by the developers only. }

 }

 }

  
\chapter{\textcolor{Chapter }{A sample computation with \textsf{Circle}}}\label{Example}
\logpage{[ 4, 0, 0 ]}
\hyperdef{L}{X803553D8849F6D7A}{}
{
  Here we give an example to give the reader an idea what \textsf{Circle} is able to compute. 

 It was proved in \cite{Kazarin-Soules-2004} that if $R$ is a finite nilpotent two-generated algebra over a field of characteristic $p>3$ whose adjoint group has at most three generators, then the dimension of $R$ is not greater than 9. Also, an example of the 6-dimensional such algebra with
the 3-generated adjoint group was given there. We will construct the algebra
from this example and investigate it using \textsf{Circle}. First we create two matrices that determine its generators: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
                                                                                            
  gap> x:=[ [ 0, 1, 0, 0, 0, 0, 0 ],
  >         [ 0, 0, 0, 1, 0, 0, 0 ],
  >         [ 0, 0, 0, 0, 1, 0, 0 ],
  >         [ 0, 0, 0, 0, 0, 0, 1 ],
  >         [ 0, 0, 0, 0, 0, 1, 0 ],
  >         [ 0, 0, 0, 0, 0, 0, 0 ],
  >         [ 0, 0, 0, 0, 0, 0, 0 ] ];;
  gap> y:=[ [ 0, 0, 1, 0, 0, 0, 0 ],
  >         [ 0, 0, 0, 0,-1, 0, 0 ],
  >         [ 0, 0, 0, 1, 0, 1, 0 ],
  >         [ 0, 0, 0, 0, 0, 1, 0 ],
  >         [ 0, 0, 0, 0, 0, 0,-1 ],
  >         [ 0, 0, 0, 0, 0, 0, 0 ],
  >         [ 0, 0, 0, 0, 0, 0, 0 ] ];;
                                                                                                  
\end{Verbatim}
 Now we construct this algebra in characteristic five and check its basic
properties: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
                                                                                            
  gap> R := Algebra( GF(5), One(GF(5))*[x,y] );
  <algebra over GF(5), with 2 generators>
  gap> Dimension( R );
  6
  gap> Size( R );
  15625
  gap> RadicalOfAlgebra( R ) = R;
  true
                                                                                                  
\end{Verbatim}
 Then we compute the adjoint group of \texttt{R}. During the computation a warning will be displayed. It is caused by the
method for \texttt{IsGeneratorsOfMagmaWithInverses} defined in the file \texttt{gap4r4/lib/grp.gi} from the \textsf{GAP} library, and may be safely ignored. 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
   
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( [ [ 0*Z(5), Z(5), Z(5), Z(5)^3, Z(5), 0*Z(5), Z(5)^2 ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), Z(5), Z(5)^3, Z(5)^3, Z(5)^3 ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), Z(5), Z(5), 0*Z(5), Z(5) ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), Z(5), Z(5) ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), Z(5), Z(5)^3 ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5) ],
        [ 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5), 0*Z(5) ] ] ) ]
  <group of size 15625 with 3 generators>
                                                                                                  
\end{Verbatim}
 Now we can find the generating set of minimal possible order for the group \texttt{G}, and check that \texttt{G} it is 3-generated. To do this, first we need to convert it to the isomorphic
PcGroup: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
   
  gap> f := IsomorphismPcGroup( G );;
  gap> H := Image( f );
  Group([ f1, f2, f3, f4, f5, f6 ])
  gap> gens := MinimalGeneratingSet( H );
  [ f1, f2, f5 ]
  gap> gens:=List( gens, x -> UnderlyingRingElement(PreImage(f,x)));;
  gap> Perform(gens,Display);                                        
   . 3 3 4 4 . 1
   . . . 3 2 1 4
   . . . 3 3 2 4
   . . . . . 3 3
   . . . . . 3 2
   . . . . . . .
   . . . . . . .
   . 3 1 1 . . .
   . . . 3 4 . 1
   . . . 1 3 2 .
   . . . . . 1 3
   . . . . . 3 4
   . . . . . . .
   . . . . . . .
   . 2 2 3 2 . 4
   . . . 2 3 3 3
   . . . 2 2 . 2
   . . . . . 2 2
   . . . . . 2 3
   . . . . . . .
   . . . . . . .
                                                                                                  
\end{Verbatim}
 It appears that the adjoint group of the algebra from example will be
3-generated in characteristic three as well: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R := Algebra( GF(3), One(GF(3))*[x,y] );
  <algebra over GF(3), with 2 generators>
  gap> G := AdjointGroup( R );
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( [ [ 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3), Z(3), 0*Z(3) ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3), Z(3)^0, Z(3)^0 ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3) ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3) ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
        [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ] ] ) ]
  <group of size 729 with 3 generators>
  gap> H := Image( IsomorphismPcGroup( G ) );
  Group([ f1, f2, f3, f4, f5, f6 ])
  gap> MinimalGeneratingSet( H );
  [ f1, f2, f4 ]
                                                                                                  
\end{Verbatim}
 But this is not the case in characteristic two, where the adjoint group is
4-generated: 
\begin{Verbatim}[fontsize=\small,frame=single,label=Example]
  
  gap> R := Algebra( GF(2), One(GF(2))*[x,y] );
  <algebra over GF(2), with 2 generators>
  gap> G := AdjointGroup( R );                   
  #I  default `IsGeneratorsOfMagmaWithInverses' method returns `true' for 
  [ CircleObject( [ [ 0*Z(2), Z(2)^0, Z(2)^0, 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0, Z(2)^0, 0*Z(2) ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0 ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0 ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0 ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
        [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ] ) ]
  <group of size 64 with 4 generators>
  gap> H := Image( IsomorphismPcGroup( G ) );
  Group([ f1, f2, f3, f4, f5, f6 ])
  gap> MinimalGeneratingSet( H );
  [ f1, f2, f4, f5 ]
                                                                                                  
\end{Verbatim}
 }

 \def\bibname{References\logpage{[ "Bib", 0, 0 ]}
\hyperdef{L}{X7A6F98FD85F02BFE}{}
}

\bibliographystyle{alpha}
\bibliography{manual}

\def\indexname{Index\logpage{[ "Ind", 0, 0 ]}
\hyperdef{L}{X83A0356F839C696F}{}
}


\printindex

\newpage
\immediate\write\pagenrlog{["End"], \arabic{page}];}
\immediate\closeout\pagenrlog
\end{document}
