diff --git a/JuliaExperimental/gap/gapperm.g b/JuliaExperimental/gap/gapperm.g index b9b6db896..800fed03f 100644 --- a/JuliaExperimental/gap/gapperm.g +++ b/JuliaExperimental/gap/gapperm.g @@ -42,8 +42,29 @@ BindGlobal( "ExtPermType", NewType( PermutationsFamily, IsExtPerm and IsPositionalObjectRep ) ); BindGlobal( "PermutationInJulia", - gapperm -> Objectify( ExtPermType, - [ Julia.GAPPermutations.Permutation( ConvertedToJulia( ListPerm( gapperm ) ) ) ] ) ); + function( gapperm, degree... ) + + if IsPerm( gapperm ) then + if Length( degree ) > 0 and IsInt( degree[1] ) then + gapperm:= ListPerm( gapperm, degree[1] ); + else + gapperm:= ListPerm( gapperm ); + fi; + elif IsPositionsList( gapperm ) then + if Length( degree ) > 0 and IsInt( degree[1] ) then + if degree[1] < Length( gapperm ) then + Error( "degree cannot be smaller than length of " ); + fi; + gapperm:= Concatenation( gapperm, + [ Length( gapperm ) + 1 .. degree[1] ] ); + fi; + else + Error( " must be a permutation or a list of positions" ); + fi; + + return Objectify( ExtPermType, + [ Julia.GAPPermutations.Permutation( GAPToJulia( gapperm ) ) ] ); + end ); BindGlobal( "WrappedPermutationInJulia", jperm -> Objectify( ExtPermType, [ jperm ] ) ); @@ -65,11 +86,11 @@ InstallMethod( ViewObj, [ IsExtPerm ], function( p ) end ); InstallMethod( \=, [ IsExtPerm, IsExtPerm ], function( p1, p2 ) - return ConvertedFromJulia( Julia.Base.("==")( p1![1], p2![1] ) ); + return Julia.Base.("==")( p1![1], p2![1] ); end ); InstallMethod( \<, [ IsExtPerm, IsExtPerm ], function( p1, p2 ) - return ConvertedFromJulia( Julia.Base.isless( p1![1], p2![1] ) ); + return Julia.Base.isless( p1![1], p2![1] ); end ); InstallMethod( \*, [ IsExtPerm, IsExtPerm ], function( p1, p2 ) @@ -79,23 +100,23 @@ InstallMethod( \*, [ IsExtPerm, IsExtPerm ], function( p1, p2 ) InstallMethod( \^, [ IsExtPerm, IsInt ], function( p1, n ) return WrappedPermutationInJulia( Julia.Base.("^")( - p1![1], ConvertedToJulia( n ) ) ); + p1![1], GAPToJulia( n ) ) ); end ); InstallMethod( \^, [ IsInt, IsExtPerm ], function( i, p ) - return ConvertedFromJulia( Julia.Base.("^")( ConvertedToJulia( i ), p![1] ) ); + return JuliaToGAP( IsInt, Julia.Base.("^")( GAPToJulia( i ), p![1] ) ); end ); InstallMethod( \/, [ IsInt, IsExtPerm ], function( i, p ) - return ConvertedFromJulia( Julia.Base.("/")( ConvertedToJulia( i ), p![1] ) ); + return JuliaToGAP( IsInt, Julia.Base.("/")( GAPToJulia( i ), p![1] ) ); end ); InstallMethod( LargestMovedPoint, [ IsExtPerm ], function( p ) - return ConvertedFromJulia( Julia.GAPPermutations.LargestMovedPointPerm( p![1] ) ); + return JuliaToGAP( IsInt, Julia.GAPPermutations.LargestMovedPointPerm( p![1] ) ); end ); InstallMethod( Order, [ IsExtPerm ], function( p ) - return ConvertedFromJulia( Julia.GAPPermutations.OrderPerm( p![1] ) ); + return JuliaToGAP( IsInt, Julia.GAPPermutations.OrderPerm( p![1] ) ); end ); InstallMethod( One, [ IsExtPerm ], p -> JuliaIdentityPerm ); diff --git a/JuliaExperimental/gap/hnf.g b/JuliaExperimental/gap/hnf.g index 960b45ed4..7013ff13f 100644 --- a/JuliaExperimental/gap/hnf.g +++ b/JuliaExperimental/gap/hnf.g @@ -20,114 +20,58 @@ JuliaIncludeFile( JuliaImportPackage( "Nemo" ); -#! @Arguments intmat -#! @Returns a Julia object -#! @Description -#! For a matrix intmat of integers, -#! this function creates the matrix of Nemo.fmpz integers in Julia -#! that has the same entries. -BindGlobal( "NemoIntegerMatrix_Eval", function( mat ) - local str, row; - - # Turn the integers into strings, and use 'JuliaEvalString'. - str:= "Nemo.ZZ["; - for row in mat do - Append( str, JoinStringsWithSeparator( List( row, String ), " " ) ); - Append( str, ";" ); - od; - str[ Length( str ) ]:= ']'; - return JuliaEvalString( str ); -end ); - - ## ## is assumed to be a list of lists of rationals. ## BindGlobal( "NemoMatrix_fmpq", function( mat ) - local arr, i, fmpz, fmpq, div, parse, map, alp, row, entry, num, den, s; + local arr, i, fmpz, div, row, entry; # Convert the entries to 'Nemo.fmpq' objects, # and use 'MatrixSpace' for creating the matrix in Julia. arr:= []; i:= 1; fmpz:= Julia.Nemo.fmpz; - fmpq:= Julia.Nemo.fmpq; div:= Julia.Base.( "//" ); - parse:= Julia.Base.parse; - map:= Julia.Base.map; - alp:= ConvertedToJulia( 16 ); for row in mat do for entry in row do - if IsSmallIntRep( entry ) then + if IsInt( entry ) then arr[i]:= entry; - elif IsInt( entry ) then - arr[i]:= parse( fmpz, HexStringInt( entry ), alp ); else - num:= parse( fmpz, HexStringInt( NumeratorRat( entry ) ), alp ); - den:= parse( fmpz, HexStringInt( DenominatorRat( entry ) ), alp ); - arr[i]:= div( num, den ); + arr[i]:= div( fmpz( NumeratorRat( entry ) ), + fmpz( DenominatorRat( entry ) ) ); fi; i:= i + 1; od; od; - arr:= map( fmpq, ConvertedToJulia( arr ) ); - s:= JuliaFunction( "MatrixSpace", "Nemo" ); - s:= s( Julia.Nemo.QQ, NumberRows( mat ), NumberColumns( mat ) ); - return s( arr ); + return Julia.Nemo.matrix( Julia.Nemo.QQ, + NumberRows( mat ), NumberColumns( mat ), + Julia.Base.map( Julia.Nemo.fmpq, GAPToJulia( arr ) ) ); end ); -## -## is assumed to be a list of lists of integers. -## -BindGlobal( "NemoMatrix_fmpz", function( mat ) - local arr, i, fmpz, parse, alp, row, entry, map, s; - - # Convert the entries to 'Nemo.fmpz' objects, - # and use 'MatrixSpace' for creating the matrix in Julia. - arr:= []; - i:= 1; - fmpz:= JuliaFunction( "fmpz", "Nemo" ); - parse:= JuliaFunction( "parse", "Base" ); - alp:= ConvertedToJulia( 16 ); - for row in mat do - for entry in row do - if IsSmallIntRep( entry ) then - arr[i]:= entry; - else - arr[i]:= parse( fmpz, HexStringInt( entry ), alp ); - fi; - i:= i + 1; - od; - od; - map:= JuliaFunction( "map", "Base" ); - arr:= map( fmpz, ConvertedToJulia( arr ) ); - s:= JuliaFunction( "MatrixSpace", "Nemo" ); - s:= s( Julia.Nemo.ZZ, NumberRows( mat ), NumberColumns( mat ) ); - - return s( arr ); -end ); +#! @Arguments intmat +#! @Returns a Julia object +#! @Description +#! For a matrix intmat of integers, +#! this function creates the matrix of Nemo.fmpz integers in Julia +#! that has the same entries. +BindGlobal( "NemoMatrix_fmpz", + mat -> Julia.Nemo.matrix( Julia.Nemo.ZZ, + NumberRows( mat ), NumberColumns( mat ), + Julia.Base.map( Julia.Nemo.fmpz, + GAPToJulia( Concatenation( mat ) ) ) ) ); ## ... BindGlobal( "GAPMatrix_fmpz_mat", function( nemomat ) - local result, getindex; + local result; # Reformat in Julia s. t. the result can be translated back to GAP. result:= Julia.GAPHNFModule.unpackedNemoMatrixFmpz( nemomat ); # Translate the Julia object to GAP. - getindex:= Julia.Base.getindex; - if ConvertedFromJulia( getindex( result, 1 ) ) = "int" then - # The entries are small integers. - return StructuralConvertedFromJulia( getindex( result, 2 ) ); - else - # The entries are hex strings encoding integers. - return List( ConvertedFromJulia( getindex( result, 2 ) ), - row -> List( ConvertedFromJulia( row ), - x -> IntHexString( ConvertedFromJulia( x ) ) ) ); - fi; + return JuliaToGAP( IsList, result, true ); end ); @@ -135,7 +79,7 @@ end ); ## The argument can be created with different methods. ## BindGlobal( "HermiteNormalFormIntegerMatUsingNemo", function( juliamat ) - local juliahnf, result, getindex; + local juliahnf; # Compute the HNF in Julia. juliahnf:= Julia.Nemo.hnf( juliamat ); diff --git a/JuliaExperimental/gap/numfield.g b/JuliaExperimental/gap/numfield.g index 20c779e76..fa4f0bc41 100644 --- a/JuliaExperimental/gap/numfield.g +++ b/JuliaExperimental/gap/numfield.g @@ -79,7 +79,7 @@ ElementsFamily( FamilyObj( Nemo_QQ ) )!.matrixType:= NewType( ## must be a list of strings (then a multivariate ring is created). ## BindGlobal( "Nemo_PolynomialRing", function( R, names ) - local type, juliaobj, efam, result, getindex, indets; + local type, juliaobj, efam, result, indets; type:= IsNemoPolynomialRing and IsAttributeStoringRep and IsFreeLeftModule and IsFLMLORWithOne; @@ -102,11 +102,13 @@ BindGlobal( "Nemo_PolynomialRing", function( R, names ) # Create the julia objects. if IsString( names ) then - juliaobj:= Julia.Nemo.PolynomialRing( JuliaPointer( R ), names ); + juliaobj:= Julia.Nemo.PolynomialRing( JuliaPointer( R ), + GAPToJulia( names ) ); elif IsList( names ) and ForAll( names, IsString ) then # Convert the names list from "Array{Any,1}" to "Array{String,1}". names:= Julia.Base.convert( JuliaEvalString( "Array{String,1}" ), - ConvertedToJulia( names ) ); + GAPToJulia( names ) ); +#T prescribe the type, no convert needed then? juliaobj:= Julia.Nemo.PolynomialRing( JuliaPointer( R ), names ); else Error( " must be a string or a list of strings" ); @@ -123,13 +125,12 @@ BindGlobal( "Nemo_PolynomialRing", function( R, names ) result!.isUnivariatePolynomialRing:= IsString( names ); # Store the GAP list of wrapped Julia indeterminates. - getindex:= Julia.Base.getindex; if IsString( names ) then # univariate case - indets:= [ getindex( juliaobj, 2 ) ]; + indets:= [ juliaobj[2] ]; else # multivariate case - indets:= ConvertedFromJulia( getindex( juliaobj, 2 ) ); + indets:= JuliaToGAP( IsList, juliaobj[2] ); fi; indets:= List( indets, x -> ObjectifyWithAttributes( rec(), @@ -137,7 +138,7 @@ BindGlobal( "Nemo_PolynomialRing", function( R, names ) JuliaPointer, x ) ); # Set attributes. - SetJuliaPointer( result, getindex( juliaobj, 1 ) ); + SetJuliaPointer( result, juliaobj[1] ); SetLeftActingDomain( result, R ); SetIndeterminatesOfPolynomialRing( result, indets ); SetGeneratorsOfLeftOperatorRingWithOne( result, indets ); @@ -176,7 +177,8 @@ BindGlobal( "Nemo_Polynomial", function( R, descr ) if ForAll( descr, IsInt ) then # Convert the coefficient list from "Array{Any,1}" to "Array{Int,1}". descr:= Julia.Base.convert( JuliaEvalString( "Array{Int,1}" ), - ConvertedToJulia( descr ) ); + GAPToJulia( descr ) ); +#T no need for convert if type prescribed! elif ForAll( descr, IsRat ) then # 'ConvertedToJulia' does not allow us to transfer rationals. fmpq:= Julia.Nemo.fmpq; @@ -191,7 +193,7 @@ BindGlobal( "Nemo_Polynomial", function( R, descr ) coeffs:= JuliaArrayOfFmpq( descr[1] ); monoms:= Julia.Base.convert( JuliaEvalString( "Array{Array{UInt,1},1}" ), - TransposedMat( descr[2] ) ); + GAPToJulia( TransposedMat( descr[2] ) ) ); else Error( " must be a list of length two" ); fi; @@ -221,9 +223,9 @@ BindGlobal( "GAPCoefficientsOfNemo_Polynomial", function( pol ) info:= Julia.GAPNemoExperimental.CoefficientsOfUnivarateNemoPolynomialFmpq( pol ); info:= Julia.GAPNemoExperimental.CoefficientsNumDenOfFmpqArray( info ); - num:= StructuralConvertedFromJulia( info[2] ); - den:= StructuralConvertedFromJulia( info[3] ); - if ConvertedFromJulia( info[1] ) = "int" then + num:= JuliaToGAP( IsList, info[2], true ); + den:= JuliaToGAP( IsList, info[3], true ); + if JuliaToGAP( info[1] ) = "int" then # Just convert the integers to GAP. return List( [ 1 .. Length( num ) ], i -> num[i] / den[i] ); else @@ -234,9 +236,9 @@ BindGlobal( "GAPCoefficientsOfNemo_Polynomial", function( pol ) else info:= JuliaGetFieldOfObject( pol, "coeffs" ); info:= Julia.GAPNemoExperimental.CoefficientsNumDenOfFmpqArray( info ); - num:= StructuralConvertedFromJulia( info[2] ); - den:= StructuralConvertedFromJulia( info[3] ); - if ConvertedFromJulia( info[1] ) = "int" then + num:= JuliaToGAP( IsList, info[2], true ); + den:= JuliaToGAP( IsList, info[3], true ); + if JuliaToGAP( info[1] ) = "int" then # Just convert the integers to GAP. info:= List( [ 1 .. Length( num ) ], i -> num[i] / den[i] ); else @@ -248,7 +250,7 @@ BindGlobal( "GAPCoefficientsOfNemo_Polynomial", function( pol ) JuliaGetFieldOfObject( pol, "exps" ) ); return [ info, - StructuralConvertedFromJulia( monomials ) ]; + JuliaToGAP( IsList, monomials, true ) ]; fi; end ); @@ -266,8 +268,7 @@ end ); #F Nemo_Field( , [, ] ) ## BindGlobal( "Nemo_Field", function( F, descr... ) - local name, coeffs, R, pol, juliaobj, efam, collfam, filt, result, - access, gen; + local name, coeffs, R, pol, juliaobj, efam, collfam, filt, result, gen; # Check the arguments. name:= "a"; @@ -301,7 +302,8 @@ BindGlobal( "Nemo_Field", function( F, descr... ) # Create the julia objects. R:= Nemo_PolynomialRing( F, "$" ); pol:= Nemo_Polynomial( R, coeffs ); - juliaobj:= Julia.Nemo.NumberField( JuliaPointer( pol ), name ); + juliaobj:= Julia.Nemo.NumberField( JuliaPointer( pol ), + GAPToJulia( name ) ); # Create the GAP wrapper. # Note that elements from two NEMO field extensions cannot be compared, @@ -318,11 +320,10 @@ BindGlobal( "Nemo_Field", function( F, descr... ) result:= Objectify( NewType( collfam, filt ), rec() ); # Set attributes. - access:= Julia.Base.getindex; - SetJuliaPointer( result, access( juliaobj, 1 ) ); + SetJuliaPointer( result, juliaobj[1] ); gen:= ObjectifyWithAttributes( rec(), efam!.defaultType, - JuliaPointer, access( juliaobj, 2 ) ); + JuliaPointer, juliaobj[2] ); SetLeftActingDomain( result, F ); SetDefiningPolynomial( result, pol ); SetRootOfDefiningPolynomial( result, gen ); @@ -356,7 +357,8 @@ BindGlobal( "ElementOfNemoNumberField", function( nemoF, coeffs ) # Convert the list of integral coefficient vectors # to a suitable matrix in Julia (Nemo.fmpz_mat). - res:= Julia.GAPUtilsExperimental.MatrixFromNestedArray( [ coeffs ] ); + res:= Julia.GAPUtilsExperimental.MatrixFromNestedArray( + GAPToJulia( [ coeffs ] ) ); res:= Julia.Nemo.matrix( Julia.Nemo.ZZ, res ); # Call the Julia function. @@ -438,18 +440,15 @@ InstallMethod( PreImageElm, FamRangeEqFamElm, [ "IsIsomorphismToNemoField", "IsNemoFieldElement" ], function( iso, elm ) - local numden, getindex, convert, num, den, coeffs, i; + local numden, convert, num, den, coeffs, i; numden:= Julia.GAPNumberFields.CoefficientVectorsNumDenOfNumberFieldElement( JuliaPointer( elm ), Dimension( Source( iso ) ) ); - getindex:= Julia.Base.getindex; convert:= Julia.Base.convert; - num:= StructuralConvertedFromJulia( - convert( JuliaEvalString( "Array{Int,1}" ), - getindex( numden, 1 ) ) ); - den:= StructuralConvertedFromJulia( - convert( JuliaEvalString( "Array{Int,1}" ), - getindex( numden, 2 ) ) ); + num:= JuliaToGAP( IsList, + convert( JuliaEvalString( "Array{Int,1}" ), numden[1] ), true ); + den:= JuliaToGAP( IsList, + convert( JuliaEvalString( "Array{Int,1}" ), numden[2] ), true ); coeffs:= []; for i in [ 1 .. Length( num ) ] do coeffs[i]:= num[i] / den[i]; @@ -530,7 +529,7 @@ InstallOtherMethod( ViewString, [ "IsNemoObject" ], InstallOtherMethod( \=, [ "IsNemoObject", "IsNemoObject" ], NEMO_RANK_SHIFT, function( x, y ) - return ConvertedFromJulia( + return JuliaToGAP( Julia.Base.("==")( JuliaPointer( x ), JuliaPointer( y ) ) ); end ); @@ -613,7 +612,8 @@ BindGlobal( "NemoMatrix", function( nemoF, gapmat ) # Convert the list of integral coefficient vectors # to a suitable matrix in Julia (Nemo.fmpz_mat). - res:= Julia.GAPUtilsExperimental.MatrixFromNestedArray( coeffs ); + res:= Julia.GAPUtilsExperimental.MatrixFromNestedArray( + GAPToJulia( coeffs ) ); # The following does not work in Nemo 0.6.0 but works in Nemo 0.7.3 ... res:= Julia.Nemo.matrix( Julia.Nemo.ZZ, res ); @@ -638,11 +638,11 @@ end ); #T different data format in Nemo for fmpz_mat and generic matrix over number fields! BindGlobal( "GAPMatrix", function( gapF, nemomat ) - local ptr, m, n, d, efam, list, getindex, nums, dens, result, k, i, j; + local ptr, m, n, d, efam, list, nums, dens, result, k, i, j; ptr:= JuliaPointer( nemomat ); - m:= ConvertedFromJulia( Julia.Nemo.rows( ptr ) ); - n:= ConvertedFromJulia( Julia.Nemo.cols( ptr ) ); + m:= Julia.Nemo.rows( ptr ); + n:= Julia.Nemo.cols( ptr ); d:= Dimension( gapF ); efam:= ElementsFamily( FamilyObj( gapF ) ); @@ -658,9 +658,8 @@ Error( "sorry, not yet implemented for matrices of rationals ..." ); JuliaPointer( nemomat ), d ); # Carry the coefficient vectors to GAP. - getindex:= Julia.Base.getindex; - nums:= GAPMatrix_fmpz_mat( getindex( list, 1 ) ); - dens:= GAPMatrix_fmpz_mat( getindex( list, 2 ) ); + nums:= GAPMatrix_fmpz_mat( list[1] ); + dens:= GAPMatrix_fmpz_mat( list[2] ); # Create the GAP matrix from the coefficient vectors. result:= []; @@ -692,18 +691,18 @@ end ); InstallMethod( NumberRows, [ "IsNemoMatrixObj" ], - nemomat -> ConvertedFromJulia( Julia.Nemo.rows( JuliaPointer( nemomat ) ) ) ); + nemomat -> Julia.Nemo.rows( JuliaPointer( nemomat ) ) ); InstallMethod( NumberColumns, [ "IsNemoMatrixObj" ], - nemomat -> ConvertedFromJulia( Julia.Nemo.cols( JuliaPointer( nemomat ) ) ) ); + nemomat -> Julia.Nemo.cols( JuliaPointer( nemomat ) ) ); #T hier!! InstallMethod( RankMat, [ "IsNemoMatrixObj" ], - nemomat -> ConvertedFromJulia( Julia.Base.rank( JuliaPointer( nemomat ) ) ) ); + nemomat -> Julia.Base.rank( JuliaPointer( nemomat ) ) ); #T RankMatDestructive? #T [] ? (absurd for mutable matrices) @@ -741,13 +740,13 @@ InstallMethod( RankMat, InstallMethod( MatElm, [ "IsNemoMatrixObj", "IsPosInt", "IsPosInt" ], function( nemomat, i, j ) - return Julia.Base.getindex( JuliaPointer( nemomat ), i, j ); + return JuliaPointer( nemomat )[ i, j ]; end ); InstallMethod( \[\], [ "IsNemoMatrixObj", "IsPosInt", "IsPosInt" ], function( nemomat, i, j ) - return Julia.Base.getindex( JuliaPointer( nemomat ), i, j ); + return JuliaPointer( nemomat )[ i, j ]; end ); #T InstallMethod( SetMatElm, diff --git a/JuliaExperimental/gap/realcyc.g b/JuliaExperimental/gap/realcyc.g index 82230d367..964b8d19a 100644 --- a/JuliaExperimental/gap/realcyc.g +++ b/JuliaExperimental/gap/realcyc.g @@ -35,16 +35,17 @@ BindGlobal( "IsPositiveRealPartCyclotomic", function( cyc ) fi; if ForAll( coeffs, IsSmallIntRep ) then - coeffs:= ConvertedToJulia( coeffs ); + coeffs:= GAPToJulia( coeffs ); else coeffs:= JuliaArrayOfFmpz( coeffs ); fi; res:= Julia.GAPRealCycModule.isPositiveRealPartCyc( coeffs ); if ValueOption( "ShowPrecision" ) = true then - Print( "#I precision needed: ", ConvertedFromJulia( res[2] ), "\n" ); + Print( "#I precision needed: ", JuliaToGAP( IsInt, res[2] ), "\n" ); fi; - return ConvertedFromJulia( res[1] ); + + return res[1]; end ); diff --git a/JuliaExperimental/gap/record.g b/JuliaExperimental/gap/record.g deleted file mode 100644 index 0c2ec3631..000000000 --- a/JuliaExperimental/gap/record.g +++ /dev/null @@ -1,110 +0,0 @@ -############################################################################## -## -## record.g -## -## Convert GAP records to Julia dictionaries and vice versa. -## -## No additional Julia code is needed for that. -## - - -############################################################################## -## -#! @Arguments arec -#! @Returns a &Julia; object -#! @Description -#! For a record arec, -#! this function creates a dictionary in &Julia; -#! whose components are the record components of arec, -#! and the corresponding -InstallMethod( ConvertedToJulia, - [ "IsRecord" ], - function( arec ) - local dict, setindex, comp, val; - - # Create an empty dictionary, in Julia one writes 'Dict()'. - # Note that 'Julia.Base.Dict' is not in 'IsJuliaFunction'; - # without a 'CallFuncList' method for 'IsJuliaObject', - # one would have to write - # dict:= _JuliaCallFunc0Arg( Julia.Base.Dict ); - dict:= Julia.Base.Dict(); - - # Add the components. - setindex:= Julia.Base.( "setindex!" ); - for comp in RecNames( arec ) do - # Do not call 'ConvertedToJulia', catch the 'fail' results. - val:= _ConvertedToJulia( arec.( comp ) ); -#T correct for IsJuliaFunction objects? - if val = fail then - # We cannot convert all components. - return fail; - fi; - setindex( dict, val, comp ); - od; - - return dict; -end ); - - -############################################################################## -## -#! @Arguments dict -#! @Returns a &GAP; record or fail -#! @Description -#! For a pointer dict to a &Julia; dictionary, -#! this function returns the &GAP; record whose components are the -#! keys of dict, and the values are the corresponding values. -#! If the global option "recursive" is true then -#! the lists and records that occur as values are unboxed recursively. -DeclareGlobalFunction( "ConvertedFromJuliaRecordFromDictionary" ); - - -############################################################################## -## -#! @Arguments obj -#! @Returns a &GAP; object -#! @Description -#! For a pointer obj to a &Julia; object, -#! this function does the same as , -#! except that also &Julia; dictionaries -DeclareGlobalFunction( "StructuralConvertedFromJulia_AlsoRecord" ); - - -InstallGlobalFunction( "ConvertedFromJuliaRecordFromDictionary", function( dict ) - local info, result, recursive, i, comp; - - info:= _ConvertedFromJulia_record_dict( dict ); - result:= rec(); - recursive:= ( ValueOption( "recursive" ) = true ); - for i in [ 1 .. Length( info[1] ) ] do - comp:= _ConvertedFromJulia( info[1][i] ); - if not IsString( comp ) then - # This dictionary cannot be converted to a GAP record. - return fail; - fi; - if recursive then - result.( comp ):= StructuralConvertedFromJulia_AlsoRecord( info[2][i] ); - else - result.( comp ):= info[2][i]; - fi; - od; - - return result; -end ); - - -InstallGlobalFunction( StructuralConvertedFromJulia_AlsoRecord, function( object ) - local unboxed_obj; - - unboxed_obj:= _ConvertedFromJulia( object ); - if IsList( unboxed_obj ) and not IsString( unboxed_obj ) then - return List( unboxed_obj, StructuralConvertedFromJulia_AlsoRecord ); - elif unboxed_obj = fail and - StartsWith( JuliaTypeInfo( object ), "Dict{" ) then - # The Julia object is a dictionary. - unboxed_obj:= ConvertedFromJuliaRecordFromDictionary( object : recursive ); - fi; - return unboxed_obj; -end ); - - diff --git a/JuliaExperimental/gap/singular.g b/JuliaExperimental/gap/singular.g index a76d1c049..7f925e9a2 100644 --- a/JuliaExperimental/gap/singular.g +++ b/JuliaExperimental/gap/singular.g @@ -195,12 +195,12 @@ BindGlobal( "SingularPolynomialRing", function( R, names ) # Convert the names list from "Array{Any,1}" to "Array{String,1}". names:= Julia.Base.convert( JuliaEvalString( "Array{String,1}" ), - ConvertedToJulia( names ) ); + GAPToJulia( names ) ); # Create the julia objects. # If we would be able to deal with keyword arguments # then wrapping would not be needed here. - dict:= ConvertedToJulia( rec( ring:= JuliaPointer( R ), + dict:= GAPToJulia( rec( ring:= JuliaPointer( R ), indeterminates:= names, cached:= true, ordering:= JuliaSymbol( ordering ), @@ -233,7 +233,7 @@ BindGlobal( "SingularPolynomialRing", function( R, names ) IsPolynomial and IsSingularObject and IsAttributeStoringRep, R ); # Store the GAP list of wrapped Julia indeterminates. - indets:= List( ConvertedFromJulia( juliaobj[2] ), + indets:= List( JuliaToGAP( IsList, juliaobj[2] ), x -> SingularElement( R, x ) ); SetIndeterminatesOfPolynomialRing( R, indets ); SetGeneratorsOfLeftOperatorRingWithOne( R, indets ); @@ -366,7 +366,7 @@ BindGlobal( "GroebnerBasisIdeal", function( I ) # Create the Singular ideal. R:= LeftActingRingOfIdeal( I ); juliaobj:= Julia.Base.std( JuliaPointer( I ) ); - gens:= List( [ 1 .. ConvertedFromJulia( Julia.Singular.ngens( juliaobj ) ) ], + gens:= List( [ 1 .. Julia.Singular.ngens( juliaobj ) ], i -> SingularElement( R, juliaobj[i] ) ); # Create the GAP domain. @@ -422,16 +422,14 @@ InstallOtherMethod( ViewString, InstallOtherMethod( \=, [ "IsSingularObject", "IsSingularObject" ], 100, function( x, y ) - return ConvertedFromJulia( - Julia.Base.("==")( JuliaPointer( x ), JuliaPointer( y ) ) ); + return Julia.Base.("==")( JuliaPointer( x ), JuliaPointer( y ) ); end ); #T 'Singular.jl' does not define 'isless' methods for polynomials. # InstallOtherMethod( \<, # [ "IsSingularObject", "IsSingularObject" ], # function( x, y ) -# return ConvertedFromJulia( -# Julia.Base.isless( JuliaPointer( x ), JuliaPointer( y ) ) ); +# return Julia.Base.isless( JuliaPointer( x ), JuliaPointer( y ) ) ); # end ); InstallOtherMethod( \+, diff --git a/JuliaExperimental/gap/utils.gi b/JuliaExperimental/gap/utils.gi index 37324a732..1e4ff861b 100644 --- a/JuliaExperimental/gap/utils.gi +++ b/JuliaExperimental/gap/utils.gi @@ -21,18 +21,6 @@ JuliaIncludeFile( DeclareAttribute( "JuliaPointer", IsObject ); -############################################################################## -## -#! @Arguments obj -#! @Returns a &Julia; object -#! @Description -#! For an object obj with attribute , -#! this function returns the value of this attribute. -InstallMethod( ConvertedToJulia, - [ "HasJuliaPointer" ], - obj -> JuliaPointer( obj ) ); - - ############################################################################## ## #F JuliaMatrixFromGapMatrix( ) @@ -42,7 +30,7 @@ InstallMethod( ConvertedToJulia, BindGlobal( "JuliaMatrixFromGapMatrix", function( gapmatrix ) local juliamatrix; - juliamatrix:= ConvertedToJulia( gapmatrix ); # nested array + juliamatrix:= GAPToJulia( gapmatrix ); # nested array return Julia.GAPUtilsExperimental.MatrixFromNestedArray( juliamatrix ); end ); diff --git a/JuliaExperimental/gap/zlattice.g b/JuliaExperimental/gap/zlattice.g index 25db863ea..939a4b6a8 100644 --- a/JuliaExperimental/gap/zlattice.g +++ b/JuliaExperimental/gap/zlattice.g @@ -37,8 +37,8 @@ BindGlobal( "ShortestVectorsUsingJulia", function( juliagrammat, bound ) # Convert the result to GAP. # We cannot simply unbox the rationals from the 'norms' component, # so we proceed in two steps. - r:= ConvertedFromJuliaRecordFromDictionary( juliaresult ); - r.vectors:= StructuralConvertedFromJulia( r.vectors ); + r:= JuliaToGAP( IsRecord, juliaresult ); + r.vectors:= JuliaToGAP( IsList, r.vectors, true ); # r.norms:= ... #T the entries can be Julia rationals; what to do? @@ -87,15 +87,15 @@ BindGlobal( "OrthogonalEmbeddingsUsingJulia", function( juliagrammat, arec... ) fi; # Compute the shortest vectors in Julia. - dict:= ConvertedToJulia( dict ); + dict:= GAPToJulia( dict ); juliaresult:= Julia.GAPZLattice.OrthogonalEmbeddings( juliagrammat, dict ); # Convert the result to GAP. # We cannot simply unbox the rationals from the 'norms' component, # so we proceed in two steps. - r:= ConvertedFromJuliaRecordFromDictionary( juliaresult ); - r.vectors:= StructuralConvertedFromJulia( r.vectors ); - r.solutions:= StructuralConvertedFromJulia( r.solutions ); + r:= JuliaToGAP( IsRecord, juliaresult ); + r.vectors:= JuliaToGAP( IsList, r.vectors, true ); + r.solutions:= JuliaToGAP( IsList, r.solutions, true ); # r.norms:= ... #T the entries can be Julia rationals; what to do? diff --git a/JuliaExperimental/julia/gapperm.jl b/JuliaExperimental/julia/gapperm.jl index 343e9e832..5fd47b61d 100644 --- a/JuliaExperimental/julia/gapperm.jl +++ b/JuliaExperimental/julia/gapperm.jl @@ -258,7 +258,7 @@ function PowPermInt( pL::Permutation2or4, n::Int ) # make sure that the buffer bag is large enough # clear the buffer bag - ptKnown = falses( pLimgs ) + ptKnown = falses( deg ) # loop over all cycles for p in 1:deg @@ -319,7 +319,7 @@ function PowPermInt( pL::Permutation2or4, n::Int ) # make sure that the buffer bag is large enough # clear the buffer bag - ptKnown = falses( pLimgs ) + ptKnown = falses( deg ) # get pointer to the permutation and the power exp = -n @@ -404,21 +404,21 @@ function QuoIntPerm( n::Int, pR::Permutation2or4 ) end +## Here the syntax is different from that in GAP's C code. function LargestMovedPointPerm( perm::Permutation2or4 ) local permimgs, sup permimgs = perm.imgs - sup = 0 # find the largest moved point for sup in perm.degree:-1:1 if permimgs[ sup ] != sup - break + return sup end end # return it - return sup + return 0 end @@ -429,7 +429,7 @@ function OrderPerm( perm::Permutation2or4 ) # make sure that the buffer bag is large enough # clear the buffer bag - ptKnown2 = falses( permimgs ) + ptKnown2 = falses( perm.degree ) # start with order 1 ord = 1 diff --git a/JuliaExperimental/julia/hnf.jl b/JuliaExperimental/julia/hnf.jl index 8b4aa473d..0b2a872df 100644 --- a/JuliaExperimental/julia/hnf.jl +++ b/JuliaExperimental/julia/hnf.jl @@ -14,35 +14,17 @@ function fitsGAPSmallIntRep( x::Nemo.fmpz ) end """ - unpackedNemoMatrixFmpz( nemomat::Nemo.fmpz_mat[, tryint::Bool = true] ) -> Return a tuple `(, )` where is a 1-dim. array -> of 1-dim. arrays (corresponding to the rows of `nemomat`), -> and is either `"int"` (the entries are small integers) -> or `"string"` (the entries are hex strings). -> This format is suitable for calling `ConvertedFromJulia` from GAP. + unpackedNemoMatrixFmpz( nemomat::Nemo.fmpz_mat ) +> Return a 1-dim. array of 1-dim. arrays of Julia integers, +> corresponding to the rows of `nemomat`. """ -function unpackedNemoMatrixFmpz( nemomat::Nemo.fmpz_mat, tryint::Bool = true ) - m, n = size( nemomat ) - - if tryint == true - # Check whether the entries are small enough for being unboxed - # to small integers in GAP, i. e., in the range '[ -2^60 .. 2^60-1 ]'. - fits = [ fitsGAPSmallIntRep( nemomat[i,j] ) for i in 1:m, j in 1:n ] - if all( fits ) - # Turn the Nemo matrix into a 2-dim. Julia array of integers. - mat = Matrix{Int}( nemomat ) - - # Turn the 2-dim. array into a 1-dim. array of 1-dim. arrays - # of small integers (which can then be unboxed with 'ConvertedFromJulia'). - return ( "int", map( i -> mat[i,:], 1:size(mat,1) ) ) - end - end - - # Either we *want* to create a nested array of strings, - # or some entry is too large. +function unpackedNemoMatrixFmpz( nemomat::Nemo.fmpz_mat ) + # Turn the Nemo matrix into a 2-dim. Julia array of integers. + mat = Matrix{BigInt}( nemomat ) + # Turn the 2-dim. array into a 1-dim. array of 1-dim. arrays - # (which can then be unboxed with 'ConvertedFromJulia'). - return ( "string", [ [ hex( nemomat[i,j] ) for j in 1:n ] for i in 1:n ] ) + # of small integers (which can then be unboxed with 'ConvertedFromJulia'). + return map( i -> mat[i,:], 1:size(mat,1) ) end end diff --git a/JuliaExperimental/julia/singular.jl b/JuliaExperimental/julia/singular.jl index b22e36499..5dd91ca2c 100644 --- a/JuliaExperimental/julia/singular.jl +++ b/JuliaExperimental/julia/singular.jl @@ -26,12 +26,12 @@ export SingularPolynomialRingWrapper > But none of these has a suitable syntax for 'jl_call'. > (Note the semicolon in the last two cases above.) """ -function SingularPolynomialRingWrapper( dict::Dict{Any,Any} ) - return Singular.PolynomialRing( dict[ "ring" ], dict[ "indeterminates" ]; - cached = dict[ "cached" ], - ordering = dict[ "ordering" ], - ordering2 = dict[ "ordering2" ], - degree_bound = dict[ "degree_bound" ] ) +function SingularPolynomialRingWrapper( dict::Dict{Symbol,Any} ) + return Singular.PolynomialRing( dict[ :ring ], dict[ :indeterminates ]; + cached = dict[ :cached ], + ordering = dict[ :ordering ], + ordering2 = dict[ :ordering2 ], + degree_bound = dict[ :degree_bound ] ) end end diff --git a/JuliaExperimental/julia/zlattice.jl b/JuliaExperimental/julia/zlattice.jl index f82572bca..1a9a417a5 100644 --- a/JuliaExperimental/julia/zlattice.jl +++ b/JuliaExperimental/julia/zlattice.jl @@ -100,15 +100,16 @@ function LLLReducedGramMat( grammatrix::Array{Int,2}, y::Rational{Int} = 3//4 ) n = size( gram, 1 ) k = 2 kmax = 1 - mue = zeros( gram ) +# mue = zeros( gram ) # this worked in earlier Julia versions ... + mue = zeros( Rational{Int}, n, n ) r = 0 - ak = Array{Rational{Int}}( n ) -# H = Array{Array{Rational{Int},1},1}( n ) + ak = Array{Rational{Int},1}( undef, n ) +# H = Array{Array{Rational{Int},1},1}( undef, n ) # for i = 1:n # H[i] = zeros( Rational{Int}, n ) # H[i][i] = 1 # end - H = eye( gram ) + H = one( gram ) # Info( InfoZLattice, 1, # "LLLReducedGramMat called with matrix of length ", n, @@ -144,7 +145,7 @@ function LLLReducedGramMat( grammatrix::Array{Int,2}, y::Rational{Int} = 3//4 ) end - B = Array{Rational{Int},1}( n ) + B = Array{Rational{Int},1}( undef, n ) B[1] = gram[1,1] while k <= n @@ -327,13 +328,13 @@ function LLLReducedGramMat( grammatrix::Array{Int,2}, y::Rational{Int} = 3//4 ) mue = mue[ (r+1):n, 1:n ] B = B[ (r+1):n ] - return Dict( "remainder" => gram, - # "relations" => reshape( hcat( H[ 1:r ]... ), r, n ), - "relations" => H[ 1:r, : ], - # "transformation" => reshape( hcat( H[ (r+1):n ]... ), n-r, n ), - "transformation" => H[ (r+1):n, : ], - "mue" => mue, - "B" => B ); + return Dict( :remainder => gram, + # :relations => reshape( hcat( H[ 1:r ]... ), r, n ), + :relations => H[ 1:r, : ], + # :transformation => reshape( hcat( H[ (r+1):n ]... ), n-r, n ), + :transformation => H[ (r+1):n, : ], + :mue => mue, + :B => B ); end @@ -455,14 +456,14 @@ function ShortestVectors( grammat::Array{Int,2}, bound::Int, positive::String = end llg = LLLReducedGramMat( grammat ) - mue = llg[ "mue" ] - B = llg[ "B" ] - transformation = llg[ "transformation" ] + mue = llg[ :mue ] + B = llg[ :B ] + transformation = llg[ :transformation ] # main program srt( n, 0 ) - return Dict( "vectors" => c_vectors, "norms" => c_norms ) + return Dict( :vectors => c_vectors, :norms => c_norms ) end @@ -637,8 +638,8 @@ row = M[ii] if haskey( arec, "vectors" ) x = arec[ "vectors" ] if isa( x, Array ) - x = Dict( "vectors" => x, - "norms" => map( v -> sum( ( v * AinvI ) .* v ), x ) ) + x = Dict( :vectors => x, + :norms => map( v -> sum( ( v * AinvI ) .* v ), x ) ) #T does not work at all!! # and .* is slow! end @@ -650,14 +651,14 @@ row = M[ii] end end - norms = sv[ "norms" ] - x = sv[ "vectors" ] + norms = sv[ :norms ] + x = sv[ :vectors ] m = length( x ) if m == 0 - return Dict( "vectors" => x, - "norms" => map( x -> x / denom, norms ), - "solutions" => [] ) + return Dict( :vectors => x, + :norms => map( x -> x / denom, norms ), + :solutions => [] ) end # println( "found $m vectors" ) @@ -702,9 +703,9 @@ row = M[ii] x = map( pair -> pair[2], tosort ) # Initialize the result record. - out = Dict( "vectors" => x, - "norms" => map( x -> x / denom, norms ), - "solutions" => [] ) + out = Dict( :vectors => x, + :norms => map( x -> x / denom, norms ), + :solutions => [] ) # 'x2[i]' stores the contribution of 'x[i]' to the diagonal of 'A'. x2 = map( v -> map( y -> y^2, v ), x ) @@ -892,7 +893,7 @@ row = M[ii] push!( single, j ) end end - push!( out[ "solutions" ], single ) + push!( out[ :solutions ], single ) end return out diff --git a/JuliaExperimental/read.g b/JuliaExperimental/read.g index 47cc77e98..88f7d669d 100644 --- a/JuliaExperimental/read.g +++ b/JuliaExperimental/read.g @@ -13,10 +13,6 @@ ReadPackage( "JuliaExperimental", "gap/utils.gi"); # BindJuliaFunc( "juliabox_cycs" ); # -# Translate GAP records to Julia dictionaries and vice versa. -ReadPackage( "JuliaExperimental", "gap/record.g"); - - # shortest vectors, LLL, orthogonal embeddings ReadPackage( "JuliaExperimental", "gap/zlattice.g"); diff --git a/JuliaExperimental/tst/gapperm.tst b/JuliaExperimental/tst/gapperm.tst new file mode 100644 index 000000000..6dce07a96 --- /dev/null +++ b/JuliaExperimental/tst/gapperm.tst @@ -0,0 +1,155 @@ +############################################################################# +## +#W gapperm.tst GAP 4 package JuliaExperimental Thomas Breuer +## +gap> START_TEST( "gapperm.tst" ); + +## +gap> p1:= PermutationInJulia( (1,2,3) ); +> +gap> p1 = PermutationInJulia( (1,2,3) ); +true +gap> p1 = PermutationInJulia( (1,2,3), 6 ); +true +gap> p1 = PermutationInJulia( [ 2, 3, 1 ] ); +true +gap> p1 = PermutationInJulia( [ 2, 3, 1 ], 6 ); +true +gap> oneperm:= One( p1 ); +> +gap> p1 = oneperm; +false +gap> oneperm = p1; +false +gap> p1 < oneperm; +false +gap> oneperm < p1; +true + +## +gap> p1:= PermutationInJulia( (1,2) ); +> +gap> p2:= PermutationInJulia( (2,3) ); +> +gap> p1 = p2; +false +gap> p2 = p1; +false +gap> p1 < p2; +false +gap> p2 < p1; +true + +## +gap> p11:= PermutationInJulia( (1,2), 3 ); +> +gap> p11 = p1; +true +gap> p1 = p11; +true +gap> p1 < p11; +false +gap> p11 < p1; +false + +## +gap> ViewString( p1 ); +">" + +## +gap> p1 * oneperm; +> +gap> oneperm * p1; +> +gap> prod:= p1 * p2; +> +gap> prod * prod; +> +gap> oneperm * oneperm; +> + +## +gap> Order( prod ); +3 +gap> Order( p1 ); +2 +gap> Order( p2 ); +2 +gap> Order( p11 ); +2 +gap> Order( PermutationInJulia( [ 2, 1, 4, 5, 3 ] ) ); +6 +gap> Order( PermutationInJulia( [ 2, 1, 4, 5, 3 ], 10 ) ); +6 + +## +gap> LargestMovedPoint( prod ); +3 +gap> LargestMovedPoint( oneperm ); +0 +gap> LargestMovedPoint( p1 ); +2 +gap> LargestMovedPoint( p11 ); +2 +gap> LargestMovedPoint( p2 ); +3 + +## +gap> Inverse( oneperm ); +> +gap> Inverse( p1 ); +> +gap> Inverse( p11 ); +> +gap> Inverse( p2 ); +> +gap> Inverse( prod ); +> + +## +gap> p1^-4711; +> +gap> p1^-9; +> +gap> p1^-8; +> +gap> p1^-2; +> +gap> p1^-1; +> +gap> p1^0; +> +gap> p1^1; +> +gap> p1^2; +> +gap> p1^8; +> +gap> p1^9; +> +gap> p1^4711; +> + +## +gap> 1^prod; +3 +gap> 2^prod; +1 +gap> 3^prod; +2 +gap> 4^prod; +4 + +## +gap> 1 / prod; +2 +gap> 2 / prod; +3 +gap> 3 / prod; +1 +gap> 4 / prod; +4 + +## +gap> STOP_TEST( "gapperm.tst", 1 ); + diff --git a/JuliaExperimental/tst/hnf.tst b/JuliaExperimental/tst/hnf.tst index e2f394cb8..137205b35 100644 --- a/JuliaExperimental/tst/hnf.tst +++ b/JuliaExperimental/tst/hnf.tst @@ -11,7 +11,7 @@ gap> START_TEST( "hnf.tst" ); ## gap> for dim in [ 10, 20 .. 60 ] do > m:= RandomMat( dim, dim, Integers );; -> m_julia:= NemoIntegerMatrix_Eval( m );; +> m_julia:= NemoMatrix_fmpz( m );; > hnf_gap:= HermiteNormalFormIntegerMat( m );; > hnf_nemo:= HermiteNormalFormIntegerMatUsingNemo( m_julia );; > if hnf_gap <> hnf_nemo then @@ -19,6 +19,15 @@ gap> for dim in [ 10, 20 .. 60 ] do > fi; > od; +## +gap> m_julia:= NemoMatrix_fmpz( [ [ 1, 2 ], [ 3, 2^65 ] ] ); + +gap> GAPMatrix_fmpz_mat( m_julia ); +[ [ 1, 2 ], [ 3, 36893488147419103232 ] ] +gap> HermiteNormalFormIntegerMatUsingNemo( m_julia ); +[ [ 1, 2 ], [ 0, 36893488147419103226 ] ] + ## gap> STOP_TEST( "hnf.tst", 1 ); diff --git a/JuliaExperimental/tst/record.tst b/JuliaExperimental/tst/record.tst deleted file mode 100644 index b0cade7da..000000000 --- a/JuliaExperimental/tst/record.tst +++ /dev/null @@ -1,36 +0,0 @@ -############################################################################# -## -#W record.tst GAP 4 package JuliaExperimental Thomas Breuer -## -## -gap> START_TEST( "record.tst" ); - -## empty record -gap> dict:= ConvertedToJulia( rec() ); - -gap> ConvertedFromJulia( dict ); -fail -gap> ConvertedFromJuliaRecordFromDictionary( dict ); -rec( ) -gap> StructuralConvertedFromJulia_AlsoRecord( dict ); -rec( ) - -# ## something which cannot be boxed -# gap> ConvertedToJulia( rec( GAPfunc:= ( x -> 1 ) ) ); -# fail - -## something which is recursive -gap> dict:= ConvertedToJulia( rec( bool:= true, -> string:= "abc", -> list:= [ 1, 2, 3 ], -> Juliafunc:= Julia.Base.map, -> ) );; -gap> ConvertedFromJuliaRecordFromDictionary( dict ); -rec( Juliafunc := , bool := , - list := , string := ) -gap> StructuralConvertedFromJulia_AlsoRecord( dict ); -rec( Juliafunc := fail, bool := true, list := [ 1, 2, 3 ], string := "abc" ) - -## -gap> STOP_TEST( "record.tst", 1 ); - diff --git a/JuliaExperimental/tst/testall.g b/JuliaExperimental/tst/testall.g index 9cfaba043..7eb090ceb 100644 --- a/JuliaExperimental/tst/testall.g +++ b/JuliaExperimental/tst/testall.g @@ -8,10 +8,10 @@ LoadPackage( "JuliaExperimental" ); pairs:= [ [ "gapnemo.tst", [ "Nemo" ] ], + [ "gapperm.tst", [] ], [ "hnf.tst", [ "Nemo" ] ], [ "numfield.tst", [ "Nemo" ] ], [ "realcyc.tst", [ "Nemo" ] ], - [ "record.tst", [] ], [ "singular.tst", [ "Singular" ] ], [ "utils.tst", [] ], ]; diff --git a/JuliaInterface/tst/convert.tst b/JuliaInterface/tst/convert.tst index 9e31ada2b..abd963bfd 100644 --- a/JuliaInterface/tst/convert.tst +++ b/JuliaInterface/tst/convert.tst @@ -170,5 +170,32 @@ gap> xx := JuliaEvalString("GAP.GAPFuncs.PROD(2^59,2^59)");; gap> JuliaToGAP( IsInt, xx ); 332306998946228968225951765070086144 +### +### Records/Dictionaries +### + +## empty record +gap> dict:= GAPToJulia( rec() ); + +gap> JuliaToGAP( IsRecord, dict ); +rec( ) + +## nested record: non-recursive vs. recursive +gap> dict:= GAPToJulia( rec( bool:= true, +> string:= "abc", +> list:= [ 1, 2, 3 ], +> ) );; +gap> JuliaToGAP( IsRecord, dict ); +rec( bool := true, list := , string := ) +gap> JuliaToGAP( IsRecord, dict, true ); +rec( bool := true, list := [ 1, 2, 3 ], string := "abc" ) + +## something where recursive conversion would run into a Julia error +gap> dict:= GAPToJulia( rec( juliafunc:= Julia.Base.map, +> ) ); +map)> +gap> JuliaToGAP( IsRecord, dict ); +rec( juliafunc := ) + ## gap> STOP_TEST( "convert.tst", 1 );