//Refer to apps_sfdl_gen/bisect_sfdl_cons.h for constants to use in this exogenous //check. bool bisect_sfdlProverExo::exogenous_check(const mpz_t* input, const mpq_t* input_q, int input_size, const mpz_t* output, const mpq_t* output_q, int output_size, mpz_t prime) { bool success = true; #ifdef ENABLE_EXOGENOUS_CHECKING int m = bisect_sfdl_cons::m; mpq_t* buffer; alloc_init_vec(&buffer, m + m); baseline(input_q, input_size, buffer, output_size); mpq_t* a = buffer; mpq_t* b = buffer + m; for(int i = 0; i < m; i++) { success &= mpq_equal(a[i], output_q[i]); success &= mpq_equal(b[i], output_q[i+m]); } clear_vec(m+m, buffer); #else gmp_printf("Exogeneous checking disabled\n"); #endif return success; };
void check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub) { mpq_t got; int neg_x, neg_y, swap; mpq_init (got); MPQ_CHECK_FORMAT (want_add); MPQ_CHECK_FORMAT (want_sub); MPQ_CHECK_FORMAT (x); MPQ_CHECK_FORMAT (y); for (swap = 0; swap <= 1; swap++) { for (neg_x = 0; neg_x <= 1; neg_x++) { for (neg_y = 0; neg_y <= 1; neg_y++) { mpq_add (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_add)) { printf ("mpq_add wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_add); abort (); } mpq_sub (got, x, y); MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want_sub)) { printf ("mpq_sub wrong\n"); mpq_trace (" x ", x); mpq_trace (" y ", y); mpq_trace (" got ", got); mpq_trace (" want", want_sub); abort (); } mpq_neg (y, y); mpq_swap (want_add, want_sub); } mpq_neg (x, x); mpq_swap (want_add, want_sub); mpq_neg (want_add, want_add); mpq_neg (want_sub, want_sub); } mpq_swap (x, y); mpq_neg (want_sub, want_sub); } mpq_clear (got); }
/*lint -e{818} supress "Pointer parameter 'var' could be declared as pointing to const" */ static void remove_fixed_var( Lps* lp, Var* var, int verbose_level) { Nzo* nzo; mpq_t x; mpq_t temp; Bool is_zero; assert(lp != NULL); assert(var != NULL); assert(var->type == VAR_FIXED && mpq_equal(var->lower, var->upper)); if (verbose_level > 0) printf("Removing variable %s fixed to %g\n", var->name, mpq_get_d(var->lower)); mpq_init(x); mpq_init(temp); is_zero = mpq_equal(var->lower, x /* zero */); while(var->first != NULL) { nzo = var->first; /* Do we have to ajust the lhs/rhs ? */ if (!is_zero) { mpq_mul(x, var->lower, nzo->value); /* do we have a valid rhs ? */ if (HAS_RHS(nzo->con)) { mpq_sub(temp, nzo->con->rhs, x); lps_setrhs(nzo->con, temp); } /* do we have a valid lhs ? */ if (HAS_LHS(nzo->con)) { mpq_sub(temp, nzo->con->lhs, x); lps_setlhs(nzo->con, temp); } } lps_delnzo(lp, nzo); } mpq_clear(temp); mpq_clear(x); }
void check_one (mpq_srcptr want, int base, const char *str) { mpq_t got; MPQ_CHECK_FORMAT (want); mp_trace_base = base; mpq_init (got); if (mpq_set_str (got, str, base) != 0) { printf ("mpq_set_str unexpectedly failed\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); abort (); } MPQ_CHECK_FORMAT (got); if (! mpq_equal (got, want)) { printf ("mpq_set_str wrong\n"); printf (" base %d\n", base); printf (" str \"%s\"\n", str); mpq_trace ("got ", got); mpq_trace ("want", want); abort (); } mpq_clear (got); }
bool QQ::is_equal(const ring_elem f, const ring_elem g) const { gmp_QQ a = MPQ_VAL(f); gmp_QQ b = MPQ_VAL(g); return mpq_equal(a, b); }
static void dumpSkip(mpq_t *t, const symbol_t *scan) { static int initialized = 0; static mpq_t dt; static int de; static int nu; static mpz_t zde; static mpz_t znu; int rnd; if (! initialized) { mpq_init(dt); mpz_init(zde); mpz_init(znu); initialized = 1; } if (mpq_equal(*t, scan->start)) { return; } while (dump_tuplet_current != NO_ID) { /* stop */ fprintf(lily_out, " }"); tuplet_pop(&dump_tuplet_current); } if (mpq_cmp(*t, scan->start) > 0) { fprintf(stderr, "Uh oh -- start time "); mpq_out_str(stderr, 10, scan->start); fprintf(stderr, " is too low, should be "); mpq_out_str(stderr, 10, *t); fprintf(stderr, " -- is my voice analysis correct?\n"); return; } mpq_sub(dt, scan->start, *t); mpq_get_num(znu, dt); mpq_get_den(zde, dt); nu = mpz_get_ui(znu); de = mpz_get_ui(zde); rnd = nu / de; if (rnd != 0) { fprintf(lily_out, " s1*%d", rnd); nu -= rnd * de; } if (! is_two_pow(de)) { fprintf(stderr, "Uh oh -- skip now already a tuplet %d/%d??\n", nu, de); fprintf(lily_out, " s1*%d/%d", nu, de); } else { if (nu != 0) { fprintf(lily_out, " s%d*%d", de, nu); } } last_dumped_symbol = &sym_any_skip; mpq_set(*t, scan->start); VPRINTF(" skip to t = "); VPRINT_MPQ(*t); }
static void do_staff_multibar_aggregate(staff_p f) { note_p multibar_open = NULL; // defy gcc warnings mpq_t time_sig; int multibar = 0; mpq_init(time_sig); for (symbol_p scan = f->unvoiced.front; scan != NULL; scan = scan->next) { int must_close = 1; note_p note; switch (scan->type) { case SYM_TIME_SIGNATURE: mpq_set(time_sig, scan->symbol.time_signature.duration); break; case SYM_TUPLET: case SYM_REPEAT: break; case SYM_NOTE: note = &scan->symbol.note; if (! (note->flags & FLAG_REST)) { break; } if (! mpq_equal(time_sig, note->duration)) { break; } // Ah, there it is: a multibar rest must_close = 0; if (multibar == 0) { multibar_open = note; } else { note->multibar = 0; // suppress } multibar++; break; case SYM_CHORD: fprintf(stderr, "Ooopppsssss... a CHORD here?\n"); break; default: must_close = 0; break; } if (must_close && multibar > 0) { multibar_open->multibar = multibar; multibar = 0; } } }
static int _equalo(CRATIONAL *a, void *o, bool invert) { if (GB.Is(o, CLASS_BigInt)) { mpq_set_z(_tmp.n, ((CBIGINT *)o)->n); return mpq_equal(a->n, _tmp.n); } else return -1; }
mpq_t* hash_mpq_find(hash_mpq* h, int operation, mpq_t operand1, mpq_t operand2) { unsigned long i; i = ((unsigned long)mpz_get_si(mpq_numref(operand1))+101) % h->keys; i *= ((unsigned long)mpz_get_si(mpq_denref(operand1))+ 11) % h->keys; i *= ((unsigned long)mpz_get_si(mpq_numref(operand2))) % h->keys; i *= ((unsigned long)mpz_get_si(mpq_denref(operand2))) % h->keys; i %= h->keys; if (h->operation[i] == operation && mpq_equal(h->operand1[i], operand1) && mpq_equal(h->operand2[i], operand2)) { //fprintf(stderr,"*"); return &(h->result[i]); } //fprintf(stderr,"."); if (h->operation[i] == HASH_OPERATION_NOT_USED) { mpq_init(h->operand1[i]); mpq_init(h->operand2[i]); mpq_init(h->result [i]); } h->operation[i] = operation; mpq_set(h->operand1[i], operand1); mpq_set(h->operand2[i], operand2); if (operation == HASH_OPERATION_ADD) mpq_add(h->result[i], operand1, operand2); //else if (operation == HASH_OPERATION_SUB) // mpq_sub(h->result[i], operand1, operand2); else //if (operation == HASH_OPERATION_MUL) mpq_mul(h->result[i], operand1, operand2); //else // mpq_div(h->result[i], operand1, operand2); return &(h->result[i]); }
static int isEmptyMultibar(symbol_p s) { if (s->type != SYM_NOTE) { return 0; } note_p note = &s->symbol.note; if ((note->flags & FLAG_REST) && mpq_equal(time_sig_current->duration, note->duration) && note->multibar == 0) { return 1; } return 0; }
void check_one (mpq_srcptr x, mpq_srcptr y, int want) { int got; MPQ_CHECK_FORMAT (x); MPQ_CHECK_FORMAT (y); got = mpq_equal (x, y); if ((got != 0) != (want != 0)) { printf ("mpq_equal got %d want %d\n", got, want); mpq_trace ("x", x); mpq_trace ("y", y); abort (); } }
static void dumpTimeSig(mpq_t *now, symbol_p s) { symbol_p t; symbol_p scan; symbol_p prev = NULL; if (mpq_equal(time_sig_current->duration, s->symbol.time_signature.duration)) { return; } dumpSkip(now, s); t = symbol_clone(s); scan = time_line; while (scan != NULL) { prev = scan; scan = scan->next; } if (prev == NULL) { time_line = t; } else { prev->next = t; } t->next = NULL; time_sig_current->top = t->symbol.time_signature.top; time_sig_current->bottom = t->symbol.time_signature.bottom; mpq_set(time_sig_current->duration, t->symbol.time_signature.duration); VPRINTF("At t = "); VPRINT_MPQ(s->start); VPRINTF(" this time sig: %d/%d\n", time_sig_current->top, time_sig_current->bottom); if (time_sig_current->top == -1) { fprintf(lily_out, " \\override Staff.TimeSignature.style = #'C \\time 4/4 "); } else if (time_sig_current->top == -2) { fprintf(lily_out, " \\override Staff.TimeSignature.style = #'C \\time 2/2 "); } else { fprintf(lily_out, " \\time %d/%d ", time_sig_current->top, time_sig_current->bottom); } newline(); }
void lps_transtable(const Lps* lp, FILE* fp, LpFormat format, const char* head) { Var* var; Con* con; char* temp; int namelen; assert(lps_valid(lp)); assert(fp != NULL); assert(head != NULL); assert(format == LP_FORM_LPF || format == LP_FORM_MPS || format == LP_FORM_RLP || format == LP_FORM_PIP); namelen = lps_getnamesize(lp, format); temp = malloc((size_t)namelen); assert(temp != NULL); lps_number(lp); for(var = lp->var_root; var != NULL; var = var->next) { lps_makename(temp, namelen, var->name, var->number); if (var->type == VAR_FIXED) fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\t%.16e\n", head, var->number, namelen - 1, temp, var->name, mpq_get_d(var->lower)); else { if (var->size > 0 || !mpq_equal(var->cost, const_zero)) fprintf(fp, "%s\tv %7d\t%-*s\t\"%s\"\n", head, var->number, namelen - 1, temp, var->name); } } for(con = lp->con_root; con != NULL; con = con->next) { lps_makename(temp, namelen, con->name, con->number); fprintf(fp, "%s\tc %7d\t%-*s\t\"%s\"\t%.16e\n", head, con->number, namelen - 1, temp, con->name, mpq_get_d(con->scale)); } free(temp); }
//Refer to apps_sfdl_gen/tolling_cons.h for constants to use in this exogenous //check. bool tollingProverExo::exogenous_check(const mpz_t* input, const mpq_t* input_q, int num_inputs, const mpz_t* output, const mpq_t* output_q, int num_outputs, mpz_t prime) { bool passed_test = true; #ifdef ENABLE_EXOGENOUS_CHECKING mpq_t *output_recomputed; alloc_init_vec(&output_recomputed, num_outputs); baseline(input_q, num_inputs, output_recomputed, num_outputs); for(int i = 0; i < num_outputs; i++) { if (mpq_equal(output_recomputed[i], output_q[i]) == 0) { passed_test = false; break; } } clear_vec(num_outputs, output_recomputed); #else gmp_printf("<Exogenous check disabled>\n"); #endif return passed_test; };
static symbol_p rest_create(niffRest *p) { symbol_p s = symbol_create(t_current); note_p n = &s->symbol.note; mpq_init(n->duration); rat2mpq(n->duration, &p->duration); stem_p stem = stem_current; if (mpq_cmp(n->duration, time_sig_current->duration) >= 0 && ! mpq_equal(t_current, t_measure_start)) { fprintf(stderr, "Meet SharpEye rest(measure) bug. Replace start time "); mpq_out_str(stderr, 10, t_current); fprintf(stderr, " with measure start time "); mpq_out_str(stderr, 10, t_measure_start); fprintf(stderr, "\n"); mpq_set(s->start, t_measure_start); stem = NULL; // don't share a stem when the time is incorrect } s->type = SYM_NOTE; n->value = p->staffStep; n->flags |= FLAG_REST; if (stem == NULL) { #if VERBOSE VPRINTF("\n ****** Get a Rest chunk without stem chunk??"); #else fprintf(stderr, "Warning: ****** Get a Rest chunk without stem chunk??\n"); #endif stem = &stem_create()->symbol.stem; } n->tie_start = NO_ID; n->tie_end = NO_ID; n->stem = stem; n->tuplet = stem->tuplet; return s; }
void lps_setrhs( Con* con, const mpq_t rhs) { assert(con != NULL); assert(con->sid == CON_SID); mpq_set(con->rhs, rhs); /* FREE -> RHS * RHS -> RHS * LHS -> RANGE/EQUAL * RANGE -> RANGE/EQUAL * EQUAL -> RANGE/EQUAL */ if (con->type == CON_FREE) con->type = CON_RHS; else if (con->type != CON_RHS) { assert(con->type == CON_LHS || con->type == CON_RANGE || con->type == CON_EQUAL); con->type = mpq_equal(con->lhs, con->rhs) ? CON_EQUAL : CON_RANGE; } }
void lps_setupper( Var* var, const mpq_t upper) { assert(var != NULL); assert(var->sid == VAR_SID); mpq_set(var->upper, upper); /* FREE -> LOWER * LOWER -> LOWER * UPPER -> BOXED/FIXED * BOXED -> BOXED/FIXED * FIXED -> BOXED/FIXED */ if (var->type == VAR_FREE) var->type = VAR_UPPER; else if (var->type != VAR_UPPER) { assert(var->type == VAR_LOWER || var->type == VAR_BOXED || var->type == VAR_FIXED); var->type = mpq_equal(var->lower, var->upper) ? VAR_FIXED : VAR_BOXED; } }
static void dumpBarStart(mpq_t *t, symbol_p s) { VPRINTF("OK, a bar start\n"); memset(measure_accidental - NOTE_VALUES, 0, (2 * NOTE_VALUES + 1) * sizeof(*measure_accidental)); assert(measure_accidental[-1] == 0); if (! mpq_zero(*t) && (last_dumped_symbol == NULL || last_dumped_symbol->type != SYM_BAR_START || ! mpq_equal(last_dumped_symbol->start, s->start))) { mpq_t remain; int num; while (dump_tuplet_current != NO_ID) { /* stop */ fprintf(lily_out, " }"); tuplet_pop(&dump_tuplet_current); } mpq_init(remain); dumpSkip(t, s); num = bar_number(t, remain); if ((mpq_zero(remain) || last_dumped_symbol->type != SYM_REPEAT) && ! isEmptyMultibar(last_dumped_note)) { fprintf(lily_out, " |"); fprintf(lily_out, " %%%d", num); last_dumped_symbol = s; newline(); } mpq_clear(remain); } }
static int _equalf(CRATIONAL *a, double f, bool invert) { my_mpq_set_d(_tmp.n, f); return mpq_equal(a->n, _tmp.n); }
static int _equal(CRATIONAL *a, CRATIONAL *b, bool invert) { return mpq_equal(a->n, b->n); }
static int e_mpq_notequal (mpq_srcptr x, mpq_srcptr y) { return ! mpq_equal (x, y); }
bool is_equal(const ElementType& f,const ElementType& g) const { return mpq_equal(&f,&g); }
/* Wrapped because mpq_equal only guarantees a non-zero return, whereas we want 1 or 0 for == and !=. */ static int e_mpq_equal (mpq_srcptr x, mpq_srcptr y) { return mpq_equal (x, y) != 0; }
int main(void) { int i, result; flint_rand_t state; printf("evaluate..."); fflush(stdout); flint_randinit(state); /* Check aliasing */ for (i = 0; i < 100; i++) { int ans1, ans2; mpq_t a, b; fmpz_t num, den; fmpz_poly_q_t f; mpq_init(a); mpq_init(b); fmpz_init(num); fmpz_init(den); fmpz_poly_q_init(f); fmpz_poly_q_randtest(f, state, n_randint(state, 10), 10, n_randint(state, 10), 10); fmpz_randtest(num, state, 50); fmpz_randtest_not_zero(den, state, 50); fmpz_get_mpz(mpq_numref(a), num); fmpz_get_mpz(mpq_denref(a), den); mpq_canonicalize(a); ans1 = fmpz_poly_q_evaluate(b, f, a); ans2 = fmpz_poly_q_evaluate(a, f, a); result = (ans1 == ans2) && mpq_equal(a, b); if (!result) { printf("FAIL:\n"); printf("f = "), fmpz_poly_q_print(f), printf("\n"); printf("num = "), fmpz_print(num), printf("\n"); printf("den = "), fmpz_print(den), printf("\n"); gmp_printf("a = %Qd\n", a); gmp_printf("b = %Qd\n", b); printf("ans1 = %d\n", ans1); printf("ans2 = %d\n", ans2); abort(); } mpq_clear(a); mpq_clear(b); fmpz_clear(num); fmpz_clear(den); fmpz_poly_q_clear(f); } flint_randclear(state); _fmpz_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
bool AlkValue::operator!=(const AlkValue &val) const { if (d == val.d) return false; return !mpq_equal(d->m_val.get_mpq_t(), val.d->m_val.get_mpq_t()); }
void dna_alignProverExo::baseline(const mpq_t* input_q, int num_inputs, mpq_t* output_recomputed, int num_outputs) { int m = dna_align_cons::A_LEN; int n = dna_align_cons::B_LEN; const mpq_t* A = input_q; const mpq_t* B = input_q + m; int LL [m*n]; int choices [m*n]; for(int i = m-1; i >= 0; i--) { for(int j = n-1; j>=0; j--) { if (mpq_equal(A[i],B[j])) { LL[i*n + j] = getScore(LL, i+1, j+1, m, n) + 1; choices[i*n + j] = 0; } else { int down = getScore(LL, i+1, j, m, n); int right = getScore(LL, i, j+1, m, n); if (down == right + 1) { LL[i*n + j] = down; choices[i*n + j] = 1; } else { //same, or right == down+1 LL[i*n + j] = right; choices[i*n + j] = 2; } } } } bool verbose = false; if (verbose){ int i = 0; int j = 0; for(i = 0; i < m; i++){ gmp_printf("%c", (char)mpz_get_ui(mpq_numref(A[i]))); } gmp_printf("\n"); for(i = 0; i < n; i++){ gmp_printf("%c", (char)mpz_get_ui(mpq_numref(B[i]))); } gmp_printf("\n"); } int i = 0; int j = 0; int checkIndex = 1; bool match = true; while(i < m && j < n) { switch(choices[i*n + j]) { case 0: if (!mpq_equal(A[i], output_recomputed[checkIndex])) { match = false; } checkIndex++; if (verbose) gmp_printf("%c", (char)mpz_get_ui(mpq_numref(A[i]))); i++; j++; break; case 1: i++; break; case 2: j++; break; } } if (verbose) gmp_printf("\n\n"); mpq_set_ui(output_recomputed[0], (int) match, 1); }
int main(void) { int i, j, result; ulong cflags = UWORD(0); mpq_t n1, n2; FLINT_TEST_INIT(state); flint_printf("get/set_coeff_fmpz...."); fflush(stdout); mpq_init(n1); mpq_init(n2); for (i = 0; i < 100 * flint_test_multiplier(); i++) { fmpq_poly_t a; fmpz_t x1, x2; slong coeff, len; fmpq_poly_init(a); fmpz_init(x1); fmpz_init(x2); len = (slong) (n_randint(state, 100) + 1); for (j = 0; j < 100; j++) { fmpz_randtest(x1, state, 200); fmpz_get_mpz(mpq_numref(n1), x1); flint_mpz_set_si(mpq_denref(n1), 1); coeff = (slong) n_randint(state, len); fmpq_poly_set_coeff_fmpz(a, coeff, x1); fmpq_poly_get_coeff_mpq(n2, a, coeff); cflags |= fmpq_poly_is_canonical(a) ? 0 : 1; result = (mpq_equal(n1, n2) && !cflags); if (!result) { flint_printf("FAIL:\n\n"); flint_printf("a = "), fmpq_poly_debug(a), flint_printf("\n\n"); flint_printf("coeff = %wd\n\n", coeff); flint_printf("len = %wd\n\n", len); flint_printf("cflags = %wu\n\n", cflags); gmp_printf("n1 = %Qd\n\n", n1); gmp_printf("n2 = %Qd\n\n", n2); abort(); } } fmpz_clear(x1); fmpz_clear(x2); fmpq_poly_clear(a); } mpq_clear(n1); mpq_clear(n2); FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
static void do_staff_chording(staff_p f, int do_chording) { symbol_p scan; symbol_p chord = NULL; symbol_p next; for (scan = f->unvoiced.front; scan != NULL; scan = next) { next = scan->next; if (scan->type != SYM_NOTE) { continue; } if (scan->prev != NULL && mpq_equal(scan->start, scan->prev->start)) { VPRINTF("\nInspect note start "); VPRINT_MPQ(scan->start); VPRINTF(" step %d length ", scan->symbol.note.value); VPRINT_MPQ(scan->symbol.note.duration); } for (chord = scan->prev; chord != NULL && mpq_equal(scan->start, chord->start); chord = chord->prev) { if (chord->type == scan->type) { VPRINTF(" against chord start "); VPRINT_MPQ(chord->start); VPRINTF(" step %d length ", chord->symbol.note.value); VPRINT_MPQ(chord->symbol.note.duration); } if (! (scan->symbol.note.flags & FLAG_REST) && chord->type == scan->type && chord->symbol.note.stem == scan->symbol.note.stem && mpq_equal(chord->symbol.note.duration, scan->symbol.note.duration) ) { /* OK, it is a chord continuation, as far as we can tell */ VPRINTF("\nFound a chord note"); if (do_chording) { q_remove(&f->unvoiced, scan); scan->symbol.note.chord = chord->symbol.note.chord; chord->symbol.note.chord = &scan->symbol.note; } else { // Generate a new stem, duplicate ties and slurs note_p note = &chord->symbol.note; stem_p stem = note->stem; symbol_p stem_symbol = SYMBOL_OF_SYM(stem); note->stem = &symbol_clone(stem_symbol)->symbol.stem; // We need to check both scan and chord if there // are slurs or ties to duplicate if (note->flags & FLAG_REST) { stem->slur_start = -1; stem->slur_end = -1; } else { if (stem->slur_start != -1) { int dupl_slur = slur_dupl_create(stem->slur_start); VPRINTF("Duplicate its slur %d -> %d\n", stem->slur_start, dupl_slur); stem->slur_start = dupl_slur; } if (stem->slur_end != -1) { int dupl_slur = slur_dupl_lookup(stem->slur_end); VPRINTF("Finish its duplicate slur %d -> %d\n", stem->slur_start, dupl_slur); stem->slur_end = dupl_slur; } } if (0) { if (note->tie_start != -1) { tie_p tie = &ties[note->tie_start]; if (tie_dupl_lookup(note->tie_start) == -1) { note->tie_start = tie_dupl_create(note->tie_start); tie = &ties[note->tie_start]; tie->occurred = 0; tie->occur = ties[chord->symbol.note.tie_start].occur; tie->notes = calloc(tie->occur, sizeof *tie->notes); } tie->occurred++; tie->notes[tie->occurred - 1] = note; } if (note->tie_end != -1) { note->tie_end = tie_dupl_lookup(note->tie_end); tie_p tie = &ties[note->tie_start]; tie->notes[tie->occurred - 1] = note; } } } break; } } } }
int AB_Value_Equal(const AB_VALUE *v1, const AB_VALUE *v2) { assert(v1); assert(v2); return mpq_equal(v1->value, v2->value); }
bool AlkValue::operator==(const AlkValue &val) const { if (d == val.d) return true; return mpq_equal(d->m_val.get_mpq_t(), val.d->m_val.get_mpq_t()); }