diff --git a/doc/source/gr.rst b/doc/source/gr.rst index 00fcb843af..48be55e68e 100644 --- a/doc/source/gr.rst +++ b/doc/source/gr.rst @@ -270,6 +270,15 @@ Context operations The name is used when printing and may be used to choose coercions. +.. function:: slong gr_ctx_ngens(gr_ctx_t ctx) + + Returns the number of generators. + +.. function:: char const * const * gr_ctx_gen_names_srcptr(gr_ctx_t ctx) + + Returns an array containing the names of the generators, or `NULL` if there + are no generators. + Element operations -------------------------------------------------------------------------------- diff --git a/src/gr.h b/src/gr.h index dd897f3330..30e0921cc8 100644 --- a/src/gr.h +++ b/src/gr.h @@ -110,6 +110,8 @@ typedef enum GR_METHOD_CTX_SET_IS_FIELD, GR_METHOD_CTX_SET_GEN_NAME, GR_METHOD_CTX_SET_GEN_NAMES, + GR_METHOD_CTX_NGENS, + GR_METHOD_CTX_GEN_NAMES_SRCPTR, GR_METHOD_INIT, GR_METHOD_CLEAR, @@ -719,6 +721,8 @@ typedef void ((*gr_method_init_clear_op)(gr_ptr, gr_ctx_ptr)); typedef void ((*gr_method_swap_op)(gr_ptr, gr_ptr, gr_ctx_ptr)); typedef int ((*gr_method_ctx)(gr_ctx_ptr)); typedef truth_t ((*gr_method_ctx_predicate)(gr_ctx_ptr)); +typedef slong ((*gr_method_ctx_size)(gr_ctx_ptr)); +typedef char const * const * ((*gr_method_ctx_gen_names_srcptr)(gr_ctx_ptr)); typedef int ((*gr_method_ctx_set_si)(gr_ctx_ptr, slong)); typedef int ((*gr_method_ctx_get_si)(slong *, gr_ctx_ptr)); typedef int ((*gr_method_ctx_set_truth)(gr_ctx_ptr, truth_t)); @@ -816,6 +820,8 @@ typedef int ((*gr_method_set_fexpr_op)(gr_ptr, fexpr_vec_t, gr_vec_t, const fexp #define GR_CTX_OP(ctx, NAME) (((gr_method_ctx *) ctx->methods)[GR_METHOD_ ## NAME]) #define GR_CTX_STREAM(ctx, NAME) (((gr_method_ctx_stream *) ctx->methods)[GR_METHOD_ ## NAME]) #define GR_CTX_PREDICATE(ctx, NAME) (((gr_method_ctx_predicate *) ctx->methods)[GR_METHOD_ ## NAME]) +#define GR_CTX_SIZE(ctx, NAME) (((gr_method_ctx_size *) ctx->methods)[GR_METHOD_ ## NAME]) +#define GR_CTX_GEN_NAMES_SRCPTR(ctx, NAME) (((gr_method_ctx_gen_names_srcptr *) ctx->methods)[GR_METHOD_ ## NAME]) #define GR_CTX_SET_SI(ctx, NAME) (((gr_method_ctx_set_si *) ctx->methods)[GR_METHOD_ ## NAME]) #define GR_CTX_GET_SI(ctx, NAME) (((gr_method_ctx_get_si *) ctx->methods)[GR_METHOD_ ## NAME]) #define GR_CTX_SET_TRUTH(ctx, NAME) (((gr_method_ctx_set_truth *) ctx->methods)[GR_METHOD_ ## NAME]) @@ -940,6 +946,8 @@ GR_INLINE WARN_UNUSED_RESULT int gr_ctx_get_real_prec(slong * prec, gr_ctx_t ctx GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_is_field(gr_ctx_t ctx, truth_t is_field) { return GR_CTX_SET_TRUTH(ctx, CTX_SET_IS_FIELD)(ctx, is_field); } GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_gen_name(gr_ctx_t ctx, const char * s) { return GR_CTX_SET_STR(ctx, CTX_SET_GEN_NAME)(ctx, s); } GR_INLINE WARN_UNUSED_RESULT int gr_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) { return GR_CTX_SET_STRS(ctx, CTX_SET_GEN_NAMES)(ctx, s); } +GR_INLINE slong gr_ctx_ngens(gr_ctx_t ctx) { return GR_CTX_SIZE(ctx, CTX_NGENS)(ctx); } +GR_INLINE char const * const * gr_ctx_gen_names_srcptr(gr_ctx_t ctx) { return GR_CTX_GEN_NAMES_SRCPTR(ctx, CTX_GEN_NAMES_SRCPTR)(ctx); } GR_INLINE slong _gr_ctx_get_real_prec(gr_ctx_t ctx) { diff --git a/src/gr/fmpq_poly.c b/src/gr/fmpq_poly.c index 60e719e8f5..e6997cf404 100644 --- a/src/gr/fmpq_poly.c +++ b/src/gr/fmpq_poly.c @@ -50,6 +50,11 @@ int _gr_fmpq_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_fmpq_poly_ctx_set_gen_name(ctx, s[0]); } +const char * const * +_gr_fmpq_poly_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (const char * const *) &FMPQ_POLY_CTX_VAR(ctx); +} int _gr_fmpq_poly_ctx_write(gr_stream_t out, gr_ctx_t ctx) @@ -735,6 +740,8 @@ gr_method_tab_input _fmpq_poly_methods_input[] = {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_fmpq_poly_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fmpq_poly_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fmpq_poly_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_fmpq_poly_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpq_poly_clear}, {GR_METHOD_SWAP, (gr_funcptr) _gr_fmpq_poly_swap}, diff --git a/src/gr/fmpz_mpoly.c b/src/gr/fmpz_mpoly.c index 615ca1e06e..47338bd4d2 100644 --- a/src/gr/fmpz_mpoly.c +++ b/src/gr/fmpz_mpoly.c @@ -85,6 +85,18 @@ _gr_fmpz_mpoly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return GR_SUCCESS; } +slong +_gr_fmpz_mpoly_ctx_ngens(gr_ctx_t ctx) +{ + return MPOLYNOMIAL_MCTX(ctx)->minfo->nvars; +} + +char const * const +_gr_fmpz_mpoly_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const) MPOLYNOMIAL_CTX(ctx)->vars; +} + void _gr_fmpz_mpoly_init(fmpz_mpoly_t res, gr_ctx_t ctx) { @@ -569,6 +581,8 @@ gr_method_tab_input _gr_fmpz_mpoly_methods_input[] = {GR_METHOD_CTX_IS_FINITE_CHARACTERISTIC, (gr_funcptr) gr_generic_ctx_predicate_false}, {GR_METHOD_CTX_IS_THREADSAFE, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fmpz_mpoly_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) _gr_fmpz_mpoly_ctx_ngens}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fmpz_mpoly_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_fmpz_mpoly_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpz_mpoly_clear}, {GR_METHOD_SWAP, (gr_funcptr) _gr_fmpz_mpoly_swap}, diff --git a/src/gr/fmpz_mpoly_q.c b/src/gr/fmpz_mpoly_q.c index 7093104c2f..921a52789b 100644 --- a/src/gr/fmpz_mpoly_q.c +++ b/src/gr/fmpz_mpoly_q.c @@ -43,9 +43,13 @@ int _gr_fmpz_mpoly_q_ctx_write(gr_stream_t out, gr_ctx_t ctx) /* Some methods are identical to their fmpz_mpoly counterparts */ void _gr_fmpz_mpoly_ctx_clear(gr_ctx_t ctx); int _gr_fmpz_mpoly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s); +slong _gr_fmpz_mpoly_ctx_ngens(gr_ctx_t ctx); +char const * const _gr_fmpz_mpoly_ctx_gen_names_srcptr(gr_ctx_t ctx); #define _gr_fmpz_mpoly_q_ctx_clear _gr_fmpz_mpoly_ctx_clear #define _gr_fmpz_mpoly_q_ctx_set_gen_names _gr_fmpz_mpoly_ctx_set_gen_names +#define _gr_fmpz_mpoly_q_ctx_ngens _gr_fmpz_mpoly_ctx_ngens +#define _gr_fmpz_mpoly_q_ctx_gen_names_srcptr _gr_fmpz_mpoly_ctx_gen_names_srcptr void _gr_fmpz_mpoly_q_init(fmpz_mpoly_q_t res, gr_ctx_t ctx) @@ -532,6 +536,8 @@ gr_method_tab_input _gr_fmpz_mpoly_q_methods_input[] = {GR_METHOD_CTX_IS_FINITE_CHARACTERISTIC, (gr_funcptr) gr_generic_ctx_predicate_false}, {GR_METHOD_CTX_IS_THREADSAFE, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fmpz_mpoly_q_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) _gr_fmpz_mpoly_q_ctx_ngens}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fmpz_mpoly_q_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_fmpz_mpoly_q_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpz_mpoly_q_clear}, {GR_METHOD_SWAP, (gr_funcptr) _gr_fmpz_mpoly_q_swap}, diff --git a/src/gr/fmpz_poly.c b/src/gr/fmpz_poly.c index 07b03ae666..00f242455a 100644 --- a/src/gr/fmpz_poly.c +++ b/src/gr/fmpz_poly.c @@ -53,6 +53,12 @@ int _gr_fmpz_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_fmpz_poly_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_fmpz_poly_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &FMPZ_POLY_CTX_VAR(ctx); +} + int _gr_fmpz_poly_ctx_write(gr_stream_t out, gr_ctx_t ctx) { @@ -828,6 +834,8 @@ gr_method_tab_input _fmpz_poly_methods_input[] = {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_fmpz_poly_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fmpz_poly_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fmpz_poly_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_fmpz_poly_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpz_poly_clear}, diff --git a/src/gr/fmpzi.c b/src/gr/fmpzi.c index b854af1c1c..0e25999762 100644 --- a/src/gr/fmpzi.c +++ b/src/gr/fmpzi.c @@ -24,6 +24,13 @@ _gr_fmpzi_ctx_write(gr_stream_t out, gr_ctx_t ctx) return GR_SUCCESS; } +char const * const * +_gr_fmpzi_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + static const char * name = "I"; + return &name; +} + void _gr_fmpzi_init(fmpzi_t x, const gr_ctx_t ctx) { @@ -951,6 +958,8 @@ gr_method_tab_input _fmpzi_methods_input[] = {GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_CANONICAL, (gr_funcptr) gr_generic_ctx_predicate_true}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fmpzi_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_fmpzi_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_fmpzi_clear}, {GR_METHOD_SWAP, (gr_funcptr) _gr_fmpzi_swap}, diff --git a/src/gr/fq.c b/src/gr/fq.c index e8228a0db8..64b769a464 100644 --- a/src/gr/fq.c +++ b/src/gr/fq.c @@ -58,6 +58,12 @@ int _gr_fq_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_fq_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_fq_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &FQ_CTX(ctx)->var; +} + void _gr_fq_init(fq_t x, const gr_ctx_t ctx) { @@ -716,6 +722,8 @@ gr_method_tab_input _fq_methods_input[] = {GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_fq_ctx_write}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_fq_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fq_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fq_ctx_gen_names_srcptr}, {GR_METHOD_CTX_IS_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true}, diff --git a/src/gr/fq_nmod.c b/src/gr/fq_nmod.c index 7f3164a32e..8ce91261bb 100644 --- a/src/gr/fq_nmod.c +++ b/src/gr/fq_nmod.c @@ -59,6 +59,12 @@ int _gr_fq_nmod_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_fq_nmod_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_fq_nmod_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &FQ_CTX(ctx)->var; +} + void _gr_fq_nmod_init(fq_nmod_t x, const gr_ctx_t ctx) { @@ -679,6 +685,8 @@ gr_method_tab_input _fq_nmod_methods_input[] = {GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_fq_nmod_ctx_write}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_fq_nmod_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fq_nmod_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fq_nmod_ctx_gen_names_srcptr}, {GR_METHOD_CTX_IS_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true}, diff --git a/src/gr/fq_zech.c b/src/gr/fq_zech.c index 3f7f41d764..fcdda921a1 100644 --- a/src/gr/fq_zech.c +++ b/src/gr/fq_zech.c @@ -60,6 +60,12 @@ int _gr_fq_zech_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_fq_zech_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_fq_zech_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &FQ_CTX(ctx)->fq_nmod_ctx->var; +} + void _gr_fq_zech_init(fq_zech_t x, const gr_ctx_t ctx) { @@ -560,6 +566,8 @@ gr_method_tab_input _fq_zech_methods_input[] = {GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_fq_zech_ctx_write}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_fq_zech_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_fq_zech_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_fq_zech_ctx_gen_names_srcptr}, {GR_METHOD_CTX_IS_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) gr_generic_ctx_predicate_true}, diff --git a/src/gr/nf.c b/src/gr/nf.c index 9b677e4d97..f375507084 100644 --- a/src/gr/nf.c +++ b/src/gr/nf.c @@ -59,6 +59,12 @@ int _gr_nf_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_nf_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_nf_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &NF_VAR(ctx); +} + void _gr_nf_ctx_clear(gr_ctx_t ctx) { @@ -541,6 +547,8 @@ gr_method_tab_input _nf_methods_input[] = (gr_funcptr) gr_generic_ctx_predicate_true}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_nf_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES,(gr_funcptr) _gr_nf_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_nf_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) _gr_nf_init}, {GR_METHOD_CLEAR, (gr_funcptr) _gr_nf_clear}, {GR_METHOD_SWAP, (gr_funcptr) _gr_nf_swap}, diff --git a/src/gr/polynomial.c b/src/gr/polynomial.c index 85134e544a..fa13f9dee1 100644 --- a/src/gr/polynomial.c +++ b/src/gr/polynomial.c @@ -52,6 +52,12 @@ int _gr_gr_poly_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_gr_poly_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_gr_poly_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &POLYNOMIAL_CTX(ctx)->var; +} + void polynomial_ctx_clear(gr_ctx_t ctx) { @@ -660,6 +666,8 @@ gr_method_tab_input _gr_poly_methods_input[] = {GR_METHOD_CTX_IS_THREADSAFE, (gr_funcptr) polynomial_ctx_is_threadsafe}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_gr_poly_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_gr_poly_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_gr_poly_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) polynomial_init}, {GR_METHOD_CLEAR, (gr_funcptr) polynomial_clear}, diff --git a/src/gr/series.c b/src/gr/series.c index d0aa56becd..cb934d4914 100644 --- a/src/gr/series.c +++ b/src/gr/series.c @@ -1777,6 +1777,11 @@ int _gr_gr_series_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_gr_series_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_gr_series_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &SERIES_CTX(ctx)->var; +} static int _gr_gr_series_gens_recursive(gr_vec_t vec, gr_ctx_t ctx) @@ -1951,6 +1956,8 @@ gr_method_tab_input _gr_series_methods_input[] = {GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_gr_series_ctx_write}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_gr_series_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_gr_series_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_gr_series_ctx_gen_names_srcptr}, {GR_METHOD_CTX_IS_RING, (gr_funcptr) _gr_gr_series_ctx_is_ring}, {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) _gr_gr_series_ctx_is_commutative_ring}, {GR_METHOD_INIT, (gr_funcptr) _gr_gr_series_init}, diff --git a/src/gr/series_mod.c b/src/gr/series_mod.c index 753ff695c4..a7db6f8bea 100644 --- a/src/gr/series_mod.c +++ b/src/gr/series_mod.c @@ -88,6 +88,12 @@ int _gr_gr_series_mod_ctx_set_gen_names(gr_ctx_t ctx, const char ** s) return _gr_gr_series_mod_ctx_set_gen_name(ctx, s[0]); } +char const * const * +_gr_gr_series_mod_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) &SERIES_MOD_CTX(ctx)->var; +} + static int _gr_gr_series_mod_gens_recursive(gr_vec_t vec, gr_ctx_t ctx) { @@ -371,6 +377,8 @@ gr_method_tab_input _gr_series_mod_methods_input[] = {GR_METHOD_CTX_WRITE, (gr_funcptr) _gr_gr_series_mod_ctx_write}, {GR_METHOD_CTX_SET_GEN_NAME, (gr_funcptr) _gr_gr_series_mod_ctx_set_gen_name}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) _gr_gr_series_mod_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_1}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_gr_series_mod_ctx_gen_names_srcptr}, {GR_METHOD_CTX_IS_RING, (gr_funcptr) _gr_gr_series_mod_ctx_is_ring}, {GR_METHOD_CTX_IS_COMMUTATIVE_RING, (gr_funcptr) _gr_gr_series_mod_ctx_is_commutative_ring}, {GR_METHOD_CTX_IS_INTEGRAL_DOMAIN, (gr_funcptr) _gr_gr_series_mod_ctx_is_integral_domain}, diff --git a/src/gr/test_ring.c b/src/gr/test_ring.c index 2341afbe93..e3a2db58ec 100644 --- a/src/gr/test_ring.c +++ b/src/gr/test_ring.c @@ -10,6 +10,7 @@ */ #include +#include #include "profiler.h" #include "long_extras.h" @@ -650,6 +651,42 @@ gr_test_ctx_get_str(gr_ctx_t R, flint_rand_t state, int test_flags) return status; } +int +gr_test_ctx_gen_names(gr_ctx_t R, flint_rand_t state, int test_flags) +{ + int status = GR_SUCCESS; + + gr_vec_t gens; + gr_vec_init(gens, 0, R); + + slong ngens = gr_ctx_ngens(R); + char const * const * names = gr_ctx_gen_names_srcptr(R); + + if (ngens < 0) + status = GR_TEST_FAIL; + + if (gr_gens(gens, R) == GR_SUCCESS) + if (gens->length != ngens) + status = GR_TEST_FAIL; + + const char * mynames[] = { "α", "x", "x1" }; + + if (ngens <= 3 && gr_ctx_set_gen_names(R, mynames) == GR_SUCCESS) + { + names = gr_ctx_gen_names_srcptr(R); + for (slong i = 0; i < ngens; i++) + if (strcmp(mynames[i], names[i])) + status = GR_TEST_FAIL; + } + + if (status == GR_TEST_FAIL) + flint_printf("gen_names\n"); + + gr_vec_clear(gens, R); + + return status; +} + int gr_test_get_set_str(gr_ctx_t R, flint_rand_t state, int test_flags) { @@ -4360,6 +4397,7 @@ gr_test_ring(gr_ctx_t R, slong iters, int test_flags) flint_abort(); */ gr_test_iter(R, state, "ctx_get_str", gr_test_ctx_get_str, 1, test_flags); + gr_test_iter(R, state, "ctx_gen_names", gr_test_ctx_gen_names, 1, test_flags); gr_test_iter(R, state, "init/clear", gr_test_init_clear, iters, test_flags); gr_test_iter(R, state, "equal", gr_test_equal, iters, test_flags); diff --git a/src/gr_generic.h b/src/gr_generic.h index 3aef69b0c7..1df49cee76 100644 --- a/src/gr_generic.h +++ b/src/gr_generic.h @@ -86,6 +86,10 @@ truth_t gr_generic_ctx_predicate_false(gr_ctx_t ctx); WARN_UNUSED_RESULT int gr_generic_ctx_clear(gr_ctx_t ctx); +slong gr_generic_ctx_ngens_0(gr_ctx_t ctx); +slong gr_generic_ctx_ngens_1(gr_ctx_t ctx); +char const * const * gr_generic_ctx_gen_names_srcptr(gr_ctx_t ctx); + void gr_generic_set_shallow(gr_ptr res, gr_srcptr x, const gr_ctx_t ctx); WARN_UNUSED_RESULT int gr_generic_write_n(gr_stream_t out, gr_srcptr x, slong n, gr_ctx_t ctx); diff --git a/src/gr_generic/generic.c b/src/gr_generic/generic.c index 72f6914072..17cf38bb04 100644 --- a/src/gr_generic/generic.c +++ b/src/gr_generic/generic.c @@ -72,6 +72,24 @@ truth_t gr_generic_ctx_is_zero_ring(gr_ctx_t ctx) return res; } +slong +gr_generic_ctx_ngens_0(gr_ctx_t ctx) +{ + return 0; +} + +slong +gr_generic_ctx_ngens_1(gr_ctx_t ctx) +{ + return 1; +} + +char const * const * +gr_generic_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return 0; +} + void gr_generic_set_shallow(gr_ptr res, gr_srcptr x, const gr_ctx_t ctx) { @@ -2638,6 +2656,9 @@ const gr_method_tab_input _gr_generic_methods[] = {GR_METHOD_CTX_IS_EXACT, (gr_funcptr) gr_generic_ctx_predicate}, {GR_METHOD_CTX_IS_CANONICAL, (gr_funcptr) gr_generic_ctx_predicate}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) gr_generic_ctx_ngens_0}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) gr_generic_ctx_gen_names_srcptr}, + {GR_METHOD_INIT, (gr_funcptr) gr_generic_init}, {GR_METHOD_CLEAR, (gr_funcptr) gr_generic_clear}, {GR_METHOD_SWAP, (gr_funcptr) gr_generic_swap}, diff --git a/src/gr_mpoly/ctx.c b/src/gr_mpoly/ctx.c index 91fcb0b5a6..1383130161 100644 --- a/src/gr_mpoly/ctx.c +++ b/src/gr_mpoly/ctx.c @@ -70,6 +70,18 @@ gr_mpoly_ctx_set_gen_names(gr_mpoly_ctx_t ctx, const char ** s) return GR_SUCCESS; } +slong +_gr_mpoly_ctx_ngens(gr_ctx_t ctx) +{ + return GR_MPOLY_NVARS(ctx); +} + +char const * const * +_gr_mpoly_ctx_gen_names_srcptr(gr_ctx_t ctx) +{ + return (char const * const *) GR_MPOLY_VARS(ctx); +} + truth_t gr_mpoly_ctx_is_ring(gr_mpoly_ctx_t ctx) { @@ -278,6 +290,8 @@ gr_method_tab_input _gr_mpoly_methods_input[] = {GR_METHOD_CTX_IS_FIELD, (gr_funcptr) gr_mpoly_ctx_is_field}, {GR_METHOD_CTX_IS_THREADSAFE, (gr_funcptr) gr_mpoly_ctx_is_threadsafe}, {GR_METHOD_CTX_SET_GEN_NAMES, (gr_funcptr) gr_mpoly_ctx_set_gen_names}, + {GR_METHOD_CTX_NGENS, (gr_funcptr) _gr_mpoly_ctx_ngens}, + {GR_METHOD_CTX_GEN_NAMES_SRCPTR, (gr_funcptr) _gr_mpoly_ctx_gen_names_srcptr}, {GR_METHOD_INIT, (gr_funcptr) gr_mpoly_init}, {GR_METHOD_CLEAR, (gr_funcptr) gr_mpoly_clear}, {GR_METHOD_SWAP, (gr_funcptr) gr_mpoly_swap},