LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/expr - skolem_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 308 332 92.8 %
Date: 2025-02-01 11:33:18 Functions: 19 20 95.0 %
Branches: 218 461 47.3 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Aina Niemetz, Amalee Wilson
       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 skolem manager class.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "expr/skolem_manager.h"
      17                 :            : 
      18                 :            : #include <sstream>
      19                 :            : 
      20                 :            : #include "expr/attribute.h"
      21                 :            : #include "expr/bound_var_manager.h"
      22                 :            : #include "expr/node_algorithm.h"
      23                 :            : #include "expr/node_manager_attributes.h"
      24                 :            : #include "expr/sort_to_term.h"
      25                 :            : #include "util/rational.h"
      26                 :            : #include "util/string.h"
      27                 :            : 
      28                 :            : using namespace cvc5::internal::kind;
      29                 :            : 
      30                 :            : namespace cvc5::internal {
      31                 :            : 
      32                 :            : struct OriginalFormAttributeId
      33                 :            : {
      34                 :            : };
      35                 :            : typedef expr::Attribute<OriginalFormAttributeId, Node> OriginalFormAttribute;
      36                 :            : 
      37                 :            : struct UnpurifiedFormAttributeId
      38                 :            : {
      39                 :            : };
      40                 :            : typedef expr::Attribute<UnpurifiedFormAttributeId, Node> UnpurifiedFormAttribute;
      41                 :            : 
      42                 :      28728 : SkolemManager::SkolemManager() : d_skolemCounter(0) {}
      43                 :            : 
      44                 :     368749 : Node SkolemManager::mkPurifySkolem(Node t)
      45                 :            : {
      46                 :     368749 :   SkolemManager* skm = t.getNodeManager()->getSkolemManager();
      47                 :            :   // We do not recursively compute the original form of t here
      48                 :     368749 :   Node k = skm->mkSkolemFunction(SkolemId::PURIFY, {t});
      49         [ +  - ]:     368749 :   Trace("sk-manager-skolem") << "skolem: " << k << " purify " << t << std::endl;
      50                 :     368749 :   return k;
      51                 :            : }
      52                 :            : 
      53                 :     374488 : Node SkolemManager::mkSkolemFunction(SkolemId id, Node cacheVal)
      54                 :            : {
      55                 :     748976 :   std::vector<Node> cvals;
      56         [ +  + ]:     374488 :   if (!cacheVal.isNull())
      57                 :            :   {
      58         [ -  + ]:     371394 :     if (cacheVal.getKind() == Kind::SEXPR)
      59                 :            :     {
      60                 :          0 :       cvals.insert(cvals.end(), cacheVal.begin(), cacheVal.end());
      61                 :            :     }
      62                 :            :     else
      63                 :            :     {
      64                 :     371394 :       cvals.push_back(cacheVal);
      65                 :            :     }
      66                 :            :   }
      67                 :     748976 :   return mkSkolemFunction(id, cvals);
      68                 :            : }
      69                 :            : 
      70                 :     413711 : Node SkolemManager::mkSkolemFunction(SkolemId id,
      71                 :            :                                      const std::vector<Node>& cacheVals)
      72                 :            : {
      73                 :     413711 :   TypeNode ctn = getTypeFor(id, cacheVals);
      74 [ -  + ][ -  + ]:     413711 :   Assert(!ctn.isNull());
                 [ -  - ]
      75                 :     827422 :   return mkSkolemFunctionTyped(id, ctn, cacheVals);
      76                 :            : }
      77                 :            : 
      78                 :     164999 : Node SkolemManager::mkInternalSkolemFunction(InternalSkolemId id,
      79                 :            :                                              TypeNode tn,
      80                 :            :                                              const std::vector<Node>& cacheVals)
      81                 :            : {
      82                 :     164999 :   NodeManager* nm = NodeManager::currentNM();
      83                 :     164999 :   std::vector<Node> cvals;
      84                 :     164999 :   cvals.push_back(nm->mkConstInt(Rational(static_cast<uint32_t>(id))));
      85                 :     164999 :   cvals.insert(cvals.end(), cacheVals.begin(), cacheVals.end());
      86                 :     329998 :   return mkSkolemFunctionTyped(SkolemId::INTERNAL, tn, cvals);
      87                 :            : }
      88                 :            : 
      89                 :         45 : bool SkolemManager::isCommutativeSkolemId(SkolemId id)
      90                 :            : {
      91         [ +  + ]:         45 :   switch (id)
      92                 :            :   {
      93                 :         30 :     case cvc5::SkolemId::ARRAY_DEQ_DIFF:
      94                 :            :     case cvc5::SkolemId::BAGS_DEQ_DIFF:
      95                 :            :     case cvc5::SkolemId::SETS_DEQ_DIFF:
      96                 :         30 :     case cvc5::SkolemId::STRINGS_DEQ_DIFF: return true;
      97                 :         15 :     default: break;
      98                 :            :   }
      99                 :         15 :   return false;
     100                 :            : }
     101                 :            : 
     102                 :     578710 : Node SkolemManager::mkSkolemFunctionTyped(SkolemId id,
     103                 :            :                                           TypeNode tn,
     104                 :            :                                           Node cacheVal)
     105                 :            : {
     106                 :    1157420 :   std::tuple<SkolemId, TypeNode, Node> key(id, tn, cacheVal);
     107                 :            :   std::map<std::tuple<SkolemId, TypeNode, Node>, Node>::iterator it =
     108                 :     578710 :       d_skolemFuns.find(key);
     109         [ +  + ]:     578710 :   if (it == d_skolemFuns.end())
     110                 :            :   {
     111                 :            :     // We use @ as a prefix, which follows the SMT-LIB standard indicating
     112                 :            :     // internal symbols starting with @ or . are reserved for internal use.
     113                 :            :     //
     114                 :     275980 :     std::stringstream ss;
     115                 :            :     // Print internal skolems by the internal identifier, otherwise all would
     116                 :            :     // be @INTERNAL_*.
     117         [ +  + ]:     137990 :     if (id == SkolemId::INTERNAL)
     118                 :            :     {
     119         [ +  + ]:      14540 :       Node cval = cacheVal.getKind() == Kind::SEXPR ? cacheVal[0] : cacheVal;
     120 [ -  + ][ -  + ]:       7270 :       Assert(cval.getKind() == Kind::CONST_INTEGER);
                 [ -  - ]
     121                 :       7270 :       Rational r = cval.getConst<Rational>();
     122                 :      14540 :       Assert(r.sgn() >= 0 && r.getNumerator().fitsUnsignedInt());
     123                 :       7270 :       ss << "@"
     124                 :       7270 :          << static_cast<InternalSkolemId>(r.getNumerator().toUnsignedInt());
     125                 :            :     }
     126                 :            :     else
     127                 :            :     {
     128                 :     130720 :       ss << "@" << id;
     129                 :            :     }
     130                 :     275980 :     Node k = mkSkolemNode(Kind::SKOLEM, ss.str(), tn);
     131         [ +  + ]:     137990 :     if (id == SkolemId::PURIFY)
     132                 :            :     {
     133 [ -  + ][ -  + ]:     106210 :       Assert(cacheVal.getType() == tn);
                 [ -  - ]
     134                 :            :       // set unpurified form attribute for k
     135                 :            :       UnpurifiedFormAttribute ufa;
     136                 :     106210 :       k.setAttribute(ufa, cacheVal);
     137                 :            :       // the original form of k can be computed by calling getOriginalForm, but
     138                 :            :       // it is not computed here
     139                 :            :     }
     140                 :     137990 :     d_skolemFuns[key] = k;
     141                 :     137990 :     d_skolemFunMap[k] = key;
     142         [ +  - ]:     275980 :     Trace("sk-manager-skolem") << "mkSkolemFunction(" << id << ", " << cacheVal
     143                 :     137990 :                                << ") returns " << k << std::endl;
     144                 :     137990 :     return k;
     145                 :            :   }
     146                 :     440720 :   return it->second;
     147                 :            : }
     148                 :            : 
     149                 :     578710 : Node SkolemManager::mkSkolemFunctionTyped(SkolemId id,
     150                 :            :                                           TypeNode tn,
     151                 :            :                                           const std::vector<Node>& cacheVals)
     152                 :            : {
     153                 :     578710 :   Node cacheVal;
     154                 :            :   // use null node if cacheVals is empty
     155         [ +  + ]:     578710 :   if (!cacheVals.empty())
     156                 :            :   {
     157                 :     575609 :     cacheVal = cacheVals.size() == 1
     158         [ +  + ]:    1151220 :                    ? cacheVals[0]
     159                 :     575609 :                    : NodeManager::currentNM()->mkNode(Kind::SEXPR, cacheVals);
     160                 :            :   }
     161                 :    1157420 :   return mkSkolemFunctionTyped(id, tn, cacheVal);
     162                 :            : }
     163                 :            : 
     164                 :          0 : bool SkolemManager::isSkolemFunction(TNode k)
     165                 :            : {
     166                 :          0 :   return k.getKind() == Kind::SKOLEM;
     167                 :            : }
     168                 :            : 
     169                 :    1190040 : bool SkolemManager::isSkolemFunction(TNode k,
     170                 :            :                                      SkolemId& id,
     171                 :            :                                      Node& cacheVal)
     172                 :            : {
     173                 :    1190040 :   SkolemManager* skm = k.getNodeManager()->getSkolemManager();
     174         [ +  + ]:    1190040 :   if (k.getKind() != Kind::SKOLEM)
     175                 :            :   {
     176                 :    1167740 :     return false;
     177                 :            :   }
     178                 :            :   std::map<Node, std::tuple<SkolemId, TypeNode, Node>>::const_iterator it =
     179                 :      22298 :       skm->d_skolemFunMap.find(k);
     180 [ -  + ][ -  + ]:      22298 :   Assert(it != skm->d_skolemFunMap.end());
                 [ -  - ]
     181                 :      22298 :   id = std::get<0>(it->second);
     182                 :      22298 :   cacheVal = std::get<2>(it->second);
     183                 :      22298 :   return true;
     184                 :            : }
     185                 :            : 
     186                 :      20208 : SkolemId SkolemManager::getId(TNode k) const
     187                 :            : {
     188                 :            :   SkolemId id;
     189                 :      40416 :   Node cacheVal;
     190         [ +  + ]:      20208 :   if (isSkolemFunction(k, id, cacheVal))
     191                 :            :   {
     192                 :        127 :     return id;
     193                 :            :   }
     194                 :      20081 :   return SkolemId::NONE;
     195                 :            : }
     196                 :            : 
     197                 :         15 : std::vector<Node> SkolemManager::getIndices(TNode k) const
     198                 :            : {
     199                 :         15 :   std::vector<Node> vec;
     200                 :            :   SkolemId id;
     201                 :         30 :   Node cacheVal;
     202         [ +  - ]:         15 :   if (isSkolemFunction(k, id, cacheVal))
     203                 :            :   {
     204         [ +  - ]:         15 :     if (!cacheVal.isNull())
     205                 :            :     {
     206         [ +  - ]:         15 :       if (cacheVal.getKind() == Kind::SEXPR)
     207                 :            :       {
     208                 :         15 :         vec.insert(vec.end(), cacheVal.begin(), cacheVal.end());
     209                 :            :       }
     210                 :            :       else
     211                 :            :       {
     212                 :          0 :         vec.push_back(cacheVal);
     213                 :            :       }
     214                 :            :     }
     215                 :            :   }
     216                 :         30 :   return vec;
     217                 :            : }
     218                 :            : 
     219                 :    1141300 : InternalSkolemId SkolemManager::getInternalId(TNode k) const
     220                 :            : {
     221                 :            :   SkolemId id;
     222                 :    2282590 :   Node cacheVal;
     223                 :            :   // if its an internal skolem
     224 [ +  + ][ +  + ]:    1141300 :   if (isSkolemFunction(k, id, cacheVal) && id == SkolemId::INTERNAL)
         [ +  - ][ +  + ]
                 [ -  - ]
     225                 :            :   {
     226 [ -  + ][ -  + ]:        801 :     Assert(!cacheVal.isNull());
                 [ -  - ]
     227         [ +  + ]:       1602 :     Node cval = cacheVal.getKind() == Kind::SEXPR ? cacheVal[0] : cacheVal;
     228 [ -  + ][ -  + ]:        801 :     Assert(cval.getKind() == Kind::CONST_INTEGER);
                 [ -  - ]
     229                 :        801 :     Rational r = cval.getConst<Rational>();
     230                 :       1602 :     Assert(r.sgn() >= 0 && r.getNumerator().fitsUnsignedInt());
     231                 :        801 :     return static_cast<InternalSkolemId>(r.getNumerator().toUnsignedInt());
     232                 :            :   }
     233                 :    1140490 :   return InternalSkolemId::NONE;
     234                 :            : }
     235                 :            : 
     236                 :     514698 : Node SkolemManager::mkDummySkolem(const std::string& prefix,
     237                 :            :                                   const TypeNode& type,
     238                 :            :                                   const std::string& comment,
     239                 :            :                                   SkolemFlags flags)
     240                 :            : {
     241                 :     514698 :   return mkSkolemNode(Kind::DUMMY_SKOLEM, prefix, type, flags);
     242                 :            : }
     243                 :            : 
     244                 :        232 : bool SkolemManager::isAbstractValue(TNode n) const
     245                 :            : {
     246                 :        232 :   return (getInternalId(n) == InternalSkolemId::ABSTRACT_VALUE);
     247                 :            : }
     248                 :            : 
     249                 :    1354810 : Node SkolemManager::getOriginalForm(Node n)
     250                 :            : {
     251         [ -  + ]:    1354810 :   if (n.isNull())
     252                 :            :   {
     253                 :          0 :     return n;
     254                 :            :   }
     255         [ +  - ]:    2709630 :   Trace("sk-manager-debug")
     256                 :    1354810 :       << "SkolemManager::getOriginalForm " << n << std::endl;
     257                 :            :   OriginalFormAttribute ofa;
     258                 :            :   UnpurifiedFormAttribute ufa;
     259                 :    1354810 :   NodeManager* nm = NodeManager::currentNM();
     260                 :    2709630 :   std::unordered_set<TNode> visited;
     261                 :    1354810 :   std::unordered_set<TNode>::iterator it;
     262                 :    2709630 :   std::vector<TNode> visit;
     263                 :    2709630 :   TNode cur;
     264                 :    1354810 :   visit.push_back(n);
     265                 :    1263050 :   do
     266                 :            :   {
     267                 :    2617860 :     cur = visit.back();
     268         [ +  + ]:    2617860 :     if (cur.hasAttribute(ofa))
     269                 :            :     {
     270                 :    1704490 :       visit.pop_back();
     271                 :    2236250 :       continue;
     272                 :            :     }
     273         [ +  + ]:     913378 :     else if (cur.hasAttribute(ufa))
     274                 :            :     {
     275                 :            :       // if it has an unpurified form, compute the original form of it
     276                 :     172244 :       Node ucur = cur.getAttribute(ufa);
     277         [ +  + ]:      86122 :       if (ucur.hasAttribute(ofa))
     278                 :            :       {
     279                 :            :         // Already computed, set. This always happens after cur is visited
     280                 :            :         // again after computing the original form of its unpurified form.
     281                 :      94878 :         Node ucuro = ucur.getAttribute(ofa);
     282                 :      47439 :         cur.setAttribute(ofa, ucuro);
     283                 :      47439 :         visit.pop_back();
     284                 :            :       }
     285                 :            :       else
     286                 :            :       {
     287                 :            :         // visit ucur then visit cur again
     288                 :      38683 :         visit.push_back(ucur);
     289                 :            :       }
     290                 :      86122 :       continue;
     291                 :            :     }
     292         [ +  + ]:     827256 :     else if (cur.getNumChildren() == 0)
     293                 :            :     {
     294                 :      64026 :       cur.setAttribute(ofa, cur);
     295                 :      64026 :       visit.pop_back();
     296                 :      64026 :       continue;
     297                 :            :     }
     298                 :     763230 :     it = visited.find(cur);
     299         [ +  + ]:     763230 :     if (it == visited.end())
     300                 :            :     {
     301                 :     381615 :       visited.insert(cur);
     302         [ +  + ]:     381615 :       if (cur.getMetaKind() == metakind::PARAMETERIZED)
     303                 :            :       {
     304                 :      15790 :         visit.push_back(cur.getOperator());
     305                 :            :       }
     306                 :     381615 :       visit.insert(visit.end(), cur.begin(), cur.end());
     307                 :     381615 :       continue;
     308                 :            :     }
     309                 :     381615 :     visit.pop_back();
     310                 :     763230 :     Node ret = cur;
     311                 :     381615 :     bool childChanged = false;
     312                 :     763230 :     std::vector<Node> children;
     313         [ +  + ]:     381615 :     if (cur.getMetaKind() == metakind::PARAMETERIZED)
     314                 :            :     {
     315                 :      31580 :       const Node& oon = cur.getOperator().getAttribute(ofa);
     316 [ -  + ][ -  + ]:      15790 :       Assert(!oon.isNull());
                 [ -  - ]
     317 [ +  - ][ +  + ]:      15790 :       childChanged = childChanged || cur.getOperator() != oon;
         [ +  - ][ -  - ]
     318                 :      15790 :       children.push_back(oon);
     319                 :            :     }
     320         [ +  + ]:    1169900 :     for (const Node& cn : cur)
     321                 :            :     {
     322                 :    1576560 :       const Node& ocn = cn.getAttribute(ofa);
     323 [ -  + ][ -  + ]:     788281 :       Assert(!ocn.isNull());
                 [ -  - ]
     324 [ +  + ][ +  + ]:     788281 :       childChanged = childChanged || cn != ocn;
     325                 :     788281 :       children.push_back(ocn);
     326                 :            :     }
     327         [ +  + ]:     381615 :     if (childChanged)
     328                 :            :     {
     329                 :     163166 :       ret = nm->mkNode(cur.getKind(), children);
     330                 :            :     }
     331                 :     381615 :     cur.setAttribute(ofa, ret);
     332                 :            : 
     333         [ +  + ]:    2617860 :   } while (!visit.empty());
     334                 :    2709630 :   const Node& on = n.getAttribute(ofa);
     335         [ +  - ]:    1354810 :   Trace("sk-manager-debug") << "..return " << on << std::endl;
     336                 :    1354810 :   return on;
     337                 :            : }
     338                 :            : 
     339                 :     286540 : Node SkolemManager::getUnpurifiedForm(Node k)
     340                 :            : {
     341                 :            :   UnpurifiedFormAttribute ufa;
     342         [ +  + ]:     286540 :   if (k.hasAttribute(ufa))
     343                 :            :   {
     344                 :     183605 :     return k.getAttribute(ufa);
     345                 :            :   }
     346                 :     102935 :   return k;
     347                 :            : }
     348                 :            : 
     349                 :     652688 : Node SkolemManager::mkSkolemNode(Kind k,
     350                 :            :                                  const std::string& prefix,
     351                 :            :                                  const TypeNode& type,
     352                 :            :                                  SkolemFlags flags)
     353                 :            : {
     354                 :     652688 :   NodeManager* nm = NodeManager::currentNM();
     355                 :     652688 :   Node n = NodeBuilder(nm, k);
     356                 :     652688 :   if ((flags & SkolemFlags::SKOLEM_EXACT_NAME)
     357         [ +  + ]:     652688 :       == SkolemFlags::SKOLEM_EXACT_NAME)
     358                 :            :   {
     359                 :     415577 :     n.setAttribute(expr::VarNameAttr(), prefix);
     360                 :            :   }
     361                 :            :   else
     362                 :            :   {
     363                 :     237111 :     std::stringstream name;
     364                 :     237111 :     name << prefix << '_' << ++d_skolemCounter;
     365                 :     237111 :     n.setAttribute(expr::VarNameAttr(), name.str());
     366                 :            :   }
     367                 :     652688 :   n.setAttribute(expr::TypeAttr(), type);
     368                 :     652688 :   n.setAttribute(expr::TypeCheckedAttr(), true);
     369                 :     652688 :   return n;
     370                 :            : }
     371                 :            : 
     372                 :     413711 : TypeNode SkolemManager::getTypeFor(SkolemId id,
     373                 :            :                                    const std::vector<Node>& cacheVals)
     374                 :            : {
     375                 :     413711 :   NodeManager* nm = NodeManager::currentNM();
     376 [ +  + ][ +  + ]:     413711 :   switch (id)
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
         [ -  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                    [ - ]
     377                 :            :   {
     378                 :            :     // Type(cacheVals[0]), i.e skolems that return same type as first argument
     379                 :     369009 :     case SkolemId::PURIFY:
     380                 :            :     case SkolemId::TRANSCENDENTAL_PURIFY:
     381 [ -  + ][ -  + ]:     369009 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     382                 :     369009 :       return cacheVals[0].getType();
     383                 :            :       break;
     384                 :        835 :     case SkolemId::GROUND_TERM:
     385                 :            :     case SkolemId::ARITH_VTS_INFINITY:
     386                 :            :     case SkolemId::ARITH_VTS_INFINITY_FREE:
     387                 :            :     {
     388 [ -  + ][ -  + ]:        835 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     389                 :        835 :       return cacheVals[0].getConst<SortToTerm>().getType();
     390                 :            :     }
     391                 :            :     // real -> real function
     392                 :        951 :     case SkolemId::DIV_BY_ZERO:
     393                 :            :     {
     394                 :       1902 :       TypeNode rtype = nm->realType();
     395                 :        951 :       return nm->mkFunctionType(rtype, rtype);
     396                 :            :     }
     397                 :            :     // real skolems
     398                 :        859 :     case SkolemId::TRANSCENDENTAL_PURIFY_ARG:
     399                 :            :     case SkolemId::TRANSCENDENTAL_SINE_PHASE_SHIFT:
     400                 :            :     case SkolemId::ARITH_VTS_DELTA:
     401                 :        859 :     case SkolemId::ARITH_VTS_DELTA_FREE: return nm->realType();
     402                 :            :     // int -> int function
     403                 :       1785 :     case SkolemId::INT_DIV_BY_ZERO:
     404                 :            :     case SkolemId::MOD_BY_ZERO:
     405                 :            :     case SkolemId::STRINGS_OCCUR_INDEX:
     406                 :            :     case SkolemId::STRINGS_OCCUR_INDEX_RE:
     407                 :            :     case SkolemId::STRINGS_OCCUR_LEN_RE:
     408                 :            :     case SkolemId::STRINGS_STOI_RESULT:
     409                 :            :     case SkolemId::STRINGS_ITOS_RESULT:
     410                 :            :     case SkolemId::BAGS_MAP_SUM:
     411                 :            :     case SkolemId::BAGS_CARD_COMBINE:
     412                 :            :     {
     413                 :       3570 :       TypeNode itype = nm->integerType();
     414                 :       1785 :       return nm->mkFunctionType(itype, itype);
     415                 :            :     }
     416                 :        662 :     case SkolemId::BV_EMPTY:
     417                 :            :     {
     418                 :        662 :       return nm->mkBitVectorType(0);
     419                 :            :     }
     420                 :            :     // int -> Type(args[0])
     421                 :        170 :     case SkolemId::STRINGS_REPLACE_ALL_RESULT:
     422                 :            :     {
     423 [ -  + ][ -  + ]:        170 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     424                 :        170 :       TypeNode itype = nm->integerType();
     425                 :        340 :       return nm->mkFunctionType(itype, cacheVals[0].getType());
     426                 :            :     }
     427                 :            :     // integer skolems
     428                 :       1278 :     case SkolemId::STRINGS_NUM_OCCUR:
     429                 :            :     case SkolemId::STRINGS_NUM_OCCUR_RE:
     430                 :            :     case SkolemId::STRINGS_DEQ_DIFF:
     431                 :            :     case SkolemId::STRINGS_STOI_NON_DIGIT:
     432                 :            :     case SkolemId::BAGS_FOLD_CARD:
     433                 :            :     case SkolemId::SETS_FOLD_CARD:
     434                 :            :     case SkolemId::BAGS_DISTINCT_ELEMENTS_SIZE:
     435                 :       1278 :     case SkolemId::BAGS_MAP_INDEX: return nm->integerType();
     436                 :            :     // string skolems
     437                 :       2823 :     case SkolemId::RE_FIRST_MATCH_PRE:
     438                 :            :     case SkolemId::RE_FIRST_MATCH:
     439                 :            :     case SkolemId::RE_FIRST_MATCH_POST:
     440                 :       2823 :     case SkolemId::RE_UNFOLD_POS_COMPONENT: return nm->stringType();
     441                 :       4052 :     case SkolemId::ARRAY_DEQ_DIFF:
     442                 :            :     {
     443 [ -  + ][ -  + ]:       4052 :       Assert(cacheVals.size() == 2);
                 [ -  - ]
     444                 :       8104 :       TypeNode atype = cacheVals[0].getType();
     445 [ -  + ][ -  + ]:       4052 :       Assert(atype.isArray());
                 [ -  - ]
     446                 :       4052 :       return atype.getArrayIndexType();
     447                 :            :     }
     448                 :      12835 :     case SkolemId::QUANTIFIERS_SKOLEMIZE:
     449                 :            :     {
     450 [ -  + ][ -  + ]:      12835 :       Assert(cacheVals.size() == 2);
                 [ -  - ]
     451 [ -  + ][ -  + ]:      12835 :       Assert(cacheVals[0].getKind() == Kind::FORALL);
                 [ -  - ]
     452 [ -  + ][ -  + ]:      12835 :       Assert(cacheVals[1].getKind() == Kind::CONST_INTEGER);
                 [ -  - ]
     453                 :      12835 :       const Rational& r = cacheVals[1].getConst<Rational>();
     454 [ -  + ][ -  + ]:      12835 :       Assert(r.getNumerator().fitsUnsignedInt());
                 [ -  - ]
     455                 :      12835 :       size_t i = r.getNumerator().toUnsignedInt();
     456 [ -  + ][ -  + ]:      12835 :       Assert(i < cacheVals[0][0].getNumChildren());
                 [ -  - ]
     457                 :      12835 :       return cacheVals[0][0][i].getType();
     458                 :            :     }
     459                 :            :     break;
     460                 :          0 :     case SkolemId::WITNESS_STRING_LENGTH:
     461                 :            :     {
     462                 :          0 :       Assert(cacheVals.size() == 3);
     463                 :          0 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
     464                 :          0 :       Assert(cacheVals[1].getKind() == Kind::CONST_INTEGER);
     465                 :          0 :       Assert(cacheVals[2].getKind() == Kind::CONST_INTEGER);
     466                 :          0 :       TypeNode t = cacheVals[0].getConst<SortToTerm>().getType();
     467                 :          0 :       return t;
     468                 :            :     }
     469                 :            :     break;
     470                 :          0 :     case SkolemId::WITNESS_INV_CONDITION:
     471                 :            :     {
     472                 :          0 :       Assert(cacheVals.size() == 1);
     473                 :          0 :       Assert(cacheVals[0].getKind() == Kind::EXISTS);
     474                 :          0 :       Assert(cacheVals[0][0].getNumChildren() == 1);
     475                 :          0 :       return cacheVals[0][0][0].getType();
     476                 :            :     }
     477                 :            :     break;
     478                 :            :     // skolems that return the set element type
     479                 :       5858 :     case SkolemId::BAGS_DEQ_DIFF:
     480                 :            :     case SkolemId::SETS_DEQ_DIFF:
     481                 :            :     {
     482 [ -  + ][ -  + ]:       5858 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     483                 :      11716 :       TypeNode stype = cacheVals[0].getType();
     484 [ -  + ][ -  + ]:       5858 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     485                 :       5858 :       return stype[0];
     486                 :            :     }
     487                 :            :     // skolems that return the set to set element type
     488                 :        285 :     case SkolemId::BAGS_CHOOSE:
     489                 :            :     case SkolemId::SETS_CHOOSE:
     490                 :            :     {
     491 [ -  + ][ -  + ]:        285 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     492                 :        285 :       TypeNode stype = cacheVals[0].getType();
     493 [ -  + ][ -  + ]:        285 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     494                 :        285 :       return nm->mkFunctionType(stype, stype[0]);
     495                 :            :     }
     496                 :       1019 :     case SkolemId::TABLES_GROUP_PART:
     497                 :            :     case SkolemId::RELATIONS_GROUP_PART:
     498                 :            :     {
     499 [ -  + ][ -  + ]:       1019 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     500                 :       1019 :       TypeNode stype = cacheVals[0].getType();
     501 [ -  + ][ -  + ]:       1019 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     502                 :       1019 :       stype = stype[0];
     503 [ -  + ][ -  + ]:       1019 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     504                 :       1019 :       return nm->mkFunctionType(stype[0], stype);
     505                 :            :     }
     506                 :            :     // skolems that return the set element of set element type
     507                 :        211 :     case SkolemId::TABLES_GROUP_PART_ELEMENT:
     508                 :            :     case SkolemId::RELATIONS_GROUP_PART_ELEMENT:
     509                 :            :     {
     510 [ -  + ][ -  + ]:        211 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     511                 :        422 :       TypeNode stype = cacheVals[0].getType();
     512 [ -  + ][ -  + ]:        211 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     513                 :        211 :       stype = stype[0];
     514 [ -  + ][ -  + ]:        211 :       Assert(stype.getNumChildren() == 1);
                 [ -  - ]
     515                 :        211 :       return stype[0];
     516                 :            :     }
     517                 :         96 :     case SkolemId::SETS_MAP_DOWN_ELEMENT:
     518                 :            :     {
     519 [ +  - ][ +  - ]:        192 :       Assert(cacheVals.size() == 2 && cacheVals[0].getKind() == Kind::SET_MAP);
         [ -  + ][ -  - ]
     520                 :        192 :       TypeNode stype = cacheVals[0][1].getType();
     521 [ -  + ][ -  + ]:         96 :       Assert(stype.isSet());
                 [ -  - ]
     522                 :         96 :       return stype.getSetElementType();
     523                 :            :     }
     524                 :         48 :     case SkolemId::BAGS_FOLD_UNION_DISJOINT:
     525                 :            :     case SkolemId::SETS_FOLD_UNION:
     526                 :            :     case SkolemId::BAGS_DISTINCT_ELEMENTS_UNION_DISJOINT:
     527                 :            :     {
     528 [ -  + ][ -  + ]:         48 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     529                 :         48 :       TypeNode itype = nm->integerType();
     530                 :         96 :       return nm->mkFunctionType(itype, cacheVals[0].getType());
     531                 :            :     }
     532                 :         84 :     case SkolemId::BAGS_DISTINCT_ELEMENTS:
     533                 :            :     case SkolemId::BAGS_FOLD_ELEMENTS:
     534                 :            :     case SkolemId::SETS_FOLD_ELEMENTS:
     535                 :            :     {
     536 [ -  + ][ -  + ]:         84 :       Assert(cacheVals.size() > 0);
                 [ -  - ]
     537                 :        168 :       TypeNode itype = nm->integerType();
     538                 :        168 :       TypeNode collectionType = cacheVals[0].getType();
     539 [ -  + ][ -  + ]:         84 :       Assert(collectionType.getNumChildren() == 1);
                 [ -  - ]
     540                 :        168 :       TypeNode elementType = collectionType[0];
     541                 :         84 :       return nm->mkFunctionType(itype, elementType);
     542                 :            :     }
     543                 :         14 :     case SkolemId::BAGS_FOLD_COMBINE:
     544                 :            :     case SkolemId::SETS_FOLD_COMBINE:
     545                 :            :     {
     546 [ -  + ][ -  + ]:         14 :       Assert(cacheVals.size() == 3);
                 [ -  - ]
     547                 :         14 :       TypeNode itype = nm->integerType();
     548                 :         28 :       return nm->mkFunctionType(itype, cacheVals[1].getType());
     549                 :            :     }
     550                 :         11 :     case SkolemId::BAGS_MAP_PREIMAGE_INJECTIVE:
     551                 :            :     {
     552 [ -  + ][ -  + ]:         11 :       Assert (cacheVals[0].getType().isFunction());
                 [ -  - ]
     553                 :         22 :       return cacheVals[0].getType().getArgTypes()[0];
     554                 :            :     }
     555                 :       2521 :     case SkolemId::SHARED_SELECTOR:
     556                 :            :     {
     557 [ -  + ][ -  + ]:       2521 :       Assert(cacheVals.size() == 3);
                 [ -  - ]
     558 [ -  + ][ -  + ]:       2521 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     559 [ -  + ][ -  + ]:       2521 :       Assert(cacheVals[1].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     560                 :       5042 :       TypeNode dtt = cacheVals[0].getConst<SortToTerm>().getType();
     561                 :       2521 :       TypeNode t = cacheVals[1].getConst<SortToTerm>().getType();
     562                 :       2521 :       return nm->mkSelectorType(dtt, t);
     563                 :            :     }
     564                 :       8160 :     case SkolemId::HO_DEQ_DIFF:
     565                 :            :     {
     566                 :       8160 :       const Rational& r = cacheVals[2].getConst<Rational>();
     567 [ -  + ][ -  + ]:       8160 :       Assert(r.getNumerator().fitsUnsignedInt());
                 [ -  - ]
     568                 :       8160 :       size_t i = r.getNumerator().toUnsignedInt();
     569 [ -  + ][ -  + ]:       8160 :       Assert(cacheVals[0].getType().isFunction());
                 [ -  - ]
     570                 :      16320 :       std::vector<TypeNode> argTypes = cacheVals[0].getType().getArgTypes();
     571 [ -  + ][ -  + ]:       8160 :       Assert(i < argTypes.size());
                 [ -  - ]
     572                 :       8160 :       return argTypes[i];
     573                 :            :     }
     574                 :            :     // fp skolems
     575                 :         12 :     case SkolemId::FP_MIN_ZERO:
     576                 :            :     case SkolemId::FP_MAX_ZERO:
     577                 :            :     {
     578 [ -  + ][ -  + ]:         12 :       Assert(cacheVals.size() == 1);
                 [ -  - ]
     579 [ -  + ][ -  + ]:         12 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     580                 :         12 :       TypeNode type = cacheVals[0].getConst<SortToTerm>().getType();
     581 [ -  + ][ -  + ]:         12 :       Assert(type.isFloatingPoint());
                 [ -  - ]
     582 [ +  + ][ -  - ]:         36 :       return nm->mkFunctionType({type, type}, nm->mkBitVectorType(1));
     583                 :            :     }
     584                 :         31 :     case SkolemId::FP_TO_SBV:
     585                 :            :     case SkolemId::FP_TO_UBV:
     586                 :            :     {
     587 [ -  + ][ -  + ]:         31 :       Assert(cacheVals.size() == 2);
                 [ -  - ]
     588 [ -  + ][ -  + ]:         31 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     589                 :         62 :       TypeNode fptype = cacheVals[0].getConst<SortToTerm>().getType();
     590 [ -  + ][ -  + ]:         31 :       Assert(fptype.isFloatingPoint());
                 [ -  - ]
     591 [ -  + ][ -  + ]:         31 :       Assert(cacheVals[1].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     592                 :         31 :       TypeNode bvtype = cacheVals[1].getConst<SortToTerm>().getType();
     593 [ -  + ][ -  + ]:         31 :       Assert(bvtype.isBitVector());
                 [ -  - ]
     594 [ +  + ][ -  - ]:         93 :       return nm->mkFunctionType({nm->roundingModeType(), fptype}, bvtype);
     595                 :            :     }
     596                 :         18 :     case SkolemId::FP_TO_REAL:
     597                 :            :     {
     598 [ -  + ][ -  + ]:         18 :       Assert(cacheVals.size() == 1);
                 [ -  - ]
     599 [ -  + ][ -  + ]:         18 :       Assert(cacheVals[0].getKind() == Kind::SORT_TO_TERM);
                 [ -  - ]
     600                 :         18 :       TypeNode type = cacheVals[0].getConst<SortToTerm>().getType();
     601 [ -  + ][ -  + ]:         18 :       Assert(type.isFloatingPoint());
                 [ -  - ]
     602                 :         36 :       return nm->mkFunctionType({type}, nm->realType());
     603                 :            :     }
     604                 :         84 :     case SkolemId::BV_TO_INT_UF:
     605                 :            :     {
     606 [ -  + ][ -  + ]:         84 :       Assert(cacheVals.size() == 1);
                 [ -  - ]
     607                 :            :       // fetch the original function
     608                 :        168 :       Node bvUF = cacheVals[0];
     609 [ -  + ][ -  + ]:         84 :       Assert(cacheVals[0].getType().isFunction());
                 [ -  - ]
     610                 :            :       // old and new types of domain and result
     611                 :        168 :       TypeNode tn = bvUF.getType();
     612                 :        168 :       TypeNode bvRange = tn.getRangeType();
     613                 :        168 :       std::vector<TypeNode> bvDomain = tn.getArgTypes();
     614                 :        168 :       std::vector<TypeNode> intDomain;
     615                 :            : 
     616                 :            :       // if the original range is a bit-vector sort,
     617                 :            :       // the new range should be an integer sort.
     618                 :            :       // Otherwise, we keep the original range.
     619                 :            :       // Similarly for the domain sorts.
     620         [ +  + ]:        168 :       TypeNode intRange = bvRange.isBitVector() ? nm->integerType() : bvRange;
     621         [ +  + ]:        197 :       for (const TypeNode& d : bvDomain)
     622                 :            :       {
     623         [ +  + ]:        113 :         intDomain.push_back(d.isBitVector() ? nm->integerType() : d);
     624                 :            :       }
     625                 :         84 :       return nm->mkFunctionType(intDomain, intRange);
     626                 :            :     }
     627                 :            :     //
     628                 :          0 :     default: break;
     629                 :            :   }
     630                 :          0 :   return TypeNode();
     631                 :            : }
     632                 :            : 
     633                 :         86 : size_t SkolemManager::getNumIndicesForSkolemId(SkolemId id) const
     634                 :            : {
     635 [ +  - ][ +  - ]:         86 :   switch (id)
                 [ +  - ]
     636                 :            :   {
     637                 :            :     // Number of skolem indices: 0
     638                 :         14 :     case SkolemId::BV_EMPTY:
     639                 :            :     case SkolemId::DIV_BY_ZERO:
     640                 :            :     case SkolemId::INT_DIV_BY_ZERO:
     641                 :         14 :     case SkolemId::MOD_BY_ZERO: return 0;
     642                 :            : 
     643                 :            :     // Number of skolem indices: 1
     644                 :          0 :     case SkolemId::PURIFY:
     645                 :            :     case SkolemId::GROUND_TERM:
     646                 :            :     case SkolemId::TRANSCENDENTAL_PURIFY:
     647                 :            :     case SkolemId::TRANSCENDENTAL_PURIFY_ARG:
     648                 :            :     case SkolemId::TRANSCENDENTAL_SINE_PHASE_SHIFT:
     649                 :            :     case SkolemId::STRINGS_REPLACE_ALL_RESULT:
     650                 :            :     case SkolemId::STRINGS_ITOS_RESULT:
     651                 :            :     case SkolemId::STRINGS_STOI_RESULT:
     652                 :            :     case SkolemId::STRINGS_STOI_NON_DIGIT:
     653                 :            :     case SkolemId::BAGS_CARD_COMBINE:
     654                 :            :     case SkolemId::BAGS_DISTINCT_ELEMENTS_UNION_DISJOINT:
     655                 :            :     case SkolemId::BAGS_FOLD_CARD:
     656                 :            :     case SkolemId::BAGS_FOLD_ELEMENTS:
     657                 :            :     case SkolemId::BAGS_FOLD_UNION_DISJOINT:
     658                 :            :     case SkolemId::BAGS_CHOOSE:
     659                 :            :     case SkolemId::BAGS_DISTINCT_ELEMENTS:
     660                 :            :     case SkolemId::BAGS_DISTINCT_ELEMENTS_SIZE:
     661                 :            :     case SkolemId::TABLES_GROUP_PART:
     662                 :            :     case SkolemId::RELATIONS_GROUP_PART:
     663                 :            :     case SkolemId::SETS_CHOOSE:
     664                 :            :     case SkolemId::SETS_FOLD_CARD:
     665                 :            :     case SkolemId::SETS_FOLD_ELEMENTS:
     666                 :            :     case SkolemId::SETS_FOLD_UNION:
     667                 :            :     case SkolemId::FP_MIN_ZERO:
     668                 :            :     case SkolemId::FP_MAX_ZERO:
     669                 :            :     case SkolemId::BV_TO_INT_UF:
     670                 :          0 :     case SkolemId::FP_TO_REAL: return 1;
     671                 :            : 
     672                 :            :     // Number of skolem indices: 2
     673                 :         68 :     case SkolemId::ARRAY_DEQ_DIFF:
     674                 :            :     case SkolemId::QUANTIFIERS_SKOLEMIZE:
     675                 :            :     case SkolemId::STRINGS_NUM_OCCUR:
     676                 :            :     case SkolemId::STRINGS_OCCUR_INDEX:
     677                 :            :     case SkolemId::STRINGS_NUM_OCCUR_RE:
     678                 :            :     case SkolemId::STRINGS_OCCUR_INDEX_RE:
     679                 :            :     case SkolemId::STRINGS_OCCUR_LEN_RE:
     680                 :            :     case SkolemId::STRINGS_DEQ_DIFF:
     681                 :            :     case SkolemId::RE_FIRST_MATCH_PRE:
     682                 :            :     case SkolemId::RE_FIRST_MATCH:
     683                 :            :     case SkolemId::RE_FIRST_MATCH_POST:
     684                 :            :     case SkolemId::BAGS_DEQ_DIFF:
     685                 :            :     case SkolemId::TABLES_GROUP_PART_ELEMENT:
     686                 :            :     case SkolemId::RELATIONS_GROUP_PART_ELEMENT:
     687                 :            :     case SkolemId::SETS_DEQ_DIFF:
     688                 :            :     case SkolemId::SETS_MAP_DOWN_ELEMENT:
     689                 :            :     case SkolemId::FP_TO_SBV:
     690                 :         68 :     case SkolemId::FP_TO_UBV: return 2;
     691                 :            : 
     692                 :            :     // Number of skolem indices: 3
     693                 :          0 :     case SkolemId::SHARED_SELECTOR:
     694                 :            :     case SkolemId::RE_UNFOLD_POS_COMPONENT:
     695                 :            :     case SkolemId::BAGS_FOLD_COMBINE:
     696                 :            :     case SkolemId::BAGS_MAP_PREIMAGE_INJECTIVE:
     697                 :            :     case SkolemId::BAGS_MAP_SUM:
     698                 :          0 :     case SkolemId::SETS_FOLD_COMBINE: return 3;
     699                 :            : 
     700                 :            :     // Number of skolem indices: 5
     701                 :          4 :     case SkolemId::BAGS_MAP_INDEX: return 5;
     702                 :            : 
     703                 :          0 :     default: Unimplemented() << "Unknown skolem kind " << id; break;
     704                 :            :   }
     705                 :            : }
     706                 :            : 
     707                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14