/** * Recursively traverse a QUAST, and put all leaves into a flat array. * */ static void get_quast_leaves(PipQuast* q, PipList** leaves) { if (!q) return; if (q->condition == NULL) { int i; for (i = 0; leaves[i]; ++i) ; leaves[i] = q->list; } else { get_quast_leaves(q->next_else, leaves); get_quast_leaves(q->next_then, leaves); } }
/** * candl_ddv_constant_val: returns true iff all possible values of the * minimization of the first variable of the system is a scalar constant * (not parametric), and has the same value for all conditions of the QUAST. * The scalar constant is put in the 'val' argument. * */ static int candl_ddv_constant_val(CandlMatrix* system, int* val, int nb_par) { PipOptions * options; PipQuast * solution; int is_constant_val = 1; int cst; int cst_base = 42; int first = 1; int i, j; // 1- Comute the lexmin of the system, to get a QUAST. options = pip_options_init(); options->Simplify = 1; options->Urs_parms = -1; options->Urs_unknowns = -1; options->Nq = 0; CandlMatrix* context = candl_matrix_malloc(0, nb_par + 2); solution = pip_solve(system, context, -1, options); if ((solution != NULL) && ((solution->list != NULL) || (solution->condition != NULL))) { // 2- Traverse all leaves, ensure they have the same value. int nb_leaves = count_quast_leaves(solution); PipList* leaveslist[nb_leaves + 1]; for (i = 0; i < nb_leaves + 1; ++i) leaveslist[i] = NULL; get_quast_leaves(solution, leaveslist); for (i = 0; i < nb_leaves; ++i) { PipList* list = leaveslist[i]; if (list && list->vector) { PipVector* vect = list->vector; for (j = 0; j < nb_par; ++j) if (CANDL_get_si(vect->the_vector[j]) != 0) { is_constant_val = 0; break; } if (is_constant_val) { cst = CANDL_get_si(vect->the_vector[vect->nb_elements - 1]); if (first) { first = 0; cst_base = cst; } else if (! first && cst != cst_base) { is_constant_val = 0; break; } } else break; } } } pip_quast_free(solution); pip_options_free(options); candl_matrix_free(context); if (is_constant_val) *val = cst_base; return is_constant_val; }