From 0b5a8c5de0aebd607875b4df35b56feb63f21dd4 Mon Sep 17 00:00:00 2001 From: Sebastian Gutsche <gutsche@momo.math.rwth-aachen.de> Date: Tue, 14 May 2019 22:48:52 +0200 Subject: [PATCH] First version of caller - WIP --- .gitignore | 1 + deps/build.jl | 3 + deps/parselibs.jl | 46 ++++ deps/src/CMakeLists.txt | 4 +- deps/src/caller.cpp | 358 ++++++++++++++++++++++++++++++ deps/src/caller.h | 8 + deps/src/coeffs.cpp | 7 +- deps/src/ideals.cpp | 4 +- deps/src/singular.cpp | 90 ++++---- src/LibSingular.jl | 2 + src/Meta.jl | 34 +++ src/Singular.jl | 11 + src/caller.jl | 189 ++++++++++++++++ src/ideal/ideal.jl | 20 +- src/module/ModuleTypes.jl | 24 ++ src/module/module.jl | 12 +- src/number/NumberTypes.jl | 2 +- src/poly/PolyTypes.jl | 7 + src/poly/poly.jl | 4 + src/resolution/ResolutionTypes.jl | 11 +- src/resolution/resolution.jl | 48 ++-- test/caller-test.jl | 46 ++++ test/runtests.jl | 21 +- 23 files changed, 849 insertions(+), 103 deletions(-) create mode 100644 deps/parselibs.jl create mode 100644 deps/src/caller.cpp create mode 100644 deps/src/caller.h create mode 100644 src/Meta.jl create mode 100644 src/caller.jl create mode 100644 test/caller-test.jl diff --git a/.gitignore b/.gitignore index b064b7d66..0ef780992 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ docs/build *.jl.*.cov *.jl.mem .gitattributes +/src/libraryfuncdictionary.jl diff --git a/deps/build.jl b/deps/build.jl index f6bd3dba4..0a4d72a3a 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -98,6 +98,7 @@ withenv("CPP_FLAGS"=>"-I$vdir/include", "LD_LIBRARY_PATH"=>"$vdir/lib:$nemodir/l cmd = split( """ $srcs/configure + --with-libparse --prefix=$vdir --libdir=$vdir/lib --disable-static @@ -152,3 +153,5 @@ print("Running cmake") run(`make VERBOSE=1`) run(`make install`) +include("parselibs.jl") + diff --git a/deps/parselibs.jl b/deps/parselibs.jl new file mode 100644 index 000000000..2510a9295 --- /dev/null +++ b/deps/parselibs.jl @@ -0,0 +1,46 @@ +function execute(cmd::Cmd) + out = Pipe() + err = Pipe() + + process = run(pipeline(ignorestatus(cmd), stdout = out, stderr = err)) + close(out.in) + close(err.in) + + (stdout = String(read(out)), + stderr = String(read(err)), + code = process.exitcode) +end + +libparsepath = abspath(joinpath(@__DIR__, "..", "local", "bin", "libparse")) + +library_dir = "" + +if haskey(ENV, "SINGULAR_LIBRARY_DIR") + library_dir = ENV["SINGULAR_LIBRARY_DIR"] +else + library_dir = abspath(joinpath(@__DIR__, "..", "local", "share", "singular", "LIB")) +end + +filenames = filter(x -> endswith(x, ".lib"), readdir(library_dir)) + +output_filename = abspath(joinpath(@__DIR__, "..", "src", "libraryfuncdictionary.jl")) + +open(output_filename, "w") do outputfile + println(outputfile, "libraryfunctiondictionary = Dict(") + for i in filenames + full_path = joinpath(library_dir, i) + libs = execute(`$libparsepath $full_path`) + if libs.stderr != "" + error("from libparse: $(libs.stderr)") + end + libs_splitted = split(libs.stdout,"\n")[4:end-1] + libs_splitted = [ split(i," ") for i in libs_splitted ] + libs_splitted = [ [ j for j in i if j != ""] for i in libs_splitted ] + println(outputfile, ":$(i[1:end - 4]) => [") + for j in libs_splitted + println(outputfile, """[ "$(j[1])", "$(j[3])" ],""") + end + println(outputfile, "],\n") + end + println(outputfile, ")\n") +end diff --git a/deps/src/CMakeLists.txt b/deps/src/CMakeLists.txt index acd8e8000..26c9c4d27 100644 --- a/deps/src/CMakeLists.txt +++ b/deps/src/CMakeLists.txt @@ -10,10 +10,10 @@ include_directories(${nemo_includes}) include_directories(${singular_includes}) include_directories(${singular_includes}/singular) -SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14" ) +SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -g" ) SET( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -L${JULIA_LIB_DIR} -Wl,-rpath,${JULIA_LIB_DIR} -L${singular_libdir} -Wl,-rpath,${singular_libdir}" ) -add_library(singularwrap SHARED singular.cpp rings.cpp coeffs.cpp ideals.cpp matrices.cpp) +add_library(singularwrap SHARED singular.cpp rings.cpp coeffs.cpp ideals.cpp matrices.cpp caller.cpp) target_link_libraries(singularwrap JlCxx::cxxwrap_julia -ljulia "-lSingular -lpolys -lsingular_resources -lfactory -lomalloc -ldl") install(TARGETS diff --git a/deps/src/caller.cpp b/deps/src/caller.cpp new file mode 100644 index 000000000..b606a10a4 --- /dev/null +++ b/deps/src/caller.cpp @@ -0,0 +1,358 @@ +#include "caller.h" + +#include <Singular/tok.h> +#include <Singular/grammar.h> +#include <Singular/ipshell.h> +#include <Singular/lists.h> +#include <misc/intvec.h> + +// #include <julia/julia.h> + +static jl_value_t * jl_int64_vector_type; +static jl_value_t * jl_int64_matrix_type; +static jl_value_t * jl_singular_number_type; +static jl_value_t * jl_singular_poly_type; +static jl_value_t * jl_singular_ring_type; +static jl_value_t * jl_singular_ideal_type; +static jl_value_t * jl_singular_matrix_type; +static jl_value_t * jl_singular_bigint_type; +static jl_value_t * jl_singular_bigintmat_type; +static jl_value_t * jl_singular_map_type; +static jl_value_t * jl_singular_resolution_type; +static jl_value_t * jl_singular_vector_type; + +static jl_value_t * get_type_mapper() +{ + std::vector<std::pair<int, std::string>> types = { + std::pair<int, std::string>(BIGINT_CMD, "BIGINT_CMD"), + std::pair<int, std::string>(NUMBER_CMD, "NUMBER_CMD"), + std::pair<int, std::string>(RING_CMD, "RING_CMD"), + std::pair<int, std::string>(POLY_CMD, "POLY_CMD"), + std::pair<int, std::string>(IDEAL_CMD, "IDEAL_CMD"), + std::pair<int, std::string>(INT_CMD, "INT_CMD"), + std::pair<int, std::string>(STRING_CMD, "STRING_CMD"), + std::pair<int, std::string>(LIST_CMD, "LIST_CMD"), + std::pair<int, std::string>(INTMAT_CMD, "INTMAT_CMD"), + std::pair<int, std::string>(BIGINTMAT_CMD, "BIGINTMAT_CMD"), + std::pair<int, std::string>(MAP_CMD, "MAP_CMD"), + std::pair<int, std::string>(RESOLUTION_CMD, "RESOLUTION_CMD"), + std::pair<int, std::string>(MODUL_CMD, "MODUL_CMD"), + std::pair<int, std::string>(VECTOR_CMD, "VECTOR_CMD"), + std::pair<int, std::string>(INTVEC_CMD, "INTVEC_CMD")}; + + jl_array_t * return_array = + jl_alloc_array_1d(jl_array_any_type, types.size()); + + for (int i = 0; i < types.size(); i++) { + jl_array_t * current_return = jl_alloc_array_1d(jl_array_any_type, 2); + jl_arrayset(current_return, jl_box_int64(types[i].first), 0); + jl_arrayset(current_return, + reinterpret_cast<jl_value_t *>( + jl_symbol(types[i].second.c_str())), + 1); + jl_arrayset(return_array, + reinterpret_cast<jl_value_t *>(current_return), i); + } + return reinterpret_cast<jl_value_t *>(return_array); +} + +static void initialize_jl_c_types(jl_value_t * module_value) +{ + jl_module_t * module = reinterpret_cast<jl_module_t *>(module_value); + jl_int64_vector_type = + jl_apply_array_type((jl_value_t *)jl_int64_type, 1); + jl_int64_matrix_type = + jl_apply_array_type((jl_value_t *)jl_int64_type, 2); + jl_singular_number_type = jl_get_global(module, jl_symbol("number")); + jl_singular_poly_type = jl_get_global(module, jl_symbol("poly")); + jl_singular_ring_type = jl_get_global(module, jl_symbol("ring")); + jl_singular_ideal_type = jl_get_global(module, jl_symbol("ideal")); + jl_singular_matrix_type = jl_get_global(module, jl_symbol("ip_smatrix")); + jl_singular_bigint_type = + jl_get_global(module, jl_symbol("__mpz_struct")); + jl_singular_bigintmat_type = + jl_get_global(module, jl_symbol("bigintmat")); + jl_singular_map_type = jl_get_global(module, jl_symbol("sip_smap")); + jl_singular_resolution_type = + jl_get_global(module, jl_symbol("resolvente")); +} + +static inline void * get_ptr_from_cxxwrap_obj(jl_value_t * obj) +{ + return *reinterpret_cast<void **>(obj); +} + +// Safe way +// void* get_ptr_from_cxxwrap_obj(jl_value_t* obj){ +// return jl_unbox_voidpointer(jl_get_field(obj,"cpp_object")); +// } + +jl_value_t * intvec_to_jl_array(intvec * v) +{ + int size = v->length(); + jl_array_t * result = jl_alloc_array_1d(jl_int64_vector_type, size); + int * v_content = v->ivGetVec(); + for (int i = 0; i < size; i++) { + jl_arrayset(result, jl_box_int64(static_cast<int64_t>(v_content[i])), + i); + } + return reinterpret_cast<jl_value_t *>(result); +} + +jl_value_t * intmat_to_jl_array(intvec * v) +{ + int rows = v->rows(); + int cols = v->cols(); + jl_array_t * result = jl_alloc_array_2d(jl_int64_matrix_type, rows, cols); + int64_t * result_ptr = reinterpret_cast<int64_t *> jl_array_data(result); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + result_ptr[j + (i * cols)] = IMATELEM(*v, i, j); + } + } + return reinterpret_cast<jl_value_t *>(result); +} + +void * jl_array_to_intvec(jl_value_t * array_val) +{ + jl_array_t * array = reinterpret_cast<jl_array_t *>(array_val); + int size = jl_array_len(array); + intvec * result = new intvec(size); + int * result_content = result->ivGetVec(); + for (int i = 0; i < size; i++) { + result_content[i] = + static_cast<int>(jl_unbox_int64(jl_arrayref(array, i))); + } + return reinterpret_cast<void *>(result); +} + +void * jl_array_to_intmat(jl_value_t * array_val) +{ + jl_array_t * array = reinterpret_cast<jl_array_t *>(array_val); + int rows = jl_array_dim(array, 0); + int cols = jl_array_dim(array, 1); + intvec * result = new intvec(rows, cols, 0); + int64_t * array_data = reinterpret_cast<int64_t *>(jl_array_data(array)); + int * vec_data = result->ivGetVec(); + for (int i = 0; i < cols; i++) { + for (int j = 0; j < rows; j++) { + IMATELEM(*result, i + 1, j + 1) = + static_cast<int>(array_data[j + (i * rows)]); + } + } + return reinterpret_cast<void *>(result); +} + +static void * get_ring_ref(ring r) +{ + r->ref++; + return reinterpret_cast<void *>(r); +} + +static jl_value_t * copy_polyptr_to_void(poly p, ring r) +{ + poly p_copy = p_Copy(p, r); + return jl_box_voidpointer(reinterpret_cast<void *>(p_copy)); +} + +static jl_value_t * copy_idealptr_to_void(ideal i, ring r) +{ + ideal i_copy = id_Copy(i, r); + return jl_box_voidpointer(reinterpret_cast<void *>(i_copy)); +} + +static void * copy_string_to_void(std::string s) +{ + return reinterpret_cast<void *>(omStrDup(s.c_str())); +} + +bool translate_singular_type(jl_value_t * obj, + void ** args, + int * argtypes, + int i) +{ + jl_array_t * array = reinterpret_cast<jl_array_t *>(obj); + int cmd = static_cast<int>(jl_unbox_int64(jl_arrayref(array, 0))); + void * arg = jl_unbox_voidpointer(jl_arrayref(array, 1)); + args[i] = arg; + argtypes[i] = cmd; + return true; +} + +jl_value_t * get_julia_type_from_sleftv(leftv ret) +{ + jl_array_t * result = jl_alloc_array_1d(jl_array_any_type, 3); + jl_arrayset(result, jl_false, 0); + jl_arrayset(result, jl_box_voidpointer(ret->data), 1); + ret->data = 0; + jl_arrayset(result, jl_box_int64(ret->Typ()), 2); + ret->rtyp = 0; + return reinterpret_cast<jl_value_t *>(result); +} + +jl_value_t * get_ring_content(ring r) +{ + // count elements + idhdl h = r->idroot; + int nr = 0; + while (h != NULL) { + nr++; + h = IDNEXT(h); + } + jl_array_t * result = jl_alloc_array_1d(jl_array_any_type, nr); + h = r->idroot; + nr = 0; + while (h != NULL) { + jl_array_t * current = jl_alloc_array_1d(jl_array_any_type, 3); + jl_arrayset(current, jl_box_int64(IDTYP(h)), 0); + jl_arrayset(current, + reinterpret_cast<jl_value_t *>(jl_symbol(IDID(h))), 1); + jl_arrayset(current, jl_box_voidpointer(IDDATA(h)), 2); + jl_arrayset(result, reinterpret_cast<jl_value_t *>(current), nr); + h = IDNEXT(h); + nr++; + } + return reinterpret_cast<jl_value_t *>(result); +} + +jl_value_t * call_singular_library_procedure( + std::string s, ring r, jlcxx::ArrayRef<jl_value_t *> arguments) +{ + int len = arguments.size(); + void * args[len]; + int argtypes[len + 1]; + argtypes[len] = 0; + for (int i = 0; i < len; i++) { + bool result = + translate_singular_type(arguments[i], args, argtypes, i); + if (!result) { + jl_error("Could not convert argument"); + } + } + BOOLEAN err; + jl_value_t * retObj; + leftv ret = ii_CallLibProcM(s.c_str(), args, argtypes, r, err); + if (err) { + jl_error("Could not call function"); + } + if (ret->next != NULL) { + int len = ret->listLength(); + jl_array_t * list = jl_alloc_array_1d(jl_array_any_type, len + 1); + jl_arrayset(list, jl_true, 0); + for (int i = 0; i < len; ++i) { + leftv next = ret->next; + ret->next = 0; + jl_arrayset(list, get_julia_type_from_sleftv(ret), i + 1); + if (i > 0) + omFreeBin(ret, sleftv_bin); + ret = next; + } + retObj = reinterpret_cast<jl_value_t *>(list); + } + else { + retObj = get_julia_type_from_sleftv(ret); + omFreeBin(ret, sleftv_bin); + } + return retObj; +} + +jl_value_t * call_singular_library_procedure_wo_ring( + std::string name, jlcxx::ArrayRef<jl_value_t *> arguments) +{ + return call_singular_library_procedure(name, NULL, arguments); +} + +jl_value_t * convert_nested_list(void * l_void) +{ + lists l = reinterpret_cast<lists>(l_void); + int len = lSize(l) + 1; + jl_array_t * result_array = jl_alloc_array_1d(jl_array_any_type, len); + for (int i = 0; i < len; i++) { + leftv current = &(l->m[i]); + if (current->Typ() == LIST_CMD) { + jl_arrayset( + result_array, + convert_nested_list(reinterpret_cast<void *>(current->data)), + i); + } + else { + jl_arrayset(result_array, get_julia_type_from_sleftv(current), i); + } + } + return reinterpret_cast<jl_value_t *>(result_array); +} + +void * create_syStrategy_data(syStrategy res, ring o) +{ + const ring origin = currRing; + rChangeCurrRing(o); + syStrategy temp = syCopy(res); + rChangeCurrRing(origin); + return reinterpret_cast<void *>(temp); +} + +void singular_define_caller(jlcxx::Module & Singular) +{ + Singular.method("load_library", [](std::string name) { + char * plib = iiConvName(name.c_str()); + idhdl h = ggetid(plib); + omFree(plib); + if (h == NULL) { + BOOLEAN bo = iiLibCmd(omStrDup(name.c_str()), TRUE, TRUE, FALSE); + if (bo) + return jl_false; + } + return jl_true; + }); + Singular.method("call_singular_library_procedure", + &call_singular_library_procedure); + Singular.method("call_singular_library_procedure", + &call_singular_library_procedure_wo_ring); + Singular.method("get_type_mapper", &get_type_mapper); + Singular.method("initialize_jl_c_types", &initialize_jl_c_types); + + + Singular.method("NUMBER_CMD_CASTER", + [](void * obj) { return reinterpret_cast<number>(obj); }); + Singular.method("RING_CMD_CASTER", + [](void * obj) { return reinterpret_cast<ring>(obj); }); + Singular.method("POLY_CMD_CASTER", + [](void * obj) { return reinterpret_cast<poly>(obj); }); + Singular.method("IDEAL_CMD_CASTER", + [](void * obj) { return reinterpret_cast<ideal>(obj); }); + Singular.method("INT_CMD_CASTER", [](void * obj) { + return jl_box_int64(reinterpret_cast<long>(obj)); + }); + Singular.method("STRING_CMD_CASTER", [](void * obj) { + return std::string(reinterpret_cast<char *>(obj)); + }); + Singular.method("INTVEC_CMD_CASTER", [](void * obj) { + return intvec_to_jl_array(reinterpret_cast<intvec *>(obj)); + }); + Singular.method("INTMAT_CMD_CASTER", [](void * obj) { + return intmat_to_jl_array(reinterpret_cast<intvec *>(obj)); + }); + Singular.method("BIGINT_CMD_CASTER", [](void * obj) { + return reinterpret_cast<__mpz_struct *>(obj); + }); + Singular.method("BIGINTMAT_CMD_CASTER", [](void * obj) { + return reinterpret_cast<bigintmat *>(obj); + }); + Singular.method("MAP_CMD_CASTER", [](void * obj) { + return reinterpret_cast<sip_smap *>(obj); + }); + Singular.method("RESOLUTION_CMD_CASTER", [](void * obj) { + return reinterpret_cast<syStrategy>(obj); + }); + Singular.method("LIST_CMD_TRAVERSAL", &convert_nested_list); + Singular.method("get_ring_content", &get_ring_content); + Singular.method("get_ring_ref", &get_ring_ref); + Singular.method("copy_polyptr_to_void", ©_polyptr_to_void); + Singular.method("copy_idealptr_to_void", ©_idealptr_to_void); + Singular.method("jl_array_to_intvec", &jl_array_to_intvec); + Singular.method("jl_array_to_intmat", &jl_array_to_intmat); + Singular.method("copy_string_to_void", ©_string_to_void); + + Singular.method("create_syStrategy_data", &create_syStrategy_data); + +} diff --git a/deps/src/caller.h b/deps/src/caller.h new file mode 100644 index 000000000..bf49c67da --- /dev/null +++ b/deps/src/caller.h @@ -0,0 +1,8 @@ +#ifndef CALLER_INCLUDE +#define CALLER_INCLUDE + +#include "includes.h" + +void singular_define_caller(jlcxx::Module &); + +#endif diff --git a/deps/src/coeffs.cpp b/deps/src/coeffs.cpp index 7d1ded8ae..b7457f2b3 100644 --- a/deps/src/coeffs.cpp +++ b/deps/src/coeffs.cpp @@ -44,11 +44,10 @@ void singular_define_coeffs(jlcxx::Module & Singular) } }); - Singular.method("n_Delete_Q", [](void * n, coeffs cf) { - number tt = reinterpret_cast<number>(n); - number * t = &tt; + Singular.method("n_Delete_Q", [](snumber * n, coeffs cf) { + ; if (n != NULL) { - n_Delete(t, cf); + n_Delete(&n, cf); } }); diff --git a/deps/src/ideals.cpp b/deps/src/ideals.cpp index a174bc635..05cc9f2a3 100644 --- a/deps/src/ideals.cpp +++ b/deps/src/ideals.cpp @@ -12,7 +12,7 @@ auto id_sres_helper(sip_sideal * m, int n, ring R) r = s->fullres; minimal = false; } - return std::make_tuple(reinterpret_cast<void *>(r), s->length, minimal); + return std::make_tuple(s, minimal); } @@ -28,7 +28,7 @@ auto id_fres_helper(sip_sideal * I, int n, std::string method, ring R) r = s->fullres; minimal = false; } - return std::make_tuple(reinterpret_cast<void *>(r), s->length, minimal); + return std::make_tuple(s, minimal); } diff --git a/deps/src/singular.cpp b/deps/src/singular.cpp index 932d424b1..f3fef6fc6 100644 --- a/deps/src/singular.cpp +++ b/deps/src/singular.cpp @@ -4,6 +4,7 @@ #include "rings.h" #include "ideals.h" #include "matrices.h" +#include "caller.h" static std::string singular_return; static std::string singular_error; @@ -48,6 +49,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module & Singular) Singular.add_type<ip_smatrix>("ip_smatrix"); Singular.add_type<ssyStrategy>("syStrategy"); Singular.add_type<sip_smap>("sip_smap"); + Singular.add_type<bigintmat>("bigintmat"); /* monomial orderings */ Singular.set_const("ringorder_no", ringorder_no); @@ -73,6 +75,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module & Singular) singular_define_rings(Singular); singular_define_ideals(Singular); singular_define_matrices(Singular); + singular_define_caller(Singular); // Calls the Singular interpreter with `input`. @@ -124,60 +127,69 @@ JLCXX_MODULE define_julia_module(jlcxx::Module & Singular) ** from resolutions.jl ***************************/ - Singular.method("res_Delete_helper", [](void * ra_void, int len, ring o) { - auto ra = reinterpret_cast<resolvente>(ra_void); - for (int i = 0; i < len; i++) { - id_Delete(ra + i, o); - } - omFreeSize((ADDRESS)ra, (len + 1) * sizeof(ideal)); - }); + Singular.method("res_Delete_helper", + [](syStrategy ra, ring o) { syKillComputation(ra, o); }); - Singular.method("res_Copy", [](void * ra_void, int len, ring o) { - auto ra = reinterpret_cast<resolvente>(ra_void); - resolvente res = (resolvente)omAlloc0((len + 1) * sizeof(ideal)); + Singular.method("res_Copy", [](syStrategy ra, ring o) { + const ring origin = currRing; rChangeCurrRing(o); - for (int i = len - 1; i >= 0; i--) { - if (ra[i] != NULL) - res[i] = id_Copy(ra[i], o); - } - return reinterpret_cast<void *>(res); + syStrategy temp = syCopy(ra); + rChangeCurrRing(origin); + return temp; }); + Singular.method("getindex_internal", + [](syStrategy ra, int64_t k, bool minimal) { + if (minimal) { + return ra->minres[k]; + } + return (ideal)ra->fullres[k]; + }); - Singular.method("getindex", [](void * ra_void, int k) { - auto ra = reinterpret_cast<resolvente>(ra_void); - return (ideal)ra[k]; - }); - - Singular.method("syMinimize", [](void * ra_void, int len, ring o) { - auto ra = reinterpret_cast<resolvente>(ra_void); + Singular.method("syMinimize", [](syStrategy ra, ring o) { const ring origin = currRing; - syStrategy temp = (syStrategy)omAlloc0(sizeof(ssyStrategy)); - resolvente result; rChangeCurrRing(o); - temp->fullres = (resolvente)omAlloc0((len + 1) * sizeof(ideal)); - for (int i = len - 1; i >= 0; i--) { - if (ra[i] != NULL) - temp->fullres[i] = idCopy(ra[i]); - } - temp->length = len; + syStrategy temp = syCopy(ra); syMinimize(temp); - result = temp->minres; - temp->minres = NULL; - // syMinimize increments this as it returns a value we ignore - temp->references--; - syKillComputation(temp, o); rChangeCurrRing(origin); - return reinterpret_cast<void *>(result); + return reinterpret_cast<void *>(temp); }); + Singular.method("get_minimal_res", [](syStrategy ra) { + return reinterpret_cast<void *>(ra->minres); + }); + + Singular.method("get_full_res", [](syStrategy ra) { + return reinterpret_cast<void *>(ra->fullres); + }); + + Singular.method("get_sySize", [](syStrategy ra) { + return static_cast<int64_t>(sySize(ra)); + }); + + Singular.method("create_SyStrategy", [](void * res_void, int64_t len, + ring r) { + resolvente res = reinterpret_cast<resolvente>(res_void); + syStrategy result = (syStrategy)omAlloc0(sizeof(ssyStrategy)); + result->list_length = static_cast<short>(len); + result->length = static_cast<int>(len); + resolvente res_cp = (resolvente)omAlloc0((len + 1) * sizeof(ideal)); + for (int i = 0; i <= len; i++) { + if (res[i] != NULL) { + res_cp[i] = id_Copy(res[i], r); + } + } + result->fullres = res_cp; + result->syRing = r; + return result; + }); - Singular.method("syBetti", [](void * ra_void, int len, ring o) { - auto ra = reinterpret_cast<resolvente>(ra_void); + Singular.method("syBetti_internal", [](void * ra, int len, ring o) { const ring origin = currRing; rChangeCurrRing(o); int dummy; - intvec * iv = syBetti(ra, len, &dummy, NULL, FALSE, NULL); + intvec * iv = syBetti(reinterpret_cast<resolvente>(ra), len, &dummy, + NULL, FALSE, NULL); rChangeCurrRing(origin); int nrows = iv->rows(); int ncols = iv->cols(); diff --git a/src/LibSingular.jl b/src/LibSingular.jl index 7d6d1d9b5..5f4ec47de 100644 --- a/src/LibSingular.jl +++ b/src/LibSingular.jl @@ -1,11 +1,13 @@ module libSingular import Libdl + using CxxWrap @wrapmodule(realpath(joinpath(@__DIR__, "..", "local", "lib", "libsingularwrap." * Libdl.dlext))) function __init__() @initcxx + initialize_jl_c_types(@__MODULE__) end include("libsingular/LibSingularTypes.jl") diff --git a/src/Meta.jl b/src/Meta.jl new file mode 100644 index 000000000..67141de9f --- /dev/null +++ b/src/Meta.jl @@ -0,0 +1,34 @@ +include("libraryfuncdictionary.jl") + +input_manipulator_funcs = Dict( + :dummy => Dict( + # :dummy => i->[ x + 1 for x in i] + ) +) + +output_manipulator_funcs = Dict( + :dummy => Dict( + # :dummy => i -> i + 1 + ) +) + +for (name,funcs) in libraryfunctiondictionary + name_caps = Symbol( "Lib" * uppercasefirst(string(name))) + func_calls = Any[] + name_string = string(name) * ".lib" + for i in funcs + if i[1] == "g" + func_name = i[2] + symb = Symbol(func_name) + input_manipulator = haskey(input_manipulator_funcs,name) && haskey(input_manipulator_funcs[name],symb) ? input_manipulator_funcs[name][symb] : identity + output_manipulator = haskey(output_manipulator_funcs,name) && haskey(output_manipulator_funcs[name],symb) ? output_manipulator_funcs[name][symb] : identity + push!(func_calls, :($symb(args...) = $(output_manipulator)(low_level_caller($(name_string),$func_name,$(input_manipulator)(args)...)) )) + push!(func_calls, :($symb(ring::PolyRing,args...) = $(output_manipulator)(low_level_caller_rng($(name_string),$func_name,ring,$(input_manipulator)(args)...)) )) + end + end + eval(:(baremodule $name_caps + import ..Singular: PolyRing, low_level_caller, low_level_caller_rng + import Base: * + $(func_calls...) + end)) +end diff --git a/src/Singular.jl b/src/Singular.jl index 1b9e08f01..5486f01f8 100644 --- a/src/Singular.jl +++ b/src/Singular.jl @@ -47,6 +47,9 @@ const libsingular = joinpath(pkgdir, "local", "lib", "libSingular") prefix = realpath(joinpath(@__DIR__, "..", "local")) +mapping_types = nothing +mapping_types_reversed = nothing + function __init__() # Initialise Singular @@ -90,6 +93,10 @@ function __init__() :comp1max => ringorder_c, :comp1min => ringorder_C ) + global mapping_types, mapping_types_reversed, casting_functions + mapping_types = Dict( i[1] => i[2] for i in libSingular.get_type_mapper() ) + mapping_types_reversed = Dict( j => i for (i, j) in mapping_types ) + casting_functions = create_casting_functions() end ############################################################################### @@ -116,4 +123,8 @@ include("Vector.jl") include("Resolution.jl") +include("caller.jl") + +include("Meta.jl") + end # module diff --git a/src/caller.jl b/src/caller.jl new file mode 100644 index 000000000..d2e4d2438 --- /dev/null +++ b/src/caller.jl @@ -0,0 +1,189 @@ + +function recursive_translate(x, R) + if length(x) > 0 && x[1] isa Bool + return convert_return_list(x, R) + else + return [ recursive_translate(i, R) for i in x] + end +end + +# function LIST_CMD_CASTER(x) +# x_new = LIST_CMD_TRAVERSAL(x) +# end + +casting_functions_pre = Dict(:NUMBER_CMD => (libSingular.NUMBER_CMD_CASTER, true, ()), + :RING_CMD => (libSingular.RING_CMD_CASTER, false, ()), + :POLY_CMD => (libSingular.POLY_CMD_CASTER, true, ()), + :IDEAL_CMD => (libSingular.IDEAL_CMD_CASTER, true, ()), + :MODUL_CMD => (libSingular.IDEAL_CMD_CASTER, true, (:module,)), + :VECTOR_CMD => (libSingular.POLY_CMD_CASTER, true, (:vector,)), + :INT_CMD => (libSingular.INT_CMD_CASTER, false, ()), + :STRING_CMD => (libSingular.STRING_CMD_CASTER, false, ()), + :LIST_CMD => (libSingular.LIST_CMD_TRAVERSAL, false, ()), + :INTVEC_CMD => (libSingular.INTVEC_CMD_CASTER, false, ()), + :INTMAT_CMD => (libSingular.INTMAT_CMD_CASTER, false, ()), + :BIGINT_CMD => (libSingular.BIGINT_CMD_CASTER, false, ()), + :BIGINTMAT_CMD => (libSingular.BIGINTMAT_CMD_CASTER, false, ()), + :MAP_CMD => (libSingular.MAP_CMD_CASTER, false, ()), + :RESOLUTION_CMD => (libSingular.RESOLUTION_CMD_CASTER, true, (:resolution,))) + +casting_functions = nothing + +function create_casting_functions() + pair_array = Any[] + for (sym, func) in casting_functions_pre + push!(pair_array, mapping_types_reversed[sym] => func) + end + return Dict(pair_array...) +end + +function convert_ring_content(value_list, rng) + return_dict = Dict{Symbol,Any}() + for i in value_list + return_dict[i[2]] = convert_return_value([false,i[3],i[1]], rng) + end + return return_dict +end + +function convert_return_value(single_value, rng = nothing) + if single_value[1] + error("recieved list instead of single value") + end + cast = casting_functions[single_value[3]][1](single_value[2]) + if cast isa Array{Any} + return recursive_translate(cast, rng) + elseif cast isa libSingular.ring + new_ring = rng(cast) + return [ new_ring, convert_ring_content(libSingular.get_ring_content(cast), new_ring) ] + elseif casting_functions[single_value[3]][2] + if length(casting_functions[single_value[3]][3]) > 0 + cast = rng(cast, Val(casting_functions[single_value[3]][3][1])) + else + cast = rng(cast) + end + end + return cast +end + + +function convert_return_list(list_value, ring = nothing) + if list_value[1] + return map(i -> convert_return_value(i, ring), list_value[2:end]) + end + return convert_return_value(list_value, ring) +end + +function get_ring(arg_list) + ring = nothing + for i in arg_list + current_ptr = nothing + try + current_ptr = i.ptr + catch + continue + end + if current_ptr isa poly + return parent(i) + elseif current_ptr isa ideal + return parent(i).base_ring + end + end + return ring +end + +function prepare_argument(x::Array{Int64,1}) + return Any[ mapping_types_reversed[:INTVEC_CMD], libSingular.jl_array_to_intvec(x) ], nothing +end + +function prepare_argument(x::Array{Int64,2}) + return Any[ mapping_types_reversed[:INTMAT_CMD], libSingular.jl_array_to_intmat(x) ], nothing +end + +function prepare_argument(x::Int64) + return Any[ mapping_types_reversed[:INT_CMD], Ptr{Cvoid}(x) ], nothing +end + +function prepare_argument(x::String) + return Any[ mapping_types_reversed[:STRING_CMD], libSingular.copy_string_to_void(x) ], nothing +end + +function prepare_argument(x::PolyRing) + new_ptr = libSingular.get_ring_ref(x.ptr) + return Any[ mapping_types_reversed[:RING_CMD], new_ptr ], x +end + +function prepare_argument(x::spoly) + rng = parent(x) + rng_ptr = rng.ptr + return Any[ mapping_types_reversed[:POLY_CMD], libSingular.copy_polyptr_to_void(x.ptr, rng_ptr) ], rng +end + +function prepare_argument(x::svector) + rng = parent(x).base_ring + rng_ptr = rng.ptr + return Any[ mapping_types_reversed[:VECTOR_CMD], libSingular.copy_polyptr_to_void(x.ptr, rng_ptr) ], rng +end + +function prepare_argument(x::sideal) + rng = parent(x).base_ring + rng_ptr = rng.ptr + return Any[ mapping_types_reversed[:IDEAL_CMD], libSingular.copy_idealptr_to_void(x.ptr, rng_ptr)], rng +end + +function prepare_argument(x::smodule) + rng = parent(x).base_ring + rng_ptr = rng.ptr + return Any[ mapping_types_reversed[:MODUL_CMD], libSingular.copy_idealptr_to_void(x.ptr, rng_ptr)], rng +end + +function prepare_argument(x::sresolution) + rng = base_ring(x) + res = Any[ mapping_types_reversed[:RESOLUTION_CMD], libSingular.create_syStrategy_data(x.ptr, rng.ptr) ] + return res, rng +end + +function prepare_argument(x::Any) + if x.ptr isa libSingular.number + ptr = x.ptr + rng = parent(x) + new_ptr = libSingular.n_Copy(ptr, rng.ptr) + return Any[ mapping_types_reversed[:NUMBER_CMD], new_ptr.cpp_object ], nothing + elseif x.ptr isa libSingular.ip_smatrix + rng = parent(x) + return Any[ mapping_types_reversed[:MATRIX_CMD], libSingular.mpCopy(x.ptr, rng.ptr).cpp_object ], rng + elseif x.ptr isa libSingular.__mpz_struct + return Any[ mapping_types_reversed[:BIGINT_CMD], x.ptr.cpp_object ], nothing + elseif x.ptr isa libSingular.sip_smap + return Any[ mapping_types_reversed[:MAP_CMD], x.ptr.cpp_object ], nothing + elseif x.ptr isa libSingular.bigintmat + return Any[ mapping_types_reversed[:BIGINTMAT_CMD], x.ptr.cpp_object ], nothing + end + +end + +function low_level_caller_rng(lib::String, name::String, ring, args...) + libSingular.load_library(lib) + arguments = [prepare_argument(i) for i in args] + arguments = Any[ i for (i, j) in arguments ] + return_value = libSingular.call_singular_library_procedure(name, ring.ptr, arguments) + return convert_return_list(return_value, ring) +end + +function low_level_caller(lib::String, name::String, args...) + libSingular.load_library(lib) + arguments = [prepare_argument(i) for i in args] + rng = nothing + for (i, j) in arguments + if j != nothing + rng = j + end + end + arguments = Any[ i for (i, j) in arguments ] + return_values = nothing + if rng == nothing + return_value = libSingular.call_singular_library_procedure(name, arguments) + else + return_value = libSingular.call_singular_library_procedure(name, rng.ptr, arguments) + end + return convert_return_list(return_value, rng) +end diff --git a/src/ideal/ideal.jl b/src/ideal/ideal.jl index 38984d9b1..418301488 100644 --- a/src/ideal/ideal.jl +++ b/src/ideal/ideal.jl @@ -484,8 +484,8 @@ function fres(id::Union{sideal{T}, smodule{T}}, max_length::Int, method::String && method != "single module") error("wrong optional argument for fres") end - r, length, minimal = libSingular.id_fres(id.ptr, Cint(max_length + 1), method, R.ptr) - return sresolution{T}(R, Int(length), r, minimal) + r, minimal = libSingular.id_fres(id.ptr, Cint(max_length + 1), method, R.ptr) + return sresolution{T}(R, r, minimal) end @doc Markdown.doc""" @@ -503,16 +503,8 @@ function sres(I::sideal{T}, max_length::Int) where T <: Nemo.RingElem max_length = nvars(R) # TODO: consider qrings end - r, length, minimal = libSingular.id_sres(I.ptr, Cint(max_length + 1), R.ptr) - for i = 1:length - ptr = libSingular.getindex(r, Cint(i - 1)) - if ptr.cpp_object == C_NULL - length = i - 1 - break - end - libSingular.idSkipZeroes(ptr) - end - return sresolution{T}(R, length, r, minimal) + r, minimal = libSingular.id_sres(I.ptr, Cint(max_length + 1), R.ptr) + return sresolution{T}(R, r, minimal) end ############################################################################### @@ -536,6 +528,10 @@ function Ideal(R::PolyRing{T}, id::libSingular.ideal) where T <: Nemo.RingElem return sideal{S}(R, id) end +function (R::PolyRing{T})(id::libSingular.ideal) where T <: Nemo.RingElem + return Ideal(R,id) +end + # maximal ideal in degree d function MaximalIdeal(R::PolyRing{T}, d::Int) where T <: Nemo.RingElem (d > typemax(Cint) || d < 0) && throw(DomainError()) diff --git a/src/module/ModuleTypes.jl b/src/module/ModuleTypes.jl index 7d881d054..d6fb2b0ca 100644 --- a/src/module/ModuleTypes.jl +++ b/src/module/ModuleTypes.jl @@ -32,6 +32,18 @@ mutable struct svector{T <: Nemo.RingElem} <: Nemo.ModuleElem{T} end end +""" + (R::PolyRing{T})(m::libSingular.poly,::Val{:vector}) where T + +If R is called with a low-level poly pointer, along with +Val(:vector), it will interpret the poly pointer as a vector. +This needs to be indicated due to the fact that Singulars +vectors and polys are both stored in the poly data structure. +""" +function (R::PolyRing{T})(m::libSingular.poly,::Val{:vector}) where T + return svector{T}(R,1,m) +end + function _svector_clear_fn(p::svector) R = p.base_ring libSingular.p_Delete(p.ptr, R.ptr) @@ -88,6 +100,18 @@ mutable struct smodule{T <: Nemo.RingElem} <: Module{T} end end +""" + (R::PolyRing{T})(m::libSingular.ideal,::Val{:module}) where T + +If R is called with a low-level ideal pointer, along with +Val(:module), it will interpret the ideal pointer as a module. +This needs to be indicated due to the fact that Singulars +modules and ideals are both stored in the ideal data structure. +""" +function (R::PolyRing{T})(m::libSingular.ideal,::Val{:module}) where T + return smodule{T}(R,m) +end + function _smodule_clear_fn(I::smodule) R = I.base_ring libSingular.id_Delete(I.ptr, R.ptr) diff --git a/src/module/module.jl b/src/module/module.jl index 891794fb1..cf4174260 100644 --- a/src/module/module.jl +++ b/src/module/module.jl @@ -160,16 +160,8 @@ function sres(I::smodule{T}, max_length::Int) where T <: Nemo.RingElem max_length = nvars(R) # TODO: consider qrings end - r, length, minimal = libSingular.id_sres(I.ptr, Cint(max_length + 1), R.ptr) - for i = 1:length - ptr = libSingular.getindex(r, Cint(i - 1)) - if ptr.cpp_object == C_NULL - length = i - 1 - break - end - libSingular.idSkipZeroes(ptr) - end - return sresolution{T}(R, length, r, minimal) + r, minimal = libSingular.id_sres(I.ptr, Cint(max_length + 1), R.ptr) + return sresolution{T}(R, r, minimal) end ############################################################################### diff --git a/src/number/NumberTypes.jl b/src/number/NumberTypes.jl index 6f4051eec..ce94b02fb 100644 --- a/src/number/NumberTypes.jl +++ b/src/number/NumberTypes.jl @@ -133,7 +133,7 @@ end function _n_Q_clear_fn(n::n_Q) R = parent(n) - libSingular.n_Delete_Q(n.ptr.cpp_object, parent(n).ptr) + libSingular.n_Delete_Q(n.ptr, parent(n).ptr) _Rationals_clear_fn(R) nothing end diff --git a/src/poly/PolyTypes.jl b/src/poly/PolyTypes.jl index f4e2f7391..1622c053b 100644 --- a/src/poly/PolyTypes.jl +++ b/src/poly/PolyTypes.jl @@ -63,6 +63,13 @@ mutable struct PolyRing{T <: Nemo.RingElem} <: Nemo.MPolyRing{T} end end +function (R::PolyRing{T})(r::libSingular.ring) where T + new_r = deepcopy(R) + new_ptr = new_r.ptr + new_r.ptr = r + return new_r +end + function _PolyRing_clear_fn(R::PolyRing) R.refcount -= 1 if R.refcount == 0 diff --git a/src/poly/poly.jl b/src/poly/poly.jl index c1658e6eb..9546d7a22 100644 --- a/src/poly/poly.jl +++ b/src/poly/poly.jl @@ -813,6 +813,10 @@ function (R::PolyRing)(p::spoly) return p end +function(R::PolyRing)(n::libSingular.number) + return R.base_ring(n) +end + ############################################################################### # # PolynomialRing constructor diff --git a/src/resolution/ResolutionTypes.jl b/src/resolution/ResolutionTypes.jl index 9e27bba62..194ad07e9 100644 --- a/src/resolution/ResolutionTypes.jl +++ b/src/resolution/ResolutionTypes.jl @@ -19,22 +19,21 @@ mutable struct ResolutionSet{T <: Nemo.RingElem} <: Set end mutable struct sresolution{T <: Nemo.RingElem} <: Nemo.SetElem - ptr::Ptr{Nothing} - len::Int + ptr::libSingular.syStrategyRef minimal::Bool base_ring::PolyRing # really takes a Singular module, which has type ideal - function sresolution{T}(R::PolyRing, n::Int, ptr::Ptr{Nothing}, minimal::Bool=false) where T + function sresolution{T}(R::PolyRing, ptr::libSingular.syStrategy, minimal::Bool=false) where T R.refcount += 1 - z = new(ptr, n, minimal, R) + z = new(ptr, minimal, R) finalizer(_sresolution_clear_fn, z) return z end end function _sresolution_clear_fn(r::sresolution) - R = base_ring(r) - libSingular.res_Delete_helper(r.ptr, Cint(r.len), R.ptr) + R = base_ring(r) + libSingular.res_Delete_helper(r.ptr, R.ptr) _PolyRing_clear_fn(R) end diff --git a/src/resolution/resolution.jl b/src/resolution/resolution.jl index 87416acf5..0290360f1 100644 --- a/src/resolution/resolution.jl +++ b/src/resolution/resolution.jl @@ -21,13 +21,13 @@ elem_type(::ResolutionSet{T}) where T <: AbstractAlgebra.RingElem = sresolution{ parent_type(::Type{sresolution{T}}) where T <: AbstractAlgebra.RingElem = ResolutionSet{T} function checkbounds(r::sresolution, i::Int) - (i < 1 || i > r.len) && throw(BoundsError(I, i)) + (i < 1 || i > libSingular.get_sySize(r.ptr)) && throw(BoundsError(r, i)) end function getindex(r::sresolution, i::Int) checkbounds(r, i) R = base_ring(r) - ptr = libSingular.getindex(r.ptr, Cint(i - 1)) + ptr = libSingular.getindex_internal(r.ptr, i-1, r.minimal ) if ptr.cpp_object != C_NULL ptr = libSingular.id_Copy(ptr, R.ptr) end @@ -40,13 +40,13 @@ end > length of a resolution. Over a field, this should be at most the number of variables > in the polynomial ring. """ -length(r::sresolution) = r.len - 1 +length(r::sresolution) = libSingular.get_sySize(r.ptr) function deepcopy_internal(r::sresolution, dict::IdDict) R = base_ring(r) - ptr = libSingular.res_Copy(r.ptr, Cint(r.len), R.ptr) + ptr = libSingular.res_Copy(r.ptr, R.ptr) S = parent(r) - return S(ptr, r.len) + return S(ptr) end ############################################################################### @@ -62,7 +62,12 @@ end > output of this command is useful only in the graded case. """ function betti(r::sresolution) - array = libSingular.syBetti(r.ptr, Cint(r.len), r.base_ring.ptr) + if r.minimal + ideal_list = libSingular.get_minimal_res(r.ptr) + else + ideal_list = libSingular.get_full_res(r.ptr) + end + array = libSingular.syBetti_internal(ideal_list, length(r), r.base_ring.ptr) return unsafe_wrap(Array, array[1], array[2:3]; own=true) end @@ -83,8 +88,8 @@ function minres(r::sresolution{T}) where T <: AbstractAlgebra.RingElem return r end R = base_ring(r) - ptr = libSingular.syMinimize(r.ptr, Cint(r.len), R.ptr) - return sresolution{T}(R, r.len, ptr, true) + ptr = libSingular.syMinimize(r.ptr, R.ptr) + return sresolution{T}(R, ptr, true) end ############################################################################### @@ -100,13 +105,16 @@ end function show(io::IO, r::sresolution) println(io, "Singular Resolution:") - if r.len > 0 - ptr = libSingular.getindex(r.ptr, Cint(0)) - print(io, "R^", libSingular.rank(ptr)) + len = libSingular.get_sySize(r.ptr) + if len > 0 + ptr = libSingular.getindex_internal(r.ptr,0,r.minimal) + if ptr.cpp_object != C_NULL + print(io, "R^", libSingular.rank(ptr)) + end end - for i = 1:r.len - 1 - ptr = libSingular.getindex(r.ptr, Cint(i-1)) - if ptr == C_NULL + for i = 1:len - 1 + ptr = libSingular.getindex_internal(r.ptr,i-1,r.minimal) + if ptr.cpp_object == C_NULL break end print(io, " <- R^", libSingular.ngens(ptr)) @@ -119,9 +127,13 @@ end # ############################################################################### -function (S::ResolutionSet{T})(ptr::Ptr{Nothing}, len::Int) where T <: AbstractAlgebra.RingElem +function (S::ResolutionSet{T})(ptr::libSingular.syStrategy, len::Int = 0) where T <: AbstractAlgebra.RingElem R = base_ring(S) - return sresolution{T}(R, len, ptr) + return sresolution{T}(R, ptr) +end + +function (R::PolyRing{T})(ptr::libSingular.syStrategy, ::Val{:resolution}) where T <: AbstractAlgebra.RingElement + return sresolution{T}(R, ptr, libSingular.get_minimal_res(ptr) != C_NULL ) end ############################################################################### @@ -143,7 +155,7 @@ function Resolution(C::Array{smodule{T}, 1}) where T <: AbstractAlgebra.RingElem R = base_ring(C[1]) CC = (m -> m.ptr).(C) C_ptr = reinterpret(Ptr{Nothing}, pointer(CC)) - ptr = libSingular.res_Copy(C_ptr, Cint(len), R.ptr) - return sresolution{T}(R, len, ptr) + ptr = libSingular.create_SyStrategy(C_ptr, len, R.ptr) + return sresolution{T}(R, ptr) end diff --git a/test/caller-test.jl b/test/caller-test.jl new file mode 100644 index 000000000..752d72b3a --- /dev/null +++ b/test/caller-test.jl @@ -0,0 +1,46 @@ +function test_caller() + print("caller...") + + R, (x, y) = PolynomialRing(Singular.ZZ, ["x", "y"]) + @test Singular.LibSets.isEqualInt(R, Singular.ZZ(1), Singular.ZZ(1)) == 1 + + R, (x, y) = PolynomialRing(Singular.QQ, ["x", "y"]) + + # Input tests + @test 1 == Singular.LibSets.isEqualInt(R, 1, 1) + @test 1 == Singular.LibSets.isEqualInt(R, x, x) + @test 1 == Singular.LibSets.isEqualInt(R, "aa", "aa") + @test 1 == Singular.LibSets.isEqualInt(R, Singular.QQ(1), Singular.QQ(1)) + @test 1 == Singular.LibSets.isEqualInt(R, [1,2,3], [1,2,3]) + @test 1 == Singular.LibSets.isEqualInt(R, [1 2; 3 4], [1 2; 3 4]) + + R, (x,y,z) = PolynomialRing(Singular.QQ, ["x", "y", "z"]) + + i1 = Singular.LibPoly.cyclic(R, 3) + i2 = Ideal( R, x+y+z, x*y+x*z+y*z, x*y*z-1 ) + @test equal(i1, i2) + + vec = FreeModule(R,2)([x,y]) + mod = Singular.Module(R, vec) + i1 = Singular.LibPoly.mod2id(R,mod,[1,2]) + i2 = Ideal(R, x^2, x*y, y^2, x^2 ) + @test equal(i1, i2) + + i1 = Ideal(R, x, y) + i2 = Ideal(R, x^2, x*y, y^2, x, y) + mod = Singular.LibPoly.id2mod(R, i1, [1,2]) + i1 = Singular.LibPoly.mod2id(R, mod, [1,2]) + @test equal(i1,i2) + @test Singular.LibPoly.content(R,vec) == 1 + @test Singular.LibPoly.lcm(R,x) == x + + i1 = Ideal(R, x*z, y*z, x^3-y^3) + @test Singular.LibStandard.res(R,i1,0) isa Singular.sresolution + i1 = Ideal(R, x*z, y*z, x^3-y^3) + @test Singular.LibPrimdec.primdecGTZ(R,i1) isa Array + + i1 = Ideal(R, x*z, y*z, x^3-y^3) + @test Singular.LibNormal.normal(i1, "withDelta", "prim") isa Array + + println("PASS") +end diff --git a/test/runtests.jl b/test/runtests.jl index 7d7e40063..dc5d3b3ec 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,14 +16,17 @@ include("../test/matrix-test.jl") include("../test/resolution-test.jl") include("../test/module-test.jl") include("../test/call_interpreter-test.jl") +include("../test/caller-test.jl") # include("../test/libsingular-test.jl") -test_number() -test_poly() -test_ideal() -test_matrix() -test_resolution() -test_module() -test_call_interpreter() -# test_libsingular() - +@testset "Singular" begin + test_caller() + test_number() + test_poly() + test_ideal() + test_matrix() + test_resolution() + test_module() + test_call_interpreter() + # test_libsingular() +end