/** * Returns true if two clocks form a zero cycle in a priced DBM. * * @param pdbm is a closed priced DBM of dimension \a dim. * @param dim is the dimension of \a pdbm. * @param i is the index of a clock * @param j is the index of a clock * @return True if and only if \a i and \a j�form a zero cycle in \a pdbm. */ static bool pdbm_areOnZeroCycle(const PDBM pdbm, cindex_t dim, cindex_t i, cindex_t j) { assert(pdbm && dim && i < dim && j < dim && i != j); raw_t *dbm = pdbm_matrix(pdbm); return (dbm_raw2bound(DBM(i, j)) == -dbm_raw2bound(DBM(j, i))); }
void test_diagonalExtrapolateLUBounds(raw_t *dbm, cindex_t dim, const int32_t *lower, const int32_t *upper) { cindex_t i,j; assert(dbm && dim > 0 && lower && upper); /* other rows */ for (i = 1; i < dim; ++i) { for (j = 0; j < dim; ++j) { if (i != j && (dbm_raw2bound(DBM(i,j)) > lower[i] || dbm_raw2bound(DBM(0,i)) < -lower[i] || dbm_raw2bound(DBM(0,j)) < -upper[j])) { DBM(i,j) = dbm_LS_INFINITY; } } } /* 1st row */ for (j = 1; j < dim; ++j) { assert(dbm_raw2bound(DBM(0,j))<= lower[0]); if (dbm_raw2bound(DBM(0,j)) < -upper[j]) { DBM(0, j) = (upper[j] >= 0 ? dbm_bound2raw(-upper[j], dbm_STRICT) : dbm_LE_ZERO); } } dbm_close(dbm, dim); }
void test_diagonalExtrapolateMaxBounds(raw_t *dbm, cindex_t dim, const int32_t *max) { cindex_t i,j; assert(dbm && dim > 0 && max); /* other rows */ for (i = 1; i < dim; ++i) { for (j = 0; j < dim; ++j) { if (i != j && (dbm_raw2bound(DBM(0,i)) < -max[i] || dbm_raw2bound(DBM(0,j)) < -max[j] || dbm_raw2bound(DBM(i,j)) > max[i])) { DBM(i,j) = dbm_LS_INFINITY; } } } /* 1st row */ for (j = 1; j < dim; ++j) { assert(dbm_raw2bound(DBM(0,j)) <= max[0]); if (dbm_raw2bound(DBM(0,j)) < -max[j]) { DBM(0,j) = (max[j] >= 0 ? dbm_bound2raw(-max[j], dbm_STRICT) : dbm_LE_ZERO); } } dbm_close(dbm, dim); }
void pdbm_getOffset(const PDBM pdbm, cindex_t dim, int32_t *valuation) { assert(pdbm && dim && valuation); raw_t *dbm = pdbm_matrix(pdbm); for (uint32_t i = 1; i < dim; i++) { assert(dbm_raw2bound(DBM(0, i)) <= 0); valuation[i] = -dbm_raw2bound(DBM(0, i)); } }
bool Clocks::print_c( std::ostream& o, unsigned int i ) const { ASSERT( i > 0 ); raw_t upper = data[ i * dim + 0 ]; raw_t lower = data[ 0 * dim + i ]; if ( lower != dbm_LE_ZERO ) o << ( -dbm_raw2bound( lower ) ) << boundEq( lower ); if ( lower != dbm_LE_ZERO || upper != dbm_LS_INFINITY ) print_name( o, i ); else return false; if ( upper != dbm_LS_INFINITY ) o << boundEq( upper ) << dbm_raw2bound( upper ); return true; }
/** * Returns the cost of the offset point of \a dbm2 in \a dbm1. * * @param dbm1 is the DBM for which to find the cost. * @param rates1 are the coefficients of the hyperplane of \a dbm1. * @param cost1 is the cost of the offset point of \a dbm1 * @param dbm2 is the DBM providing the offset point for which * we want to find the cost. * @param dim is the dimension of \a dbm1 and \a dbm2. */ static int32_t costAtOtherOffset( const raw_t *dbm1, const int32_t *rates1, int32_t cost1, const raw_t *dbm2, cindex_t dim) { assert(dbm1 && dbm2 && rates1 && dim); /* Notice that -dbm1[i] and -dbm2[i] are the lower bounds of clock * i in dbm1 and dbm2, respectively. */ for (uint32_t i = 1; i < dim; i++) { cost1 += rates1[i] * (-dbm_raw2bound(dbm2[i]) - -dbm_raw2bound(dbm1[i])); } return cost1; }
bool Clocks::print_d( std::ostream& o, unsigned int i, unsigned int j ) const { ASSERT( i > 0 && j > 0 ); raw_t upper = data[ i * dim + j ]; raw_t lower = data[ j * dim + i ]; if ( lower != dbm_LS_INFINITY ) o << ( -dbm_raw2bound( lower ) ) << boundEq( lower ); if ( lower != dbm_LS_INFINITY || upper != dbm_LS_INFINITY ) { print_name( o, i ); o << "-"; print_name( o, j ); } else return false; if ( upper != dbm_LS_INFINITY ) o << boundEq( upper ) << dbm_raw2bound( upper ); return true; }
/** * Find the zero cycles of a DBM. The zero cycles are represented by * an array which for each clock contains the next element on the zero * cycle, or * 0 if the clock is the last element. I.e. next[i] is the * index of the next clock on a zero cycle with i. * * @post forall i.next[i] == 0 || next[i] > i */ static void dbm_findZeroCycles(const raw_t *dbm, cindex_t dim, cindex_t *next) { cindex_t i, j; for (i = 0; i < dim; i++) { next[i] = 0; for (j = i + 1; j < dim; j++) { if (dbm_raw2bound(DBM(i, j)) == -dbm_raw2bound(DBM(j, i))) { next[i]= j; break; } } } }
bool pdbm_findNextZeroCycle(const PDBM pdbm, cindex_t dim, cindex_t x, cindex_t *out) { assert(pdbm && dim && x < dim && out); const raw_t *dbm = pdbm_matrix(pdbm); cindex_t i = *out; while (i < dim) { if (i != x && dbm_raw2bound(DBM(i, x)) == -dbm_raw2bound(DBM(x, i))) { *out = i; return true; } i++; } *out = i; return false; }
int32_t pdbm_getInfimumValuation( const PDBM pdbm, cindex_t dim, int32_t *valuation, const bool *free) { assert(pdbm && dim && valuation); assert(pdbm_isValid(pdbm, dim)); raw_t copy[dim * dim]; raw_t *dbm = pdbm_matrix(pdbm); int32_t *rates = pdbm_rates(pdbm); /* Compute the cost of the origin. */ int32_t cost = pdbm_cost(pdbm); for (uint32_t i = 1; i < dim; i++) { cost -= rates[i] * -dbm_raw2bound(DBM(0, i)); } /* If not all clocks are free, then restrict a copy of the DBM * according to the valuation given. */ if (free) { dbm_copy(copy, dbm, dim); dbm = copy; for (uint32_t i = 1; i < dim; i++) { if (!free[i]) { constraint_t con[2] = { dbm_constraint(i, 0, valuation[i], dbm_WEAK), dbm_constraint(0, i, -valuation[i], dbm_WEAK) }; if (!dbm_constrainN(dbm, dim, con, 2)) { throw std::out_of_range("No such evaluation exists"); } } } } pdbm_infimum(dbm, dim, pdbm_cost(pdbm), rates, valuation); for (uint32_t i = 0; i < dim; i++) { cost += rates[i] * valuation[i]; } ASSERT(cost == pdbm_getCostOfValuation(pdbm, dim, valuation), pdbm_print(stderr, pdbm, dim)); return cost; }
bool pdbm_constrainN( PDBM &pdbm, cindex_t dim, const constraint_t *constraints, size_t n) { assert(pdbm && dim); raw_t *dbm = pdbm_matrix(pdbm); for (; n; n--, constraints++) { if (constraints->value < DBM(constraints->i, constraints->j)) { pdbm_prepare(pdbm, dim); dbm = pdbm_matrix(pdbm); int32_t cost = pdbm_cost(pdbm); int32_t *rates = pdbm_rates(pdbm); for (uint32_t k = 1; k < dim; k++) { cost += rates[k] * dbm_raw2bound(DBM(0, k)); } if (dbm_constrainN(dbm, dim, constraints, n) == FALSE) { return false; } for (uint32_t k = 1; k < dim; k++) { cost -= rates[k] * dbm_raw2bound(DBM(0, k)); } pdbm_cost(pdbm) = cost; pdbm_cache(pdbm) = INVALID; break; } } return true; }
int32_t pdbm_getCostOfVertex(const PDBM pdbm, cindex_t dim, const int32_t *valuation) { assert(pdbm && dim && valuation); assert(pdbm_containsIntWeakly(pdbm, dim, valuation)); raw_t *dbm = pdbm_matrix(pdbm); int32_t cost = pdbm_cost(pdbm); for (uint32_t i = 1; i < dim; i++) { cost += (valuation[i] - -dbm_raw2bound(DBM(0, i))) * pdbm_rates(pdbm)[i]; } return cost; }
static bool isPointIncludedWeakly(const int32_t *pt, const raw_t *dbm, cindex_t dim) { cindex_t i, j; assert(pt && dbm && dim); for (i = 0; i < dim; ++i) { for (j = 0; j < dim; ++j) { if (pt[i] - pt[j] > dbm_raw2bound(DBM(i,j))) { return false; } } } return true; }
void pdbm_relax(PDBM &pdbm, cindex_t dim) { pdbm_prepare(pdbm, dim); raw_t *dbm = pdbm_matrix(pdbm); raw_t *first = dbm + 1; raw_t *last = dbm + dim * dim - 1; while (first != last) { if (*first < dbm_LS_INFINITY) { *first = dbm_bound2raw(dbm_raw2bound(*first), dbm_WEAK); } first++; } assertx(pdbm_isValid(pdbm, dim)); }
void pdbm_freeDown(PDBM &pdbm, cindex_t dim, cindex_t index) { assert(pdbm_rates(pdbm)[index] <= 0); pdbm_prepare(pdbm, dim); raw_t *dbm = pdbm_matrix(pdbm); /* Move offset point. */ int32_t rate = pdbm_rates(pdbm)[index]; int32_t bound = -dbm_raw2bound(DBM(0, index)); pdbm_cost(pdbm) -= bound * rate; /* Stretch down. */ dbm_freeDown(dbm, dim, index); }
/* check for infinity values * before printing. */ std::ostream& dbm_cppPrintRaw(std::ostream& out, raw_t c) { return dbm_cppPrintBound(out << (dbm_rawIsWeak(c) ? "<=" : "<"), dbm_raw2bound(c)); }
bool pdbm_constrainToFacet(PDBM &pdbm, cindex_t dim, cindex_t i, cindex_t j) { const raw_t *dbm = pdbm_getMatrix(pdbm, dim); int32_t bound = -dbm_raw2bound(dbm[i * dim + j]); return pdbm_constrain1(pdbm, dim, j, i, dbm_bound2raw(bound, dbm_WEAK)); }
bool pdbm_constrain1( PDBM &pdbm, cindex_t dim, cindex_t i, cindex_t j, raw_t constraint) { assert(pdbm && dim && i < dim && j < dim); raw_t *dbm = pdbm_matrix(pdbm); /* Check if entry is already tighter than constraint. */ if (constraint >= DBM(i, j)) { return true; } /* If constraint will make DBM empty, then mark it as empty. */ if (dbm_negRaw(constraint) >= DBM(j, i)) { if (pdbm_count(pdbm) > 1) { pdbm_decRef(pdbm); pdbm = NULL; } else { DBM(i,j) = constraint; DBM(0,0) = -1; /* consistent with isEmpty */ } return false; } /* If DBM is shared, copy it first. */ pdbm_prepare(pdbm, dim); dbm = pdbm_matrix(pdbm); /* Compute the cost at the origin. */ int32_t cost = pdbm_cost(pdbm); int32_t *rates = pdbm_rates(pdbm); for (uint32_t k = 1; k < dim; k++) { cost += rates[k] * dbm_raw2bound(DBM(0, k)); } /* Apply the constraint. */ DBM(i,j) = constraint; dbm_closeij(dbm, dim, i, j); /* Compute the cost at the new offset point and invalidate the * cache. */ for (uint32_t k = 1; k < dim; k++) { cost -= rates[k] * dbm_raw2bound(DBM(0, k)); } pdbm_cost(pdbm) = cost; pdbm_cache(pdbm) = INVALID; assertx(pdbm_isValid(pdbm, dim)); return true; }