LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/expr - sequence.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 128 192 66.7 %
Date: 2026-06-28 10:36:19 Functions: 21 29 72.4 %
Branches: 99 180 55.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Implementation of the sequence data type.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "expr/sequence.h"
      14                 :            : 
      15                 :            : #include <limits>
      16                 :            : #include <sstream>
      17                 :            : #include <vector>
      18                 :            : 
      19                 :            : #include "expr/node.h"
      20                 :            : #include "expr/type_node.h"
      21                 :            : 
      22                 :            : using namespace std;
      23                 :            : 
      24                 :            : namespace cvc5::internal {
      25                 :            : 
      26                 :      96927 : Sequence::Sequence(const TypeNode& t, const std::vector<Node>& s)
      27                 :      96927 :     : d_type(new TypeNode(t)), d_seq(s)
      28                 :            : {
      29                 :      96927 : }
      30                 :            : 
      31                 :      14819 : Sequence::Sequence(const Sequence& seq)
      32                 :      14819 :     : d_type(new TypeNode(seq.getType())), d_seq(seq.getVec())
      33                 :            : {
      34                 :      14819 : }
      35                 :            : 
      36                 :     111679 : Sequence::~Sequence() {}
      37                 :            : 
      38                 :          0 : Sequence& Sequence::operator=(const Sequence& y)
      39                 :            : {
      40         [ -  - ]:          0 :   if (this != &y)
      41                 :            :   {
      42                 :          0 :     d_type.reset(new TypeNode(y.getType()));
      43                 :          0 :     d_seq = y.getVec();
      44                 :            :   }
      45                 :          0 :   return *this;
      46                 :            : }
      47                 :            : 
      48                 :     144350 : int Sequence::cmp(const Sequence& y) const
      49                 :            : {
      50         [ +  + ]:     144350 :   if (getType() != y.getType())
      51                 :            :   {
      52         [ +  + ]:      32964 :     return getType() < y.getType() ? -1 : 1;
      53                 :            :   }
      54         [ -  + ]:     111386 :   if (size() != y.size())
      55                 :            :   {
      56         [ -  - ]:          0 :     return size() < y.size() ? -1 : 1;
      57                 :            :   }
      58         [ +  + ]:     122600 :   for (size_t i = 0, sz = size(); i < sz; ++i)
      59                 :            :   {
      60         [ +  + ]:      11360 :     if (nth(i) != y.nth(i))
      61                 :            :     {
      62         [ +  + ]:        146 :       return nth(i) < y.nth(i) ? -1 : 1;
      63                 :            :     }
      64                 :            :   }
      65                 :     111240 :   return 0;
      66                 :            : }
      67                 :            : 
      68                 :          0 : Sequence Sequence::concat(const Sequence& other) const
      69                 :            : {
      70                 :          0 :   Assert(getType() == other.getType());
      71                 :          0 :   std::vector<Node> ret_vec(d_seq);
      72                 :          0 :   ret_vec.insert(ret_vec.end(), other.d_seq.begin(), other.d_seq.end());
      73                 :          0 :   return Sequence(getType(), ret_vec);
      74                 :          0 : }
      75                 :            : 
      76                 :         64 : bool Sequence::strncmp(const Sequence& y, size_t n) const
      77                 :            : {
      78 [ -  + ][ -  + ]:         64 :   Assert(getType() == y.getType());
                 [ -  - ]
      79         [ +  + ]:         64 :   size_t b = (size() >= y.size()) ? size() : y.size();
      80         [ +  + ]:         64 :   size_t s = (size() <= y.size()) ? size() : y.size();
      81         [ -  + ]:         64 :   if (n > s)
      82                 :            :   {
      83         [ -  - ]:          0 :     if (b != s)
      84                 :            :     {
      85                 :          0 :       return false;
      86                 :            :     }
      87                 :          0 :     n = s;
      88                 :            :   }
      89         [ +  + ]:        104 :   for (size_t i = 0; i < n; ++i)
      90                 :            :   {
      91         [ +  + ]:         71 :     if (nth(i) != y.nth(i))
      92                 :            :     {
      93                 :         31 :       return false;
      94                 :            :     }
      95                 :            :   }
      96                 :         33 :   return true;
      97                 :            : }
      98                 :            : 
      99                 :        147 : bool Sequence::rstrncmp(const Sequence& y, size_t n) const
     100                 :            : {
     101 [ -  + ][ -  + ]:        147 :   Assert(getType() == y.getType());
                 [ -  - ]
     102         [ +  + ]:        147 :   size_t b = (size() >= y.size()) ? size() : y.size();
     103         [ +  + ]:        147 :   size_t s = (size() <= y.size()) ? size() : y.size();
     104         [ -  + ]:        147 :   if (n > s)
     105                 :            :   {
     106         [ -  - ]:          0 :     if (b != s)
     107                 :            :     {
     108                 :          0 :       return false;
     109                 :            :     }
     110                 :          0 :     n = s;
     111                 :            :   }
     112         [ +  + ]:        340 :   for (size_t i = 0; i < n; ++i)
     113                 :            :   {
     114         [ +  + ]:        205 :     if (nth(size() - i - 1) != y.nth(y.size() - i - 1))
     115                 :            :     {
     116                 :         12 :       return false;
     117                 :            :     }
     118                 :            :   }
     119                 :        135 :   return true;
     120                 :            : }
     121                 :            : 
     122                 :       5069 : bool Sequence::empty() const { return d_seq.empty(); }
     123                 :            : 
     124                 :     400210 : size_t Sequence::size() const { return d_seq.size(); }
     125                 :            : 
     126                 :          0 : const Node& Sequence::front() const
     127                 :            : {
     128                 :          0 :   Assert(!d_seq.empty());
     129                 :          0 :   return d_seq.front();
     130                 :            : }
     131                 :            : 
     132                 :          0 : const Node& Sequence::back() const
     133                 :            : {
     134                 :          0 :   Assert(!d_seq.empty());
     135                 :          0 :   return d_seq.back();
     136                 :            : }
     137                 :            : 
     138                 :      24048 : const Node& Sequence::nth(size_t i) const
     139                 :            : {
     140 [ -  + ][ -  + ]:      24048 :   Assert(i < size());
                 [ -  - ]
     141                 :      24048 :   return d_seq[i];
     142                 :            : }
     143                 :            : 
     144                 :        158 : size_t Sequence::overlap(const Sequence& y) const
     145                 :            : {
     146 [ -  + ][ -  + ]:        158 :   Assert(getType() == y.getType());
                 [ -  - ]
     147         [ +  + ]:        158 :   size_t i = size() < y.size() ? size() : y.size();
     148         [ +  + ]:        292 :   for (; i > 0; i--)
     149                 :            :   {
     150                 :        212 :     Sequence s = suffix(i);
     151                 :        212 :     Sequence p = y.prefix(i);
     152         [ +  + ]:        212 :     if (s == p)
     153                 :            :     {
     154                 :         78 :       return i;
     155                 :            :     }
     156 [ +  + ][ +  + ]:        290 :   }
     157                 :         80 :   return i;
     158                 :            : }
     159                 :            : 
     160                 :         22 : size_t Sequence::roverlap(const Sequence& y) const
     161                 :            : {
     162 [ -  + ][ -  + ]:         22 :   Assert(getType() == y.getType());
                 [ -  - ]
     163         [ +  + ]:         22 :   size_t i = size() < y.size() ? size() : y.size();
     164         [ +  + ]:         34 :   for (; i > 0; i--)
     165                 :            :   {
     166                 :         14 :     Sequence s = prefix(i);
     167                 :         14 :     Sequence p = y.suffix(i);
     168         [ +  + ]:         14 :     if (s == p)
     169                 :            :     {
     170                 :          2 :       return i;
     171                 :            :     }
     172 [ +  + ][ +  + ]:         16 :   }
     173                 :         20 :   return i;
     174                 :            : }
     175                 :            : 
     176                 :     382549 : const TypeNode& Sequence::getType() const { return *d_type; }
     177                 :            : 
     178                 :     180457 : const std::vector<Node>& Sequence::getVec() const { return d_seq; }
     179                 :            : 
     180                 :          0 : bool Sequence::isRepeated() const
     181                 :            : {
     182         [ -  - ]:          0 :   if (size() > 1)
     183                 :            :   {
     184                 :          0 :     Node f = nth(0);
     185         [ -  - ]:          0 :     for (unsigned i = 1, sz = size(); i < sz; ++i)
     186                 :            :     {
     187         [ -  - ]:          0 :       if (f != nth(i))
     188                 :            :       {
     189                 :          0 :         return false;
     190                 :            :       }
     191                 :            :     }
     192         [ -  - ]:          0 :   }
     193                 :          0 :   return true;
     194                 :            : }
     195                 :            : 
     196                 :       2310 : size_t Sequence::find(const Sequence& y, size_t start) const
     197                 :            : {
     198 [ -  + ][ -  + ]:       2310 :   Assert(getType() == y.getType());
                 [ -  - ]
     199         [ +  + ]:       2310 :   if (size() < y.size() + start)
     200                 :            :   {
     201                 :         79 :     return std::string::npos;
     202                 :            :   }
     203         [ +  + ]:       2231 :   if (y.empty())
     204                 :            :   {
     205                 :         15 :     return start;
     206                 :            :   }
     207         [ -  + ]:       2216 :   if (empty())
     208                 :            :   {
     209                 :          0 :     return std::string::npos;
     210                 :            :   }
     211                 :       4432 :   std::vector<Node>::const_iterator itr = std::search(
     212                 :       2216 :       d_seq.begin() + start, d_seq.end(), y.d_seq.begin(), y.d_seq.end());
     213         [ +  + ]:       2216 :   if (itr != d_seq.end())
     214                 :            :   {
     215                 :       1892 :     return itr - d_seq.begin();
     216                 :            :   }
     217                 :        324 :   return std::string::npos;
     218                 :            : }
     219                 :            : 
     220                 :        226 : size_t Sequence::rfind(const Sequence& y, size_t start) const
     221                 :            : {
     222 [ -  + ][ -  + ]:        226 :   Assert(getType() == y.getType());
                 [ -  - ]
     223         [ +  + ]:        226 :   if (size() < y.size() + start)
     224                 :            :   {
     225                 :         10 :     return std::string::npos;
     226                 :            :   }
     227         [ -  + ]:        216 :   if (y.empty())
     228                 :            :   {
     229                 :          0 :     return start;
     230                 :            :   }
     231         [ -  + ]:        216 :   if (empty())
     232                 :            :   {
     233                 :          0 :     return std::string::npos;
     234                 :            :   }
     235                 :            :   std::vector<Node>::const_reverse_iterator itr = std::search(
     236                 :        216 :       d_seq.rbegin() + start, d_seq.rend(), y.d_seq.rbegin(), y.d_seq.rend());
     237         [ +  + ]:        216 :   if (itr != d_seq.rend())
     238                 :            :   {
     239                 :        198 :     return itr - d_seq.rbegin();
     240                 :            :   }
     241                 :         18 :   return std::string::npos;
     242                 :            : }
     243                 :            : 
     244                 :          8 : bool Sequence::hasPrefix(const Sequence& y) const
     245                 :            : {
     246 [ -  + ][ -  + ]:          8 :   Assert(getType() == y.getType());
                 [ -  - ]
     247                 :          8 :   size_t s = size();
     248                 :          8 :   size_t ys = y.size();
     249         [ -  + ]:          8 :   if (ys > s)
     250                 :            :   {
     251                 :          0 :     return false;
     252                 :            :   }
     253         [ +  + ]:         16 :   for (size_t i = 0; i < ys; i++)
     254                 :            :   {
     255         [ -  + ]:          8 :     if (nth(i) != y.nth(i))
     256                 :            :     {
     257                 :          0 :       return false;
     258                 :            :     }
     259                 :            :   }
     260                 :          8 :   return true;
     261                 :            : }
     262                 :            : 
     263                 :        234 : bool Sequence::hasSuffix(const Sequence& y) const
     264                 :            : {
     265 [ -  + ][ -  + ]:        234 :   Assert(getType() == y.getType());
                 [ -  - ]
     266                 :        234 :   size_t s = size();
     267                 :        234 :   size_t ys = y.size();
     268         [ -  + ]:        234 :   if (ys > s)
     269                 :            :   {
     270                 :          0 :     return false;
     271                 :            :   }
     272                 :        234 :   size_t idiff = s - ys;
     273         [ +  + ]:        468 :   for (size_t i = 0; i < ys; i++)
     274                 :            :   {
     275         [ -  + ]:        234 :     if (nth(i + idiff) != y.nth(i))
     276                 :            :     {
     277                 :          0 :       return false;
     278                 :            :     }
     279                 :            :   }
     280                 :        234 :   return true;
     281                 :            : }
     282                 :            : 
     283                 :         42 : Sequence Sequence::update(size_t i, const Sequence& t) const
     284                 :            : {
     285 [ -  + ][ -  + ]:         42 :   Assert(getType() == t.getType());
                 [ -  - ]
     286         [ +  - ]:         42 :   if (i < size())
     287                 :            :   {
     288                 :         42 :     std::vector<Node> vec(d_seq.begin(), d_seq.begin() + i);
     289                 :         42 :     size_t remNum = size() - i;
     290                 :         42 :     size_t tnum = t.d_seq.size();
     291         [ +  + ]:         42 :     if (tnum >= remNum)
     292                 :            :     {
     293                 :         24 :       vec.insert(vec.end(), t.d_seq.begin(), t.d_seq.begin() + remNum);
     294                 :            :     }
     295                 :            :     else
     296                 :            :     {
     297                 :         18 :       vec.insert(vec.end(), t.d_seq.begin(), t.d_seq.end());
     298                 :         18 :       vec.insert(vec.end(), d_seq.begin() + i + tnum, d_seq.end());
     299                 :            :     }
     300                 :         42 :     return Sequence(getType(), vec);
     301                 :         42 :   }
     302                 :          0 :   return *this;
     303                 :            : }
     304                 :            : 
     305                 :          0 : Sequence Sequence::replace(const Sequence& s, const Sequence& t) const
     306                 :            : {
     307                 :          0 :   Assert(getType() == s.getType());
     308                 :          0 :   Assert(getType() == t.getType());
     309                 :          0 :   size_t ret = find(s);
     310         [ -  - ]:          0 :   if (ret != std::string::npos)
     311                 :            :   {
     312                 :          0 :     std::vector<Node> vec;
     313                 :          0 :     vec.insert(vec.begin(), d_seq.begin(), d_seq.begin() + ret);
     314                 :          0 :     vec.insert(vec.end(), t.d_seq.begin(), t.d_seq.end());
     315                 :          0 :     vec.insert(vec.end(), d_seq.begin() + ret + s.size(), d_seq.end());
     316                 :          0 :     return Sequence(getType(), vec);
     317                 :          0 :   }
     318                 :          0 :   return *this;
     319                 :            : }
     320                 :            : 
     321                 :         70 : Sequence Sequence::substr(size_t i) const
     322                 :            : {
     323 [ -  + ][ -  + ]:         70 :   Assert(i <= size());
                 [ -  - ]
     324                 :         70 :   std::vector<Node> retVec(d_seq.begin() + i, d_seq.end());
     325                 :        140 :   return Sequence(getType(), retVec);
     326                 :         70 : }
     327                 :            : 
     328                 :        906 : Sequence Sequence::substr(size_t i, size_t j) const
     329                 :            : {
     330 [ -  + ][ -  + ]:        906 :   Assert(i + j <= size());
                 [ -  - ]
     331                 :        906 :   std::vector<Node>::const_iterator itr = d_seq.begin() + i;
     332                 :        906 :   std::vector<Node> retVec(itr, itr + j);
     333                 :       1812 :   return Sequence(getType(), retVec);
     334                 :        906 : }
     335                 :            : 
     336                 :          0 : size_t Sequence::maxSize() { return std::numeric_limits<uint32_t>::max(); }
     337                 :            : 
     338                 :          0 : std::ostream& operator<<(std::ostream& os, const Sequence& s)
     339                 :            : {
     340                 :          0 :   const std::vector<Node>& vec = s.getVec();
     341                 :          0 :   std::stringstream ss;
     342         [ -  - ]:          0 :   if (vec.empty())
     343                 :            :   {
     344                 :          0 :     ss << "(as seq.empty " << s.getType() << ")";
     345                 :            :   }
     346                 :            :   else
     347                 :            :   {
     348                 :          0 :     ss << "(seq.++";
     349         [ -  - ]:          0 :     for (const Node& n : vec)
     350                 :            :     {
     351                 :          0 :       ss << " " << n;
     352                 :            :     }
     353                 :          0 :     ss << ")";
     354                 :            :   }
     355                 :          0 :   return os << ss.str();
     356                 :          0 : }
     357                 :            : 
     358                 :     155617 : size_t SequenceHashFunction::operator()(const Sequence& s) const
     359                 :            : {
     360                 :     155617 :   uint64_t ret = fnv1a::offsetBasis;
     361                 :     155617 :   const std::vector<Node>& vec = s.getVec();
     362         [ +  + ]:     173504 :   for (const Node& n : vec)
     363                 :            :   {
     364                 :      17887 :     ret = fnv1a::fnv1a_64(ret, std::hash<Node>()(n));
     365                 :            :   }
     366                 :     155617 :   return static_cast<size_t>(ret);
     367                 :            : }
     368                 :            : 
     369                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14