LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith/linear - matrix.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 351 446 78.7 %
Date: 2026-04-01 10:41:05 Functions: 76 86 88.4 %
Branches: 139 294 47.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                 :            :  * Sparse matrix implementations for different types.
      10                 :            :  *
      11                 :            :  * Sparse matrix implementations for different types.
      12                 :            :  * This defines Matrix<T>, IntegerEqualityTables and Tableau.
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "cvc5_private.h"
      16                 :            : 
      17                 :            : #pragma once
      18                 :            : 
      19                 :            : #include <queue>
      20                 :            : #include <utility>
      21                 :            : #include <vector>
      22                 :            : 
      23                 :            : #include "base/output.h"
      24                 :            : #include "theory/arith/linear/arithvar.h"
      25                 :            : #include "util/dense_map.h"
      26                 :            : #include "util/index.h"
      27                 :            : 
      28                 :            : namespace cvc5::internal {
      29                 :            : namespace theory {
      30                 :            : namespace arith::linear {
      31                 :            : 
      32                 :            : typedef Index EntryID;
      33                 :            : const EntryID ENTRYID_SENTINEL = std::numeric_limits<EntryID>::max();
      34                 :            : 
      35                 :            : typedef Index RowIndex;
      36                 :            : const RowIndex ROW_INDEX_SENTINEL  = std::numeric_limits<RowIndex>::max();
      37                 :            : 
      38                 :            : class CoefficientChangeCallback {
      39                 :            : public:
      40                 :     251767 :   virtual ~CoefficientChangeCallback() {}
      41                 :            :   virtual void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn) = 0;
      42                 :            :   virtual void multiplyRow(RowIndex ridx, int Sgn) = 0;
      43                 :            :   virtual bool canUseRow(RowIndex ridx) const = 0;
      44                 :            : };
      45                 :            : 
      46                 :            : class NoEffectCCCB : public CoefficientChangeCallback {
      47                 :            : public:
      48                 :            :  void update(RowIndex ridx, ArithVar nb, int oldSgn, int currSgn) override;
      49                 :            :  void multiplyRow(RowIndex ridx, int Sgn) override;
      50                 :            :  bool canUseRow(RowIndex ridx) const override;
      51                 :            : };
      52                 :            : 
      53                 :            : template<class T>
      54                 :            : class MatrixEntry {
      55                 :            : private:
      56                 :            :   RowIndex d_rowIndex;
      57                 :            :   ArithVar d_colVar;
      58                 :            : 
      59                 :            :   EntryID d_nextRow;
      60                 :            :   EntryID d_nextCol;
      61                 :            : 
      62                 :            :   EntryID d_prevRow;
      63                 :            :   EntryID d_prevCol;
      64                 :            : 
      65                 :            :   T d_coefficient;
      66                 :            : 
      67                 :            : public:
      68                 :    1560720 :   MatrixEntry():
      69                 :    1560720 :     d_rowIndex(ROW_INDEX_SENTINEL),
      70                 :    1560720 :     d_colVar(ARITHVAR_SENTINEL),
      71                 :    1560720 :     d_nextRow(ENTRYID_SENTINEL),
      72                 :    1560720 :     d_nextCol(ENTRYID_SENTINEL),
      73                 :    1560720 :     d_prevRow(ENTRYID_SENTINEL),
      74                 :    1560720 :     d_prevCol(ENTRYID_SENTINEL),
      75                 :    1560720 :     d_coefficient()
      76                 :    1560720 :   {}
      77                 :            : 
      78                 :   42454406 :   MatrixEntry(RowIndex row, ArithVar col, const T& coeff):
      79                 :   42454406 :      d_rowIndex(row),
      80                 :   42454406 :      d_colVar(col),
      81                 :   42454406 :      d_nextRow(ENTRYID_SENTINEL),
      82                 :   42454406 :      d_nextCol(ENTRYID_SENTINEL),
      83                 :   42454406 :      d_prevRow(ENTRYID_SENTINEL),
      84                 :   42454406 :      d_prevCol(ENTRYID_SENTINEL),
      85                 :   42454406 :      d_coefficient(coeff)
      86                 :   42454406 :   {}
      87                 :            : 
      88                 :            : private:
      89                 :   41610019 :   bool unusedConsistent() const {
      90                 :            :     return
      91 [ +  + ][ -  + ]:   41978631 :       (d_rowIndex == ROW_INDEX_SENTINEL && d_colVar == ARITHVAR_SENTINEL) ||
      92 [ +  - ][ +  - ]:   41978631 :       (d_rowIndex != ROW_INDEX_SENTINEL && d_colVar != ARITHVAR_SENTINEL);
      93                 :            :   }
      94                 :            : 
      95                 :            : public:
      96                 :            : 
      97                 :  552086047 :   EntryID getNextRowEntryID() const {
      98                 :  552086047 :     return d_nextRow;
      99                 :            :   }
     100                 :            : 
     101                 :  155692164 :   EntryID getNextColEntryID() const {
     102                 :  155692164 :     return d_nextCol;
     103                 :            :   }
     104                 :   41241407 :   EntryID getPrevRowEntryID() const {
     105                 :   41241407 :     return d_prevRow;
     106                 :            :   }
     107                 :            : 
     108                 :   41241407 :   EntryID getPrevColEntryID() const {
     109                 :   41241407 :     return d_prevCol;
     110                 :            :   }
     111                 :            : 
     112                 :   65480131 :   void setNextRowEntryID(EntryID id) {
     113                 :   65480131 :     d_nextRow = id;
     114                 :   65480131 :   }
     115                 :   72963274 :   void setNextColEntryID(EntryID id) {
     116                 :   72963274 :     d_nextCol = id;
     117                 :   72963274 :   }
     118                 :   83088293 :   void setPrevRowEntryID(EntryID id) {
     119                 :   83088293 :     d_prevRow = id;
     120                 :   83088293 :   }
     121                 :   82418615 :   void setPrevColEntryID(EntryID id) {
     122                 :   82418615 :     d_prevCol = id;
     123                 :   82418615 :   }
     124                 :            : 
     125                 :  139748211 :   RowIndex getRowIndex() const{
     126                 :  139748211 :     return d_rowIndex;
     127                 :            :   }
     128                 :            : 
     129                 :  409517275 :   ArithVar getColVar() const{
     130                 :  409517275 :     return d_colVar;
     131                 :            :   }
     132                 :            : 
     133                 :  451905936 :   const T& getCoefficient() const {
     134                 :  451905936 :     return d_coefficient;
     135                 :            :   }
     136                 :            : 
     137                 :  114731986 :   T& getCoefficient(){
     138                 :  114731986 :     return d_coefficient;
     139                 :            :   }
     140                 :            : 
     141                 :            :   void setCoefficient(const T& t){
     142                 :            :     d_coefficient = t;
     143                 :            :   }
     144                 :            : 
     145                 :   41241407 :   void markBlank() {
     146                 :   41241407 :     d_rowIndex = ROW_INDEX_SENTINEL;
     147                 :   41241407 :     d_colVar = ARITHVAR_SENTINEL;
     148                 :   41241407 :   }
     149                 :            : 
     150                 :   41610019 :   bool blank() const{
     151 [ -  + ][ -  + ]:   41610019 :     Assert(unusedConsistent());
                 [ -  - ]
     152                 :            : 
     153                 :   41610019 :     return d_rowIndex == ROW_INDEX_SENTINEL;
     154                 :            :   }
     155                 :            : }; /* class MatrixEntry<T> */
     156                 :            : 
     157                 :            : template<class T>
     158                 :            : class MatrixEntryVector {
     159                 :            : private:
     160                 :            :   typedef MatrixEntry<T> EntryType;
     161                 :            :   typedef std::vector<EntryType> EntryArray;
     162                 :            : 
     163                 :            :   EntryArray d_entries;
     164                 :            :   std::queue<EntryID> d_freedEntries;
     165                 :            : 
     166                 :            :   uint32_t d_size;
     167                 :            : 
     168                 :            : public:
     169                 :     101814 :   MatrixEntryVector():
     170                 :     101814 :     d_entries(), d_freedEntries(), d_size(0)
     171                 :     101814 :   {}
     172                 :            : 
     173                 : 1135369419 :   const EntryType& operator[](EntryID id) const{
     174 [ -  + ][ -  + ]: 1135369419 :     Assert(inBounds(id));
                 [ -  - ]
     175                 : 1135369419 :     return d_entries[id];
     176                 :            :   }
     177                 :            : 
     178                 :  776332807 :   EntryType& get(EntryID id){
     179 [ -  + ][ -  + ]:  776332807 :     Assert(inBounds(id));
                 [ -  - ]
     180                 :  776332807 :     return d_entries[id];
     181                 :            :   }
     182                 :            : 
     183                 :   41241407 :   void freeEntry(EntryID id){
     184 [ -  + ][ -  + ]:   41241407 :     Assert(get(id).blank());
                 [ -  - ]
     185 [ -  + ][ -  + ]:   41241407 :     Assert(d_size > 0);
                 [ -  - ]
     186                 :            : 
     187                 :   41241407 :     d_freedEntries.push(id);
     188                 :   41241407 :     --d_size;
     189                 :   41241407 :   }
     190                 :            : 
     191                 :   42454406 :   EntryID newEntry(){
     192                 :            :     EntryID newId;
     193         [ +  + ]:   42454406 :     if(d_freedEntries.empty()){
     194                 :    1458906 :       newId = d_entries.size();
     195                 :    1458906 :       d_entries.push_back(MatrixEntry<T>());
     196                 :            :     }else{
     197                 :   40995500 :       newId = d_freedEntries.front();
     198                 :   40995500 :       d_freedEntries.pop();
     199                 :            :     }
     200                 :   42454406 :     ++d_size;
     201                 :   42454406 :     return newId;
     202                 :            :   }
     203                 :            : 
     204                 :            :   uint32_t size() const{ return d_size; }
     205                 :            :   uint32_t capacity() const{ return d_entries.capacity(); }
     206                 :            : 
     207                 :            : 
     208                 :            : private:
     209                 : 1911702226 :   bool inBounds(EntryID id) const{
     210                 : 1911702226 :     return id <  d_entries.size();
     211                 :            :   }
     212                 :            : }; /* class MatrixEntryVector<T> */
     213                 :            : 
     214                 :            : template <class T, bool isRow>
     215                 :            : class MatrixVector {
     216                 :            : private:
     217                 :            :   EntryID d_head;
     218                 :            :   uint32_t d_size;
     219                 :            : 
     220                 :            :   MatrixEntryVector<T>* d_entries;
     221                 :            : 
     222                 :            :   class Iterator {
     223                 :            :   private:
     224                 :            :     EntryID d_curr;
     225                 :            :     const MatrixEntryVector<T>* d_entries;
     226                 :            : 
     227                 :            :   public:
     228                 :   69817894 :     Iterator(EntryID start, const MatrixEntryVector<T>* entries) :
     229                 :   69817894 :       d_curr(start), d_entries(entries)
     230                 :   69817894 :     {}
     231                 :            : 
     232                 :            :   public:
     233                 :            : 
     234                 :  139220800 :     EntryID getID() const {
     235                 :  139220800 :       return d_curr;
     236                 :            :     }
     237                 :            : 
     238                 :  509705410 :     const MatrixEntry<T>& operator*() const{
     239 [ -  + ][ -  + ]:  509705410 :       Assert(!atEnd());
                 [ -  - ]
     240                 :  509705410 :       return (*d_entries)[d_curr];
     241                 :            :     }
     242                 :            : 
     243                 :  625295397 :     Iterator& operator++(){
     244 [ -  + ][ -  + ]:  625295397 :       Assert(!atEnd());
                 [ -  - ]
     245                 :  625295397 :       const MatrixEntry<T>& entry = (*d_entries)[d_curr];
     246                 :  625295397 :       d_curr = isRow ? entry.getNextRowEntryID() : entry.getNextColEntryID();
     247                 :  625295397 :       return *this;
     248                 :            :     }
     249                 :            : 
     250                 : 1577799378 :     bool atEnd() const {
     251                 : 1577799378 :       return d_curr == ENTRYID_SENTINEL;
     252                 :            :     }
     253                 :            : 
     254                 :            :     bool operator==(const Iterator& i) const{
     255                 :            :       return d_curr == i.d_curr && d_entries == i.d_entries;
     256                 :            :     }
     257                 :            : 
     258                 :  237810370 :     bool operator!=(const Iterator& i) const{
     259 [ +  + ][ -  + ]:  237810370 :       return !(d_curr == i.d_curr && d_entries == i.d_entries);
     260                 :            :     }
     261                 :            :   }; /* class MatrixVector<T, isRow>::Iterator */
     262                 :            : 
     263                 :            : public:
     264                 :     561829 :   MatrixVector(MatrixEntryVector<T>* mev)
     265                 :     561829 :     : d_head(ENTRYID_SENTINEL), d_size(0), d_entries(mev)
     266                 :     561829 :   {}
     267                 :            : 
     268                 :            :   MatrixVector(EntryID head, uint32_t size, MatrixEntryVector<T>* mev)
     269                 :            :     : d_head(head), d_size(size), d_entries(mev)
     270                 :            :   {}
     271                 :            : 
     272                 :            :   typedef Iterator const_iterator;
     273                 :   55313544 :   const_iterator begin() const {
     274                 :   55313544 :     return Iterator(d_head, d_entries);
     275                 :            :   }
     276                 :   14504350 :   const_iterator end() const {
     277                 :   14504350 :     return Iterator(ENTRYID_SENTINEL, d_entries);
     278                 :            :   }
     279                 :            : 
     280                 :            :   EntryID getHead() const { return d_head; }
     281                 :            : 
     282                 :  108855219 :   uint32_t getSize() const { return d_size; }
     283                 :            : 
     284                 :   84908812 :   void insert(EntryID newId){
     285                 :            :     if(isRow){
     286                 :   42454406 :       d_entries->get(newId).setNextRowEntryID(d_head);
     287                 :            : 
     288         [ +  + ]:   42454406 :       if(d_head != ENTRYID_SENTINEL){
     289                 :   42253201 :         d_entries->get(d_head).setPrevRowEntryID(newId);
     290                 :            :       }
     291                 :            :     }else{
     292                 :   42454406 :       d_entries->get(newId).setNextColEntryID(d_head);
     293                 :            : 
     294         [ +  + ]:   42454406 :       if(d_head != ENTRYID_SENTINEL){
     295                 :   42114457 :         d_entries->get(d_head).setPrevColEntryID(newId);
     296                 :            :       }
     297                 :            :     }
     298                 :            : 
     299                 :   84908812 :     d_head = newId;
     300                 :   84908812 :     ++d_size;
     301                 :   84908812 :   }
     302                 :   82482814 :   void remove(EntryID id){
     303 [ -  + ][ -  + ]:   82482814 :     Assert(d_size > 0);
                 [ -  - ]
     304                 :   82482814 :     --d_size;
     305                 :            :     if(isRow){
     306                 :   41241407 :       EntryID prevRow = d_entries->get(id).getPrevRowEntryID();
     307                 :   41241407 :       EntryID nextRow = d_entries->get(id).getNextRowEntryID();
     308                 :            : 
     309         [ +  + ]:   41241407 :       if(d_head == id){
     310                 :   18215682 :         d_head = nextRow;
     311                 :            :       }
     312         [ +  + ]:   41241407 :       if(prevRow != ENTRYID_SENTINEL){
     313                 :   23025725 :         d_entries->get(prevRow).setNextRowEntryID(nextRow);
     314                 :            :       }
     315         [ +  + ]:   41241407 :       if(nextRow != ENTRYID_SENTINEL){
     316                 :   40835092 :         d_entries->get(nextRow).setPrevRowEntryID(prevRow);
     317                 :            :       }
     318                 :            :     }else{
     319                 :   41241407 :       EntryID prevCol = d_entries->get(id).getPrevColEntryID();
     320                 :   41241407 :       EntryID nextCol = d_entries->get(id).getNextColEntryID();
     321                 :            : 
     322         [ +  + ]:   41241407 :       if(d_head == id){
     323                 :   10732539 :         d_head = nextCol;
     324                 :            :       }
     325                 :            : 
     326         [ +  + ]:   41241407 :       if(prevCol != ENTRYID_SENTINEL){
     327                 :   30508868 :         d_entries->get(prevCol).setNextColEntryID(nextCol);
     328                 :            :       }
     329         [ +  + ]:   41241407 :       if(nextCol != ENTRYID_SENTINEL){
     330                 :   40304158 :         d_entries->get(nextCol).setPrevColEntryID(prevCol);
     331                 :            :       }
     332                 :            :     }
     333                 :   82482814 :   }
     334                 :            : }; /* class MatrixVector<T, isRow> */
     335                 :            : 
     336                 :            : template <class T>
     337                 :            :   class RowVector : public MatrixVector<T, true>
     338                 :            : {
     339                 :            : private:
     340                 :            :   typedef MatrixVector<T, true> SuperT;
     341                 :            : public:
     342                 :            :   typedef typename SuperT::const_iterator const_iterator;
     343                 :            : 
     344                 :     197280 :   RowVector(MatrixEntryVector<T>* mev) : SuperT(mev){}
     345                 :            :   RowVector(EntryID head, uint32_t size, MatrixEntryVector<T>* mev)
     346                 :            :     : SuperT(head, size, mev){}
     347                 :            : };/* class RowVector<T> */
     348                 :            : 
     349                 :            : template <class T>
     350                 :            :   class ColumnVector : public MatrixVector<T, false>
     351                 :            : {
     352                 :            : private:
     353                 :            :   typedef MatrixVector<T, false> SuperT;
     354                 :            : public:
     355                 :            :   typedef typename SuperT::const_iterator const_iterator;
     356                 :            : 
     357                 :     364549 :   ColumnVector(MatrixEntryVector<T>* mev) : SuperT(mev){}
     358                 :            :   ColumnVector(EntryID head, uint32_t size, MatrixEntryVector<T>* mev)
     359                 :            :     : SuperT(head, size, mev){}
     360                 :            : };/* class ColumnVector<T> */
     361                 :            : 
     362                 :            : template <class T>
     363                 :            : class Matrix {
     364                 :            : public:
     365                 :            :   typedef MatrixEntry<T> Entry;
     366                 :            : 
     367                 :            : protected:
     368                 :            :  typedef RowVector<T> RowVectorT;
     369                 :            :  typedef ColumnVector<T> ColumnVectorT;
     370                 :            : 
     371                 :            : public:
     372                 :            :   typedef typename RowVectorT::const_iterator RowIterator;
     373                 :            :   typedef typename ColumnVectorT::const_iterator ColIterator;
     374                 :            : 
     375                 :            : protected:
     376                 :            :   // RowTable : RowID |-> RowVector
     377                 :            :   typedef std::vector< RowVectorT > RowTable;
     378                 :            :   RowTable d_rows;
     379                 :            : 
     380                 :            :   // ColumnTable : ArithVar |-> ColumnVector
     381                 :            :   typedef std::vector< ColumnVectorT > ColumnTable;
     382                 :            :   ColumnTable d_columns;
     383                 :            : 
     384                 :            :   /* The merge buffer is used to store a row in order to optimize row addition. */
     385                 :            :   typedef std::pair<EntryID, bool> PosUsedPair;
     386                 :            :   typedef DenseMap< PosUsedPair > RowToPosUsedPairMap;
     387                 :            :   RowToPosUsedPairMap d_mergeBuffer;
     388                 :            : 
     389                 :            :   /* The row that is in the merge buffer. */
     390                 :            :   RowIndex d_rowInMergeBuffer;
     391                 :            : 
     392                 :            :   uint32_t d_entriesInUse;
     393                 :            :   MatrixEntryVector<T> d_entries;
     394                 :            : 
     395                 :            :   std::vector<RowIndex> d_pool;
     396                 :            : 
     397                 :            :   T d_zero;
     398                 :            : 
     399                 :            : public:
     400                 :            :   /**
     401                 :            :    * Constructs an empty Matrix.
     402                 :            :    */
     403                 :          0 :   Matrix()
     404                 :          0 :   : d_rows(),
     405                 :          0 :     d_columns(),
     406                 :          0 :     d_mergeBuffer(),
     407                 :          0 :     d_rowInMergeBuffer(ROW_INDEX_SENTINEL),
     408                 :          0 :     d_entriesInUse(0),
     409                 :          0 :     d_entries(),
     410                 :          0 :     d_zero(0)
     411                 :          0 :   {}
     412                 :            : 
     413                 :     101814 :   Matrix(const T& zero)
     414                 :     101814 :   : d_rows(),
     415                 :     101814 :     d_columns(),
     416                 :     101814 :     d_mergeBuffer(),
     417                 :     101814 :     d_rowInMergeBuffer(ROW_INDEX_SENTINEL),
     418                 :     101814 :     d_entriesInUse(0),
     419                 :     101814 :     d_entries(),
     420                 :     101814 :     d_zero(zero)
     421                 :     101814 :   {}
     422                 :            : 
     423                 :            :   Matrix(const Matrix& m)
     424                 :            :   : d_rows(),
     425                 :            :     d_columns(),
     426                 :            :     d_mergeBuffer(m.d_mergeBuffer),
     427                 :            :     d_rowInMergeBuffer(m.d_rowInMergeBuffer),
     428                 :            :     d_entriesInUse(m.d_entriesInUse),
     429                 :            :     d_entries(m.d_entries),
     430                 :            :     d_zero(m.d_zero)
     431                 :            :   {
     432                 :            :     d_columns.clear();
     433                 :            :     for(typename ColumnTable::const_iterator c=m.d_columns.begin(), cend = m.d_columns.end(); c!=cend; ++c){
     434                 :            :       const ColumnVectorT& col = *c;
     435                 :            :       d_columns.push_back(ColumnVectorT(col.getHead(),col.getSize(),&d_entries));
     436                 :            :     }
     437                 :            :     d_rows.clear();
     438                 :            :     for(typename RowTable::const_iterator r=m.d_rows.begin(), rend = m.d_rows.end(); r!=rend; ++r){
     439                 :            :       const RowVectorT& row = *r;
     440                 :            :       d_rows.push_back(RowVectorT(row.getHead(),row.getSize(),&d_entries));
     441                 :            :     }
     442                 :            :   }
     443                 :            : 
     444                 :            :   Matrix& operator=(const Matrix& m){
     445                 :            :     d_mergeBuffer = (m.d_mergeBuffer);
     446                 :            :     d_rowInMergeBuffer = (m.d_rowInMergeBuffer);
     447                 :            :     d_entriesInUse = (m.d_entriesInUse);
     448                 :            :     d_entries = (m.d_entries);
     449                 :            :     d_zero = (m.d_zero);
     450                 :            :     d_columns.clear();
     451                 :            :     for(typename ColumnTable::const_iterator c=m.d_columns.begin(), cend = m.d_columns.end(); c!=cend; ++c){
     452                 :            :       const ColumnVector<T>& col = *c;
     453                 :            :       d_columns.push_back(ColumnVector<T>(col.getHead(), col.getSize(), &d_entries));
     454                 :            :     }
     455                 :            :     d_rows.clear();
     456                 :            :     for(typename RowTable::const_iterator r=m.d_rows.begin(), rend = m.d_rows.end(); r!=rend; ++r){
     457                 :            :       const RowVector<T>& row = *r;
     458                 :            :       d_rows.push_back(RowVector<T>(row.getHead(), row.getSize(), &d_entries));
     459                 :            :     }
     460                 :            :     return *this;
     461                 :            :   }
     462                 :            : 
     463                 :            : protected:
     464                 :            : 
     465                 :   42454406 :   void addEntry(RowIndex row, ArithVar col, const T& coeff){
     466         [ +  - ]:   42454406 :     Trace("tableau") << "addEntry(" << row << "," << col <<"," << coeff << ")" << std::endl;
     467                 :            : 
     468 [ -  + ][ -  + ]:   42454406 :     Assert(coeff != 0);
                 [ -  - ]
     469 [ -  + ][ -  + ]:   42454406 :     Assert(row < d_rows.size());
                 [ -  - ]
     470 [ -  + ][ -  + ]:   42454406 :     Assert(col < d_columns.size());
                 [ -  - ]
     471                 :            : 
     472                 :   42454406 :     EntryID newId = d_entries.newEntry();
     473                 :   42454406 :     Entry& newEntry = d_entries.get(newId);
     474                 :   42454406 :     newEntry = Entry(row, col, coeff);
     475                 :            : 
     476 [ -  + ][ -  + ]:   42454406 :     Assert(newEntry.getCoefficient() != 0);
                 [ -  - ]
     477                 :            : 
     478                 :   42454406 :     ++d_entriesInUse;
     479                 :            : 
     480                 :   42454406 :     d_rows[row].insert(newId);
     481                 :   42454406 :     d_columns[col].insert(newId);
     482                 :   42454406 :   }
     483                 :            : 
     484                 :   41241407 :   void removeEntry(EntryID id){
     485 [ -  + ][ -  + ]:   41241407 :     Assert(d_entriesInUse > 0);
                 [ -  - ]
     486                 :   41241407 :     --d_entriesInUse;
     487                 :            : 
     488                 :   41241407 :     Entry& entry = d_entries.get(id);
     489                 :            : 
     490                 :   41241407 :     RowIndex ridx = entry.getRowIndex();
     491                 :   41241407 :     ArithVar col = entry.getColVar();
     492                 :            : 
     493 [ -  + ][ -  + ]:   41241407 :     Assert(d_rows[ridx].getSize() > 0);
                 [ -  - ]
     494 [ -  + ][ -  + ]:   41241407 :     Assert(d_columns[col].getSize() > 0);
                 [ -  - ]
     495                 :            : 
     496                 :   41241407 :     d_rows[ridx].remove(id);
     497                 :   41241407 :     d_columns[col].remove(id);
     498                 :            : 
     499                 :   41241407 :     entry.markBlank();
     500                 :            : 
     501                 :   41241407 :     d_entries.freeEntry(id);
     502                 :   41241407 :   }
     503                 :            : 
     504                 :            :  private:
     505                 :     201205 :   RowIndex requestRowIndex(){
     506         [ +  + ]:     201205 :     if(d_pool.empty()){
     507                 :     197280 :       RowIndex ridx = d_rows.size();
     508                 :     197280 :       d_rows.push_back(RowVectorT(&d_entries));
     509                 :     197280 :       return ridx;
     510                 :            :     }else{
     511                 :       3925 :       RowIndex rid = d_pool.back();
     512                 :       3925 :       d_pool.pop_back();
     513                 :       3925 :       return rid;
     514                 :            :     }
     515                 :            :   }
     516                 :            : 
     517                 :       3943 :   void releaseRowIndex(RowIndex rid){
     518                 :       3943 :     d_pool.push_back(rid);
     519                 :       3943 :   }
     520                 :            : 
     521                 :            : public:
     522                 :            : 
     523                 :            :   size_t getNumRows() const {
     524                 :            :     return d_rows.size();
     525                 :            :   }
     526                 :            : 
     527                 :     656052 :   size_t getNumColumns() const {
     528                 :     656052 :     return d_columns.size();
     529                 :            :   }
     530                 :            : 
     531                 :     364549 :   void increaseSize(){
     532                 :     364549 :     d_columns.push_back(ColumnVector<T>(&d_entries));
     533                 :     364549 :   }
     534                 :            : 
     535                 :          0 :   void increaseSizeTo(size_t s){
     536         [ -  - ]:          0 :     while(getNumColumns() < s){
     537                 :          0 :       increaseSize();
     538                 :            :     }
     539                 :          0 :   }
     540                 :            : 
     541                 :   76316302 :   const RowVector<T>& getRow(RowIndex r) const {
     542 [ -  + ][ -  + ]:   76316302 :     Assert(r < d_rows.size());
                 [ -  - ]
     543                 :   76316302 :     return d_rows[r];
     544                 :            :   }
     545                 :            : 
     546                 :   18390863 :   const ColumnVector<T>& getColumn(ArithVar v) const {
     547 [ -  + ][ -  + ]:   18390863 :     Assert(v < d_columns.size());
                 [ -  - ]
     548                 :   18390863 :     return d_columns[v];
     549                 :            :   }
     550                 :            : 
     551                 :   21649871 :   uint32_t getRowLength(RowIndex r) const{
     552                 :   21649871 :     return getRow(r).getSize();
     553                 :            :   }
     554                 :            : 
     555                 :    4722534 :   uint32_t getColLength(ArithVar x) const{
     556                 :    4722534 :     return getColumn(x).getSize();
     557                 :            :   }
     558                 :            : 
     559                 :            :   /**
     560                 :            :    * Adds a row to the matrix.
     561                 :            :    * The new row is equivalent to:
     562                 :            :    *   \f$\sum_i\f$ coeffs[i] * variables[i]
     563                 :            :    */
     564                 :     201205 :   RowIndex addRow(const std::vector<T>& coeffs,
     565                 :            :                   const std::vector<ArithVar>& variables){
     566                 :            : 
     567                 :     201205 :     RowIndex ridx = requestRowIndex();
     568                 :            : 
     569                 :            :     //RowIndex ridx = d_rows.size();
     570                 :            :     //d_rows.push_back(RowVectorT(&d_entries));
     571                 :            : 
     572                 :     201205 :     typename std::vector<T>::const_iterator coeffIter = coeffs.begin();
     573                 :     201205 :     std::vector<ArithVar>::const_iterator varsIter = variables.begin();
     574                 :     201205 :     std::vector<ArithVar>::const_iterator varsEnd = variables.end();
     575                 :            : 
     576         [ +  + ]:     656052 :     for(; varsIter != varsEnd; ++coeffIter, ++varsIter){
     577                 :     454847 :       const T& coeff = *coeffIter;
     578                 :     454847 :       ArithVar var_i = *varsIter;
     579 [ -  + ][ -  + ]:     454847 :       Assert(var_i < getNumColumns());
                 [ -  - ]
     580                 :     454847 :       addEntry(ridx, var_i, coeff);
     581                 :            :     }
     582                 :            : 
     583                 :     201205 :     return ridx;
     584                 :            :   }
     585                 :            : 
     586                 :            : 
     587                 :     496828 :   void loadRowIntoBuffer(RowIndex rid){
     588 [ -  + ][ -  + ]:     496828 :     Assert(d_mergeBuffer.empty());
                 [ -  - ]
     589 [ -  + ][ -  + ]:     496828 :     Assert(d_rowInMergeBuffer == ROW_INDEX_SENTINEL);
                 [ -  - ]
     590                 :            : 
     591                 :     496828 :     RowIterator i = getRow(rid).begin(), i_end = getRow(rid).end();
     592         [ +  + ]:    9156045 :     for(; i != i_end; ++i){
     593                 :    8659217 :       EntryID id = i.getID();
     594                 :    8659217 :       const MatrixEntry<T>& entry = *i;
     595                 :    8659217 :       ArithVar colVar = entry.getColVar();
     596                 :    8659217 :       d_mergeBuffer.set(colVar, std::make_pair(id, false));
     597                 :            :     }
     598                 :            : 
     599                 :     496828 :     d_rowInMergeBuffer = rid;
     600                 :     496828 :   }
     601                 :            : 
     602                 :     496828 :   void clearBuffer() {
     603 [ -  + ][ -  + ]:     496828 :     Assert(d_rowInMergeBuffer != ROW_INDEX_SENTINEL);
                 [ -  - ]
     604                 :            : 
     605                 :     496828 :     d_rowInMergeBuffer = ROW_INDEX_SENTINEL;
     606                 :     496828 :     d_mergeBuffer.purge();
     607                 :     496828 :   }
     608                 :            : 
     609                 :            :   /* to *= mult */
     610                 :          0 :   void multiplyRowByConstant(RowIndex to, const T& mult){
     611                 :          0 :     RowIterator i = getRow(to).begin();
     612                 :          0 :     RowIterator i_end = getRow(to).end();
     613         [ -  - ]:          0 :     for( ; i != i_end; ++i){
     614                 :          0 :       EntryID id = i.getID();
     615                 :          0 :       Entry& entry = d_entries.get(id);
     616                 :          0 :       T& coeff = entry.getCoefficient();
     617                 :          0 :       coeff *= mult;
     618                 :            :     }
     619                 :          0 :   }
     620                 :            : 
     621                 :            :   /**  to += mult * from.
     622                 :            :    * Use the more efficient rowPlusBufferTimesConstant() for
     623                 :            :    * repeated use.
     624                 :            :    */
     625                 :          0 :   void rowPlusRowTimesConstant(RowIndex to, RowIndex from, const T& mult){
     626                 :          0 :     Assert(to != from);
     627                 :          0 :     loadRowIntoBuffer(from);
     628                 :          0 :     rowPlusBufferTimesConstant(to, mult);
     629                 :          0 :     clearBuffer();
     630                 :          0 :   }
     631                 :            : 
     632                 :            :   /**  to += mult * buffer.
     633                 :            :    * Invalidates coefficients on the row.
     634                 :            :    * (mult should never be a direct copy of a coefficient!)
     635                 :            :    */
     636                 :          0 :   void rowPlusBufferTimesConstant(RowIndex to, const T& mult){
     637                 :          0 :     Assert(d_rowInMergeBuffer != ROW_INDEX_SENTINEL);
     638                 :          0 :     Assert(to != ROW_INDEX_SENTINEL);
     639                 :            : 
     640         [ -  - ]:          0 :     Trace("tableau") << "rowPlusRowTimesConstant("
     641                 :          0 :                      << to << "," << mult << "," << d_rowInMergeBuffer << ")"
     642                 :          0 :                      << std::endl;
     643                 :            : 
     644                 :          0 :     Assert(debugNoZeroCoefficients(to));
     645                 :          0 :     Assert(debugNoZeroCoefficients(d_rowInMergeBuffer));
     646                 :            : 
     647                 :          0 :     Assert(mult != 0);
     648                 :            : 
     649                 :          0 :     RowIterator i = getRow(to).begin();
     650                 :          0 :     RowIterator i_end = getRow(to).end();
     651         [ -  - ]:          0 :     while(i != i_end){
     652                 :          0 :       EntryID id = i.getID();
     653                 :          0 :       Entry& entry = d_entries.get(id);
     654                 :          0 :       ArithVar colVar = entry.getColVar();
     655                 :            : 
     656                 :          0 :       ++i;
     657                 :            : 
     658         [ -  - ]:          0 :       if(d_mergeBuffer.isKey(colVar)){
     659                 :          0 :         EntryID bufferEntry = d_mergeBuffer[colVar].first;
     660                 :          0 :         Assert(!d_mergeBuffer[colVar].second);
     661                 :          0 :         d_mergeBuffer.get(colVar).second = true;
     662                 :            : 
     663                 :          0 :         const Entry& other = d_entries.get(bufferEntry);
     664                 :          0 :         T& coeff = entry.getCoefficient();
     665                 :          0 :         coeff += mult * other.getCoefficient();
     666                 :            : 
     667         [ -  - ]:          0 :         if(coeff.sgn() == 0){
     668                 :          0 :           removeEntry(id);
     669                 :            :         }
     670                 :            :       }
     671                 :            :     }
     672                 :            : 
     673                 :          0 :     i = getRow(d_rowInMergeBuffer).begin();
     674                 :          0 :     i_end = getRow(d_rowInMergeBuffer).end();
     675                 :            : 
     676         [ -  - ]:          0 :     for(; i != i_end; ++i){
     677                 :          0 :       const Entry& entry = *i;
     678                 :          0 :       ArithVar colVar = entry.getColVar();
     679                 :            : 
     680         [ -  - ]:          0 :       if(d_mergeBuffer[colVar].second){
     681                 :          0 :         d_mergeBuffer.get(colVar).second = false;
     682                 :            :       }else{
     683                 :          0 :         Assert(!(d_mergeBuffer[colVar]).second);
     684                 :          0 :         T newCoeff =  mult * entry.getCoefficient();
     685                 :          0 :         addEntry(to, colVar, newCoeff);
     686                 :          0 :       }
     687                 :            :     }
     688                 :            : 
     689                 :          0 :     Assert(mergeBufferIsClear());
     690                 :            : 
     691         [ -  - ]:          0 :     if(TraceIsOn("matrix")) { printMatrix(); }
     692                 :          0 :   }
     693                 :            : 
     694                 :            :   /**  to += mult * buffer. */
     695                 :    6631006 :   void rowPlusBufferTimesConstant(RowIndex to, const T& mult, CoefficientChangeCallback& cb){
     696 [ -  + ][ -  + ]:    6631006 :     Assert(d_rowInMergeBuffer != ROW_INDEX_SENTINEL);
                 [ -  - ]
     697 [ -  + ][ -  + ]:    6631006 :     Assert(to != ROW_INDEX_SENTINEL);
                 [ -  - ]
     698                 :            : 
     699         [ +  - ]:    6631006 :     Trace("tableau") << "rowPlusRowTimesConstant("
     700                 :          0 :                      << to << "," << mult << "," << d_rowInMergeBuffer << ")"
     701                 :          0 :                      << std::endl;
     702                 :            : 
     703 [ -  + ][ -  + ]:    6631006 :     Assert(debugNoZeroCoefficients(to));
                 [ -  - ]
     704 [ -  + ][ -  + ]:    6631006 :     Assert(debugNoZeroCoefficients(d_rowInMergeBuffer));
                 [ -  - ]
     705                 :            : 
     706 [ -  + ][ -  + ]:    6631006 :     Assert(mult != 0);
                 [ -  - ]
     707                 :            : 
     708                 :    6631006 :     RowIterator i = getRow(to).begin();
     709                 :    6631006 :     RowIterator i_end = getRow(to).end();
     710         [ +  + ]:  116464460 :     while(i != i_end){
     711                 :  109833454 :       EntryID id = i.getID();
     712                 :  109833454 :       Entry& entry = d_entries.get(id);
     713                 :  109833454 :       ArithVar colVar = entry.getColVar();
     714                 :            : 
     715                 :  109833454 :       ++i;
     716                 :            : 
     717         [ +  + ]:  109833454 :       if(d_mergeBuffer.isKey(colVar)){
     718                 :   57653352 :         EntryID bufferEntry = d_mergeBuffer[colVar].first;
     719 [ -  + ][ -  + ]:   57653352 :         Assert(!d_mergeBuffer[colVar].second);
                 [ -  - ]
     720                 :   57653352 :         d_mergeBuffer.get(colVar).second = true;
     721                 :            : 
     722                 :   57653352 :         const Entry& other = d_entries.get(bufferEntry);
     723                 :   57653352 :         T& coeff = entry.getCoefficient();
     724                 :   57653352 :         int coeffOldSgn = coeff.sgn();
     725                 :   57653352 :         coeff += mult * other.getCoefficient();
     726                 :   57653352 :         int coeffNewSgn = coeff.sgn();
     727                 :            : 
     728         [ +  + ]:   57653352 :         if(coeffOldSgn != coeffNewSgn){
     729                 :   46795068 :           cb.update(to, colVar, coeffOldSgn,  coeffNewSgn);
     730                 :            : 
     731         [ +  + ]:   46795068 :           if(coeffNewSgn == 0){
     732                 :   41221901 :             removeEntry(id);
     733                 :            :           }
     734                 :            :         }
     735                 :            :       }
     736                 :            :     }
     737                 :            : 
     738                 :    6631006 :     i = getRow(d_rowInMergeBuffer).begin();
     739                 :    6631006 :     i_end = getRow(d_rowInMergeBuffer).end();
     740                 :            : 
     741         [ +  + ]:  106077678 :     for(; i != i_end; ++i){
     742                 :   99446672 :       const Entry& entry = *i;
     743                 :   99446672 :       ArithVar colVar = entry.getColVar();
     744                 :            : 
     745         [ +  + ]:   99446672 :       if(d_mergeBuffer[colVar].second){
     746                 :   57653352 :         d_mergeBuffer.get(colVar).second = false;
     747                 :            :       }else{
     748 [ -  + ][ -  + ]:   41793320 :         Assert(!(d_mergeBuffer[colVar]).second);
                 [ -  - ]
     749                 :   41793320 :         T newCoeff =  mult * entry.getCoefficient();
     750                 :   41793320 :         addEntry(to, colVar, newCoeff);
     751                 :            : 
     752                 :   41793320 :         cb.update(to, colVar, 0,  newCoeff.sgn());
     753                 :   41793320 :       }
     754                 :            :     }
     755                 :            : 
     756 [ -  + ][ -  + ]:    6631006 :     Assert(mergeBufferIsClear());
                 [ -  - ]
     757                 :            : 
     758         [ -  + ]:    6631006 :     if(TraceIsOn("matrix")) { printMatrix(); }
     759                 :    6631006 :   }
     760                 :            : 
     761                 :    6631006 :   bool mergeBufferIsClear() const{
     762                 :    6631006 :     RowToPosUsedPairMap::const_iterator i = d_mergeBuffer.begin();
     763                 :    6631006 :     RowToPosUsedPairMap::const_iterator i_end = d_mergeBuffer.end();
     764         [ +  + ]:  106077678 :     for(; i != i_end; ++i){
     765                 :   99446672 :       RowIndex rid = *i;
     766         [ -  + ]:   99446672 :       if(d_mergeBuffer[rid].second){
     767                 :          0 :         return false;
     768                 :            :       }
     769                 :            :     }
     770                 :    6631006 :     return true;
     771                 :            :   }
     772                 :            : 
     773                 :            : protected:
     774                 :            : 
     775                 :     553758 :   EntryID findOnRow(RowIndex rid, ArithVar column) const {
     776                 :     553758 :     RowIterator i = d_rows[rid].begin(), i_end = d_rows[rid].end();
     777         [ +  + ]:    5588338 :     for(; i != i_end; ++i){
     778                 :    5588253 :       EntryID id = i.getID();
     779                 :    5588253 :       const MatrixEntry<T>& entry = *i;
     780                 :    5588253 :       ArithVar colVar = entry.getColVar();
     781                 :            : 
     782         [ +  + ]:    5588253 :       if(colVar == column){
     783                 :     553673 :         return id;
     784                 :            :       }
     785                 :            :     }
     786                 :         85 :     return ENTRYID_SENTINEL;
     787                 :            :   }
     788                 :            : 
     789                 :     187809 :   EntryID findOnCol(RowIndex rid, ArithVar column) const{
     790                 :     187809 :     ColIterator i = d_columns[column].begin(), i_end = d_columns[column].end();
     791         [ +  + ]:     503744 :     for(; i != i_end; ++i){
     792                 :     503709 :       EntryID id = i.getID();
     793                 :     503709 :       const MatrixEntry<T>& entry = *i;
     794                 :     503709 :       RowIndex currRow = entry.getRowIndex();
     795                 :            : 
     796         [ +  + ]:     503709 :       if(currRow == rid){
     797                 :     187774 :         return id;
     798                 :            :       }
     799                 :            :     }
     800                 :         35 :     return ENTRYID_SENTINEL;
     801                 :            :   }
     802                 :            : 
     803                 :     372955 :   EntryID findEntryID(RowIndex rid, ArithVar col) const{
     804                 :     372955 :     bool colIsShorter = getColLength(col) < getRowLength(rid);
     805         [ +  + ]:     372955 :     EntryID id = colIsShorter ? findOnCol(rid, col) : findOnRow(rid,col);
     806                 :     372955 :     return id;
     807                 :            :   }
     808                 :            :   MatrixEntry<T> d_failedFind;
     809                 :            : public:
     810                 :            : 
     811                 :            :   /** If the find fails, isUnused is true on the entry. */
     812                 :     368612 :   const MatrixEntry<T>& findEntry(RowIndex rid, ArithVar col) const{
     813                 :     368612 :     EntryID id = findEntryID(rid, col);
     814         [ -  + ]:     368612 :     if(id == ENTRYID_SENTINEL){
     815                 :          0 :       return d_failedFind;
     816                 :            :     }else{
     817                 :     368612 :       return d_entries[id];
     818                 :            :     }
     819                 :            :   }
     820                 :            : 
     821                 :            :   /**
     822                 :            :    * Prints the contents of the Matrix to Trace("matrix")
     823                 :            :    */
     824                 :          0 :   void printMatrix(std::ostream& out) const {
     825                 :          0 :     out << "Matrix::printMatrix"  << std::endl;
     826                 :            : 
     827         [ -  - ]:          0 :     for(RowIndex i = 0, N = d_rows.size(); i < N; ++i){
     828                 :          0 :       printRow(i, out);
     829                 :            :     }
     830                 :          0 :   }
     831                 :          0 :   void printMatrix() const {
     832         [ -  - ]:          0 :     printMatrix(Trace("matrix"));
     833                 :          0 :   }
     834                 :            : 
     835                 :          0 :   void printRow(RowIndex rid, std::ostream& out) const {
     836                 :          0 :     out << "{" << rid << ":";
     837                 :          0 :     const RowVector<T>& row = getRow(rid);
     838                 :          0 :     RowIterator i = row.begin();
     839                 :          0 :     RowIterator i_end = row.end();
     840         [ -  - ]:          0 :     for(; i != i_end; ++i){
     841                 :          0 :       printEntry(*i, out);
     842                 :          0 :       out << ",";
     843                 :            :     }
     844                 :          0 :     out << "}" << std::endl;
     845                 :          0 :   }
     846                 :            :   void printRow(RowIndex rid) const {
     847                 :            :     printRow(rid, Trace("matrix"));
     848                 :            :   }
     849                 :            : 
     850                 :          0 :   void printEntry(const MatrixEntry<T>& entry, std::ostream& out) const {
     851                 :          0 :     out << entry.getColVar() << "*" << entry.getCoefficient();
     852                 :          0 :   }
     853                 :            :   void printEntry(const MatrixEntry<T>& entry) const {
     854                 :            :     printEntry(entry, Trace("matrix"));
     855                 :            :   }
     856                 :            : public:
     857                 :      50346 :   uint32_t size() const {
     858                 :      50346 :     return d_entriesInUse;
     859                 :            :   }
     860                 :            :   uint32_t getNumEntriesInTableau() const {
     861                 :            :     return d_entries.size();
     862                 :            :   }
     863                 :            :   uint32_t getEntryCapacity() const {
     864                 :            :     return d_entries.capacity();
     865                 :            :   }
     866                 :            : 
     867                 :       4343 :   void manipulateRowEntry(RowIndex row, ArithVar col, const T& c, CoefficientChangeCallback& cb){
     868                 :            :     int coeffOldSgn;
     869                 :            :     int coeffNewSgn;
     870                 :            : 
     871                 :       4343 :     EntryID id = findEntryID(row, col);
     872         [ +  + ]:       4343 :     if(id == ENTRYID_SENTINEL){
     873                 :        120 :       coeffOldSgn = 0;
     874                 :        120 :       addEntry(row, col, c);
     875                 :        120 :       coeffNewSgn = c.sgn();
     876                 :            :     }else{
     877                 :       4223 :       Entry& e = d_entries.get(id);
     878                 :       4223 :       T& t = e.getCoefficient();
     879                 :       4223 :       coeffOldSgn = t.sgn();
     880                 :       4223 :       t += c;
     881                 :       4223 :       coeffNewSgn = t.sgn();
     882                 :            :     }
     883                 :            : 
     884         [ +  + ]:       4343 :     if(coeffOldSgn != coeffNewSgn){
     885                 :       3507 :       cb.update(row, col, coeffOldSgn,  coeffNewSgn);
     886                 :            :     }
     887         [ +  + ]:       4343 :     if(coeffNewSgn == 0){
     888                 :       3344 :       removeEntry(id);
     889                 :            :     }
     890                 :       4343 :   }
     891                 :            : 
     892                 :       3943 :   void removeRow(RowIndex rid){
     893                 :       3943 :     RowIterator i = getRow(rid).begin();
     894                 :       3943 :     RowIterator i_end = getRow(rid).end();
     895         [ +  + ]:      20105 :     for(; i != i_end; ++i){
     896                 :      16162 :       EntryID id = i.getID();
     897                 :      16162 :       removeEntry(id);
     898                 :            :     }
     899                 :       3943 :     releaseRowIndex(rid);
     900                 :       3943 :   }
     901                 :            : 
     902                 :            :   double densityMeasure() const{
     903                 :            :     Assert(numNonZeroEntriesByRow() == numNonZeroEntries());
     904                 :            :     Assert(numNonZeroEntriesByCol() == numNonZeroEntries());
     905                 :            : 
     906                 :            :     uint32_t n = getNumRows();
     907                 :            :     if(n == 0){
     908                 :            :       return 1.0;
     909                 :            :     }else {
     910                 :            :       uint32_t s = numNonZeroEntries();
     911                 :            :       uint32_t m = d_columns.size();
     912                 :            :       uint32_t divisor = (n *(m - n + 1));
     913                 :            : 
     914                 :            :       Assert(n >= 1);
     915                 :            :       Assert(m >= n);
     916                 :            :       Assert(divisor > 0);
     917                 :            :       Assert(divisor >= s);
     918                 :            : 
     919                 :            :       return (double(s)) / divisor;
     920                 :            :     }
     921                 :            :   }
     922                 :            : 
     923                 :            :   void loadSignQueries(RowIndex rid, DenseMap<int>& target) const{
     924                 :            : 
     925                 :            :     RowIterator i = getRow(rid).begin(), i_end = getRow(rid).end();
     926                 :            :     for(; i != i_end; ++i){
     927                 :            :       const MatrixEntry<T>& entry = *i;
     928                 :            :       target.set(entry.getColVar(), entry.getCoefficient().sgn());
     929                 :            :     }
     930                 :            :   }
     931                 :            : 
     932                 :            : protected:
     933                 :            :   uint32_t numNonZeroEntries() const { return size(); }
     934                 :            : 
     935                 :            :   uint32_t numNonZeroEntriesByRow() const {
     936                 :            :     uint32_t rowSum = 0;
     937                 :            :     for(RowIndex rid = 0, N = d_rows.size(); rid < N; ++rid){
     938                 :            :       rowSum += getRowLength(rid);
     939                 :            :     }
     940                 :            :     return rowSum;
     941                 :            :   }
     942                 :            : 
     943                 :            :   uint32_t numNonZeroEntriesByCol() const {
     944                 :            :     uint32_t colSum = 0;
     945                 :            :     for(ArithVar v = 0, N = d_columns.size(); v < N; ++v){
     946                 :            :       colSum += getColLength(v);
     947                 :            :     }
     948                 :            :     return colSum;
     949                 :            :   }
     950                 :            : 
     951                 :            : 
     952                 :   13463217 :   bool debugNoZeroCoefficients(RowIndex ridx){
     953         [ +  + ]:  223752837 :     for(RowIterator i=getRow(ridx).begin(); !i.atEnd(); ++i){
     954                 :  210289620 :       const Entry& entry = *i;
     955         [ -  + ]:  210289620 :       if(entry.getCoefficient() == 0){
     956                 :          0 :         return false;
     957                 :            :       }
     958                 :            :     }
     959                 :   13463217 :     return true;
     960                 :            :   }
     961                 :     201205 :   bool debugMatchingCountsForRow(RowIndex ridx){
     962         [ +  + ]:    1210699 :     for(RowIterator i=getRow(ridx).begin(); !i.atEnd(); ++i){
     963                 :    1009494 :       const Entry& entry = *i;
     964                 :    1009494 :       ArithVar colVar = entry.getColVar();
     965                 :    1009494 :       uint32_t count = debugCountColLength(colVar);
     966         [ +  - ]:    2018988 :       Trace("tableau") << "debugMatchingCountsForRow "
     967                 :          0 :                        << ridx << ":" << colVar << " " << count
     968                 :    1009494 :                        <<" "<< getColLength(colVar) << std::endl;
     969         [ -  + ]:    1009494 :       if( count != getColLength(colVar) ){
     970                 :          0 :         return false;
     971                 :            :       }
     972                 :            :     }
     973                 :     201205 :     return true;
     974                 :            :   }
     975                 :            : 
     976                 :    1009494 :   uint32_t debugCountColLength(ArithVar var){
     977         [ +  - ]:    1009494 :     Trace("tableau") << var << " ";
     978                 :    1009494 :     uint32_t count = 0;
     979         [ +  + ]:   24670062 :     for(ColIterator i=getColumn(var).begin(); !i.atEnd(); ++i){
     980                 :   23660568 :       const Entry& entry = *i;
     981         [ +  - ]:   23660568 :       Trace("tableau") << "(" << entry.getRowIndex() << ", " << i.getID() << ") ";
     982                 :   23660568 :       ++count;
     983                 :            :     }
     984         [ +  - ]:    1009494 :     Trace("tableau") << std::endl;
     985                 :    1009494 :     return count;
     986                 :            :   }
     987                 :            :   uint32_t debugCountRowLength(RowIndex ridx){
     988                 :            :     uint32_t count = 0;
     989                 :            :     for(RowIterator i=getRow(ridx).begin(); !i.atEnd(); ++i){
     990                 :            :       ++count;
     991                 :            :     }
     992                 :            :     return count;
     993                 :            :   }
     994                 :            : 
     995                 :            : };/* class Matrix<T> */
     996                 :            : 
     997                 :            : }  // namespace arith
     998                 :            : }  // namespace theory
     999                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14