Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * This file is part of the cvc5 project. 3 : : * 4 : : * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS 5 : : * in the top-level source directory and their institutional affiliations. 6 : : * All rights reserved. See the file COPYING in the top-level source 7 : : * directory for licensing information. 8 : : * **************************************************************************** 9 : : * 10 : : * Representation of cardinality. 11 : : * 12 : : * Simple class to represent a cardinality; used by the cvc5 type system 13 : : * give the cardinality of sorts. 14 : : */ 15 : : 16 : : #include "cvc5_public.h" 17 : : 18 : : #ifndef CVC5__CARDINALITY_H 19 : : #define CVC5__CARDINALITY_H 20 : : 21 : : #include <iosfwd> 22 : : 23 : : #include "util/integer.h" 24 : : 25 : : namespace cvc5::internal { 26 : : 27 : : /** 28 : : * Representation for a Beth number, used only to construct 29 : : * Cardinality objects. 30 : : */ 31 : : class CardinalityBeth 32 : : { 33 : : Integer d_index; 34 : : 35 : : public: 36 : : CardinalityBeth(const Integer& beth); 37 : : 38 : 58651 : const Integer& getNumber() const { return d_index; } 39 : : 40 : : }; /* class CardinalityBeth */ 41 : : 42 : : /** 43 : : * Representation for an unknown cardinality. 44 : : */ 45 : : class CardinalityUnknown 46 : : { 47 : : public: 48 : 78549 : CardinalityUnknown() {} 49 : 78549 : ~CardinalityUnknown() {} 50 : : }; /* class CardinalityUnknown */ 51 : : 52 : : /** 53 : : * A simple representation of a cardinality. We store an 54 : : * arbitrary-precision integer for finite cardinalities, and we 55 : : * distinguish infinite cardinalities represented as Beth numbers. 56 : : */ 57 : : class Cardinality 58 : : { 59 : : /** Cardinality of the integers */ 60 : : static const Integer s_intCard; 61 : : 62 : : /** Cardinality of the reals */ 63 : : static const Integer s_realCard; 64 : : 65 : : /** A representation for unknown cardinality */ 66 : : static const Integer s_unknownCard; 67 : : 68 : : /** A representation for large, finite cardinality */ 69 : : static const Integer s_largeFiniteCard; 70 : : 71 : : /** 72 : : * In the case of finite cardinality, this is > 0, and is equal to 73 : : * the cardinality+1. If infinite, it is < 0, and is Beth[|card|-1]. 74 : : * That is, "-1" means Beth 0 == |Z|, "-2" means Beth 1 == |R|, etc. 75 : : * If this field is 0, the cardinality is unknown. 76 : : * 77 : : * We impose a ceiling on finite cardinalities of 2^64. If this field 78 : : * is >= 2^64 + 1, we consider it at "ceiling" cardinality, and 79 : : * comparisons between all such cardinalities result in "unknown." 80 : : */ 81 : : Integer d_card; 82 : : 83 : : public: 84 : : /** The cardinality of the set of integers. */ 85 : : static const Cardinality INTEGERS; 86 : : 87 : : /** The cardinality of the set of real numbers. */ 88 : : static const Cardinality REALS; 89 : : 90 : : /** The unknown cardinality */ 91 : : static const Cardinality UNKNOWN_CARD; 92 : : 93 : : /** Used as a result code for Cardinality::compare(). */ 94 : : enum CardinalityComparison 95 : : { 96 : : LESS, 97 : : EQUAL, 98 : : GREATER, 99 : : UNKNOWN 100 : : }; /* enum CardinalityComparison */ 101 : : 102 : : /** 103 : : * Construct a finite cardinality equal to the integer argument. 104 : : * The argument must be nonnegative. If we change this to an 105 : : * "unsigned" argument to enforce the restriction, we mask some 106 : : * errors that automatically convert, like "Cardinality(-1)". 107 : : */ 108 : : Cardinality(long card); 109 : : 110 : : /** 111 : : * Construct a finite cardinality equal to the integer argument. 112 : : * The argument must be nonnegative. 113 : : */ 114 : : Cardinality(const Integer& card); 115 : : 116 : : /** 117 : : * Construct an infinite cardinality equal to the given Beth number. 118 : : */ 119 : 58650 : Cardinality(CardinalityBeth beth) : d_card(-beth.getNumber() - 1) {} 120 : : 121 : : /** 122 : : * Construct an unknown cardinality. 123 : : */ 124 : 78549 : Cardinality(CardinalityUnknown) : d_card(0) {} 125 : : 126 : : /** 127 : : * Returns true iff this cardinality is unknown. "Unknown" in this 128 : : * sense means that the cardinality is completely unknown; it might 129 : : * be finite, or infinite---anything. Large, finite cardinalities 130 : : * at the "ceiling" return "false" for isUnknown() and true for 131 : : * isFinite() and isLargeFinite(). 132 : : */ 133 : 36345 : bool isUnknown() const { return d_card == 0; } 134 : : 135 : : /** Returns true iff this cardinality is finite. */ 136 : 52895 : bool isFinite() const { return d_card > 0; } 137 : : /** Returns true iff this cardinality is one */ 138 : 4 : bool isOne() const { return d_card == 2; } 139 : : /** 140 : : * Returns true iff this cardinality is finite and large (i.e., 141 : : * at the ceiling of representable finite cardinalities). 142 : : */ 143 : 68794 : bool isLargeFinite() const { return d_card >= s_largeFiniteCard; } 144 : : 145 : : /** Returns true iff this cardinality is infinite. */ 146 : 35974 : bool isInfinite() const { return d_card < 0; } 147 : : 148 : : /** 149 : : * Returns true iff this cardinality is finite or countably 150 : : * infinite. 151 : : */ 152 [ + - ][ + + ]: 3 : bool isCountable() const { return isFinite() || d_card == s_intCard; } 153 : : 154 : : /** 155 : : * Return a finite cardinality as an integer. This method can only be called 156 : : * on finite cardinalities. 157 : : */ 158 : : Integer getFiniteCardinality() const; 159 : : 160 : : /** 161 : : * Return the Beth number of an infinite cardinality. This method can only be 162 : : * called on infinite cardinalities. 163 : : */ 164 : : Integer getBethNumber() const; 165 : : 166 : : /** Assigning addition of this cardinality with another. */ 167 : : Cardinality& operator+=(const Cardinality& c); 168 : : 169 : : /** Assigning multiplication of this cardinality with another. */ 170 : : Cardinality& operator*=(const Cardinality& c); 171 : : 172 : : /** Assigning exponentiation of this cardinality with another. */ 173 : : Cardinality& operator^=(const Cardinality& c); 174 : : 175 : : /** Add two cardinalities. */ 176 : 4 : Cardinality operator+(const Cardinality& c) const 177 : : { 178 : 4 : Cardinality card(*this); 179 : 4 : card += c; 180 : 4 : return card; 181 : 0 : } 182 : : 183 : : /** Multiply two cardinalities. */ 184 : 4 : Cardinality operator*(const Cardinality& c) const 185 : : { 186 : 4 : Cardinality card(*this); 187 : 4 : card *= c; 188 : 4 : return card; 189 : 0 : } 190 : : 191 : : /** 192 : : * Exponentiation of two cardinalities. 193 : : */ 194 : 423 : Cardinality operator^(const Cardinality& c) const 195 : : { 196 : 423 : Cardinality card(*this); 197 : 423 : card ^= c; 198 : 423 : return card; 199 : 0 : } 200 : : 201 : : /** 202 : : * Compare two cardinalities. This can return UNKNOWN if two 203 : : * finite cardinalities are at the ceiling (and thus not precisely 204 : : * represented), or if one or the other is the special "unknown" 205 : : * cardinality. 206 : : */ 207 : : Cardinality::CardinalityComparison compare(const Cardinality& c) const; 208 : : 209 : : /** 210 : : * Return a string representation of this cardinality. 211 : : */ 212 : : std::string toString() const; 213 : : 214 : : /** 215 : : * Compare two cardinalities and if it is known that the current 216 : : * cardinality is smaller or equal to c, it returns true. 217 : : */ 218 : : bool knownLessThanOrEqual(const Cardinality& c) const; 219 : : }; /* class Cardinality */ 220 : : 221 : : /** Print an element of the InfiniteCardinality enumeration. */ 222 : : std::ostream& operator<<(std::ostream& out, CardinalityBeth b); 223 : : 224 : : /** Print a cardinality in a human-readable fashion. */ 225 : : std::ostream& operator<<(std::ostream& out, const Cardinality& c); 226 : : 227 : : } // namespace cvc5::internal 228 : : 229 : : #endif /* CVC5__CARDINALITY_H */