File indexing completed on 2026-11-07 10:15:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef FEXPR_H
0013 #define FEXPR_H
0014
0015 #ifdef FEXPR_INLINES_C
0016 #define FEXPR_INLINE
0017 #else
0018 #define FEXPR_INLINE static inline
0019 #endif
0020
0021 #include "mpoly_types.h"
0022 #include "arf_types.h"
0023 #include "gr_types.h"
0024
0025 #ifdef __cplusplus
0026 extern "C" {
0027 #endif
0028
0029
0030
0031
0032 #ifndef calcium_stream_struct
0033 # define calcium_stream_struct gr_stream_struct
0034 # define calcium_stream_t gr_stream_t
0035 #endif
0036
0037 #define FEXPR_TYPE_SMALL_INT UWORD(0)
0038 #define FEXPR_TYPE_SMALL_SYMBOL UWORD(1)
0039 #define FEXPR_TYPE_SMALL_STRING UWORD(2)
0040 #define FEXPR_TYPE_BIG_INT_POS UWORD(3)
0041 #define FEXPR_TYPE_BIG_INT_NEG UWORD(4)
0042 #define FEXPR_TYPE_BIG_SYMBOL UWORD(5)
0043 #define FEXPR_TYPE_BIG_STRING UWORD(6)
0044 #define FEXPR_TYPE_CALL0 UWORD(7)
0045 #define FEXPR_TYPE_CALL1 UWORD(8)
0046 #define FEXPR_TYPE_CALL2 UWORD(9)
0047 #define FEXPR_TYPE_CALL3 UWORD(10)
0048 #define FEXPR_TYPE_CALL4 UWORD(11)
0049 #define FEXPR_TYPE_CALLN UWORD(12)
0050
0051 #define FEXPR_TYPE_BITS 4
0052 #define FEXPR_TYPE_MASK ((UWORD(1) << FEXPR_TYPE_BITS) - 1)
0053
0054 #define FEXPR_COEFF_MAX ((WORD(1) << (FLINT_BITS - FEXPR_TYPE_BITS - 1)) - 1)
0055 #define FEXPR_COEFF_MIN (-FEXPR_COEFF_MAX)
0056
0057 #define FEXPR_TYPE(head) ((head) & FEXPR_TYPE_MASK)
0058 #define FEXPR_SIZE(head) ((slong) ((FEXPR_TYPE(head) <= FEXPR_TYPE_SMALL_STRING) ? 1 : (head) >> FEXPR_TYPE_BITS))
0059
0060 #define FEXPR_HEADER_SIZE WORD(1)
0061 #define FEXPR_SMALL_SYMBOL_LEN ((FLINT_BITS / 8) - 1)
0062
0063 #define FEXPR_BUILTIN_ID(head) ((head) >> 16)
0064
0065 typedef struct
0066 {
0067 ulong * data;
0068 slong alloc;
0069 }
0070 fexpr_struct;
0071
0072 typedef fexpr_struct fexpr_t[1];
0073 typedef fexpr_struct * fexpr_ptr;
0074 typedef const fexpr_struct * fexpr_srcptr;
0075
0076 typedef struct
0077 {
0078 fexpr_struct * entries;
0079 slong alloc;
0080 slong length;
0081 }
0082 fexpr_vec_struct;
0083
0084 typedef fexpr_vec_struct fexpr_vec_t[1];
0085
0086 #define fexpr_vec_entry(vec, i) ((vec)->entries + (i))
0087
0088 FEXPR_INLINE void
0089 fexpr_init(fexpr_t expr)
0090 {
0091 expr->data = (ulong *) flint_malloc(sizeof(ulong));
0092 expr->data[0] = 0;
0093 expr->alloc = 1;
0094 }
0095
0096 FEXPR_INLINE void
0097 fexpr_clear(fexpr_t expr)
0098 {
0099 flint_free(expr->data);
0100 }
0101
0102 FEXPR_INLINE fexpr_ptr
0103 _fexpr_vec_init(slong len)
0104 {
0105 slong i;
0106 fexpr_ptr vec = (fexpr_ptr) flint_malloc(sizeof(fexpr_struct) * len);
0107 for (i = 0; i < len; i++)
0108 fexpr_init(vec + i);
0109 return vec;
0110 }
0111
0112 FEXPR_INLINE void
0113 _fexpr_vec_clear(fexpr_ptr vec, slong len)
0114 {
0115 slong i;
0116 for (i = 0; i < len; i++)
0117 fexpr_clear(vec + i);
0118 flint_free(vec);
0119 }
0120
0121 FEXPR_INLINE void
0122 fexpr_fit_size(fexpr_t expr, slong size)
0123 {
0124 if (expr->alloc < size)
0125 {
0126 size = FLINT_MAX(size, 2 * expr->alloc);
0127 expr->data = (ulong *) flint_realloc(expr->data, size * sizeof(ulong));
0128 expr->alloc = size;
0129 }
0130 }
0131
0132 FEXPR_INLINE slong
0133 _fexpr_size(const ulong * expr)
0134 {
0135 ulong head = expr[0];
0136 return FEXPR_SIZE(head);
0137 }
0138
0139 FEXPR_INLINE slong
0140 fexpr_size(const fexpr_t expr)
0141 {
0142 return _fexpr_size(expr->data);
0143 }
0144
0145 FEXPR_INLINE void
0146 fexpr_set(fexpr_t res, const fexpr_t expr)
0147 {
0148 if (res != expr)
0149 {
0150 slong i;
0151 slong size = fexpr_size(expr);
0152 fexpr_fit_size(res, size);
0153 for (i = 0; i < size; i++)
0154 res->data[i] = expr->data[i];
0155 }
0156 }
0157
0158 FEXPR_INLINE void
0159 fexpr_swap(fexpr_t a, fexpr_t b)
0160 {
0161 FLINT_SWAP(fexpr_struct, *a, *b);
0162 }
0163
0164 FEXPR_INLINE int
0165 fexpr_equal(const fexpr_t a, const fexpr_t b)
0166 {
0167 ulong ha, hb;
0168 slong i, sa, sb;
0169
0170 ha = a->data[0];
0171 hb = b->data[0];
0172
0173 if (ha != hb)
0174 return 0;
0175
0176 sa = FEXPR_SIZE(ha);
0177 sb = FEXPR_SIZE(hb);
0178
0179 if (sa != sb)
0180 return 0;
0181
0182 for (i = 1; i < sa; i++)
0183 if (a->data[i] != b->data[i])
0184 return 0;
0185
0186 return 1;
0187 }
0188
0189
0190 int fexpr_equal_si(const fexpr_t expr, slong c);
0191 int fexpr_equal_ui(const fexpr_t expr, ulong c);
0192 ulong fexpr_hash(const fexpr_t expr);
0193
0194 int fexpr_cmp_fast(const fexpr_t a, const fexpr_t b);
0195
0196 void
0197 _fexpr_vec_sort_fast(fexpr_ptr vec, slong len);
0198
0199 FEXPR_INLINE int
0200 _fexpr_is_integer(const ulong * expr)
0201 {
0202 ulong type = FEXPR_TYPE(expr[0]);
0203 return (type == FEXPR_TYPE_SMALL_INT) || (type == FEXPR_TYPE_BIG_INT_POS) || (type == FEXPR_TYPE_BIG_INT_NEG);
0204 }
0205
0206 FEXPR_INLINE int
0207 fexpr_is_integer(const fexpr_t expr)
0208 {
0209 return _fexpr_is_integer(expr->data);
0210 }
0211
0212
0213 int fexpr_is_neg_integer(const fexpr_t expr);
0214
0215 FEXPR_INLINE int
0216 _fexpr_is_symbol(const ulong * expr)
0217 {
0218 ulong type = FEXPR_TYPE(expr[0]);
0219 return (type == FEXPR_TYPE_SMALL_SYMBOL) || (type == FEXPR_TYPE_BIG_SYMBOL);
0220 }
0221
0222 FEXPR_INLINE int
0223 fexpr_is_symbol(const fexpr_t expr)
0224 {
0225 return _fexpr_is_symbol(expr->data);
0226 }
0227
0228 FEXPR_INLINE int
0229 _fexpr_is_string(const ulong * expr)
0230 {
0231 ulong type = FEXPR_TYPE(expr[0]);
0232 return (type == FEXPR_TYPE_SMALL_STRING) || (type == FEXPR_TYPE_BIG_STRING);
0233 }
0234
0235 FEXPR_INLINE int
0236 fexpr_is_string(const fexpr_t expr)
0237 {
0238 return _fexpr_is_string(expr->data);
0239 }
0240
0241 FEXPR_INLINE int
0242 _fexpr_is_atom(const ulong * expr)
0243 {
0244 return FEXPR_TYPE(expr[0]) <= FEXPR_TYPE_BIG_STRING;
0245 }
0246
0247 FEXPR_INLINE int
0248 fexpr_is_atom(const fexpr_t expr)
0249 {
0250 return _fexpr_is_atom(expr->data);
0251 }
0252
0253 FEXPR_INLINE void
0254 fexpr_zero(fexpr_t res)
0255 {
0256 res->data[0] = 0;
0257 }
0258
0259 FEXPR_INLINE int
0260 fexpr_is_zero(const fexpr_t expr)
0261 {
0262 return expr->data[0] == 0;
0263 }
0264
0265 void fexpr_set_si(fexpr_t res, slong c);
0266 void fexpr_set_ui(fexpr_t res, ulong c);
0267 void fexpr_set_fmpz(fexpr_t res, const fmpz_t c);
0268 int fexpr_get_fmpz(fmpz_t c, const fexpr_t x);
0269 void fexpr_set_fmpq(fexpr_t res, const fmpq_t x);
0270
0271 FEXPR_INLINE void
0272 fexpr_set_symbol_builtin(fexpr_t res, slong id)
0273 {
0274 res->data[0] = FEXPR_TYPE_SMALL_SYMBOL | (id << 16);
0275 }
0276
0277 void fexpr_set_symbol_str(fexpr_t res, const char * s);
0278 void fexpr_set_string(fexpr_t res, const char * s);
0279
0280 char * fexpr_get_symbol_str(const fexpr_t expr);
0281 char * fexpr_get_string(const fexpr_t expr);
0282 char * fexpr_get_decimal_str(const fexpr_t expr, slong digits, ulong flags);
0283
0284 slong fexpr_depth(const fexpr_t expr);
0285 slong fexpr_num_leaves(const fexpr_t expr);
0286
0287 FEXPR_INLINE slong
0288 fexpr_size_bytes(const fexpr_t expr)
0289 {
0290 return fexpr_size(expr) * sizeof(ulong);
0291 }
0292
0293 FEXPR_INLINE slong
0294 fexpr_allocated_bytes(const fexpr_t expr)
0295 {
0296 return expr->alloc * sizeof(ulong);
0297 }
0298
0299
0300 FEXPR_INLINE int
0301 fexpr_is_any_builtin_symbol(const fexpr_t expr)
0302 {
0303 ulong head;
0304 head = expr->data[0];
0305 return (FEXPR_TYPE(head) == FEXPR_TYPE_SMALL_SYMBOL) && (((head >> 8) & 0xff) == 0);
0306 }
0307
0308
0309 FEXPR_INLINE int
0310 fexpr_is_builtin_symbol(const fexpr_t expr, slong i)
0311 {
0312 ulong head;
0313 head = expr->data[0];
0314 return (FEXPR_TYPE(head) == FEXPR_TYPE_SMALL_SYMBOL) && (((head >> 8) & 0xff) == 0) && (FEXPR_BUILTIN_ID(head) == i);
0315 }
0316
0317
0318 int fexpr_is_builtin_call(const fexpr_t expr, slong i);
0319 int fexpr_is_any_builtin_call(const fexpr_t expr);
0320
0321 FEXPR_INLINE slong
0322 fexpr_nargs(const fexpr_t expr)
0323 {
0324 ulong type = FEXPR_TYPE(expr->data[0]);
0325
0326 if (FEXPR_TYPE_CALL0 <= type && type <= FEXPR_TYPE_CALL4)
0327 {
0328 return type - FEXPR_TYPE_CALL0;
0329 }
0330 else if (type == FEXPR_TYPE_CALLN)
0331 {
0332 return expr->data[1];
0333 }
0334 else
0335 {
0336 return -1;
0337 }
0338 }
0339
0340 void fexpr_func(fexpr_t res, const fexpr_t expr);
0341 void fexpr_view_func(fexpr_t res, const fexpr_t expr);
0342
0343 void fexpr_arg(fexpr_t res, const fexpr_t expr, slong i);
0344 void fexpr_view_arg(fexpr_t res, const fexpr_t expr, slong i);
0345
0346 FEXPR_INLINE void
0347 fexpr_view_next(fexpr_t view)
0348 {
0349 view->data += fexpr_size(view);
0350 }
0351
0352
0353 void fexpr_call0(fexpr_t res, const fexpr_t f);
0354 void fexpr_call1(fexpr_t res, const fexpr_t f, const fexpr_t x1);
0355 void fexpr_call2(fexpr_t res, const fexpr_t f, const fexpr_t x1, const fexpr_t x2);
0356 void fexpr_call3(fexpr_t res, const fexpr_t f, const fexpr_t x1, const fexpr_t x2, const fexpr_t x3);
0357 void fexpr_call4(fexpr_t res, const fexpr_t f, const fexpr_t x1, const fexpr_t x2, const fexpr_t x3, const fexpr_t x4);
0358
0359 void fexpr_call_vec(fexpr_t res, const fexpr_t f, fexpr_srcptr args, slong len);
0360
0361 void fexpr_call_builtin1(fexpr_t res, slong f, const fexpr_t x);
0362 void fexpr_call_builtin2(fexpr_t res, slong f, const fexpr_t x, const fexpr_t y);
0363
0364
0365
0366 int fexpr_contains(const fexpr_t expr, const fexpr_t x);
0367 int fexpr_replace(fexpr_t res, const fexpr_t expr, const fexpr_t x, const fexpr_t y);
0368 int fexpr_replace2(fexpr_t res, const fexpr_t expr, const fexpr_t x1, const fexpr_t y1, const fexpr_t x2, const fexpr_t y2);
0369 int fexpr_replace_vec(fexpr_t res, const fexpr_t expr, const fexpr_vec_t xs, const fexpr_vec_t ys);
0370
0371
0372
0373
0374 void fexpr_write(calcium_stream_t stream, const fexpr_t expr);
0375 void fexpr_print(const fexpr_t expr);
0376 char * fexpr_get_str(const fexpr_t expr);
0377
0378
0379
0380 #define FEXPR_LATEX_SMALL 1
0381 #define FEXPR_LATEX_LOGIC 2
0382
0383 void fexpr_write_latex(calcium_stream_t out, const fexpr_t expr, ulong flags);
0384 void fexpr_print_latex(const fexpr_t expr, ulong flags);
0385 char * fexpr_get_str_latex(const fexpr_t expr, ulong flags);
0386
0387 void fexpr_write_latex_call(calcium_stream_t out, const fexpr_t expr, ulong flags);
0388 void fexpr_write_latex_subscript(calcium_stream_t out, const fexpr_t expr, ulong flags);
0389 void fexpr_write_latex_subscript_call(calcium_stream_t out, const fexpr_t expr, ulong flags);
0390 void fexpr_write_latex_infix(calcium_stream_t out, const fexpr_t expr, ulong flags);
0391 void fexpr_write_latex_mul(calcium_stream_t out, const fexpr_t expr, ulong flags);
0392 void fexpr_write_latex_div(calcium_stream_t out, const fexpr_t expr, ulong flags);
0393 void fexpr_write_latex_neg_pos(calcium_stream_t out, const fexpr_t expr, ulong flags);
0394 void fexpr_write_latex_add(calcium_stream_t out, const fexpr_t expr, ulong flags);
0395 void fexpr_write_latex_sub(calcium_stream_t out, const fexpr_t expr, ulong flags);
0396 void fexpr_write_latex_pow(calcium_stream_t out, const fexpr_t expr, ulong flags);
0397 void fexpr_write_latex_exp(calcium_stream_t out, const fexpr_t expr, ulong flags);
0398 void fexpr_write_latex_factorial(calcium_stream_t out, const fexpr_t expr, ulong flags);
0399 void fexpr_write_latex_integral(calcium_stream_t out, const fexpr_t expr, ulong flags);
0400 void fexpr_write_latex_sum_product(calcium_stream_t out, const fexpr_t expr, ulong flags);
0401 void fexpr_write_latex_divsum(calcium_stream_t out, const fexpr_t expr, ulong flags);
0402 void fexpr_write_latex_limit(calcium_stream_t out, const fexpr_t expr, ulong flags);
0403 void fexpr_write_latex_derivative(calcium_stream_t out, const fexpr_t expr, ulong flags);
0404 void fexpr_write_latex_logic(calcium_stream_t out, const fexpr_t expr, ulong flags);
0405 void fexpr_write_latex_collection(calcium_stream_t out, const fexpr_t expr, ulong flags);
0406 void fexpr_write_latex_matrix(calcium_stream_t out, const fexpr_t expr, ulong flags);
0407 void fexpr_write_latex_simple(calcium_stream_t out, const fexpr_t expr, ulong flags);
0408 void fexpr_write_latex_simple2(calcium_stream_t out, const fexpr_t expr, ulong flags);
0409 void fexpr_write_latex_simple2_small(calcium_stream_t out, const fexpr_t expr, ulong flags);
0410 void fexpr_write_latex_alg_structure(calcium_stream_t out, const fexpr_t expr, ulong flags);
0411 void fexpr_write_latex_setop(calcium_stream_t out, const fexpr_t expr, ulong flags);
0412 void fexpr_write_latex_cases(calcium_stream_t out, const fexpr_t expr, ulong flags);
0413 void fexpr_write_latex_where(calcium_stream_t out, const fexpr_t expr, ulong flags);
0414 void fexpr_write_latex_show_form(calcium_stream_t out, const fexpr_t expr, ulong flags);
0415 void fexpr_write_latex_range(calcium_stream_t out, const fexpr_t expr, ulong flags);
0416 void fexpr_write_latex_decimal(calcium_stream_t out, const fexpr_t expr, ulong flags);
0417 void fexpr_write_latex_call1_optional_derivative(calcium_stream_t out, const fexpr_t expr, ulong flags);
0418 void fexpr_write_latex_call2_optional_derivative(calcium_stream_t out, const fexpr_t expr, ulong flags);
0419 void fexpr_write_latex_sub1_call1_optional_derivative(calcium_stream_t out, const fexpr_t expr, ulong flags);
0420 void fexpr_write_latex_sub1_call2_optional_derivative(calcium_stream_t out, const fexpr_t expr, ulong flags);
0421 void fexpr_write_latex_misc_special(calcium_stream_t out, const fexpr_t expr, ulong flags);
0422 void fexpr_write_latex_residue(calcium_stream_t out, const fexpr_t expr, ulong flags);
0423
0424 void fexpr_set_arf(fexpr_t res, const arf_t x);
0425 void fexpr_set_d(fexpr_t res, double x);
0426 void fexpr_set_re_im_d(fexpr_t res, double x, double y);
0427
0428 void fexpr_neg(fexpr_t res, const fexpr_t a);
0429 void fexpr_add(fexpr_t res, const fexpr_t a, const fexpr_t b);
0430 void fexpr_sub(fexpr_t res, const fexpr_t a, const fexpr_t b);
0431 void fexpr_mul(fexpr_t res, const fexpr_t a, const fexpr_t b);
0432 void fexpr_div(fexpr_t res, const fexpr_t a, const fexpr_t b);
0433 void fexpr_pow(fexpr_t res, const fexpr_t a, const fexpr_t b);
0434
0435 int fexpr_is_arithmetic_operation(const fexpr_t expr);
0436
0437 void fexpr_arithmetic_nodes(fexpr_vec_t nodes, const fexpr_t expr);
0438
0439 int fexpr_get_fmpz_mpoly_q(fmpz_mpoly_q_t res, const fexpr_t expr, const fexpr_vec_t vars, const fmpz_mpoly_ctx_t ctx);
0440
0441 void fexpr_set_fmpz_mpoly(fexpr_t res, const fmpz_mpoly_t poly, const fexpr_vec_t vars, const fmpz_mpoly_ctx_t ctx);
0442 void fexpr_set_fmpz_mpoly_q(fexpr_t res, const fmpz_mpoly_q_t frac, const fexpr_vec_t vars, const fmpz_mpoly_ctx_t ctx);
0443
0444 int fexpr_expanded_normal_form(fexpr_t res, const fexpr_t expr, ulong flags);
0445
0446
0447
0448 FEXPR_INLINE void
0449 fexpr_vec_init(fexpr_vec_t vec, slong len)
0450 {
0451 if (len == 0)
0452 {
0453 vec->entries = NULL;
0454 vec->length = 0;
0455 vec->alloc = 0;
0456 }
0457 else
0458 {
0459 slong i;
0460 vec->entries = (fexpr_ptr) flint_malloc(sizeof(fexpr_struct) * len);
0461 for (i = 0; i < len; i++)
0462 fexpr_init(vec->entries + i);
0463 vec->length = vec->alloc = len;
0464 }
0465 }
0466
0467 FEXPR_INLINE void
0468 fexpr_vec_print(const fexpr_vec_t F)
0469 {
0470 slong i;
0471
0472 flint_printf("[");
0473 for (i = 0; i < F->length; i++)
0474 {
0475 fexpr_print(F->entries + i);
0476 if (i < F->length - 1)
0477 flint_printf(", ");
0478 }
0479 flint_printf("]");
0480 }
0481
0482 FEXPR_INLINE void
0483 fexpr_vec_swap(fexpr_vec_t x, fexpr_vec_t y)
0484 {
0485 fexpr_vec_t tmp;
0486 *tmp = *x;
0487 *x = *y;
0488 *y = *tmp;
0489 }
0490
0491 FEXPR_INLINE void
0492 fexpr_vec_fit_length(fexpr_vec_t vec, slong len)
0493 {
0494 if (len > vec->alloc)
0495 {
0496 slong i;
0497
0498 if (len < 2 * vec->alloc)
0499 len = 2 * vec->alloc;
0500
0501 vec->entries = (fexpr_struct *) flint_realloc(vec->entries, len * sizeof(fexpr_struct));
0502
0503 for (i = vec->alloc; i < len; i++)
0504 fexpr_init(vec->entries + i);
0505
0506 vec->alloc = len;
0507 }
0508 }
0509
0510 FEXPR_INLINE void
0511 fexpr_vec_clear(fexpr_vec_t vec)
0512 {
0513 slong i;
0514
0515 for (i = 0; i < vec->alloc; i++)
0516 fexpr_clear(vec->entries + i);
0517
0518 flint_free(vec->entries);
0519 }
0520
0521 FEXPR_INLINE void
0522 fexpr_vec_set(fexpr_vec_t dest, const fexpr_vec_t src)
0523 {
0524 if (dest != src)
0525 {
0526 slong i;
0527
0528 fexpr_vec_fit_length(dest, src->length);
0529
0530 for (i = 0; i < src->length; i++)
0531 fexpr_set(dest->entries + i, src->entries + i);
0532
0533 dest->length = src->length;
0534 }
0535 }
0536
0537 FEXPR_INLINE void
0538 fexpr_vec_append(fexpr_vec_t vec, const fexpr_t f)
0539 {
0540 fexpr_vec_fit_length(vec, vec->length + 1);
0541 fexpr_set(vec->entries + vec->length, f);
0542 vec->length++;
0543 }
0544
0545 FEXPR_INLINE slong
0546 fexpr_vec_insert_unique(fexpr_vec_t vec, const fexpr_t f)
0547 {
0548 slong i;
0549
0550 for (i = 0; i < vec->length; i++)
0551 {
0552 if (fexpr_equal(vec->entries + i, f))
0553 return i;
0554 }
0555
0556 fexpr_vec_append(vec, f);
0557 return vec->length - 1;
0558 }
0559
0560 FEXPR_INLINE void
0561 fexpr_vec_set_length(fexpr_vec_t vec, slong len)
0562 {
0563 slong i;
0564
0565 if (len > vec->length)
0566 {
0567 fexpr_vec_fit_length(vec, len);
0568 for (i = vec->length; i < len; i++)
0569 fexpr_zero(vec->entries + i);
0570 }
0571 else if (len < vec->length)
0572 {
0573 for (i = len; i < vec->length; i++)
0574 fexpr_zero(vec->entries + i);
0575 }
0576
0577 vec->length = len;
0578 }
0579
0580
0581 #ifdef __cplusplus
0582 }
0583 #endif
0584
0585 #endif