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.
Types
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.evalstr( "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> isa( GAP.evalstr( "[ 1, 2 ]" ), GapObj ) # a GAP list
true
julia> isa( GAP.evalstr( "rec()" ), GapObj ) # a GAP record
true
julia> isa( GAP.evalstr( "(1,2,3)" ), GapObj ) # a GAP permutation
true
julia> isa( GAP.evalstr( "2^64" ), GapObj ) # a large GAP integer
true
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
.
Examples
julia> GapObj(1//3)
GAP: 1/3
julia> GapObj([1 2; 3 4])
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
For technical reasons, GapObj
is created inside the Julia module GAP_jll
, before the module GAP
gets loaded. Thus Julia prints it as GAP_jll.MPtr
.
Examples
julia> GapObj
GAP_jll.MPtr
Macros
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.@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: LoadError: 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"
Conversions
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
, or using Base.convert
, see Explicit GAP-to-Julia and Julia-to-GAP Conversions, respectively.
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
.
Automatic GAP-to-Julia and Julia-to-GAP Conversions
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.
GAP's immediate integers (in the range -2^60 to 2^60-1) are automatically converted to Julia's
Int64
objects; Julia'sInt64
objects are automatically converted to GAP's immediate integers if they fit, and to GAP's large integers otherwise.GAP's immediate finite field elements are automatically converted to Julia's
GAP.FFE
objects, and vice versa.GAP's
true
andfalse
are automatically converted to Julia'strue
andfalse
, and vice versa.
Explicit GAP-to-Julia and Julia-to-GAP Conversions
GAP.gap_to_julia
— Functiongap_to_julia(type, x, recursion_dict=nothing; recursive=true)
Try to convert the object x
to a Julia object of type type
. If x
is a GAP.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 meant 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( GAP.evalstr( "1/3" ) )
1//3
julia> GAP.gap_to_julia( GAP.evalstr( "\"abc\"" ) )
"abc"
julia> val = GAP.evalstr( "[ [ 1, 2 ], [ 3, 4 ] ]" );
julia> GAP.gap_to_julia( val )
2-element Array{Any,1}:
Any[1, 2]
Any[3, 4]
julia> GAP.gap_to_julia( val, recursive = false )
2-element Array{Any,1}:
GAP: [ 1, 2 ]
GAP: [ 3, 4 ]
GAP.julia_to_gap
— Functionjulia_to_gap(input, recursion_dict = IdDict(); recursive = 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 egal 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 ] ]
Base.convert
— Functionconvert(T, obj::GapObj; recursive::Bool = true)
Return the Julia object of type T
that corresponds to obj
. If recursive
is true
then subobjects of obj
are also converted, otherwise not. Such calls are delegated to gap_to_julia
.
Examples
julia> val = @gap 2^64
GAP: 18446744073709551616
julia> convert(Rational{BigInt}, val)
18446744073709551616//1
julia> val = @gap [ [ 1 ], [ 2 ] ]
GAP: [ [ 1 ], [ 2 ] ]
julia> convert(Vector{Any}, val)
2-element Array{Any,1}:
Any[1]
Any[2]
julia> convert(Vector{Any}, val, recursive = false)
2-element Array{Any,1}:
GAP: [ 1 ]
GAP: [ 2 ]
convert(GapObj, obj; recursive = false)
Return the GAP object that corresponds to the Julia object obj
. If recursive
is true
then subobjects of obj
are also converted, otherwise not.
Examples
julia> convert( GapObj, [1 2; 3 4] )
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> convert( GapObj, [[1, 2], [3, 4]] )
GAP: [ <Julia: [1, 2]>, <Julia: [3, 4]> ]
julia> convert( GapObj, [[1, 2], [3, 4]], recursive = true )
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
Constructor Methods for GAP-to-Julia Conversions
(For Julia-to-GAP conversions, one can use GapObj
as a constructor.)
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.evalstr("2^80")
GAP: 1208925819614629174706176
julia> Int128(val)
1208925819614629174706176
Base.GMP.BigInt
— TypeBigInt(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.evalstr("2^64")
GAP: 18446744073709551616
julia> BigInt(val)
18446744073709551616
julia> val = GAP.evalstr("2^59")
576460752303423488
julia> isa(val, GapObj)
false
julia> BigInt(val)
576460752303423488
Base.Rational
— TypeRational{T}(obj::GapObj) where {T<:Integer}
Return the rational converted from the GAP integer or the GAP rational obj
,
Examples
julia> val = GAP.evalstr("2^64")
GAP: 18446744073709551616
julia> Rational{Int128}(val)
18446744073709551616//1
julia> Rational{BigInt}(val)
18446744073709551616//1
julia> val = GAP.evalstr("1/3")
GAP: 1/3
julia> Rational{Int64}(val)
1//3
Core.Float64
— TypeFloat64(obj::GapObj)
Return the float converted from the GAP float obj
.
Examples
julia> val = GAP.evalstr("2.2")
GAP: 2.2
julia> Float64(val)
2.2
julia> Float32(val)
2.2f0
Base.big
— Functionbig(obj::GapObj)
Return the big integer converted from the GAP integer obj
, or the big rational converted from the GAP rational obj
, or the big float converted from the GAP float obj
.
Examples
julia> val = GAP.evalstr("2^64")
GAP: 18446744073709551616
julia> big(val)
18446744073709551616
julia> val = GAP.evalstr("1/3")
GAP: 1/3
julia> big(val)
1//3
julia> val = GAP.evalstr("1.1")
GAP: 1.1
julia> big(val)
1.100000000000000088817841970012523233890533447265625
Core.Char
— TypeChar(obj::GapObj)
Return the character converted from the GAP character obj
.
Examples
julia> val = GAP.evalstr("'x'")
GAP: 'x'
julia> Char(val)
'x': ASCII/Unicode U+0078 (category Ll: Letter, lowercase)
Base.Cuchar
— TypeCuchar(obj::GapObj)
Return the UInt8
that belongs to the GAP character obj
.
Examples
julia> val = GAP.evalstr("'x'")
GAP: 'x'
julia> Cuchar(val)
0x78
Core.String
— TypeString(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.evalstr("\"abc\"")
GAP: "abc"
julia> String(val)
"abc"
julia> val = GAP.evalstr("[]")
GAP: [ ]
julia> String(val) # an empty GAP list is a string
""
Core.Symbol
— TypeSymbol(obj::GapObj)
Return the symbol converted from the GAP string obj
.
Examples
julia> str = GAP.evalstr("\"abc\"")
GAP: "abc"
julia> Symbol(str)
:abc
Base.UnitRange
— TypeUnitRange(obj::GapObj)
Return the unit range converted from the GAP range obj
, which has step width 1.
Examples
julia> val = GAP.evalstr("[ 1 .. 10 ]")
GAP: [ 1 .. 10 ]
julia> UnitRange(val)
1:10
julia> UnitRange{Int32}(val)
1:10
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.evalstr("[ 1, 3 .. 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}
Core.Tuple
— TypeTuple{Types...}(obj::GapObj; recursive = 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.evalstr("[ 1, 5 ]")
GAP: [ 1, 5 ]
julia> Tuple{Int64,Int64}(val)
(1, 5)
julia> val = GAP.evalstr("[ [ 1 ], [ 2 ] ]")
GAP: [ [ 1 ], [ 2 ] ]
julia> Tuple{Any,Any}(val)
(Any[1], Any[2])
julia> Tuple{GapObj,GapObj}(val, recursive = false)
(GAP: [ 1 ], GAP: [ 2 ])
Base.BitArray
— TypeBitArray{1}(obj::GapObj)
Return the 1-dimensional bit array converted from the GAP list of booleans obj
.
Examples
julia> val = GAP.evalstr("[ true, false, true ]")
GAP: [ true, false, true ]
julia> BitArray{1}(val)
3-element BitArray{1}:
1
0
1
Base.Vector
— TypeVector{T}(obj::GapObj; recursive = 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.evalstr("[ [ 1 ], [ 2 ] ]")
GAP: [ [ 1 ], [ 2 ] ]
julia> Vector{Any}(val)
2-element Array{Any,1}:
Any[1]
Any[2]
julia> Vector{Any}(val, recursive = false)
2-element Array{Any,1}:
GAP: [ 1 ]
GAP: [ 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 Array{Int64,1}:
0
2
5
julia> val = GAP.evalstr("\"abc\"")
GAP: "abc"
julia> Vector{UInt8}(val)
3-element Array{UInt8,1}:
0x61
0x62
0x63
Base.Matrix
— TypeMatrix{T}(obj::GapObj; recursive = 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.evalstr("[ [ 1, 2 ], [ 3, 4 ] ]")
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> Matrix{Int64}(val)
2×2 Array{Int64,2}:
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 Array{Int64,2}:
0 1
2 3
Base.Set
— TypeSet{T}(obj::GapObj; recursive = 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.evalstr("[ 1, 2, 1 ]"))
Set{Int64} with 2 elements:
2
1
julia> Set{Vector{Int}}(GAP.evalstr("[[1], [2], [1]]"))
Set{Array{Int64,1}} with 2 elements:
[1]
[2]
julia> Set{String}(GAP.evalstr("[\"a\", \"b\"]"))
Set{String} with 2 elements:
"b"
"a"
julia> Set{Any}(GAP.evalstr("[[1], [2], [1]]"))
Set{Any} with 2 elements:
Any[1]
Any[2]
In the following examples, the order in which the Julia output is shown may vary.
Examples
julia> s = Set{Any}(GAP.evalstr("[[1], [2], [1]]"), recursive = false);
julia> s == Set{Any}([GAP.evalstr("[ 1 ]"), GAP.evalstr("[ 2 ]")])
true
julia> s = Set{Any}(GAP.evalstr("SymmetricGroup(2)"), recursive = false);
julia> s == Set{Any}([GAP.evalstr("()"), GAP.evalstr("(1,2)")])
true
Base.Dict
— TypeDict{Symbol,T}(obj::GapObj; recursive = 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.evalstr("rec( 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.evalstr("rec( l:= [ 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,Array{Int,1}}(val, recursive = true)
Dict{Symbol,Array{Int64,1}} with 1 entry:
:l => [1, 2]
Convenience adapters
This section describes how one can manipulate GAP objects from the Julia side, using Julia syntax features.
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.Julia # Julia objects can be values of GAP variables
Main
GAP.call_gap_func
— Functioncall_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> g = GAP.Globals.SylowSubgroup( GAP.Globals.SymmetricGroup( 6 ), 2 )
GAP: Group([ (1,2), (3,4), (1,3)(2,4), (5,6) ])
julia> GAP.Globals.StructureDescription( g )
GAP: "C2 x D8"
julia> g = GAP.Globals.SylowSubgroup( GAP.Globals.SymmetricGroup( 6 ), 2 );
julia> GAP.Globals.StructureDescription( g, short = true )
GAP: "2xD8"
GAP.evalstr
— Functionevalstr(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, 1 )" )
julia> GAP.evalstr( "x" )
GAP: [ 1 ]
Base.getindex
— Functiongetindex(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 list.
Examples
julia> l = GAP.evalstr( "[ 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 = GAP.evalstr( "[ [ 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.setindex!
— Functionsetindex!(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 list.
Examples
julia> l = GAP.evalstr( "[ 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 Array{Int64,1}:
7
7
7
julia> l
GAP: [ 0, 7, 7, 7, 8, 13,, -1 ]
julia> m = GAP.evalstr( "[ [ 1, 2 ], [ 3, 4 ] ]" )
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> m[1,2] = 0
0
julia> m
GAP: [ [ 1, 0 ], [ 3, 4 ] ]
Base.getproperty
— Functiongetproperty(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 = GAP.evalstr( "rec( a:= 1 )" )
GAP: rec( a := 1 )
julia> r.a
1
Base.setproperty!
— Functionsetproperty!(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 = GAP.evalstr( "rec( a:= 1 )" )
GAP: rec( a := 1 )
julia> r.b = 0
0
julia> r
GAP: rec( a := 1, b := 0 )
Base.hasproperty
— Functionhasproperty(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 = GAP.evalstr( "rec( 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 )
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.
Julia | GAP |
---|---|
length | Length |
in | \in |
zero | ZERO |
one | ONE |
- (unary) | AINV |
+ | SUM |
- (binary) | DIFF |
* | PROD |
/ | QUO |
\ | LQUO |
^ | POW |
mod | MOD |
< | LT |
== | EQ |
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 ] )
GAP: [ [ 1, 2 ], [ 3, 4 ] ]
julia> length( l )
4
julia> length( m ) # different from Julia's behaviour
2
julia> 1 in l
true
julia> 2 in l
false
julia> zero( l )
GAP: [ 0, 0, 0, 0 ]
julia> one( m )
GAP: [ [ 1, 0 ], [ 0, 1 ] ]
julia> - l
GAP: [ -1, -3, -7, -15 ]
julia> l + 1
GAP: [ 2, 4, 8, 16 ]
julia> l + l
GAP: [ 2, 6, 14, 30 ]
julia> m + m
GAP: [ [ 2, 4 ], [ 6, 8 ] ]
julia> 1 - m
GAP: [ [ 0, -1 ], [ -2, -3 ] ]
julia> l * l
284
julia> l * m
GAP: [ 10, 14 ]
julia> m * m
GAP: [ [ 7, 10 ], [ 15, 22 ] ]
julia> 1 / m
GAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]
julia> m / 2
GAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]
julia> 2 \ m
GAP: [ [ 1/2, 1 ], [ 3/2, 2 ] ]
julia> m ^ 2
GAP: [ [ 7, 10 ], [ 15, 22 ] ]
julia> m ^ -1
GAP: [ [ -2, 1 ], [ 3/2, -1/2 ] ]
julia> mod( l, 3 )
GAP: [ 1, 0, 1, 0 ]
julia> m < 2 * m
true
julia> m^2 - 5 * m == 2 * one( m )
true
Access to the GAP help system
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
Managing GAP packages
The following functions allow one to load/install/update/remove GAP packages.
GAP.Packages.load
— Functionload(spec::String, version::String = ""; install = false)
Try to load the newest installed version of the GAP package with name spec
. Return true
if this is successful, and false
otherwise.
The function calls GAP's LoadPackage
function; the package banner is not printed.
If install
is set to true
and the required GAP package is not yet installed then install
is called first, in order to install the newest released version of the package.
GAP.Packages.install
— Functioninstall(spec::String, interactive::Bool = true)
Download and install the newest released version of the GAP package given by spec
in the pkg
subdirectory of GAP's build directory (variable GAP.GAPROOT
). Return true
if the installation is successful or if the package was already installed, 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 InstallPackage
from GAP's package PackageManager
.
GAP.Packages.update
— Functionupdate(spec::String)
Update the GAP package given by spec
that is installed in the pkg
subdirectory of GAP's build directory (variable GAP.GAPROOT
), 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
.
GAP.Packages.remove
— Functionremove(spec::String)
Remove the GAP package with name spec
that is installed in the pkg
subdirectory of GAP's build directory (variable GAP.GAPROOT
). Return true
if the removal was successful, and false
otherwise.
The function uses the function RemovePackage
from GAP's package PackageManager
.
Other
GAP.prompt
— Functionprompt()
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.
Index
GAP.Globals
Base.BitArray
Base.Cuchar
Base.Dict
Base.GMP.BigInt
Base.Matrix
Base.Rational
Base.Set
Base.StepRange
Base.UnitRange
Base.Vector
Core.Char
Core.Float64
Core.Int128
Core.String
Core.Symbol
Core.Tuple
GAP.FFE
GAP.GapObj
Base.big
Base.convert
Base.getindex
Base.getproperty
Base.hasproperty
Base.setindex!
Base.setproperty!
GAP.Packages.install
GAP.Packages.load
GAP.Packages.remove
GAP.Packages.update
GAP.call_gap_func
GAP.evalstr
GAP.gap_to_julia
GAP.julia_to_gap
GAP.prompt
GAP.show_gap_help
GAP.@g_str
GAP.@gap