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: 193 208 92.8 %
Date: 2024-09-19 10:47:20 Functions: 8 8 100.0 %
Branches: 202 296 68.2 %

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

Generated by: LCOV version 1.14