LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/prop - skolem_def_manager.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 95 95 100.0 %
Date: 2026-04-20 10:41:59 Functions: 7 7 100.0 %
Branches: 64 82 78.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                 :            :  * Skolem definition manager.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "prop/skolem_def_manager.h"
      14                 :            : 
      15                 :            : namespace cvc5::internal {
      16                 :            : namespace prop {
      17                 :            : 
      18                 :      51624 : SkolemDefManager::SkolemDefManager(context::Context* context,
      19                 :      51624 :                                    context::UserContext* userContext)
      20                 :      51624 :     : d_skDefs(userContext), d_skActive(context), d_hasSkolems(userContext)
      21                 :            : {
      22                 :      51624 : }
      23                 :            : 
      24                 :      51279 : SkolemDefManager::~SkolemDefManager() {}
      25                 :            : 
      26                 :      61928 : void SkolemDefManager::notifySkolemDefinition(TNode skolem, Node def)
      27                 :            : {
      28                 :            :   // Notice that skolem should have kind SKOLEM
      29         [ +  - ]:     123856 :   Trace("sk-defs") << "notifySkolemDefinition: " << def << " for " << skolem
      30                 :      61928 :                    << std::endl;
      31                 :            :   // in very rare cases, a skolem may be generated twice for terms that are
      32                 :            :   // equivalent up to purification
      33         [ +  + ]:      61928 :   if (d_skDefs.find(skolem) == d_skDefs.end())
      34                 :            :   {
      35                 :            :     // should not have already computed whether the skolem has skolems or
      36                 :            :     // otherwise we should have marked that we have skolems, or else
      37                 :            :     // our computation of hasSkolems is wrong after adding this definition
      38                 :      58253 :     Assert(d_hasSkolems.find(skolem) == d_hasSkolems.end()
      39                 :            :            || d_hasSkolems[skolem]);
      40                 :      58253 :     d_skDefs.insert(skolem, def);
      41                 :            :   }
      42                 :      61928 : }
      43                 :            : 
      44                 :       4390 : TNode SkolemDefManager::getDefinitionForSkolem(TNode skolem) const
      45                 :            : {
      46                 :       4390 :   NodeNodeMap::const_iterator it = d_skDefs.find(skolem);
      47                 :       4390 :   Assert(it != d_skDefs.end()) << "No skolem def for " << skolem;
      48                 :       8780 :   return it->second;
      49                 :            : }
      50                 :            : 
      51                 :   13018384 : void SkolemDefManager::notifyAsserted(TNode literal,
      52                 :            :                                       std::vector<TNode>& activatedSkolems)
      53                 :            : {
      54         [ +  + ]:   13018384 :   if (d_skActive.size() == d_skDefs.size())
      55                 :            :   {
      56                 :            :     // already activated all skolems
      57                 :    7807707 :     return;
      58                 :            :   }
      59                 :    5210677 :   std::unordered_set<Node> defs;
      60                 :    5210677 :   getSkolems(literal, defs, true);
      61         [ +  - ]:   10421354 :   Trace("sk-defs") << "notifyAsserted: " << literal << " has skolems " << defs
      62                 :    5210677 :                    << std::endl;
      63         [ +  + ]:   12374890 :   for (const Node& d : defs)
      64                 :            :   {
      65         [ +  + ]:    7164213 :     if (d_skActive.find(d) != d_skActive.end())
      66                 :            :     {
      67                 :            :       // already active
      68                 :    6347028 :       continue;
      69                 :            :     }
      70                 :     817185 :     d_skActive.insert(d);
      71         [ +  - ]:     817185 :     Trace("sk-defs") << "...activate " << d << std::endl;
      72                 :            :     // add its definition to the activated list
      73                 :     817185 :     activatedSkolems.push_back(d);
      74                 :            :   }
      75                 :    5210677 : }
      76                 :            : 
      77                 :   34016241 : bool SkolemDefManager::hasSkolems(TNode n)
      78                 :            : {
      79         [ +  - ]:   34016241 :   Trace("sk-defs-debug") << "Compute has skolems for " << n << std::endl;
      80                 :   34016241 :   std::unordered_set<TNode> visited;
      81                 :   34016241 :   std::unordered_set<TNode>::iterator it;
      82                 :   34016241 :   NodeBoolMap::const_iterator itn;
      83                 :   34016241 :   std::vector<TNode> visit;
      84                 :   34016241 :   TNode cur;
      85                 :   34016241 :   visit.push_back(n);
      86                 :            :   do
      87                 :            :   {
      88                 :   35402587 :     cur = visit.back();
      89                 :   35402587 :     itn = d_hasSkolems.find(cur);
      90         [ +  + ]:   35402587 :     if (itn != d_hasSkolems.end())
      91                 :            :     {
      92                 :   34347706 :       visit.pop_back();
      93                 :            :       // already computed
      94                 :   34347706 :       continue;
      95                 :            :     }
      96                 :    1054881 :     it = visited.find(cur);
      97         [ +  + ]:    1054881 :     if (it == visited.end())
      98                 :            :     {
      99                 :     585298 :       visited.insert(cur);
     100         [ +  + ]:     585298 :       if (cur.getNumChildren() == 0)
     101                 :            :       {
     102                 :     115715 :         visit.pop_back();
     103                 :     115715 :         Kind ck = cur.getKind();
     104                 :            :         // We have skolems if we are a skolem that has a definition, or
     105                 :            :         // we are a Boolean term variable. For Boolean term variables, we do
     106                 :            :         // not make this test depend on whether the skolem has a definition,
     107                 :            :         // since that is prone to change if the Boolean term variable was
     108                 :            :         // introduced in a lemma prior to its definition being introduced.
     109                 :            :         // This is for example the case in strings reduction for Booleans,
     110                 :            :         // ground term purification for E-matching, etc.
     111                 :     231430 :         d_hasSkolems[cur] = (ck == Kind::SKOLEM
     112 [ +  + ][ +  + ]:     242156 :                              && (d_skDefs.find(cur) != d_skDefs.end()
                 [ -  - ]
     113 [ +  + ][ +  + ]:     242156 :                                  || cur.getType().isBoolean()));
         [ +  + ][ -  - ]
     114                 :            :       }
     115                 :            :       else
     116                 :            :       {
     117         [ +  + ]:     469583 :         if (cur.getMetaKind() == kind::metakind::PARAMETERIZED)
     118                 :            :         {
     119                 :      80914 :           visit.push_back(cur.getOperator());
     120                 :            :         }
     121                 :     469583 :         visit.insert(visit.end(), cur.begin(), cur.end());
     122                 :            :       }
     123                 :            :     }
     124                 :            :     else
     125                 :            :     {
     126                 :     469583 :       visit.pop_back();
     127                 :            :       bool hasSkolem;
     128                 :    1408749 :       if (cur.getMetaKind() == kind::metakind::PARAMETERIZED
     129 [ +  + ][ +  + ]:     469583 :           && d_hasSkolems[cur.getOperator()])
         [ +  + ][ +  + ]
                 [ -  - ]
     130                 :            :       {
     131                 :        151 :         hasSkolem = true;
     132                 :            :       }
     133                 :            :       else
     134                 :            :       {
     135                 :     469432 :         hasSkolem = false;
     136         [ +  + ]:    1076214 :         for (TNode i : cur)
     137                 :            :         {
     138 [ -  + ][ -  + ]:     766914 :           Assert(d_hasSkolems.find(i) != d_hasSkolems.end());
                 [ -  - ]
     139         [ +  + ]:     766914 :           if (d_hasSkolems[i])
     140                 :            :           {
     141                 :     160132 :             hasSkolem = true;
     142                 :     160132 :             break;
     143                 :            :           }
     144         [ +  + ]:     766914 :         }
     145                 :            :       }
     146                 :     469583 :       d_hasSkolems[cur] = hasSkolem;
     147                 :            :     }
     148         [ +  + ]:   35402587 :   } while (!visit.empty());
     149 [ -  + ][ -  + ]:   34016241 :   Assert(d_hasSkolems.find(n) != d_hasSkolems.end());
                 [ -  - ]
     150                 :   68032482 :   return d_hasSkolems[n];
     151                 :   34016241 : }
     152                 :            : 
     153                 :    5217232 : void SkolemDefManager::getSkolems(TNode n,
     154                 :            :                                   std::unordered_set<Node>& skolems,
     155                 :            :                                   bool useDefs)
     156                 :            : {
     157                 :    5217232 :   NodeNodeMap::const_iterator itd;
     158                 :    5217232 :   std::unordered_set<TNode> visited;
     159                 :    5217232 :   std::unordered_set<TNode>::iterator it;
     160                 :    5217232 :   std::vector<TNode> visit;
     161                 :    5217232 :   TNode cur;
     162                 :    5217232 :   visit.push_back(n);
     163                 :            :   do
     164                 :            :   {
     165                 :   34016241 :     cur = visit.back();
     166                 :   34016241 :     visit.pop_back();
     167         [ +  + ]:   34016241 :     if (!hasSkolems(cur))
     168                 :            :     {
     169                 :            :       // does not have skolems, continue
     170                 :   10033072 :       continue;
     171                 :            :     }
     172                 :   23983169 :     it = visited.find(cur);
     173         [ +  + ]:   23983169 :     if (it == visited.end())
     174                 :            :     {
     175                 :   22619982 :       visited.insert(cur);
     176         [ +  + ]:   22619982 :       if (cur.isVar())
     177                 :            :       {
     178                 :    7168636 :         itd = d_skDefs.find(cur);
     179         [ +  + ]:    7168636 :         if (itd != d_skDefs.end())
     180                 :            :         {
     181         [ +  + ]:    7168603 :           skolems.insert(useDefs ? itd->second : Node(cur));
     182                 :            :         }
     183                 :    7168636 :         continue;
     184                 :            :       }
     185         [ +  + ]:   15451346 :       if (cur.getMetaKind() == kind::metakind::PARAMETERIZED)
     186                 :            :       {
     187                 :    2465004 :         visit.push_back(cur.getOperator());
     188                 :            :       }
     189                 :   15451346 :       visit.insert(visit.end(), cur.begin(), cur.end());
     190                 :            :     }
     191         [ +  + ]:   34016241 :   } while (!visit.empty());
     192                 :    5217232 : }
     193                 :            : 
     194                 :            : }  // namespace prop
     195                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14