LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers - term_util.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 239 311 76.8 %
Date: 2026-02-27 11:41:18 Functions: 22 25 88.0 %
Branches: 317 430 73.7 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Implementation of term utilities class.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/quantifiers/term_util.h"
      14                 :            : 
      15                 :            : #include "expr/array_store_all.h"
      16                 :            : #include "expr/function_array_const.h"
      17                 :            : #include "expr/node_algorithm.h"
      18                 :            : #include "expr/sequence.h"
      19                 :            : #include "expr/skolem_manager.h"
      20                 :            : #include "theory/arith/arith_msum.h"
      21                 :            : #include "theory/bv/theory_bv_utils.h"
      22                 :            : #include "theory/quantifiers/term_database.h"
      23                 :            : #include "theory/quantifiers/term_enumeration.h"
      24                 :            : #include "theory/rewriter.h"
      25                 :            : #include "theory/strings/word.h"
      26                 :            : #include "util/bitvector.h"
      27                 :            : #include "util/rational.h"
      28                 :            : 
      29                 :            : using namespace cvc5::internal::kind;
      30                 :            : 
      31                 :            : namespace cvc5::internal {
      32                 :            : namespace theory {
      33                 :            : namespace quantifiers {
      34                 :            : 
      35                 :       6591 : size_t TermUtil::getVariableNum(Node q, Node v)
      36                 :            : {
      37                 :       6591 :   Node::iterator it = std::find(q[0].begin(), q[0].end(), v);
      38 [ -  + ][ -  + ]:       6591 :   Assert(it != q[0].end());
                 [ -  - ]
      39                 :       6591 :   return it - q[0].begin();
      40                 :            : }
      41                 :            : 
      42                 :      27421 : Node TermUtil::getRemoveQuantifiers2( Node n, std::map< Node, Node >& visited ) {
      43                 :      27421 :   std::map< Node, Node >::iterator it = visited.find( n );
      44         [ +  + ]:      27421 :   if( it!=visited.end() ){
      45                 :      10110 :     return it->second;
      46                 :            :   }else{
      47                 :      17311 :     Node ret = n;
      48         [ +  + ]:      17311 :     if (n.getKind() == Kind::FORALL)
      49                 :            :     {
      50                 :       1060 :       ret = getRemoveQuantifiers2( n[1], visited );
      51                 :            :     }
      52         [ +  + ]:      16251 :     else if (n.getNumChildren() > 0)
      53                 :            :     {
      54                 :      11480 :       std::vector< Node > children;
      55                 :      11480 :       bool childrenChanged = false;
      56         [ +  + ]:      36769 :       for( unsigned i=0; i<n.getNumChildren(); i++ ){
      57                 :      25289 :         Node ni = getRemoveQuantifiers2( n[i], visited );
      58 [ +  + ][ +  + ]:      25289 :         childrenChanged = childrenChanged || ni!=n[i];
         [ +  + ][ -  - ]
      59                 :      25289 :         children.push_back( ni );
      60                 :      25289 :       }
      61         [ +  + ]:      11480 :       if( childrenChanged ){
      62         [ -  + ]:         12 :         if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
      63                 :          0 :           children.insert( children.begin(), n.getOperator() );
      64                 :            :         }
      65                 :         12 :         ret = n.getNodeManager()->mkNode(n.getKind(), children);
      66                 :            :       }
      67                 :      11480 :     }
      68                 :      17311 :     visited[n] = ret;
      69                 :      17311 :     return ret;
      70                 :      17311 :   }
      71                 :            : }
      72                 :            : 
      73                 :   13965423 : Node TermUtil::getInstConstAttr( Node n ) {
      74         [ +  + ]:   13965423 :   if (!n.hasAttribute(InstConstantAttribute()))
      75                 :            :   {
      76                 :    1099840 :     Node q;
      77         [ +  + ]:    1099840 :     if (n.isVar())
      78                 :            :     {
      79                 :            :       // If it is a purification variable, it may correspond to a term
      80                 :            :       // with instantiation constants in it. We get the unpurified form here
      81                 :            :       // to handle this case.
      82                 :     172322 :       Node un = SkolemManager::getUnpurifiedForm(n);
      83 [ +  - ][ +  + ]:     172322 :       if (!un.isNull() && un != n)
                 [ +  + ]
      84                 :            :       {
      85                 :      76481 :         q = getInstConstAttr(un);
      86                 :            :       }
      87                 :     172322 :     }
      88                 :            :     else
      89                 :            :     {
      90         [ +  + ]:    2238270 :       for (const Node& nc : n)
      91                 :            :       {
      92                 :    1540560 :         q = getInstConstAttr(nc);
      93         [ +  + ]:    1540560 :         if (!q.isNull())
      94                 :            :         {
      95                 :     229808 :           break;
      96                 :            :         }
      97         [ +  + ]:    1540560 :       }
      98         [ +  + ]:     927518 :       if (q.isNull())
      99                 :            :       {
     100         [ +  + ]:     697710 :         if (n.hasOperator())
     101                 :            :         {
     102                 :     590096 :           q = getInstConstAttr(n.getOperator());
     103                 :            :         }
     104                 :            :       }
     105                 :            :     }
     106                 :            :     InstConstantAttribute ica;
     107                 :    1099840 :     n.setAttribute(ica, q);
     108                 :    1099840 :   }
     109                 :   27930846 :   return n.getAttribute(InstConstantAttribute());
     110                 :            : }
     111                 :            : 
     112                 :    7818165 : bool TermUtil::hasInstConstAttr(Node n)
     113                 :            : {
     114                 :    7818165 :   return !getInstConstAttr(n).isNull();
     115                 :            : }
     116                 :            : 
     117                 :            : //remove quantifiers
     118                 :       1072 : Node TermUtil::getRemoveQuantifiers( Node n ) {
     119                 :       1072 :   std::map< Node, Node > visited;
     120                 :       2144 :   return getRemoveQuantifiers2( n, visited );
     121                 :       1072 : }
     122                 :            : 
     123                 :     271048 : void TermUtil::computeInstConstContainsForQuant(Node q,
     124                 :            :                                                 Node n,
     125                 :            :                                                 std::vector<Node>& vars)
     126                 :            : {
     127                 :     271048 :   std::unordered_set<Node> ics;
     128                 :     271048 :   expr::getSubtermsKind(Kind::INST_CONSTANT, n, ics);
     129         [ +  + ]:    1032676 :   for (const Node& v : ics)
     130                 :            :   {
     131         [ +  - ]:     761628 :     if (v.getAttribute(InstConstantAttribute()) == q)
     132                 :            :     {
     133         [ +  + ]:     761628 :       if (std::find(vars.begin(), vars.end(), v) == vars.end())
     134                 :            :       {
     135                 :     761626 :         vars.push_back(v);
     136                 :            :       }
     137                 :            :     }
     138                 :            :   }
     139                 :     271048 : }
     140                 :            : 
     141                 :          0 : int TermUtil::getTermDepth( Node n ) {
     142         [ -  - ]:          0 :   if (!n.hasAttribute(TermDepthAttribute()) ){
     143                 :          0 :     int maxDepth = -1;
     144         [ -  - ]:          0 :     for( unsigned i=0; i<n.getNumChildren(); i++ ){
     145                 :          0 :       int depth = getTermDepth( n[i] );
     146         [ -  - ]:          0 :       if( depth>maxDepth ){
     147                 :          0 :         maxDepth = depth;
     148                 :            :       }
     149                 :            :     }
     150                 :            :     TermDepthAttribute tda;
     151                 :          0 :     n.setAttribute(tda,1+maxDepth);
     152                 :            :   }
     153                 :          0 :   return n.getAttribute(TermDepthAttribute());
     154                 :            : }
     155                 :            : 
     156                 :     504721 : bool TermUtil::containsUninterpretedConstant( Node n ) {
     157         [ +  + ]:     504721 :   if (n.hasAttribute(ContainsUConstAttribute()))
     158                 :            :   {
     159                 :     464370 :     return n.getAttribute(ContainsUConstAttribute()) != 0;
     160                 :            :   }
     161                 :      40351 :   bool ret = false;
     162                 :      40351 :   Kind k = n.getKind();
     163         [ +  + ]:      40351 :   if (k == Kind::UNINTERPRETED_SORT_VALUE)
     164                 :            :   {
     165 [ -  + ][ -  + ]:       1431 :     Assert(n.getType().isUninterpretedSort());
                 [ -  - ]
     166                 :       1431 :     ret = true;
     167                 :            :   }
     168         [ +  + ]:      38920 :   else if (k == Kind::STORE_ALL)
     169                 :            :   {
     170                 :          8 :     ret = containsUninterpretedConstant(n.getConst<ArrayStoreAll>().getValue());
     171                 :            :   }
     172         [ -  + ]:      38912 :   else if (k == Kind::FUNCTION_ARRAY_CONST)
     173                 :            :   {
     174                 :          0 :     ret = containsUninterpretedConstant(
     175                 :          0 :         n.getConst<FunctionArrayConst>().getArrayValue());
     176                 :            :   }
     177         [ +  + ]:      38912 :   else if (k == Kind::CONST_SEQUENCE)
     178                 :            :   {
     179                 :          6 :     const std::vector<Node>& charVec = n.getConst<Sequence>().getVec();
     180         [ -  + ]:          6 :     for (const Node& nc : charVec)
     181                 :            :     {
     182         [ -  - ]:          0 :       if (containsUninterpretedConstant(nc))
     183                 :            :       {
     184                 :          0 :         ret = true;
     185                 :          0 :         break;
     186                 :            :       }
     187                 :            :     }
     188                 :            :   }
     189                 :            :   else
     190                 :            :   {
     191         [ +  + ]:      70922 :     for (const Node& nc : n)
     192                 :            :     {
     193         [ -  + ]:      32016 :       if (containsUninterpretedConstant(nc))
     194                 :            :       {
     195                 :          0 :         ret = true;
     196                 :          0 :         break;
     197                 :            :       }
     198         [ +  - ]:      32016 :     }
     199                 :            :   }
     200                 :            :   ContainsUConstAttribute cuca;
     201         [ +  + ]:      40351 :   n.setAttribute(cuca, ret ? 1 : 0);
     202                 :      40351 :   return ret;
     203                 :            : }
     204                 :            : 
     205                 :      15058 : Node TermUtil::simpleNegate(Node n)
     206                 :            : {
     207 [ -  + ][ -  + ]:      15058 :   Assert(n.getType().isBoolean());
                 [ -  - ]
     208                 :      15058 :   NodeManager* nm = n.getNodeManager();
     209 [ +  + ][ +  + ]:      15058 :   if (n.getKind() == Kind::OR || n.getKind() == Kind::AND)
                 [ +  + ]
     210                 :            :   {
     211                 :       3513 :     std::vector< Node > children;
     212         [ +  + ]:      13034 :     for (const Node& cn : n)
     213                 :            :     {
     214                 :       9521 :       children.push_back(simpleNegate(cn));
     215                 :       9521 :     }
     216         [ +  + ]:       3513 :     return nm->mkNode(n.getKind() == Kind::OR ? Kind::AND : Kind::OR, children);
     217                 :       3513 :   }
     218         [ +  + ]:      11545 :   else if (n.isConst())
     219                 :            :   {
     220                 :       6320 :     return nm->mkConst(!n.getConst<bool>());
     221                 :            :   }
     222                 :       8385 :   return n.negate();
     223                 :            : }
     224                 :            : 
     225                 :       6819 : Node TermUtil::mkNegate(Kind notk, Node n)
     226                 :            : {
     227         [ +  + ]:       6819 :   if (n.getKind() == notk)
     228                 :            :   {
     229                 :        592 :     return n[0];
     230                 :            :   }
     231                 :       6227 :   return NodeManager::mkNode(notk, n);
     232                 :            : }
     233                 :            : 
     234                 :      15452 : bool TermUtil::isNegate(Kind k)
     235                 :            : {
     236 [ +  + ][ +  + ]:      14817 :   return k == Kind::NOT || k == Kind::BITVECTOR_NOT || k == Kind::BITVECTOR_NEG
     237 [ +  + ][ -  + ]:      30269 :          || k == Kind::NEG;
     238                 :            : }
     239                 :            : 
     240                 :     247859 : bool TermUtil::isAssoc(Kind k, bool reqNAry)
     241                 :            : {
     242         [ +  + ]:     247859 :   if (reqNAry)
     243                 :            :   {
     244 [ +  + ][ +  + ]:     246946 :     if (k == Kind::SET_UNION || k == Kind::SET_INTER)
     245                 :            :     {
     246                 :         62 :       return false;
     247                 :            :     }
     248                 :            :   }
     249 [ +  + ][ +  + ]:     229027 :   return k == Kind::ADD || k == Kind::MULT || k == Kind::NONLINEAR_MULT
     250 [ +  + ][ +  + ]:     223482 :          || k == Kind::AND || k == Kind::OR || k == Kind::XOR
                 [ +  + ]
     251 [ +  + ][ +  + ]:     148189 :          || k == Kind::BITVECTOR_ADD || k == Kind::BITVECTOR_MULT
     252 [ +  + ][ +  + ]:     139879 :          || k == Kind::BITVECTOR_AND || k == Kind::BITVECTOR_OR
     253 [ +  + ][ +  - ]:     130516 :          || k == Kind::BITVECTOR_XOR || k == Kind::BITVECTOR_XNOR
     254 [ +  + ][ +  + ]:     130402 :          || k == Kind::BITVECTOR_CONCAT || k == Kind::STRING_CONCAT
     255 [ +  + ][ +  + ]:     127647 :          || k == Kind::SET_UNION || k == Kind::SET_INTER
     256 [ +  - ][ +  - ]:     127639 :          || k == Kind::RELATION_JOIN || k == Kind::RELATION_TABLE_JOIN
     257 [ +  + ][ +  - ]:     476824 :          || k == Kind::RELATION_PRODUCT || k == Kind::SEP_STAR;
                 [ -  + ]
     258                 :            : }
     259                 :            : 
     260                 :     830145 : bool TermUtil::isComm(Kind k, bool reqNAry)
     261                 :            : {
     262         [ -  + ]:     830145 :   if (reqNAry)
     263                 :            :   {
     264 [ -  - ][ -  - ]:          0 :     if (k == Kind::SET_UNION || k == Kind::SET_INTER)
     265                 :            :     {
     266                 :          0 :       return false;
     267                 :            :     }
     268                 :            :   }
     269 [ +  + ][ +  + ]:     708320 :   return k == Kind::EQUAL || k == Kind::ADD || k == Kind::MULT
     270 [ +  + ][ +  + ]:     636037 :          || k == Kind::NONLINEAR_MULT || k == Kind::AND || k == Kind::OR
                 [ +  + ]
     271 [ +  + ][ +  + ]:     511479 :          || k == Kind::XOR || k == Kind::BITVECTOR_ADD
     272 [ +  + ][ +  + ]:     507519 :          || k == Kind::BITVECTOR_MULT || k == Kind::BITVECTOR_AND
     273 [ +  + ][ +  + ]:     497734 :          || k == Kind::BITVECTOR_OR || k == Kind::BITVECTOR_XOR
     274 [ +  - ][ +  + ]:     492309 :          || k == Kind::BITVECTOR_XNOR || k == Kind::SET_UNION
     275 [ +  + ][ +  + ]:    1538465 :          || k == Kind::SET_INTER || k == Kind::SEP_STAR;
                 [ +  + ]
     276                 :            : }
     277                 :            : 
     278                 :     247218 : bool TermUtil::isNonAdditive( Kind k ) {
     279 [ +  + ][ +  + ]:     207009 :   return k == Kind::AND || k == Kind::OR || k == Kind::BITVECTOR_AND
     280 [ +  + ][ +  + ]:     454227 :          || k == Kind::BITVECTOR_OR;
     281                 :            : }
     282                 :            : 
     283                 :     712554 : bool TermUtil::isBoolConnective( Kind k ) {
     284 [ +  + ][ +  + ]:     617563 :   return k == Kind::OR || k == Kind::AND || k == Kind::EQUAL || k == Kind::ITE
                 [ +  + ]
     285 [ +  + ][ +  + ]:    1330117 :          || k == Kind::FORALL || k == Kind::NOT || k == Kind::SEP_STAR;
         [ +  + ][ +  + ]
     286                 :            : }
     287                 :            : 
     288                 :     608283 : bool TermUtil::isBoolConnectiveTerm( TNode n ) {
     289                 :     608283 :   return isBoolConnective(n.getKind())
     290                 :    1032228 :          && (n.getKind() != Kind::EQUAL || n[0].getType().isBoolean())
     291 [ +  + ][ +  + ]:    2248794 :          && (n.getKind() != Kind::ITE || n.getType().isBoolean());
         [ +  + ][ +  + ]
         [ +  + ][ -  - ]
     292                 :            : }
     293                 :            : 
     294                 :      83148 : Node TermUtil::mkTypeValue(TypeNode tn, int32_t val)
     295                 :            : {
     296                 :      83148 :   Node n;
     297         [ +  + ]:      83148 :   if (tn.isRealOrInt())
     298                 :            :   {
     299                 :       6550 :     Rational c(val);
     300                 :       6550 :     n = tn.getNodeManager()->mkConstRealOrInt(tn, c);
     301                 :       6550 :   }
     302         [ +  + ]:      76598 :   else if (tn.isBitVector())
     303                 :            :   {
     304                 :            :     // cast to unsigned
     305                 :        802 :     uint32_t uv = static_cast<uint32_t>(val);
     306                 :        802 :     BitVector bval(tn.getConst<BitVectorSize>(), uv);
     307                 :        802 :     n = tn.getNodeManager()->mkConst<BitVector>(bval);
     308                 :        802 :   }
     309         [ +  + ]:      75796 :   else if (tn.isBoolean())
     310                 :            :   {
     311         [ +  + ]:      75290 :     if (val == 0)
     312                 :            :     {
     313                 :      74728 :       n = tn.getNodeManager()->mkConst(false);
     314                 :            :     }
     315                 :            :   }
     316         [ +  + ]:        506 :   else if (tn.isStringLike())
     317                 :            :   {
     318         [ +  + ]:        386 :     if (val == 0)
     319                 :            :     {
     320                 :        208 :       n = strings::Word::mkEmptyWord(tn);
     321                 :            :     }
     322                 :            :   }
     323                 :      83148 :   return n;
     324                 :          0 : }
     325                 :            : 
     326                 :      76732 : Node TermUtil::mkTypeMaxValue(TypeNode tn)
     327                 :            : {
     328                 :      76732 :   Node n;
     329                 :      76732 :   NodeManager* nm = tn.getNodeManager();
     330         [ +  + ]:      76732 :   if (tn.isBitVector())
     331                 :            :   {
     332                 :        142 :     n = bv::utils::mkOnes(nm, tn.getConst<BitVectorSize>());
     333                 :            :   }
     334         [ +  + ]:      76590 :   else if (tn.isBoolean())
     335                 :            :   {
     336                 :      74432 :     n = nm->mkConst(true);
     337                 :            :   }
     338                 :      76732 :   return n;
     339                 :          0 : }
     340                 :            : 
     341                 :          8 : Node TermUtil::mkTypeValueOffset(TypeNode tn,
     342                 :            :                                  Node val,
     343                 :            :                                  int32_t offset,
     344                 :            :                                  int32_t& status)
     345                 :            : {
     346                 :          8 :   Assert(val.isConst() && val.getType() == tn);
     347                 :          8 :   Node val_o;
     348                 :          8 :   status = -1;
     349         [ +  - ]:          8 :   if (tn.isRealOrInt())
     350                 :            :   {
     351                 :          8 :     Rational vval = val.getConst<Rational>();
     352                 :          8 :     Rational oval(offset);
     353                 :          8 :     status = 0;
     354                 :         16 :     return NodeManager::mkConstRealOrInt(tn, vval + oval);
     355                 :          8 :   }
     356         [ -  - ]:          0 :   else if (tn.isBitVector())
     357                 :            :   {
     358                 :          0 :     BitVector vval = val.getConst<BitVector>();
     359                 :          0 :     uint32_t uv = static_cast<uint32_t>(offset);
     360                 :          0 :     BitVector oval(tn.getConst<BitVectorSize>(), uv);
     361                 :          0 :     return tn.getNodeManager()->mkConst(vval + oval);
     362                 :          0 :   }
     363                 :          0 :   return val_o;
     364                 :          8 : }
     365                 :            : 
     366                 :          0 : Node TermUtil::mkTypeConst(TypeNode tn, bool pol)
     367                 :            : {
     368                 :          0 :   return pol ? mkTypeMaxValue(tn) : mkTypeValue(tn, 0);
     369                 :            : }
     370                 :            : 
     371                 :          0 : bool TermUtil::isAntisymmetric(Kind k, Kind& dk)
     372                 :            : {
     373         [ -  - ]:          0 :   if (k == Kind::GT)
     374                 :            :   {
     375                 :          0 :     dk = Kind::LT;
     376                 :          0 :     return true;
     377                 :            :   }
     378         [ -  - ]:          0 :   else if (k == Kind::GEQ)
     379                 :            :   {
     380                 :          0 :     dk = Kind::LEQ;
     381                 :          0 :     return true;
     382                 :            :   }
     383         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_UGT)
     384                 :            :   {
     385                 :          0 :     dk = Kind::BITVECTOR_ULT;
     386                 :          0 :     return true;
     387                 :            :   }
     388         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_UGE)
     389                 :            :   {
     390                 :          0 :     dk = Kind::BITVECTOR_ULE;
     391                 :          0 :     return true;
     392                 :            :   }
     393         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_SGT)
     394                 :            :   {
     395                 :          0 :     dk = Kind::BITVECTOR_SLT;
     396                 :          0 :     return true;
     397                 :            :   }
     398         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_SGE)
     399                 :            :   {
     400                 :          0 :     dk = Kind::BITVECTOR_SLE;
     401                 :          0 :     return true;
     402                 :            :   }
     403                 :          0 :   return false;
     404                 :            : }
     405                 :            : 
     406                 :       1974 : bool TermUtil::isIdempotentArg(Node n, Kind ik, int arg)
     407                 :            : {
     408                 :            :   // these should all be binary operators
     409                 :            :   // Assert( ik!=DIVISION && ik!=INTS_DIVISION && ik!=INTS_MODULUS &&
     410                 :            :   // ik!=BITVECTOR_UDIV );
     411                 :       1974 :   TypeNode tn = n.getType();
     412         [ +  + ]:       1974 :   if (n == mkTypeValue(tn, 0))
     413                 :            :   {
     414 [ +  + ][ +  + ]:        776 :     if (ik == Kind::ADD || ik == Kind::OR || ik == Kind::XOR
                 [ +  - ]
     415 [ +  + ][ +  + ]:        624 :         || ik == Kind::BITVECTOR_ADD || ik == Kind::BITVECTOR_OR
     416 [ +  + ][ +  + ]:        600 :         || ik == Kind::BITVECTOR_XOR || ik == Kind::STRING_CONCAT)
     417                 :            :     {
     418                 :        202 :       return true;
     419                 :            :     }
     420 [ +  + ][ +  - ]:        574 :     else if (ik == Kind::SUB || ik == Kind::BITVECTOR_SHL
     421 [ +  + ][ +  + ]:        474 :              || ik == Kind::BITVECTOR_LSHR || ik == Kind::BITVECTOR_ASHR
     422 [ +  + ][ +  + ]:        466 :              || ik == Kind::BITVECTOR_SUB || ik == Kind::BITVECTOR_UREM)
     423                 :            :     {
     424                 :        116 :       return arg == 1;
     425                 :            :     }
     426                 :            :   }
     427         [ +  + ]:       1198 :   else if (n == mkTypeValue(tn, 1))
     428                 :            :   {
     429 [ +  + ][ -  + ]:        558 :     if (ik == Kind::MULT || ik == Kind::BITVECTOR_MULT)
     430                 :            :     {
     431                 :         10 :       return true;
     432                 :            :     }
     433 [ +  + ][ +  - ]:        548 :     else if (ik == Kind::DIVISION || ik == Kind::DIVISION_TOTAL
     434 [ +  - ][ +  - ]:        540 :              || ik == Kind::INTS_DIVISION || ik == Kind::INTS_DIVISION_TOTAL
     435 [ +  - ][ +  - ]:        540 :              || ik == Kind::INTS_MODULUS || ik == Kind::INTS_MODULUS_TOTAL
     436 [ +  + ][ +  + ]:        540 :              || ik == Kind::BITVECTOR_UDIV || ik == Kind::BITVECTOR_SDIV)
     437                 :            :     {
     438                 :         20 :       return arg == 1;
     439                 :            :     }
     440                 :            :   }
     441         [ +  + ]:        640 :   else if (n == mkTypeMaxValue(tn))
     442                 :            :   {
     443 [ +  - ][ +  - ]:        174 :     if (ik == Kind::EQUAL || ik == Kind::BITVECTOR_AND
     444         [ -  + ]:        174 :         || ik == Kind::BITVECTOR_XNOR)
     445                 :            :     {
     446                 :          0 :       return true;
     447                 :            :     }
     448                 :            :   }
     449                 :       1626 :   return false;
     450                 :       1974 : }
     451                 :            : 
     452                 :       1694 : Node TermUtil::isSingularArg(Node n, Kind ik, unsigned arg)
     453                 :            : {
     454                 :       1694 :   TypeNode tn = n.getType();
     455         [ +  + ]:       1694 :   if (n == mkTypeValue(tn, 0))
     456                 :            :   {
     457 [ +  + ][ +  + ]:        516 :     if (ik == Kind::AND || ik == Kind::MULT || ik == Kind::BITVECTOR_AND
                 [ +  + ]
     458         [ -  + ]:        452 :         || ik == Kind::BITVECTOR_MULT)
     459                 :            :     {
     460                 :         64 :       return n;
     461                 :            :     }
     462 [ +  - ][ +  + ]:        452 :     else if (ik == Kind::BITVECTOR_SHL || ik == Kind::BITVECTOR_LSHR
     463 [ +  + ][ +  + ]:        450 :              || ik == Kind::BITVECTOR_ASHR || ik == Kind::BITVECTOR_UREM)
     464                 :            :     {
     465         [ +  - ]:          6 :       if (arg == 0)
     466                 :            :       {
     467                 :          6 :         return n;
     468                 :            :       }
     469                 :            :     }
     470 [ +  + ][ -  + ]:        446 :     else if (ik == Kind::BITVECTOR_UDIV || ik == Kind::BITVECTOR_SDIV)
     471                 :            :     {
     472         [ +  + ]:          8 :       if (arg == 0)
     473                 :            :       {
     474                 :          4 :         return n;
     475                 :            :       }
     476         [ +  - ]:          4 :       else if (arg == 1)
     477                 :            :       {
     478                 :          4 :         return mkTypeMaxValue(tn);
     479                 :            :       }
     480                 :            :     }
     481 [ +  + ][ +  - ]:        438 :     else if (ik == Kind::DIVISION || ik == Kind::DIVISION_TOTAL
     482 [ +  - ][ +  - ]:        434 :              || ik == Kind::INTS_DIVISION || ik == Kind::INTS_DIVISION_TOTAL
     483 [ +  + ][ -  + ]:        434 :              || ik == Kind::INTS_MODULUS || ik == Kind::INTS_MODULUS_TOTAL)
     484                 :            :     {
     485         [ +  + ]:         10 :       if (arg == 0)
     486                 :            :       {
     487                 :          6 :         return n;
     488                 :            :       }
     489                 :            :     }
     490         [ -  + ]:        428 :     else if (ik == Kind::STRING_SUBSTR)
     491                 :            :     {
     492         [ -  - ]:          0 :       if (arg == 0)
     493                 :            :       {
     494                 :          0 :         return n;
     495                 :            :       }
     496         [ -  - ]:          0 :       else if (arg == 2)
     497                 :            :       {
     498                 :          0 :         return mkTypeValue(n.getNodeManager()->stringType(), 0);
     499                 :            :       }
     500                 :            :     }
     501         [ -  + ]:        428 :     else if (ik == Kind::STRING_INDEXOF)
     502                 :            :     {
     503 [ -  - ][ -  - ]:          0 :       if (arg == 0 || arg == 1)
     504                 :            :       {
     505                 :          0 :         return mkTypeValue(n.getNodeManager()->integerType(), -1);
     506                 :            :       }
     507                 :            :     }
     508                 :            :   }
     509         [ +  + ]:       1178 :   else if (n == mkTypeValue(tn, 1))
     510                 :            :   {
     511         [ +  + ]:        538 :     if (ik == Kind::BITVECTOR_UREM)
     512                 :            :     {
     513                 :          4 :       return mkTypeValue(tn, 0);
     514                 :            :     }
     515                 :            :   }
     516         [ +  + ]:        640 :   else if (n == mkTypeMaxValue(tn))
     517                 :            :   {
     518 [ +  + ][ -  + ]:        174 :     if (ik == Kind::OR || ik == Kind::BITVECTOR_OR)
     519                 :            :     {
     520                 :         44 :       return n;
     521                 :            :     }
     522                 :            :   }
     523                 :            :   else
     524                 :            :   {
     525 [ +  + ][ -  + ]:        466 :     if (n.getType().isInteger() && n.getConst<Rational>().sgn() < 0)
         [ +  - ][ -  + ]
                 [ -  - ]
     526                 :            :     {
     527                 :            :       // negative arguments
     528 [ -  - ][ -  - ]:          0 :       if (ik == Kind::STRING_SUBSTR || ik == Kind::STRING_CHARAT)
     529                 :            :       {
     530                 :          0 :         return mkTypeValue(n.getNodeManager()->stringType(), 0);
     531                 :            :       }
     532         [ -  - ]:          0 :       else if (ik == Kind::STRING_INDEXOF)
     533                 :            :       {
     534                 :          0 :         Assert(arg == 2);
     535                 :          0 :         return mkTypeValue(n.getNodeManager()->integerType(), -1);
     536                 :            :       }
     537                 :            :     }
     538                 :            :   }
     539                 :       1562 :   return Node::null();
     540                 :       1694 : }
     541                 :            : 
     542                 :       1076 : bool TermUtil::hasOffsetArg(Kind ik, int arg, int& offset, Kind& ok)
     543                 :            : {
     544         [ +  + ]:       1076 :   if (ik == Kind::LT)
     545                 :            :   {
     546 [ +  + ][ +  - ]:          8 :     Assert(arg == 0 || arg == 1);
         [ -  + ][ -  + ]
                 [ -  - ]
     547         [ +  + ]:          8 :     offset = arg == 0 ? 1 : -1;
     548                 :          8 :     ok = Kind::LEQ;
     549                 :          8 :     return true;
     550                 :            :   }
     551         [ -  + ]:       1068 :   else if (ik == Kind::BITVECTOR_ULT)
     552                 :            :   {
     553                 :          0 :     Assert(arg == 0 || arg == 1);
     554         [ -  - ]:          0 :     offset = arg == 0 ? 1 : -1;
     555                 :          0 :     ok = Kind::BITVECTOR_ULE;
     556                 :          0 :     return true;
     557                 :            :   }
     558         [ -  + ]:       1068 :   else if (ik == Kind::BITVECTOR_SLT)
     559                 :            :   {
     560                 :          0 :     Assert(arg == 0 || arg == 1);
     561         [ -  - ]:          0 :     offset = arg == 0 ? 1 : -1;
     562                 :          0 :     ok = Kind::BITVECTOR_SLE;
     563                 :          0 :     return true;
     564                 :            :   }
     565                 :       1068 :   return false;
     566                 :            : }
     567                 :            : 
     568                 :        525 : Node TermUtil::ensureType(Node n, TypeNode tn)
     569                 :            : {
     570                 :        525 :   TypeNode ntn = n.getType();
     571         [ +  + ]:        525 :   if (ntn == tn)
     572                 :            :   {
     573                 :        516 :     return n;
     574                 :            :   }
     575         [ -  + ]:          9 :   if (tn.isInteger())
     576                 :            :   {
     577                 :          0 :     return NodeManager::mkNode(Kind::TO_INTEGER, n);
     578                 :            :   }
     579         [ +  - ]:          9 :   else if (tn.isReal())
     580                 :            :   {
     581                 :          9 :     return NodeManager::mkNode(Kind::TO_REAL, n);
     582                 :            :   }
     583                 :          0 :   return Node::null();
     584                 :        525 : }
     585                 :            : 
     586                 :            : }  // namespace quantifiers
     587                 :            : }  // namespace theory
     588                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14