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: 263 333 79.0 %
Date: 2025-02-18 13:42:10 Functions: 28 31 90.3 %
Branches: 332 444 74.8 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Aina Niemetz, Andres Noetzli
       4                 :            :  *
       5                 :            :  * This file is part of the cvc5 project.
       6                 :            :  *
       7                 :            :  * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS
       8                 :            :  * in the top-level source directory and their institutional affiliations.
       9                 :            :  * All rights reserved.  See the file COPYING in the top-level source
      10                 :            :  * directory for licensing information.
      11                 :            :  * ****************************************************************************
      12                 :            :  *
      13                 :            :  * Implementation of term utilities class.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/quantifiers/term_util.h"
      17                 :            : 
      18                 :            : #include "expr/array_store_all.h"
      19                 :            : #include "expr/function_array_const.h"
      20                 :            : #include "expr/node_algorithm.h"
      21                 :            : #include "expr/sequence.h"
      22                 :            : #include "expr/skolem_manager.h"
      23                 :            : #include "theory/arith/arith_msum.h"
      24                 :            : #include "theory/bv/theory_bv_utils.h"
      25                 :            : #include "theory/quantifiers/term_database.h"
      26                 :            : #include "theory/quantifiers/term_enumeration.h"
      27                 :            : #include "theory/rewriter.h"
      28                 :            : #include "theory/strings/word.h"
      29                 :            : #include "util/bitvector.h"
      30                 :            : #include "util/rational.h"
      31                 :            : 
      32                 :            : using namespace cvc5::internal::kind;
      33                 :            : 
      34                 :            : namespace cvc5::internal {
      35                 :            : namespace theory {
      36                 :            : namespace quantifiers {
      37                 :            : 
      38                 :       6530 : size_t TermUtil::getVariableNum(Node q, Node v)
      39                 :            : {
      40                 :       6530 :   Node::iterator it = std::find(q[0].begin(), q[0].end(), v);
      41 [ -  + ][ -  + ]:       6530 :   Assert(it != q[0].end());
                 [ -  - ]
      42                 :       6530 :   return it - q[0].begin();
      43                 :            : }
      44                 :            : 
      45                 :      26485 : Node TermUtil::getRemoveQuantifiers2( Node n, std::map< Node, Node >& visited ) {
      46                 :      26485 :   std::map< Node, Node >::iterator it = visited.find( n );
      47         [ +  + ]:      26485 :   if( it!=visited.end() ){
      48                 :       9941 :     return it->second;
      49                 :            :   }else{
      50                 :      33088 :     Node ret = n;
      51         [ +  + ]:      16544 :     if (n.getKind() == Kind::FORALL)
      52                 :            :     {
      53                 :        997 :       ret = getRemoveQuantifiers2( n[1], visited );
      54                 :            :     }
      55         [ +  + ]:      15547 :     else if (n.getNumChildren() > 0)
      56                 :            :     {
      57                 :      22070 :       std::vector< Node > children;
      58                 :      11035 :       bool childrenChanged = false;
      59         [ +  + ]:      35514 :       for( unsigned i=0; i<n.getNumChildren(); i++ ){
      60                 :      48958 :         Node ni = getRemoveQuantifiers2( n[i], visited );
      61 [ +  + ][ +  + ]:      24479 :         childrenChanged = childrenChanged || ni!=n[i];
         [ +  + ][ -  - ]
      62                 :      24479 :         children.push_back( ni );
      63                 :            :       }
      64         [ +  + ]:      11035 :       if( childrenChanged ){
      65         [ -  + ]:         12 :         if( n.getMetaKind() == kind::metakind::PARAMETERIZED ){
      66                 :          0 :           children.insert( children.begin(), n.getOperator() );
      67                 :            :         }
      68                 :         12 :         ret = NodeManager::currentNM()->mkNode( n.getKind(), children );
      69                 :            :       }
      70                 :            :     }
      71                 :      16544 :     visited[n] = ret;
      72                 :      16544 :     return ret;
      73                 :            :   }
      74                 :            : }
      75                 :            : 
      76                 :   15296700 : Node TermUtil::getInstConstAttr( Node n ) {
      77         [ +  + ]:   15296700 :   if (!n.hasAttribute(InstConstantAttribute()))
      78                 :            :   {
      79                 :    2353560 :     Node q;
      80         [ +  + ]:    1176780 :     if (n.isVar())
      81                 :            :     {
      82                 :            :       // If it is a purification variable, it may correspond to a term
      83                 :            :       // with instantiation constants in it. We get the unpurified form here
      84                 :            :       // to handle this case.
      85                 :     358222 :       Node un = SkolemManager::getUnpurifiedForm(n);
      86 [ +  - ][ +  + ]:     179111 :       if (!un.isNull() && un != n)
                 [ +  + ]
      87                 :            :       {
      88                 :      76753 :         q = getInstConstAttr(un);
      89                 :            :       }
      90                 :            :     }
      91                 :            :     else
      92                 :            :     {
      93         [ +  + ]:    2412620 :       for (const Node& nc : n)
      94                 :            :       {
      95                 :    1672020 :         q = getInstConstAttr(nc);
      96         [ +  + ]:    1672020 :         if (!q.isNull())
      97                 :            :         {
      98                 :     257078 :           break;
      99                 :            :         }
     100                 :            :       }
     101         [ +  + ]:     997668 :       if (q.isNull())
     102                 :            :       {
     103         [ +  + ]:     740590 :         if (n.hasOperator())
     104                 :            :         {
     105                 :     640736 :           q = getInstConstAttr(n.getOperator());
     106                 :            :         }
     107                 :            :       }
     108                 :            :     }
     109                 :            :     InstConstantAttribute ica;
     110                 :    1176780 :     n.setAttribute(ica, q);
     111                 :            :   }
     112                 :   30593400 :   return n.getAttribute(InstConstantAttribute());
     113                 :            : }
     114                 :            : 
     115                 :    8394780 : bool TermUtil::hasInstConstAttr(Node n)
     116                 :            : {
     117                 :    8394780 :   return !getInstConstAttr(n).isNull();
     118                 :            : }
     119                 :            : 
     120                 :     350506 : Node TermUtil::getBoundVarAttr( Node n ) {
     121         [ +  + ]:     350506 :   if (!n.hasAttribute(BoundVarAttribute()) ){
     122                 :     345664 :     Node bv;
     123         [ +  + ]:     172832 :     if (n.getKind() == Kind::BOUND_VARIABLE)
     124                 :            :     {
     125                 :      12249 :       bv = n;
     126                 :            :     }
     127                 :            :     else
     128                 :            :     {
     129         [ +  + ]:     214205 :       for( unsigned i=0; i<n.getNumChildren(); i++ ){
     130                 :     178860 :         bv = getBoundVarAttr(n[i]);
     131         [ +  + ]:     178860 :         if( !bv.isNull() ){
     132                 :     125238 :           break;
     133                 :            :         }
     134                 :            :       }
     135                 :            :     }
     136                 :            :     BoundVarAttribute bva;
     137                 :     172832 :     n.setAttribute(bva, bv);
     138                 :            :   }
     139                 :     701012 :   return n.getAttribute(BoundVarAttribute());
     140                 :            : }
     141                 :            : 
     142                 :     171646 : bool TermUtil::hasBoundVarAttr( Node n ) {
     143                 :     171646 :   return !getBoundVarAttr(n).isNull();
     144                 :            : }
     145                 :            : 
     146                 :            : //remove quantifiers
     147                 :       1009 : Node TermUtil::getRemoveQuantifiers( Node n ) {
     148                 :       1009 :   std::map< Node, Node > visited;
     149                 :       2018 :   return getRemoveQuantifiers2( n, visited );
     150                 :            : }
     151                 :            : 
     152                 :     433983 : void TermUtil::computeInstConstContains(Node n, std::vector<Node>& ics)
     153                 :            : {
     154                 :     433983 :   computeVarContainsInternal(n, Kind::INST_CONSTANT, ics);
     155                 :     433983 : }
     156                 :            : 
     157                 :          0 : void TermUtil::computeVarContains(Node n, std::vector<Node>& vars)
     158                 :            : {
     159                 :          0 :   computeVarContainsInternal(n, Kind::BOUND_VARIABLE, vars);
     160                 :          0 : }
     161                 :            : 
     162                 :       3313 : void TermUtil::computeQuantContains(Node n, std::vector<Node>& quants)
     163                 :            : {
     164                 :       3313 :   computeVarContainsInternal(n, Kind::FORALL, quants);
     165                 :       3313 : }
     166                 :            : 
     167                 :     437296 : void TermUtil::computeVarContainsInternal(Node n,
     168                 :            :                                           Kind k,
     169                 :            :                                           std::vector<Node>& vars)
     170                 :            : {
     171                 :     874592 :   std::unordered_set<TNode> visited;
     172                 :     437296 :   std::unordered_set<TNode>::iterator it;
     173                 :     874592 :   std::vector<TNode> visit;
     174                 :     874592 :   TNode cur;
     175                 :     437296 :   visit.push_back(n);
     176                 :    3468610 :   do
     177                 :            :   {
     178                 :    3905900 :     cur = visit.back();
     179                 :    3905900 :     visit.pop_back();
     180                 :    3905900 :     it = visited.find(cur);
     181                 :            : 
     182         [ +  + ]:    3905900 :     if (it == visited.end())
     183                 :            :     {
     184                 :    3571410 :       visited.insert(cur);
     185         [ +  + ]:    3571410 :       if (cur.getKind() == k)
     186                 :            :       {
     187         [ +  - ]:    1148260 :         if (std::find(vars.begin(), vars.end(), cur) == vars.end())
     188                 :            :         {
     189                 :    1148260 :           vars.push_back(cur);
     190                 :            :         }
     191                 :            :       }
     192                 :            :       else
     193                 :            :       {
     194         [ +  + ]:    2423150 :         if (cur.hasOperator())
     195                 :            :         {
     196                 :    1109210 :           visit.push_back(cur.getOperator());
     197                 :            :         }
     198         [ +  + ]:    4782540 :         for (const Node& cn : cur)
     199                 :            :         {
     200                 :    2359400 :           visit.push_back(cn);
     201                 :            :         }
     202                 :            :       }
     203                 :            :     }
     204         [ +  + ]:    3905900 :   } while (!visit.empty());
     205                 :     437296 : }
     206                 :            : 
     207                 :     312337 : void TermUtil::computeInstConstContainsForQuant(Node q,
     208                 :            :                                                 Node n,
     209                 :            :                                                 std::vector<Node>& vars)
     210                 :            : {
     211                 :     624674 :   std::vector<Node> ics;
     212                 :     312337 :   computeInstConstContains(n, ics);
     213         [ +  + ]:    1192130 :   for (const Node& v : ics)
     214                 :            :   {
     215         [ +  - ]:     879796 :     if (v.getAttribute(InstConstantAttribute()) == q)
     216                 :            :     {
     217         [ +  + ]:     879796 :       if (std::find(vars.begin(), vars.end(), v) == vars.end())
     218                 :            :       {
     219                 :     879794 :         vars.push_back(v);
     220                 :            :       }
     221                 :            :     }
     222                 :            :   }
     223                 :     312337 : }
     224                 :            : 
     225                 :          0 : int TermUtil::getTermDepth( Node n ) {
     226         [ -  - ]:          0 :   if (!n.hasAttribute(TermDepthAttribute()) ){
     227                 :          0 :     int maxDepth = -1;
     228         [ -  - ]:          0 :     for( unsigned i=0; i<n.getNumChildren(); i++ ){
     229                 :          0 :       int depth = getTermDepth( n[i] );
     230         [ -  - ]:          0 :       if( depth>maxDepth ){
     231                 :          0 :         maxDepth = depth;
     232                 :            :       }
     233                 :            :     }
     234                 :            :     TermDepthAttribute tda;
     235                 :          0 :     n.setAttribute(tda,1+maxDepth);
     236                 :            :   }
     237                 :          0 :   return n.getAttribute(TermDepthAttribute());
     238                 :            : }
     239                 :            : 
     240                 :     556983 : bool TermUtil::containsUninterpretedConstant( Node n ) {
     241         [ +  + ]:     556983 :   if (n.hasAttribute(ContainsUConstAttribute()))
     242                 :            :   {
     243                 :     512010 :     return n.getAttribute(ContainsUConstAttribute()) != 0;
     244                 :            :   }
     245                 :      44973 :   bool ret = false;
     246                 :      44973 :   Kind k = n.getKind();
     247         [ +  + ]:      44973 :   if (k == Kind::UNINTERPRETED_SORT_VALUE)
     248                 :            :   {
     249 [ -  + ][ -  + ]:       1509 :     Assert(n.getType().isUninterpretedSort());
                 [ -  - ]
     250                 :       1509 :     ret = true;
     251                 :            :   }
     252         [ +  + ]:      43464 :   else if (k == Kind::STORE_ALL)
     253                 :            :   {
     254                 :          6 :     ret = containsUninterpretedConstant(n.getConst<ArrayStoreAll>().getValue());
     255                 :            :   }
     256         [ -  + ]:      43458 :   else if (k == Kind::FUNCTION_ARRAY_CONST)
     257                 :            :   {
     258                 :          0 :     ret = containsUninterpretedConstant(
     259                 :          0 :         n.getConst<FunctionArrayConst>().getArrayValue());
     260                 :            :   }
     261         [ +  + ]:      43458 :   else if (k == Kind::CONST_SEQUENCE)
     262                 :            :   {
     263                 :          7 :     const std::vector<Node>& charVec = n.getConst<Sequence>().getVec();
     264         [ -  + ]:          7 :     for (const Node& nc : charVec)
     265                 :            :     {
     266         [ -  - ]:          0 :       if (containsUninterpretedConstant(nc))
     267                 :            :       {
     268                 :          0 :         ret = true;
     269                 :          0 :         break;
     270                 :            :       }
     271                 :            :     }
     272                 :            :   }
     273                 :            :   else
     274                 :            :   {
     275         [ +  + ]:      79976 :     for (const Node& nc : n)
     276                 :            :     {
     277         [ -  + ]:      36525 :       if (containsUninterpretedConstant(nc))
     278                 :            :       {
     279                 :          0 :         ret = true;
     280                 :          0 :         break;
     281                 :            :       }
     282                 :            :     }
     283                 :            :   }
     284                 :            :   ContainsUConstAttribute cuca;
     285         [ +  + ]:      44973 :   n.setAttribute(cuca, ret ? 1 : 0);
     286                 :      44973 :   return ret;
     287                 :            : }
     288                 :            : 
     289                 :      18565 : Node TermUtil::simpleNegate(Node n)
     290                 :            : {
     291 [ -  + ][ -  + ]:      18565 :   Assert(n.getType().isBoolean());
                 [ -  - ]
     292                 :      18565 :   NodeManager* nm = NodeManager::currentNM();
     293 [ +  + ][ +  + ]:      18565 :   if (n.getKind() == Kind::OR || n.getKind() == Kind::AND)
                 [ +  + ]
     294                 :            :   {
     295                 :       8148 :     std::vector< Node > children;
     296         [ +  + ]:      15214 :     for (const Node& cn : n)
     297                 :            :     {
     298                 :      11140 :       children.push_back(simpleNegate(cn));
     299                 :            :     }
     300         [ +  + ]:       4074 :     return nm->mkNode(n.getKind() == Kind::OR ? Kind::AND : Kind::OR, children);
     301                 :            :   }
     302         [ +  + ]:      14491 :   else if (n.isConst())
     303                 :            :   {
     304                 :       8418 :     return nm->mkConst(!n.getConst<bool>());
     305                 :            :   }
     306                 :      10282 :   return n.negate();
     307                 :            : }
     308                 :            : 
     309                 :       6736 : Node TermUtil::mkNegate(Kind notk, Node n)
     310                 :            : {
     311         [ +  + ]:       6736 :   if (n.getKind() == notk)
     312                 :            :   {
     313                 :        588 :     return n[0];
     314                 :            :   }
     315                 :       6148 :   return NodeManager::mkNode(notk, n);
     316                 :            : }
     317                 :            : 
     318                 :      15998 : bool TermUtil::isNegate(Kind k)
     319                 :            : {
     320 [ +  + ][ +  + ]:      15351 :   return k == Kind::NOT || k == Kind::BITVECTOR_NOT || k == Kind::BITVECTOR_NEG
     321 [ +  + ][ -  + ]:      31349 :          || k == Kind::NEG;
     322                 :            : }
     323                 :            : 
     324                 :     253808 : bool TermUtil::isAssoc(Kind k, bool reqNAry)
     325                 :            : {
     326         [ +  + ]:     253808 :   if (reqNAry)
     327                 :            :   {
     328 [ +  + ][ +  + ]:     252914 :     if (k == Kind::SET_UNION || k == Kind::SET_INTER)
     329                 :            :     {
     330                 :         62 :       return false;
     331                 :            :     }
     332                 :            :   }
     333 [ +  + ][ +  + ]:     234224 :   return k == Kind::ADD || k == Kind::MULT || k == Kind::NONLINEAR_MULT
     334 [ +  + ][ +  + ]:     228612 :          || k == Kind::AND || k == Kind::OR || k == Kind::XOR
                 [ +  + ]
     335 [ +  + ][ +  + ]:     153353 :          || k == Kind::BITVECTOR_ADD || k == Kind::BITVECTOR_MULT
     336 [ +  + ][ +  + ]:     144643 :          || k == Kind::BITVECTOR_AND || k == Kind::BITVECTOR_OR
     337 [ +  + ][ +  - ]:     135268 :          || k == Kind::BITVECTOR_XOR || k == Kind::BITVECTOR_XNOR
     338 [ +  + ][ +  + ]:     135148 :          || k == Kind::BITVECTOR_CONCAT || k == Kind::STRING_CONCAT
     339 [ +  + ][ +  + ]:     131891 :          || k == Kind::SET_UNION || k == Kind::SET_INTER
     340 [ +  - ][ +  - ]:     131883 :          || k == Kind::RELATION_JOIN || k == Kind::RELATION_TABLE_JOIN
     341 [ +  + ][ +  - ]:     487970 :          || k == Kind::RELATION_PRODUCT || k == Kind::SEP_STAR;
                 [ -  + ]
     342                 :            : }
     343                 :            : 
     344                 :     894517 : bool TermUtil::isComm(Kind k, bool reqNAry)
     345                 :            : {
     346         [ -  + ]:     894517 :   if (reqNAry)
     347                 :            :   {
     348 [ -  - ][ -  - ]:          0 :     if (k == Kind::SET_UNION || k == Kind::SET_INTER)
     349                 :            :     {
     350                 :          0 :       return false;
     351                 :            :     }
     352                 :            :   }
     353 [ +  + ][ +  + ]:     764063 :   return k == Kind::EQUAL || k == Kind::ADD || k == Kind::MULT
     354 [ +  + ][ +  + ]:     685832 :          || k == Kind::NONLINEAR_MULT || k == Kind::AND || k == Kind::OR
                 [ +  + ]
     355 [ +  + ][ +  + ]:     556000 :          || k == Kind::XOR || k == Kind::BITVECTOR_ADD
     356 [ +  + ][ +  + ]:     551563 :          || k == Kind::BITVECTOR_MULT || k == Kind::BITVECTOR_AND
     357 [ +  + ][ +  + ]:     541822 :          || k == Kind::BITVECTOR_OR || k == Kind::BITVECTOR_XOR
     358 [ +  - ][ +  + ]:     536419 :          || k == Kind::BITVECTOR_XNOR || k == Kind::SET_UNION
     359 [ +  + ][ +  + ]:    1658580 :          || k == Kind::SET_INTER || k == Kind::SEP_STAR;
                 [ +  + ]
     360                 :            : }
     361                 :            : 
     362                 :     253186 : bool TermUtil::isNonAdditive( Kind k ) {
     363 [ +  + ][ +  + ]:     212875 :   return k == Kind::AND || k == Kind::OR || k == Kind::BITVECTOR_AND
     364 [ +  + ][ +  + ]:     466061 :          || k == Kind::BITVECTOR_OR;
     365                 :            : }
     366                 :            : 
     367                 :     796318 : bool TermUtil::isBoolConnective( Kind k ) {
     368 [ +  + ][ +  + ]:     689592 :   return k == Kind::OR || k == Kind::AND || k == Kind::EQUAL || k == Kind::ITE
                 [ +  + ]
     369 [ +  + ][ +  + ]:    1485910 :          || k == Kind::FORALL || k == Kind::NOT || k == Kind::SEP_STAR;
         [ +  + ][ +  + ]
     370                 :            : }
     371                 :            : 
     372                 :     683533 : bool TermUtil::isBoolConnectiveTerm( TNode n ) {
     373                 :     683533 :   return isBoolConnective(n.getKind())
     374                 :    1159650 :          && (n.getKind() != Kind::EQUAL || n[0].getType().isBoolean())
     375 [ +  + ][ +  + ]:    2526710 :          && (n.getKind() != Kind::ITE || n.getType().isBoolean());
         [ +  + ][ +  + ]
         [ +  + ][ -  - ]
     376                 :            : }
     377                 :            : 
     378                 :      82966 : Node TermUtil::mkTypeValue(TypeNode tn, int32_t val)
     379                 :            : {
     380                 :      82966 :   Node n;
     381         [ +  + ]:      82966 :   if (tn.isRealOrInt())
     382                 :            :   {
     383                 :       6238 :     Rational c(val);
     384                 :       6238 :     n = NodeManager::currentNM()->mkConstRealOrInt(tn, c);
     385                 :            :   }
     386         [ +  + ]:      76728 :   else if (tn.isBitVector())
     387                 :            :   {
     388                 :            :     // cast to unsigned
     389                 :        802 :     uint32_t uv = static_cast<uint32_t>(val);
     390                 :        802 :     BitVector bval(tn.getConst<BitVectorSize>(), uv);
     391                 :        802 :     n = NodeManager::currentNM()->mkConst<BitVector>(bval);
     392                 :            :   }
     393         [ +  + ]:      75926 :   else if (tn.isBoolean())
     394                 :            :   {
     395         [ +  + ]:      75346 :     if (val == 0)
     396                 :            :     {
     397                 :      74790 :       n = NodeManager::currentNM()->mkConst(false);
     398                 :            :     }
     399                 :            :   }
     400         [ +  + ]:        580 :   else if (tn.isStringLike())
     401                 :            :   {
     402         [ +  + ]:        412 :     if (val == 0)
     403                 :            :     {
     404                 :        222 :       n = strings::Word::mkEmptyWord(tn);
     405                 :            :     }
     406                 :            :   }
     407                 :      82966 :   return n;
     408                 :            : }
     409                 :            : 
     410                 :      76744 : Node TermUtil::mkTypeMaxValue(TypeNode tn)
     411                 :            : {
     412                 :      76744 :   Node n;
     413         [ +  + ]:      76744 :   if (tn.isBitVector())
     414                 :            :   {
     415                 :        142 :     n = bv::utils::mkOnes(tn.getConst<BitVectorSize>());
     416                 :            :   }
     417         [ +  + ]:      76602 :   else if (tn.isBoolean())
     418                 :            :   {
     419                 :      74492 :     n = NodeManager::currentNM()->mkConst(true);
     420                 :            :   }
     421                 :      76744 :   return n;
     422                 :            : }
     423                 :            : 
     424                 :          8 : Node TermUtil::mkTypeValueOffset(TypeNode tn,
     425                 :            :                                  Node val,
     426                 :            :                                  int32_t offset,
     427                 :            :                                  int32_t& status)
     428                 :            : {
     429                 :         16 :   Assert(val.isConst() && val.getType() == tn);
     430                 :         16 :   Node val_o;
     431                 :          8 :   status = -1;
     432         [ +  - ]:          8 :   if (tn.isRealOrInt())
     433                 :            :   {
     434                 :         16 :     Rational vval = val.getConst<Rational>();
     435                 :          8 :     Rational oval(offset);
     436                 :          8 :     status = 0;
     437                 :         16 :     return NodeManager::currentNM()->mkConstRealOrInt(tn, vval + oval);
     438                 :            :   }
     439         [ -  - ]:          0 :   else if (tn.isBitVector())
     440                 :            :   {
     441                 :          0 :     BitVector vval = val.getConst<BitVector>();
     442                 :          0 :     uint32_t uv = static_cast<uint32_t>(offset);
     443                 :          0 :     BitVector oval(tn.getConst<BitVectorSize>(), uv);
     444                 :          0 :     return NodeManager::currentNM()->mkConst(vval + oval);
     445                 :            :   }
     446                 :          0 :   return val_o;
     447                 :            : }
     448                 :            : 
     449                 :          2 : Node TermUtil::mkTypeConst(TypeNode tn, bool pol)
     450                 :            : {
     451                 :          2 :   return pol ? mkTypeMaxValue(tn) : mkTypeValue(tn, 0);
     452                 :            : }
     453                 :            : 
     454                 :          0 : bool TermUtil::isAntisymmetric(Kind k, Kind& dk)
     455                 :            : {
     456         [ -  - ]:          0 :   if (k == Kind::GT)
     457                 :            :   {
     458                 :          0 :     dk = Kind::LT;
     459                 :          0 :     return true;
     460                 :            :   }
     461         [ -  - ]:          0 :   else if (k == Kind::GEQ)
     462                 :            :   {
     463                 :          0 :     dk = Kind::LEQ;
     464                 :          0 :     return true;
     465                 :            :   }
     466         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_UGT)
     467                 :            :   {
     468                 :          0 :     dk = Kind::BITVECTOR_ULT;
     469                 :          0 :     return true;
     470                 :            :   }
     471         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_UGE)
     472                 :            :   {
     473                 :          0 :     dk = Kind::BITVECTOR_ULE;
     474                 :          0 :     return true;
     475                 :            :   }
     476         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_SGT)
     477                 :            :   {
     478                 :          0 :     dk = Kind::BITVECTOR_SLT;
     479                 :          0 :     return true;
     480                 :            :   }
     481         [ -  - ]:          0 :   else if (k == Kind::BITVECTOR_SGE)
     482                 :            :   {
     483                 :          0 :     dk = Kind::BITVECTOR_SLE;
     484                 :          0 :     return true;
     485                 :            :   }
     486                 :          0 :   return false;
     487                 :            : }
     488                 :            : 
     489                 :       1922 : bool TermUtil::isIdempotentArg(Node n, Kind ik, int arg)
     490                 :            : {
     491                 :            :   // these should all be binary operators
     492                 :            :   // Assert( ik!=DIVISION && ik!=INTS_DIVISION && ik!=INTS_MODULUS &&
     493                 :            :   // ik!=BITVECTOR_UDIV );
     494                 :       3844 :   TypeNode tn = n.getType();
     495         [ +  + ]:       1922 :   if (n == mkTypeValue(tn, 0))
     496                 :            :   {
     497 [ +  + ][ +  + ]:        751 :     if (ik == Kind::ADD || ik == Kind::OR || ik == Kind::XOR
                 [ +  - ]
     498 [ +  + ][ +  + ]:        603 :         || ik == Kind::BITVECTOR_ADD || ik == Kind::BITVECTOR_OR
     499 [ +  + ][ +  + ]:        579 :         || ik == Kind::BITVECTOR_XOR || ik == Kind::STRING_CONCAT)
     500                 :            :     {
     501                 :        200 :       return true;
     502                 :            :     }
     503 [ +  + ][ +  - ]:        551 :     else if (ik == Kind::SUB || ik == Kind::BITVECTOR_SHL
     504 [ +  + ][ +  + ]:        451 :              || ik == Kind::BITVECTOR_LSHR || ik == Kind::BITVECTOR_ASHR
     505 [ +  + ][ +  + ]:        443 :              || ik == Kind::BITVECTOR_SUB || ik == Kind::BITVECTOR_UREM)
     506                 :            :     {
     507                 :        116 :       return arg == 1;
     508                 :            :     }
     509                 :            :   }
     510         [ +  + ]:       1171 :   else if (n == mkTypeValue(tn, 1))
     511                 :            :   {
     512 [ +  + ][ -  + ]:        534 :     if (ik == Kind::MULT || ik == Kind::BITVECTOR_MULT)
     513                 :            :     {
     514                 :         10 :       return true;
     515                 :            :     }
     516 [ +  + ][ +  - ]:        524 :     else if (ik == Kind::DIVISION || ik == Kind::DIVISION_TOTAL
     517 [ +  - ][ +  - ]:        516 :              || ik == Kind::INTS_DIVISION || ik == Kind::INTS_DIVISION_TOTAL
     518 [ +  - ][ +  - ]:        516 :              || ik == Kind::INTS_MODULUS || ik == Kind::INTS_MODULUS_TOTAL
     519 [ +  + ][ +  + ]:        516 :              || ik == Kind::BITVECTOR_UDIV || ik == Kind::BITVECTOR_SDIV)
     520                 :            :     {
     521                 :         20 :       return arg == 1;
     522                 :            :     }
     523                 :            :   }
     524         [ +  + ]:        637 :   else if (n == mkTypeMaxValue(tn))
     525                 :            :   {
     526 [ +  - ][ +  - ]:        171 :     if (ik == Kind::EQUAL || ik == Kind::BITVECTOR_AND
     527         [ -  + ]:        171 :         || ik == Kind::BITVECTOR_XNOR)
     528                 :            :     {
     529                 :          0 :       return true;
     530                 :            :     }
     531                 :            :   }
     532                 :       1576 :   return false;
     533                 :            : }
     534                 :            : 
     535                 :       1644 : Node TermUtil::isSingularArg(Node n, Kind ik, unsigned arg)
     536                 :            : {
     537                 :       3288 :   TypeNode tn = n.getType();
     538         [ +  + ]:       1644 :   if (n == mkTypeValue(tn, 0))
     539                 :            :   {
     540 [ +  + ][ +  + ]:        493 :     if (ik == Kind::AND || ik == Kind::MULT || ik == Kind::BITVECTOR_AND
                 [ +  + ]
     541         [ -  + ]:        427 :         || ik == Kind::BITVECTOR_MULT)
     542                 :            :     {
     543                 :         66 :       return n;
     544                 :            :     }
     545 [ +  - ][ +  + ]:        427 :     else if (ik == Kind::BITVECTOR_SHL || ik == Kind::BITVECTOR_LSHR
     546 [ +  + ][ +  + ]:        425 :              || ik == Kind::BITVECTOR_ASHR || ik == Kind::BITVECTOR_UREM)
     547                 :            :     {
     548         [ +  - ]:          6 :       if (arg == 0)
     549                 :            :       {
     550                 :          6 :         return n;
     551                 :            :       }
     552                 :            :     }
     553 [ +  + ][ -  + ]:        421 :     else if (ik == Kind::BITVECTOR_UDIV || ik == Kind::BITVECTOR_SDIV)
     554                 :            :     {
     555         [ +  + ]:          8 :       if (arg == 0)
     556                 :            :       {
     557                 :          4 :         return n;
     558                 :            :       }
     559         [ +  - ]:          4 :       else if (arg == 1)
     560                 :            :       {
     561                 :          4 :         return mkTypeMaxValue(tn);
     562                 :            :       }
     563                 :            :     }
     564 [ +  + ][ +  - ]:        413 :     else if (ik == Kind::DIVISION || ik == Kind::DIVISION_TOTAL
     565 [ +  - ][ +  - ]:        409 :              || ik == Kind::INTS_DIVISION || ik == Kind::INTS_DIVISION_TOTAL
     566 [ +  + ][ -  + ]:        409 :              || ik == Kind::INTS_MODULUS || ik == Kind::INTS_MODULUS_TOTAL)
     567                 :            :     {
     568         [ +  + ]:         10 :       if (arg == 0)
     569                 :            :       {
     570                 :          6 :         return n;
     571                 :            :       }
     572                 :            :     }
     573         [ -  + ]:        403 :     else if (ik == Kind::STRING_SUBSTR)
     574                 :            :     {
     575         [ -  - ]:          0 :       if (arg == 0)
     576                 :            :       {
     577                 :          0 :         return n;
     578                 :            :       }
     579         [ -  - ]:          0 :       else if (arg == 2)
     580                 :            :       {
     581                 :          0 :         return mkTypeValue(NodeManager::currentNM()->stringType(), 0);
     582                 :            :       }
     583                 :            :     }
     584         [ -  + ]:        403 :     else if (ik == Kind::STRING_INDEXOF)
     585                 :            :     {
     586 [ -  - ][ -  - ]:          0 :       if (arg == 0 || arg == 1)
     587                 :            :       {
     588                 :          0 :         return mkTypeValue(NodeManager::currentNM()->integerType(), -1);
     589                 :            :       }
     590                 :            :     }
     591                 :            :   }
     592         [ +  + ]:       1151 :   else if (n == mkTypeValue(tn, 1))
     593                 :            :   {
     594         [ +  + ]:        514 :     if (ik == Kind::BITVECTOR_UREM)
     595                 :            :     {
     596                 :          4 :       return mkTypeValue(tn, 0);
     597                 :            :     }
     598                 :            :   }
     599         [ +  + ]:        637 :   else if (n == mkTypeMaxValue(tn))
     600                 :            :   {
     601 [ +  + ][ -  + ]:        171 :     if (ik == Kind::OR || ik == Kind::BITVECTOR_OR)
     602                 :            :     {
     603                 :         40 :       return n;
     604                 :            :     }
     605                 :            :   }
     606                 :            :   else
     607                 :            :   {
     608 [ +  + ][ -  + ]:        466 :     if (n.getType().isInteger() && n.getConst<Rational>().sgn() < 0)
         [ +  - ][ -  + ]
                 [ -  - ]
     609                 :            :     {
     610                 :            :       // negative arguments
     611 [ -  - ][ -  - ]:          0 :       if (ik == Kind::STRING_SUBSTR || ik == Kind::STRING_CHARAT)
     612                 :            :       {
     613                 :          0 :         return mkTypeValue(NodeManager::currentNM()->stringType(), 0);
     614                 :            :       }
     615         [ -  - ]:          0 :       else if (ik == Kind::STRING_INDEXOF)
     616                 :            :       {
     617                 :          0 :         Assert(arg == 2);
     618                 :          0 :         return mkTypeValue(NodeManager::currentNM()->integerType(), -1);
     619                 :            :       }
     620                 :            :     }
     621                 :            :   }
     622                 :       1514 :   return Node::null();
     623                 :            : }
     624                 :            : 
     625                 :       1034 : bool TermUtil::hasOffsetArg(Kind ik, int arg, int& offset, Kind& ok)
     626                 :            : {
     627         [ +  + ]:       1034 :   if (ik == Kind::LT)
     628                 :            :   {
     629 [ +  + ][ -  + ]:          8 :     Assert(arg == 0 || arg == 1);
         [ -  + ][ -  - ]
     630         [ +  + ]:          8 :     offset = arg == 0 ? 1 : -1;
     631                 :          8 :     ok = Kind::LEQ;
     632                 :          8 :     return true;
     633                 :            :   }
     634         [ -  + ]:       1026 :   else if (ik == Kind::BITVECTOR_ULT)
     635                 :            :   {
     636                 :          0 :     Assert(arg == 0 || arg == 1);
     637         [ -  - ]:          0 :     offset = arg == 0 ? 1 : -1;
     638                 :          0 :     ok = Kind::BITVECTOR_ULE;
     639                 :          0 :     return true;
     640                 :            :   }
     641         [ -  + ]:       1026 :   else if (ik == Kind::BITVECTOR_SLT)
     642                 :            :   {
     643                 :          0 :     Assert(arg == 0 || arg == 1);
     644         [ -  - ]:          0 :     offset = arg == 0 ? 1 : -1;
     645                 :          0 :     ok = Kind::BITVECTOR_SLE;
     646                 :          0 :     return true;
     647                 :            :   }
     648                 :       1026 :   return false;
     649                 :            : }
     650                 :            : 
     651                 :        606 : Node TermUtil::ensureType(Node n, TypeNode tn)
     652                 :            : {
     653                 :       1212 :   TypeNode ntn = n.getType();
     654         [ +  + ]:        606 :   if (ntn == tn)
     655                 :            :   {
     656                 :        588 :     return n;
     657                 :            :   }
     658         [ -  + ]:         18 :   if (tn.isInteger())
     659                 :            :   {
     660                 :          0 :     return NodeManager::mkNode(Kind::TO_INTEGER, n);
     661                 :            :   }
     662         [ +  - ]:         18 :   else if (tn.isReal())
     663                 :            :   {
     664                 :         18 :     return NodeManager::mkNode(Kind::TO_REAL, n);
     665                 :            :   }
     666                 :          0 :   return Node::null();
     667                 :            : }
     668                 :            : 
     669                 :            : }  // namespace quantifiers
     670                 :            : }  // namespace theory
     671                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14