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 GapObj(x, cache::GapCacheDict = nothing; recursive::Bool = false)
, 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::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.GapObj
— TypeGapObj(input, recursion_dict::GapCacheDict = nothing; recursive::Bool = false)
GapObj(input, recursive::Bool = false)
One can use the type GapObj
as a constructor, in order to convert the julia object input
to an appropriate GAP object.
If recursive
is set to true
, recursive conversion of nested Julia objects (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> GapObj(1//3)
GAP: 1/3
julia> GapObj("abc")
GAP: "abc"
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 ] ]
Note that this conversion is not restricted to outputs that actually are of type GapObj
, also GAP integers, finite field elements, and booleans can be created by the constructor GapObj
.
julia> res = GapObj(42); res isa GapObj
false
julia> res isa GAP.Obj
true
The following GapObj
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 |
Set{T} | IsList |
Tuple{T} | IsList |
Matrix{T} | IsList |
Dict{String, T} , Dict{Symbol, T} | IsRecord |
UnitRange{T} , StepRange{T, S} | IsRange |
Function | IsFunction |
Constructor Methods for GAP-to-Julia Conversions
(For Julia-to-GAP conversions, one can use GapObj
and GAP.Obj
as constructors.)
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)
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.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.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.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
Core.Float64
— TypeFloat64(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.Char
— TypeChar(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)
Base.Cuchar
— TypeCuchar(obj::GapObj)
Return the UInt8
that belongs to the GAP character obj
.
Examples
julia> val = GAP.Obj('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.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
— TypeSymbol(obj::GapObj)
Return the symbol converted from the GAP string obj
.
Examples
julia> str = GAP.Obj("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.Obj(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.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}
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 ])
Base.BitVector
— TypeBitVector(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.Vector
— TypeVector{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
Base.Matrix
— TypeMatrix{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.Set
— TypeSet{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.Dict
— TypeDict{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]