示例#1
0
/** Assigning multiplication of this cardinality with another. */
Cardinality& Cardinality::operator*=(const Cardinality& c) {
  if (isUnknown()) {
    return *this;
  } else if (c.isUnknown()) {
    d_card = s_unknownCard;
    return *this;
  }

  if (c.isFinite() && isLargeFinite()) {
    return *this;
  } else if (isFinite() && c.isLargeFinite()) {
    d_card = s_largeFiniteCard;
    return *this;
  }

  if (compare(0) == EQUAL || c.compare(0) == EQUAL) {
    return *this = 0;
  } else if (!isFinite() || !c.isFinite()) {
    if (compare(c) == LESS) {
      return *this = c;
    } else {
      return *this;
    }
  } else {
    d_card -= 1;
    d_card *= c.d_card - 1;
    d_card += 1;
    return *this;
  }

  Unreachable();
}
示例#2
0
Cardinality& Cardinality::operator+=(const Cardinality& c) {
  if (isUnknown()) {
    return *this;
  } else if (c.isUnknown()) {
    d_card = s_unknownCard;
    return *this;
  }

  if (c.isFinite() && isLargeFinite()) {
    return *this;
  } else if (isFinite() && c.isLargeFinite()) {
    d_card = s_largeFiniteCard;
    return *this;
  }

  if (isFinite() && c.isFinite()) {
    d_card += c.d_card - 1;
    return *this;
  }
  if (compare(c) == LESS) {
    return *this = c;
  } else {
    return *this;
  }

  Unreachable();
}
示例#3
0
Integer Cardinality::getFiniteCardinality() const {
  PrettyCheckArgument(isFinite(), *this, "This cardinality is not finite.");
  PrettyCheckArgument(
      !isLargeFinite(), *this,
      "This cardinality is finite, but too large to represent.");
  return d_card - 1;
}
示例#4
0
Cardinality::CardinalityComparison Cardinality::compare(const Cardinality& c) const throw() {
  if(isUnknown() || c.isUnknown()) {
    return UNKNOWN;
  } else if(isLargeFinite()) {
    if(c.isLargeFinite()) {
      return UNKNOWN;
    } else if(c.isFinite()) {
        return GREATER;
    } else {
      Assert(c.isInfinite());
      return LESS;
    }
  } else if(c.isLargeFinite()) {
    if(isLargeFinite()) {
      return UNKNOWN;
    } else if(isFinite()) {
      return LESS;
    } else {
      Assert(isInfinite());
      return GREATER;
    }
  } else if(isInfinite()) {
    if(c.isFinite()) {
      return GREATER;
    } else {
      return d_card < c.d_card ? GREATER :
               (d_card == c.d_card ? EQUAL : LESS);
    }
  } else if(c.isInfinite()) {
    Assert(isFinite());
    return LESS;
  } else {
    Assert(isFinite() && !isLargeFinite());
    Assert(c.isFinite() && !c.isLargeFinite());
    return d_card < c.d_card ? LESS :
             (d_card == c.d_card ? EQUAL : GREATER);
  }

  Unreachable();
}
示例#5
0
/** Assigning exponentiation of this cardinality with another. */
Cardinality& Cardinality::operator^=(const Cardinality& c) {
  if (isUnknown()) {
    return *this;
  } else if (c.isUnknown()) {
    d_card = s_unknownCard;
    return *this;
  }

  if (c.isFinite() && isLargeFinite()) {
    return *this;
  } else if (isFinite() && c.isLargeFinite()) {
    d_card = s_largeFiniteCard;
    return *this;
  }

  if (c.compare(0) == EQUAL) {
    // (anything) ^ 0 == 1
    d_card = 2;  // remember, +1 for finite cardinalities
    return *this;
  } else if (compare(0) == EQUAL) {
    // 0 ^ (>= 1) == 0
    return *this;
  } else if (compare(1) == EQUAL) {
    // 1 ^ (>= 1) == 1
    return *this;
  } else if (c.compare(1) == EQUAL) {
    // (anything) ^ 1 == (that thing)
    return *this;
  } else if (isFinite() && c.isFinite()) {
    // finite ^ finite == finite
    try {
      // Note: can throw an assertion if c is too big for
      // exponentiation
      if (d_card - 1 >= 2 && c.d_card - 1 >= 64) {
        // don't bother, it's too large anyways
        d_card = s_largeFiniteCard;
      } else {
        d_card = (d_card - 1).pow(c.d_card.getUnsignedLong() - 1) + 1;
      }
    } catch (IllegalArgumentException&) {
      d_card = s_largeFiniteCard;
    }
    return *this;
  } else if (!isFinite() && c.isFinite()) {
    // inf ^ finite == inf
    return *this;
  } else {
    Assert(compare(2) != LESS && !c.isFinite(),
           "fall-through case not as expected:\n%s\n%s",
           this->toString().c_str(), c.toString().c_str());
    // (>= 2) ^ beth_k == beth_(k+1)
    // unless the base is already > the exponent
    if (compare(c) == GREATER) {
      return *this;
    }
    d_card = c.d_card - 1;
    return *this;
  }

  Unreachable();
}