Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Alex Ozdemir 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 : : * A finite-field element, implemented as a wrapper around Integer. 14 : : */ 15 : : 16 : : #include "util/finite_field_value.h" 17 : : 18 : : #include "util/hash.h" 19 : : 20 : : namespace cvc5::internal { 21 : : 22 : 53192 : const Integer& FiniteFieldValue::getValue() const { return d_value; } 23 : : 24 : 0 : bool FiniteFieldValue::isZero() const { return d_value.isZero(); } 25 : : 26 : 9 : bool FiniteFieldValue::isOne() const { return d_value.isOne(); } 27 : : 28 : 2545 : const Integer& FiniteFieldValue::getFieldSize() const { return d_size; } 29 : : 30 : 0 : Integer FiniteFieldValue::toInteger() const { return d_value; } 31 : : 32 : 229 : Integer FiniteFieldValue::toSignedInteger() const 33 : : { 34 : 687 : Integer half_size = d_size.d_val.divByPow2(1) + 1; 35 [ + + ]: 458 : return (d_value < half_size) ? d_value : d_value - d_size; 36 : : } 37 : : 38 : 0 : std::string FiniteFieldValue::toString() const 39 : : { 40 : 0 : return toSignedInteger().toString(); 41 : : } 42 : : 43 : 34013 : size_t FiniteFieldValue::hash() const 44 : : { 45 : : PairHashFunction<size_t, size_t> h; 46 : 34013 : return h(std::make_pair(d_value.hash(), d_size.d_val.hash())); 47 : : } 48 : : 49 : 113 : void FiniteFieldValue::normalize() 50 : : { 51 : 113 : d_value = d_value.floorDivideRemainder(d_size.d_val); 52 : 113 : } 53 : : 54 : : /* ----------------------------------------------------------------------- 55 : : * Operators 56 : : * ----------------------------------------------------------------------- */ 57 : : 58 : : /* (Dis)Equality --------------------------------------------------------- */ 59 : : 60 : 29117 : bool operator==(const FiniteFieldValue& x, const FiniteFieldValue& y) 61 : : { 62 [ - + ]: 29117 : if (x.d_size != y.d_size) return false; 63 : 29117 : return x.d_value == y.d_value; 64 : : } 65 : : 66 : 0 : bool operator!=(const FiniteFieldValue& x, const FiniteFieldValue& y) 67 : : { 68 [ - - ]: 0 : if (x.d_size != y.d_size) return true; 69 : 0 : return x.d_value != y.d_value; 70 : : } 71 : : 72 : : /* Unsigned Inequality --------------------------------------------------- */ 73 : : 74 : 4 : bool operator<(const FiniteFieldValue& x, const FiniteFieldValue& y) 75 : : { 76 : 4 : return x.d_value < y.d_value; 77 : : } 78 : : 79 : 0 : bool operator<=(const FiniteFieldValue& x, const FiniteFieldValue& y) 80 : : { 81 : 0 : return x.d_value <= y.d_value; 82 : : } 83 : : 84 : 0 : bool operator>(const FiniteFieldValue& x, const FiniteFieldValue& y) 85 : : { 86 : 0 : return x.d_value > y.d_value; 87 : : } 88 : : 89 : 0 : bool operator>=(const FiniteFieldValue& x, const FiniteFieldValue& y) 90 : : { 91 : 0 : return x.d_value >= y.d_value; 92 : : } 93 : : 94 : : /* Arithmetic operations ------------------------------------------------- */ 95 : : 96 : 7337 : FiniteFieldValue operator+(const FiniteFieldValue& x, const FiniteFieldValue& y) 97 : : { 98 [ - + ][ - + ]: 7337 : Assert(x.d_size == y.d_size) [ - - ] 99 : 0 : << "Size mismatch: " << x.d_size << " != " << y.d_size; 100 : 14674 : Integer sum = x.d_value.modAdd(y.d_value, x.d_size); 101 : 14674 : return {sum, x.d_size}; 102 : : } 103 : : 104 : 10424 : FiniteFieldValue operator-(const FiniteFieldValue& x, const FiniteFieldValue& y) 105 : : { 106 [ - + ][ - + ]: 10424 : Assert(x.d_size == y.d_size) [ - - ] 107 : 0 : << "Size mismatch: " << x.d_size << " != " << y.d_size; 108 : 20848 : return {x.d_value - y.d_value, x.d_size}; 109 : : } 110 : : 111 : 0 : FiniteFieldValue operator-(const FiniteFieldValue& x) 112 : : { 113 : 0 : return {x.d_size.d_val - x.d_value, x.d_size}; 114 : : } 115 : : 116 : 8522 : FiniteFieldValue operator*(const FiniteFieldValue& x, const FiniteFieldValue& y) 117 : : { 118 [ - + ][ - + ]: 8522 : Assert(x.d_size == y.d_size) [ - - ] 119 : 0 : << "Size mismatch: " << x.d_size << " != " << y.d_size; 120 : 17044 : Integer prod = x.d_value.modMultiply(y.d_value, x.d_size); 121 : 17044 : return {prod, x.d_size}; 122 : : } 123 : : 124 : 66 : FiniteFieldValue operator/(const FiniteFieldValue& x, const FiniteFieldValue& y) 125 : : { 126 : 132 : return x * y.recip(); 127 : : } 128 : : 129 : 66 : FiniteFieldValue FiniteFieldValue::recip() const 130 : : { 131 [ - + ][ - + ]: 66 : Assert(!d_value.isZero()); [ - - ] 132 : 132 : return {d_value.modInverse(d_size), d_size}; 133 : : } 134 : : 135 : : /* In-Place Arithmetic --------------------------------------------------- */ 136 : : 137 : 0 : FiniteFieldValue& FiniteFieldValue::operator+=(const FiniteFieldValue& y) 138 : : { 139 : 0 : Assert(d_size == y.d_size) 140 : 0 : << "Size mismatch: " << d_size << " != " << y.d_size; 141 : 0 : d_value += y.d_value; 142 : 0 : normalize(); 143 : 0 : return *this; 144 : : } 145 : : 146 : 0 : FiniteFieldValue& FiniteFieldValue::operator-=(const FiniteFieldValue& y) 147 : : { 148 : 0 : Assert(d_size == y.d_size) 149 : 0 : << "Size mismatch: " << d_size << " != " << y.d_size; 150 : 0 : d_value -= y.d_value; 151 : 0 : normalize(); 152 : 0 : return *this; 153 : : } 154 : : 155 : 113 : FiniteFieldValue& FiniteFieldValue::operator*=(const FiniteFieldValue& y) 156 : : { 157 [ - + ][ - + ]: 113 : Assert(d_size == y.d_size) [ - - ] 158 : 0 : << "Size mismatch: " << d_size << " != " << y.d_size; 159 : 113 : d_value *= y.d_value; 160 : 113 : normalize(); 161 : 113 : return *this; 162 : : } 163 : : 164 : 0 : FiniteFieldValue& FiniteFieldValue::operator/=(const FiniteFieldValue& y) 165 : : { 166 : 0 : Assert(d_size == y.d_size) 167 : 0 : << "Size mismatch: " << d_size << " != " << y.d_size; 168 : 0 : d_value *= y.d_value.modInverse(d_size); 169 : 0 : normalize(); 170 : 0 : return *this; 171 : : } 172 : : 173 : : 174 : : /* ----------------------------------------------------------------------- 175 : : * Output stream 176 : : * ----------------------------------------------------------------------- */ 177 : : 178 : 0 : std::ostream& operator<<(std::ostream& os, const FiniteFieldValue& ff) 179 : : { 180 : 0 : return os << ff.toString(); 181 : : } 182 : : 183 : 0 : std::ostream& operator<<(std::ostream& os, const FfSize& ff) 184 : : { 185 : 0 : return os << ff.d_val; 186 : : } 187 : : 188 : : /* ----------------------------------------------------------------------- 189 : : * Static helpers. 190 : : * ----------------------------------------------------------------------- */ 191 : : 192 : 6207 : FiniteFieldValue FiniteFieldValue::mkZero(const Integer& size) 193 : : { 194 : 6207 : return {0, size}; 195 : : } 196 : : 197 : 30162 : FiniteFieldValue FiniteFieldValue::mkOne(const Integer& size) 198 : : { 199 : 30162 : return {1, size}; 200 : : } 201 : : 202 : : } // namespace cvc5::internal