LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/util - finite_field_value.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 12 12 100.0 %
Date: 2026-04-17 10:42:04 Functions: 7 7 100.0 %
Branches: 2 6 33.3 %

           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                 :            :  * A finite-field element, implemented as a wrapper around Integer.
      11                 :            :  *
      12                 :            :  * TODOs:
      13                 :            :  * * extend to non-prime fields
      14                 :            :  * (https://github.com/cvc5/cvc5-wishues/issues/139)
      15                 :            :  * * consider montgomery form (https://github.com/cvc5/cvc5-wishues/issues/140)
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "cvc5_public.h"
      19                 :            : 
      20                 :            : #ifndef CVC5__FINITE_FIELDVALUE_H
      21                 :            : #define CVC5__FINITE_FIELDVALUE_H
      22                 :            : 
      23                 :            : #include <iosfwd>
      24                 :            : 
      25                 :            : #include "base/check.h"
      26                 :            : #include "base/exception.h"
      27                 :            : #include "util/integer.h"
      28                 :            : 
      29                 :            : namespace cvc5::internal {
      30                 :            : 
      31                 :            : /** Stores a field size that have been validated to be prime */
      32                 :            : struct FfSize
      33                 :            : {
      34                 :      70046 :   FfSize(Integer size) : d_val(size)
      35                 :            :   {
      36                 :            :     // we only support prime fields right now
      37 [ -  + ][ -  + ]:      70046 :     Assert(size.isProbablePrime()) << "not prime: " << size;
                 [ -  - ]
      38                 :      70046 :   }
      39                 :            :   FfSize(int size) : d_val(size)
      40                 :            :   {
      41                 :            :     // we only support prime fields right now
      42                 :            :     Assert(d_val.isProbablePrime()) << "not prime: " << size;
      43                 :            :   }
      44                 :            :   FfSize(size_t size) : d_val(size)
      45                 :            :   {
      46                 :            :     // we only support prime fields right now
      47                 :            :     Assert(d_val.isProbablePrime()) << "not prime: " << size;
      48                 :            :   }
      49                 :     740756 :   operator const Integer&() const { return d_val; }
      50                 :      32588 :   bool operator==(const FfSize& y) const { return d_val == y.d_val; }
      51                 :      27567 :   bool operator!=(const FfSize& y) const { return d_val != y.d_val; }
      52                 :            : 
      53                 :            :   Integer d_val;
      54                 :            : }; /* struct FfSize */
      55                 :            : 
      56                 :            : class FiniteFieldValue
      57                 :            : {
      58                 :            :  public:
      59                 :      93095 :   FiniteFieldValue(const Integer& val, const FfSize& size)
      60                 :      93095 :       : d_size(size),
      61                 :            :         // normalize value into [0, size)
      62                 :      93095 :         d_value(val.floorDivideRemainder(size))
      63                 :            :   {
      64                 :      93095 :   }
      65                 :            : 
      66                 :            :   /**
      67                 :            :    * Construct the zero in this field
      68                 :            :    */
      69                 :            :   FiniteFieldValue(const FfSize& size) : d_size(size), d_value(0) {}
      70                 :            : 
      71                 :            :   /* Get value. */
      72                 :            :   const Integer& getValue() const;
      73                 :            : 
      74                 :            :   /* Is zero? */
      75                 :            :   bool isZero() const;
      76                 :            : 
      77                 :            :   /* Is one? */
      78                 :            :   bool isOne() const;
      79                 :            : 
      80                 :            :   /* Get field size. */
      81                 :            :   const Integer& getFieldSize() const;
      82                 :            : 
      83                 :            :   /* Return value. */
      84                 :            :   Integer toInteger() const;
      85                 :            :   /* Return Integer of smallest absolute value that represents this.
      86                 :            :    *
      87                 :            :    * For fields of odd size, there is always a unique representative of
      88                 :            :    * smallest absolute value.
      89                 :            :    *
      90                 :            :    * For GF(2), the multiplicative identity is represented as "1", not "-1".
      91                 :            :    * */
      92                 :            :   Integer toSignedInteger() const;
      93                 :            :   /* Return string representation (of the value as a signed integer). */
      94                 :            :   std::string toString() const;
      95                 :            : 
      96                 :            :   /* Return hash value. */
      97                 :            :   size_t hash() const;
      98                 :            : 
      99                 :            :   friend bool operator==(const FiniteFieldValue&, const FiniteFieldValue&);
     100                 :            :   friend bool operator!=(const FiniteFieldValue&, const FiniteFieldValue&);
     101                 :            :   friend bool operator<(const FiniteFieldValue&, const FiniteFieldValue&);
     102                 :            :   friend bool operator>(const FiniteFieldValue&, const FiniteFieldValue&);
     103                 :            :   friend bool operator>=(const FiniteFieldValue&, const FiniteFieldValue&);
     104                 :            :   friend bool operator<=(const FiniteFieldValue&, const FiniteFieldValue&);
     105                 :            :   friend FiniteFieldValue operator+(const FiniteFieldValue&,
     106                 :            :                                     const FiniteFieldValue&);
     107                 :            :   friend FiniteFieldValue operator-(const FiniteFieldValue&,
     108                 :            :                                     const FiniteFieldValue&);
     109                 :            :   friend FiniteFieldValue operator-(const FiniteFieldValue&);
     110                 :            :   friend FiniteFieldValue operator*(const FiniteFieldValue&,
     111                 :            :                                     const FiniteFieldValue&);
     112                 :            :   friend FiniteFieldValue operator/(const FiniteFieldValue&,
     113                 :            :                                     const FiniteFieldValue&);
     114                 :            : 
     115                 :            :   FiniteFieldValue& operator+=(const FiniteFieldValue&);
     116                 :            :   FiniteFieldValue& operator-=(const FiniteFieldValue&);
     117                 :            :   FiniteFieldValue& operator*=(const FiniteFieldValue&);
     118                 :            :   FiniteFieldValue& operator/=(const FiniteFieldValue&);
     119                 :            : 
     120                 :            :   /* Reciprocal. Crashes on 0. */
     121                 :            :   FiniteFieldValue recip() const;
     122                 :            : 
     123                 :            :   /* -----------------------------------------------------------------------
     124                 :            :    ** Static helpers.
     125                 :            :    * ----------------------------------------------------------------------- */
     126                 :            : 
     127                 :            :   /* Create zero bit-vector of given size. */
     128                 :            :   static FiniteFieldValue mkZero(const Integer& modulus);
     129                 :            : 
     130                 :            :   /* Create bit-vector representing value 1 of given size. */
     131                 :            :   static FiniteFieldValue mkOne(const Integer& modulus);
     132                 :            : 
     133                 :            :  private:
     134                 :            :   /** bring d_value back into the range below */
     135                 :            :   void normalize();
     136                 :            : 
     137                 :            :   /**
     138                 :            :    * Class invariants:
     139                 :            :    *  - no overflows: d_value < d_modulus
     140                 :            :    *  - no negative numbers: d_value >= 0
     141                 :            :    */
     142                 :            : 
     143                 :            :   FfSize d_size;
     144                 :            :   Integer d_value;
     145                 :            : 
     146                 :            : }; /* class FiniteFieldValue */
     147                 :            : 
     148                 :            : /*
     149                 :            :  * Hash function for the FfSize constants.
     150                 :            :  */
     151                 :            : struct FfSizeHashFunction
     152                 :            : {
     153                 :      15239 :   size_t operator()(const FfSize& to) const { return to.d_val.hash(); }
     154                 :            : }; /* struct FfSizeHashFunction */
     155                 :            : 
     156                 :            : /*
     157                 :            :  * Hash function for the FiniteFieldValue.
     158                 :            :  */
     159                 :            : struct FiniteFieldValueHashFunction
     160                 :            : {
     161                 :      33100 :   size_t operator()(const FiniteFieldValue& ff) const { return ff.hash(); }
     162                 :            : }; /* struct FiniteFieldValueHashFunction */
     163                 :            : 
     164                 :            : /* -----------------------------------------------------------------------
     165                 :            :  ** Operators
     166                 :            :  * ----------------------------------------------------------------------- */
     167                 :            : 
     168                 :            : /* (Dis)Equality --------------------------------------------------------- */
     169                 :            : 
     170                 :            : /* Return true if x is equal to 'y'. */
     171                 :            : bool operator==(const FiniteFieldValue& x, const FiniteFieldValue& y);
     172                 :            : 
     173                 :            : /* Return true if x is not equal to 'y'. */
     174                 :            : bool operator!=(const FiniteFieldValue& x, const FiniteFieldValue& y);
     175                 :            : 
     176                 :            : /* Unsigned Inequality --------------------------------------------------- */
     177                 :            : 
     178                 :            : /* Return true if x is unsigned less than finite field 'y'. */
     179                 :            : bool operator<(const FiniteFieldValue& x, const FiniteFieldValue& y);
     180                 :            : 
     181                 :            : /* Return true if x is unsigned less than or equal to finite field 'y'. */
     182                 :            : bool operator<=(const FiniteFieldValue& x, const FiniteFieldValue& y);
     183                 :            : 
     184                 :            : /* Return true if x is unsigned greater than finite field 'y'. */
     185                 :            : bool operator>(const FiniteFieldValue& x, const FiniteFieldValue& y);
     186                 :            : 
     187                 :            : /* Return true if x is unsigned greater than or equal to finite field 'y'. */
     188                 :            : bool operator>=(const FiniteFieldValue& x, const FiniteFieldValue& y);
     189                 :            : 
     190                 :            : /* Arithmetic operations ------------------------------------------------- */
     191                 :            : 
     192                 :            : /* Return a finite field representing the addition (x + y). */
     193                 :            : FiniteFieldValue operator+(const FiniteFieldValue& x,
     194                 :            :                            const FiniteFieldValue& y);
     195                 :            : 
     196                 :            : /* Return a finite field representing the subtraction (x - y). */
     197                 :            : FiniteFieldValue operator-(const FiniteFieldValue& x,
     198                 :            :                            const FiniteFieldValue& y);
     199                 :            : 
     200                 :            : /* Return a finite field representing the negation of x. */
     201                 :            : FiniteFieldValue operator-(const FiniteFieldValue& x);
     202                 :            : 
     203                 :            : /* Return a finite field representing the multiplication (x * y). */
     204                 :            : FiniteFieldValue operator*(const FiniteFieldValue& x,
     205                 :            :                            const FiniteFieldValue& y);
     206                 :            : 
     207                 :            : /* Return a finite field representing the division (x / y). */
     208                 :            : FiniteFieldValue operator/(const FiniteFieldValue& x,
     209                 :            :                            const FiniteFieldValue& y);
     210                 :            : 
     211                 :            : /* -----------------------------------------------------------------------
     212                 :            :  * Output stream
     213                 :            :  * ----------------------------------------------------------------------- */
     214                 :            : 
     215                 :            : std::ostream& operator<<(std::ostream& os, const FiniteFieldValue& ff);
     216                 :            : std::ostream& operator<<(std::ostream& os, const FfSize& ff);
     217                 :            : 
     218                 :            : }  // namespace cvc5::internal
     219                 :            : 
     220                 :            : #endif /* CVC5__FINITE_FIELDVALUE_H */

Generated by: LCOV version 1.14