Interpreter Functionality
Singular.jl provides limited access to the functionality of the Singular interpreter and its associated standard library procedures. The following features of the Singular language are not supported:
The singular language allows arbitrary attributes to be attached to each object. These are not supported because Singular.jl works with the raw kernel types ring, poly, ideal, etc. that do not have attributes.
Maps between polynomial rings cannot be effectively communicated between the Singular language and Singular.jl because the Singular language tracks the preimage ring by name only and the rings in Singular.jl do not have names.
Very few library procedures work with Nemo rings and fields.
Calling a Library Procedure
In general, if we have a procedure sort
in general.lib
, then the corresponding function in Singular.jl
is called Singular.LibGeneral.sort
. The full list of libraries included can be viewed by typing Singular.Lib
at the REPL and double pressing the tab key.
One issue that comes up in calling library procedures is the implicit argument basering
that all procedures receive in the Singular language. Singular.jl
tries to infer the base ring from the arguments provided to the function. When this fails or is simply not possible, the user can always provide a base ring by passing it in as the first argument to the Singular.jl
function. Note that if the first argument to the Singular.jl
version of a library procedure is a polynomial or non-commutative ring, then this is automatically assumed to be the base ring. Hence, if a procedure in the Singular language takes a ring as a first argument, you will have to pass that ring as the second argument after specifying the base ring in the first argument.
Examples
This example illustrates passing Singular lists and providing the base ring.
julia> r0, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"], ordering=ordering_lp());
julia> Singular.LibGeneral.sort([x, y])
ERROR: `intvec` may be passed in as Vector{Int}. All other vectors (`list` in Singular) must be passed in as Vector{Any} along with an explicit base ring in the first argument
julia> Singular.LibGeneral.sort(r0, Any[x, y])
2-element Vector{Vector}:
spoly{n_Q}[y, x]
[2, 1]
This example illustrates the base ring inference:
julia> AA, (x, y, z, t) = polynomial_ring(QQ, ["x", "y", "z", "t"]);
julia> D = zero_matrix(AA, 4, 4);
julia> D[1,2] = -z; D[1,3] = 2*x; D[2,3] = -2*y;
julia> A, (x, y, z, t) = GAlgebra(AA, 1, D);
julia> Singular.LibNctools.isCentral(x) # base ring A is inferred from x
0
julia> Singular.LibCentral.center(A, 3) # base ring cannot be inferred from the plain Int 3
Singular ideal over Singular G-algebra (QQ),(x,y,z,t),(dp(4),C) with generators (t, 4*x*y + z^2 - 2*z)
Global Interpreter Variables
The function Singular.call_interpreter
can be used to execute arbitrary strings inside the Singular interpreter, and the function Singular.lookup_library_symbol
fetches results from the interpreter.
Singular.lookup_library_symbol
— Methodlookup_library_symbol(package::String, name::String)
Attempt to look up a symbol in a particular Singular interpreter package and return its value as a usable Singular.jl object. The package at the top level is called "Top", and ring dependent objects are contained in their basering, which is returned as a dictionary.
Examples
julia> Singular.call_interpreter("bigint a = 42;");
julia> a = Singular.lookup_library_symbol("Top", "a"); (a, typeof(a))
(42, BigInt)
julia> Singular.call_interpreter("ring r=0,(x,y,z),dp; poly f = (x+y)^2;");
julia> Singular.lookup_library_symbol("Top", "r")
2-element Vector{Any}:
Singular polynomial ring (QQ),(x,y,z),(dp(3),C)
Dict{Symbol, spoly{n_Q}}(:f => x^2 + 2*x*y + y^2)
Global Kernel Variables
The global variables degBound
and multBound
can be used in a local fashion. As with any global variable, their usage should be accompanied with caution.
Singular.with_degBound
— Methodwith_degBound(f, degb::Integer)
Evaluate and return f()
with the Singular global setting degBound = degb
. The value of degBound
is automatically restored upon return; the effect is only a local one on f()
. The value degBound = 0
corresponds to no degree bound in Singular and this is the starting value.
Singular.with_multBound
— Methodwith_multBound(f, mu::Integer)
Evaluate and return f()
with the Singular global setting multBound = mu
. The value of multBound
is automatically restored upon return; the effect is only a local one on f()
. The value multBound = 0
corresponds to no multiplicity bound in Singular and this is the starting value.
The following options are available. The usage of, say, the option infRefTail
would be as with_infRefTail(f, flag::Bool)
where the same do-block syntax can be used as with the degree bounds.
fastHC, infRedTail, lazy, length, notBuckets, prot, qringNF, redTail, redThrough
Examples
julia> r, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"], ordering=ordering_ds());
julia> i = Ideal(r, [x^7+y^7+z^6,x^6+y^8+z^7,x^7+y^5+z^8,x^2*y^3+y^2*z^3+x^3*z^2,x^3*y^2+y^3*z^2+x^2*z^3]);
julia> degree(std(i)) # default behaviour of no multiplicity bound
(0, 86)
julia> with_multBound(100) do
# run with a multiplicity bound of 100
return degree(std(i))
end
(0, 98)
julia> degree(std(i)) # back to default behaviour
(0, 86)
julia> gens(std(i))
11-element Vector{spoly{n_Q}}:
x^3*y^2 + y^3*z^2 + x^2*z^3
x^2*y^3 + x^3*z^2 + y^2*z^3
y^5 + x^7 + z^8
x^6 + z^7 + y^8
x^4*z^2 - y^4*z^2 - x^2*y*z^3 + x*y^2*z^3
z^6 + x^7 + y^7
y^4*z^3 - y^3*z^4 - x^2*z^5 - x^9
x^3*y*z^4 - x^2*y^2*z^4 + x*y^3*z^4 - y^4*z^4 + x^3*z^5 - x^2*y*z^5
x^3*z^5
x^2*y*z^5 + y^3*z^5 + x^2*z^6
x*y^3*z^5
julia> gens(with_degBound(5) do; return std(i); end)
5-element Vector{spoly{n_Q}}:
x^3*y^2 + y^3*z^2 + x^2*z^3
x^2*y^3 + x^3*z^2 + y^2*z^3
y^5 + x^7 + z^8
x^6 + z^7 + y^8
z^6 + x^7 + y^7
julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"])
(Singular polynomial ring (QQ),(x,y),(dp(2),C), spoly{n_Q}[x, y])
julia> with_prot(true) do; return std(Ideal(R, x^5 - y*x + 1, y^6*x + x^2 + y^3)); end
[4294967295:2]5s7s11s1214-s15
product criterion:1 chain criterion:1
Singular ideal over Singular polynomial ring (QQ),(x,y),(dp(2),C) with generators (x^5 - x*y + 1, x*y^6 + y^3 + x^2, x^4*y^3 - y^6 - y^4 - x, y^9 + y^7 + x^3*y^3 + x*y^3 + x*y - 1)