GAP.Packages.install
— Functioninstall(spec::String, version::String = "";
interactive::Bool = true, quiet::Bool = false,
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.
GAP.Packages.load
— Functionload(spec::String, version::String = ""; install::Union{Bool, String} = 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
or to a string 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. A string value of install
can be the URL of an archive or repository containing a package, or the URL of a PackageInfo.g
file, like the first argument of install
.
The function calls GAP's LoadPackage
function. If quiet
is set to false
then package banners are shown for all packages being loaded. The quiet
value is also passed on to install
.
GAP.Packages.locate_package
— Methodlocate_package(name::String)
Return the path where the GAP package with name name
is installed if this package is loaded, and ""
otherwise.
GAP.Packages.remove
— Methodremove(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.
GAP.Packages.update
— Methodupdate(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.
GAP.GAP
— ModuleGAP.jl is the Julia interface to the GAP-System.
For the package manual see https://oscar-system.github.io/GAP.jl/.
For more information about GAP see https://www.gap-system.org/.
GAP.GapInt
— TypeGapInt
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).
GAP.Globals
— ConstantGlobals
This is a global object that gives access to all global variables of the current GAP session via getproperty
and setproperty!
.
Examples
julia> GAP.Globals.Size # a global GAP function
GAP: <Attribute "Size">
julia> GAP.Globals.size # there is no GAP variable with this name
ERROR: GAP variable size not bound
[...]
julia> hasproperty( GAP.Globals, :size )
false
julia> GAP.Globals.size = 17;
julia> hasproperty( GAP.Globals, :size )
true
julia> GAP.Globals.size
17
julia> GAP.Globals.UnbindGlobal(g"size")
julia> GAP.Globals.Julia # Julia objects can be values of GAP variables
Main
GAP.Obj
— TypeGAP.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 argument 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])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.Obj([[1, 2], [3, 4]])
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
julia> GAP.Obj([[1, 2], [3, 4]], true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.Obj([[1, 2], [3, 4]], recursive=true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.Obj(42)
42
Base.BitVector
— MethodBitVector(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)
3-element BitVector:
1
0
1
Base.Cuchar
— MethodCuchar(obj::GapObj)
Return the UInt8
that belongs to the GAP character obj
.
Examples
julia> val = GAP.Obj('x')
GAP: 'x'
julia> Cuchar(val)
0x78
Base.Dict
— MethodDict{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)
Dict{Symbol, Int64} with 2 entries:
:a => 1
:b => 2
julia> val = GAP.Obj(Dict(:l => GAP.Obj([1, 2])))
GAP: rec( l := [ 1, 2 ] )
julia> Dict{Symbol,Any}(val; recursive=false)
Dict{Symbol, Any} with 1 entry:
:l => GAP: [ 1, 2 ]
julia> Dict{Symbol,Any}(val; recursive=true)
Dict{Symbol, Any} with 1 entry:
:l => Any[1, 2]
julia> Dict{Symbol,Vector{Int}}(val; recursive=true)
Dict{Symbol, Vector{Int64}} with 1 entry:
:l => [1, 2]
Base.GMP.BigInt
— MethodBigInt(obj::GapObj)
Return the big integer converted from the GAP integer obj
. (Note that small GAP integers are not represented by GapObj
s, their conversion with BigInt
is handled by Julia's methods.)
Examples
julia> val = GAP.Globals.Factorial(25)
GAP: 15511210043330985984000000
julia> BigInt(val)
15511210043330985984000000
julia> val = GAP.Globals.Factorial(10)
3628800
julia> isa(val, GapObj)
false
julia> BigInt(val)
3628800
Base.Matrix
— MethodMatrix{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)
2×2 Matrix{Int64}:
1 2
3 4
julia> val = GAP.evalstr( "NewMatrix( IsPlistMatrixRep, Integers, 2, [ 0, 1, 2, 3 ] )" )
GAP: <2x2-matrix over Integers>
julia> Matrix{Int64}(val)
2×2 Matrix{Int64}:
0 1
2 3
Base.Rational
— MethodRational{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)
15511210043330985984000000//1
julia> Rational{BigInt}(val)
15511210043330985984000000//1
julia> val = GAP.Obj(1//3)
GAP: 1/3
julia> Rational{Int64}(val)
1//3
Base.Set
— MethodSet{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
julia> Set{Vector{Int}}(GAP.Obj([[1], [2], [1]]; recursive=true))
Set{Vector{Int64}} with 2 elements:
[1]
[2]
julia> Set{String}(GAP.Obj(["a", "b"]; recursive=true))
Set{String} with 2 elements:
"b"
"a"
julia> Set{Any}(GAP.Obj([[1], [2], [1]]; recursive=true))
Set{Any} with 2 elements:
Any[1]
Any[2]
Base.StepRange
— TypeStepRange(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)
1:2:11
julia> r = StepRange{Int8,Int8}(val)
1:2:11
julia> typeof(r)
StepRange{Int8, Int8}
Base.UnitRange
— TypeUnitRange(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)
1:10
julia> UnitRange{Int32}(val)
1:10
Base.Vector
— MethodVector{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)
2-element Vector{Any}:
Any[1]
Any[2]
julia> Vector{Any}(val; recursive=false)
2-element Vector{Any}:
GAP: [ 1 ]
GAP: [ 2 ]
julia> Vector{Vector{Int64}}(val)
2-element Vector{Vector{Int64}}:
[1]
[2]
julia> val = GAP.evalstr( "NewVector( IsPlistVectorRep, Integers, [ 0, 2, 5 ] )" )
GAP: <plist vector over Integers of length 3>
julia> Vector{Int64}(val)
3-element Vector{Int64}:
0
2
5
julia> val = GAP.Obj("abc")
GAP: "abc"
julia> Vector{UInt8}(val)
3-element Vector{UInt8}:
0x61
0x62
0x63
Core.Char
— MethodChar(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)
Core.Float64
— MethodFloat64(obj::GapObj)
Return the float converted from the GAP float obj
.
Examples
julia> val = GAP.Obj(2.2)
GAP: 2.2
julia> Float64(val)
2.2
julia> Float32(val)
2.2f0
Core.Int128
— TypeInt128(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 GapObj
s; 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)
Core.String
— MethodString(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)
"abc"
julia> val = GAP.Obj([])
GAP: [ ]
julia> String(val) # an empty GAP list is a string
""
Core.Symbol
— MethodSymbol(obj::GapObj)
Return the symbol converted from the GAP string obj
.
Examples
julia> str = GAP.Obj("abc")
GAP: "abc"
julia> Symbol(str)
:abc
Core.Tuple
— TypeTuple{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)
(1, 5)
julia> val = GAP.Obj([[1], [2]]; recursive=true)
GAP: [ [ 1 ], [ 2 ] ]
julia> Tuple{Any,Any}(val)
(Any[1], Any[2])
julia> Tuple{GapObj,GapObj}(val; recursive=false)
(GAP: [ 1 ], GAP: [ 2 ])
GAP.FFE
— TypeFFE
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
GAP.GapObj
— TypeGapObj
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
GapObj
julia> typeof( GAP.evalstr( "(1,2,3)" ) ) # a GAP permutation
GapObj
julia> typeof( GAP.evalstr( "2^64" ) ) # a large GAP integer
GapObj
julia> typeof( GAP.evalstr( "2^59" ) ) # a small GAP integer
Int64
julia> typeof( GAP.evalstr( "Z(2)" ) ) # a GAP FFE
FFE
julia> typeof( GAP.evalstr( "true" ) ) # a boolean
Bool
Note 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".
Examples
julia> GAP.evalstr( "Julia.Base" )
Base
julia> typeof( GAP.evalstr( "Julia.Base" ) ) # native Julia object
Module
One can use GapObj
as a constructor, in order to convert Julia objects to GAP objects. Such calls are delegated to julia_to_gap
.
However, 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.
Recursive conversion of nested Julia objects (arrays, tuples, dictionaries) can be forced either by a second argument true
or by the keyword argument recursive
with value true
.
Examples
julia> GapObj(1//3)
GAP: 1/3
julia> GapObj([1 2; 3 4])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GapObj([[1, 2], [3, 4]])
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
julia> GapObj([[1, 2], [3, 4]], true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GapObj([[1, 2], [3, 4]], recursive=true)
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GapObj(42)
ERROR: TypeError: in typeassert, expected GapObj, got a value of type Int64
GAP.RecDict
— TypeRecDict
An internal type of GAP.jl used for tracking conversion results in gap_to_julia
.
Base.getindex
— Methodgetindex(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 ]
julia> l[4]
5
julia> l[end]
13
julia> l[2:4]
GAP: [ 2, 3, 5 ]
julia> l[[1,4,4]]
GAP: [ 1, 5, 5 ]
julia> m = GapObj([ 1 2 ; 3 4 ])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> m[1,1]
1
julia> m[1,2]
2
julia> m[2,1]
3
Base.getproperty
— Methodgetproperty(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
Base.hasproperty
— Methodhasproperty(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 )
julia> hasproperty( r, :a )
true
julia> hasproperty( r, :b )
false
julia> r.b = 2
2
julia> hasproperty( r, :b )
true
julia> r
GAP: rec( a := 1, b := 2 )
Base.setindex!
— Methodsetindex!(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 ]
julia> l[1] = 0
0
julia> l[8] = -1
-1
julia> l[2:4] = [ 7, 7, 7 ]
3-element Vector{Int64}:
7
7
7
julia> l
GAP: [ 0, 7, 7, 7, 8, 13,, -1 ]
julia> m = GapObj([ 1 2 ; 3 4 ])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> m[1,2] = 0
0
julia> m
GAP: [ [ 1, 0 ], [ 3, 4 ] ]
Base.setproperty!
— Methodsetproperty!(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 )
julia> r.b = 0
0
julia> r
GAP: rec( a := 1, b := 0 )
GAP.call_gap_func
— Methodcall_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
GAP.call_with_catch
— Methodcall_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);
julia> flag
false
julia> startswith(res, "DomainError")
true
GAP.create_gap_sh
— Methodcreate_gap_sh(dstdir::String)
Given a directory path, create three files in that directory:
- a shell script named
gap.sh
which acts like thegap.sh
shipped with a regular GAP installation, but which behind the scenes launches GAP via Julia. - two TOML files,
Manifest.toml
andProject.toml
, which are required bygap.sh
to function (they record the precise versions of GAP.jl and other Julia packages involved)
GAP.evalstr
— Methodevalstr(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:= []" )
GAP: [ ]
julia> GAP.evalstr( "y:= 2; Add( x, y )" )
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.
GAP.evalstr_ex
— Methodevalstr_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, andfalse
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, andfalse
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
GAP: [ [ true, 3, false,, "3" ] ]
julia> GAP.evalstr_ex( "1+2;;" ) # the same with suppressed output
GAP: [ [ true, 3, true,, "" ] ]
julia> GAP.evalstr_ex( "x:= []; Add(x, 1);" ) # two valid commands
GAP: [ [ true, [ 1 ], false,, "[ ]" ], [ true,, false,, "" ] ]
julia> GAP.evalstr_ex( "1/0; 1+1;" ) # one error, one valid command
GAP: [ [ false,,,, "" ], [ true, 2, false,, "2" ] ]
julia> GAP.evalstr_ex( "Print(1);" ) # no return value but output
GAP: [ [ true,, false,, "1" ] ]
julia> GAP.evalstr_ex( "" ) # empty input
GAP: [ ]
GAP.gap_to_julia
— Methodgap_to_julia(type, x, recursion_dict::Union{Nothing,RecDict}=nothing; recursive::Bool=true)
Try 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
.
The parameter recursion_dict
is used to preserve the identity of converted subobjects and should never be given by the user.
For 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
.
Examples
julia> GAP.gap_to_julia(GapObj(1//3))
1//3
julia> GAP.gap_to_julia(GapObj("abc"))
"abc"
julia> val = GapObj([ 1 2 ; 3 4 ])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> GAP.gap_to_julia( val )
2-element Vector{Any}:
Any[1, 2]
Any[3, 4]
julia> GAP.gap_to_julia( val, recursive = false )
2-element Vector{Any}:
GAP: [ 1, 2 ]
GAP: [ 3, 4 ]
julia> GAP.gap_to_julia( Vector{GapObj}, val )
2-element Vector{GapObj}:
GAP: [ 1, 2 ]
GAP: [ 3, 4 ]
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 filter | default Julia type | other Julia types |
---|---|---|
IsInt | BigInt | `T <: Integer |
IsFFE | GapFFE | |
IsBool | Bool | |
IsRat | Rational{BigInt} | `Rational{T} |
IsFloat | Float64 | `T <: AbstractFloat |
IsChar | Cuchar | Char |
IsStringRep | String | Symbol , Vector{T} |
IsRangeRep | StepRange{Int64,Int64} | Vector{T} |
IsBListRep | BitVector | Vector{T} |
IsList | Vector{Any} | Vector{T} |
IsVectorObj | Vector{Any} | Vector{T} |
IsMatrixObj | Matrix{Any} | Matrix{T} |
IsRecord | Dict{Symbol, Any} | Dict{Symbol, T} |
GAP.get_symbols_in_module
— Methodget_symbols_in_module(m::Module) :: Vector{Symbol}
Return all symbols in the module m
. This is used in a GAP method for RecNames
.
GAP.getbangindex
— Methodgetbangindex(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)
true
julia> getbangindex(x, 1)
1
GAP.getbangproperty
— Methodgetbangproperty(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)
true
julia> getbangproperty(x, :counter)
0
GAP.hasbangindex
— Methodhasbangindex(x::GapObj, i::Int64)
Return whether the entry at position i
exists in the positional object x
.
Examples
julia> x = GAP.Globals.ZmodnZObj(1, 6)
GAP: ZmodnZObj( 1, 6 )
julia> GAP.Globals.IsPositionalObjectRep(x)
true
julia> hasbangindex(x, 1)
true
julia> hasbangindex(x, 2)
false
GAP.hasbangproperty
— Methodhasbangproperty(x::GapObj, f::Union{AbstractString,Int64,Symbol})
Return whether the component object x
has the component f
.
Examples
julia> x = GAP.Globals.Iterator(GAP.Globals.Integers)
GAP: <iterator of Integers at 0>
julia> GAP.Globals.IsComponentObjectRep(x)
true
julia> hasbangproperty(x, :counter)
true
julia> hasbangproperty(x, :x)
false
GAP.julia_to_gap
— Methodjulia_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")
GAP: "abc"
julia> GAP.julia_to_gap([ [1, 2], [3, 4]])
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
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 type | GAP filter |
---|---|
Int8 , Int16 , ..., BigInt | IsInt |
GapFFE | IsFFE |
Bool | IsBool |
Rational{T} | IsRat |
Float16 , Float32 , Float64 | IsFloat |
AbstractString | IsString |
Symbol | IsString |
Char | IsChar |
Vector{T} | IsList |
Vector{Bool} , BitVector | IsBList |
Tuple{T} | IsList |
Matrix{T} | IsList |
Dict{String, T} , Dict{Symbol, T} | IsRecord |
UnitRange{T} , StepRange{T, S} | IsRange |
Function | IsFunction |
GAP.kwarg_wrapper
— Methodkwarg_wrapper(func, args::Vector{T1}, kwargs::Dict{Symbol,T2}) where {T1, T2}
Call the function func
with arguments args
and keyword arguments given by the keys and values of kwargs
.
This function is used on the GAP side, in calls of Julia functions that require keyword arguments. Note that jl_call
and Core._apply
do not support keyword arguments.
Examples
julia> range(2, length = 5, step = 2)
2:2:10
julia> GAP.kwarg_wrapper(range, [2], Dict(:length => 5, :step => 2))
2:2:10
GAP.prompt
— Methodprompt()
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.
GAP.randseed!
— FunctionGAP.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.
GAP.setbangindex!
— Methodsetbangindex!(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)
true
julia> setbangindex!(x, 0, 1)
GAP: ZmodnZObj( 0, 6 )
GAP.setbangproperty!
— Methodsetbangproperty!(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)
true
julia> setbangproperty!(x, :counter, 3)
GAP: <iterator of Integers at -1>
julia> getbangproperty(x, :counter)
3
GAP.show_gap_help
— Functionshow_gap_help(topic::String, onlyexact::Bool = false)
Print 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
.
For the variant showing all matches, one can also enter ?GAP.Globals.Size
at the Julia prompt instead of calling show_gap_help
.
Examples
julia> GAP.show_gap_help( "Size" )
[...] # more than 50 entries from GAP manuals
help?> GAP.Globals.Size
[...] # the same
julia> GAP.show_gap_help( "Size", true )
[...] # about 15 entries from GAP manuals
GAP.wrap_rng
— Methodwrap_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);
julia> rng1 == rng2
true
julia> rng1 === rng2
false
julia> gap_rng1 = GAP.wrap_rng(rng1)
GAP: <RandomSource in IsRandomSourceJulia>
julia> gap_rng2 = GAP.wrap_rng(rng2)
GAP: <RandomSource in IsRandomSourceJulia>
julia> res1 = GAP.Globals.Random(gap_rng1, 1, 10);
julia> rng1 == rng2 # the two rngs have diverged
false
julia> res1 == GAP.Globals.Random(gap_rng2, GapObj(1:10))
true
julia> rng1 == rng2 # now the two rngs are again in sync
true
julia> g = GAP.Globals.SymmetricGroup(10);
julia> p = GAP.Globals.Random(gap_rng1, g);
julia> p in g
true
julia> GAP.Globals.Random(gap_rng1, GAP.Globals.GF(2)^10)
GAP: <a GF2 vector of length 10>
GAP.@g_str
— Macro@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
GAP: "ab\ncd\"ef\\gh"
Due to Julia's way of handing over arguments into the code of macros, not all strings representing valid GAP strings can be processed.
julia> g"\\"
ERROR: Error thrown by GAP: Syntax error: String must end with " before end of file in stream:1
[...]
Conversely, there are valid arguments for the macro that are not valid Julia strings.
julia> g"\c"
GAP: "\c"
GAP.@gap
— Macro@gap <expr>
@gap(<expr>)
Execute <expr> directly in GAP, as if GAP.evalstr("<expr>")
was called. This can be used for creating GAP literals directly from Julia.
Examples
julia> @gap [1,2,3]
GAP: [ 1, 2, 3 ]
julia> @gap SymmetricGroup(3)
GAP: Sym( [ 1 .. 3 ] )
julia> @gap(SymmetricGroup)(3)
GAP: Sym( [ 1 .. 3 ] )
Note 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
.
Due 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.
julia> @gap (1,2,3)
GAP: (1,2,3)
julia> @gap (1,2)(3,4)
ERROR: LoadError: Error thrown by GAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
[...]
julia> @gap [ 1,, 2 ]
ERROR: syntax: unexpected ","
[...]
Note also that a string argument gets evaluated with GAP.evalstr
.
julia> @gap "\"abc\""
GAP: "abc"
julia> @gap "[1,,2]"
GAP: [ 1,, 2 ]
julia> @gap "(1,2)(3,4)"
GAP: (1,2)(3,4)
GAP.@gapattribute
— Macro@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 ]);
julia> has_isstrictlysortedlist( l )
false
julia> isstrictlysortedlist( l )
true
julia> has_isstrictlysortedlist( l )
true
julia> l = GapObj([ 1, 3, 7 ]);
julia> has_isstrictlysortedlist( l )
false
julia> set_isstrictlysortedlist( l, true )
julia> has_isstrictlysortedlist( l )
true
julia> isstrictlysortedlist( l )
true
GAP.@gapwrap
— Macro@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
GAP.@wrap
— Macro@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.
If an argument is annotated as ::GapObj
(respectively ::GAP.Obj
or ::GapInt
), the resulting function accepts arguments of any type and attempts to convert them to GapObj
(respectively GAP.Obj
or GapInt
) before passing them to the GAP function.
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 IsString(x::GapObj)::Bool
IsString (generic function with 1 method)
julia> IsString("abc")
true
julia> GAP.@wrap Jacobi(x::GapInt, y::GapInt)::Int
Jacobi (generic function with 1 method)
julia> Jacobi(11,35)
1
julia> Jacobi(big(35)^100+11, 35)
1