LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith/linear - infer_bounds.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 32 152 21.1 %
Date: 2026-02-23 11:51:46 Functions: 12 39 30.8 %
Branches: 3 47 6.4 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Tim King, Andres Noetzli, Andrew Reynolds
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * [[ Add one-line brief description here ]]
      14                 :            :  *
      15                 :            :  * [[ Add lengthier description here ]]
      16                 :            :  * \todo document this file
      17                 :            :  */
      18                 :            : 
      19                 :            : #include "theory/arith/linear/infer_bounds.h"
      20                 :            : #include "theory/rewriter.h"
      21                 :            : 
      22                 :            : using namespace cvc5::internal::kind;
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : namespace theory {
      26                 :            : namespace arith::linear {
      27                 :            : 
      28                 :            : using namespace inferbounds;
      29                 :            : 
      30                 :          0 : InferBoundAlgorithm::InferBoundAlgorithm()
      31                 :          0 :   : d_alg(None)
      32                 :          0 : {}
      33                 :            : 
      34                 :      22764 : InferBoundAlgorithm::InferBoundAlgorithm(Algorithms a)
      35                 :      22764 :   : d_alg(a)
      36                 :            : {
      37 [ -  + ][ -  + ]:      22764 :   Assert(a != Simplex);
                 [ -  - ]
      38                 :      22764 : }
      39                 :            : 
      40                 :          0 : InferBoundAlgorithm::InferBoundAlgorithm(
      41                 :          0 :     const std::optional<int>& simplexRounds)
      42                 :          0 :     : d_alg(Simplex), d_simplexRounds(simplexRounds)
      43                 :          0 : {}
      44                 :            : 
      45                 :      43268 : Algorithms InferBoundAlgorithm::getAlgorithm() const{
      46                 :      43268 :   return d_alg;
      47                 :            : }
      48                 :            : 
      49                 :          0 : const std::optional<int>& InferBoundAlgorithm::getSimplexRounds() const
      50                 :            : {
      51                 :          0 :   Assert(getAlgorithm() == Simplex);
      52                 :          0 :   return d_simplexRounds;
      53                 :            : }
      54                 :            : 
      55                 :      11382 : InferBoundAlgorithm InferBoundAlgorithm::mkLookup(){
      56                 :      11382 :   return InferBoundAlgorithm(Lookup);
      57                 :            : }
      58                 :            : 
      59                 :      11382 : InferBoundAlgorithm InferBoundAlgorithm::mkRowSum(){
      60                 :      11382 :   return InferBoundAlgorithm(RowSum);
      61                 :            : }
      62                 :            : 
      63                 :          0 : InferBoundAlgorithm InferBoundAlgorithm::mkSimplex(
      64                 :            :     const std::optional<int>& rounds)
      65                 :            : {
      66                 :          0 :   return InferBoundAlgorithm(rounds);
      67                 :            : }
      68                 :            : 
      69                 :      11382 : ArithEntailmentCheckParameters::ArithEntailmentCheckParameters()
      70                 :      11382 :     : d_algorithms()
      71                 :      11382 : {}
      72                 :            : 
      73                 :      11382 : ArithEntailmentCheckParameters::~ArithEntailmentCheckParameters()
      74                 :      11382 : {}
      75                 :            : 
      76                 :            : 
      77                 :      11382 : void ArithEntailmentCheckParameters::addLookupRowSumAlgorithms(){
      78                 :      11382 :   addAlgorithm(InferBoundAlgorithm::mkLookup());
      79                 :      11382 :   addAlgorithm(InferBoundAlgorithm::mkRowSum());
      80                 :      11382 : }
      81                 :            : 
      82                 :      22764 : void ArithEntailmentCheckParameters::addAlgorithm(const inferbounds::InferBoundAlgorithm& alg){
      83                 :      22764 :   d_algorithms.push_back(alg);
      84                 :      22764 : }
      85                 :            : 
      86                 :      11382 : ArithEntailmentCheckParameters::const_iterator ArithEntailmentCheckParameters::begin() const{
      87                 :      11382 :   return d_algorithms.begin();
      88                 :            : }
      89                 :            : 
      90                 :      11382 : ArithEntailmentCheckParameters::const_iterator ArithEntailmentCheckParameters::end() const{
      91                 :      11382 :   return d_algorithms.end();
      92                 :            : }
      93                 :            : 
      94                 :          0 : InferBoundsResult::InferBoundsResult()
      95                 :          0 :   : d_foundBound(false)
      96                 :          0 :   , d_budgetExhausted(false)
      97                 :          0 :   , d_boundIsProvenOpt(false)
      98                 :          0 :   , d_inconsistentState(false)
      99                 :          0 :   , d_reachedThreshold(false)
     100                 :          0 :   , d_value(false)
     101                 :          0 :   , d_term(Node::null())
     102                 :          0 :   , d_upperBound(true)
     103                 :          0 :   , d_explanation(Node::null())
     104                 :          0 : {}
     105                 :            : 
     106                 :          0 : InferBoundsResult::InferBoundsResult(Node term, bool ub)
     107                 :          0 :   : d_foundBound(false)
     108                 :          0 :   , d_budgetExhausted(false)
     109                 :          0 :   , d_boundIsProvenOpt(false)
     110                 :          0 :   , d_inconsistentState(false)
     111                 :          0 :   , d_reachedThreshold(false)
     112                 :          0 :   , d_value(false)
     113                 :          0 :   , d_term(term)
     114                 :          0 :   , d_upperBound(ub)
     115                 :          0 :   , d_explanation(Node::null())
     116                 :          0 : {}
     117                 :            : 
     118                 :          0 : bool InferBoundsResult::foundBound() const {
     119                 :          0 :   return d_foundBound;
     120                 :            : }
     121                 :          0 : bool InferBoundsResult::boundIsOptimal() const {
     122                 :          0 :   return d_boundIsProvenOpt;
     123                 :            : }
     124                 :          0 : bool InferBoundsResult::inconsistentState() const {
     125                 :          0 :   return d_inconsistentState;
     126                 :            : }
     127                 :            : 
     128                 :          0 : bool InferBoundsResult::boundIsInteger() const{
     129 [ -  - ][ -  - ]:          0 :   return foundBound() && d_value.isIntegral();
     130                 :            : }
     131                 :            : 
     132                 :          0 : bool InferBoundsResult::boundIsRational() const {
     133 [ -  - ][ -  - ]:          0 :   return foundBound() && d_value.infinitesimalIsZero();
     134                 :            : }
     135                 :            : 
     136                 :          0 : Integer InferBoundsResult::valueAsInteger() const{
     137                 :          0 :   Assert(boundIsInteger());
     138                 :          0 :   return getValue().floor();
     139                 :            : }
     140                 :          0 : const Rational& InferBoundsResult::valueAsRational() const{
     141                 :          0 :   Assert(boundIsRational());
     142                 :          0 :   return getValue().getNoninfinitesimalPart();
     143                 :            : }
     144                 :            : 
     145                 :          0 : const DeltaRational& InferBoundsResult::getValue() const{
     146                 :          0 :   return d_value;
     147                 :            : }
     148                 :            : 
     149                 :          0 : Node InferBoundsResult::getTerm() const { return d_term; }
     150                 :            : 
     151                 :          0 : Node InferBoundsResult::getLiteral() const{
     152                 :          0 :   const Rational& q = getValue().getNoninfinitesimalPart();
     153                 :          0 :   NodeManager* nm = d_term.getNodeManager();
     154                 :          0 :   Node qnode = nm->mkConstReal(q);
     155                 :            : 
     156                 :            :   Kind k;
     157         [ -  - ]:          0 :   if(d_upperBound){
     158                 :            :     // x <= q + c*delta
     159                 :          0 :     Assert(getValue().infinitesimalSgn() <= 0);
     160         [ -  - ]:          0 :     k = boundIsRational() ? Kind::LEQ : Kind::LT;
     161                 :            :   }else{
     162                 :            :     // x >= q + c*delta
     163                 :          0 :     Assert(getValue().infinitesimalSgn() >= 0);
     164         [ -  - ]:          0 :     k = boundIsRational() ? Kind::GEQ : Kind::GT;
     165                 :            :   }
     166                 :          0 :   return nm->mkNode(k, getTerm(), qnode);
     167                 :          0 : }
     168                 :            : 
     169                 :            : /* If there is a bound, this is a node that explains the bound. */
     170                 :          0 : Node InferBoundsResult::getExplanation() const{
     171                 :          0 :   return d_explanation;
     172                 :            : }
     173                 :            : 
     174                 :            : 
     175                 :          0 : void InferBoundsResult::setBound(const DeltaRational& dr, Node exp){
     176                 :          0 :   d_foundBound = true;
     177                 :          0 :   d_value = dr;
     178                 :          0 :   d_explanation = exp;
     179                 :          0 : }
     180                 :            : 
     181                 :          0 : void InferBoundsResult::setBudgetExhausted() { d_budgetExhausted = true; }
     182                 :          0 : void InferBoundsResult::setReachedThreshold() { d_reachedThreshold = true; }
     183                 :          0 : void InferBoundsResult::setIsOptimal() { d_boundIsProvenOpt = true; }
     184                 :          0 : void InferBoundsResult::setInconsistent() { d_inconsistentState = true; }
     185                 :            : 
     186                 :          0 : bool InferBoundsResult::thresholdWasReached() const{
     187                 :          0 :   return d_reachedThreshold;
     188                 :            : }
     189                 :          0 : bool InferBoundsResult::budgetIsExhausted() const{
     190                 :          0 :   return d_budgetExhausted;
     191                 :            : }
     192                 :            : 
     193                 :          0 : std::ostream& operator<<(std::ostream& os, const InferBoundsResult& ibr){
     194                 :          0 :   os << "{InferBoundsResult " << std::endl;
     195                 :          0 :   os << "on " << ibr.getTerm() << ", ";
     196         [ -  - ]:          0 :   if(ibr.findUpperBound()){
     197                 :          0 :     os << "find upper bound, ";
     198                 :            :   }else{
     199                 :          0 :     os << "find lower bound, ";
     200                 :            :   }
     201         [ -  - ]:          0 :   if(ibr.foundBound()){
     202                 :          0 :     os << "found a bound: ";
     203         [ -  - ]:          0 :     if(ibr.boundIsInteger()){
     204                 :          0 :       os << ibr.valueAsInteger() << "(int), ";
     205         [ -  - ]:          0 :     }else if(ibr.boundIsRational()){
     206                 :          0 :       os << ibr.valueAsRational() << "(rat), ";
     207                 :            :     }else{
     208                 :          0 :       os << ibr.getValue() << "(extended), ";
     209                 :            :     }
     210                 :            : 
     211                 :          0 :     os << "as term " << ibr.getLiteral() << ", ";
     212                 :          0 :     os << "explanation " << ibr.getExplanation() << ", ";
     213                 :            :   }else {
     214                 :          0 :     os << "did not find a bound, ";
     215                 :            :   }
     216                 :            : 
     217         [ -  - ]:          0 :   if(ibr.boundIsOptimal()){
     218                 :          0 :     os << "(opt), ";
     219                 :            :   }
     220                 :            : 
     221         [ -  - ]:          0 :   if(ibr.inconsistentState()){
     222                 :          0 :     os << "(inconsistent), ";
     223                 :            :   }
     224         [ -  - ]:          0 :   if(ibr.budgetIsExhausted()){
     225                 :          0 :     os << "(budget exhausted), ";
     226                 :            :   }
     227         [ -  - ]:          0 :   if(ibr.thresholdWasReached()){
     228                 :          0 :     os << "(reached threshold), ";
     229                 :            :   }
     230                 :          0 :   os << "}";
     231                 :          0 :   return os;
     232                 :            : }
     233                 :            : 
     234                 :      11382 : ArithEntailmentCheckSideEffects::ArithEntailmentCheckSideEffects()
     235                 :      11382 :     : d_simplexSideEffects(NULL)
     236                 :      11382 : {}
     237                 :            : 
     238                 :      11382 : ArithEntailmentCheckSideEffects::~ArithEntailmentCheckSideEffects(){
     239         [ -  + ]:      11382 :   if(d_simplexSideEffects != NULL){
     240         [ -  - ]:          0 :     delete d_simplexSideEffects;
     241                 :          0 :     d_simplexSideEffects = NULL;
     242                 :            :   }
     243                 :      11382 : }
     244                 :            : 
     245                 :          0 : InferBoundsResult& ArithEntailmentCheckSideEffects::getSimplexSideEffects(){
     246         [ -  - ]:          0 :   if(d_simplexSideEffects == NULL){
     247                 :          0 :     d_simplexSideEffects = new InferBoundsResult;
     248                 :            :   }
     249                 :          0 :   return *d_simplexSideEffects;
     250                 :            : }
     251                 :            : 
     252                 :            : namespace inferbounds { /* namespace arith */
     253                 :            : 
     254                 :          0 : std::ostream& operator<<(std::ostream& os,  const Algorithms a){
     255 [ -  - ][ -  - ]:          0 :   switch(a){
                    [ - ]
     256                 :          0 :   case None:    os << "AlgNone"; break;
     257                 :          0 :   case Lookup:  os << "AlgLookup"; break;
     258                 :          0 :   case RowSum:  os << "AlgRowSum"; break;
     259                 :          0 :   case Simplex: os << "AlgSimplex"; break;
     260                 :          0 :   default:
     261                 :          0 :     Unhandled();
     262                 :            :   }
     263                 :            : 
     264                 :          0 :   return os;
     265                 :            : }
     266                 :            : 
     267                 :            : } /* namespace inferbounds */
     268                 :            : 
     269                 :            : } /* namespace arith */
     270                 :            : } /* namespace theory */
     271                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14