diff --git a/dev/basics/index.html b/dev/basics/index.html index 53eaf7b52..33a66e795 100644 --- a/dev/basics/index.html +++ b/dev/basics/index.html @@ -21,7 +21,7 @@ julia> GAP.Globals.Julia # Julia objects can be values of GAP variables Main -source
GAP.evalstrFunction
evalstr(cmd::String)

Let GAP execute the command(s) given by cmd; if an error occurs then report this error, otherwise if the last command has a result then return it, otherwise return nothing.

Examples

julia> GAP.evalstr( "1+2" )
+
source
GAP.evalstrFunction
evalstr(cmd::String)

Let GAP execute the command(s) given by cmd; if an error occurs then report this error, otherwise if the last command has a result then return it, otherwise return nothing.

Examples

julia> GAP.evalstr( "1+2" )
 3
 
 julia> GAP.evalstr( "x:= []" )
@@ -32,7 +32,7 @@
 julia> GAP.evalstr( "x" )
 GAP: [ 2 ]
 
-julia> GAP.evalstr( "Print( x )" )

Note that screen outputs caused by evaluating cmd are not shown by evalstr; use evalstr_ex for accessing both the outputs and the return values of the command(s).

In general we recommend to avoid using evalstr, but it sometimes can be a useful escape hatch to access GAP functionality that is otherwise impossible to difficult to reach. But in most typical scenarios it should not be necessary to use it at all.

Instead, use GAP.GapObj or GAP.Obj for constructing GAP objects that correspond to given Julia objects, and call GAP functions directly in the Julia session. For example, executing GAP.evalstr( "x:= []; Add( x, 2 )" ) can be replaced by the Julia code x = GAP.GapObj([]); GAP.Globals.Add(x, 2). Note that the variable x in the former example lives in the GAP session, i.e., it can be accessed as GAP.Globals.x after the call of GAP.evalstr, whereas x in the latter example lives in the Julia session.

source
GAP.evalstr_exFunction
evalstr_ex(cmd::String)

Assume that cmd consists of $n$ GAP statements, each terminated by ; or ;;. Let GAP execute these statements and return a GAP list of length $n$ that describes their results. Each entry of the return value is a GAP list of length 5, with the following meaning.

  • The first entry is true if the statement was executed successfully, and false otherwise.
  • If the first entry is true, then the second entry is bound to the result of the statement if there was one, and unbound otherwise.
  • The third entry is unbound if an error occured, true if the statement ends in a double semicolon, and false otherwise.
  • The fourth entry currently is always unbound.
  • The fifth entry contains the captured output of the statement as a string. If there was no double semicolon then also the output of GAP.Globals.ViewObj applied to the result value in the second entry, if any, is part of that string.

Examples

julia> GAP.evalstr_ex( "1+2" )        # error due to missing semicolon
+julia> GAP.evalstr( "Print( x )" )

Note that screen outputs caused by evaluating cmd are not shown by evalstr; use evalstr_ex for accessing both the outputs and the return values of the command(s).

In general we recommend to avoid using evalstr, but it sometimes can be a useful escape hatch to access GAP functionality that is otherwise impossible to difficult to reach. But in most typical scenarios it should not be necessary to use it at all.

Instead, use GAP.GapObj or GAP.Obj for constructing GAP objects that correspond to given Julia objects, and call GAP functions directly in the Julia session. For example, executing GAP.evalstr( "x:= []; Add( x, 2 )" ) can be replaced by the Julia code x = GAP.GapObj([]); GAP.Globals.Add(x, 2). Note that the variable x in the former example lives in the GAP session, i.e., it can be accessed as GAP.Globals.x after the call of GAP.evalstr, whereas x in the latter example lives in the Julia session.

source
GAP.evalstr_exFunction
evalstr_ex(cmd::String)

Assume that cmd consists of $n$ GAP statements, each terminated by ; or ;;. Let GAP execute these statements and return a GAP list of length $n$ that describes their results. Each entry of the return value is a GAP list of length 5, with the following meaning.

  • The first entry is true if the statement was executed successfully, and false otherwise.
  • If the first entry is true, then the second entry is bound to the result of the statement if there was one, and unbound otherwise.
  • The third entry is unbound if an error occured, true if the statement ends in a double semicolon, and false otherwise.
  • The fourth entry currently is always unbound.
  • The fifth entry contains the captured output of the statement as a string. If there was no double semicolon then also the output of GAP.Globals.ViewObj applied to the result value in the second entry, if any, is part of that string.

Examples

julia> GAP.evalstr_ex( "1+2" )        # error due to missing semicolon
 GAP: [ [ false,,,, "" ] ]
 
 julia> GAP.evalstr_ex( "1+2;" )       # one statement with return value
@@ -51,11 +51,11 @@
 GAP: [ [ true,, false,, "1" ] ]
 
 julia> GAP.evalstr_ex( "" )           # empty input
-GAP: [  ]
source
GAP.promptFunction
prompt()

Start a GAP prompt where you can enter GAP commands as in a regular GAP session. This prompt can be left as any GAP prompt by either entering quit; or pressing ctrl-D, which returns to the Julia prompt.

This GAP prompt allows to quickly switch between writing Julia and GAP code in a session where all data is shared.

source
GAP.create_gap_shFunction
create_gap_sh(dstdir::String)

Given a directory path, create three files in that directory:

  • a shell script named gap.sh which acts like the gap.sh shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia.
  • two TOML files, Manifest.toml and Project.toml, which are required by gap.sh to function (they record the precise versions of GAP.jl and other Julia packages involved)
source

Accessing Julia from GAP

The GAP-Julia interface is fully bidirectional, so it is also possible to access all Julia functionality from GAP. To learn more about this, please consult the manual of the GAP package JuliaInterface.

Types

GAP.FFEType
FFE

Wrap a pointer to a GAP FFE ("finite field element") immediate object. This type is defined in the JuliaInterface C code.

Examples

julia> x = GAP.Globals.Z(3)
+GAP: [  ]
source
GAP.promptFunction
prompt()

Start a GAP prompt where you can enter GAP commands as in a regular GAP session. This prompt can be left as any GAP prompt by either entering quit; or pressing ctrl-D, which returns to the Julia prompt.

This GAP prompt allows to quickly switch between writing Julia and GAP code in a session where all data is shared.

source
GAP.create_gap_shFunction
create_gap_sh(dstdir::String)

Given a directory path, create three files in that directory:

  • a shell script named gap.sh which acts like the gap.sh shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia.
  • two TOML files, Manifest.toml and Project.toml, which are required by gap.sh to function (they record the precise versions of GAP.jl and other Julia packages involved)
source

Accessing Julia from GAP

The GAP-Julia interface is fully bidirectional, so it is also possible to access all Julia functionality from GAP. To learn more about this, please consult the manual of the GAP package JuliaInterface.

Types

GAP.FFEType
FFE

Wrap a pointer to a GAP FFE ("finite field element") immediate object. This type is defined in the JuliaInterface C code.

Examples

julia> x = GAP.Globals.Z(3)
 GAP: Z(3)
 
 julia> typeof(x)
-FFE
source
GAP.GapObjType
GapObj

This is the Julia type of all those GAP objects that are not "immediate" (booleans, small integers, FFEs).

Examples

julia> typeof(GapObj([1, 2]))          # a GAP list
+FFE
source
GAP.GapObjType
GapObj

This is the Julia type of all those GAP objects that are not "immediate" (booleans, small integers, FFEs).

Examples

julia> typeof(GapObj([1, 2]))          # a GAP list
 GapObj
 
 julia> typeof(GapObj(Dict(:a => 1)))   # a GAP record
@@ -94,7 +94,7 @@
 GAP: [ [ 1, 2 ], [ 3, 4 ] ]
 
 julia> GapObj(42)
-ERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64
source
GAP.ObjType
GAP.Obj

This is an alias for Union{GapObj,FFE,Int64,Bool}. This type union covers all types a "native" GAP object may have from Julia's viewpoint.

Moreover, it can be used as a constructor, in order to convert Julia objects to GAP objects, whenever a suitable conversion has been defined.

Recursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.

Examples

julia> GAP.Obj(1//3)
+ERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64
source
GAP.ObjType
GAP.Obj

This is an alias for Union{GapObj,FFE,Int64,Bool}. This type union covers all types a "native" GAP object may have from Julia's viewpoint.

Moreover, it can be used as a constructor, in order to convert Julia objects to GAP objects, whenever a suitable conversion has been defined.

Recursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.

Examples

julia> GAP.Obj(1//3)
 GAP: 1/3
 
 julia> GAP.Obj([1 2; 3 4])
@@ -110,4 +110,4 @@
 GAP: [ [ 1, 2 ], [ 3, 4 ] ]
 
 julia> GAP.Obj(42)
-42
source
GAP.GapIntType
GapInt

Any GAP integer object is represented in Julia as either a GapObj (if it is a "large" integer) or as an Int (if it is a "small" integer). This type union can be used to express this conveniently, e.g. when one wants to help type stability.

Note that also GAP's infinity and -infinity fit under this type (as do many other objects which are not numbers).

source
+42source
GAP.GapIntType
GapInt

Any GAP integer object is represented in Julia as either a GapObj (if it is a "large" integer) or as an Int (if it is a "small" integer). This type union can be used to express this conveniently, e.g. when one wants to help type stability.

Note that also GAP's infinity and -infinity fit under this type (as do many other objects which are not numbers).

source
diff --git a/dev/conversion/index.html b/dev/conversion/index.html index bdd2632d2..f092d36d5 100644 --- a/dev/conversion/index.html +++ b/dev/conversion/index.html @@ -26,7 +26,7 @@ julia> GAP.gap_to_julia( Matrix{Int}, val ) 2×2 Matrix{Int64}: 1 2 - 3 4

The following gap_to_julia conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more GAP objects.)

GAP filterdefault Julia typeother Julia types
IsIntBigInt`T <: Integer
IsFFEGapFFE
IsBoolBool
IsRatRational{BigInt}`Rational{T}
IsFloatFloat64`T <: AbstractFloat
IsCharCucharChar
IsStringRepStringSymbol, Vector{T}
IsRangeRepStepRange{Int64,Int64}Vector{T}
IsBListRepBitVectorVector{T}
IsListVector{Any}Vector{T}
IsVectorObjVector{Any}Vector{T}
IsMatrixObjMatrix{Any}Matrix{T}
IsRecordDict{Symbol, Any}Dict{Symbol, T}
source
GAP.julia_to_gapFunction
julia_to_gap(input, recursion_dict = IdDict(); recursive::Bool = false)

Convert a julia object input to an appropriate GAP object. If recursive is set to true, recursive conversions on arrays, tuples, and dictionaries is performed.

The input recursion_dict should never be set by the user, it is meant to keep egality of input data, by converting equal data to identical objects in GAP.

Examples

julia> GAP.julia_to_gap(1//3)
+ 3  4

The following gap_to_julia conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more GAP objects.)

GAP filterdefault Julia typeother Julia types
IsIntBigInt`T <: Integer
IsFFEGapFFE
IsBoolBool
IsRatRational{BigInt}`Rational{T}
IsFloatFloat64`T <: AbstractFloat
IsCharCucharChar
IsStringRepStringSymbol, Vector{T}
IsRangeRepStepRange{Int64,Int64}Vector{T}
IsBListRepBitVectorVector{T}
IsListVector{Any}Vector{T}
IsVectorObjVector{Any}Vector{T}
IsMatrixObjMatrix{Any}Matrix{T}
IsRecordDict{Symbol, Any}Dict{Symbol, T}
source
GAP.julia_to_gapFunction
julia_to_gap(input, recursion_dict = IdDict(); recursive::Bool = false)

Convert a julia object input to an appropriate GAP object. If recursive is set to true, recursive conversions on arrays, tuples, and dictionaries is performed.

The input recursion_dict should never be set by the user, it is meant to keep egality of input data, by converting equal data to identical objects in GAP.

Examples

julia> GAP.julia_to_gap(1//3)
 GAP: 1/3
 
 julia> GAP.julia_to_gap("abc")
@@ -37,14 +37,14 @@
 
 julia> GAP.julia_to_gap([ [1, 2], [3, 4]], recursive = true)
 GAP: [ [ 1, 2 ], [ 3, 4 ] ]
-

The following julia_to_gap conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more Julia objects.)

Julia typeGAP filter
Int8, Int16, ..., BigIntIsInt
GapFFEIsFFE
BoolIsBool
Rational{T}IsRat
Float16, Float32, Float64IsFloat
AbstractStringIsString
SymbolIsString
CharIsChar
Vector{T}IsList
Vector{Bool}, BitVectorIsBList
Tuple{T}IsList
Matrix{T}IsList
Dict{String, T}, Dict{Symbol, T}IsRecord
UnitRange{T}, StepRange{T, S}IsRange
FunctionIsFunction
source

Constructor Methods for GAP-to-Julia Conversions

(For Julia-to-GAP conversions, one can use GapObj and GAP.Obj as constructors.)

Core.Int128Type
Int128(obj::GapObj)

Return the Int128 converted from the GAP integer obj. (Note that small GAP integers are represented by Julia Int64 objects, in particular they are not GapObjs; their conversion is not handled by methods installed in GAP.jl.)

Examples

julia> val = GAP.Globals.Factorial(25)
+

The following julia_to_gap conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more Julia objects.)

Julia typeGAP filter
Int8, Int16, ..., BigIntIsInt
GapFFEIsFFE
BoolIsBool
Rational{T}IsRat
Float16, Float32, Float64IsFloat
AbstractStringIsString
SymbolIsString
CharIsChar
Vector{T}IsList
Vector{Bool}, BitVectorIsBList
Tuple{T}IsList
Matrix{T}IsList
Dict{String, T}, Dict{Symbol, T}IsRecord
UnitRange{T}, StepRange{T, S}IsRange
FunctionIsFunction
source

Constructor Methods for GAP-to-Julia Conversions

(For Julia-to-GAP conversions, one can use GapObj and GAP.Obj as constructors.)

Core.Int128Type
Int128(obj::GapObj)

Return the Int128 converted from the GAP integer obj. (Note that small GAP integers are represented by Julia Int64 objects, in particular they are not GapObjs; their conversion is not handled by methods installed in GAP.jl.)

Examples

julia> val = GAP.Globals.Factorial(25)
 GAP: 15511210043330985984000000
 
 julia> Int128(val)
 15511210043330985984000000
 
 julia> Int(val)
-ERROR: InexactError: Int64(15511210043330985984000000)
source
Base.GMP.BigIntType
BigInt(obj::GapObj)

