LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/expr - sequence.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 126 187 67.4 %
Date: 2024-10-12 11:38:19 Functions: 22 30 73.3 %
Branches: 97 184 52.7 %

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

Generated by: LCOV version 1.14