// Trim arg1 to within bounds arg2 & arg3; should have arg2 <= arg3. Integer trim_to(const Integer &i, const Bound &lo, const Bound &hi) { assert(lo.is_infinite() || hi.is_infinite() || lo.value() <= hi.value()); if (!lo.is_le(i)) return lo.value(); else if (!hi.is_ge(i)) return hi.value(); else return i; }
// Reset right bound (must be to >= left bound.) void BiVector::set_right(const Bound &e) { assert(left.is_infinite() || e.is_infinite() || left.value() <= e.value()); if (!e.is_infinite() && (right.is_infinite() || e.value() < right.value())) { right = e; trim_bivector_at_right(); } else right = e; }
// Reset left bound (must be to <= right bound.) void BiVector::set_left(const Bound &e) { assert(e.is_infinite() || right.is_infinite() || e.value() <= right.value()); if (!e.is_infinite() && (left.is_infinite() || e.value() > left.value())) { left = e; trim_bivector_at_left(); } else left = e; }
// Trim all values in vector to be between LOW and HIGH, inclusive. // We should have LOW <= 0, HIGH >= 0. void BiVector::trim_values(const Bound &low, const Bound &high) { assert(low.is_le(0) && high.is_ge(0)); for (std::map<Integer, Integer>::iterator i = contents.begin(); i != contents.end(); i++) { if (!low.is_infinite() && i->second < low.value()) i->second = low.value(); if (!high.is_infinite() && i->second > high.value()) i->second = high.value(); } }
// // Try to remap a tape position to the specified range. Return FALSE if we // must abort, TRUE o.w. // // // In the event of one bound being wraparound and the other being undefined, // tape operations will have been combined and optimization will have been // done, so tape references may come either from the future or the // past of the BF program. This fact means that we must treat the // tape as wraparound in both directions. // bool remap_tape_difficult(Integer *p_i, EndType e_lo, const Bound &lo, EndType e_hi, const Bound &hi) { if (!lo.is_le(*p_i)) { switch ((e_hi == ET_wraparound && e_lo == ET_undefined) ? ET_wraparound : e_lo) { case ET_abort: case ET_truncate: case ET_undefined: assert(!lo.is_infinite()); *p_i = lo.value(); if (e_lo == ET_abort || e_lo == ET_undefined) return false; break; case ET_wraparound: assert(!lo.is_infinite() && !hi.is_infinite()); *p_i = (*p_i - lo.value()) % (hi.value() - lo.value() + 1) + lo.value(); break; } } else if (!hi.is_ge(*p_i)) { switch ((e_lo == ET_wraparound && e_hi == ET_undefined) ? ET_wraparound : e_hi) { case ET_abort: case ET_truncate: case ET_undefined: assert(!hi.is_infinite()); *p_i = hi.value(); if (e_hi == ET_abort || e_hi == ET_undefined) return false; break; case ET_wraparound: assert(!lo.is_infinite() && !hi.is_infinite()); *p_i = (*p_i - lo.value()) % (hi.value() - lo.value() + 1) + lo.value(); break; } } else // Never called in this case assert(0); return true; }
// See if arg1 is within bounds arg2 & arg3; should have arg2 <= arg3. bool is_within(const Integer &i, const Bound &lo, const Bound &hi) { assert(lo.is_infinite() || hi.is_infinite() || lo.value() <= hi.value()); return lo.is_le(i) && hi.is_ge(i); }