LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith/linear - tableau.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 95 114 83.3 %
Date: 2026-05-02 10:46:03 Functions: 5 8 62.5 %
Branches: 55 146 37.7 %

           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                 :            :  * [[ Add one-line brief description here ]]
      11                 :            :  *
      12                 :            :  * [[ Add lengthier description here ]]
      13                 :            :  * \todo document this file
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/arith/linear/tableau.h"
      17                 :            : 
      18                 :            : #include "base/output.h"
      19                 :            : 
      20                 :            : using namespace std;
      21                 :            : namespace cvc5::internal {
      22                 :            : namespace theory {
      23                 :            : namespace arith::linear {
      24                 :            : 
      25                 :     341292 : void Tableau::pivot(ArithVar oldBasic,
      26                 :            :                     ArithVar newBasic,
      27                 :            :                     CoefficientChangeCallback& cb)
      28                 :            : {
      29 [ -  + ][ -  + ]:     341292 :   Assert(isBasic(oldBasic));
                 [ -  - ]
      30 [ -  + ][ -  + ]:     341292 :   Assert(!isBasic(newBasic));
                 [ -  - ]
      31 [ -  + ][ -  + ]:     341292 :   Assert(d_mergeBuffer.empty());
                 [ -  - ]
      32                 :            : 
      33         [ +  - ]:     682584 :   Trace("tableau") << "Tableau::pivot(" << oldBasic << ", " << newBasic << ")"
      34                 :     341292 :                    << endl;
      35                 :            : 
      36                 :     341292 :   RowIndex ridx = basicToRowIndex(oldBasic);
      37                 :            : 
      38                 :     341292 :   rowPivot(oldBasic, newBasic, cb);
      39 [ -  + ][ -  + ]:     341292 :   Assert(ridx == basicToRowIndex(newBasic));
                 [ -  - ]
      40                 :            : 
      41                 :     341292 :   loadRowIntoBuffer(ridx);
      42                 :            : 
      43                 :     341292 :   ColIterator colIter = colIterator(newBasic);
      44         [ +  + ]:    6955770 :   while (!colIter.atEnd())
      45                 :            :   {
      46                 :    6614478 :     EntryID id = colIter.getID();
      47                 :    6614478 :     Entry& entry = d_entries.get(id);
      48                 :            : 
      49                 :    6614478 :     ++colIter;  // needs to be incremented before the variable is removed
      50         [ +  + ]:    6614478 :     if (entry.getRowIndex() == ridx)
      51                 :            :     {
      52                 :     341292 :       continue;
      53                 :            :     }
      54                 :            : 
      55                 :    6273186 :     RowIndex to = entry.getRowIndex();
      56                 :    6273186 :     Rational coeff = entry.getCoefficient();
      57         [ +  - ]:    6273186 :     if (cb.canUseRow(to))
      58                 :            :     {
      59                 :    6273186 :       rowPlusBufferTimesConstant(to, coeff, cb);
      60                 :            :     }
      61                 :            :     else
      62                 :            :     {
      63                 :          0 :       rowPlusBufferTimesConstant(to, coeff);
      64                 :            :     }
      65                 :    6273186 :   }
      66                 :     341292 :   clearBuffer();
      67                 :            : 
      68                 :            :   // Clear the column for used for this variable
      69                 :            : 
      70 [ -  + ][ -  + ]:     341292 :   Assert(d_mergeBuffer.empty());
                 [ -  - ]
      71 [ -  + ][ -  + ]:     341292 :   Assert(!isBasic(oldBasic));
                 [ -  - ]
      72 [ -  + ][ -  + ]:     341292 :   Assert(isBasic(newBasic));
                 [ -  - ]
      73 [ -  + ][ -  + ]:     341292 :   Assert(getColLength(newBasic) == 1);
                 [ -  - ]
      74                 :     341292 : }
      75                 :            : 
      76                 :            : /**
      77                 :            :  * Changes basic to newbasic (a variable on the row).
      78                 :            :  */
      79                 :     341292 : void Tableau::rowPivot(ArithVar basicOld,
      80                 :            :                        ArithVar basicNew,
      81                 :            :                        CoefficientChangeCallback& cb)
      82                 :            : {
      83 [ -  + ][ -  + ]:     341292 :   Assert(isBasic(basicOld));
                 [ -  - ]
      84 [ -  + ][ -  + ]:     341292 :   Assert(!isBasic(basicNew));
                 [ -  - ]
      85                 :            : 
      86                 :     341292 :   RowIndex rid = basicToRowIndex(basicOld);
      87                 :            : 
      88                 :     341292 :   EntryID newBasicID = findOnRow(rid, basicNew);
      89                 :            : 
      90 [ -  + ][ -  + ]:     341292 :   Assert(newBasicID != ENTRYID_SENTINEL);
                 [ -  - ]
      91                 :            : 
      92                 :     341292 :   Tableau::Entry& newBasicEntry = d_entries.get(newBasicID);
      93                 :     341292 :   const Rational& a_rs = newBasicEntry.getCoefficient();
      94                 :     341292 :   int a_rs_sgn = a_rs.sgn();
      95                 :     341292 :   Rational negInverseA_rs = -(a_rs.inverse());
      96                 :            : 
      97         [ +  + ]:    6161733 :   for (RowIterator i = basicRowIterator(basicOld); !i.atEnd(); ++i)
      98                 :            :   {
      99                 :    5820441 :     EntryID id = i.getID();
     100                 :    5820441 :     Tableau::Entry& entry = d_entries.get(id);
     101                 :            : 
     102                 :    5820441 :     entry.getCoefficient() *= negInverseA_rs;
     103                 :            :   }
     104                 :            : 
     105                 :     341292 :   d_basic2RowIndex.remove(basicOld);
     106                 :     341292 :   d_basic2RowIndex.set(basicNew, rid);
     107                 :     341292 :   d_rowIndex2basic.set(rid, basicNew);
     108                 :            : 
     109                 :     341292 :   cb.multiplyRow(rid, -a_rs_sgn);
     110                 :     341292 : }
     111                 :            : 
     112                 :     201247 : void Tableau::addRow(ArithVar basic,
     113                 :            :                      const std::vector<Rational>& coefficients,
     114                 :            :                      const std::vector<ArithVar>& variables)
     115                 :            : {
     116 [ -  + ][ -  + ]:     201247 :   Assert(basic < getNumColumns());
                 [ -  - ]
     117 [ -  + ][ -  + ]:     201247 :   Assert(debugIsASet(variables));
                 [ -  - ]
     118 [ -  + ][ -  + ]:     201247 :   Assert(coefficients.size() == variables.size());
                 [ -  - ]
     119 [ -  + ][ -  + ]:     201247 :   Assert(!isBasic(basic));
                 [ -  - ]
     120                 :            : 
     121                 :     201247 :   RowIndex newRow = Matrix<Rational>::addRow(coefficients, variables);
     122                 :     201247 :   addEntry(newRow, basic, Rational(-1));
     123                 :            : 
     124 [ -  + ][ -  + ]:     201247 :   Assert(!d_basic2RowIndex.isKey(basic));
                 [ -  - ]
     125 [ -  + ][ -  + ]:     201247 :   Assert(!d_rowIndex2basic.isKey(newRow));
                 [ -  - ]
     126                 :            : 
     127                 :     201247 :   d_basic2RowIndex.set(basic, newRow);
     128                 :     201247 :   d_rowIndex2basic.set(newRow, basic);
     129                 :            : 
     130         [ -  + ]:     201247 :   if (TraceIsOn("matrix"))
     131                 :            :   {
     132                 :          0 :     printMatrix();
     133                 :            :   }
     134                 :            : 
     135                 :     201247 :   NoEffectCCCB noeffect;
     136                 :     201247 :   NoEffectCCCB* nep = &noeffect;
     137                 :     201247 :   CoefficientChangeCallback* cccb =
     138                 :            :       static_cast<CoefficientChangeCallback*>(nep);
     139                 :            : 
     140                 :     201247 :   vector<Rational>::const_iterator coeffIter = coefficients.begin();
     141                 :     201247 :   vector<ArithVar>::const_iterator varsIter = variables.begin();
     142                 :     201247 :   vector<ArithVar>::const_iterator varsEnd = variables.end();
     143         [ +  + ]:     658640 :   for (; varsIter != varsEnd; ++coeffIter, ++varsIter)
     144                 :            :   {
     145                 :     457393 :     ArithVar var = *varsIter;
     146                 :            : 
     147         [ +  + ]:     457393 :     if (isBasic(var))
     148                 :            :     {
     149                 :     125473 :       Rational coeff = *coeffIter;
     150                 :            : 
     151                 :     125473 :       RowIndex ri = basicToRowIndex(var);
     152                 :            : 
     153                 :     125473 :       loadRowIntoBuffer(ri);
     154                 :     125473 :       rowPlusBufferTimesConstant(newRow, coeff, *cccb);
     155                 :     125473 :       clearBuffer();
     156                 :     125473 :     }
     157                 :            :   }
     158                 :            : 
     159         [ -  + ]:     201247 :   if (TraceIsOn("matrix"))
     160                 :            :   {
     161                 :          0 :     printMatrix();
     162                 :            :   }
     163                 :            : 
     164 [ -  + ][ -  + ]:     201247 :   Assert(debugNoZeroCoefficients(newRow));
                 [ -  - ]
     165 [ -  + ][ -  + ]:     201247 :   Assert(debugMatchingCountsForRow(newRow));
                 [ -  - ]
     166 [ -  + ][ -  + ]:     201247 :   Assert(getColLength(basic) == 1);
                 [ -  - ]
     167                 :     201247 : }
     168                 :            : 
     169                 :       4096 : void Tableau::removeBasicRow(ArithVar basic)
     170                 :            : {
     171                 :       4096 :   RowIndex rid = basicToRowIndex(basic);
     172                 :            : 
     173                 :       4096 :   removeRow(rid);
     174                 :       4096 :   d_basic2RowIndex.remove(basic);
     175                 :       4096 :   d_rowIndex2basic.remove(rid);
     176                 :       4096 : }
     177                 :            : 
     178                 :       5039 : void Tableau::substitutePlusTimesConstant(ArithVar to,
     179                 :            :                                           ArithVar from,
     180                 :            :                                           const Rational& mult,
     181                 :            :                                           CoefficientChangeCallback& cb)
     182                 :            : {
     183         [ +  - ]:       5039 :   if (!mult.isZero())
     184                 :            :   {
     185                 :       5039 :     RowIndex to_idx = basicToRowIndex(to);
     186                 :       5039 :     addEntry(to_idx, from, mult);  // Add an entry to be cancelled out
     187                 :       5039 :     RowIndex from_idx = basicToRowIndex(from);
     188                 :            : 
     189                 :       5039 :     cb.update(to_idx, from, 0, mult.sgn());
     190                 :            : 
     191                 :       5039 :     loadRowIntoBuffer(from_idx);
     192                 :       5039 :     rowPlusBufferTimesConstant(to_idx, mult, cb);
     193                 :       5039 :     clearBuffer();
     194                 :            :   }
     195                 :       5039 : }
     196                 :            : 
     197                 :          0 : uint32_t Tableau::rowComplexity(ArithVar basic) const
     198                 :            : {
     199                 :          0 :   uint32_t complexity = 0;
     200         [ -  - ]:          0 :   for (RowIterator i = basicRowIterator(basic); !i.atEnd(); ++i)
     201                 :            :   {
     202                 :          0 :     const Entry& e = *i;
     203                 :          0 :     complexity += e.getCoefficient().complexity();
     204                 :            :   }
     205                 :          0 :   return complexity;
     206                 :            : }
     207                 :            : 
     208                 :          0 : double Tableau::avgRowComplexity() const
     209                 :            : {
     210                 :          0 :   double sum = 0;
     211                 :          0 :   uint32_t rows = 0;
     212         [ -  - ]:          0 :   for (BasicIterator i = beginBasic(), i_end = endBasic(); i != i_end; ++i)
     213                 :            :   {
     214                 :          0 :     sum += rowComplexity(*i);
     215                 :          0 :     rows++;
     216                 :            :   }
     217         [ -  - ]:          0 :   return (rows == 0) ? 0 : (sum / rows);
     218                 :            : }
     219                 :            : 
     220                 :          0 : void Tableau::printBasicRow(ArithVar basic, std::ostream& out)
     221                 :            : {
     222                 :          0 :   printRow(basicToRowIndex(basic), out);
     223                 :          0 : }
     224                 :            : 
     225                 :            : }  // namespace arith::linear
     226                 :            : }  // namespace theory
     227                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14