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