LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers - bv_inverter.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 202 217 93.1 %
Date: 2026-08-03 10:34:52 Functions: 8 8 100.0 %
Branches: 221 320 69.1 %

           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                 :            :  * Inverse rules for bit-vector operators.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/quantifiers/bv_inverter.h"
      14                 :            : 
      15                 :            : #include <algorithm>
      16                 :            : 
      17                 :            : #include "expr/skolem_manager.h"
      18                 :            : #include "options/quantifiers_options.h"
      19                 :            : #include "theory/bv/theory_bv_utils.h"
      20                 :            : #include "theory/quantifiers/bv_inverter_utils.h"
      21                 :            : #include "theory/quantifiers/term_util.h"
      22                 :            : #include "theory/rewriter.h"
      23                 :            : #include "util/bitvector.h"
      24                 :            : 
      25                 :            : using namespace cvc5::internal::kind;
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : namespace theory {
      29                 :            : namespace quantifiers {
      30                 :            : 
      31                 :      55686 : BvInverter::BvInverter(Rewriter* r) : d_rewriter(r) {}
      32                 :            : 
      33                 :            : /*---------------------------------------------------------------------------*/
      34                 :            : 
      35                 :      15305 : Node BvInverter::getSolveVariable(TypeNode tn)
      36                 :            : {
      37                 :      15305 :   std::map<TypeNode, Node>::iterator its = d_solve_var.find(tn);
      38         [ +  + ]:      15305 :   if (its == d_solve_var.end())
      39                 :            :   {
      40                 :       5274 :     Node k = NodeManager::mkDummySkolem("slv", tn);
      41                 :       2637 :     d_solve_var[tn] = k;
      42                 :       2637 :     return k;
      43                 :       2637 :   }
      44                 :      12668 :   return its->second;
      45                 :            : }
      46                 :            : 
      47                 :            : /*---------------------------------------------------------------------------*/
      48                 :            : 
      49                 :       1967 : Node BvInverter::getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m)
      50                 :            : {
      51                 :       3934 :   TNode solve_var = getSolveVariable(tn);
      52                 :            : 
      53                 :            :   // condition should be rewritten
      54                 :       1967 :   Node new_cond = cond;
      55         [ +  + ]:       1967 :   if (d_rewriter != nullptr)
      56                 :            :   {
      57                 :        813 :     new_cond = d_rewriter->rewrite(cond);
      58         [ +  - ]:        813 :     if (new_cond != cond)
      59                 :            :     {
      60         [ +  - ]:       1626 :       Trace("cegqi-bv-skvinv-debug")
      61                 :          0 :           << "Condition " << cond << " was rewritten to " << new_cond
      62                 :        813 :           << std::endl;
      63                 :            :     }
      64                 :            :   }
      65                 :            :   // optimization : if condition is ( x = solve_var ) should just return
      66                 :            :   // solve_var and not introduce a Skolem this can happen when we ask for
      67                 :            :   // the multiplicative inversion with bv1
      68                 :       1967 :   Node c;
      69         [ +  + ]:       1967 :   if (new_cond.getKind() == Kind::EQUAL)
      70                 :            :   {
      71         [ +  + ]:         21 :     for (unsigned i = 0; i < 2; i++)
      72                 :            :     {
      73         [ -  + ]:         14 :       if (new_cond[i] == solve_var)
      74                 :            :       {
      75                 :          0 :         c = new_cond[1 - i];
      76         [ -  - ]:          0 :         Trace("cegqi-bv-skvinv")
      77                 :          0 :             << "SKVINV : " << c << " is trivially associated with conditon "
      78                 :          0 :             << new_cond << std::endl;
      79                 :          0 :         break;
      80                 :            :       }
      81                 :            :     }
      82                 :            :   }
      83                 :            : 
      84         [ +  - ]:       1967 :   if (c.isNull())
      85                 :            :   {
      86         [ +  + ]:       1967 :     if (m)
      87                 :            :     {
      88                 :        813 :       Node x = m->getBoundVariable(tn);
      89                 :       1626 :       Node ccond = new_cond.substitute(solve_var, x);
      90                 :       2439 :       c = NodeManager::mkNode(
      91                 :       2439 :           Kind::WITNESS, NodeManager::mkNode(Kind::BOUND_VAR_LIST, x), ccond);
      92         [ +  - ]:       1626 :       Trace("cegqi-bv-skvinv")
      93                 :        813 :           << "SKVINV : Make " << c << " for " << new_cond << std::endl;
      94                 :        813 :     }
      95                 :            :     else
      96                 :            :     {
      97         [ +  - ]:       2308 :       Trace("bv-invert") << "...fail for " << cond << " : no inverter query!"
      98                 :       1154 :                          << std::endl;
      99                 :            :     }
     100                 :            :   }
     101                 :            :   // currently shouldn't cache since
     102                 :            :   // the return value depends on the
     103                 :            :   // state of m (which bound variable is returned).
     104                 :       3934 :   return c;
     105                 :       1967 : }
     106                 :            : 
     107                 :            : /*---------------------------------------------------------------------------*/
     108                 :            : 
     109                 :     194667 : static bool isInvertible(Kind k)
     110                 :            : {
     111 [ +  + ][ +  + ]:     194607 :   return k == Kind::NOT || k == Kind::EQUAL || k == Kind::BITVECTOR_ULT
     112 [ +  - ][ +  + ]:     115672 :          || k == Kind::BITVECTOR_SLT || k == Kind::BITVECTOR_COMP
     113 [ +  + ][ +  + ]:     114098 :          || k == Kind::BITVECTOR_NOT || k == Kind::BITVECTOR_NEG
     114 [ +  + ][ +  + ]:     113510 :          || k == Kind::BITVECTOR_CONCAT || k == Kind::BITVECTOR_SIGN_EXTEND
     115 [ +  + ][ +  + ]:     111185 :          || k == Kind::BITVECTOR_ADD || k == Kind::BITVECTOR_MULT
     116 [ +  + ][ +  + ]:     106599 :          || k == Kind::BITVECTOR_UREM || k == Kind::BITVECTOR_UDIV
     117 [ +  + ][ +  + ]:     105995 :          || k == Kind::BITVECTOR_AND || k == Kind::BITVECTOR_OR
     118 [ +  + ][ +  + ]:     104027 :          || k == Kind::BITVECTOR_XOR || k == Kind::BITVECTOR_LSHR
     119 [ +  + ][ +  + ]:     389274 :          || k == Kind::BITVECTOR_ASHR || k == Kind::BITVECTOR_SHL;
                 [ +  + ]
     120                 :            : }
     121                 :            : 
     122                 :     132346 : Node BvInverter::getPathToPv(Node lit,
     123                 :            :                              Node pv,
     124                 :            :                              Node sv,
     125                 :            :                              std::vector<uint32_t>& path,
     126                 :            :                              std::unordered_set<TNode>& visited)
     127                 :            : {
     128         [ +  + ]:     132346 :   if (visited.find(lit) == visited.end())
     129                 :            :   {
     130                 :     131630 :     visited.insert(lit);
     131         [ +  + ]:     131630 :     if (lit == pv)
     132                 :            :     {
     133                 :       6175 :       return sv;
     134                 :            :     }
     135                 :            :     else
     136                 :            :     {
     137                 :     125455 :       unsigned rmod = 0;  // TODO : randomize?
     138         [ +  + ]:     307652 :       for (size_t i = 0, num = lit.getNumChildren(); i < num; i++)
     139                 :            :       {
     140                 :     194667 :         size_t ii = (i + rmod) % lit.getNumChildren();
     141                 :            :         // only recurse if the kind is invertible
     142                 :            :         // this allows us to avoid paths that go through skolem functions
     143         [ +  + ]:     194667 :         if (!isInvertible(lit.getKind()))
     144                 :            :         {
     145                 :     102494 :           continue;
     146                 :            :         }
     147                 :     184346 :         Node litc = getPathToPv(lit[ii], pv, sv, path, visited);
     148         [ +  + ]:      92173 :         if (!litc.isNull())
     149                 :            :         {
     150                 :            :           // path is outermost term index last
     151                 :      12470 :           path.push_back(ii);
     152                 :      12470 :           std::vector<Node> children;
     153         [ +  + ]:      12470 :           if (lit.getMetaKind() == kind::metakind::PARAMETERIZED)
     154                 :            :           {
     155                 :         56 :             children.push_back(lit.getOperator());
     156                 :            :           }
     157         [ +  + ]:      37368 :           for (size_t j = 0, num2 = lit.getNumChildren(); j < num2; j++)
     158                 :            :           {
     159         [ +  + ]:      24898 :             children.push_back(j == ii ? litc : lit[j]);
     160                 :            :           }
     161                 :      12470 :           return lit.getNodeManager()->mkNode(lit.getKind(), children);
     162                 :      12470 :         }
     163         [ +  + ]:      92173 :       }
     164                 :            :     }
     165                 :            :   }
     166                 :     113701 :   return Node::null();
     167                 :            : }
     168                 :            : 
     169                 :      40173 : Node BvInverter::getPathToPv(Node lit,
     170                 :            :                              Node pv,
     171                 :            :                              Node sv,
     172                 :            :                              Node pvs,
     173                 :            :                              std::vector<uint32_t>& path,
     174                 :            :                              bool projectNl)
     175                 :            : {
     176                 :      40173 :   std::unordered_set<TNode> visited;
     177                 :      80346 :   Node slit = getPathToPv(lit, pv, sv, path, visited);
     178                 :            :   // if we are able to find a (invertible) path to pv
     179 [ +  + ][ +  + ]:      40173 :   if (!slit.isNull() && !pvs.isNull())
                 [ +  + ]
     180                 :            :   {
     181                 :            :     // substitute pvs for the other occurrences of pv
     182                 :       4106 :     TNode tpv = pv;
     183                 :       4106 :     TNode tpvs = pvs;
     184                 :       4106 :     Node prev_lit = slit;
     185                 :       4106 :     slit = slit.substitute(tpv, tpvs);
     186 [ +  - ][ +  + ]:       4106 :     if (!projectNl && slit != prev_lit)
                 [ +  + ]
     187                 :            :     {
     188                 :            :       // found another occurrence of pv that was not on the solve path,
     189                 :            :       // hence lit is non-linear wrt pv and we return null.
     190                 :        178 :       return Node::null();
     191                 :            :     }
     192 [ +  + ][ +  + ]:       4462 :   }
                 [ +  + ]
     193                 :      39995 :   return slit;
     194                 :      40173 : }
     195                 :            : 
     196                 :            : /*---------------------------------------------------------------------------*/
     197                 :            : 
     198                 :            : /* Drop child at given index from expression.
     199                 :            :  * E.g., dropChild((x + y + z), 1) -> (x + z)  */
     200                 :       5632 : static Node dropChild(Node n, unsigned index)
     201                 :            : {
     202                 :       5632 :   unsigned nchildren = n.getNumChildren();
     203 [ -  + ][ -  + ]:       5632 :   Assert(nchildren > 0);
                 [ -  - ]
     204 [ -  + ][ -  + ]:       5632 :   Assert(index < nchildren);
                 [ -  - ]
     205                 :            : 
     206         [ +  + ]:       5632 :   if (nchildren < 2) return Node::null();
     207                 :            : 
     208                 :       5382 :   Kind k = n.getKind();
     209                 :       5382 :   NodeBuilder nb(n.getNodeManager(), k);
     210         [ +  + ]:      16338 :   for (unsigned i = 0; i < nchildren; ++i)
     211                 :            :   {
     212         [ +  + ]:      10956 :     if (i == index) continue;
     213                 :       5574 :     nb << n[i];
     214                 :            :   }
     215 [ -  + ][ -  + ]:       5382 :   Assert(nb.getNumChildren() > 0);
                 [ -  - ]
     216         [ +  + ]:       5382 :   return nb.getNumChildren() == 1 ? nb[0] : nb.constructNode();
     217                 :       5382 : }
     218                 :            : 
     219                 :       5991 : Node BvInverter::solveBvLit(Node sv,
     220                 :            :                             Node lit,
     221                 :            :                             std::vector<uint32_t>& path,
     222                 :            :                             BvInverterQuery* m)
     223                 :            : {
     224 [ -  + ][ -  + ]:       5991 :   Assert(!path.empty());
                 [ -  - ]
     225                 :            : 
     226                 :       5991 :   bool pol = true;
     227                 :            :   uint32_t index;
     228                 :            :   Kind k, litk;
     229                 :            : 
     230 [ -  + ][ -  + ]:       5991 :   Assert(!path.empty());
                 [ -  - ]
     231                 :       5991 :   index = path.back();
     232 [ -  + ][ -  + ]:       5991 :   Assert(index < lit.getNumChildren());
                 [ -  - ]
     233                 :       5991 :   path.pop_back();
     234                 :       5991 :   litk = k = lit.getKind();
     235                 :            : 
     236                 :       5991 :   NodeManager* nm = lit.getNodeManager();
     237                 :            : 
     238                 :            :   /* Note: option --bool-to-bv is currently disabled when CBQI BV
     239                 :            :    *       is enabled and the logic is quantified.
     240                 :            :    *       We currently do not support Boolean operators
     241                 :            :    *       that are interpreted as bit-vector operators of width 1.  */
     242                 :            : 
     243                 :            :   /* Boolean layer ----------------------------------------------- */
     244                 :            : 
     245         [ +  + ]:       5991 :   if (k == Kind::NOT)
     246                 :            :   {
     247                 :         60 :     pol = !pol;
     248                 :         60 :     lit = lit[index];
     249 [ -  + ][ -  + ]:         60 :     Assert(!path.empty());
                 [ -  - ]
     250                 :         60 :     index = path.back();
     251 [ -  + ][ -  + ]:         60 :     Assert(index < lit.getNumChildren());
                 [ -  - ]
     252                 :         60 :     path.pop_back();
     253                 :         60 :     litk = k = lit.getKind();
     254                 :            :   }
     255                 :            : 
     256 [ +  + ][ +  - ]:       5991 :   Assert(k == Kind::EQUAL || k == Kind::BITVECTOR_ULT
         [ -  + ][ -  - ]
         [ -  + ][ -  + ]
                 [ -  - ]
     257                 :            :          || k == Kind::BITVECTOR_SLT);
     258                 :            : 
     259                 :       5991 :   Node sv_t = lit[index];
     260                 :       5991 :   Node t = lit[1 - index];
     261 [ +  + ][ +  - ]:       5991 :   if (litk == Kind::BITVECTOR_ULT && index == 1)
     262                 :            :   {
     263                 :          2 :     litk = Kind::BITVECTOR_UGT;
     264                 :            :   }
     265 [ -  + ][ -  - ]:       5989 :   else if (litk == Kind::BITVECTOR_SLT && index == 1)
     266                 :            :   {
     267                 :          0 :     litk = Kind::BITVECTOR_SGT;
     268                 :            :   }
     269                 :            : 
     270                 :            :   /* Bit-vector layer -------------------------------------------- */
     271                 :            : 
     272         [ +  + ]:       8903 :   while (!path.empty())
     273                 :            :   {
     274                 :       5632 :     unsigned nchildren = sv_t.getNumChildren();
     275 [ -  + ][ -  + ]:       5632 :     Assert(nchildren > 0);
                 [ -  - ]
     276                 :       5632 :     index = path.back();
     277 [ -  + ][ -  + ]:       5632 :     Assert(index < nchildren);
                 [ -  - ]
     278                 :       5632 :     path.pop_back();
     279                 :       5632 :     k = sv_t.getKind();
     280                 :            : 
     281                 :            :     /* Note: All n-ary kinds except for CONCAT (i.e., BITVECTOR_AND,
     282                 :            :      *       BITVECTOR_OR, MULT, ADD) are commutative (no case split
     283                 :            :      *       based on index). */
     284                 :       5632 :     Node s = dropChild(sv_t, index);
     285 [ +  + ][ +  - ]:       5632 :     Assert((nchildren == 1 && s.isNull()) || (nchildren > 1 && !s.isNull()));
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
                 [ -  - ]
     286                 :       5632 :     TypeNode solve_tn = sv_t[index].getType();
     287                 :       5632 :     Node x = getSolveVariable(solve_tn);
     288                 :       5632 :     Node ic;
     289                 :            : 
     290         [ +  - ]:       5632 :     if (litk == Kind::EQUAL
     291 [ +  + ][ +  + ]:       5632 :         && (k == Kind::BITVECTOR_NOT || k == Kind::BITVECTOR_NEG))
     292                 :            :     {
     293                 :        194 :       t = NodeManager::mkNode(k, t);
     294                 :            :     }
     295 [ +  - ][ +  + ]:       5438 :     else if (litk == Kind::EQUAL && k == Kind::BITVECTOR_ADD)
     296                 :            :     {
     297                 :       1139 :       t = NodeManager::mkNode(Kind::BITVECTOR_SUB, t, s);
     298                 :            :     }
     299 [ +  - ][ +  + ]:       4299 :     else if (litk == Kind::EQUAL && k == Kind::BITVECTOR_XOR)
     300                 :            :     {
     301                 :        211 :       t = NodeManager::mkNode(Kind::BITVECTOR_XOR, t, s);
     302                 :            :     }
     303 [ +  + ][ +  + ]:       4088 :     else if (litk == Kind::EQUAL && k == Kind::BITVECTOR_MULT && s.isConst()
     304 [ +  - ][ +  + ]:       8176 :              && bv::utils::getBit(s, 0))
         [ +  + ][ +  + ]
                 [ -  - ]
     305                 :            :     {
     306                 :        257 :       unsigned w = bv::utils::getSize(s);
     307                 :        257 :       Integer s_val = s.getConst<BitVector>().toInteger();
     308                 :        257 :       Integer mod_val = Integer(1).multiplyByPow2(w);
     309         [ +  - ]:        514 :       Trace("bv-invert-debug")
     310                 :        257 :           << "Compute inverse : " << s_val << " " << mod_val << std::endl;
     311                 :        257 :       Integer inv_val = s_val.modInverse(mod_val);
     312         [ +  - ]:        257 :       Trace("bv-invert-debug") << "Inverse : " << inv_val << std::endl;
     313                 :        257 :       Node inv = bv::utils::mkConst(nm, w, inv_val);
     314                 :        257 :       t = NodeManager::mkNode(Kind::BITVECTOR_MULT, inv, t);
     315                 :        257 :     }
     316         [ +  + ]:       3831 :     else if (k == Kind::BITVECTOR_MULT)
     317                 :            :     {
     318                 :        270 :       ic = utils::getICBvMult(pol, litk, k, index, x, s, t);
     319                 :            :     }
     320         [ +  + ]:       3561 :     else if (k == Kind::BITVECTOR_SHL)
     321                 :            :     {
     322                 :        238 :       ic = utils::getICBvShl(pol, litk, k, index, x, s, t);
     323                 :            :     }
     324         [ +  + ]:       3323 :     else if (k == Kind::BITVECTOR_UREM)
     325                 :            :     {
     326                 :        201 :       ic = utils::getICBvUrem(pol, litk, k, index, x, s, t);
     327                 :            :     }
     328         [ +  + ]:       3122 :     else if (k == Kind::BITVECTOR_UDIV)
     329                 :            :     {
     330                 :        193 :       ic = utils::getICBvUdiv(pol, litk, k, index, x, s, t);
     331                 :            :     }
     332 [ +  + ][ +  + ]:       2929 :     else if (k == Kind::BITVECTOR_AND || k == Kind::BITVECTOR_OR)
     333                 :            :     {
     334                 :        554 :       ic = utils::getICBvAndOr(pol, litk, k, index, x, s, t);
     335                 :            :     }
     336         [ +  + ]:       2375 :     else if (k == Kind::BITVECTOR_LSHR)
     337                 :            :     {
     338                 :        214 :       ic = utils::getICBvLshr(pol, litk, k, index, x, s, t);
     339                 :            :     }
     340         [ +  + ]:       2161 :     else if (k == Kind::BITVECTOR_ASHR)
     341                 :            :     {
     342                 :        218 :       ic = utils::getICBvAshr(pol, litk, k, index, x, s, t);
     343                 :            :     }
     344         [ +  + ]:       1943 :     else if (k == Kind::BITVECTOR_CONCAT)
     345                 :            :     {
     346         [ +  - ]:        321 :       if (litk == Kind::EQUAL)
     347                 :            :       {
     348                 :            :         /* Compute inverse for s1 o x, x o s2, s1 o x o s2
     349                 :            :          * (while disregarding that invertibility depends on si)
     350                 :            :          * rather than an invertibility condition (the proper handling).
     351                 :            :          * This improves performance on a considerable number of benchmarks.
     352                 :            :          *
     353                 :            :          * x = t[upper:lower]
     354                 :            :          * where
     355                 :            :          * upper = getSize(t) - 1 - sum(getSize(sv_t[i])) for i < index
     356                 :            :          * lower = getSize(sv_t[i]) for i > index  */
     357                 :            :         unsigned upper, lower;
     358                 :        321 :         upper = bv::utils::getSize(t) - 1;
     359                 :        321 :         lower = 0;
     360                 :        321 :         NodeBuilder nb(nm, Kind::BITVECTOR_CONCAT);
     361         [ +  + ]:       1016 :         for (unsigned i = 0; i < nchildren; i++)
     362                 :            :         {
     363         [ +  + ]:        695 :           if (i < index)
     364                 :            :           {
     365                 :        105 :             upper -= bv::utils::getSize(sv_t[i]);
     366                 :            :           }
     367         [ +  + ]:        590 :           else if (i > index)
     368                 :            :           {
     369                 :        269 :             lower += bv::utils::getSize(sv_t[i]);
     370                 :            :           }
     371                 :            :         }
     372                 :        321 :         t = bv::utils::mkExtract(t, upper, lower);
     373                 :        321 :       }
     374                 :            :       else
     375                 :            :       {
     376                 :          0 :         ic = utils::getICBvConcat(pol, litk, index, x, sv_t, t);
     377                 :            :       }
     378                 :            :     }
     379         [ +  + ]:       1622 :     else if (k == Kind::BITVECTOR_SIGN_EXTEND)
     380                 :            :     {
     381                 :         56 :       ic = utils::getICBvSext(pol, litk, index, x, sv_t, t);
     382                 :            :     }
     383 [ +  - ][ -  + ]:       1566 :     else if (litk == Kind::BITVECTOR_ULT || litk == Kind::BITVECTOR_UGT)
     384                 :            :     {
     385                 :          0 :       ic = utils::getICBvUltUgt(pol, litk, x, t);
     386                 :            :     }
     387 [ +  - ][ -  + ]:       1566 :     else if (litk == Kind::BITVECTOR_SLT || litk == Kind::BITVECTOR_SGT)
     388                 :            :     {
     389                 :          0 :       ic = utils::getICBvSltSgt(pol, litk, x, t);
     390                 :            :     }
     391         [ -  + ]:       1566 :     else if (pol == false)
     392                 :            :     {
     393                 :          0 :       Assert(litk == Kind::EQUAL);
     394                 :          0 :       ic = NodeManager::mkNode(Kind::DISTINCT, x, t);
     395         [ -  - ]:          0 :       Trace("bv-invert") << "Add SC_" << litk << "(" << x << "): " << ic
     396                 :          0 :                          << std::endl;
     397                 :            :     }
     398                 :            :     else
     399                 :            :     {
     400         [ +  - ]:       3132 :       Trace("bv-invert") << "bv-invert : Unknown kind " << k
     401                 :       1566 :                          << " for bit-vector term " << sv_t << std::endl;
     402                 :       1566 :       return Node::null();
     403                 :            :     }
     404                 :            : 
     405         [ +  + ]:       4066 :     if (!ic.isNull())
     406                 :            :     {
     407                 :            :       /* We generate a witness term (witness x0. ic => x0 <k> s <litk> t) for
     408                 :            :        * x <k> s <litk> t. When traversing down, this witness term determines
     409                 :            :        * the value for x <k> s = (witness x0. ic => x0 <k> s <litk> t), i.e.,
     410                 :            :        * from here on, the propagated literal is a positive equality. */
     411                 :       1944 :       litk = Kind::EQUAL;
     412                 :       1944 :       pol = true;
     413                 :            :       /* t = fresh skolem constant */
     414                 :       1944 :       t = getInversionNode(ic, solve_tn, m);
     415         [ +  + ]:       1944 :       if (t.isNull())
     416                 :            :       {
     417                 :       1154 :         return t;
     418                 :            :       }
     419                 :            :     }
     420                 :            : 
     421                 :       2912 :     sv_t = sv_t[index];
     422 [ +  + ][ +  + ]:      13792 :   }
         [ +  + ][ +  + ]
     423                 :            : 
     424                 :            :   /* Base case  */
     425 [ -  + ][ -  + ]:       3271 :   Assert(sv_t == sv);
                 [ -  - ]
     426                 :       3271 :   TypeNode solve_tn = sv.getType();
     427                 :       3271 :   Node x = getSolveVariable(solve_tn);
     428                 :       3271 :   Node ic;
     429 [ +  - ][ +  + ]:       3271 :   if (litk == Kind::BITVECTOR_ULT || litk == Kind::BITVECTOR_UGT)
     430                 :            :   {
     431                 :          2 :     ic = utils::getICBvUltUgt(pol, litk, x, t);
     432                 :            :   }
     433 [ +  - ][ -  + ]:       3269 :   else if (litk == Kind::BITVECTOR_SLT || litk == Kind::BITVECTOR_SGT)
     434                 :            :   {
     435                 :          0 :     ic = utils::getICBvSltSgt(pol, litk, x, t);
     436                 :            :   }
     437         [ +  + ]:       3269 :   else if (pol == false)
     438                 :            :   {
     439 [ -  + ][ -  + ]:         21 :     Assert(litk == Kind::EQUAL);
                 [ -  - ]
     440                 :         21 :     ic = NodeManager::mkNode(Kind::DISTINCT, x, t);
     441         [ +  - ]:         42 :     Trace("bv-invert") << "Add SC_" << litk << "(" << x << "): " << ic
     442                 :         21 :                        << std::endl;
     443                 :            :   }
     444                 :            : 
     445                 :       3271 :   return ic.isNull() ? t : getInversionNode(ic, solve_tn, m);
     446                 :       5991 : }
     447                 :            : 
     448                 :            : /*---------------------------------------------------------------------------*/
     449                 :            : 
     450                 :            : }  // namespace quantifiers
     451                 :            : }  // namespace theory
     452                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14