/* * Difference logic triple (x - y + d) * - x and y are vertices */ void print_idl_triple(FILE *f, dl_triple_t *triple) { bool space; space = false; if (triple->target >= 0) { print_idl_vertex(f, triple->target); // x space = true; } if (triple->source >= 0) { if (space) fputc(' ', f); fputs("- ", f); print_idl_vertex(f, triple->source); // y space = true; } if (! space) { q_print(f, &triple->constant); } else if (q_is_pos(&triple->constant)) { fprintf(f, " + "); q_print(f, &triple->constant); } else if (q_is_neg(&triple->constant)) { fprintf(f, " - "); q_print_abs(f, &triple->constant); } }
/* * Print a triple */ static void print_dl_triple(dl_triple_t *t) { bool space; space = false; if (t->target >= 0) { printf("x!%"PRId32, t->target); space = true; } if (t->source >= 0) { if (space) printf(" "); printf("- x!%"PRId32, t->source); } if (! space) { q_print(stdout, &t->constant); } else if (q_is_pos(&t->constant)) { printf(" + "); q_print(stdout, &t->constant); } else if (q_is_neg(&t->constant)) { printf(" - "); q_print_abs(stdout, &t->constant); } }
/* * Check whether b is constant and positive, negative, etc. * - b must be normalized */ bool arith_buffer_is_pos(arith_buffer_t *b) { return b->nterms == 1 && b->list->prod == empty_pp && q_is_pos(&b->list->coeff); }
bool polynomial_is_nonneg(polynomial_t *p) { return p->nterms == 0 || (p->nterms == 1 && p->mono[0].var == const_idx && q_is_pos(&p->mono[0].coeff)); }
/* * Phase and period of p * - p is c + (a_1/b_1) x_1 + ... + (a_n/b_n) x_n where * a_i/b_i is an irreducible fraction * - let D = gcd(a_1,..., a_n) and L = lcm(b_1,...,b_n) * then period = D/L and phase = c - floor(c/period) * period */ void monarray_period_and_phase(monomial_t *p, rational_t *period, rational_t *phase) { rational_t aux; monomial_t *c; int32_t v; /* * c := the constant monomial of p or NULL if p's constant is zero */ c = NULL; v = p->var; if (v == const_idx) { c = p; p ++; v = p->var; } if (v < max_idx) { /* * p is not a constant: compute D and L * we use period for D and phase for L */ q_get_num(period, &p->coeff); // D := |a_1| if (q_is_neg(period)) { q_neg(period); } q_get_den(phase, &p->coeff); // L := b_1 q_init(&aux); for (;;) { p ++; v = p->var; if (v >= max_idx) break; q_get_num(&aux, &p->coeff); q_gcd(period, &aux); // D := gcd(D, a_i) q_get_den(&aux, &p->coeff); q_lcm(phase, &aux); // L := lcm(L, b_i) } assert(q_is_pos(period) && q_is_pos(phase)); q_div(period, phase); // period := D/L /* * Phase: constant modulo D/L */ if (c == NULL) { q_clear(phase); // no constant: phase = 0 } else { q_set(&aux, &c->coeff); q_div(&aux, period); q_floor(&aux); // aux = floor(c/period) q_set(phase, &c->coeff); q_submul(phase, &aux, period); // phase = c - aux * period assert(q_is_nonneg(phase) && q_lt(phase, period)); } q_clear(&aux); } else { /* * p is constant: period := 0, phase = constant coeff */ q_clear(period); if (c == NULL) { q_clear(phase); } else { q_set(phase, &c->coeff); } } }