LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/quantifiers - ho_term_database.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 93 99 93.9 %
Date: 2026-02-25 11:44:22 Functions: 9 9 100.0 %
Branches: 41 52 78.8 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * Top contributors (to current version):
       3                 :            :  *   Andrew Reynolds, Aina Niemetz, Daniel Larraz
       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 higher-order term database class.
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "theory/quantifiers/ho_term_database.h"
      17                 :            : 
      18                 :            : #include "expr/skolem_manager.h"
      19                 :            : #include "options/quantifiers_options.h"
      20                 :            : #include "theory/quantifiers/quantifiers_inference_manager.h"
      21                 :            : #include "theory/quantifiers/quantifiers_state.h"
      22                 :            : #include "theory/rewriter.h"
      23                 :            : #include "theory/uf/equality_engine.h"
      24                 :            : 
      25                 :            : using namespace cvc5::internal::kind;
      26                 :            : 
      27                 :            : namespace cvc5::internal {
      28                 :            : namespace theory {
      29                 :            : namespace quantifiers {
      30                 :            : 
      31                 :       1201 : HoTermDb::HoTermDb(Env& env, QuantifiersState& qs, QuantifiersRegistry& qr)
      32                 :       1201 :     : TermDb(env, qs, qr), d_hoFunOpPurify(userContext())
      33                 :            : {
      34                 :       1201 : }
      35                 :            : 
      36                 :       2398 : HoTermDb::~HoTermDb() {}
      37                 :            : 
      38                 :      90888 : void HoTermDb::addTermInternal(Node n)
      39                 :            : {
      40         [ +  + ]:      90888 :   if (n.getType().isFunction())
      41                 :            :   {
      42                 :            :     // nothing special to do with functions
      43                 :        976 :     return;
      44                 :            :   }
      45                 :      89912 :   NodeManager* nm = n.getNodeManager();
      46                 :      89912 :   Node curr = n;
      47                 :      89912 :   std::vector<Node> args;
      48         [ +  + ]:     128923 :   while (curr.getKind() == Kind::HO_APPLY)
      49                 :            :   {
      50                 :      39011 :     args.insert(args.begin(), curr[1]);
      51                 :      39011 :     curr = curr[0];
      52         [ +  + ]:      39011 :     if (!curr.isVar())
      53                 :            :     {
      54                 :            :       // purify the term
      55                 :       6729 :       context::CDHashSet<Node>::const_iterator itp = d_hoFunOpPurify.find(curr);
      56         [ +  + ]:       6729 :       if (itp != d_hoFunOpPurify.end())
      57                 :            :       {
      58                 :       6201 :         continue;
      59                 :            :       }
      60                 :        528 :       d_hoFunOpPurify.insert(curr);
      61                 :        528 :       Node psk = SkolemManager::mkPurifySkolem(curr);
      62                 :            :       // we do not add it to d_ops since it is an internal operator
      63                 :        528 :       Node eq = psk.eqNode(curr);
      64                 :        528 :       std::vector<Node> children;
      65                 :        528 :       children.push_back(psk);
      66                 :        528 :       children.insert(children.end(), args.begin(), args.end());
      67                 :        528 :       Node p_n = nm->mkNode(Kind::APPLY_UF, children);
      68                 :        528 :       Node eqa = p_n.eqNode(n);
      69                 :       1056 :       Node lem = nm->mkNode(Kind::AND, eq, eqa);
      70                 :        528 :       d_qim->addPendingLemma(lem, InferenceId::QUANTIFIERS_HO_PURIFY);
      71                 :        528 :     }
      72                 :            :   }
      73 [ +  + ][ +  - ]:      89912 :   if (!args.empty() && curr.isVar())
                 [ +  + ]
      74                 :            :   {
      75                 :            :     // also add standard application version
      76                 :      32282 :     args.insert(args.begin(), curr);
      77                 :      32282 :     Node uf_n = nm->mkNode(Kind::APPLY_UF, args);
      78                 :      32282 :     addTerm(uf_n);
      79                 :      32282 :   }
      80                 :      89912 : }
      81                 :            : 
      82                 :      11117 : void HoTermDb::getOperatorsFor(TNode f, std::vector<TNode>& ops)
      83                 :            : {
      84                 :      11117 :   ops.push_back(f);
      85                 :      11117 :   ops.insert(ops.end(), d_hoOpSlaves[f].begin(), d_hoOpSlaves[f].end());
      86                 :      11117 : }
      87                 :            : 
      88                 :    1173533 : Node HoTermDb::getOperatorRepresentative(TNode op) const
      89                 :            : {
      90                 :    1173533 :   std::map<TNode, TNode>::const_iterator it = d_hoOpRep.find(op);
      91         [ +  + ]:    1173533 :   if (it != d_hoOpRep.end())
      92                 :            :   {
      93                 :    1080793 :     return it->second;
      94                 :            :   }
      95                 :      92740 :   return op;
      96                 :            : }
      97                 :       3950 : bool HoTermDb::finishResetInternal(CVC5_UNUSED Theory::Effort effort)
      98                 :            : {
      99         [ -  + ]:       3950 :   if (!options().quantifiers.hoMergeTermDb)
     100                 :            :   {
     101                 :          0 :     return true;
     102                 :            :   }
     103         [ +  - ]:       7900 :   Trace("quant-ho") << "HoTermDb::reset : compute equal functions..."
     104                 :       3950 :                     << std::endl;
     105                 :            :   // build operator representative map
     106                 :       3950 :   d_hoOpRep.clear();
     107                 :       3950 :   d_hoOpSlaves.clear();
     108                 :       3950 :   eq::EqualityEngine* ee = d_qstate.getEqualityEngine();
     109                 :       3950 :   eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(ee);
     110         [ +  + ]:     163824 :   while (!eqcs_i.isFinished())
     111                 :            :   {
     112                 :     159874 :     TNode r = (*eqcs_i);
     113         [ +  + ]:     159874 :     if (r.getType().isFunction())
     114                 :            :     {
     115         [ +  - ]:      20306 :       Trace("quant-ho") << "  process function eqc " << r << std::endl;
     116                 :      20306 :       Node first;
     117                 :      20306 :       eq::EqClassIterator eqc_i = eq::EqClassIterator(r, ee);
     118         [ +  + ]:      45521 :       while (!eqc_i.isFinished())
     119                 :            :       {
     120                 :      25215 :         TNode n = (*eqc_i);
     121                 :      25215 :         Node n_use;
     122         [ +  + ]:      25215 :         if (n.isVar())
     123                 :            :         {
     124                 :      23228 :           n_use = n;
     125                 :            :         }
     126         [ +  - ]:      50430 :         Trace("quant-ho") << "  - process " << n_use << ", from " << n
     127                 :      25215 :                           << std::endl;
     128 [ +  + ][ +  + ]:      25215 :         if (!n_use.isNull() && d_opMap.find(n_use) != d_opMap.end())
                 [ +  + ]
     129                 :            :         {
     130         [ +  + ]:      15936 :           if (first.isNull())
     131                 :            :           {
     132                 :      13087 :             first = n_use;
     133                 :      13087 :             d_hoOpRep[n_use] = n_use;
     134                 :            :           }
     135                 :            :           else
     136                 :            :           {
     137         [ +  - ]:       5698 :             Trace("quant-ho") << "  have : " << n_use << " == " << first
     138 [ -  + ][ -  - ]:       2849 :                               << ", type = " << n_use.getType() << std::endl;
     139                 :       2849 :             d_hoOpRep[n_use] = first;
     140                 :       2849 :             d_hoOpSlaves[first].push_back(n_use);
     141                 :            :           }
     142                 :            :         }
     143                 :      25215 :         ++eqc_i;
     144                 :      25215 :       }
     145                 :      20306 :     }
     146                 :     159874 :     ++eqcs_i;
     147                 :     159874 :   }
     148         [ +  - ]:       3950 :   Trace("quant-ho") << "...finished compute equal functions." << std::endl;
     149                 :            : 
     150                 :       3950 :   return true;
     151                 :            : }
     152                 :      41399 : bool HoTermDb::checkCongruentDisequal(TNode a, TNode b, std::vector<Node>& exp)
     153                 :            : {
     154         [ +  + ]:      41399 :   if (!d_qstate.areDisequal(a, b))
     155                 :            :   {
     156                 :      41392 :     return false;
     157                 :            :   }
     158                 :            :   // operators might be disequal
     159                 :          7 :   Node af = getMatchOperator(a);
     160                 :          7 :   Node bf = getMatchOperator(b);
     161         [ -  + ]:          7 :   if (af != bf)
     162                 :            :   {
     163                 :          0 :     if (a.getKind() == Kind::APPLY_UF && b.getKind() == Kind::APPLY_UF)
     164                 :            :     {
     165                 :          0 :       exp.push_back(af.eqNode(bf));
     166                 :          0 :       Assert(d_qstate.areEqual(af, bf))
     167                 :          0 :           << af << " and " << bf << " are not equal";
     168                 :            :     }
     169                 :            :     else
     170                 :            :     {
     171                 :          0 :       DebugUnhandled();
     172                 :            :       return false;
     173                 :            :     }
     174                 :            :   }
     175                 :          7 :   return true;
     176                 :          7 : }
     177                 :            : 
     178                 :       2758 : Node HoTermDb::getHoTypeMatchPredicate(TypeNode tn)
     179                 :            : {
     180                 :       2758 :   NodeManager* nm = tn.getNodeManager();
     181                 :       2758 :   SkolemManager* sm = nm->getSkolemManager();
     182                 :       2758 :   TypeNode ptn = nm->mkFunctionType(tn, nm->booleanType());
     183                 :            :   return sm->mkInternalSkolemFunction(InternalSkolemId::HO_TYPE_MATCH_PRED,
     184                 :       5516 :                                       ptn);
     185                 :       2758 : }
     186                 :            : 
     187                 :            : }  // namespace quantifiers
     188                 :            : }  // namespace theory
     189                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14