Return the big integer converted from the GAP integer obj. (Note that small GAP integers are not represented by GapObjs, their conversion with BigInt is handled by Julia's methods.)

Examples

julia> val = GAP.Globals.Factorial(25)
+ERROR: InexactError: Int64(15511210043330985984000000)
source
Base.GMP.BigIntType
BigInt(obj::GapObj)

Return the big integer converted from the GAP integer obj. (Note that small GAP integers are not represented by GapObjs, their conversion with BigInt is handled by Julia's methods.)

Examples

julia> val = GAP.Globals.Factorial(25)
 GAP: 15511210043330985984000000
 
 julia> BigInt(val)
@@ -58,7 +58,7 @@
 
 julia> BigInt(val)
 3628800
-
source
Base.RationalType
Rational{T}(obj::GapObj) where {T<:Integer}

Return the rational converted from the GAP integer or the GAP rational obj,

Examples

julia> val = GAP.Globals.Factorial(25)
+
source
Base.RationalType
Rational{T}(obj::GapObj) where {T<:Integer}

Return the rational converted from the GAP integer or the GAP rational obj,

Examples

julia> val = GAP.Globals.Factorial(25)
 GAP: 15511210043330985984000000
 
 julia> Rational{Int128}(val)
@@ -72,7 +72,7 @@
 
 julia> Rational{Int64}(val)
 1//3
-
source
Core.Float64Type
Float64(obj::GapObj)

Return the float converted from the GAP float obj.

Examples

julia> val = GAP.Obj(2.2)
+
source
Core.Float64Type
Float64(obj::GapObj)

Return the float converted from the GAP float obj.

Examples

julia> val = GAP.Obj(2.2)
 GAP: 2.2
 
 julia> Float64(val)
@@ -80,17 +80,17 @@
 
 julia> Float32(val)
 2.2f0
-
source
Core.CharType
Char(obj::GapObj)

Return the character converted from the GAP character obj.

Examples

julia> val = GAP.Obj('x')
+
source
Core.CharType
Char(obj::GapObj)

Return the character converted from the GAP character obj.

Examples

julia> val = GAP.Obj('x')
 GAP: 'x'
 
 julia> Char(val)
 'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)
-
source
Base.CucharType
Cuchar(obj::GapObj)

Return the UInt8 that belongs to the GAP character obj.

Examples

julia> val = GAP.Obj('x')
+
source
Base.CucharType
Cuchar(obj::GapObj)

Return the UInt8 that belongs to the GAP character obj.

Examples

julia> val = GAP.Obj('x')
 GAP: 'x'
 
 julia> Cuchar(val)
 0x78
-
source
Core.StringType
String(obj::GapObj)

Return the Julia string converted from the GAP string obj. Note that GAP's String function can be applied to arbitrary GAP objects, similar to Julia's string function; this behaviour is not intended for this String constructor.

Examples

julia> val = GAP.Obj("abc")
+
source
Core.StringType
String(obj::GapObj)

Return the Julia string converted from the GAP string obj. Note that GAP's String function can be applied to arbitrary GAP objects, similar to Julia's string function; this behaviour is not intended for this String constructor.

Examples

julia> val = GAP.Obj("abc")
 GAP: "abc"
 
 julia> String(val)
@@ -101,12 +101,12 @@
 
 julia> String(val)   # an empty GAP list is a string
 ""
-
source
Core.SymbolType
Symbol(obj::GapObj)

Return the symbol converted from the GAP string obj.

Examples

julia> str = GAP.Obj("abc")
+
source
Core.SymbolType
Symbol(obj::GapObj)

Return the symbol converted from the GAP string obj.

Examples

julia> str = GAP.Obj("abc")
 GAP: "abc"
 
 julia> Symbol(str)
 :abc
-
source
Base.UnitRangeType
UnitRange(obj::GapObj)

Return the unit range converted from the GAP range obj, which has step width 1.

Examples

julia> val = GAP.Obj(1:10)
+
source
Base.UnitRangeType
UnitRange(obj::GapObj)

Return the unit range converted from the GAP range obj, which has step width 1.

Examples

julia> val = GAP.Obj(1:10)
 GAP: [ 1 .. 10 ]
 
 julia> UnitRange(val)
@@ -114,7 +114,7 @@
 
 julia> UnitRange{Int32}(val)
 1:10
-
source
Base.StepRangeType
StepRange(obj::GapObj)

Return the step range converted from the GAP range obj, which may have arbitrary step width.

Examples

julia> val = GAP.Obj(1:2:11)
+
source
Base.StepRangeType
StepRange(obj::GapObj)

Return the step range converted from the GAP range obj, which may have arbitrary step width.

Examples

julia> val = GAP.Obj(1:2:11)
 GAP: [ 1, 3 .. 11 ]
 
 julia> StepRange(val)
@@ -125,7 +125,7 @@
 
 julia> typeof(r)
 StepRange{Int8, Int8}
-
source
Core.TupleType
Tuple{Types...}(obj::GapObj; recursive::Bool = true)

Return the tuple converted from the GAP list obj. The entries of the list are converted to the required types Types..., using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.

Examples

julia> val = GAP.Obj([1, 5])
+
source
Core.TupleType
Tuple{Types...}(obj::GapObj; recursive::Bool = true)

Return the tuple converted from the GAP list obj. The entries of the list are converted to the required types Types..., using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.

Examples

julia> val = GAP.Obj([1, 5])
 GAP: [ 1, 5 ]
 
 julia> Tuple{Int64,Int64}(val)
@@ -139,7 +139,7 @@
 
 julia> Tuple{GapObj,GapObj}(val; recursive=false)
 (GAP: [ 1 ], GAP: [ 2 ])
-
source
Base.BitVectorType
BitVector(obj::GapObj)

Return the bit vector converted from the GAP list of booleans obj.

Examples

julia> val = GAP.Obj([true, false, true])
+
source
Base.BitVectorType
BitVector(obj::GapObj)

Return the bit vector converted from the GAP list of booleans obj.

Examples

julia> val = GAP.Obj([true, false, true])
 GAP: [ true, false, true ]
 
 julia> BitVector(val)
@@ -147,7 +147,7 @@
  1
  0
  1
-
source
Base.VectorType
Vector{T}(obj::GapObj; recursive::Bool = true)

Return the 1-dimensional array converted from the GAP list obj. The entries of the list are converted to the type T, using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.

If T is UInt8 then obj may be a GAP string.

Examples

julia> val = GAP.Obj([[1], [2]]; recursive=true)
+
source
Base.VectorType
Vector{T}(obj::GapObj; recursive::Bool = true)

Return the 1-dimensional array converted from the GAP list obj. The entries of the list are converted to the type T, using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.

If T is UInt8 then obj may be a GAP string.

Examples

julia> val = GAP.Obj([[1], [2]]; recursive=true)
 GAP: [ [ 1 ], [ 2 ] ]
 
 julia> Vector{Any}(val)
@@ -182,7 +182,7 @@
  0x61
  0x62
  0x63
-
source
Base.MatrixType
Matrix{T}(obj::GapObj; recursive::Bool = true)

Return the 2-dimensional array converted from the GAP matrix obj, which can be a GAP list of lists or a GAP matrix object. The entries of the matrix are converted to the type T, using gap_to_julia. If recursive is true then the entries are converted recursively, otherwise non-recursively.

Examples

julia> val = GAP.Obj([[1, 2], [3, 4]]; recursive=true)
+
source
Base.MatrixType
Matrix{T}(obj::GapObj; recursive::Bool = true)

Return the 2-dimensional array converted from the GAP matrix obj, which can be a GAP list of lists or a GAP matrix object. The entries of the matrix are converted to the type T, using gap_to_julia. If recursive is true then the entries are converted recursively, otherwise non-recursively.

Examples

julia> val = GAP.Obj([[1, 2], [3, 4]]; recursive=true)
 GAP: [ [ 1, 2 ], [ 3, 4 ] ]
 
 julia> Matrix{Int64}(val)
@@ -197,7 +197,7 @@
 2×2 Matrix{Int64}:
  0  1
  2  3
-
source
Base.SetType
Set{T}(obj::GapObj; recursive::Bool = true)

Return the set converted from the GAP list or GAP collection obj. The elements of obj are converted to the required type T, using gap_to_julia. If recursive is true then the elements are converted recursively, otherwise non-recursively.

This constructor method is intended for situations where the result involves only native Julia objects such as integers and strings. Dealing with results containing GAP objects will be inefficient.

Examples

julia> Set{Int}(GAP.Obj([1, 2, 1]))
+
source
Base.SetType
Set{T}(obj::GapObj; recursive::Bool = true)

Return the set converted from the GAP list or GAP collection obj. The elements of obj are converted to the required type T, using gap_to_julia. If recursive is true then the elements are converted recursively, otherwise non-recursively.

This constructor method is intended for situations where the result involves only native Julia objects such as integers and strings. Dealing with results containing GAP objects will be inefficient.

Examples

julia> Set{Int}(GAP.Obj([1, 2, 1]))
 Set{Int64} with 2 elements:
   2
   1
@@ -224,7 +224,7 @@
 
 julia> s == Set{Any}([GAP.evalstr("()"), GAP.evalstr("(1,2)")])
 true
-
source
Base.DictType
Dict{Symbol,T}(obj::GapObj; recursive::Bool = true)

Return the dictionary converted from the GAP record obj. If recursive is true then the values of the record components are recursively converted to objects of the type T, using gap_to_julia, otherwise they are kept as they are.

Examples

julia> val = GAP.Obj(Dict(:a => 1, :b => 2))
+
source
Base.DictType
Dict{Symbol,T}(obj::GapObj; recursive::Bool = true)

Return the dictionary converted from the GAP record obj. If recursive is true then the values of the record components are recursively converted to objects of the type T, using gap_to_julia, otherwise they are kept as they are.

Examples

julia> val = GAP.Obj(Dict(:a => 1, :b => 2))
 GAP: rec( a := 1, b := 2 )
 
 julia> Dict{Symbol,Int}(val)
@@ -246,4 +246,4 @@
 julia> Dict{Symbol,Vector{Int}}(val; recursive=true)
 Dict{Symbol, Vector{Int64}} with 1 entry:
   :l => [1, 2]
-
source
+source diff --git a/dev/examples/index.html b/dev/examples/index.html index 3e314e9fb..efb4353e7 100644 --- a/dev/examples/index.html +++ b/dev/examples/index.html @@ -145,4 +145,4 @@ julia> length(pre3) 116

... and we verify that the decomposition is correct:

julia> GAP.Globals.Image(fhom, pre3) == r
-true

This concludes our example.

+true

This concludes our example.

diff --git a/dev/index.html b/dev/index.html index a3ae0b139..2173b09be 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -GAP.jl · GAP.jl

GAP.jl

Introduction

GAP.jl is a low level interface from Julia to the computer algebra system GAP. The term "low level" means that the aim is to give Julia access to all GAP objects, to let Julia call GAP functions, and to provide conversions of low level data (integers, Booleans, strings, arrays/lists, dictionaries/records) between the two systems.

In particular, it is not the aim of GAP.jl to provide Julia types for higher level GAP objects that represent algebraic structures, such as groups, rings, fields, etc., and mappings between such structures.

The connection between GAP and Julia is in fact bidirectional, that is, GAP can access all Julia objects, call Julia functions, and perform conversions of low level data. This direction will become interesting on the Julia side as soon as GAP packages provide functionality that is based on using Julia code from the GAP side.

The viewpoint of an interface from GAP to Julia is described in the manual of the GAP package JuliaInterface.

Table of contents

+GAP.jl · GAP.jl

GAP.jl

Introduction

GAP.jl is a low level interface from Julia to the computer algebra system GAP. The term "low level" means that the aim is to give Julia access to all GAP objects, to let Julia call GAP functions, and to provide conversions of low level data (integers, Booleans, strings, arrays/lists, dictionaries/records) between the two systems.

In particular, it is not the aim of GAP.jl to provide Julia types for higher level GAP objects that represent algebraic structures, such as groups, rings, fields, etc., and mappings between such structures.

The connection between GAP and Julia is in fact bidirectional, that is, GAP can access all Julia objects, call Julia functions, and perform conversions of low level data. This direction will become interesting on the Julia side as soon as GAP packages provide functionality that is based on using Julia code from the GAP side.

The viewpoint of an interface from GAP to Julia is described in the manual of the GAP package JuliaInterface.

Table of contents

diff --git a/dev/manualindex/index.html b/dev/manualindex/index.html index 2dd021392..5794fec72 100644 --- a/dev/manualindex/index.html +++ b/dev/manualindex/index.html @@ -1,2 +1,2 @@ -Index · GAP.jl

Index

+Index · GAP.jl

Index

diff --git a/dev/other/index.html b/dev/other/index.html index d9bf09bb2..3d0733b89 100644 --- a/dev/other/index.html +++ b/dev/other/index.html @@ -26,7 +26,7 @@ julia> @gap "(1,2)(3,4)" GAP: (1,2)(3,4) -source
GAP.@g_strMacro
@g_str

Create a GAP string by typing g"content".

Examples

julia> g"foo"
+
source
GAP.@g_strMacro
@g_str

Create a GAP string by typing g"content".

Examples

julia> g"foo"
 GAP: "foo"
 
 julia> g"ab\ncd\"ef\\gh"   # special characters are handled as in GAP
@@ -36,14 +36,14 @@
 [...]
 

Conversely, there are valid arguments for the macro that are not valid Julia strings.

julia> g"\c"
 GAP: "\c"
-
source
GAP.@gapwrapMacro
@gapwrap

When applied to a method definition that involves access to entries of GAP.Globals, this macro rewrites the code such that the relevant GAP globals are cached, and need not be fetched again and again.

Examples

julia> @gapwrap isevenint(x) = GAP.Globals.IsEvenInt(x)::Bool;
+
source
GAP.@gapwrapMacro
@gapwrap

When applied to a method definition that involves access to entries of GAP.Globals, this macro rewrites the code such that the relevant GAP globals are cached, and need not be fetched again and again.

Examples

julia> @gapwrap isevenint(x) = GAP.Globals.IsEvenInt(x)::Bool;
 
 julia> isevenint(1)
 false
 
 julia> isevenint(2)
 true
-
source
GAP.@gapattributeMacro
@gapattribute

This macro is intended to be applied to a method definition for a unary function called attr, say, where the argument has the type T, say, the code contains exactly one call of the form GAP.Globals.Something(X), where Something is a GAP attribute such as Centre or IsSolvableGroup, and attr returns the corresponding attribute value for its argument.

The macro defines three functions attr, has_attr, and set_attr, where attr takes an argument of type T and returns what the given method definition says, has_attr takes an argument of type T and returns the result of GAP.Globals.HasSomething(X) (which is either true or false), set_attr takes an argument of type T and an object obj and calls GAP.Globals.SetSomething(X, obj).

In order to avoid runtime access via GAP.Globals.Something etc., the same modifications are applied in the construction of the three functions that are applied by @gapwrap.

The variables that are created by the macro belong to the Julia module in whose scope the macro is called.

Examples

julia> @gapattribute isstrictlysortedlist(obj::GapObj) = GAP.Globals.IsSSortedList(obj)::Bool;
+
source
GAP.@gapattributeMacro
@gapattribute

This macro is intended to be applied to a method definition for a unary function called attr, say, where the argument has the type T, say, the code contains exactly one call of the form GAP.Globals.Something(X), where Something is a GAP attribute such as Centre or IsSolvableGroup, and attr returns the corresponding attribute value for its argument.

The macro defines three functions attr, has_attr, and set_attr, where attr takes an argument of type T and returns what the given method definition says, has_attr takes an argument of type T and returns the result of GAP.Globals.HasSomething(X) (which is either true or false), set_attr takes an argument of type T and an object obj and calls GAP.Globals.SetSomething(X, obj).

In order to avoid runtime access via GAP.Globals.Something etc., the same modifications are applied in the construction of the three functions that are applied by @gapwrap.

The variables that are created by the macro belong to the Julia module in whose scope the macro is called.

Examples

julia> @gapattribute isstrictlysortedlist(obj::GapObj) = GAP.Globals.IsSSortedList(obj)::Bool;
 
 julia> l = GapObj([ 1, 3, 7 ]);
 
@@ -68,18 +68,18 @@
 
 julia> isstrictlysortedlist( l )
 true
-
source
GAP.@wrapMacro
@wrap funcdecl

When applied to a function declaration of the form NAME(a::T) or NAME(a::T)::S, this macro generates a function which behaves equivalently to NAME(a::T) = GAP.Globals.NAME(a) resp. NAME(a::T) = GAP.Globals.NAME(a)::S, assuming that GAP.Globals.NAME references a GAP function. Function declarations with more than one argument or zero arguments are also supported.

However, the generated function actually caches the GAP object GAP.Globals.NAME. This minimizes the call overhead. So @wrap typically is used to provide an optimized way to call certain GAP functions.

Another use case for this macro is to improve type stability of code calling into GAP, via the type annotations for the arguments and return value contained in the function declaration.

Be advised, though, that if the value of GAP.Globals.NAME is changed later on, the function generated by this macro will not be updated, i.e., it will still reference the original GAP object.

Examples

julia> GAP.@wrap Jacobi(x::GapInt, y::GapInt)::Int
+
source
GAP.@wrapMacro
@wrap funcdecl

When applied to a function declaration of the form NAME(a::T) or NAME(a::T)::S, this macro generates a function which behaves equivalently to NAME(a::T) = GAP.Globals.NAME(a) resp. NAME(a::T) = GAP.Globals.NAME(a)::S, assuming that GAP.Globals.NAME references a GAP function. Function declarations with more than one argument or zero arguments are also supported.

However, the generated function actually caches the GAP object GAP.Globals.NAME. This minimizes the call overhead. So @wrap typically is used to provide an optimized way to call certain GAP functions.

Another use case for this macro is to improve type stability of code calling into GAP, via the type annotations for the arguments and return value contained in the function declaration.

Be advised, though, that if the value of GAP.Globals.NAME is changed later on, the function generated by this macro will not be updated, i.e., it will still reference the original GAP object.

Examples

julia> GAP.@wrap Jacobi(x::GapInt, y::GapInt)::Int
 Jacobi (generic function with 1 method)
 
 julia> Jacobi(11,35)
-1
source

Convenience adapters

This section describes how one can manipulate GAP objects from the Julia side, using Julia syntax features.

In particular, the following is available on the Julia side in order to support special GAP syntax beyond function calls with arguments.

GAP.call_gap_funcFunction
call_gap_func(func::GapObj, args...; kwargs...)

Call the GAP object func as a function, with arguments args... and global GAP options kwargs..., and return the result if there is one, and nothing otherwise.

There is no argument number checking here, all checks on the arguments are done by GAP itself.

For convenience, one can use the syntax func(args...; kwargs...).

Examples

julia> GAP.Globals.Factors( 12 )
+1
source

Convenience adapters

This section describes how one can manipulate GAP objects from the Julia side, using Julia syntax features.

In particular, the following is available on the Julia side in order to support special GAP syntax beyond function calls with arguments.

GAP.call_gap_funcFunction
call_gap_func(func::GapObj, args...; kwargs...)

Call the GAP object func as a function, with arguments args... and global GAP options kwargs..., and return the result if there is one, and nothing otherwise.

There is no argument number checking here, all checks on the arguments are done by GAP itself.

For convenience, one can use the syntax func(args...; kwargs...).

Examples

julia> GAP.Globals.Factors( 12 )
 GAP: [ 2, 2, 3 ]
 
 julia> GAP.Globals.Cyc(GAP.Obj(1.41421356))
 GAP: 35355339/25000000
 
 julia> GAP.Globals.Cyc(GAP.Obj(1.41421356); bits=20)
-GAP: E(8)-E(8)^3
source
GAP.call_with_catchFunction
call_with_catch(juliafunc, arguments)

Return a tuple (ok, val) where ok is either true, meaning that calling the function juliafunc with arguments returns the value val, or false, meaning that the function call runs into an error; in the latter case, val is set to the string of the error message.

Examples

julia> GAP.call_with_catch(sqrt, 2)
+GAP: E(8)-E(8)^3
source
GAP.call_with_catchFunction
call_with_catch(juliafunc, arguments)

Return a tuple (ok, val) where ok is either true, meaning that calling the function juliafunc with arguments returns the value val, or false, meaning that the function call runs into an error; in the latter case, val is set to the string of the error message.

Examples

julia> GAP.call_with_catch(sqrt, 2)
 (true, 1.4142135623730951)
 
 julia> flag, res = GAP.call_with_catch(sqrt, -2);
@@ -89,7 +89,7 @@
 
 julia> startswith(res, "DomainError")
 true
-
source
Base.getindexFunction
getindex(x::GapObj, i::Int64)
+
source
Base.getindexFunction
getindex(x::GapObj, i::Int64)
 getindex(x::GapObj, i::Int64, j::Int64)
 getindex(x::GapObj, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}

Return the entry at position i or at position (i,j) in x, or the list of entries in x at the positions described by l, provided that x is a GAP object supporting this, such as a GAP list or matrix object.

Examples

julia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])
 GAP: [ 1, 2, 3, 5, 8, 13 ]
@@ -117,7 +117,7 @@
 
 julia> m[2,1]
 3
-
source
Base.setindex!Function
setindex!(x::GapObj, v::Any, i::Int64)
+
source
Base.setindex!Function
setindex!(x::GapObj, v::Any, i::Int64)
 setindex!(x::GapObj, v::Any, i::Int64, j::Int64)
 setindex!(x::GapObj, v::Any, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}

Set the entry at position i or (i,j) in x to v, or set the entries at the positions in x that are described by l to the entries in v, provided that x is a GAP object supporting this, such as a GAP list or matrix object.

Examples

julia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])
 GAP: [ 1, 2, 3, 5, 8, 13 ]
@@ -145,7 +145,7 @@
 
 julia> m
 GAP: [ [ 1, 0 ], [ 3, 4 ] ]
-
source
GAP.getbangindexFunction
getbangindex(x::GapObj, i::Int64)

Return the entry at position i in the positional object x.

Examples

julia> x = GAP.Globals.ZmodnZObj(1, 6)
+
source
GAP.getbangindexFunction
getbangindex(x::GapObj, i::Int64)

Return the entry at position i in the positional object x.

Examples

julia> x = GAP.Globals.ZmodnZObj(1, 6)
 GAP: ZmodnZObj( 1, 6 )
 
 julia> GAP.Globals.IsPositionalObjectRep(x)
@@ -153,7 +153,7 @@
 
 julia> getbangindex(x, 1)
 1
-
source
GAP.setbangindex!Function
setbangindex!(x::GapObj, v::Any, i::Int64)

Set the entry at position i in the positional object x to v, and return x.

Examples

julia> x = GAP.Globals.ZmodnZObj(1, 6)
+
source
GAP.setbangindex!Function
setbangindex!(x::GapObj, v::Any, i::Int64)

Set the entry at position i in the positional object x to v, and return x.

Examples

julia> x = GAP.Globals.ZmodnZObj(1, 6)
 GAP: ZmodnZObj( 1, 6 )
 
 julia> GAP.Globals.IsPositionalObjectRep(x)
@@ -161,13 +161,13 @@
 
 julia> setbangindex!(x, 0, 1)
 GAP: ZmodnZObj( 0, 6 )
-
source
Base.getpropertyFunction
getproperty(x::GapObj, f::Symbol)
+
source
Base.getpropertyFunction
getproperty(x::GapObj, f::Symbol)
 getproperty(x::GapObj, f::Union{AbstractString,Int64})

Return the record component of the GAP record x that is described by f.

Examples

julia> r = GapObj(Dict(:a => 1))
 GAP: rec( a := 1 )
 
 julia> r.a
 1
-
source
Base.setproperty!Function
setproperty!(x::GapObj, f::Symbol, v)
+
source
Base.setproperty!Function
setproperty!(x::GapObj, f::Symbol, v)
 setproperty!(x::GapObj, f::Union{AbstractString,Int64}, v)

Set the record component of the GAP record x that is described by f to the value v.

Examples

julia> r = GapObj(Dict(:a => 1))
 GAP: rec( a := 1 )
 
@@ -176,7 +176,7 @@
 
 julia> r
 GAP: rec( a := 1, b := 0 )
-
source
Base.haspropertyFunction
hasproperty(x::GapObj, f::Symbol)
+
source
Base.haspropertyFunction
hasproperty(x::GapObj, f::Symbol)
 hasproperty(x::GapObj, f::Union{AbstractString,Int64})

Return true if the GAP record x has a component that is described by f, and false otherwise.

Examples

julia> r = GapObj(Dict(:a => 1))
 GAP: rec( a := 1 )
 
@@ -194,7 +194,7 @@
 
 julia> r
 GAP: rec( a := 1, b := 2 )
-
source
GAP.getbangpropertyFunction
getbangproperty(x::GapObj, f::Union{AbstractString,Int64,Symbol})

Return the value of the component f in the component object x.

Examples

julia> x = GAP.Globals.Iterator(GAP.Globals.Integers)
+
source
GAP.getbangpropertyFunction
getbangproperty(x::GapObj, f::Union{AbstractString,Int64,Symbol})

Return the value of the component f in the component object x.

Examples

julia> x = GAP.Globals.Iterator(GAP.Globals.Integers)
 GAP: <iterator of Integers at 0>
 
 julia> GAP.Globals.IsComponentObjectRep(x)
@@ -202,7 +202,7 @@
 
 julia> getbangproperty(x, :counter)
 0
-
source
GAP.setbangproperty!Function
setbangproperty!(x::GapObj, f::Union{AbstractString,Int64,Symbol}, v)

Set the value of the component f in the component object x to v, and return x.

Examples

julia> x = GAP.Globals.Iterator(GAP.Globals.Integers)
+
source
GAP.setbangproperty!Function
setbangproperty!(x::GapObj, f::Union{AbstractString,Int64,Symbol}, v)

Set the value of the component f in the component object x to v, and return x.

Examples

julia> x = GAP.Globals.Iterator(GAP.Globals.Integers)
 GAP: <iterator of Integers at 0>
 
 julia> GAP.Globals.IsComponentObjectRep(x)
@@ -213,7 +213,7 @@
 
 julia> getbangproperty(x, :counter)
 3
-
source
GAP.wrap_rngFunction
wrap_rng(rng::Random.AbstractRNG)

Return a GAP object in the filter IsRandomSource that uses rng in calls to GAP's Random function. The idea is that GAP's Random methods for high level objects will just hand over the given random source to subfunctions until Random gets called for a list or the bounds of a range, and then Base.rand gets called with rng.

Examples

julia> rng1 = Random.default_rng();
+
source
GAP.wrap_rngFunction
wrap_rng(rng::Random.AbstractRNG)

Return a GAP object in the filter IsRandomSource that uses rng in calls to GAP's Random function. The idea is that GAP's Random methods for high level objects will just hand over the given random source to subfunctions until Random gets called for a list or the bounds of a range, and then Base.rand gets called with rng.

Examples

julia> rng1 = Random.default_rng();
 
 julia> rng2 = copy(rng1);
 
@@ -249,7 +249,7 @@
 
 julia> GAP.Globals.Random(gap_rng1, GAP.Globals.GF(2)^10)
 GAP: <a GF2 vector of length 10>
-
source
GAP.randseed!Function
GAP.randseed!([seed::Integer])

Reseed GAP's global RNG with seed.

The given seed must be a non-negative integer. When seed is not specified, a random seed is generated from Julia's global RNG.

For a fixed seed, the stream of generated numbers is allowed to change between different versions of GAP.

source

For the following Julia functions, methods are provided that deal with the case that the arguments are GAP objects; they delegate to the corresponding GAP operations.

JuliaGAP
lengthLength
in\in
zeroZeroSameMutability
oneOneSameMutability
- (unary)AdditiveInverseSameMutability
invInverseSameMutability
+SUM
- (binary)DIFF
*PROD
/QUO
\LQUO
^POW
modMOD
<LT
==EQ

The reason why four SameMutability operations are chosen in this list is as follows. In GAP, binary arithmetic operations return immutable results if and only if the two arguments are immutable. Thus it is consistent if unary arithmetic operations return a result with the same mutability as the argument. Note that GAP provides several variants of these unary operations, regarding the mutability of the result (ZeroMutable, ZeroImmutable, ZeroSameMutability, etc.), but here we have to choose one behaviour for the Julia function.

julia> l = GAP.julia_to_gap( [ 1, 3, 7, 15 ] )
+
source
GAP.randseed!Function
GAP.randseed!([seed::Integer])

Reseed GAP's global RNG with seed.

The given seed must be a non-negative integer. When seed is not specified, a random seed is generated from Julia's global RNG.

For a fixed seed, the stream of generated numbers is allowed to change between different versions of GAP.

source

For the following Julia functions, methods are provided that deal with the case that the arguments are GAP objects; they delegate to the corresponding GAP operations.

JuliaGAP
lengthLength
in\in
zeroZeroSameMutability
oneOneSameMutability
- (unary)AdditiveInverseSameMutability
invInverseSameMutability
+SUM
- (binary)DIFF
*PROD
/QUO
\LQUO
^POW
modMOD
<LT
==EQ

The reason why four SameMutability operations are chosen in this list is as follows. In GAP, binary arithmetic operations return immutable results if and only if the two arguments are immutable. Thus it is consistent if unary arithmetic operations return a result with the same mutability as the argument. Note that GAP provides several variants of these unary operations, regarding the mutability of the result (ZeroMutable, ZeroImmutable, ZeroSameMutability, etc.), but here we have to choose one behaviour for the Julia function.

julia> l = GAP.julia_to_gap( [ 1, 3, 7, 15 ] )
 GAP: [ 1, 3, 7, 15 ]
 
 julia> m = GAP.julia_to_gap( [ 1 2; 3 4 ] )
@@ -328,4 +328,4 @@
 
 julia> GAP.show_gap_help( "Size", true )
 [...]  # about 15 entries from GAP manuals
-
source +source diff --git a/dev/packages/index.html b/dev/packages/index.html index 55a19472e..7c8a286fe 100644 --- a/dev/packages/index.html +++ b/dev/packages/index.html @@ -1,6 +1,9 @@ -Managing GAP packages · GAP.jl

Managing GAP packages

