static void show_monomial(FILE *f, rational_t *a, int32_t x, bool first) { assert(0 <= x && x < NVARS); assert(q_is_nonzero(a)); show_constant(f, a, first); fprintf(f, " %s", var[x].name); }
static void show_constraint(FILE *f, int_constraint_t *cnstr) { fprintf(f, " IsInt("); show_sum(f, cnstr->sum, cnstr->sum_nterms, true); show_sum(f, cnstr->fixed_sum, cnstr->fixed_nterms, false); if (q_is_nonzero(&cnstr->constant)) { show_constant(f, &cnstr->constant, false); } fprintf(f, ")\n"); }
/* * Print row in a simplified form: replace fixed variables by their value */ void print_simplex_reduced_row(FILE *f, simplex_solver_t *solver, row_t *row) { arith_vartable_t *vtbl; arith_bstack_t *bstack; rational_t q; uint32_t i, n; thvar_t x; bool first; int32_t l, u; vtbl = &solver->vtbl; bstack = &solver->bstack; // compute the constant q_init(&q); n = row->size; for (i=0; i<n; i++) { x = row->data[i].c_idx; if (x >= 0) { l = arith_var_lower_index(&solver->vtbl, x); u = arith_var_upper_index(&solver->vtbl, x); if (l >= 0 && u >= 0 && xq_eq(bstack->bound + l, bstack->bound + u)) { // x is a a fixed variable assert(xq_eq(bstack->bound + l, arith_var_value(vtbl, x))); assert(xq_is_rational(arith_var_value(vtbl, x))); q_addmul(&q, &row->data[i].coeff, &arith_var_value(vtbl, x)->main); } } } // print the non-constant monomials and q first = true; if (q_is_nonzero(&q)) { print_avar_monomial(f, vtbl, const_idx, &q, first); first = false; } for (i=0; i<n; i++) { x = row->data[i].c_idx; if (x >= 0) { l = arith_var_lower_index(&solver->vtbl, x); u = arith_var_upper_index(&solver->vtbl, x); if (l < 0 || u < 0 || xq_neq(bstack->bound + l, bstack->bound + u)) { // x is not a fixed variable print_avar_monomial(f, vtbl, x, &row->data[i].coeff, first); first = false; } } } if (first) { // nothing printed so the row is empty fputc('0', f); } fputs(" == 0", f); q_clear(&q); }
/* * Normalize an array of monomials a or size n: * 1) merge monomials with identical variables: * (c * v + d * v) --> (c + d) * v * 2) remove monomials with zero coefficients * 3) add end marker. * - a must be sorted. * - the function returns the size of the result = number of monomials * in a after normalization. */ uint32_t normalize_monarray(monomial_t *a, uint32_t n) { uint32_t i, j, v; rational_t c; if (n == 0) return n; j = 0; q_init(&c); v = a[0].var; // c := a[0].coeff, clear a[0].coeff to prevent memory leak q_copy_and_clear(&c, &a[0].coeff); for (i=1; i<n; i++) { if (a[i].var == v) { q_add(&c, &a[i].coeff); q_clear(&a[i].coeff); } else { if (q_is_nonzero(&c)) { a[j].var = v; // copy c into a[j].coeff, then clear c q_copy_and_clear(&a[j].coeff, &c); j ++; } v = a[i].var; // copy a[i].coeff in c then clear a[i].coeff q_copy_and_clear(&c, &a[i].coeff); } } if (q_is_nonzero(&c)) { a[j].var = v; q_copy_and_clear(&a[j].coeff, &c); j ++; } // set end-marker a[j].var = max_idx; return j; }
/* * Degree of variable x in b * - return largest d such that x^d occurs in b * - return 0 if x does not occur in b */ uint32_t arith_buffer_var_degree(arith_buffer_t *b, int32_t x) { mlist_t *p; uint32_t d, e; d = 0; p = b->list; while (p->next != NULL) { assert(p->prod != end_pp); if (q_is_nonzero(&p->coeff)) { e = pprod_var_degree(p->prod, x); if (e > d) { d = e; } } p = p->next; } return d; }