LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith/nl - strategy.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 110 118 93.2 %
Date: 2026-04-27 10:45:38 Functions: 10 11 90.9 %
Branches: 66 83 79.5 %

           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                 :            :  * Implementation of non-linear solver.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/arith/nl/strategy.h"
      14                 :            : 
      15                 :            : #include <iostream>
      16                 :            : 
      17                 :            : #include "base/check.h"
      18                 :            : #include "options/arith_options.h"
      19                 :            : 
      20                 :            : namespace cvc5::internal {
      21                 :            : namespace theory {
      22                 :            : namespace arith {
      23                 :            : namespace nl {
      24                 :            : 
      25                 :         31 : std::ostream& operator<<(std::ostream& os, InferStep step)
      26                 :            : {
      27 [ +  + ][ +  + ]:         31 :   switch (step)
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
                    [ - ]
      28                 :            :   {
      29                 :          1 :     case InferStep::NONE: return os << "NONE";
      30                 :          1 :     case InferStep::BREAK: return os << "BREAK";
      31                 :          1 :     case InferStep::FLUSH_WAITING_LEMMAS: return os << "FLUSH_WAITING_LEMMAS";
      32                 :          1 :     case InferStep::COVERINGS_INIT: return os << "COVERINGS_INIT";
      33                 :          1 :     case InferStep::COVERINGS_FULL: return os << "COVERINGS_FULL";
      34                 :          1 :     case InferStep::NL_FACTORING: return os << "NL_FACTORING";
      35                 :          1 :     case InferStep::NL_FLATTEN_MON: return os << "NL_FLATTEN_MON";
      36                 :          1 :     case InferStep::IAND_INIT: return os << "IAND_INIT";
      37                 :          1 :     case InferStep::IAND_FULL: return os << "IAND_FULL";
      38                 :          1 :     case InferStep::IAND_INITIAL: return os << "IAND_INITIAL";
      39                 :          1 :     case InferStep::PIAND_INIT: return os << "PIAND_INIT";
      40                 :          1 :     case InferStep::PIAND_FULL: return os << "PIAND_FULL";
      41                 :          1 :     case InferStep::PIAND_INITIAL: return os << "PIAND_INITIAL";
      42                 :          1 :     case InferStep::POW2_INIT: return os << "POW2_INIT";
      43                 :          1 :     case InferStep::POW2_FULL: return os << "POW2_FULL";
      44                 :          1 :     case InferStep::POW2_INITIAL: return os << "POW2_INITIAL";
      45                 :          1 :     case InferStep::ICP: return os << "ICP";
      46                 :          1 :     case InferStep::NL_INIT: return os << "NL_INIT";
      47                 :          1 :     case InferStep::NL_MONOMIAL_INFER_BOUNDS:
      48                 :          1 :       return os << "NL_MONOMIAL_INFER_BOUNDS";
      49                 :          1 :     case InferStep::NL_MONOMIAL_MAGNITUDE0:
      50                 :          1 :       return os << "NL_MONOMIAL_MAGNITUDE0";
      51                 :          1 :     case InferStep::NL_MONOMIAL_MAGNITUDE1:
      52                 :          1 :       return os << "NL_MONOMIAL_MAGNITUDE1";
      53                 :          1 :     case InferStep::NL_MONOMIAL_MAGNITUDE2:
      54                 :          1 :       return os << "NL_MONOMIAL_MAGNITUDE2";
      55                 :          1 :     case InferStep::NL_MONOMIAL_SIGN: return os << "NL_MONOMIAL_SIGN";
      56                 :          1 :     case InferStep::NL_RESOLUTION_BOUNDS: return os << "NL_RESOLUTION_BOUNDS";
      57                 :          1 :     case InferStep::NL_SPLIT_ZERO: return os << "NL_SPLIT_ZERO";
      58                 :          1 :     case InferStep::NL_TANGENT_PLANES: return os << "NL_TANGENT_PLANES";
      59                 :          1 :     case InferStep::NL_TANGENT_PLANES_WAITING:
      60                 :          1 :       return os << "NL_TANGENT_PLANES_WAITING";
      61                 :          1 :     case InferStep::TRANS_INIT: return os << "TRANS_INIT";
      62                 :          1 :     case InferStep::TRANS_INITIAL: return os << "TRANS_INITIAL";
      63                 :          1 :     case InferStep::TRANS_MONOTONIC: return os << "TRANS_MONOTONIC";
      64                 :          1 :     case InferStep::TRANS_TANGENT_PLANES: return os << "TRANS_TANGENT_PLANES";
      65                 :          0 :     case InferStep::UNKNOWN: return os << "?";
      66                 :          0 :     default: Unreachable(); return os << "UNKNOWN_STEP";
      67                 :            :   }
      68                 :            : }
      69                 :            : 
      70                 :            : namespace {
      71                 :            : /** Puts a new InferStep into a StepSequence */
      72                 :      68061 : inline StepSequence& operator<<(StepSequence& steps, InferStep s)
      73                 :            : {
      74                 :      68061 :   steps.emplace_back(s);
      75                 :      68061 :   return steps;
      76                 :            : }
      77                 :            : }  // namespace
      78                 :            : 
      79                 :       1687 : void Interleaving::add(const StepSequence& ss, std::size_t constant)
      80                 :            : {
      81                 :       1687 :   d_branches.emplace_back(Branch{ss, constant});
      82                 :       1687 :   d_size += constant;
      83                 :       1687 : }
      84                 :          0 : void Interleaving::resetCounter() { d_counter = 0; }
      85                 :            : 
      86                 :      12364 : const StepSequence& Interleaving::get()
      87                 :            : {
      88 [ -  + ][ -  + ]:      12364 :   Assert(!d_branches.empty())
                 [ -  - ]
      89                 :          0 :       << "Can not get next sequence from an empty interleaving.";
      90                 :      12364 :   std::size_t cnt = d_counter;
      91                 :            :   // Increase the counter
      92                 :      12364 :   d_counter = (d_counter + 1) % d_size;
      93         [ +  - ]:      12364 :   for (const auto& branch : d_branches)
      94                 :            :   {
      95         [ +  - ]:      12364 :     if (cnt < branch.d_interleavingConstant)
      96                 :            :     {
      97                 :            :       // This is the current branch
      98                 :      12364 :       return branch.d_steps;
      99                 :            :     }
     100                 :          0 :     cnt -= branch.d_interleavingConstant;
     101                 :            :   }
     102                 :          0 :   DebugUnhandled() << "Something went wrong.";
     103                 :            :   return d_branches[0].d_steps;
     104                 :            : }
     105                 :      12364 : bool Interleaving::empty() const { return d_branches.empty(); }
     106                 :            : 
     107                 :     273876 : bool StepGenerator::hasNext() const { return d_next < d_steps.size(); }
     108                 :     272925 : InferStep StepGenerator::next() { return d_steps[d_next++]; }
     109                 :            : 
     110                 :      12364 : bool Strategy::isStrategyInit() const { return !d_interleaving.empty(); }
     111                 :       1687 : void Strategy::initializeStrategy(const Options& options)
     112                 :            : {
     113                 :       1687 :   StepSequence one;
     114         [ +  + ]:       1687 :   if (options.arith.nlICP)
     115                 :            :   {
     116                 :          4 :     one << InferStep::ICP << InferStep::BREAK;
     117                 :            :   }
     118         [ +  + ]:       1687 :   if (options.arith.nlExt == options::NlExtMode::FULL
     119         [ +  + ]:        163 :       || options.arith.nlExt == options::NlExtMode::LIGHT)
     120                 :            :   {
     121                 :       1675 :     one << InferStep::NL_INIT << InferStep::BREAK;
     122                 :            :   }
     123         [ +  + ]:       1687 :   if (options.arith.nlExt == options::NlExtMode::FULL)
     124                 :            :   {
     125                 :       1524 :     one << InferStep::TRANS_INIT << InferStep::BREAK;
     126         [ +  + ]:       1524 :     if (options.arith.nlExtSplitZero)
     127                 :            :     {
     128                 :          2 :       one << InferStep::NL_SPLIT_ZERO << InferStep::BREAK;
     129                 :            :     }
     130                 :       1524 :     one << InferStep::TRANS_INITIAL << InferStep::BREAK;
     131                 :            :   }
     132                 :       1687 :   one << InferStep::IAND_INIT;
     133                 :       1687 :   one << InferStep::IAND_INITIAL << InferStep::BREAK;
     134                 :       1687 :   one << InferStep::PIAND_INIT;
     135                 :       1687 :   one << InferStep::PIAND_INITIAL << InferStep::BREAK;
     136                 :       1687 :   one << InferStep::POW2_INIT;
     137                 :       1687 :   one << InferStep::POW2_INITIAL << InferStep::BREAK;
     138         [ +  + ]:       1687 :   if (options.arith.nlExt == options::NlExtMode::FULL
     139         [ +  + ]:        163 :       || options.arith.nlExt == options::NlExtMode::LIGHT)
     140                 :            :   {
     141                 :       1675 :     one << InferStep::NL_MONOMIAL_SIGN << InferStep::BREAK;
     142                 :       1675 :     one << InferStep::NL_MONOMIAL_MAGNITUDE0 << InferStep::BREAK;
     143                 :            :   }
     144         [ +  - ]:       1687 :   if (options.arith.nlExtFlattenMon)
     145                 :            :   {
     146                 :       1687 :     one << InferStep::NL_FLATTEN_MON << InferStep::BREAK;
     147                 :            :   }
     148         [ +  + ]:       1687 :   if (options.arith.nlExt == options::NlExtMode::FULL)
     149                 :            :   {
     150                 :       1524 :     one << InferStep::TRANS_MONOTONIC << InferStep::BREAK;
     151                 :       1524 :     one << InferStep::NL_MONOMIAL_MAGNITUDE1 << InferStep::BREAK;
     152                 :       1524 :     one << InferStep::NL_MONOMIAL_MAGNITUDE2 << InferStep::BREAK;
     153                 :       1524 :     one << InferStep::NL_MONOMIAL_INFER_BOUNDS;
     154         [ +  - ]:       1524 :     if (options.arith.nlExtTangentPlanes
     155         [ -  + ]:       1524 :         && options.arith.nlExtTangentPlanesInterleave)
     156                 :            :     {
     157                 :          0 :       one << InferStep::NL_TANGENT_PLANES;
     158                 :            :     }
     159                 :       1524 :     one << InferStep::BREAK;
     160                 :            :   }
     161                 :       1687 :   one << InferStep::IAND_FULL << InferStep::BREAK;
     162                 :       1687 :   one << InferStep::PIAND_FULL << InferStep::BREAK;
     163                 :       1687 :   one << InferStep::POW2_FULL << InferStep::BREAK;
     164         [ +  + ]:       1687 :   if (options.arith.nlCov)
     165                 :            :   {
     166                 :        259 :     one << InferStep::COVERINGS_INIT << InferStep::BREAK;
     167                 :        259 :     one << InferStep::COVERINGS_FULL << InferStep::BREAK;
     168                 :            :   }
     169         [ +  + ]:       1687 :   if (options.arith.nlExt == options::NlExtMode::FULL
     170 [ +  + ][ -  + ]:       1524 :       && (!options.arith.nlCov || options.arith.nlCovForce))
     171                 :            :   {
     172                 :            :     // if nl-cov is not enabled or we forced it to be enabled, then we use
     173                 :            :     // heuristic non-terminating techniques as a last resort
     174                 :       1428 :     one << InferStep::FLUSH_WAITING_LEMMAS << InferStep::BREAK;
     175         [ +  - ]:       1428 :     if (options.arith.nlExtFactor)
     176                 :            :     {
     177                 :       1428 :       one << InferStep::NL_FACTORING << InferStep::BREAK;
     178                 :            :     }
     179         [ -  + ]:       1428 :     if (options.arith.nlExtResBound)
     180                 :            :     {
     181                 :          0 :       one << InferStep::NL_MONOMIAL_INFER_BOUNDS << InferStep::BREAK;
     182                 :            :     }
     183         [ +  - ]:       1428 :     if (options.arith.nlExtTangentPlanes
     184         [ +  - ]:       1428 :         && !options.arith.nlExtTangentPlanesInterleave)
     185                 :            :     {
     186                 :       1428 :       one << InferStep::NL_TANGENT_PLANES_WAITING;
     187                 :            :     }
     188         [ +  - ]:       1428 :     if (options.arith.nlExtTfTangentPlanes)
     189                 :            :     {
     190                 :       1428 :       one << InferStep::TRANS_TANGENT_PLANES;
     191                 :            :     }
     192                 :       1428 :     one << InferStep::BREAK;
     193                 :            :   }
     194                 :            : 
     195                 :       1687 :   d_interleaving.add(one);
     196                 :       1687 : }
     197                 :      12364 : StepGenerator Strategy::getStrategy()
     198                 :            : {
     199                 :      12364 :   return StepGenerator(d_interleaving.get());
     200                 :            : }
     201                 :            : 
     202                 :            : }  // namespace nl
     203                 :            : }  // namespace arith
     204                 :            : }  // namespace theory
     205                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14