The following functions allow one to load/install/update/remove GAP packages.

GAP.Packages.loadFunction
load(spec::String, version::String = ""; install::Bool = false, quiet::Bool = true)

Try to load the GAP package given by spec, which can be either the name of the package or a local path where the package is installed (a directory that contains the package's PackageInfo.g file).

If version is specified then try to load a version of the package that is compatible with version, in the sense of GAP's CompareVersionNumbers function, otherwise try to load the newest installed version. Return true if this is successful, and false otherwise.

If install is set to true and (the desired version of) the required GAP package is not yet installed and spec is the package name then install is called first, in order to install the package; if no version is prescribed then the newest released version of the package will be installed.

The function calls GAP's LoadPackage function. If quiet is set to false then package banners are shown for all packages being loaded. It is also passed on to install.

source
GAP.Packages.installFunction
install(spec::String, version::String = "";
+Managing GAP packages · GAP.jl

Managing GAP packages

The following functions allow one to load/install/update/remove GAP packages.

GAP.Packages.loadFunction
load(spec::String, version::String = ""; install::Bool = false, quiet::Bool = true)

Try to load the GAP package given by spec, which can be either the name of the package or a local path where the package is installed (a directory that contains the package's PackageInfo.g file).

If version is specified then try to load a version of the package that is compatible with version, in the sense of GAP's CompareVersionNumbers function, otherwise try to load the newest installed version. Return true if this is successful, and false otherwise.

If install is set to true and (the desired version of) the required GAP package is not yet installed and spec is the package name then install is called first, in order to install the package; if no version is prescribed then the newest released version of the package will be installed.

The function calls GAP's LoadPackage function. If quiet is set to false then package banners are shown for all packages being loaded. It is also passed on to install.

source
GAP.Packages.installFunction
install(spec::String, version::String = "";
                       interactive::Bool = true, quiet::Bool = false,
-                      pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Download and install the GAP package given by spec into the pkgdir directory.

spec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.

If spec is the name of a package then the package version can be specified by version, in the format described for GAP's CompareVersionNumbers function. In all other cases the newest released version of the package will get installed.

Return true if the installation is successful or if (a version compatible with version) of the package was already installed, and false otherwise.

The function uses the function InstallPackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
GAP.Packages.updateFunction
update(spec::String; interactive::Bool = true, quiet::Bool = false,
-                     pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Update the GAP package given by spec that is installed in the pkgdir directory, to the latest version. Return true if a newer version was installed successfully, or if no newer version is available, and false otherwise.

spec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.

The function uses the function UpdatePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
GAP.Packages.removeFunction
remove(spec::String; interactive::Bool = true, quiet::Bool = false,
-                     pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Remove the GAP package with name spec that is installed in the pkgdir directory. Return true if the removal was successful, and false otherwise.

The function uses the function RemovePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
+ debug::Bool = false, + pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Download and install the GAP package given by spec into the pkgdir directory.

spec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.

If spec is the name of a package then the package version can be specified by version, in the format described for GAP's CompareVersionNumbers function. In all other cases the newest released version of the package will get installed.

Return true if the installation is successful or if (a version compatible with version) of the package was already installed, and false otherwise.

The function uses the function InstallPackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
GAP.Packages.updateFunction
update(spec::String; interactive::Bool = true, quiet::Bool = false,
+                     debug::Bool = false,
+                     pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Update the GAP package given by spec that is installed in the pkgdir directory, to the latest version. Return true if a newer version was installed successfully, or if no newer version is available, and false otherwise.

spec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.

The function uses the function UpdatePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
GAP.Packages.removeFunction
remove(spec::String; interactive::Bool = true, quiet::Bool = false,
+                     debug::Bool = false,
+                     pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])

Remove the GAP package with name spec that is installed in the pkgdir directory. Return true if the removal was successful, and false otherwise.

The function uses the function RemovePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.

source
diff --git a/dev/search/index.html b/dev/search/index.html index 592ff47d3..0395dd85f 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · GAP.jl

Loading search...

    +Search · GAP.jl

    Loading search...

      diff --git a/dev/search_index.js b/dev/search_index.js index 54fc6fed2..f71604392 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"conversion/","page":"Conversions","title":"Conversions","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"conversion/#Conversions","page":"Conversions","title":"Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"One of the main ideas of GAP.jl is that automatic conversions of Julia objects to GAP objects and vice versa shall be avoided whenever this is possible. For a few types of objects, such conversions are unavoidable, see Automatic GAP-to-Julia and Julia-to-GAP Conversions. In all other situations, the conversions between GAP objects and corresponding Julia objects can be performed using gap_to_julia and julia_to_gap, see Explicit GAP-to-Julia and Julia-to-GAP Conversions, respectively.","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"For convenience, also constructor methods are provided, for example Vector{Int64}(obj) can be used instead of GAP.gap_to_julia(Vector{Int64}, obj), where obj is a GAP list of integers; see Constructor Methods for GAP-to-Julia Conversions for a description of these methods. For Julia-to-GAP conversions, one can use for example GapObj(obj), where obj is a Julia object, see GapObj.","category":"page"},{"location":"conversion/#Automatic-GAP-to-Julia-and-Julia-to-GAP-Conversions","page":"Conversions","title":"Automatic GAP-to-Julia and Julia-to-GAP Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"When one calls a GAP function with Julia objects as arguments, or a Julia function with GAP objects as arguments, the arguments are in general not automatically converted to GAP objects or Julia objects, respectively. The exceptions are as follows.","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"GAP's immediate integers (in the range -2^60 to 2^60-1) are automatically converted to Julia's Int64 objects; Julia's Int64 objects are automatically converted to GAP's immediate integers if they fit, and to GAP's large integers otherwise.\nGAP's immediate finite field elements are automatically converted to Julia's GAP.FFE objects, and vice versa.\nGAP's true and false are automatically converted to Julia's true and false, and vice versa.","category":"page"},{"location":"conversion/#Explicit-GAP-to-Julia-and-Julia-to-GAP-Conversions","page":"Conversions","title":"Explicit GAP-to-Julia and Julia-to-GAP Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"gap_to_julia\njulia_to_gap","category":"page"},{"location":"conversion/#GAP.gap_to_julia","page":"Conversions","title":"GAP.gap_to_julia","text":"gap_to_julia(type, x, recursion_dict::Union{Nothing,RecDict}=nothing; recursive::Bool=true)\n\nTry to convert the object x to a Julia object of type type. If x is a GapObj then the conversion rules are defined in the manual of the GAP package JuliaInterface. If x is another GAP.Obj (for example a Int64) then the result is defined in Julia by type.\n\nThe parameter recursion_dict is used to preserve the identity of converted subobjects and should never be given by the user.\n\nFor GAP lists and records, it makes sense to convert also the subobjects recursively, or to keep the subobjects as they are; the behaviour is controlled by recursive, which can be true or false.\n\nExamples\n\njulia> GAP.gap_to_julia(GapObj(1//3))\n1//3\n\njulia> GAP.gap_to_julia(GapObj(\"abc\"))\n\"abc\"\n\njulia> val = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.gap_to_julia( val )\n2-element Vector{Any}:\n Any[1, 2]\n Any[3, 4]\n\njulia> GAP.gap_to_julia( val, recursive = false )\n2-element Vector{Any}:\n GAP: [ 1, 2 ]\n GAP: [ 3, 4 ]\n\njulia> GAP.gap_to_julia( Vector{GapObj}, val )\n2-element Vector{GapObj}:\n GAP: [ 1, 2 ]\n GAP: [ 3, 4 ]\n\njulia> GAP.gap_to_julia( Matrix{Int}, val )\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\nThe following gap_to_julia conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more GAP objects.)\n\nGAP filter default Julia type other Julia types\nIsInt BigInt `T <: Integer\nIsFFE GapFFE \nIsBool Bool \nIsRat Rational{BigInt} `Rational{T}\nIsFloat Float64 `T <: AbstractFloat\nIsChar Cuchar Char\nIsStringRep String Symbol, Vector{T}\nIsRangeRep StepRange{Int64,Int64} Vector{T}\nIsBListRep BitVector Vector{T}\nIsList Vector{Any} Vector{T}\nIsVectorObj Vector{Any} Vector{T}\nIsMatrixObj Matrix{Any} Matrix{T}\nIsRecord Dict{Symbol, Any} Dict{Symbol, T}\n\n\n\n\n\n","category":"function"},{"location":"conversion/#GAP.julia_to_gap","page":"Conversions","title":"GAP.julia_to_gap","text":"julia_to_gap(input, recursion_dict = IdDict(); recursive::Bool = false)\n\nConvert a julia object input to an appropriate GAP object. If recursive is set to true, recursive conversions on arrays, tuples, and dictionaries is performed.\n\nThe input recursion_dict should never be set by the user, it is meant to keep egality of input data, by converting equal data to identical objects in GAP.\n\nExamples\n\njulia> GAP.julia_to_gap(1//3)\nGAP: 1/3\n\njulia> GAP.julia_to_gap(\"abc\")\nGAP: \"abc\"\n\njulia> GAP.julia_to_gap([ [1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GAP.julia_to_gap([ [1, 2], [3, 4]], recursive = true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\n\nThe following julia_to_gap conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more Julia objects.)\n\nJulia type GAP filter\nInt8, Int16, ..., BigInt IsInt\nGapFFE IsFFE\nBool IsBool\nRational{T} IsRat\nFloat16, Float32, Float64 IsFloat\nAbstractString IsString\nSymbol IsString\nChar IsChar\nVector{T} IsList\nVector{Bool}, BitVector IsBList\nTuple{T} IsList\nMatrix{T} IsList\nDict{String, T}, Dict{Symbol, T} IsRecord\nUnitRange{T}, StepRange{T, S} IsRange\nFunction IsFunction\n\n\n\n\n\n","category":"function"},{"location":"conversion/#Constructor-Methods-for-GAP-to-Julia-Conversions","page":"Conversions","title":"Constructor Methods for GAP-to-Julia Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"(For Julia-to-GAP conversions, one can use GapObj and GAP.Obj as constructors.)","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"Int128\nBigInt\nRational\nFloat64\nChar\nCuchar\nString\nSymbol\nUnitRange\nStepRange\nTuple\nBitVector\nVector{T}\nMatrix{T}\nSet{T}\nDict{Symbol,T}","category":"page"},{"location":"conversion/#Core.Int128","page":"Conversions","title":"Core.Int128","text":"Int128(obj::GapObj)\n\nReturn the Int128 converted from the GAP integer obj. (Note that small GAP integers are represented by Julia Int64 objects, in particular they are not GapObjs; their conversion is not handled by methods installed in GAP.jl.)\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> Int128(val)\n15511210043330985984000000\n\njulia> Int(val)\nERROR: InexactError: Int64(15511210043330985984000000)\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.GMP.BigInt","page":"Conversions","title":"Base.GMP.BigInt","text":"BigInt(obj::GapObj)\n\nReturn the big integer converted from the GAP integer obj. (Note that small GAP integers are not represented by GapObjs, their conversion with BigInt is handled by Julia's methods.)\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> BigInt(val)\n15511210043330985984000000\n\njulia> val = GAP.Globals.Factorial(10)\n3628800\n\njulia> isa(val, GapObj)\nfalse\n\njulia> BigInt(val)\n3628800\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Rational","page":"Conversions","title":"Base.Rational","text":"Rational{T}(obj::GapObj) where {T<:Integer}\n\nReturn the rational converted from the GAP integer or the GAP rational obj,\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> Rational{Int128}(val)\n15511210043330985984000000//1\n\njulia> Rational{BigInt}(val)\n15511210043330985984000000//1\n\njulia> val = GAP.Obj(1//3)\nGAP: 1/3\n\njulia> Rational{Int64}(val)\n1//3\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Float64","page":"Conversions","title":"Core.Float64","text":"Float64(obj::GapObj)\n\nReturn the float converted from the GAP float obj.\n\nExamples\n\njulia> val = GAP.Obj(2.2)\nGAP: 2.2\n\njulia> Float64(val)\n2.2\n\njulia> Float32(val)\n2.2f0\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Char","page":"Conversions","title":"Core.Char","text":"Char(obj::GapObj)\n\nReturn the character converted from the GAP character obj.\n\nExamples\n\njulia> val = GAP.Obj('x')\nGAP: 'x'\n\njulia> Char(val)\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Cuchar","page":"Conversions","title":"Base.Cuchar","text":"Cuchar(obj::GapObj)\n\nReturn the UInt8 that belongs to the GAP character obj.\n\nExamples\n\njulia> val = GAP.Obj('x')\nGAP: 'x'\n\njulia> Cuchar(val)\n0x78\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.String","page":"Conversions","title":"Core.String","text":"String(obj::GapObj)\n\nReturn the Julia string converted from the GAP string obj. Note that GAP's String function can be applied to arbitrary GAP objects, similar to Julia's string function; this behaviour is not intended for this String constructor.\n\nExamples\n\njulia> val = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> String(val)\n\"abc\"\n\njulia> val = GAP.Obj([])\nGAP: [ ]\n\njulia> String(val) # an empty GAP list is a string\n\"\"\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Symbol","page":"Conversions","title":"Core.Symbol","text":"Symbol(obj::GapObj)\n\nReturn the symbol converted from the GAP string obj.\n\nExamples\n\njulia> str = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> Symbol(str)\n:abc\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.UnitRange","page":"Conversions","title":"Base.UnitRange","text":"UnitRange(obj::GapObj)\n\nReturn the unit range converted from the GAP range obj, which has step width 1.\n\nExamples\n\njulia> val = GAP.Obj(1:10)\nGAP: [ 1 .. 10 ]\n\njulia> UnitRange(val)\n1:10\n\njulia> UnitRange{Int32}(val)\n1:10\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.StepRange","page":"Conversions","title":"Base.StepRange","text":"StepRange(obj::GapObj)\n\nReturn the step range converted from the GAP range obj, which may have arbitrary step width.\n\nExamples\n\njulia> val = GAP.Obj(1:2:11)\nGAP: [ 1, 3 .. 11 ]\n\njulia> StepRange(val)\n1:2:11\n\njulia> r = StepRange{Int8,Int8}(val)\n1:2:11\n\njulia> typeof(r)\nStepRange{Int8, Int8}\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Tuple","page":"Conversions","title":"Core.Tuple","text":"Tuple{Types...}(obj::GapObj; recursive::Bool = true)\n\nReturn the tuple converted from the GAP list obj. The entries of the list are converted to the required types Types..., using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.\n\nExamples\n\njulia> val = GAP.Obj([1, 5])\nGAP: [ 1, 5 ]\n\njulia> Tuple{Int64,Int64}(val)\n(1, 5)\n\njulia> val = GAP.Obj([[1], [2]]; recursive=true)\nGAP: [ [ 1 ], [ 2 ] ]\n\njulia> Tuple{Any,Any}(val)\n(Any[1], Any[2])\n\njulia> Tuple{GapObj,GapObj}(val; recursive=false)\n(GAP: [ 1 ], GAP: [ 2 ])\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.BitVector","page":"Conversions","title":"Base.BitVector","text":"BitVector(obj::GapObj)\n\nReturn the bit vector converted from the GAP list of booleans obj.\n\nExamples\n\njulia> val = GAP.Obj([true, false, true])\nGAP: [ true, false, true ]\n\njulia> BitVector(val)\n3-element BitVector:\n 1\n 0\n 1\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Vector","page":"Conversions","title":"Base.Vector","text":"Vector{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the 1-dimensional array converted from the GAP list obj. The entries of the list are converted to the type T, using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.\n\nIf T is UInt8 then obj may be a GAP string.\n\nExamples\n\njulia> val = GAP.Obj([[1], [2]]; recursive=true)\nGAP: [ [ 1 ], [ 2 ] ]\n\njulia> Vector{Any}(val)\n2-element Vector{Any}:\n Any[1]\n Any[2]\n\njulia> Vector{Any}(val; recursive=false)\n2-element Vector{Any}:\n GAP: [ 1 ]\n GAP: [ 2 ]\n\njulia> Vector{Vector{Int64}}(val)\n2-element Vector{Vector{Int64}}:\n [1]\n [2]\n\njulia> val = GAP.evalstr( \"NewVector( IsPlistVectorRep, Integers, [ 0, 2, 5 ] )\" )\nGAP: \n\njulia> Vector{Int64}(val)\n3-element Vector{Int64}:\n 0\n 2\n 5\n\njulia> val = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> Vector{UInt8}(val)\n3-element Vector{UInt8}:\n 0x61\n 0x62\n 0x63\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Matrix","page":"Conversions","title":"Base.Matrix","text":"Matrix{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the 2-dimensional array converted from the GAP matrix obj, which can be a GAP list of lists or a GAP matrix object. The entries of the matrix are converted to the type T, using gap_to_julia. If recursive is true then the entries are converted recursively, otherwise non-recursively.\n\nExamples\n\njulia> val = GAP.Obj([[1, 2], [3, 4]]; recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> Matrix{Int64}(val)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> val = GAP.evalstr( \"NewMatrix( IsPlistMatrixRep, Integers, 2, [ 0, 1, 2, 3 ] )\" )\nGAP: <2x2-matrix over Integers>\n\njulia> Matrix{Int64}(val)\n2×2 Matrix{Int64}:\n 0 1\n 2 3\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Set","page":"Conversions","title":"Base.Set","text":"Set{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the set converted from the GAP list or GAP collection obj. The elements of obj are converted to the required type T, using gap_to_julia. If recursive is true then the elements are converted recursively, otherwise non-recursively.\n\nThis constructor method is intended for situations where the result involves only native Julia objects such as integers and strings. Dealing with results containing GAP objects will be inefficient.\n\nExamples\n\njulia> Set{Int}(GAP.Obj([1, 2, 1]))\nSet{Int64} with 2 elements:\n 2\n 1\n\njulia> Set{Vector{Int}}(GAP.Obj([[1], [2], [1]]; recursive=true))\nSet{Vector{Int64}} with 2 elements:\n [1]\n [2]\n\njulia> Set{String}(GAP.Obj([\"a\", \"b\"]; recursive=true))\nSet{String} with 2 elements:\n \"b\"\n \"a\"\n\njulia> Set{Any}(GAP.Obj([[1], [2], [1]]; recursive=true))\nSet{Any} with 2 elements:\n Any[1]\n Any[2]\n\nIn the following examples, the order in which the Julia output is shown may vary.\n\nExamples\n\njulia> s = Set{Any}(GAP.Obj([[1], [2], [1]]; recursive=true); recursive=false);\n\njulia> s == Set{Any}([GAP.Obj([1]), GAP.Obj([2])])\ntrue\n\njulia> s = Set{Any}(GAP.Globals.SymmetricGroup(2); recursive=false);\n\njulia> s == Set{Any}([GAP.evalstr(\"()\"), GAP.evalstr(\"(1,2)\")])\ntrue\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Dict","page":"Conversions","title":"Base.Dict","text":"Dict{Symbol,T}(obj::GapObj; recursive::Bool = true)\n\nReturn the dictionary converted from the GAP record obj. If recursive is true then the values of the record components are recursively converted to objects of the type T, using gap_to_julia, otherwise they are kept as they are.\n\nExamples\n\njulia> val = GAP.Obj(Dict(:a => 1, :b => 2))\nGAP: rec( a := 1, b := 2 )\n\njulia> Dict{Symbol,Int}(val)\nDict{Symbol, Int64} with 2 entries:\n :a => 1\n :b => 2\n\njulia> val = GAP.Obj(Dict(:l => GAP.Obj([1, 2])))\nGAP: rec( l := [ 1, 2 ] )\n\njulia> Dict{Symbol,Any}(val; recursive=false)\nDict{Symbol, Any} with 1 entry:\n :l => GAP: [ 1, 2 ]\n\njulia> Dict{Symbol,Any}(val; recursive=true)\nDict{Symbol, Any} with 1 entry:\n :l => Any[1, 2]\n\njulia> Dict{Symbol,Vector{Int}}(val; recursive=true)\nDict{Symbol, Vector{Int64}} with 1 entry:\n :l => [1, 2]\n\n\n\n\n\n\n","category":"type"},{"location":"manualindex/#Index","page":"Index","title":"Index","text":"","category":"section"},{"location":"manualindex/","page":"Index","title":"Index","text":"","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Analyzing-Rubik's-Cube-using-GAP.jl","page":"Examples","title":"Analyzing Rubik's Cube using GAP.jl","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"The following Julia session shows the GAP computations from the Rubik's Cube example from the GAP webpages.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We consider the group of transformations of Rubik's magic cube. If we number the faces of this cube as follows","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":" +--------------+\n | |\n | 1 2 3 |\n | |\n | 4 top 5 |\n | |\n | 6 7 8 |\n | |\n +--------------+--------------+--------------+--------------+\n | | | | |\n | 9 10 11 | 17 18 19 | 25 26 27 | 33 34 35 |\n | | | | |\n | 12 left 13 | 20 front 21 | 28 right 29 | 36 rear 37 |\n | | | | |\n | 14 15 16 | 22 23 24 | 30 31 32 | 38 39 40 |\n | | | | |\n +--------------+--------------+--------------+--------------+\n | |\n | 41 42 43 |\n | |\n | 44 bottom 45 |\n | |\n | 46 47 48 |\n | |\n +--------------+","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"then the group is generated by the following generators, corresponding to the six faces of the cube.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube = @gap(\"Group(\n ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),\n ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),\n (17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),\n (25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),\n (33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),\n (41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40) );\")\nGAP: ","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"First we want to know the size of this group.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube_size = GAP.Globals.Size(cube)\nGAP: 43252003274489856000","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Since this is a little bit unhandy, let us factorize this number.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cf = GAP.Globals.Collected(GAP.Globals.Factors(cube_size))\nGAP: [ [ 2, 27 ], [ 3, 14 ], [ 5, 3 ], [ 7, 2 ], [ 11, 1 ] ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"(The result tells us that the size is 2^27 3^14 5^3 7^2 11.)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"In order to convert this GAP list to Julia, we can either use gap_to_julia or a suitable Vector constructor, see Conversions. Note that the one-argument version of the former returns a vector of Any objects.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.gap_to_julia(cf)\n5-element Vector{Any}:\n Any[2, 27]\n Any[3, 14]\n Any[5, 3]\n Any[7, 2]\n Any[11, 1]\n\njulia> Vector{Vector{Int}}(cf)\n5-element Vector{Vector{Int64}}:\n [2, 27]\n [3, 14]\n [5, 3]\n [7, 2]\n [11, 1]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Next let us investigate the operation of the group on the 48 points.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> orbs = GAP.Globals.Orbits(cube, GAP.GapObj(1:48))\nGAP: [ [ 1, 3, 17, 14, 8, 38, 9, 41, 19, 48, 22, 6, 30, 33, 43, 11, 46, 40, 24, 27, 25, 35, 16, 32 ], [ 2, 5, 12, 7, 36, 10, 47, 4, 28, 45, 34, 13, 29, 44, 20, 42, 26, 21, 37, 15, 31, 18, 23, 39 ] ]\n\njulia> length(orbs)\n2","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The first orbit contains the points at the corners, the second those at the edges; clearly the group cannot move a point at a corner onto a point at an edge.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"So to investigate the cube group we first investigate the operation on the corner points. Note that the constructed group that describes this operation will operate on the set [1..24], not on the original set orbs[1].","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube1 = GAP.Globals.Action(cube, orbs[1])\nGAP: \n\njulia> GAP.Globals.NrMovedPoints(cube1)\n24\n\njulia> GAP.Globals.Size(cube1)\n88179840","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Now this group obviously operates transitively, but let us test whether it is also primitive.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> corners = GAP.Globals.Blocks(cube1, GAP.Globals.MovedPoints(cube1))\nGAP: [ [ 1, 7, 22 ], [ 2, 14, 20 ], [ 3, 12, 16 ], [ 4, 17, 18 ], [ 5, 9, 21 ], [ 6, 10, 24 ], [ 8, 11, 23 ], [ 13, 15, 19 ] ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Those eight blocks correspond to the eight corners of the cube; on the one hand the group permutes those and on the other hand it permutes the three points at each corner cyclically.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> blockhom1 = GAP.Globals.ActionHomomorphism(cube1, corners, GAP.Globals.OnSets)\nGAP: \n\njulia> cube1b = GAP.Globals.Image(blockhom1)\nGAP: Group([ (1,2,4,3), (1,3,6,5), (1,5,8,2), (3,4,7,6), (5,6,7,8), (2,8,7,4) ])\n\njulia> GAP.Globals.Size(cube1b)\n40320","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Now a permutation group of degree 8 that has order 40320 must be the full symmetric group Sym(8) on eight points.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The next thing then is to investigate the kernel of this operation on blocks, i.e., the subgroup of cube1 of those elements that fix the blocks setwise.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> ker1 = GAP.Globals.Kernel(blockhom1)\nGAP: \n\njulia> println(Vector{Int}(GAP.Globals.Factors(GAP.Globals.Size(ker1))))\n[3, 3, 3, 3, 3, 3, 3]\n\njulia> GAP.Globals.IsElementaryAbelian(ker1)\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We can show that the product of this elementary abelian group 3^7 with the Sym(8) is semidirect by finding a complement, i.e., a subgroup that has trivial intersection with the kernel and that generates cube1 together with the kernel.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cmpl1 = GAP.Globals.ComplementClassesRepresentatives(cube1, ker1)\nGAP: [ ]\n\njulia> cmpl1 = cmpl1[1]; GAP.Globals.Size(cmpl1)\n40320","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We verify the complement properties:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.Size(GAP.Globals.Intersection(cmpl1, ker1))\n1\n\njulia> GAP.Globals.ClosureGroup(cmpl1, ker1) == cube1\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"There is even a more elegant way to show that cmpl1 is a complement.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.IsBijective(GAP.Globals.RestrictedMapping(blockhom1, cmpl1))\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Of course, theoretically it is clear that cmpl1 must indeed be a complement.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"In fact we know that cube1 is a subgroup of index 3 in the wreath product of a cyclic 3 with Sym(8). This missing index 3 tells us that we do not have total freedom in turning the corners. The following tests show that whenever we turn one corner clockwise we must turn another corner counterclockwise.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(1, 7, 22)\") in cube1\nfalse\n\njulia> @gap(\"(1, 7, 22)(2, 20, 14)\") in cube1\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"More or less the same things happen when we consider the operation of the cube group on the edges.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube2 = GAP.Globals.Action(cube, orbs[2]); GAP.Globals.Size(cube2)\n980995276800\n\njulia> edges = GAP.Globals.Blocks(cube2, GAP.Globals.MovedPoints(cube2))\nGAP: [ [ 1, 11 ], [ 2, 17 ], [ 3, 19 ], [ 4, 22 ], [ 5, 13 ], [ 6, 8 ], [ 7, 24 ], [ 9, 18 ], [ 10, 21 ], [ 12, 15 ], [ 14, 20 ], [ 16, 23 ] ]\n\njulia> blockhom2 = GAP.Globals.ActionHomomorphism(cube2, edges, GAP.Globals.OnSets);\n\njulia> cube2b = GAP.Globals.Image(blockhom2); GAP.Globals.Size(cube2b)\n479001600\n\njulia> ker2 = GAP.Globals.Kernel(blockhom2)\nGAP: \n\njulia> GAP.Globals.Factors(GAP.Globals.Size(ker2))\nGAP: [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]\n\njulia> GAP.Globals.IsElementaryAbelian(ker2)\ntrue\n\njulia> cmpl2 = GAP.Globals.ComplementClassesRepresentatives(cube2, ker2); length(cmpl2)\n4","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"So there are even 4 classes of complements here. This time we get a semidirect product of a 2^11 with an Sym(12), namely a subgroup of index 2 of the wreath product of a cyclic 2 with Sym(12). Here the missing index 2 tells us again that we do not have total freedom in turning the edges. The following tests show that whenever we flip one edge we must also flip another edge.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(1, 11)\") in cube2\nfalse\n\njulia> @gap(\"(1, 11)(2, 17)\") in cube2\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Since cube1 and cube2 are the groups describing the actions on the two orbits of cube, it is clear that cube is a subdirect product of those groups, i.e., a subgroup of the direct product. Comparing the sizes of cube1, cube2, and cube we see that cube must be a subgroup of index 2 in the direct product of those two groups.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> BigInt(GAP.Globals.Size(cube1)) * BigInt(GAP.Globals.Size(cube2))\n86504006548979712000\n\njulia> GAP.Globals.Size(cube)\nGAP: 43252003274489856000","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"(Note that both GAP.Globals.Size(cube1) and GAP.Globals.Size(cube2) have the Julia type Int64, and forming their product yields an overflow. In order to obtain the correct value we have created arbitrary precision integers for the two values before multiplying them.)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This final missing index 2 tells us that we cannot operate on corners and edges totally independently. The following tests show that whenever we exchange a pair of corners we must also exchange a pair of edges (and vice versa).","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(17, 19)(11, 8)(6, 25)\") in cube\nfalse\n\njulia> @gap(\"(7, 28)(18, 21)\") in cube\nfalse\n\njulia> @gap(\"(17, 19)(11, 8)(6, 25)(7, 28)(18, 21)\") in cube\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"As a last part of the structure analysis of the cube group let us compute the centre of the cube group, i.e., the subgroup of those operations that can be performed either before or after any other operation with the same result.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> z = GAP.Globals.Centre(cube)\nGAP: Group([ (2,34)(4,10)(5,26)(7,18)(12,37)(13,20)(15,44)(21,28)(23,42)(29,36)(31,45)(39,47) ])","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We see that the centre contains one nontrivial element, namely the operation that flips all 12 edges simultaneously.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Finally we turn to the original idea connected with the cube, namely to find a sequence of turns of the faces that will transform the cube back into its original state. This amounts to a decomposition of a given element of the cube group into a product of the generators. For this purpose we introduce a free group and a homomorphism of it onto the cube group.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> f = GAP.Globals.FreeGroup(GAP.GapObj([\"t\", \"l\", \"f\", \"r\", \"e\", \"b\"], recursive = true))\nGAP: \n\njulia> fhom = GAP.Globals.GroupHomomorphismByImages(f, cube)\nGAP: [ t, l, f, r, e, b ] -> [ (1,3,8,6)(2,5,7,4)(9,33,25,17)(10,34,26,18)(11,35,27,19), (1,17,41,40)(4,20,44,37)(6,22,46,35)(9,11,16,14)(10,13,15,12), (6,25,43,16)(7,28,42,13)(8,30,41,11)(17,19,24,22)(18,21,23,20), (3,38,43,19)(5,36,45,21)(8,33,48,24)(25,27,32,30)(26,29,31,28), (1,14,48,27)(2,12,47,29)(3,9,46,32)(33,35,40,38)(34,37,39,36), (14,22,30,38)(15,23,31,39)(16,24,32,40)(41,43,48,46)(42,45,47,44) ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Using this homomorphism, we can now decompose elements into generators. The method used utilizes a stabilizer chain and does not enumerate all group elements, therefore the words obtained are not the shortest possible, though they are short enough for hand solutions.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The computed decompositions may be different in different sessions, because they involve the computation of pseudo random elements. Therefore the results shown in the following may look different in actual Julia sessions.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"First we decompose the nonidentity centre element:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> zgen = GAP.Globals.GeneratorsOfGroup(z)[1]\nGAP: (2,34)(4,10)(5,26)(7,18)(12,37)(13,20)(15,44)(21,28)(23,42)(29,36)(31,45)(39,47)\n\njulia> pre1 = GAP.Globals.PreImagesRepresentative(fhom, zgen)\nGAP: t^-1*l*t*l^-1*e^-1*t*f^-1*e*l*f*(t^-1*l^-1)^2*t*l*f*t*r*t^-1*r^-1*f^-1*l^-1*e^-1*t^-1*e*t*l*t*f*t*r*t^-1*r^-1*f^-1*t^-2*f*t^-1*f^-1*t^2*e*l^-1*e^-1*t^-1*l*t*l*f*t^-1*f^-1*l^-1*t*l*t^2*l^-1*t^-1*l*t^-1*l^-1*t^2*f^-1*l^-1*t^-1*l*t*f*t*l^-1*t*l*f^-1*l*f*l^-1*t^-2*l^-1*f^-1*l*f*l*t*e^-1*t*e*l*t*l^-1*e*l*e^-1*t^-1*f*l*f*l^-1*f^-1*t^-2*f^-1*t*l^-1*f*t^-2*f^-2*b*r^-1*b^-1*t^-2*e^-1*r^-2*e*t^-1*r*b*e^-1*b^-1*l^-1*r^-2*t^-2*l^-1*b^-1*r^-1*e^-1\n\njulia> length(pre1)\n134","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Next we decompose some element arbitrarily chosen by us:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> pre2 = GAP.Globals.PreImagesRepresentative(fhom, @gap(\"(17, 19)(11, 8)(6, 25)(7, 28)(18, 21)\"))\nGAP: l^-1*t^-1*l*f*r*t*r^-1*f^-1*l*t*f*t^-1*f^-1*l^-1*t^2*f*t*l*t*l^-1*f^-1*l*t^-1*l^-1*f*t^-1*f^-1*l*t*l^-1*t*l*t^-2*l^-1*f*(t*r*t^-1*r^-1)^2*f^-1*t*l*f^-1*l^-1*f*l^-1*t^-1*l*t^-2*f*t*(f^-1*l^-1)^2*l^-1*f*l*e^-1*t*e*l*t^-1*e^-1*t^-1*e*l*b*f^-1*b^-1\n\njulia> length(pre2)\n77","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Last we let GAP choose a random element ...","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> r = GAP.Globals.Random(cube)\nGAP: (1,6,9,17,35,11)(2,13,29,42,4,34,20,36,23,10)(3,22,14,8,38,24,27,16,40,19,32,43,33,41,46,25,48,30)(5,39,28,37,18,31,44,26,47,21,12,7,45,15)\n\njulia> pre3 = GAP.Globals.PreImagesRepresentative(fhom, r)\nGAP: r*e^-1*t^-1*e^-1*r^-2*e*f*t^2*b^-1*e^-1*b*l*f^-1*r*t^-1*r^-1*l*b*f^-2*b^-1*f^-1*l*f*t^-1*l^-1*f^-1*l^-1*f*e*l^-1*e^-1*l^-2*t^-1*l*f^-1*l^-1*f*l^-1*t^-1*l^2*f*t*f^-1*(t^-1*l^-1)^3*e*l*e^-1*t*l*t^-1*l*t^2*l^-1*t^-1*l*t^-1*l^-1*f*t*f^-1*l*t*l^-1*f*l*t^-1*l^-1*t^-1*f^-1*t^-1*f*r*t*r^-1*t^-1*f^-1*t^-1*l^-1*t^-1*e^-1*t*e*l*f*r*t*r^-1*t^-1*f^-1*l^-1*t^-1*(l*t)^2*f^-1*l^-1*e^-1*f*t^-1*e*l*t^-1*l^-1*t\n\njulia> length(pre3)\n116","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"... and we verify that the decomposition is correct:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.Image(fhom, pre3) == r\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This concludes our example.","category":"page"},{"location":"basics/","page":"Basics","title":"Basics","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"basics/#Accessing-GAP-from-Julia","page":"Basics","title":"Accessing GAP from Julia","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"Any global GAP variable and function can be accessed from Julia via the GAP.Globals object; for example GAP.Globals.Binomial(5,3). See Convenience adapters for dealing with GAP syntax beyond simple function calls.\nThe GAP.prompt command can be used to switch to a GAP session that works like a regular GAP, except that leaving it (via quit; or by pressing Ctrl-D) returns one to a Julia prompt. From the GAP prompt, one can access Julia variables via the Julia object, for example Julia.binomial(5,3). For more details on how to access Julia from GAP, please consult the manual of the GAP package JuliaInterface.\nAlternatively, one can start GAP in the traditional way, by executing a shell script. Such a script can be created in a location of your choice via GAP.create_gap_sh. Note that one cannot switch from such a GAP session to the underlying Julia session and back.","category":"page"},{"location":"basics/","page":"Basics","title":"Basics","text":"Globals\nevalstr\nevalstr_ex\nGAP.prompt\nGAP.create_gap_sh","category":"page"},{"location":"basics/#GAP.Globals","page":"Basics","title":"GAP.Globals","text":"Globals\n\nThis is a global object that gives access to all global variables of the current GAP session via getproperty and setproperty!.\n\nExamples\n\njulia> GAP.Globals.Size # a global GAP function\nGAP: \n\njulia> GAP.Globals.size # there is no GAP variable with this name\nERROR: GAP variable size not bound\n[...]\n\njulia> hasproperty( GAP.Globals, :size )\nfalse\n\njulia> GAP.Globals.size = 17;\n\njulia> hasproperty( GAP.Globals, :size )\ntrue\n\njulia> GAP.Globals.size\n17\n\njulia> GAP.Globals.UnbindGlobal(g\"size\")\n\njulia> GAP.Globals.Julia # Julia objects can be values of GAP variables\nMain\n\n\n\n\n\n\n","category":"constant"},{"location":"basics/#GAP.evalstr","page":"Basics","title":"GAP.evalstr","text":"evalstr(cmd::String)\n\nLet GAP execute the command(s) given by cmd; if an error occurs then report this error, otherwise if the last command has a result then return it, otherwise return nothing.\n\nExamples\n\njulia> GAP.evalstr( \"1+2\" )\n3\n\njulia> GAP.evalstr( \"x:= []\" )\nGAP: [ ]\n\njulia> GAP.evalstr( \"y:= 2; Add( x, y )\" )\n\njulia> GAP.evalstr( \"x\" )\nGAP: [ 2 ]\n\njulia> GAP.evalstr( \"Print( x )\" )\n\nNote that screen outputs caused by evaluating cmd are not shown by evalstr; use evalstr_ex for accessing both the outputs and the return values of the command(s).\n\nIn general we recommend to avoid using evalstr, but it sometimes can be a useful escape hatch to access GAP functionality that is otherwise impossible to difficult to reach. But in most typical scenarios it should not be necessary to use it at all.\n\nInstead, use GAP.GapObj or GAP.Obj for constructing GAP objects that correspond to given Julia objects, and call GAP functions directly in the Julia session. For example, executing GAP.evalstr( \"x:= []; Add( x, 2 )\" ) can be replaced by the Julia code x = GAP.GapObj([]); GAP.Globals.Add(x, 2). Note that the variable x in the former example lives in the GAP session, i.e., it can be accessed as GAP.Globals.x after the call of GAP.evalstr, whereas x in the latter example lives in the Julia session.\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.evalstr_ex","page":"Basics","title":"GAP.evalstr_ex","text":"evalstr_ex(cmd::String)\n\nAssume that cmd consists of n GAP statements, each terminated by ; or ;;. Let GAP execute these statements and return a GAP list of length n that describes their results. Each entry of the return value is a GAP list of length 5, with the following meaning.\n\nThe first entry is true if the statement was executed successfully, and false otherwise.\nIf the first entry is true, then the second entry is bound to the result of the statement if there was one, and unbound otherwise.\nThe third entry is unbound if an error occured, true if the statement ends in a double semicolon, and false otherwise.\nThe fourth entry currently is always unbound.\nThe fifth entry contains the captured output of the statement as a string. If there was no double semicolon then also the output of GAP.Globals.ViewObj applied to the result value in the second entry, if any, is part of that string.\n\nExamples\n\njulia> GAP.evalstr_ex( \"1+2\" ) # error due to missing semicolon\nGAP: [ [ false,,,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"1+2;\" ) # one statement with return value\nGAP: [ [ true, 3, false,, \"3\" ] ]\n\njulia> GAP.evalstr_ex( \"1+2;;\" ) # the same with suppressed output\nGAP: [ [ true, 3, true,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"x:= []; Add(x, 1);\" ) # two valid commands\nGAP: [ [ true, [ 1 ], false,, \"[ ]\" ], [ true,, false,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"1/0; 1+1;\" ) # one error, one valid command\nGAP: [ [ false,,,, \"\" ], [ true, 2, false,, \"2\" ] ]\n\njulia> GAP.evalstr_ex( \"Print(1);\" ) # no return value but output\nGAP: [ [ true,, false,, \"1\" ] ]\n\njulia> GAP.evalstr_ex( \"\" ) # empty input\nGAP: [ ]\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.prompt","page":"Basics","title":"GAP.prompt","text":"prompt()\n\nStart a GAP prompt where you can enter GAP commands as in a regular GAP session. This prompt can be left as any GAP prompt by either entering quit; or pressing ctrl-D, which returns to the Julia prompt.\n\nThis GAP prompt allows to quickly switch between writing Julia and GAP code in a session where all data is shared.\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.create_gap_sh","page":"Basics","title":"GAP.create_gap_sh","text":"create_gap_sh(dstdir::String)\n\nGiven a directory path, create three files in that directory:\n\na shell script named gap.sh which acts like the gap.sh shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia.\ntwo TOML files, Manifest.toml and Project.toml, which are required by gap.sh to function (they record the precise versions of GAP.jl and other Julia packages involved)\n\n\n\n\n\n","category":"function"},{"location":"basics/#Accessing-Julia-from-GAP","page":"Basics","title":"Accessing Julia from GAP","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"The GAP-Julia interface is fully bidirectional, so it is also possible to access all Julia functionality from GAP. To learn more about this, please consult the manual of the GAP package JuliaInterface.","category":"page"},{"location":"basics/#Types","page":"Basics","title":"Types","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"FFE\nGapObj\nGAP.Obj\nGapInt","category":"page"},{"location":"basics/#GAP.FFE","page":"Basics","title":"GAP.FFE","text":"FFE\n\nWrap a pointer to a GAP FFE (\"finite field element\") immediate object. This type is defined in the JuliaInterface C code.\n\nExamples\n\njulia> x = GAP.Globals.Z(3)\nGAP: Z(3)\n\njulia> typeof(x)\nFFE\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.GapObj","page":"Basics","title":"GAP.GapObj","text":"GapObj\n\nThis is the Julia type of all those GAP objects that are not \"immediate\" (booleans, small integers, FFEs).\n\nExamples\n\njulia> typeof(GapObj([1, 2])) # a GAP list\nGapObj\n\njulia> typeof(GapObj(Dict(:a => 1))) # a GAP record\nGapObj\n\njulia> typeof( GAP.evalstr( \"(1,2,3)\" ) ) # a GAP permutation\nGapObj\n\njulia> typeof( GAP.evalstr( \"2^64\" ) ) # a large GAP integer\nGapObj\n\njulia> typeof( GAP.evalstr( \"2^59\" ) ) # a small GAP integer\nInt64\n\njulia> typeof( GAP.evalstr( \"Z(2)\" ) ) # a GAP FFE\nFFE\n\njulia> typeof( GAP.evalstr( \"true\" ) ) # a boolean\nBool\n\nNote that this is Julia's viewpoint on GAP objects. From the viewpoint of GAP, also the pointers to Julia objects are implemented as \"non-immediate GAP objects\", but they appear as Julia objects to Julia, not \"doubly wrapped\".\n\nExamples\n\njulia> GAP.evalstr( \"Julia.Base\" )\nBase\n\njulia> typeof( GAP.evalstr( \"Julia.Base\" ) ) # native Julia object\nModule\n\nOne can use GapObj as a constructor, in order to convert Julia objects to GAP objects. Such calls are delegated to julia_to_gap.\n\nHowever, this is restricted to outputs that actually are of type GapObj. To also deal with GAP integers, finite field elements and booleans, use GAP.Obj instead.\n\nRecursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.\n\nExamples\n\njulia> GapObj(1//3)\nGAP: 1/3\n\njulia> GapObj([1 2; 3 4])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj([[1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GapObj([[1, 2], [3, 4]], true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj([[1, 2], [3, 4]], recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj(42)\nERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.Obj","page":"Basics","title":"GAP.Obj","text":"GAP.Obj\n\nThis is an alias for Union{GapObj,FFE,Int64,Bool}. This type union covers all types a \"native\" GAP object may have from Julia's viewpoint.\n\nMoreover, it can be used as a constructor, in order to convert Julia objects to GAP objects, whenever a suitable conversion has been defined.\n\nRecursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.\n\nExamples\n\njulia> GAP.Obj(1//3)\nGAP: 1/3\n\njulia> GAP.Obj([1 2; 3 4])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj([[1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GAP.Obj([[1, 2], [3, 4]], true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj([[1, 2], [3, 4]], recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj(42)\n42\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.GapInt","page":"Basics","title":"GAP.GapInt","text":"GapInt\n\nAny GAP integer object is represented in Julia as either a GapObj (if it is a \"large\" integer) or as an Int (if it is a \"small\" integer). This type union can be used to express this conveniently, e.g. when one wants to help type stability.\n\nNote that also GAP's infinity and -infinity fit under this type (as do many other objects which are not numbers).\n\n\n\n\n\n","category":"type"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"other/#Other-stuff","page":"Other stuff","title":"Other stuff","text":"","category":"section"},{"location":"other/#Macros","page":"Other stuff","title":"Macros","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"@gap\n@g_str\n@gapwrap\n@gapattribute\n@wrap","category":"page"},{"location":"other/#GAP.@gap","page":"Other stuff","title":"GAP.@gap","text":"@gap \n@gap()\n\nExecute directly in GAP, as if GAP.evalstr(\"\") was called. This can be used for creating GAP literals directly from Julia.\n\nExamples\n\njulia> @gap [1,2,3]\nGAP: [ 1, 2, 3 ]\n\njulia> @gap SymmetricGroup(3)\nGAP: Sym( [ 1 .. 3 ] )\n\njulia> @gap(SymmetricGroup)(3)\nGAP: Sym( [ 1 .. 3 ] )\n\n\nNote that the last two examples have a slight syntactical, and therefore also a semantical difference. The first one executes the string SymmetricGroup(3) directly inside GAP. The second example returns the function SymmetricGroup via @gap(SymmetricGroup), then calls that function with the argument 3.\n\nDue to Julia's way of handing over arguments into the code of macros, not all expressions representing valid GAP code can be processed. For example, the GAP syntax of permutations consisting of more than one cycle cause problems, as well as the GAP syntax of non-dense lists.\n\njulia> @gap (1,2,3)\nGAP: (1,2,3)\n\njulia> @gap (1,2)(3,4)\nERROR: LoadError: Error thrown by GAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound\n[...]\n\njulia> @gap [ 1,, 2 ]\nERROR: syntax: unexpected \",\"\n[...]\n\n\nNote also that a string argument gets evaluated with GAP.evalstr.\n\njulia> @gap \"\\\"abc\\\"\"\nGAP: \"abc\"\n\njulia> @gap \"[1,,2]\"\nGAP: [ 1,, 2 ]\n\njulia> @gap \"(1,2)(3,4)\"\nGAP: (1,2)(3,4)\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@g_str","page":"Other stuff","title":"GAP.@g_str","text":"@g_str\n\nCreate a GAP string by typing g\"content\".\n\nExamples\n\njulia> g\"foo\"\nGAP: \"foo\"\n\njulia> g\"ab\\ncd\\\"ef\\\\gh\" # special characters are handled as in GAP\nGAP: \"ab\\ncd\\\"ef\\\\gh\"\n\n\nDue to Julia's way of handing over arguments into the code of macros, not all strings representing valid GAP strings can be processed.\n\njulia> g\"\\\\\"\nERROR: Error thrown by GAP: Syntax error: String must end with \" before end of file in stream:1\n[...]\n\n\nConversely, there are valid arguments for the macro that are not valid Julia strings.\n\njulia> g\"\\c\"\nGAP: \"\\c\"\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@gapwrap","page":"Other stuff","title":"GAP.@gapwrap","text":"@gapwrap\n\nWhen applied to a method definition that involves access to entries of GAP.Globals, this macro rewrites the code such that the relevant GAP globals are cached, and need not be fetched again and again.\n\nExamples\n\njulia> @gapwrap isevenint(x) = GAP.Globals.IsEvenInt(x)::Bool;\n\njulia> isevenint(1)\nfalse\n\njulia> isevenint(2)\ntrue\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@gapattribute","page":"Other stuff","title":"GAP.@gapattribute","text":"@gapattribute\n\nThis macro is intended to be applied to a method definition for a unary function called attr, say, where the argument has the type T, say, the code contains exactly one call of the form GAP.Globals.Something(X), where Something is a GAP attribute such as Centre or IsSolvableGroup, and attr returns the corresponding attribute value for its argument.\n\nThe macro defines three functions attr, has_attr, and set_attr, where attr takes an argument of type T and returns what the given method definition says, has_attr takes an argument of type T and returns the result of GAP.Globals.HasSomething(X) (which is either true or false), set_attr takes an argument of type T and an object obj and calls GAP.Globals.SetSomething(X, obj).\n\nIn order to avoid runtime access via GAP.Globals.Something etc., the same modifications are applied in the construction of the three functions that are applied by @gapwrap.\n\nThe variables that are created by the macro belong to the Julia module in whose scope the macro is called.\n\nExamples\n\njulia> @gapattribute isstrictlysortedlist(obj::GapObj) = GAP.Globals.IsSSortedList(obj)::Bool;\n\njulia> l = GapObj([ 1, 3, 7 ]);\n\njulia> has_isstrictlysortedlist( l )\nfalse\n\njulia> isstrictlysortedlist( l )\ntrue\n\njulia> has_isstrictlysortedlist( l )\ntrue\n\njulia> l = GapObj([ 1, 3, 7 ]);\n\njulia> has_isstrictlysortedlist( l )\nfalse\n\njulia> set_isstrictlysortedlist( l, true )\n\njulia> has_isstrictlysortedlist( l )\ntrue\n\njulia> isstrictlysortedlist( l )\ntrue\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@wrap","page":"Other stuff","title":"GAP.@wrap","text":"@wrap funcdecl\n\nWhen applied to a function declaration of the form NAME(a::T) or NAME(a::T)::S, this macro generates a function which behaves equivalently to NAME(a::T) = GAP.Globals.NAME(a) resp. NAME(a::T) = GAP.Globals.NAME(a)::S, assuming that GAP.Globals.NAME references a GAP function. Function declarations with more than one argument or zero arguments are also supported.\n\nHowever, the generated function actually caches the GAP object GAP.Globals.NAME. This minimizes the call overhead. So @wrap typically is used to provide an optimized way to call certain GAP functions.\n\nAnother use case for this macro is to improve type stability of code calling into GAP, via the type annotations for the arguments and return value contained in the function declaration.\n\nBe advised, though, that if the value of GAP.Globals.NAME is changed later on, the function generated by this macro will not be updated, i.e., it will still reference the original GAP object.\n\nExamples\n\njulia> GAP.@wrap Jacobi(x::GapInt, y::GapInt)::Int\nJacobi (generic function with 1 method)\n\njulia> Jacobi(11,35)\n1\n\n\n\n\n\n","category":"macro"},{"location":"other/#Convenience-adapters","page":"Other stuff","title":"Convenience adapters","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"This section describes how one can manipulate GAP objects from the Julia side, using Julia syntax features.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"In particular, the following is available on the Julia side in order to support special GAP syntax beyond function calls with arguments.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"Call functions with global options via call_gap_func or using Julia's keyword argument syntax. For example, Cyc(1.41421356 : bits:=20) in GAP translates to GAP.Globals.Cyc(GAP.Obj(1.41421356); bits=20) in Julia.\nAccess list/matrix entries via getindex and setindex! respectively the corresponding Julia syntax (described there).\nAccess record components via getproperty and setproperty! respectively the corresponding Julia syntax (described there).\nCheck for bound record components via hasproperty.\nAccess entries of a positional object via getbangindex, equivalent to GAP's ![] operator.\nAccess components of a component object via getbangproperty, equivalent to GAP's !. operator.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"call_gap_func\ncall_with_catch\ngetindex\nsetindex!\ngetbangindex\nsetbangindex!\ngetproperty\nsetproperty!\nhasproperty\ngetbangproperty\nsetbangproperty!\nwrap_rng\nrandseed!","category":"page"},{"location":"other/#GAP.call_gap_func","page":"Other stuff","title":"GAP.call_gap_func","text":"call_gap_func(func::GapObj, args...; kwargs...)\n\nCall the GAP object func as a function, with arguments args... and global GAP options kwargs..., and return the result if there is one, and nothing otherwise.\n\nThere is no argument number checking here, all checks on the arguments are done by GAP itself.\n\nFor convenience, one can use the syntax func(args...; kwargs...).\n\nExamples\n\njulia> GAP.Globals.Factors( 12 )\nGAP: [ 2, 2, 3 ]\n\njulia> GAP.Globals.Cyc(GAP.Obj(1.41421356))\nGAP: 35355339/25000000\n\njulia> GAP.Globals.Cyc(GAP.Obj(1.41421356); bits=20)\nGAP: E(8)-E(8)^3\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.call_with_catch","page":"Other stuff","title":"GAP.call_with_catch","text":"call_with_catch(juliafunc, arguments)\n\nReturn a tuple (ok, val) where ok is either true, meaning that calling the function juliafunc with arguments returns the value val, or false, meaning that the function call runs into an error; in the latter case, val is set to the string of the error message.\n\nExamples\n\njulia> GAP.call_with_catch(sqrt, 2)\n(true, 1.4142135623730951)\n\njulia> flag, res = GAP.call_with_catch(sqrt, -2);\n\njulia> flag\nfalse\n\njulia> startswith(res, \"DomainError\")\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.getindex","page":"Other stuff","title":"Base.getindex","text":"getindex(x::GapObj, i::Int64)\ngetindex(x::GapObj, i::Int64, j::Int64)\ngetindex(x::GapObj, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}\n\nReturn the entry at position i or at position (i,j) in x, or the list of entries in x at the positions described by l, provided that x is a GAP object supporting this, such as a GAP list or matrix object.\n\nExamples\n\njulia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])\nGAP: [ 1, 2, 3, 5, 8, 13 ]\n\njulia> l[4]\n5\n\njulia> l[end]\n13\n\njulia> l[2:4]\nGAP: [ 2, 3, 5 ]\n\njulia> l[[1,4,4]]\nGAP: [ 1, 5, 5 ]\n\njulia> m = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> m[1,1]\n1\n\njulia> m[1,2]\n2\n\njulia> m[2,1]\n3\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.setindex!","page":"Other stuff","title":"Base.setindex!","text":"setindex!(x::GapObj, v::Any, i::Int64)\nsetindex!(x::GapObj, v::Any, i::Int64, j::Int64)\nsetindex!(x::GapObj, v::Any, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}\n\nSet the entry at position i or (i,j) in x to v, or set the entries at the positions in x that are described by l to the entries in v, provided that x is a GAP object supporting this, such as a GAP list or matrix object.\n\nExamples\n\njulia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])\nGAP: [ 1, 2, 3, 5, 8, 13 ]\n\njulia> l[1] = 0\n0\n\njulia> l[8] = -1\n-1\n\njulia> l[2:4] = [ 7, 7, 7 ]\n3-element Vector{Int64}:\n 7\n 7\n 7\n\njulia> l\nGAP: [ 0, 7, 7, 7, 8, 13,, -1 ]\n\njulia> m = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> m[1,2] = 0\n0\n\njulia> m\nGAP: [ [ 1, 0 ], [ 3, 4 ] ]\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.getbangindex","page":"Other stuff","title":"GAP.getbangindex","text":"getbangindex(x::GapObj, i::Int64)\n\nReturn the entry at position i in the positional object x.\n\nExamples\n\njulia> x = GAP.Globals.ZmodnZObj(1, 6)\nGAP: ZmodnZObj( 1, 6 )\n\njulia> GAP.Globals.IsPositionalObjectRep(x)\ntrue\n\njulia> getbangindex(x, 1)\n1\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.setbangindex!","page":"Other stuff","title":"GAP.setbangindex!","text":"setbangindex!(x::GapObj, v::Any, i::Int64)\n\nSet the entry at position i in the positional object x to v, and return x.\n\nExamples\n\njulia> x = GAP.Globals.ZmodnZObj(1, 6)\nGAP: ZmodnZObj( 1, 6 )\n\njulia> GAP.Globals.IsPositionalObjectRep(x)\ntrue\n\njulia> setbangindex!(x, 0, 1)\nGAP: ZmodnZObj( 0, 6 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.getproperty","page":"Other stuff","title":"Base.getproperty","text":"getproperty(x::GapObj, f::Symbol)\ngetproperty(x::GapObj, f::Union{AbstractString,Int64})\n\nReturn the record component of the GAP record x that is described by f.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> r.a\n1\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.setproperty!","page":"Other stuff","title":"Base.setproperty!","text":"setproperty!(x::GapObj, f::Symbol, v)\nsetproperty!(x::GapObj, f::Union{AbstractString,Int64}, v)\n\nSet the record component of the GAP record x that is described by f to the value v.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> r.b = 0\n0\n\njulia> r\nGAP: rec( a := 1, b := 0 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.hasproperty","page":"Other stuff","title":"Base.hasproperty","text":"hasproperty(x::GapObj, f::Symbol)\nhasproperty(x::GapObj, f::Union{AbstractString,Int64})\n\nReturn true if the GAP record x has a component that is described by f, and false otherwise.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> hasproperty( r, :a )\ntrue\n\njulia> hasproperty( r, :b )\nfalse\n\njulia> r.b = 2\n2\n\njulia> hasproperty( r, :b )\ntrue\n\njulia> r\nGAP: rec( a := 1, b := 2 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.getbangproperty","page":"Other stuff","title":"GAP.getbangproperty","text":"getbangproperty(x::GapObj, f::Union{AbstractString,Int64,Symbol})\n\nReturn the value of the component f in the component object x.\n\nExamples\n\njulia> x = GAP.Globals.Iterator(GAP.Globals.Integers)\nGAP: \n\njulia> GAP.Globals.IsComponentObjectRep(x)\ntrue\n\njulia> getbangproperty(x, :counter)\n0\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.setbangproperty!","page":"Other stuff","title":"GAP.setbangproperty!","text":"setbangproperty!(x::GapObj, f::Union{AbstractString,Int64,Symbol}, v)\n\nSet the value of the component f in the component object x to v, and return x.\n\nExamples\n\njulia> x = GAP.Globals.Iterator(GAP.Globals.Integers)\nGAP: \n\njulia> GAP.Globals.IsComponentObjectRep(x)\ntrue\n\njulia> setbangproperty!(x, :counter, 3)\nGAP: \n\njulia> getbangproperty(x, :counter)\n3\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.wrap_rng","page":"Other stuff","title":"GAP.wrap_rng","text":"wrap_rng(rng::Random.AbstractRNG)\n\nReturn a GAP object in the filter IsRandomSource that uses rng in calls to GAP's Random function. The idea is that GAP's Random methods for high level objects will just hand over the given random source to subfunctions until Random gets called for a list or the bounds of a range, and then Base.rand gets called with rng.\n\nExamples\n\njulia> rng1 = Random.default_rng();\n\njulia> rng2 = copy(rng1);\n\njulia> rng1 == rng2\ntrue\n\njulia> rng1 === rng2\nfalse\n\njulia> gap_rng1 = GAP.wrap_rng(rng1)\nGAP: \n\njulia> gap_rng2 = GAP.wrap_rng(rng2)\nGAP: \n\njulia> res1 = GAP.Globals.Random(gap_rng1, 1, 10);\n\njulia> rng1 == rng2 # the two rngs have diverged\nfalse\n\njulia> res1 == GAP.Globals.Random(gap_rng2, GapObj(1:10))\ntrue\n\njulia> rng1 == rng2 # now the two rngs are again in sync\ntrue\n\njulia> g = GAP.Globals.SymmetricGroup(10);\n\njulia> p = GAP.Globals.Random(gap_rng1, g);\n\njulia> p in g\ntrue\n\njulia> GAP.Globals.Random(gap_rng1, GAP.Globals.GF(2)^10)\nGAP: \n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.randseed!","page":"Other stuff","title":"GAP.randseed!","text":"GAP.randseed!([seed::Integer])\n\nReseed GAP's global RNG with seed.\n\nThe given seed must be a non-negative integer. When seed is not specified, a random seed is generated from Julia's global RNG.\n\nFor a fixed seed, the stream of generated numbers is allowed to change between different versions of GAP.\n\n\n\n\n\n","category":"function"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"For the following Julia functions, methods are provided that deal with the case that the arguments are GAP objects; they delegate to the corresponding GAP operations.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"Julia GAP\nlength Length\nin \\in\nzero ZeroSameMutability\none OneSameMutability\n- (unary) AdditiveInverseSameMutability\ninv InverseSameMutability\n+ SUM\n- (binary) DIFF\n* PROD\n/ QUO\n\\ LQUO\n^ POW\nmod MOD\n< LT\n== EQ","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"The reason why four SameMutability operations are chosen in this list is as follows. In GAP, binary arithmetic operations return immutable results if and only if the two arguments are immutable. Thus it is consistent if unary arithmetic operations return a result with the same mutability as the argument. Note that GAP provides several variants of these unary operations, regarding the mutability of the result (ZeroMutable, ZeroImmutable, ZeroSameMutability, etc.), but here we have to choose one behaviour for the Julia function.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"julia> l = GAP.julia_to_gap( [ 1, 3, 7, 15 ] )\nGAP: [ 1, 3, 7, 15 ]\n\njulia> m = GAP.julia_to_gap( [ 1 2; 3 4 ] )\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> length( l )\n4\n\njulia> length( m ) # different from Julia's behaviour\n2\n\njulia> 1 in l\ntrue\n\njulia> 2 in l\nfalse\n\njulia> zero( l )\nGAP: [ 0, 0, 0, 0 ]\n\njulia> one( m )\nGAP: [ [ 1, 0 ], [ 0, 1 ] ]\n\njulia> - l\nGAP: [ -1, -3, -7, -15 ]\n\njulia> l + 1\nGAP: [ 2, 4, 8, 16 ]\n\njulia> l + l\nGAP: [ 2, 6, 14, 30 ]\n\njulia> m + m\nGAP: [ [ 2, 4 ], [ 6, 8 ] ]\n\njulia> 1 - m\nGAP: [ [ 0, -1 ], [ -2, -3 ] ]\n\njulia> l * l\n284\n\njulia> l * m\nGAP: [ 10, 14 ]\n\njulia> m * m\nGAP: [ [ 7, 10 ], [ 15, 22 ] ]\n\njulia> 1 / m\nGAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]\n\njulia> m / 2\nGAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]\n\njulia> 2 \\ m\nGAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]\n\njulia> m ^ 2\nGAP: [ [ 7, 10 ], [ 15, 22 ] ]\n\njulia> m ^ -1\nGAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]\n\njulia> mod( l, 3 )\nGAP: [ 1, 0, 1, 0 ]\n\njulia> m < 2 * m\ntrue\n\njulia> m^2 - 5 * m == 2 * one( m )\ntrue\n","category":"page"},{"location":"other/#Access-to-the-GAP-help-system","page":"Other stuff","title":"Access to the GAP help system","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"show_gap_help","category":"page"},{"location":"other/#GAP.show_gap_help","page":"Other stuff","title":"GAP.show_gap_help","text":"show_gap_help(topic::String, onlyexact::Bool = false)\n\nPrint the information from the GAP help system about topic to the screen. If onlyexact is true then only exact matches are shown, otherwise all matches. For example, GAP.show_gap_help(\"Size\") shows also documentation for SizeScreen and SizesPerfectGroups, whereas GAP.show_gap_help(\"Size\", true) shows only documentation for Size.\n\nFor the variant showing all matches, one can also enter ?GAP.Globals.Size at the Julia prompt instead of calling show_gap_help.\n\nExamples\n\njulia> GAP.show_gap_help( \"Size\" )\n[...] # more than 50 entries from GAP manuals\n\nhelp?> GAP.Globals.Size\n[...] # the same\n\njulia> GAP.show_gap_help( \"Size\", true )\n[...] # about 15 entries from GAP manuals\n\n\n\n\n\n\n","category":"function"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"packages/#Managing-GAP-packages","page":"Managing GAP packages","title":"Managing GAP packages","text":"","category":"section"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"The following functions allow one to load/install/update/remove GAP packages.","category":"page"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"GAP.Packages.load\nGAP.Packages.install\nGAP.Packages.update\nGAP.Packages.remove","category":"page"},{"location":"packages/#GAP.Packages.load","page":"Managing GAP packages","title":"GAP.Packages.load","text":"load(spec::String, version::String = \"\"; install::Bool = false, quiet::Bool = true)\n\nTry to load the GAP package given by spec, which can be either the name of the package or a local path where the package is installed (a directory that contains the package's PackageInfo.g file).\n\nIf version is specified then try to load a version of the package that is compatible with version, in the sense of GAP's CompareVersionNumbers function, otherwise try to load the newest installed version. Return true if this is successful, and false otherwise.\n\nIf install is set to true and (the desired version of) the required GAP package is not yet installed and spec is the package name then install is called first, in order to install the package; if no version is prescribed then the newest released version of the package will be installed.\n\nThe function calls GAP's LoadPackage function. If quiet is set to false then package banners are shown for all packages being loaded. It is also passed on to install.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.install","page":"Managing GAP packages","title":"GAP.Packages.install","text":"install(spec::String, version::String = \"\";\n interactive::Bool = true, quiet::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nDownload and install the GAP package given by spec into the pkgdir directory.\n\nspec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.\n\nIf spec is the name of a package then the package version can be specified by version, in the format described for GAP's CompareVersionNumbers function. In all other cases the newest released version of the package will get installed.\n\nReturn true if the installation is successful or if (a version compatible with version) of the package was already installed, and false otherwise.\n\nThe function uses the function InstallPackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.update","page":"Managing GAP packages","title":"GAP.Packages.update","text":"update(spec::String; interactive::Bool = true, quiet::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nUpdate the GAP package given by spec that is installed in the pkgdir directory, to the latest version. Return true if a newer version was installed successfully, or if no newer version is available, and false otherwise.\n\nspec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.\n\nThe function uses the function UpdatePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.remove","page":"Managing GAP packages","title":"GAP.Packages.remove","text":"remove(spec::String; interactive::Bool = true, quiet::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nRemove the GAP package with name spec that is installed in the pkgdir directory. Return true if the removal was successful, and false otherwise.\n\nThe function uses the function RemovePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"#GAP.jl","page":"GAP.jl","title":"GAP.jl","text":"","category":"section"},{"location":"#Introduction","page":"GAP.jl","title":"Introduction","text":"","category":"section"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"GAP.jl is a low level interface from Julia to the computer algebra system GAP. The term \"low level\" means that the aim is to give Julia access to all GAP objects, to let Julia call GAP functions, and to provide conversions of low level data (integers, Booleans, strings, arrays/lists, dictionaries/records) between the two systems.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"In particular, it is not the aim of GAP.jl to provide Julia types for higher level GAP objects that represent algebraic structures, such as groups, rings, fields, etc., and mappings between such structures.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"The connection between GAP and Julia is in fact bidirectional, that is, GAP can access all Julia objects, call Julia functions, and perform conversions of low level data. This direction will become interesting on the Julia side as soon as GAP packages provide functionality that is based on using Julia code from the GAP side.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"The viewpoint of an interface from GAP to Julia is described in the manual of the GAP package JuliaInterface.","category":"page"},{"location":"#Table-of-contents","page":"GAP.jl","title":"Table of contents","text":"","category":"section"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"Pages = GAP.GAP_docs_pages","category":"page"}] +[{"location":"conversion/","page":"Conversions","title":"Conversions","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"conversion/#Conversions","page":"Conversions","title":"Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"One of the main ideas of GAP.jl is that automatic conversions of Julia objects to GAP objects and vice versa shall be avoided whenever this is possible. For a few types of objects, such conversions are unavoidable, see Automatic GAP-to-Julia and Julia-to-GAP Conversions. In all other situations, the conversions between GAP objects and corresponding Julia objects can be performed using gap_to_julia and julia_to_gap, see Explicit GAP-to-Julia and Julia-to-GAP Conversions, respectively.","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"For convenience, also constructor methods are provided, for example Vector{Int64}(obj) can be used instead of GAP.gap_to_julia(Vector{Int64}, obj), where obj is a GAP list of integers; see Constructor Methods for GAP-to-Julia Conversions for a description of these methods. For Julia-to-GAP conversions, one can use for example GapObj(obj), where obj is a Julia object, see GapObj.","category":"page"},{"location":"conversion/#Automatic-GAP-to-Julia-and-Julia-to-GAP-Conversions","page":"Conversions","title":"Automatic GAP-to-Julia and Julia-to-GAP Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"When one calls a GAP function with Julia objects as arguments, or a Julia function with GAP objects as arguments, the arguments are in general not automatically converted to GAP objects or Julia objects, respectively. The exceptions are as follows.","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"GAP's immediate integers (in the range -2^60 to 2^60-1) are automatically converted to Julia's Int64 objects; Julia's Int64 objects are automatically converted to GAP's immediate integers if they fit, and to GAP's large integers otherwise.\nGAP's immediate finite field elements are automatically converted to Julia's GAP.FFE objects, and vice versa.\nGAP's true and false are automatically converted to Julia's true and false, and vice versa.","category":"page"},{"location":"conversion/#Explicit-GAP-to-Julia-and-Julia-to-GAP-Conversions","page":"Conversions","title":"Explicit GAP-to-Julia and Julia-to-GAP Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"gap_to_julia\njulia_to_gap","category":"page"},{"location":"conversion/#GAP.gap_to_julia","page":"Conversions","title":"GAP.gap_to_julia","text":"gap_to_julia(type, x, recursion_dict::Union{Nothing,RecDict}=nothing; recursive::Bool=true)\n\nTry to convert the object x to a Julia object of type type. If x is a GapObj then the conversion rules are defined in the manual of the GAP package JuliaInterface. If x is another GAP.Obj (for example a Int64) then the result is defined in Julia by type.\n\nThe parameter recursion_dict is used to preserve the identity of converted subobjects and should never be given by the user.\n\nFor GAP lists and records, it makes sense to convert also the subobjects recursively, or to keep the subobjects as they are; the behaviour is controlled by recursive, which can be true or false.\n\nExamples\n\njulia> GAP.gap_to_julia(GapObj(1//3))\n1//3\n\njulia> GAP.gap_to_julia(GapObj(\"abc\"))\n\"abc\"\n\njulia> val = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.gap_to_julia( val )\n2-element Vector{Any}:\n Any[1, 2]\n Any[3, 4]\n\njulia> GAP.gap_to_julia( val, recursive = false )\n2-element Vector{Any}:\n GAP: [ 1, 2 ]\n GAP: [ 3, 4 ]\n\njulia> GAP.gap_to_julia( Vector{GapObj}, val )\n2-element Vector{GapObj}:\n GAP: [ 1, 2 ]\n GAP: [ 3, 4 ]\n\njulia> GAP.gap_to_julia( Matrix{Int}, val )\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\nThe following gap_to_julia conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more GAP objects.)\n\nGAP filter default Julia type other Julia types\nIsInt BigInt `T <: Integer\nIsFFE GapFFE \nIsBool Bool \nIsRat Rational{BigInt} `Rational{T}\nIsFloat Float64 `T <: AbstractFloat\nIsChar Cuchar Char\nIsStringRep String Symbol, Vector{T}\nIsRangeRep StepRange{Int64,Int64} Vector{T}\nIsBListRep BitVector Vector{T}\nIsList Vector{Any} Vector{T}\nIsVectorObj Vector{Any} Vector{T}\nIsMatrixObj Matrix{Any} Matrix{T}\nIsRecord Dict{Symbol, Any} Dict{Symbol, T}\n\n\n\n\n\n","category":"function"},{"location":"conversion/#GAP.julia_to_gap","page":"Conversions","title":"GAP.julia_to_gap","text":"julia_to_gap(input, recursion_dict = IdDict(); recursive::Bool = false)\n\nConvert a julia object input to an appropriate GAP object. If recursive is set to true, recursive conversions on arrays, tuples, and dictionaries is performed.\n\nThe input recursion_dict should never be set by the user, it is meant to keep egality of input data, by converting equal data to identical objects in GAP.\n\nExamples\n\njulia> GAP.julia_to_gap(1//3)\nGAP: 1/3\n\njulia> GAP.julia_to_gap(\"abc\")\nGAP: \"abc\"\n\njulia> GAP.julia_to_gap([ [1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GAP.julia_to_gap([ [1, 2], [3, 4]], recursive = true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\n\nThe following julia_to_gap conversions are supported by GAP.jl. (Other Julia packages may provide conversions for more Julia objects.)\n\nJulia type GAP filter\nInt8, Int16, ..., BigInt IsInt\nGapFFE IsFFE\nBool IsBool\nRational{T} IsRat\nFloat16, Float32, Float64 IsFloat\nAbstractString IsString\nSymbol IsString\nChar IsChar\nVector{T} IsList\nVector{Bool}, BitVector IsBList\nTuple{T} IsList\nMatrix{T} IsList\nDict{String, T}, Dict{Symbol, T} IsRecord\nUnitRange{T}, StepRange{T, S} IsRange\nFunction IsFunction\n\n\n\n\n\n","category":"function"},{"location":"conversion/#Constructor-Methods-for-GAP-to-Julia-Conversions","page":"Conversions","title":"Constructor Methods for GAP-to-Julia Conversions","text":"","category":"section"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"(For Julia-to-GAP conversions, one can use GapObj and GAP.Obj as constructors.)","category":"page"},{"location":"conversion/","page":"Conversions","title":"Conversions","text":"Int128\nBigInt\nRational\nFloat64\nChar\nCuchar\nString\nSymbol\nUnitRange\nStepRange\nTuple\nBitVector\nVector{T}\nMatrix{T}\nSet{T}\nDict{Symbol,T}","category":"page"},{"location":"conversion/#Core.Int128","page":"Conversions","title":"Core.Int128","text":"Int128(obj::GapObj)\n\nReturn the Int128 converted from the GAP integer obj. (Note that small GAP integers are represented by Julia Int64 objects, in particular they are not GapObjs; their conversion is not handled by methods installed in GAP.jl.)\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> Int128(val)\n15511210043330985984000000\n\njulia> Int(val)\nERROR: InexactError: Int64(15511210043330985984000000)\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.GMP.BigInt","page":"Conversions","title":"Base.GMP.BigInt","text":"BigInt(obj::GapObj)\n\nReturn the big integer converted from the GAP integer obj. (Note that small GAP integers are not represented by GapObjs, their conversion with BigInt is handled by Julia's methods.)\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> BigInt(val)\n15511210043330985984000000\n\njulia> val = GAP.Globals.Factorial(10)\n3628800\n\njulia> isa(val, GapObj)\nfalse\n\njulia> BigInt(val)\n3628800\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Rational","page":"Conversions","title":"Base.Rational","text":"Rational{T}(obj::GapObj) where {T<:Integer}\n\nReturn the rational converted from the GAP integer or the GAP rational obj,\n\nExamples\n\njulia> val = GAP.Globals.Factorial(25)\nGAP: 15511210043330985984000000\n\njulia> Rational{Int128}(val)\n15511210043330985984000000//1\n\njulia> Rational{BigInt}(val)\n15511210043330985984000000//1\n\njulia> val = GAP.Obj(1//3)\nGAP: 1/3\n\njulia> Rational{Int64}(val)\n1//3\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Float64","page":"Conversions","title":"Core.Float64","text":"Float64(obj::GapObj)\n\nReturn the float converted from the GAP float obj.\n\nExamples\n\njulia> val = GAP.Obj(2.2)\nGAP: 2.2\n\njulia> Float64(val)\n2.2\n\njulia> Float32(val)\n2.2f0\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Char","page":"Conversions","title":"Core.Char","text":"Char(obj::GapObj)\n\nReturn the character converted from the GAP character obj.\n\nExamples\n\njulia> val = GAP.Obj('x')\nGAP: 'x'\n\njulia> Char(val)\n'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Cuchar","page":"Conversions","title":"Base.Cuchar","text":"Cuchar(obj::GapObj)\n\nReturn the UInt8 that belongs to the GAP character obj.\n\nExamples\n\njulia> val = GAP.Obj('x')\nGAP: 'x'\n\njulia> Cuchar(val)\n0x78\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.String","page":"Conversions","title":"Core.String","text":"String(obj::GapObj)\n\nReturn the Julia string converted from the GAP string obj. Note that GAP's String function can be applied to arbitrary GAP objects, similar to Julia's string function; this behaviour is not intended for this String constructor.\n\nExamples\n\njulia> val = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> String(val)\n\"abc\"\n\njulia> val = GAP.Obj([])\nGAP: [ ]\n\njulia> String(val) # an empty GAP list is a string\n\"\"\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Symbol","page":"Conversions","title":"Core.Symbol","text":"Symbol(obj::GapObj)\n\nReturn the symbol converted from the GAP string obj.\n\nExamples\n\njulia> str = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> Symbol(str)\n:abc\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.UnitRange","page":"Conversions","title":"Base.UnitRange","text":"UnitRange(obj::GapObj)\n\nReturn the unit range converted from the GAP range obj, which has step width 1.\n\nExamples\n\njulia> val = GAP.Obj(1:10)\nGAP: [ 1 .. 10 ]\n\njulia> UnitRange(val)\n1:10\n\njulia> UnitRange{Int32}(val)\n1:10\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.StepRange","page":"Conversions","title":"Base.StepRange","text":"StepRange(obj::GapObj)\n\nReturn the step range converted from the GAP range obj, which may have arbitrary step width.\n\nExamples\n\njulia> val = GAP.Obj(1:2:11)\nGAP: [ 1, 3 .. 11 ]\n\njulia> StepRange(val)\n1:2:11\n\njulia> r = StepRange{Int8,Int8}(val)\n1:2:11\n\njulia> typeof(r)\nStepRange{Int8, Int8}\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Core.Tuple","page":"Conversions","title":"Core.Tuple","text":"Tuple{Types...}(obj::GapObj; recursive::Bool = true)\n\nReturn the tuple converted from the GAP list obj. The entries of the list are converted to the required types Types..., using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.\n\nExamples\n\njulia> val = GAP.Obj([1, 5])\nGAP: [ 1, 5 ]\n\njulia> Tuple{Int64,Int64}(val)\n(1, 5)\n\njulia> val = GAP.Obj([[1], [2]]; recursive=true)\nGAP: [ [ 1 ], [ 2 ] ]\n\njulia> Tuple{Any,Any}(val)\n(Any[1], Any[2])\n\njulia> Tuple{GapObj,GapObj}(val; recursive=false)\n(GAP: [ 1 ], GAP: [ 2 ])\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.BitVector","page":"Conversions","title":"Base.BitVector","text":"BitVector(obj::GapObj)\n\nReturn the bit vector converted from the GAP list of booleans obj.\n\nExamples\n\njulia> val = GAP.Obj([true, false, true])\nGAP: [ true, false, true ]\n\njulia> BitVector(val)\n3-element BitVector:\n 1\n 0\n 1\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Vector","page":"Conversions","title":"Base.Vector","text":"Vector{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the 1-dimensional array converted from the GAP list obj. The entries of the list are converted to the type T, using gap_to_julia. If recursive is true then the entries of the list are converted recursively, otherwise non-recursively.\n\nIf T is UInt8 then obj may be a GAP string.\n\nExamples\n\njulia> val = GAP.Obj([[1], [2]]; recursive=true)\nGAP: [ [ 1 ], [ 2 ] ]\n\njulia> Vector{Any}(val)\n2-element Vector{Any}:\n Any[1]\n Any[2]\n\njulia> Vector{Any}(val; recursive=false)\n2-element Vector{Any}:\n GAP: [ 1 ]\n GAP: [ 2 ]\n\njulia> Vector{Vector{Int64}}(val)\n2-element Vector{Vector{Int64}}:\n [1]\n [2]\n\njulia> val = GAP.evalstr( \"NewVector( IsPlistVectorRep, Integers, [ 0, 2, 5 ] )\" )\nGAP: \n\njulia> Vector{Int64}(val)\n3-element Vector{Int64}:\n 0\n 2\n 5\n\njulia> val = GAP.Obj(\"abc\")\nGAP: \"abc\"\n\njulia> Vector{UInt8}(val)\n3-element Vector{UInt8}:\n 0x61\n 0x62\n 0x63\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Matrix","page":"Conversions","title":"Base.Matrix","text":"Matrix{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the 2-dimensional array converted from the GAP matrix obj, which can be a GAP list of lists or a GAP matrix object. The entries of the matrix are converted to the type T, using gap_to_julia. If recursive is true then the entries are converted recursively, otherwise non-recursively.\n\nExamples\n\njulia> val = GAP.Obj([[1, 2], [3, 4]]; recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> Matrix{Int64}(val)\n2×2 Matrix{Int64}:\n 1 2\n 3 4\n\njulia> val = GAP.evalstr( \"NewMatrix( IsPlistMatrixRep, Integers, 2, [ 0, 1, 2, 3 ] )\" )\nGAP: <2x2-matrix over Integers>\n\njulia> Matrix{Int64}(val)\n2×2 Matrix{Int64}:\n 0 1\n 2 3\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Set","page":"Conversions","title":"Base.Set","text":"Set{T}(obj::GapObj; recursive::Bool = true)\n\nReturn the set converted from the GAP list or GAP collection obj. The elements of obj are converted to the required type T, using gap_to_julia. If recursive is true then the elements are converted recursively, otherwise non-recursively.\n\nThis constructor method is intended for situations where the result involves only native Julia objects such as integers and strings. Dealing with results containing GAP objects will be inefficient.\n\nExamples\n\njulia> Set{Int}(GAP.Obj([1, 2, 1]))\nSet{Int64} with 2 elements:\n 2\n 1\n\njulia> Set{Vector{Int}}(GAP.Obj([[1], [2], [1]]; recursive=true))\nSet{Vector{Int64}} with 2 elements:\n [1]\n [2]\n\njulia> Set{String}(GAP.Obj([\"a\", \"b\"]; recursive=true))\nSet{String} with 2 elements:\n \"b\"\n \"a\"\n\njulia> Set{Any}(GAP.Obj([[1], [2], [1]]; recursive=true))\nSet{Any} with 2 elements:\n Any[1]\n Any[2]\n\nIn the following examples, the order in which the Julia output is shown may vary.\n\nExamples\n\njulia> s = Set{Any}(GAP.Obj([[1], [2], [1]]; recursive=true); recursive=false);\n\njulia> s == Set{Any}([GAP.Obj([1]), GAP.Obj([2])])\ntrue\n\njulia> s = Set{Any}(GAP.Globals.SymmetricGroup(2); recursive=false);\n\njulia> s == Set{Any}([GAP.evalstr(\"()\"), GAP.evalstr(\"(1,2)\")])\ntrue\n\n\n\n\n\n\n","category":"type"},{"location":"conversion/#Base.Dict","page":"Conversions","title":"Base.Dict","text":"Dict{Symbol,T}(obj::GapObj; recursive::Bool = true)\n\nReturn the dictionary converted from the GAP record obj. If recursive is true then the values of the record components are recursively converted to objects of the type T, using gap_to_julia, otherwise they are kept as they are.\n\nExamples\n\njulia> val = GAP.Obj(Dict(:a => 1, :b => 2))\nGAP: rec( a := 1, b := 2 )\n\njulia> Dict{Symbol,Int}(val)\nDict{Symbol, Int64} with 2 entries:\n :a => 1\n :b => 2\n\njulia> val = GAP.Obj(Dict(:l => GAP.Obj([1, 2])))\nGAP: rec( l := [ 1, 2 ] )\n\njulia> Dict{Symbol,Any}(val; recursive=false)\nDict{Symbol, Any} with 1 entry:\n :l => GAP: [ 1, 2 ]\n\njulia> Dict{Symbol,Any}(val; recursive=true)\nDict{Symbol, Any} with 1 entry:\n :l => Any[1, 2]\n\njulia> Dict{Symbol,Vector{Int}}(val; recursive=true)\nDict{Symbol, Vector{Int64}} with 1 entry:\n :l => [1, 2]\n\n\n\n\n\n\n","category":"type"},{"location":"manualindex/#Index","page":"Index","title":"Index","text":"","category":"section"},{"location":"manualindex/","page":"Index","title":"Index","text":"","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Analyzing-Rubik's-Cube-using-GAP.jl","page":"Examples","title":"Analyzing Rubik's Cube using GAP.jl","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"The following Julia session shows the GAP computations from the Rubik's Cube example from the GAP webpages.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We consider the group of transformations of Rubik's magic cube. If we number the faces of this cube as follows","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":" +--------------+\n | |\n | 1 2 3 |\n | |\n | 4 top 5 |\n | |\n | 6 7 8 |\n | |\n +--------------+--------------+--------------+--------------+\n | | | | |\n | 9 10 11 | 17 18 19 | 25 26 27 | 33 34 35 |\n | | | | |\n | 12 left 13 | 20 front 21 | 28 right 29 | 36 rear 37 |\n | | | | |\n | 14 15 16 | 22 23 24 | 30 31 32 | 38 39 40 |\n | | | | |\n +--------------+--------------+--------------+--------------+\n | |\n | 41 42 43 |\n | |\n | 44 bottom 45 |\n | |\n | 46 47 48 |\n | |\n +--------------+","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"then the group is generated by the following generators, corresponding to the six faces of the cube.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube = @gap(\"Group(\n ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),\n ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),\n (17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),\n (25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),\n (33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),\n (41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40) );\")\nGAP: ","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"First we want to know the size of this group.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube_size = GAP.Globals.Size(cube)\nGAP: 43252003274489856000","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Since this is a little bit unhandy, let us factorize this number.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cf = GAP.Globals.Collected(GAP.Globals.Factors(cube_size))\nGAP: [ [ 2, 27 ], [ 3, 14 ], [ 5, 3 ], [ 7, 2 ], [ 11, 1 ] ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"(The result tells us that the size is 2^27 3^14 5^3 7^2 11.)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"In order to convert this GAP list to Julia, we can either use gap_to_julia or a suitable Vector constructor, see Conversions. Note that the one-argument version of the former returns a vector of Any objects.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.gap_to_julia(cf)\n5-element Vector{Any}:\n Any[2, 27]\n Any[3, 14]\n Any[5, 3]\n Any[7, 2]\n Any[11, 1]\n\njulia> Vector{Vector{Int}}(cf)\n5-element Vector{Vector{Int64}}:\n [2, 27]\n [3, 14]\n [5, 3]\n [7, 2]\n [11, 1]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Next let us investigate the operation of the group on the 48 points.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> orbs = GAP.Globals.Orbits(cube, GAP.GapObj(1:48))\nGAP: [ [ 1, 3, 17, 14, 8, 38, 9, 41, 19, 48, 22, 6, 30, 33, 43, 11, 46, 40, 24, 27, 25, 35, 16, 32 ], [ 2, 5, 12, 7, 36, 10, 47, 4, 28, 45, 34, 13, 29, 44, 20, 42, 26, 21, 37, 15, 31, 18, 23, 39 ] ]\n\njulia> length(orbs)\n2","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The first orbit contains the points at the corners, the second those at the edges; clearly the group cannot move a point at a corner onto a point at an edge.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"So to investigate the cube group we first investigate the operation on the corner points. Note that the constructed group that describes this operation will operate on the set [1..24], not on the original set orbs[1].","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube1 = GAP.Globals.Action(cube, orbs[1])\nGAP: \n\njulia> GAP.Globals.NrMovedPoints(cube1)\n24\n\njulia> GAP.Globals.Size(cube1)\n88179840","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Now this group obviously operates transitively, but let us test whether it is also primitive.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> corners = GAP.Globals.Blocks(cube1, GAP.Globals.MovedPoints(cube1))\nGAP: [ [ 1, 7, 22 ], [ 2, 14, 20 ], [ 3, 12, 16 ], [ 4, 17, 18 ], [ 5, 9, 21 ], [ 6, 10, 24 ], [ 8, 11, 23 ], [ 13, 15, 19 ] ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Those eight blocks correspond to the eight corners of the cube; on the one hand the group permutes those and on the other hand it permutes the three points at each corner cyclically.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> blockhom1 = GAP.Globals.ActionHomomorphism(cube1, corners, GAP.Globals.OnSets)\nGAP: \n\njulia> cube1b = GAP.Globals.Image(blockhom1)\nGAP: Group([ (1,2,4,3), (1,3,6,5), (1,5,8,2), (3,4,7,6), (5,6,7,8), (2,8,7,4) ])\n\njulia> GAP.Globals.Size(cube1b)\n40320","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Now a permutation group of degree 8 that has order 40320 must be the full symmetric group Sym(8) on eight points.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The next thing then is to investigate the kernel of this operation on blocks, i.e., the subgroup of cube1 of those elements that fix the blocks setwise.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> ker1 = GAP.Globals.Kernel(blockhom1)\nGAP: \n\njulia> println(Vector{Int}(GAP.Globals.Factors(GAP.Globals.Size(ker1))))\n[3, 3, 3, 3, 3, 3, 3]\n\njulia> GAP.Globals.IsElementaryAbelian(ker1)\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We can show that the product of this elementary abelian group 3^7 with the Sym(8) is semidirect by finding a complement, i.e., a subgroup that has trivial intersection with the kernel and that generates cube1 together with the kernel.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cmpl1 = GAP.Globals.ComplementClassesRepresentatives(cube1, ker1)\nGAP: [ ]\n\njulia> cmpl1 = cmpl1[1]; GAP.Globals.Size(cmpl1)\n40320","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We verify the complement properties:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.Size(GAP.Globals.Intersection(cmpl1, ker1))\n1\n\njulia> GAP.Globals.ClosureGroup(cmpl1, ker1) == cube1\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"There is even a more elegant way to show that cmpl1 is a complement.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.IsBijective(GAP.Globals.RestrictedMapping(blockhom1, cmpl1))\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Of course, theoretically it is clear that cmpl1 must indeed be a complement.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"In fact we know that cube1 is a subgroup of index 3 in the wreath product of a cyclic 3 with Sym(8). This missing index 3 tells us that we do not have total freedom in turning the corners. The following tests show that whenever we turn one corner clockwise we must turn another corner counterclockwise.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(1, 7, 22)\") in cube1\nfalse\n\njulia> @gap(\"(1, 7, 22)(2, 20, 14)\") in cube1\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"More or less the same things happen when we consider the operation of the cube group on the edges.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> cube2 = GAP.Globals.Action(cube, orbs[2]); GAP.Globals.Size(cube2)\n980995276800\n\njulia> edges = GAP.Globals.Blocks(cube2, GAP.Globals.MovedPoints(cube2))\nGAP: [ [ 1, 11 ], [ 2, 17 ], [ 3, 19 ], [ 4, 22 ], [ 5, 13 ], [ 6, 8 ], [ 7, 24 ], [ 9, 18 ], [ 10, 21 ], [ 12, 15 ], [ 14, 20 ], [ 16, 23 ] ]\n\njulia> blockhom2 = GAP.Globals.ActionHomomorphism(cube2, edges, GAP.Globals.OnSets);\n\njulia> cube2b = GAP.Globals.Image(blockhom2); GAP.Globals.Size(cube2b)\n479001600\n\njulia> ker2 = GAP.Globals.Kernel(blockhom2)\nGAP: \n\njulia> GAP.Globals.Factors(GAP.Globals.Size(ker2))\nGAP: [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]\n\njulia> GAP.Globals.IsElementaryAbelian(ker2)\ntrue\n\njulia> cmpl2 = GAP.Globals.ComplementClassesRepresentatives(cube2, ker2); length(cmpl2)\n4","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"So there are even 4 classes of complements here. This time we get a semidirect product of a 2^11 with an Sym(12), namely a subgroup of index 2 of the wreath product of a cyclic 2 with Sym(12). Here the missing index 2 tells us again that we do not have total freedom in turning the edges. The following tests show that whenever we flip one edge we must also flip another edge.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(1, 11)\") in cube2\nfalse\n\njulia> @gap(\"(1, 11)(2, 17)\") in cube2\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Since cube1 and cube2 are the groups describing the actions on the two orbits of cube, it is clear that cube is a subdirect product of those groups, i.e., a subgroup of the direct product. Comparing the sizes of cube1, cube2, and cube we see that cube must be a subgroup of index 2 in the direct product of those two groups.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> BigInt(GAP.Globals.Size(cube1)) * BigInt(GAP.Globals.Size(cube2))\n86504006548979712000\n\njulia> GAP.Globals.Size(cube)\nGAP: 43252003274489856000","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"(Note that both GAP.Globals.Size(cube1) and GAP.Globals.Size(cube2) have the Julia type Int64, and forming their product yields an overflow. In order to obtain the correct value we have created arbitrary precision integers for the two values before multiplying them.)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This final missing index 2 tells us that we cannot operate on corners and edges totally independently. The following tests show that whenever we exchange a pair of corners we must also exchange a pair of edges (and vice versa).","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> @gap(\"(17, 19)(11, 8)(6, 25)\") in cube\nfalse\n\njulia> @gap(\"(7, 28)(18, 21)\") in cube\nfalse\n\njulia> @gap(\"(17, 19)(11, 8)(6, 25)(7, 28)(18, 21)\") in cube\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"As a last part of the structure analysis of the cube group let us compute the centre of the cube group, i.e., the subgroup of those operations that can be performed either before or after any other operation with the same result.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> z = GAP.Globals.Centre(cube)\nGAP: Group([ (2,34)(4,10)(5,26)(7,18)(12,37)(13,20)(15,44)(21,28)(23,42)(29,36)(31,45)(39,47) ])","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"We see that the centre contains one nontrivial element, namely the operation that flips all 12 edges simultaneously.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Finally we turn to the original idea connected with the cube, namely to find a sequence of turns of the faces that will transform the cube back into its original state. This amounts to a decomposition of a given element of the cube group into a product of the generators. For this purpose we introduce a free group and a homomorphism of it onto the cube group.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> f = GAP.Globals.FreeGroup(GAP.GapObj([\"t\", \"l\", \"f\", \"r\", \"e\", \"b\"], recursive = true))\nGAP: \n\njulia> fhom = GAP.Globals.GroupHomomorphismByImages(f, cube)\nGAP: [ t, l, f, r, e, b ] -> [ (1,3,8,6)(2,5,7,4)(9,33,25,17)(10,34,26,18)(11,35,27,19), (1,17,41,40)(4,20,44,37)(6,22,46,35)(9,11,16,14)(10,13,15,12), (6,25,43,16)(7,28,42,13)(8,30,41,11)(17,19,24,22)(18,21,23,20), (3,38,43,19)(5,36,45,21)(8,33,48,24)(25,27,32,30)(26,29,31,28), (1,14,48,27)(2,12,47,29)(3,9,46,32)(33,35,40,38)(34,37,39,36), (14,22,30,38)(15,23,31,39)(16,24,32,40)(41,43,48,46)(42,45,47,44) ]","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Using this homomorphism, we can now decompose elements into generators. The method used utilizes a stabilizer chain and does not enumerate all group elements, therefore the words obtained are not the shortest possible, though they are short enough for hand solutions.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"The computed decompositions may be different in different sessions, because they involve the computation of pseudo random elements. Therefore the results shown in the following may look different in actual Julia sessions.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"First we decompose the nonidentity centre element:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> zgen = GAP.Globals.GeneratorsOfGroup(z)[1]\nGAP: (2,34)(4,10)(5,26)(7,18)(12,37)(13,20)(15,44)(21,28)(23,42)(29,36)(31,45)(39,47)\n\njulia> pre1 = GAP.Globals.PreImagesRepresentative(fhom, zgen)\nGAP: t^-1*l*t*l^-1*e^-1*t*f^-1*e*l*f*(t^-1*l^-1)^2*t*l*f*t*r*t^-1*r^-1*f^-1*l^-1*e^-1*t^-1*e*t*l*t*f*t*r*t^-1*r^-1*f^-1*t^-2*f*t^-1*f^-1*t^2*e*l^-1*e^-1*t^-1*l*t*l*f*t^-1*f^-1*l^-1*t*l*t^2*l^-1*t^-1*l*t^-1*l^-1*t^2*f^-1*l^-1*t^-1*l*t*f*t*l^-1*t*l*f^-1*l*f*l^-1*t^-2*l^-1*f^-1*l*f*l*t*e^-1*t*e*l*t*l^-1*e*l*e^-1*t^-1*f*l*f*l^-1*f^-1*t^-2*f^-1*t*l^-1*f*t^-2*f^-2*b*r^-1*b^-1*t^-2*e^-1*r^-2*e*t^-1*r*b*e^-1*b^-1*l^-1*r^-2*t^-2*l^-1*b^-1*r^-1*e^-1\n\njulia> length(pre1)\n134","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Next we decompose some element arbitrarily chosen by us:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> pre2 = GAP.Globals.PreImagesRepresentative(fhom, @gap(\"(17, 19)(11, 8)(6, 25)(7, 28)(18, 21)\"))\nGAP: l^-1*t^-1*l*f*r*t*r^-1*f^-1*l*t*f*t^-1*f^-1*l^-1*t^2*f*t*l*t*l^-1*f^-1*l*t^-1*l^-1*f*t^-1*f^-1*l*t*l^-1*t*l*t^-2*l^-1*f*(t*r*t^-1*r^-1)^2*f^-1*t*l*f^-1*l^-1*f*l^-1*t^-1*l*t^-2*f*t*(f^-1*l^-1)^2*l^-1*f*l*e^-1*t*e*l*t^-1*e^-1*t^-1*e*l*b*f^-1*b^-1\n\njulia> length(pre2)\n77","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"Last we let GAP choose a random element ...","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> r = GAP.Globals.Random(cube)\nGAP: (1,6,9,17,35,11)(2,13,29,42,4,34,20,36,23,10)(3,22,14,8,38,24,27,16,40,19,32,43,33,41,46,25,48,30)(5,39,28,37,18,31,44,26,47,21,12,7,45,15)\n\njulia> pre3 = GAP.Globals.PreImagesRepresentative(fhom, r)\nGAP: r*e^-1*t^-1*e^-1*r^-2*e*f*t^2*b^-1*e^-1*b*l*f^-1*r*t^-1*r^-1*l*b*f^-2*b^-1*f^-1*l*f*t^-1*l^-1*f^-1*l^-1*f*e*l^-1*e^-1*l^-2*t^-1*l*f^-1*l^-1*f*l^-1*t^-1*l^2*f*t*f^-1*(t^-1*l^-1)^3*e*l*e^-1*t*l*t^-1*l*t^2*l^-1*t^-1*l*t^-1*l^-1*f*t*f^-1*l*t*l^-1*f*l*t^-1*l^-1*t^-1*f^-1*t^-1*f*r*t*r^-1*t^-1*f^-1*t^-1*l^-1*t^-1*e^-1*t*e*l*f*r*t*r^-1*t^-1*f^-1*l^-1*t^-1*(l*t)^2*f^-1*l^-1*e^-1*f*t^-1*e*l*t^-1*l^-1*t\n\njulia> length(pre3)\n116","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"... and we verify that the decomposition is correct:","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"julia> GAP.Globals.Image(fhom, pre3) == r\ntrue","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This concludes our example.","category":"page"},{"location":"basics/","page":"Basics","title":"Basics","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"basics/#Basics","page":"Basics","title":"Basics","text":"","category":"section"},{"location":"basics/#Accessing-GAP-from-Julia","page":"Basics","title":"Accessing GAP from Julia","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"Any global GAP variable and function can be accessed from Julia via the GAP.Globals object; for example GAP.Globals.Binomial(5,3). See Convenience adapters for dealing with GAP syntax beyond simple function calls.\nThe GAP.prompt command can be used to switch to a GAP session that works like a regular GAP, except that leaving it (via quit; or by pressing Ctrl-D) returns one to a Julia prompt. From the GAP prompt, one can access Julia variables via the Julia object, for example Julia.binomial(5,3). For more details on how to access Julia from GAP, please consult the manual of the GAP package JuliaInterface.\nAlternatively, one can start GAP in the traditional way, by executing a shell script. Such a script can be created in a location of your choice via GAP.create_gap_sh. Note that one cannot switch from such a GAP session to the underlying Julia session and back.","category":"page"},{"location":"basics/","page":"Basics","title":"Basics","text":"Globals\nevalstr\nevalstr_ex\nGAP.prompt\nGAP.create_gap_sh","category":"page"},{"location":"basics/#GAP.Globals","page":"Basics","title":"GAP.Globals","text":"Globals\n\nThis is a global object that gives access to all global variables of the current GAP session via getproperty and setproperty!.\n\nExamples\n\njulia> GAP.Globals.Size # a global GAP function\nGAP: \n\njulia> GAP.Globals.size # there is no GAP variable with this name\nERROR: GAP variable size not bound\n[...]\n\njulia> hasproperty( GAP.Globals, :size )\nfalse\n\njulia> GAP.Globals.size = 17;\n\njulia> hasproperty( GAP.Globals, :size )\ntrue\n\njulia> GAP.Globals.size\n17\n\njulia> GAP.Globals.UnbindGlobal(g\"size\")\n\njulia> GAP.Globals.Julia # Julia objects can be values of GAP variables\nMain\n\n\n\n\n\n\n","category":"constant"},{"location":"basics/#GAP.evalstr","page":"Basics","title":"GAP.evalstr","text":"evalstr(cmd::String)\n\nLet GAP execute the command(s) given by cmd; if an error occurs then report this error, otherwise if the last command has a result then return it, otherwise return nothing.\n\nExamples\n\njulia> GAP.evalstr( \"1+2\" )\n3\n\njulia> GAP.evalstr( \"x:= []\" )\nGAP: [ ]\n\njulia> GAP.evalstr( \"y:= 2; Add( x, y )\" )\n\njulia> GAP.evalstr( \"x\" )\nGAP: [ 2 ]\n\njulia> GAP.evalstr( \"Print( x )\" )\n\nNote that screen outputs caused by evaluating cmd are not shown by evalstr; use evalstr_ex for accessing both the outputs and the return values of the command(s).\n\nIn general we recommend to avoid using evalstr, but it sometimes can be a useful escape hatch to access GAP functionality that is otherwise impossible to difficult to reach. But in most typical scenarios it should not be necessary to use it at all.\n\nInstead, use GAP.GapObj or GAP.Obj for constructing GAP objects that correspond to given Julia objects, and call GAP functions directly in the Julia session. For example, executing GAP.evalstr( \"x:= []; Add( x, 2 )\" ) can be replaced by the Julia code x = GAP.GapObj([]); GAP.Globals.Add(x, 2). Note that the variable x in the former example lives in the GAP session, i.e., it can be accessed as GAP.Globals.x after the call of GAP.evalstr, whereas x in the latter example lives in the Julia session.\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.evalstr_ex","page":"Basics","title":"GAP.evalstr_ex","text":"evalstr_ex(cmd::String)\n\nAssume that cmd consists of n GAP statements, each terminated by ; or ;;. Let GAP execute these statements and return a GAP list of length n that describes their results. Each entry of the return value is a GAP list of length 5, with the following meaning.\n\nThe first entry is true if the statement was executed successfully, and false otherwise.\nIf the first entry is true, then the second entry is bound to the result of the statement if there was one, and unbound otherwise.\nThe third entry is unbound if an error occured, true if the statement ends in a double semicolon, and false otherwise.\nThe fourth entry currently is always unbound.\nThe fifth entry contains the captured output of the statement as a string. If there was no double semicolon then also the output of GAP.Globals.ViewObj applied to the result value in the second entry, if any, is part of that string.\n\nExamples\n\njulia> GAP.evalstr_ex( \"1+2\" ) # error due to missing semicolon\nGAP: [ [ false,,,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"1+2;\" ) # one statement with return value\nGAP: [ [ true, 3, false,, \"3\" ] ]\n\njulia> GAP.evalstr_ex( \"1+2;;\" ) # the same with suppressed output\nGAP: [ [ true, 3, true,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"x:= []; Add(x, 1);\" ) # two valid commands\nGAP: [ [ true, [ 1 ], false,, \"[ ]\" ], [ true,, false,, \"\" ] ]\n\njulia> GAP.evalstr_ex( \"1/0; 1+1;\" ) # one error, one valid command\nGAP: [ [ false,,,, \"\" ], [ true, 2, false,, \"2\" ] ]\n\njulia> GAP.evalstr_ex( \"Print(1);\" ) # no return value but output\nGAP: [ [ true,, false,, \"1\" ] ]\n\njulia> GAP.evalstr_ex( \"\" ) # empty input\nGAP: [ ]\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.prompt","page":"Basics","title":"GAP.prompt","text":"prompt()\n\nStart a GAP prompt where you can enter GAP commands as in a regular GAP session. This prompt can be left as any GAP prompt by either entering quit; or pressing ctrl-D, which returns to the Julia prompt.\n\nThis GAP prompt allows to quickly switch between writing Julia and GAP code in a session where all data is shared.\n\n\n\n\n\n","category":"function"},{"location":"basics/#GAP.create_gap_sh","page":"Basics","title":"GAP.create_gap_sh","text":"create_gap_sh(dstdir::String)\n\nGiven a directory path, create three files in that directory:\n\na shell script named gap.sh which acts like the gap.sh shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia.\ntwo TOML files, Manifest.toml and Project.toml, which are required by gap.sh to function (they record the precise versions of GAP.jl and other Julia packages involved)\n\n\n\n\n\n","category":"function"},{"location":"basics/#Accessing-Julia-from-GAP","page":"Basics","title":"Accessing Julia from GAP","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"The GAP-Julia interface is fully bidirectional, so it is also possible to access all Julia functionality from GAP. To learn more about this, please consult the manual of the GAP package JuliaInterface.","category":"page"},{"location":"basics/#Types","page":"Basics","title":"Types","text":"","category":"section"},{"location":"basics/","page":"Basics","title":"Basics","text":"FFE\nGapObj\nGAP.Obj\nGapInt","category":"page"},{"location":"basics/#GAP.FFE","page":"Basics","title":"GAP.FFE","text":"FFE\n\nWrap a pointer to a GAP FFE (\"finite field element\") immediate object. This type is defined in the JuliaInterface C code.\n\nExamples\n\njulia> x = GAP.Globals.Z(3)\nGAP: Z(3)\n\njulia> typeof(x)\nFFE\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.GapObj","page":"Basics","title":"GAP.GapObj","text":"GapObj\n\nThis is the Julia type of all those GAP objects that are not \"immediate\" (booleans, small integers, FFEs).\n\nExamples\n\njulia> typeof(GapObj([1, 2])) # a GAP list\nGapObj\n\njulia> typeof(GapObj(Dict(:a => 1))) # a GAP record\nGapObj\n\njulia> typeof( GAP.evalstr( \"(1,2,3)\" ) ) # a GAP permutation\nGapObj\n\njulia> typeof( GAP.evalstr( \"2^64\" ) ) # a large GAP integer\nGapObj\n\njulia> typeof( GAP.evalstr( \"2^59\" ) ) # a small GAP integer\nInt64\n\njulia> typeof( GAP.evalstr( \"Z(2)\" ) ) # a GAP FFE\nFFE\n\njulia> typeof( GAP.evalstr( \"true\" ) ) # a boolean\nBool\n\nNote that this is Julia's viewpoint on GAP objects. From the viewpoint of GAP, also the pointers to Julia objects are implemented as \"non-immediate GAP objects\", but they appear as Julia objects to Julia, not \"doubly wrapped\".\n\nExamples\n\njulia> GAP.evalstr( \"Julia.Base\" )\nBase\n\njulia> typeof( GAP.evalstr( \"Julia.Base\" ) ) # native Julia object\nModule\n\nOne can use GapObj as a constructor, in order to convert Julia objects to GAP objects. Such calls are delegated to julia_to_gap.\n\nHowever, this is restricted to outputs that actually are of type GapObj. To also deal with GAP integers, finite field elements and booleans, use GAP.Obj instead.\n\nRecursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.\n\nExamples\n\njulia> GapObj(1//3)\nGAP: 1/3\n\njulia> GapObj([1 2; 3 4])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj([[1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GapObj([[1, 2], [3, 4]], true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj([[1, 2], [3, 4]], recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GapObj(42)\nERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.Obj","page":"Basics","title":"GAP.Obj","text":"GAP.Obj\n\nThis is an alias for Union{GapObj,FFE,Int64,Bool}. This type union covers all types a \"native\" GAP object may have from Julia's viewpoint.\n\nMoreover, it can be used as a constructor, in order to convert Julia objects to GAP objects, whenever a suitable conversion has been defined.\n\nRecursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second agument true or by the keyword argument recursive with value true.\n\nExamples\n\njulia> GAP.Obj(1//3)\nGAP: 1/3\n\njulia> GAP.Obj([1 2; 3 4])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj([[1, 2], [3, 4]])\nGAP: [ , ]\n\njulia> GAP.Obj([[1, 2], [3, 4]], true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj([[1, 2], [3, 4]], recursive=true)\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> GAP.Obj(42)\n42\n\n\n\n\n\n","category":"type"},{"location":"basics/#GAP.GapInt","page":"Basics","title":"GAP.GapInt","text":"GapInt\n\nAny GAP integer object is represented in Julia as either a GapObj (if it is a \"large\" integer) or as an Int (if it is a \"small\" integer). This type union can be used to express this conveniently, e.g. when one wants to help type stability.\n\nNote that also GAP's infinity and -infinity fit under this type (as do many other objects which are not numbers).\n\n\n\n\n\n","category":"type"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"other/#Other-stuff","page":"Other stuff","title":"Other stuff","text":"","category":"section"},{"location":"other/#Macros","page":"Other stuff","title":"Macros","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"@gap\n@g_str\n@gapwrap\n@gapattribute\n@wrap","category":"page"},{"location":"other/#GAP.@gap","page":"Other stuff","title":"GAP.@gap","text":"@gap \n@gap()\n\nExecute directly in GAP, as if GAP.evalstr(\"\") was called. This can be used for creating GAP literals directly from Julia.\n\nExamples\n\njulia> @gap [1,2,3]\nGAP: [ 1, 2, 3 ]\n\njulia> @gap SymmetricGroup(3)\nGAP: Sym( [ 1 .. 3 ] )\n\njulia> @gap(SymmetricGroup)(3)\nGAP: Sym( [ 1 .. 3 ] )\n\n\nNote that the last two examples have a slight syntactical, and therefore also a semantical difference. The first one executes the string SymmetricGroup(3) directly inside GAP. The second example returns the function SymmetricGroup via @gap(SymmetricGroup), then calls that function with the argument 3.\n\nDue to Julia's way of handing over arguments into the code of macros, not all expressions representing valid GAP code can be processed. For example, the GAP syntax of permutations consisting of more than one cycle cause problems, as well as the GAP syntax of non-dense lists.\n\njulia> @gap (1,2,3)\nGAP: (1,2,3)\n\njulia> @gap (1,2)(3,4)\nERROR: LoadError: Error thrown by GAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound\n[...]\n\njulia> @gap [ 1,, 2 ]\nERROR: syntax: unexpected \",\"\n[...]\n\n\nNote also that a string argument gets evaluated with GAP.evalstr.\n\njulia> @gap \"\\\"abc\\\"\"\nGAP: \"abc\"\n\njulia> @gap \"[1,,2]\"\nGAP: [ 1,, 2 ]\n\njulia> @gap \"(1,2)(3,4)\"\nGAP: (1,2)(3,4)\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@g_str","page":"Other stuff","title":"GAP.@g_str","text":"@g_str\n\nCreate a GAP string by typing g\"content\".\n\nExamples\n\njulia> g\"foo\"\nGAP: \"foo\"\n\njulia> g\"ab\\ncd\\\"ef\\\\gh\" # special characters are handled as in GAP\nGAP: \"ab\\ncd\\\"ef\\\\gh\"\n\n\nDue to Julia's way of handing over arguments into the code of macros, not all strings representing valid GAP strings can be processed.\n\njulia> g\"\\\\\"\nERROR: Error thrown by GAP: Syntax error: String must end with \" before end of file in stream:1\n[...]\n\n\nConversely, there are valid arguments for the macro that are not valid Julia strings.\n\njulia> g\"\\c\"\nGAP: \"\\c\"\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@gapwrap","page":"Other stuff","title":"GAP.@gapwrap","text":"@gapwrap\n\nWhen applied to a method definition that involves access to entries of GAP.Globals, this macro rewrites the code such that the relevant GAP globals are cached, and need not be fetched again and again.\n\nExamples\n\njulia> @gapwrap isevenint(x) = GAP.Globals.IsEvenInt(x)::Bool;\n\njulia> isevenint(1)\nfalse\n\njulia> isevenint(2)\ntrue\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@gapattribute","page":"Other stuff","title":"GAP.@gapattribute","text":"@gapattribute\n\nThis macro is intended to be applied to a method definition for a unary function called attr, say, where the argument has the type T, say, the code contains exactly one call of the form GAP.Globals.Something(X), where Something is a GAP attribute such as Centre or IsSolvableGroup, and attr returns the corresponding attribute value for its argument.\n\nThe macro defines three functions attr, has_attr, and set_attr, where attr takes an argument of type T and returns what the given method definition says, has_attr takes an argument of type T and returns the result of GAP.Globals.HasSomething(X) (which is either true or false), set_attr takes an argument of type T and an object obj and calls GAP.Globals.SetSomething(X, obj).\n\nIn order to avoid runtime access via GAP.Globals.Something etc., the same modifications are applied in the construction of the three functions that are applied by @gapwrap.\n\nThe variables that are created by the macro belong to the Julia module in whose scope the macro is called.\n\nExamples\n\njulia> @gapattribute isstrictlysortedlist(obj::GapObj) = GAP.Globals.IsSSortedList(obj)::Bool;\n\njulia> l = GapObj([ 1, 3, 7 ]);\n\njulia> has_isstrictlysortedlist( l )\nfalse\n\njulia> isstrictlysortedlist( l )\ntrue\n\njulia> has_isstrictlysortedlist( l )\ntrue\n\njulia> l = GapObj([ 1, 3, 7 ]);\n\njulia> has_isstrictlysortedlist( l )\nfalse\n\njulia> set_isstrictlysortedlist( l, true )\n\njulia> has_isstrictlysortedlist( l )\ntrue\n\njulia> isstrictlysortedlist( l )\ntrue\n\n\n\n\n\n\n","category":"macro"},{"location":"other/#GAP.@wrap","page":"Other stuff","title":"GAP.@wrap","text":"@wrap funcdecl\n\nWhen applied to a function declaration of the form NAME(a::T) or NAME(a::T)::S, this macro generates a function which behaves equivalently to NAME(a::T) = GAP.Globals.NAME(a) resp. NAME(a::T) = GAP.Globals.NAME(a)::S, assuming that GAP.Globals.NAME references a GAP function. Function declarations with more than one argument or zero arguments are also supported.\n\nHowever, the generated function actually caches the GAP object GAP.Globals.NAME. This minimizes the call overhead. So @wrap typically is used to provide an optimized way to call certain GAP functions.\n\nAnother use case for this macro is to improve type stability of code calling into GAP, via the type annotations for the arguments and return value contained in the function declaration.\n\nBe advised, though, that if the value of GAP.Globals.NAME is changed later on, the function generated by this macro will not be updated, i.e., it will still reference the original GAP object.\n\nExamples\n\njulia> GAP.@wrap Jacobi(x::GapInt, y::GapInt)::Int\nJacobi (generic function with 1 method)\n\njulia> Jacobi(11,35)\n1\n\n\n\n\n\n","category":"macro"},{"location":"other/#Convenience-adapters","page":"Other stuff","title":"Convenience adapters","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"This section describes how one can manipulate GAP objects from the Julia side, using Julia syntax features.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"In particular, the following is available on the Julia side in order to support special GAP syntax beyond function calls with arguments.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"Call functions with global options via call_gap_func or using Julia's keyword argument syntax. For example, Cyc(1.41421356 : bits:=20) in GAP translates to GAP.Globals.Cyc(GAP.Obj(1.41421356); bits=20) in Julia.\nAccess list/matrix entries via getindex and setindex! respectively the corresponding Julia syntax (described there).\nAccess record components via getproperty and setproperty! respectively the corresponding Julia syntax (described there).\nCheck for bound record components via hasproperty.\nAccess entries of a positional object via getbangindex, equivalent to GAP's ![] operator.\nAccess components of a component object via getbangproperty, equivalent to GAP's !. operator.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"call_gap_func\ncall_with_catch\ngetindex\nsetindex!\ngetbangindex\nsetbangindex!\ngetproperty\nsetproperty!\nhasproperty\ngetbangproperty\nsetbangproperty!\nwrap_rng\nrandseed!","category":"page"},{"location":"other/#GAP.call_gap_func","page":"Other stuff","title":"GAP.call_gap_func","text":"call_gap_func(func::GapObj, args...; kwargs...)\n\nCall the GAP object func as a function, with arguments args... and global GAP options kwargs..., and return the result if there is one, and nothing otherwise.\n\nThere is no argument number checking here, all checks on the arguments are done by GAP itself.\n\nFor convenience, one can use the syntax func(args...; kwargs...).\n\nExamples\n\njulia> GAP.Globals.Factors( 12 )\nGAP: [ 2, 2, 3 ]\n\njulia> GAP.Globals.Cyc(GAP.Obj(1.41421356))\nGAP: 35355339/25000000\n\njulia> GAP.Globals.Cyc(GAP.Obj(1.41421356); bits=20)\nGAP: E(8)-E(8)^3\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.call_with_catch","page":"Other stuff","title":"GAP.call_with_catch","text":"call_with_catch(juliafunc, arguments)\n\nReturn a tuple (ok, val) where ok is either true, meaning that calling the function juliafunc with arguments returns the value val, or false, meaning that the function call runs into an error; in the latter case, val is set to the string of the error message.\n\nExamples\n\njulia> GAP.call_with_catch(sqrt, 2)\n(true, 1.4142135623730951)\n\njulia> flag, res = GAP.call_with_catch(sqrt, -2);\n\njulia> flag\nfalse\n\njulia> startswith(res, \"DomainError\")\ntrue\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.getindex","page":"Other stuff","title":"Base.getindex","text":"getindex(x::GapObj, i::Int64)\ngetindex(x::GapObj, i::Int64, j::Int64)\ngetindex(x::GapObj, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}\n\nReturn the entry at position i or at position (i,j) in x, or the list of entries in x at the positions described by l, provided that x is a GAP object supporting this, such as a GAP list or matrix object.\n\nExamples\n\njulia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])\nGAP: [ 1, 2, 3, 5, 8, 13 ]\n\njulia> l[4]\n5\n\njulia> l[end]\n13\n\njulia> l[2:4]\nGAP: [ 2, 3, 5 ]\n\njulia> l[[1,4,4]]\nGAP: [ 1, 5, 5 ]\n\njulia> m = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> m[1,1]\n1\n\njulia> m[1,2]\n2\n\njulia> m[2,1]\n3\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.setindex!","page":"Other stuff","title":"Base.setindex!","text":"setindex!(x::GapObj, v::Any, i::Int64)\nsetindex!(x::GapObj, v::Any, i::Int64, j::Int64)\nsetindex!(x::GapObj, v::Any, l::Union{Vector{T},AbstractRange{T}}) where {T<:Integer}\n\nSet the entry at position i or (i,j) in x to v, or set the entries at the positions in x that are described by l to the entries in v, provided that x is a GAP object supporting this, such as a GAP list or matrix object.\n\nExamples\n\njulia> l = GapObj([ 1, 2, 3, 5, 8, 13 ])\nGAP: [ 1, 2, 3, 5, 8, 13 ]\n\njulia> l[1] = 0\n0\n\njulia> l[8] = -1\n-1\n\njulia> l[2:4] = [ 7, 7, 7 ]\n3-element Vector{Int64}:\n 7\n 7\n 7\n\njulia> l\nGAP: [ 0, 7, 7, 7, 8, 13,, -1 ]\n\njulia> m = GapObj([ 1 2 ; 3 4 ])\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> m[1,2] = 0\n0\n\njulia> m\nGAP: [ [ 1, 0 ], [ 3, 4 ] ]\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.getbangindex","page":"Other stuff","title":"GAP.getbangindex","text":"getbangindex(x::GapObj, i::Int64)\n\nReturn the entry at position i in the positional object x.\n\nExamples\n\njulia> x = GAP.Globals.ZmodnZObj(1, 6)\nGAP: ZmodnZObj( 1, 6 )\n\njulia> GAP.Globals.IsPositionalObjectRep(x)\ntrue\n\njulia> getbangindex(x, 1)\n1\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.setbangindex!","page":"Other stuff","title":"GAP.setbangindex!","text":"setbangindex!(x::GapObj, v::Any, i::Int64)\n\nSet the entry at position i in the positional object x to v, and return x.\n\nExamples\n\njulia> x = GAP.Globals.ZmodnZObj(1, 6)\nGAP: ZmodnZObj( 1, 6 )\n\njulia> GAP.Globals.IsPositionalObjectRep(x)\ntrue\n\njulia> setbangindex!(x, 0, 1)\nGAP: ZmodnZObj( 0, 6 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.getproperty","page":"Other stuff","title":"Base.getproperty","text":"getproperty(x::GapObj, f::Symbol)\ngetproperty(x::GapObj, f::Union{AbstractString,Int64})\n\nReturn the record component of the GAP record x that is described by f.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> r.a\n1\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.setproperty!","page":"Other stuff","title":"Base.setproperty!","text":"setproperty!(x::GapObj, f::Symbol, v)\nsetproperty!(x::GapObj, f::Union{AbstractString,Int64}, v)\n\nSet the record component of the GAP record x that is described by f to the value v.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> r.b = 0\n0\n\njulia> r\nGAP: rec( a := 1, b := 0 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#Base.hasproperty","page":"Other stuff","title":"Base.hasproperty","text":"hasproperty(x::GapObj, f::Symbol)\nhasproperty(x::GapObj, f::Union{AbstractString,Int64})\n\nReturn true if the GAP record x has a component that is described by f, and false otherwise.\n\nExamples\n\njulia> r = GapObj(Dict(:a => 1))\nGAP: rec( a := 1 )\n\njulia> hasproperty( r, :a )\ntrue\n\njulia> hasproperty( r, :b )\nfalse\n\njulia> r.b = 2\n2\n\njulia> hasproperty( r, :b )\ntrue\n\njulia> r\nGAP: rec( a := 1, b := 2 )\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.getbangproperty","page":"Other stuff","title":"GAP.getbangproperty","text":"getbangproperty(x::GapObj, f::Union{AbstractString,Int64,Symbol})\n\nReturn the value of the component f in the component object x.\n\nExamples\n\njulia> x = GAP.Globals.Iterator(GAP.Globals.Integers)\nGAP: \n\njulia> GAP.Globals.IsComponentObjectRep(x)\ntrue\n\njulia> getbangproperty(x, :counter)\n0\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.setbangproperty!","page":"Other stuff","title":"GAP.setbangproperty!","text":"setbangproperty!(x::GapObj, f::Union{AbstractString,Int64,Symbol}, v)\n\nSet the value of the component f in the component object x to v, and return x.\n\nExamples\n\njulia> x = GAP.Globals.Iterator(GAP.Globals.Integers)\nGAP: \n\njulia> GAP.Globals.IsComponentObjectRep(x)\ntrue\n\njulia> setbangproperty!(x, :counter, 3)\nGAP: \n\njulia> getbangproperty(x, :counter)\n3\n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.wrap_rng","page":"Other stuff","title":"GAP.wrap_rng","text":"wrap_rng(rng::Random.AbstractRNG)\n\nReturn a GAP object in the filter IsRandomSource that uses rng in calls to GAP's Random function. The idea is that GAP's Random methods for high level objects will just hand over the given random source to subfunctions until Random gets called for a list or the bounds of a range, and then Base.rand gets called with rng.\n\nExamples\n\njulia> rng1 = Random.default_rng();\n\njulia> rng2 = copy(rng1);\n\njulia> rng1 == rng2\ntrue\n\njulia> rng1 === rng2\nfalse\n\njulia> gap_rng1 = GAP.wrap_rng(rng1)\nGAP: \n\njulia> gap_rng2 = GAP.wrap_rng(rng2)\nGAP: \n\njulia> res1 = GAP.Globals.Random(gap_rng1, 1, 10);\n\njulia> rng1 == rng2 # the two rngs have diverged\nfalse\n\njulia> res1 == GAP.Globals.Random(gap_rng2, GapObj(1:10))\ntrue\n\njulia> rng1 == rng2 # now the two rngs are again in sync\ntrue\n\njulia> g = GAP.Globals.SymmetricGroup(10);\n\njulia> p = GAP.Globals.Random(gap_rng1, g);\n\njulia> p in g\ntrue\n\njulia> GAP.Globals.Random(gap_rng1, GAP.Globals.GF(2)^10)\nGAP: \n\n\n\n\n\n\n","category":"function"},{"location":"other/#GAP.randseed!","page":"Other stuff","title":"GAP.randseed!","text":"GAP.randseed!([seed::Integer])\n\nReseed GAP's global RNG with seed.\n\nThe given seed must be a non-negative integer. When seed is not specified, a random seed is generated from Julia's global RNG.\n\nFor a fixed seed, the stream of generated numbers is allowed to change between different versions of GAP.\n\n\n\n\n\n","category":"function"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"For the following Julia functions, methods are provided that deal with the case that the arguments are GAP objects; they delegate to the corresponding GAP operations.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"Julia GAP\nlength Length\nin \\in\nzero ZeroSameMutability\none OneSameMutability\n- (unary) AdditiveInverseSameMutability\ninv InverseSameMutability\n+ SUM\n- (binary) DIFF\n* PROD\n/ QUO\n\\ LQUO\n^ POW\nmod MOD\n< LT\n== EQ","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"The reason why four SameMutability operations are chosen in this list is as follows. In GAP, binary arithmetic operations return immutable results if and only if the two arguments are immutable. Thus it is consistent if unary arithmetic operations return a result with the same mutability as the argument. Note that GAP provides several variants of these unary operations, regarding the mutability of the result (ZeroMutable, ZeroImmutable, ZeroSameMutability, etc.), but here we have to choose one behaviour for the Julia function.","category":"page"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"julia> l = GAP.julia_to_gap( [ 1, 3, 7, 15 ] )\nGAP: [ 1, 3, 7, 15 ]\n\njulia> m = GAP.julia_to_gap( [ 1 2; 3 4 ] )\nGAP: [ [ 1, 2 ], [ 3, 4 ] ]\n\njulia> length( l )\n4\n\njulia> length( m ) # different from Julia's behaviour\n2\n\njulia> 1 in l\ntrue\n\njulia> 2 in l\nfalse\n\njulia> zero( l )\nGAP: [ 0, 0, 0, 0 ]\n\njulia> one( m )\nGAP: [ [ 1, 0 ], [ 0, 1 ] ]\n\njulia> - l\nGAP: [ -1, -3, -7, -15 ]\n\njulia> l + 1\nGAP: [ 2, 4, 8, 16 ]\n\njulia> l + l\nGAP: [ 2, 6, 14, 30 ]\n\njulia> m + m\nGAP: [ [ 2, 4 ], [ 6, 8 ] ]\n\njulia> 1 - m\nGAP: [ [ 0, -1 ], [ -2, -3 ] ]\n\njulia> l * l\n284\n\njulia> l * m\nGAP: [ 10, 14 ]\n\njulia> m * m\nGAP: [ [ 7, 10 ], [ 15, 22 ] ]\n\njulia> 1 / m\nGAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]\n\njulia> m / 2\nGAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]\n\njulia> 2 \\ m\nGAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]\n\njulia> m ^ 2\nGAP: [ [ 7, 10 ], [ 15, 22 ] ]\n\njulia> m ^ -1\nGAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]\n\njulia> mod( l, 3 )\nGAP: [ 1, 0, 1, 0 ]\n\njulia> m < 2 * m\ntrue\n\njulia> m^2 - 5 * m == 2 * one( m )\ntrue\n","category":"page"},{"location":"other/#Access-to-the-GAP-help-system","page":"Other stuff","title":"Access to the GAP help system","text":"","category":"section"},{"location":"other/","page":"Other stuff","title":"Other stuff","text":"show_gap_help","category":"page"},{"location":"other/#GAP.show_gap_help","page":"Other stuff","title":"GAP.show_gap_help","text":"show_gap_help(topic::String, onlyexact::Bool = false)\n\nPrint the information from the GAP help system about topic to the screen. If onlyexact is true then only exact matches are shown, otherwise all matches. For example, GAP.show_gap_help(\"Size\") shows also documentation for SizeScreen and SizesPerfectGroups, whereas GAP.show_gap_help(\"Size\", true) shows only documentation for Size.\n\nFor the variant showing all matches, one can also enter ?GAP.Globals.Size at the Julia prompt instead of calling show_gap_help.\n\nExamples\n\njulia> GAP.show_gap_help( \"Size\" )\n[...] # more than 50 entries from GAP manuals\n\nhelp?> GAP.Globals.Size\n[...] # the same\n\njulia> GAP.show_gap_help( \"Size\", true )\n[...] # about 15 entries from GAP manuals\n\n\n\n\n\n\n","category":"function"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"packages/#Managing-GAP-packages","page":"Managing GAP packages","title":"Managing GAP packages","text":"","category":"section"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"The following functions allow one to load/install/update/remove GAP packages.","category":"page"},{"location":"packages/","page":"Managing GAP packages","title":"Managing GAP packages","text":"GAP.Packages.load\nGAP.Packages.install\nGAP.Packages.update\nGAP.Packages.remove","category":"page"},{"location":"packages/#GAP.Packages.load","page":"Managing GAP packages","title":"GAP.Packages.load","text":"load(spec::String, version::String = \"\"; install::Bool = false, quiet::Bool = true)\n\nTry to load the GAP package given by spec, which can be either the name of the package or a local path where the package is installed (a directory that contains the package's PackageInfo.g file).\n\nIf version is specified then try to load a version of the package that is compatible with version, in the sense of GAP's CompareVersionNumbers function, otherwise try to load the newest installed version. Return true if this is successful, and false otherwise.\n\nIf install is set to true and (the desired version of) the required GAP package is not yet installed and spec is the package name then install is called first, in order to install the package; if no version is prescribed then the newest released version of the package will be installed.\n\nThe function calls GAP's LoadPackage function. If quiet is set to false then package banners are shown for all packages being loaded. It is also passed on to install.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.install","page":"Managing GAP packages","title":"GAP.Packages.install","text":"install(spec::String, version::String = \"\";\n interactive::Bool = true, quiet::Bool = false,\n debug::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nDownload and install the GAP package given by spec into the pkgdir directory.\n\nspec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.\n\nIf spec is the name of a package then the package version can be specified by version, in the format described for GAP's CompareVersionNumbers function. In all other cases the newest released version of the package will get installed.\n\nReturn true if the installation is successful or if (a version compatible with version) of the package was already installed, and false otherwise.\n\nThe function uses the function InstallPackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.update","page":"Managing GAP packages","title":"GAP.Packages.update","text":"update(spec::String; interactive::Bool = true, quiet::Bool = false,\n debug::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nUpdate the GAP package given by spec that is installed in the pkgdir directory, to the latest version. Return true if a newer version was installed successfully, or if no newer version is available, and false otherwise.\n\nspec can be either the name of a package or the URL of an archive or repository containing a package, or the URL of a PackageInfo.g file.\n\nThe function uses the function UpdatePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"packages/#GAP.Packages.remove","page":"Managing GAP packages","title":"GAP.Packages.remove","text":"remove(spec::String; interactive::Bool = true, quiet::Bool = false,\n debug::Bool = false,\n pkgdir::AbstractString = GAP.Packages.DEFAULT_PKGDIR[])\n\nRemove the GAP package with name spec that is installed in the pkgdir directory. Return true if the removal was successful, and false otherwise.\n\nThe function uses the function RemovePackage from GAP's package PackageManager. The info messages shown by this function can be suppressed by passing true as the value of quiet. Specifying interactive = false will prevent PackageManager from prompting the user for input interactively. For details, please refer to its documentation.\n\n\n\n\n\n","category":"function"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"CurrentModule = GAP\nDocTestSetup = :(using GAP)","category":"page"},{"location":"#GAP.jl","page":"GAP.jl","title":"GAP.jl","text":"","category":"section"},{"location":"#Introduction","page":"GAP.jl","title":"Introduction","text":"","category":"section"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"GAP.jl is a low level interface from Julia to the computer algebra system GAP. The term \"low level\" means that the aim is to give Julia access to all GAP objects, to let Julia call GAP functions, and to provide conversions of low level data (integers, Booleans, strings, arrays/lists, dictionaries/records) between the two systems.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"In particular, it is not the aim of GAP.jl to provide Julia types for higher level GAP objects that represent algebraic structures, such as groups, rings, fields, etc., and mappings between such structures.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"The connection between GAP and Julia is in fact bidirectional, that is, GAP can access all Julia objects, call Julia functions, and perform conversions of low level data. This direction will become interesting on the Julia side as soon as GAP packages provide functionality that is based on using Julia code from the GAP side.","category":"page"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"The viewpoint of an interface from GAP to Julia is described in the manual of the GAP package JuliaInterface.","category":"page"},{"location":"#Table-of-contents","page":"GAP.jl","title":"Table of contents","text":"","category":"section"},{"location":"","page":"GAP.jl","title":"GAP.jl","text":"Pages = GAP.GAP_docs_pages","category":"page"}] }