Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:14

0001 /*
0002     Copyright (C) 2019-2020 Daniel Schultz
0003 
0004     This file is part of FLINT.
0005 
0006     FLINT is free software: you can redistribute it and/or modify it under
0007     the terms of the GNU Lesser General Public License (LGPL) as published
0008     by the Free Software Foundation; either version 3 of the License, or
0009     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0010 */
0011 
0012 #ifndef FMPZ_MOD_MPOLY_H
0013 #define FMPZ_MOD_MPOLY_H
0014 
0015 #ifdef FMPZ_MOD_MPOLY_INLINES_C
0016 #define FMPZ_MOD_MPOLY_INLINE
0017 #else
0018 #define FMPZ_MOD_MPOLY_INLINE static inline
0019 #endif
0020 
0021 #include "fmpz.h"
0022 #include "mpoly_types.h"
0023 
0024 #if FLINT_WANT_ASSERT
0025 # include "mpoly.h"
0026 #endif
0027 
0028 #ifdef __cplusplus
0029 extern "C" {
0030 #endif
0031 
0032 /* type definitions **********************************************************/
0033 
0034 /*
0035     fmpz_mod_mpoly_univar_t
0036     sparse univariates with multivariate coefficients
0037 */
0038 typedef struct
0039 {
0040    fmpz_mod_mpoly_struct * coeffs; /* multivariate coefficients */
0041    fmpz * exps;
0042    slong alloc;
0043    slong length;
0044 } fmpz_mod_mpoly_univar_struct;
0045 
0046 typedef fmpz_mod_mpoly_univar_struct fmpz_mod_mpoly_univar_t[1];
0047 
0048 
0049 /* Context object ************************************************************/
0050 
0051 void fmpz_mod_mpoly_ctx_init(fmpz_mod_mpoly_ctx_t ctx,
0052                       slong nvars, const ordering_t ord, const fmpz_t modulus);
0053 
0054 void fmpz_mod_mpoly_ctx_init_rand(fmpz_mod_mpoly_ctx_t ctx,
0055                     flint_rand_t state, slong max_nvars, const fmpz_t modulus);
0056 
0057 void fmpz_mod_mpoly_ctx_init_rand_bits_prime(fmpz_mod_mpoly_ctx_t ctx,
0058                  flint_rand_t state, slong max_nvars, flint_bitcnt_t max_bits);
0059 
0060 void fmpz_mod_mpoly_ctx_init_rand_bits(fmpz_mod_mpoly_ctx_t ctx,
0061                  flint_rand_t state, slong max_nvars, flint_bitcnt_t max_bits);
0062 
0063 void fmpz_mod_mpoly_ctx_clear(fmpz_mod_mpoly_ctx_t ctx);
0064 
0065 FMPZ_MOD_MPOLY_INLINE
0066 slong fmpz_mod_mpoly_ctx_nvars(const fmpz_mod_mpoly_ctx_t ctx)
0067 {
0068     return ctx->minfo->nvars;
0069 }
0070 
0071 FMPZ_MOD_MPOLY_INLINE
0072 ordering_t fmpz_mod_mpoly_ctx_ord(const fmpz_mod_mpoly_ctx_t ctx)
0073 {
0074     return ctx->minfo->ord;
0075 }
0076 
0077 FMPZ_MOD_MPOLY_INLINE
0078 const fmpz * fmpz_mod_mpoly_ctx_modulus(const fmpz_mod_mpoly_ctx_t ctx)
0079 {
0080     return ctx->ffinfo->n;
0081 }
0082 
0083 FMPZ_MOD_MPOLY_INLINE
0084 void fmpz_mod_mpoly_ctx_get_modulus(fmpz_t m, const fmpz_mod_mpoly_ctx_t ctx)
0085 {
0086     fmpz_set(m, fmpz_mod_mpoly_ctx_modulus(ctx));
0087 }
0088 
0089 /*  Memory management ********************************************************/
0090 
0091 
0092 FMPZ_MOD_MPOLY_INLINE
0093 void fmpz_mod_mpoly_init(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0094 {
0095     A->coeffs = NULL;
0096     A->exps = NULL;
0097     A->length = 0;
0098     A->bits = MPOLY_MIN_BITS;
0099     A->coeffs_alloc = 0;
0100     A->exps_alloc = 0;
0101 }
0102 
0103 void fmpz_mod_mpoly_clear(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0104 
0105 void fmpz_mod_mpoly_init2(fmpz_mod_mpoly_t A, slong alloc,
0106                                                const fmpz_mod_mpoly_ctx_t ctx);
0107 
0108 void fmpz_mod_mpoly_init3(fmpz_mod_mpoly_t A, slong alloc,
0109                           flint_bitcnt_t bits, const fmpz_mod_mpoly_ctx_t ctx);
0110 
0111 void fmpz_mod_mpoly_realloc(fmpz_mod_mpoly_t A,
0112                                   slong alloc, const fmpz_mod_mpoly_ctx_t ctx);
0113 
0114 void fmpz_mod_mpoly_fit_length(fmpz_mod_mpoly_t A, slong length,
0115                                                const fmpz_mod_mpoly_ctx_t ctx);
0116 
0117 void fmpz_mod_mpoly_fit_length_fit_bits(fmpz_mod_mpoly_t A,
0118                slong len, flint_bitcnt_t bits, const fmpz_mod_mpoly_ctx_t ctx);
0119 
0120 void fmpz_mod_mpoly_fit_length_reset_bits(fmpz_mod_mpoly_t A,
0121                slong len, flint_bitcnt_t bits, const fmpz_mod_mpoly_ctx_t ctx);
0122 
0123 FMPZ_MOD_MPOLY_INLINE
0124 void _fmpz_mod_mpoly_fit_length(
0125     fmpz ** coeffs,
0126     slong * coeffs_alloc,
0127     ulong ** exps,
0128     slong * exps_alloc,
0129     slong N,
0130     slong length)
0131 {
0132     if (length > *coeffs_alloc)
0133     {
0134         slong i, old_alloc = *coeffs_alloc;
0135         slong new_alloc = FLINT_MAX(length, old_alloc*2);
0136         *coeffs_alloc = new_alloc;
0137         *coeffs = (fmpz *) flint_realloc(*coeffs, new_alloc*sizeof(fmpz));
0138         for (i = old_alloc; i < new_alloc; i++)
0139             fmpz_init(*coeffs + i);
0140     }
0141 
0142     if (N*length > *exps_alloc)
0143     {
0144         *exps_alloc = FLINT_MAX(N*length, *exps_alloc*2);
0145         *exps = (ulong *) flint_realloc(*exps, *exps_alloc*sizeof(ulong));
0146     }
0147 }
0148 
0149 FMPZ_MOD_MPOLY_INLINE
0150 void _fmpz_mod_mpoly_set_length(fmpz_mod_mpoly_t A, slong newlen,
0151                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0152 {
0153     FLINT_ASSERT(newlen <= A->coeffs_alloc);
0154     FLINT_ASSERT(mpoly_words_per_exp(A->bits, ctx->minfo)*newlen <= A->exps_alloc);
0155 
0156     A->length = newlen;
0157 }
0158 
0159 FMPZ_MOD_MPOLY_INLINE
0160 void fmpz_mod_mpoly_truncate(fmpz_mod_mpoly_t A, slong newlen,
0161                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0162 {
0163     if (A->length > newlen)
0164     {
0165         slong i;
0166 
0167         for (i = newlen; i < A->length; i++)
0168             _fmpz_demote(A->coeffs + i);
0169 
0170         A->length = newlen;
0171     }
0172 }
0173 
0174 
0175 /* Input/output **************************************************************/
0176 
0177 int fmpz_mod_mpoly_set_str_pretty(fmpz_mod_mpoly_t A,
0178             const char * str, const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0179 
0180 char * fmpz_mod_mpoly_get_str_pretty(const fmpz_mod_mpoly_t A,
0181                               const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0182 
0183 #ifdef FLINT_HAVE_FILE
0184 int fmpz_mod_mpoly_fprint_pretty(FILE * file, const fmpz_mod_mpoly_t A, const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0185 #endif
0186 
0187 int fmpz_mod_mpoly_print_pretty(const fmpz_mod_mpoly_t A, const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0188 
0189 /*  Basic manipulation *******************************************************/
0190 
0191 void fmpz_mod_mpoly_gen(fmpz_mod_mpoly_t A, slong var,
0192                                                const fmpz_mod_mpoly_ctx_t ctx);
0193 
0194 int fmpz_mod_mpoly_is_gen(const fmpz_mod_mpoly_t A,
0195                                     slong var, const fmpz_mod_mpoly_ctx_t ctx);
0196 
0197 void fmpz_mod_mpoly_set(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0198                                                const fmpz_mod_mpoly_ctx_t ctx);
0199 
0200 int fmpz_mod_mpoly_equal(const fmpz_mod_mpoly_t A,
0201                      const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx);
0202 
0203 FMPZ_MOD_MPOLY_INLINE
0204 void fmpz_mod_mpoly_swap(fmpz_mod_mpoly_t A, fmpz_mod_mpoly_t B,
0205                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0206 {
0207     FLINT_SWAP(fmpz_mod_mpoly_struct, *A, *B);
0208 }
0209 
0210 /* Constants *****************************************************************/
0211 
0212 int fmpz_mod_mpoly_is_fmpz(const fmpz_mod_mpoly_t A,
0213                                                const fmpz_mod_mpoly_ctx_t ctx);
0214 
0215 void fmpz_mod_mpoly_get_fmpz(fmpz_t c, const fmpz_mod_mpoly_t A,
0216                                                const fmpz_mod_mpoly_ctx_t ctx);
0217 
0218 void fmpz_mod_mpoly_set_fmpz_mod(fmpz_mod_mpoly_t A,
0219                                const fmpz_t c, const fmpz_mod_mpoly_ctx_t ctx);
0220 
0221 void fmpz_mod_mpoly_set_fmpz(fmpz_mod_mpoly_t A,
0222                                const fmpz_t c, const fmpz_mod_mpoly_ctx_t ctx);
0223 
0224 void fmpz_mod_mpoly_set_ui(fmpz_mod_mpoly_t A,
0225                                       ulong c, const fmpz_mod_mpoly_ctx_t ctx);
0226 
0227 void fmpz_mod_mpoly_set_si(fmpz_mod_mpoly_t A,
0228                                       slong c, const fmpz_mod_mpoly_ctx_t ctx);
0229 
0230 FMPZ_MOD_MPOLY_INLINE
0231 void fmpz_mod_mpoly_zero(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx)
0232 {
0233    _fmpz_mod_mpoly_set_length(A, 0, ctx);
0234 }
0235 
0236 FMPZ_MOD_MPOLY_INLINE
0237 void fmpz_mod_mpoly_one(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx)
0238 {
0239     fmpz_mod_mpoly_set_si(A, 1, ctx);
0240 }
0241 
0242 int fmpz_mod_mpoly_equal_fmpz(const fmpz_mod_mpoly_t A,
0243                                const fmpz_t c, const fmpz_mod_mpoly_ctx_t ctx);
0244 
0245 int fmpz_mod_mpoly_equal_ui(const fmpz_mod_mpoly_t A,
0246                                       ulong c, const fmpz_mod_mpoly_ctx_t ctx);
0247 
0248 int fmpz_mod_mpoly_equal_si(const fmpz_mod_mpoly_t A,
0249                                       slong c, const fmpz_mod_mpoly_ctx_t ctx);
0250 
0251 FMPZ_MOD_MPOLY_INLINE
0252 int fmpz_mod_mpoly_is_zero(const fmpz_mod_mpoly_t A,
0253                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0254 {
0255    return A->length < 1;
0256 }
0257 
0258 FMPZ_MOD_MPOLY_INLINE
0259 int fmpz_mod_mpoly_is_one(const fmpz_mod_mpoly_t A,
0260                                                 const fmpz_mod_mpoly_ctx_t ctx)
0261 {
0262    return fmpz_mod_mpoly_equal_si(A, 1, ctx);
0263 }
0264 
0265 /* Degrees *******************************************************************/
0266 
0267 int fmpz_mod_mpoly_degrees_fit_si(const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0268 
0269 void fmpz_mod_mpoly_degrees_fmpz(fmpz ** degs, const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0270 void fmpz_mod_mpoly_degrees_si(slong * degs, const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0271 
0272 void fmpz_mod_mpoly_degree_fmpz(fmpz_t deg, const fmpz_mod_mpoly_t A, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0273 slong fmpz_mod_mpoly_degree_si(const fmpz_mod_mpoly_t A, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0274 
0275 int fmpz_mod_mpoly_total_degree_fits_si(const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0276 
0277 void fmpz_mod_mpoly_total_degree_fmpz(fmpz_t td, const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0278 slong fmpz_mod_mpoly_total_degree_si(const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0279 
0280 void fmpz_mod_mpoly_used_vars(int * used, const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0281 
0282 /* Coefficients **************************************************************/
0283 
0284 void fmpz_mod_mpoly_get_coeff_fmpz_monomial(fmpz_t c,
0285                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t M,
0286                                                const fmpz_mod_mpoly_ctx_t ctx);
0287 
0288 void fmpz_mod_mpoly_set_coeff_fmpz_monomial(fmpz_mod_mpoly_t A,
0289                                     const fmpz_t c, const fmpz_mod_mpoly_t M,
0290                                                const fmpz_mod_mpoly_ctx_t ctx);
0291 
0292 void fmpz_mod_mpoly_get_coeff_fmpz_fmpz(fmpz_t c,
0293                                 const fmpz_mod_mpoly_t A, fmpz * const * exp,
0294                                                const fmpz_mod_mpoly_ctx_t ctx);
0295 
0296 void fmpz_mod_mpoly_get_coeff_fmpz_ui(fmpz_t c,
0297                                 const fmpz_mod_mpoly_t A, const ulong * exp,
0298                                                const fmpz_mod_mpoly_ctx_t ctx);
0299 
0300 void _fmpz_mod_mpoly_set_coeff_fmpz_fmpz(fmpz_mod_mpoly_t A,
0301              const fmpz_t c, const fmpz * exp, const fmpz_mod_mpoly_ctx_t ctx);
0302 
0303 void fmpz_mod_mpoly_set_coeff_fmpz_fmpz(fmpz_mod_mpoly_t A,
0304            const fmpz_t c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0305 
0306 void fmpz_mod_mpoly_set_coeff_ui_fmpz(fmpz_mod_mpoly_t A,
0307                   ulong c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0308 
0309 void fmpz_mod_mpoly_set_coeff_si_fmpz(fmpz_mod_mpoly_t A,
0310                   slong c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0311 
0312 void fmpz_mod_mpoly_set_coeff_fmpz_ui(fmpz_mod_mpoly_t A,
0313             const fmpz_t c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0314 
0315 void fmpz_mod_mpoly_set_coeff_ui_ui(fmpz_mod_mpoly_t A,
0316                    ulong c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0317 
0318 void fmpz_mod_mpoly_set_coeff_si_ui(fmpz_mod_mpoly_t A,
0319                    slong c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0320 
0321 void fmpz_mod_mpoly_get_coeff_vars_ui(fmpz_mod_mpoly_t C,
0322              const fmpz_mod_mpoly_t A, const slong * vars, const ulong * exps,
0323                                  slong length, const fmpz_mod_mpoly_ctx_t ctx);
0324 
0325 FMPZ_MOD_MPOLY_INLINE fmpz * fmpz_mod_mpoly_leadcoeff(fmpz_mod_mpoly_t A)
0326 {
0327     FLINT_ASSERT(A->length > 0);
0328     return A->coeffs + 0;
0329 }
0330 
0331 /* conversion ****************************************************************/
0332 
0333 int fmpz_mod_mpoly_is_fmpz_mod_poly(const fmpz_mod_mpoly_t A,
0334                                     slong var, const fmpz_mod_mpoly_ctx_t ctx);
0335 
0336 int fmpz_mod_mpoly_get_fmpz_mod_poly(fmpz_mod_poly_t A,
0337           const fmpz_mod_mpoly_t B, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0338 
0339 void _fmpz_mod_mpoly_set_fmpz_mod_poly(fmpz_mod_mpoly_t A,
0340                     flint_bitcnt_t Abits, const fmpz * Bcoeffs, slong Blen,
0341                                     slong var, const fmpz_mod_mpoly_ctx_t ctx);
0342 
0343 void fmpz_mod_mpoly_set_fmpz_mod_poly(fmpz_mod_mpoly_t A,
0344            const fmpz_mod_poly_t B, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0345 
0346 /* comparison ****************************************************************/
0347 
0348 int fmpz_mod_mpoly_cmp(const fmpz_mod_mpoly_t A,
0349                      const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx);
0350 
0351 
0352 /* container operations ******************************************************/
0353 
0354 int fmpz_mod_mpoly_is_canonical(const fmpz_mod_mpoly_t A,
0355                                                const fmpz_mod_mpoly_ctx_t ctx);
0356 
0357 FMPZ_MOD_MPOLY_INLINE
0358 slong fmpz_mod_mpoly_length(const fmpz_mod_mpoly_t A,
0359                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0360 {
0361     return A->length;
0362 }
0363 
0364 void fmpz_mod_mpoly_resize(fmpz_mod_mpoly_t A, slong new_length,
0365                                                const fmpz_mod_mpoly_ctx_t ctx);
0366 
0367 void fmpz_mod_mpoly_get_term_coeff_fmpz(fmpz_t c,
0368             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0369 
0370 void fmpz_mod_mpoly_set_term_coeff_fmpz(fmpz_mod_mpoly_t A, slong i,
0371                                const fmpz_t c, const fmpz_mod_mpoly_ctx_t ctx);
0372 
0373 void fmpz_mod_mpoly_set_term_coeff_ui(fmpz_mod_mpoly_t A, slong i,
0374                                       ulong c, const fmpz_mod_mpoly_ctx_t ctx);
0375 
0376 void fmpz_mod_mpoly_set_term_coeff_si(fmpz_mod_mpoly_t A, slong i,
0377                                       slong c, const fmpz_mod_mpoly_ctx_t ctx);
0378 
0379 int fmpz_mod_mpoly_term_exp_fits_ui(const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0380 int fmpz_mod_mpoly_term_exp_fits_si(const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0381 
0382 void fmpz_mod_mpoly_get_term_exp_fmpz(fmpz ** exp,
0383             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0384 
0385 void fmpz_mod_mpoly_get_term_exp_ui(ulong * exp,
0386             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0387 
0388 void fmpz_mod_mpoly_get_term_exp_si(slong * exp,
0389             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0390 
0391 ulong fmpz_mod_mpoly_get_term_var_exp_ui(const fmpz_mod_mpoly_t A,
0392                            slong i, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0393 
0394 slong fmpz_mod_mpoly_get_term_var_exp_si(const fmpz_mod_mpoly_t A,
0395                            slong i, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0396 
0397 void fmpz_mod_mpoly_set_term_exp_fmpz(fmpz_mod_mpoly_t A, slong i,
0398                            fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0399 
0400 void fmpz_mod_mpoly_set_term_exp_ui(fmpz_mod_mpoly_t A, slong i,
0401                             const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0402 
0403 void fmpz_mod_mpoly_get_term(fmpz_mod_mpoly_t M,
0404             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0405 
0406 void fmpz_mod_mpoly_get_term_monomial(fmpz_mod_mpoly_t M,
0407             const fmpz_mod_mpoly_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx);
0408 
0409 void fmpz_mod_mpoly_push_term_fmpz_fmpz(fmpz_mod_mpoly_t A,
0410            const fmpz_t c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0411 
0412 void fmpz_mod_mpoly_push_term_fmpz_ffmpz(fmpz_mod_mpoly_t A,
0413            const fmpz_t c, const fmpz * exp, const fmpz_mod_mpoly_ctx_t ctx);
0414 
0415 void fmpz_mod_mpoly_push_term_ui_fmpz(fmpz_mod_mpoly_t A,
0416                   ulong c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0417 
0418 void fmpz_mod_mpoly_push_term_ui_ffmpz(fmpz_mod_mpoly_t A,
0419                   ulong c, const fmpz * exp, const fmpz_mod_mpoly_ctx_t ctx);
0420 
0421 void fmpz_mod_mpoly_push_term_si_fmpz(fmpz_mod_mpoly_t A,
0422                   slong c, fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0423 
0424 void fmpz_mod_mpoly_push_term_si_ffmpz(fmpz_mod_mpoly_t A,
0425                   slong c, const fmpz * exp, const fmpz_mod_mpoly_ctx_t ctx);
0426 
0427 void fmpz_mod_mpoly_push_term_fmpz_ui(fmpz_mod_mpoly_t A,
0428             const fmpz_t c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0429 
0430 void fmpz_mod_mpoly_push_term_ui_ui(fmpz_mod_mpoly_t A,
0431                    ulong c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0432 
0433 void fmpz_mod_mpoly_push_term_si_ui(fmpz_mod_mpoly_t A,
0434                    slong c, const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0435 
0436 void fmpz_mod_mpoly_sort_terms(fmpz_mod_mpoly_t A,
0437                                                const fmpz_mod_mpoly_ctx_t ctx);
0438 
0439 void fmpz_mod_mpoly_combine_like_terms(fmpz_mod_mpoly_t A,
0440                                                const fmpz_mod_mpoly_ctx_t ctx);
0441 
0442 void fmpz_mod_mpoly_reverse(fmpz_mod_mpoly_t A,
0443                      const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx);
0444 
0445 void fmpz_mod_mpoly_assert_canonical(const fmpz_mod_mpoly_t A,
0446                                                const fmpz_mod_mpoly_ctx_t ctx);
0447 
0448 void _fmpz_mod_mpoly_radix_sort1(fmpz *, ulong *, slong left,
0449               slong right, flint_bitcnt_t pos, ulong cmpmask, ulong totalmask);
0450 
0451 void _fmpz_mod_mpoly_radix_sort(fmpz *, ulong *, slong left,
0452                     slong right, flint_bitcnt_t pos, slong N, ulong * cmpmask);
0453 
0454 void _fmpz_mod_mpoly_push_exp_ffmpz(fmpz_mod_mpoly_t A,
0455                              const fmpz * exp, const fmpz_mod_mpoly_ctx_t ctx);
0456 
0457 void _fmpz_mod_mpoly_push_exp_pfmpz(fmpz_mod_mpoly_t A,
0458                            fmpz * const * exp, const fmpz_mod_mpoly_ctx_t ctx);
0459 
0460 void _fmpz_mod_mpoly_push_exp_ui(fmpz_mod_mpoly_t A,
0461                             const ulong * exp, const fmpz_mod_mpoly_ctx_t ctx);
0462 
0463 
0464 /* Random generation *********************************************************/
0465 
0466 void fmpz_mod_mpoly_randtest_bounds(fmpz_mod_mpoly_t A,
0467                         flint_rand_t state, slong length, ulong * exp_bounds,
0468                                                const fmpz_mod_mpoly_ctx_t ctx);
0469 
0470 void fmpz_mod_mpoly_randtest_bound(fmpz_mod_mpoly_t A,
0471                             flint_rand_t state, slong length, ulong exp_bound,
0472                                                const fmpz_mod_mpoly_ctx_t ctx);
0473 
0474 void fmpz_mod_mpoly_randtest_bits(fmpz_mod_mpoly_t A,
0475                     flint_rand_t state, slong length, flint_bitcnt_t exp_bits,
0476                                                const fmpz_mod_mpoly_ctx_t ctx);
0477 
0478 
0479 /* Addition/Subtraction ******************************************************/
0480 
0481 void fmpz_mod_mpoly_add_fmpz_mod(fmpz_mod_mpoly_t A,
0482                                     const fmpz_mod_mpoly_t B, const fmpz_t c,
0483                                                const fmpz_mod_mpoly_ctx_t ctx);
0484 
0485 void fmpz_mod_mpoly_add_fmpz(fmpz_mod_mpoly_t A,
0486                                     const fmpz_mod_mpoly_t B, const fmpz_t c,
0487                                                const fmpz_mod_mpoly_ctx_t ctx);
0488 
0489 void fmpz_mod_mpoly_add_ui(fmpz_mod_mpoly_t A,
0490                                     const fmpz_mod_mpoly_t B, ulong c,
0491                                                const fmpz_mod_mpoly_ctx_t ctx);
0492 
0493 void fmpz_mod_mpoly_add_si(fmpz_mod_mpoly_t A,
0494                                     const fmpz_mod_mpoly_t B, slong c,
0495                                                const fmpz_mod_mpoly_ctx_t ctx);
0496 
0497 void fmpz_mod_mpoly_sub_fmpz(fmpz_mod_mpoly_t A,
0498                                     const fmpz_mod_mpoly_t B, const fmpz_t c,
0499                                                const fmpz_mod_mpoly_ctx_t ctx);
0500 
0501 void fmpz_mod_mpoly_sub_ui(fmpz_mod_mpoly_t A,
0502                                     const fmpz_mod_mpoly_t B, ulong c,
0503                                                const fmpz_mod_mpoly_ctx_t ctx);
0504 
0505 void fmpz_mod_mpoly_sub_si(fmpz_mod_mpoly_t A,
0506                                     const fmpz_mod_mpoly_t B, slong c,
0507                                                const fmpz_mod_mpoly_ctx_t ctx);
0508 
0509 void fmpz_mod_mpoly_add(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0510                      const fmpz_mod_mpoly_t C, const fmpz_mod_mpoly_ctx_t ctx);
0511 
0512 void fmpz_mod_mpoly_sub(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0513                      const fmpz_mod_mpoly_t C, const fmpz_mod_mpoly_ctx_t ctx);
0514 
0515 /* Scalar operations *********************************************************/
0516 
0517 void fmpz_mod_mpoly_neg(fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0518                                                const fmpz_mod_mpoly_ctx_t ctx);
0519 
0520 void fmpz_mod_mpoly_scalar_mul_fmpz_mod_invertible(fmpz_mod_mpoly_t A,
0521                                     const fmpz_mod_mpoly_t B, const fmpz_t c,
0522                                                const fmpz_mod_mpoly_ctx_t ctx);
0523 
0524 void fmpz_mod_mpoly_scalar_mul_fmpz(fmpz_mod_mpoly_t A,
0525                                     const fmpz_mod_mpoly_t B, const fmpz_t c,
0526                                                const fmpz_mod_mpoly_ctx_t ctx);
0527 
0528 void fmpz_mod_mpoly_scalar_mul_ui(fmpz_mod_mpoly_t A,
0529                                     const fmpz_mod_mpoly_t B, ulong c,
0530                                                const fmpz_mod_mpoly_ctx_t ctx);
0531 
0532 void fmpz_mod_mpoly_scalar_mul_si(fmpz_mod_mpoly_t A,
0533                                     const fmpz_mod_mpoly_t B, slong c,
0534                                                const fmpz_mod_mpoly_ctx_t ctx);
0535 
0536 void fmpz_mod_mpoly_scalar_addmul_fmpz(fmpz_mod_mpoly_t A,
0537                         const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_t C,
0538                                const fmpz_t d, const fmpz_mod_mpoly_ctx_t ctx);
0539 
0540 void fmpz_mod_mpoly_make_monic(fmpz_mod_mpoly_t A,
0541                      const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx);
0542 
0543 
0544 /* Differentiation ************************************************************/
0545 
0546 void fmpz_mod_mpoly_derivative(fmpz_mod_mpoly_t A,
0547           const fmpz_mod_mpoly_t B, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0548 
0549 
0550 /* Evaluation ****************************************************************/
0551 
0552 void _fmpz_mod_mpoly_eval_all_fmpz_mod(fmpz_t eval,
0553                         const fmpz * Acoeffs, const ulong * Aexps, slong Alen,
0554                             flint_bitcnt_t Abits, const fmpz * alphas,
0555                             const mpoly_ctx_t mctx, const fmpz_mod_ctx_t fctx);
0556 
0557 void fmpz_mod_mpoly_evaluate_all_fmpz(fmpz_t eval,
0558                             const fmpz_mod_mpoly_t A, fmpz * const * alphas,
0559                                                const fmpz_mod_mpoly_ctx_t ctx);
0560 
0561 void fmpz_mod_mpoly_evaluate_one_fmpz(fmpz_mod_mpoly_t A,
0562                         const fmpz_mod_mpoly_t B, slong var, const fmpz_t val,
0563                                                const fmpz_mod_mpoly_ctx_t ctx);
0564 
0565 void _fmpz_mod_mpoly_compose_mat(fmpz_mod_mpoly_t A,
0566             const fmpz_mod_mpoly_t B, const fmpz_mat_t M,
0567             const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);
0568 
0569 int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_geobucket(fmpz_mod_mpoly_t A,
0570             const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
0571             const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);
0572 
0573 int fmpz_mod_mpoly_compose_fmpz_mod_mpoly_horner(fmpz_mod_mpoly_t A,
0574             const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
0575             const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);
0576 
0577 int fmpz_mod_mpoly_compose_fmpz_mod_mpoly(fmpz_mod_mpoly_t A,
0578             const fmpz_mod_mpoly_t B, fmpz_mod_mpoly_struct * const * C,
0579             const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);
0580 
0581 void fmpz_mod_mpoly_compose_fmpz_mod_mpoly_gen(fmpz_mod_mpoly_t A,
0582             const fmpz_mod_mpoly_t B, const slong * c,
0583             const fmpz_mod_mpoly_ctx_t ctxB, const fmpz_mod_mpoly_ctx_t ctxAC);
0584 
0585 
0586 /* Multiplication ************************************************************/
0587 
0588 void fmpz_mod_mpoly_mul(fmpz_mod_mpoly_t A,
0589                           const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_t C,
0590                                                const fmpz_mod_mpoly_ctx_t ctx);
0591 
0592 void fmpz_mod_mpoly_mul_johnson(fmpz_mod_mpoly_t A,
0593                           const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_t C,
0594                                                const fmpz_mod_mpoly_ctx_t ctx);
0595 
0596 void _fmpz_mod_mpoly_mul_johnson_maxfields(fmpz_mod_mpoly_t A,
0597                                 const fmpz_mod_mpoly_t B, fmpz * maxBfields,
0598                                 const fmpz_mod_mpoly_t C, fmpz * maxCfields,
0599                                                const fmpz_mod_mpoly_ctx_t ctx);
0600 
0601 int fmpz_mod_mpoly_mul_dense(fmpz_mod_mpoly_t A,
0602                         const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_t C,
0603                                                const fmpz_mod_mpoly_ctx_t ctx);
0604 
0605 int _fmpz_mod_mpoly_mul_dense_maxfields(fmpz_mod_mpoly_t P,
0606                                 const fmpz_mod_mpoly_t A, fmpz * maxAfields,
0607                                 const fmpz_mod_mpoly_t B, fmpz * maxBfields,
0608                                                const fmpz_mod_mpoly_ctx_t ctx);
0609 
0610 /* Powering ******************************************************************/
0611 
0612 int fmpz_mod_mpoly_pow_fmpz(fmpz_mod_mpoly_t A,
0613      const fmpz_mod_mpoly_t B, const fmpz_t k, const fmpz_mod_mpoly_ctx_t ctx);
0614 
0615 int fmpz_mod_mpoly_pow_ui(fmpz_mod_mpoly_t A,
0616             const fmpz_mod_mpoly_t B, ulong k, const fmpz_mod_mpoly_ctx_t ctx);
0617 
0618 void fmpz_mod_mpoly_pow_rmul(fmpz_mod_mpoly_t A,
0619             const fmpz_mod_mpoly_t B, ulong k, const fmpz_mod_mpoly_ctx_t ctx);
0620 
0621 /* Division ******************************************************************/
0622 
0623 int fmpz_mod_mpoly_divides(fmpz_mod_mpoly_t Q,
0624                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0625                                                const fmpz_mod_mpoly_ctx_t ctx);
0626 
0627 void fmpz_mod_mpoly_div(fmpz_mod_mpoly_t Q,
0628                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0629                                                const fmpz_mod_mpoly_ctx_t ctx);
0630 
0631 void fmpz_mod_mpoly_divrem(fmpz_mod_mpoly_t Q, fmpz_mod_mpoly_t R,
0632                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0633                                                const fmpz_mod_mpoly_ctx_t ctx);
0634 
0635 void fmpz_mod_mpoly_divrem_ideal(fmpz_mod_mpoly_struct ** Q,
0636                             fmpz_mod_mpoly_t R, const fmpz_mod_mpoly_t A,
0637                             fmpz_mod_mpoly_struct * const * B, slong len,
0638                                                const fmpz_mod_mpoly_ctx_t ctx);
0639 
0640 FMPZ_MOD_MPOLY_INLINE
0641 void fmpz_mod_mpoly_divexact(fmpz_mod_mpoly_t Q, const fmpz_mod_mpoly_t A,
0642                       const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx)
0643 {
0644     if (fmpz_mod_mpoly_divides(Q, A, B, ctx))
0645         return;
0646 
0647     flint_throw(FLINT_ERROR, "fmpz_mod_mpoly_divexact: nonexact division");
0648 }
0649 
0650 int _fmpz_mod_mpoly_divides_dense_maxfields(fmpz_mod_mpoly_t Q,
0651                                 const fmpz_mod_mpoly_t A, fmpz * maxAfields,
0652                                 const fmpz_mod_mpoly_t B, fmpz * maxBfields,
0653                                                const fmpz_mod_mpoly_ctx_t ctx);
0654 
0655 int fmpz_mod_mpoly_divides_dense(fmpz_mod_mpoly_t Q,
0656                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0657                                                const fmpz_mod_mpoly_ctx_t ctx);
0658 
0659 int _fmpz_mod_mpoly_divides_monagan_pearce_maxfields(
0660             fmpz_mod_mpoly_t Q, const fmpz_mod_mpoly_t A, fmpz * maxAfields,
0661                                 const fmpz_mod_mpoly_t B, fmpz * maxBfields,
0662                                                const fmpz_mod_mpoly_ctx_t ctx);
0663 
0664 int fmpz_mod_mpoly_divides_monagan_pearce(fmpz_mod_mpoly_t Q,
0665                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0666                                                const fmpz_mod_mpoly_ctx_t ctx);
0667 
0668 void fmpz_mod_mpoly_div_monagan_pearce(fmpz_mod_mpoly_t Q,
0669                           const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0670                                                const fmpz_mod_mpoly_ctx_t ctx);
0671 
0672 void fmpz_mod_mpoly_divrem_monagan_pearce(fmpz_mod_mpoly_t Q,
0673         fmpz_mod_mpoly_t R, const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0674                                                const fmpz_mod_mpoly_ctx_t ctx);
0675 
0676 void fmpz_mod_mpoly_divrem_ideal_monagan_pearce(
0677         fmpz_mod_mpoly_struct ** Q, fmpz_mod_mpoly_t R,
0678         const fmpz_mod_mpoly_t A, fmpz_mod_mpoly_struct * const * B, slong len,
0679                                                const fmpz_mod_mpoly_ctx_t ctx);
0680 
0681 
0682 /* Square root ***************************************************************/
0683 
0684 int fmpz_mod_mpoly_sqrt_heap(fmpz_mod_mpoly_t Q,
0685                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0686 
0687 FMPZ_MOD_MPOLY_INLINE
0688 int fmpz_mod_mpoly_sqrt(fmpz_mod_mpoly_t Q, const fmpz_mod_mpoly_t A,
0689                                                 const fmpz_mod_mpoly_ctx_t ctx)
0690 {
0691     return fmpz_mod_mpoly_sqrt_heap(Q, A, ctx);
0692 }
0693 
0694 FMPZ_MOD_MPOLY_INLINE
0695 int fmpz_mod_mpoly_is_square(const fmpz_mod_mpoly_t A,
0696                                                 const fmpz_mod_mpoly_ctx_t ctx)
0697 {
0698     int res;
0699     fmpz_mod_mpoly_t Q;
0700     fmpz_mod_mpoly_init(Q, ctx);
0701     res = fmpz_mod_mpoly_sqrt_heap(Q, A, ctx);
0702     fmpz_mod_mpoly_clear(Q, ctx);
0703     return res;
0704 }
0705 
0706 int fmpz_mod_mpoly_quadratic_root(fmpz_mod_mpoly_t Q,
0707                     const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0708                                                const fmpz_mod_mpoly_ctx_t ctx);
0709 
0710 /* GCD ***********************************************************************/
0711 
0712 void fmpz_mod_mpoly_term_content(fmpz_mod_mpoly_t M,
0713                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0714 
0715 void fmpz_mod_mpoly_monic_part(fmpz_mod_mpoly_t res, 
0716     const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
0717 
0718 int fmpz_mod_mpoly_content_vars(fmpz_mod_mpoly_t g,
0719                     const fmpz_mod_mpoly_t A, slong * vars, slong vars_length,
0720                                                const fmpz_mod_mpoly_ctx_t ctx);
0721 
0722 int fmpz_mod_mpoly_gcd(fmpz_mod_mpoly_t G, const fmpz_mod_mpoly_t A,
0723                      const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t ctx);
0724 
0725 int fmpz_mod_mpoly_gcd_cofactors(fmpz_mod_mpoly_t G,
0726                         fmpz_mod_mpoly_t Abar, fmpz_mod_mpoly_t Bbar,
0727                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0728                                                const fmpz_mod_mpoly_ctx_t ctx);
0729 
0730 int fmpz_mod_mpoly_gcd_subresultant(fmpz_mod_mpoly_t G,
0731                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0732                                                const fmpz_mod_mpoly_ctx_t ctx);
0733 
0734 int fmpz_mod_mpoly_gcd_brown(fmpz_mod_mpoly_t G,
0735                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0736                                                const fmpz_mod_mpoly_ctx_t ctx);
0737 
0738 int fmpz_mod_mpoly_gcd_hensel(fmpz_mod_mpoly_t G,
0739                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0740                                                const fmpz_mod_mpoly_ctx_t ctx);
0741 
0742 int fmpz_mod_mpoly_gcd_zippel(fmpz_mod_mpoly_t G,
0743                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0744                                                const fmpz_mod_mpoly_ctx_t ctx);
0745 
0746 int fmpz_mod_mpoly_gcd_zippel2(fmpz_mod_mpoly_t G,
0747                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0748                                                const fmpz_mod_mpoly_ctx_t ctx);
0749 
0750 void fmpz_mod_mpoly_deflation(fmpz * shift, fmpz * stride,
0751                      const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_ctx_t ctx);
0752 
0753 void fmpz_mod_mpoly_deflate(fmpz_mod_mpoly_t A,
0754             const fmpz_mod_mpoly_t B, const fmpz * shift, const fmpz * stride,
0755                                                const fmpz_mod_mpoly_ctx_t ctx);
0756 
0757 void fmpz_mod_mpoly_inflate(fmpz_mod_mpoly_t A,
0758             const fmpz_mod_mpoly_t B, const fmpz * shift, const fmpz * stride,
0759                                                const fmpz_mod_mpoly_ctx_t ctx);
0760 
0761 /* Univariates ***************************************************************/
0762 
0763 void fmpz_mod_mpoly_univar_init(fmpz_mod_mpoly_univar_t A,
0764                                                const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0765 
0766 void fmpz_mod_mpoly_univar_clear(fmpz_mod_mpoly_univar_t A,
0767                                                const fmpz_mod_mpoly_ctx_t ctx);
0768 
0769 void fmpz_mod_mpoly_univar_fit_length(fmpz_mod_mpoly_univar_t A,
0770                                  slong length, const fmpz_mod_mpoly_ctx_t ctx);
0771 
0772 void fmpz_mod_mpoly_univar_print_pretty(const fmpz_mod_mpoly_univar_t A,
0773                               const char ** x, const fmpz_mod_mpoly_ctx_t ctx);
0774 
0775 void fmpz_mod_mpoly_univar_assert_canonical(fmpz_mod_mpoly_univar_t A,
0776                                                const fmpz_mod_mpoly_ctx_t ctx);
0777 
0778 FMPZ_MOD_MPOLY_INLINE
0779 void fmpz_mod_mpoly_univar_zero(fmpz_mod_mpoly_univar_t A,
0780                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0781 {
0782     A->length = 0;
0783 }
0784 
0785 void fmpz_mod_mpoly_univar_set_coeff_ui(fmpz_mod_mpoly_univar_t A,
0786             ulong e, const fmpz_mod_mpoly_t c, const fmpz_mod_mpoly_ctx_t ctx);
0787 
0788 void fmpz_mod_mpoly_to_univar(fmpz_mod_mpoly_univar_t A,
0789           const fmpz_mod_mpoly_t B, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0790 
0791 void _fmpz_mod_mpoly_from_univar(fmpz_mod_mpoly_t A,
0792             flint_bitcnt_t Abits, const fmpz_mod_mpoly_univar_t B, slong var,
0793                                                const fmpz_mod_mpoly_ctx_t ctx);
0794 
0795 void fmpz_mod_mpoly_from_univar(fmpz_mod_mpoly_t A,
0796                                   const fmpz_mod_mpoly_univar_t B, slong var,
0797                                                const fmpz_mod_mpoly_ctx_t ctx);
0798 
0799 FMPZ_MOD_MPOLY_INLINE
0800 void fmpz_mod_mpoly_univar_swap(fmpz_mod_mpoly_univar_t A,
0801                      fmpz_mod_mpoly_univar_t B, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0802 {
0803     FLINT_SWAP(fmpz_mod_mpoly_univar_struct, *A, *B);
0804 }
0805 
0806 FMPZ_MOD_MPOLY_INLINE
0807 int fmpz_mod_mpoly_univar_degree_fits_si(const fmpz_mod_mpoly_univar_t A,
0808                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0809 {
0810     return A->length == 0 || fmpz_fits_si(A->exps + 0);
0811 }
0812 
0813 FMPZ_MOD_MPOLY_INLINE
0814 slong fmpz_mod_mpoly_univar_length(const fmpz_mod_mpoly_univar_t A,
0815                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0816 {
0817     return A->length;
0818 }
0819 
0820 FMPZ_MOD_MPOLY_INLINE
0821 slong fmpz_mod_mpoly_univar_get_term_exp_si(fmpz_mod_mpoly_univar_t A, slong i,
0822                                                 const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx))
0823 {
0824     FLINT_ASSERT(i < (ulong)A->length);
0825     return fmpz_get_si(A->exps + i);
0826 }
0827 
0828 FMPZ_MOD_MPOLY_INLINE
0829 void fmpz_mod_mpoly_univar_get_term_coeff(fmpz_mod_mpoly_t c,
0830       const fmpz_mod_mpoly_univar_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx)
0831 {
0832     FLINT_ASSERT((ulong)i < (ulong)A->length);
0833     fmpz_mod_mpoly_set(c, A->coeffs + i, ctx);
0834 }
0835 
0836 FMPZ_MOD_MPOLY_INLINE
0837 void fmpz_mod_mpoly_univar_swap_term_coeff(fmpz_mod_mpoly_t c,
0838             fmpz_mod_mpoly_univar_t A, slong i, const fmpz_mod_mpoly_ctx_t ctx)
0839 {
0840     FLINT_ASSERT((ulong)i < (ulong)A->length);
0841     fmpz_mod_mpoly_swap(c, A->coeffs + i, ctx);
0842 }
0843 
0844 int fmpz_mod_mpoly_univar_pseudo_gcd(fmpz_mod_mpoly_univar_t Gx,
0845         const fmpz_mod_mpoly_univar_t Ax, const fmpz_mod_mpoly_univar_t Bx,
0846                                                const fmpz_mod_mpoly_ctx_t ctx);
0847 
0848 int fmpz_mod_mpoly_univar_resultant(fmpz_mod_mpoly_t R,
0849         const fmpz_mod_mpoly_univar_t Ax, const fmpz_mod_mpoly_univar_t Bx,
0850                                                const fmpz_mod_mpoly_ctx_t ctx);
0851 
0852 int fmpz_mod_mpoly_univar_discriminant(fmpz_mod_mpoly_t D,
0853              const fmpz_mod_mpoly_univar_t Fx, const fmpz_mod_mpoly_ctx_t ctx);
0854 
0855 int fmpz_mod_mpoly_resultant(fmpz_mod_mpoly_t R,
0856                         const fmpz_mod_mpoly_t A, const fmpz_mod_mpoly_t B,
0857                                     slong var, const fmpz_mod_mpoly_ctx_t ctx);
0858 
0859 int fmpz_mod_mpoly_discriminant(fmpz_mod_mpoly_t R,
0860           const fmpz_mod_mpoly_t A, slong var, const fmpz_mod_mpoly_ctx_t ctx);
0861 
0862 /******************************************************************************
0863 
0864    Internal functions (guaranteed to change without notice)
0865 
0866 ******************************************************************************/
0867 
0868 FMPZ_MOD_MPOLY_INLINE
0869 void _fmpz_mod_mpoly_clear_dense_mock(fmpz_mod_poly_t D)
0870 {
0871     flint_free(D->coeffs);
0872 }
0873 
0874 void _fmpz_mod_mpoly_init_dense_mock(fmpz_mod_poly_t D,
0875                         const fmpz_mod_mpoly_t A, const slong * Adeg_bounds,
0876                                                const fmpz_mod_mpoly_ctx_t ctx);
0877 
0878 void mpoly_void_ring_init_fmpz_mod_mpoly_ctx(mpoly_void_ring_t R,
0879                                               const fmpz_mod_mpoly_ctx_t ctx);
0880 
0881 /* geobuckets ****************************************************************/
0882 
0883 typedef struct fmpz_mod_mpoly_geobucket
0884 {
0885     fmpz_mod_mpoly_struct polys[FLINT_BITS/2];
0886     fmpz_mod_mpoly_struct temps[FLINT_BITS/2];
0887     slong length;
0888 } fmpz_mod_mpoly_geobucket_struct;
0889 
0890 typedef fmpz_mod_mpoly_geobucket_struct fmpz_mod_mpoly_geobucket_t[1];
0891 
0892 void fmpz_mod_mpoly_geobucket_init(fmpz_mod_mpoly_geobucket_t B,
0893                                                const fmpz_mod_mpoly_ctx_t ctx);
0894 
0895 void fmpz_mod_mpoly_geobucket_clear(fmpz_mod_mpoly_geobucket_t B,
0896                                                const fmpz_mod_mpoly_ctx_t ctx);
0897 
0898 void fmpz_mod_mpoly_geobucket_empty(fmpz_mod_mpoly_t p,
0899                  fmpz_mod_mpoly_geobucket_t B, const fmpz_mod_mpoly_ctx_t ctx);
0900 
0901 void fmpz_mod_mpoly_geobucket_fit_length(fmpz_mod_mpoly_geobucket_t B,
0902                                       slong i, const fmpz_mod_mpoly_ctx_t ctx);
0903 
0904 void fmpz_mod_mpoly_geobucket_set(fmpz_mod_mpoly_geobucket_t B,
0905                            fmpz_mod_mpoly_t p, const fmpz_mod_mpoly_ctx_t ctx);
0906 
0907 void fmpz_mod_mpoly_geobucket_add(fmpz_mod_mpoly_geobucket_t B,
0908                            fmpz_mod_mpoly_t p, const fmpz_mod_mpoly_ctx_t ctx);
0909 
0910 void fmpz_mod_mpoly_geobucket_sub(fmpz_mod_mpoly_geobucket_t B,
0911                            fmpz_mod_mpoly_t p, const fmpz_mod_mpoly_ctx_t ctx);
0912 
0913 void fmpz_mod_mpolyl_lead_coeff(fmpz_mod_mpoly_t c,
0914      const fmpz_mod_mpoly_t A, slong num_vars, const fmpz_mod_mpoly_ctx_t ctx);
0915 
0916 int fmpz_mod_mpolyl_content(fmpz_mod_mpoly_t g,
0917      const fmpz_mod_mpoly_t A, slong num_vars, const fmpz_mod_mpoly_ctx_t ctx);
0918 
0919 void _fmpz_mod_mpoly_to_fmpz_mod_poly_deflate(fmpz_mod_poly_t A,
0920                 const fmpz_mod_mpoly_t B, slong var, const ulong * Bshift,
0921                         const ulong * Bstride, const fmpz_mod_mpoly_ctx_t ctx);
0922 
0923 void _fmpz_mod_mpoly_from_fmpz_mod_poly_inflate(fmpz_mod_mpoly_t A,
0924                     flint_bitcnt_t Abits, const fmpz_mod_poly_t B, slong var,
0925                     const ulong * Ashift, const ulong * Astride,
0926                                                const fmpz_mod_mpoly_ctx_t ctx);
0927 
0928 void _fmpz_mod_mpoly_set_nmod_mpoly(fmpz_mod_mpoly_t A,
0929                         const fmpz_mod_mpoly_ctx_t ctx, const nmod_mpoly_t nA,
0930                                                   const nmod_mpoly_ctx_t FLINT_UNUSED(nctx));
0931 
0932 void _fmpz_mod_mpoly_get_nmod_mpoly(nmod_mpoly_t nA,
0933                         const nmod_mpoly_ctx_t nctx, const fmpz_mod_mpoly_t A,
0934                                                const fmpz_mod_mpoly_ctx_t ctx);
0935 
0936 int fmpz_mod_mpoly_repack_bits(fmpz_mod_mpoly_t A,
0937                             const fmpz_mod_mpoly_t B, flint_bitcnt_t Abits,
0938                                                const fmpz_mod_mpoly_ctx_t ctx);
0939 
0940 int fmpz_mod_mpoly_repack_bits_inplace(fmpz_mod_mpoly_t A,
0941                          flint_bitcnt_t Abits, const fmpz_mod_mpoly_ctx_t ctx);
0942 
0943 void fmpz_mod_mpoly_to_mpolyl_perm_deflate(fmpz_mod_mpoly_t A,
0944                     const fmpz_mod_mpoly_ctx_t lctx, const fmpz_mod_mpoly_t B,
0945                     const fmpz_mod_mpoly_ctx_t ctx,
0946                 const slong * perm, const ulong * shift, const ulong * stride);
0947 
0948 void fmpz_mod_mpoly_from_mpolyl_perm_inflate(fmpz_mod_mpoly_t A,
0949                 flint_bitcnt_t Abits, const fmpz_mod_mpoly_ctx_t ctx,
0950                 const fmpz_mod_mpoly_t B, const fmpz_mod_mpoly_ctx_t lctx,
0951                 const slong * perm, const ulong * shift, const ulong * stride);
0952 
0953 
0954 /* Vectors of multivariate polynomials */
0955 
0956 typedef struct
0957 {
0958     fmpz_mod_mpoly_struct * p;
0959     slong alloc;
0960     slong length;
0961 }
0962 fmpz_mod_mpoly_vec_struct;
0963 
0964 typedef fmpz_mod_mpoly_vec_struct fmpz_mod_mpoly_vec_t[1];
0965 
0966 #define fmpz_mod_mpoly_vec_entry(vec, i) ((vec)->p + (i))
0967 
0968 void fmpz_mod_mpoly_vec_init(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
0969 void fmpz_mod_mpoly_vec_print(const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
0970 void fmpz_mod_mpoly_vec_swap(fmpz_mod_mpoly_vec_t x, fmpz_mod_mpoly_vec_t y, const fmpz_mod_mpoly_ctx_t FLINT_UNUSED(ctx));
0971 void fmpz_mod_mpoly_vec_fit_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
0972 void fmpz_mod_mpoly_vec_clear(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_ctx_t ctx);
0973 void fmpz_mod_mpoly_vec_set(fmpz_mod_mpoly_vec_t dest, const fmpz_mod_mpoly_vec_t src, const fmpz_mod_mpoly_ctx_t ctx);
0974 void fmpz_mod_mpoly_vec_append(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
0975 slong fmpz_mod_mpoly_vec_insert_unique(fmpz_mod_mpoly_vec_t vec, const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_ctx_t ctx);
0976 void fmpz_mod_mpoly_vec_set_length(fmpz_mod_mpoly_vec_t vec, slong len, const fmpz_mod_mpoly_ctx_t ctx);
0977 void fmpz_mod_mpoly_vec_randtest_not_zero(fmpz_mod_mpoly_vec_t vec, flint_rand_t state, slong len, slong poly_len, ulong exp_bound, fmpz_mod_mpoly_ctx_t ctx);
0978 
0979 
0980 /* Ideals and Groenber bases */
0981 
0982 void fmpz_mod_mpoly_spoly(fmpz_mod_mpoly_t res, 
0983     const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_t g, const fmpz_mod_mpoly_ctx_t ctx);
0984 
0985 void fmpz_mod_mpoly_reduction_monic_part(fmpz_mod_mpoly_t res, 
0986     const fmpz_mod_mpoly_t f, const fmpz_mod_mpoly_vec_t Iv, const fmpz_mod_mpoly_ctx_t ctx);
0987 
0988 int fmpz_mod_mpoly_vec_is_groebner(const fmpz_mod_mpoly_vec_t G, 
0989     const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
0990 
0991 void fmpz_mod_mpoly_vec_set_monic_unique(fmpz_mod_mpoly_vec_t G, 
0992     const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
0993 
0994 int fmpz_mod_mpoly_buchberger_naive_with_limits(fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_vec_t F,
0995     slong ideal_len_limit, slong poly_len_limit, const fmpz_mod_mpoly_ctx_t ctx);
0996 
0997 void fmpz_mod_mpoly_buchberger_naive(fmpz_mod_mpoly_vec_t G, 
0998     const fmpz_mod_mpoly_vec_t F, const fmpz_mod_mpoly_ctx_t ctx);
0999 
1000 int fmpz_mod_mpoly_vec_is_autoreduced(const fmpz_mod_mpoly_vec_t G, 
1001     const fmpz_mod_mpoly_ctx_t ctx);
1002 
1003 void fmpz_mod_mpoly_vec_autoreduction_groebner(fmpz_mod_mpoly_vec_t H, 
1004     const fmpz_mod_mpoly_vec_t G, const fmpz_mod_mpoly_ctx_t ctx);
1005 
1006 /* Convert to/from fmpz_mpoly */
1007 
1008 void fmpz_mod_mpoly_set_fmpz_mpoly(fmpz_mod_mpoly_t res, 
1009     const fmpz_mpoly_t f, fmpz_mod_mpoly_ctx_t ctxm, fmpz_mpoly_ctx_t ctx);
1010 
1011 void fmpz_mod_mpoly_get_fmpz_mpoly(fmpz_mpoly_t res, 
1012     const fmpz_mod_mpoly_t f, fmpz_mpoly_ctx_t ctx);
1013 
1014 
1015 /******************************************************************************
1016 
1017    Internal consistency checks
1018 
1019 ******************************************************************************/
1020 
1021 void fmpz_mod_mpoly_remainder_strongtest(const fmpz_mod_mpoly_t r, const fmpz_mod_mpoly_t g, const fmpz_mod_mpoly_ctx_t ctx);
1022 
1023 #ifdef __cplusplus
1024 }
1025 #endif
1026 
1027 #endif