LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/sets - infer_proof_cons.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 197 212 92.9 %
Date: 2026-03-06 12:12:49 Functions: 7 7 100.0 %
Branches: 153 296 51.7 %

           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                 :            :  * Inference to proof conversion for sets.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/sets/infer_proof_cons.h"
      14                 :            : 
      15                 :            : #include "expr/skolem_manager.h"
      16                 :            : #include "proof/proof_node_algorithm.h"
      17                 :            : #include "proof/proof_node_manager.h"
      18                 :            : #include "proof/theory_proof_step_buffer.h"
      19                 :            : #include "theory/builtin/proof_checker.h"
      20                 :            : #include "theory/sets/theory_sets_rewriter.h"
      21                 :            : 
      22                 :            : namespace cvc5::internal {
      23                 :            : namespace theory {
      24                 :            : namespace sets {
      25                 :            : 
      26                 :      10177 : InferProofCons::InferProofCons(Env& env, TheorySetsRewriter* tsr)
      27                 :            :     : EnvObj(env),
      28                 :      10177 :       d_tsr(tsr),
      29                 :      10177 :       d_uimap(userContext()),
      30                 :      10177 :       d_fmap(context()),
      31                 :      20354 :       d_expMap(context())
      32                 :            : {
      33                 :      10177 :   d_false = nodeManager()->mkConst(false);
      34                 :      10177 : }
      35                 :            : 
      36                 :       3646 : void InferProofCons::notifyFact(const Node& conc,
      37                 :            :                                 const Node& exp,
      38                 :            :                                 InferenceId id)
      39                 :            : {
      40 [ +  - ][ +  - ]:       3646 :   Assert(conc.getKind() != Kind::AND && conc.getKind() != Kind::IMPLIES);
         [ -  + ][ -  + ]
                 [ -  - ]
      41         [ +  + ]:       3646 :   if (d_fmap.find(conc) != d_fmap.end())
      42                 :            :   {
      43                 :            :     // already exists, redundant
      44                 :        367 :     return;
      45                 :            :   }
      46                 :       3279 :   d_fmap[conc] = id;
      47                 :       3279 :   d_expMap[conc] = exp;
      48                 :            : }
      49                 :            : 
      50                 :        309 : void InferProofCons::notifyConflict(const Node& conf, InferenceId id)
      51                 :            : {
      52         [ +  - ]:        618 :   Trace("sets-ipc-debug") << "SetsIpc::conflict " << conf << " " << id
      53                 :        309 :                           << std::endl;
      54                 :        309 :   d_uimap[conf.notNode()] = id;
      55                 :        309 : }
      56                 :            : 
      57                 :      23003 : void InferProofCons::notifyLemma(const Node& lem, InferenceId id)
      58                 :            : {
      59         [ +  - ]:      23003 :   Trace("sets-ipc-debug") << "SetsIpc::lemma " << lem << " " << id << std::endl;
      60                 :      23003 :   d_uimap[lem] = id;
      61                 :      23003 : }
      62                 :            : 
      63                 :       1952 : std::shared_ptr<ProofNode> InferProofCons::getProofFor(Node fact)
      64                 :            : {
      65                 :       1952 :   NodeInferenceMap::iterator it = d_uimap.find(fact);
      66         [ +  + ]:       1952 :   if (it == d_uimap.end())
      67                 :            :   {
      68                 :            :     // should be a fact
      69                 :        179 :     it = d_fmap.find(fact);
      70 [ -  + ][ -  + ]:        179 :     Assert(it != d_fmap.end());
                 [ -  - ]
      71                 :            :   }
      72                 :       1952 :   InferenceId id = it->second;
      73                 :            : 
      74                 :            :   // temporary proof
      75                 :       3904 :   CDProof cdp(d_env);
      76                 :       1952 :   std::vector<Node> assumps;
      77                 :       1952 :   Node conc = fact;
      78                 :            :   // First split into conclusion and assumptions.
      79 [ +  + ][ +  + ]:       1952 :   if (fact.getKind() == Kind::IMPLIES || fact.getKind() == Kind::NOT)
                 [ +  + ]
      80                 :            :   {
      81         [ +  + ]:       1209 :     if (fact[0].getKind() == Kind::AND)
      82                 :            :     {
      83                 :        753 :       assumps.insert(assumps.begin(), fact[0].begin(), fact[0].end());
      84                 :            :     }
      85                 :            :     else
      86                 :            :     {
      87                 :        456 :       assumps.push_back(fact[0]);
      88                 :            :     }
      89         [ +  + ]:       1209 :     if (fact.getKind() == Kind::IMPLIES)
      90                 :            :     {
      91                 :       1072 :       conc = fact[1];
      92                 :            :     }
      93                 :            :     else
      94                 :            :     {
      95                 :        137 :       conc = d_false;
      96                 :            :     }
      97                 :       2418 :     cdp.addStep(fact, ProofRule::SCOPE, {conc}, {assumps});
      98                 :            :   }
      99                 :            :   else
     100                 :            :   {
     101                 :            :     // should be a fact
     102                 :        743 :     NodeExpMap::iterator itex = d_expMap.find(fact);
     103         [ +  + ]:        743 :     if (itex != d_expMap.end())
     104                 :            :     {
     105                 :        179 :       Node exp = itex->second;
     106         [ +  + ]:        179 :       if (exp.getKind() == Kind::AND)
     107                 :            :       {
     108                 :        147 :         assumps.insert(assumps.end(), exp.begin(), exp.end());
     109                 :            :       }
     110                 :            :       else
     111                 :            :       {
     112                 :         32 :         assumps.push_back(exp);
     113                 :            :       }
     114                 :        179 :     }
     115                 :            :   }
     116                 :            :   // Try to convert.
     117         [ +  + ]:       1952 :   if (!convert(cdp, id, assumps, conc))
     118                 :            :   {
     119                 :        867 :     cdp.addTrustedStep(conc, TrustId::THEORY_INFERENCE_SETS, assumps, {});
     120                 :            :   }
     121                 :       3904 :   return cdp.getProofFor(fact);
     122                 :       1952 : }
     123                 :            : 
     124                 :       1952 : bool InferProofCons::convert(CDProof& cdp,
     125                 :            :                              InferenceId id,
     126                 :            :                              const std::vector<Node>& assumps,
     127                 :            :                              const Node& conc)
     128                 :            : {
     129                 :            :   // these are handled manually
     130 [ +  - ][ +  - ]:       1952 :   Assert(id != InferenceId::SETS_PROXY
         [ -  + ][ -  + ]
                 [ -  - ]
     131                 :            :          && id != InferenceId::SETS_PROXY_SINGLETON);
     132         [ +  - ]:       1952 :   Trace("sets-ipc") << "InferProofCons::convert " << id << std::endl;
     133         [ +  - ]:       1952 :   Trace("sets-ipc") << "- assumptions: " << assumps << std::endl;
     134         [ +  - ]:       1952 :   Trace("sets-ipc") << "- conclusion:  " << conc << std::endl;
     135                 :       1952 :   bool success = false;
     136                 :       1952 :   TheoryProofStepBuffer psb(cdp.getManager()->getChecker(), true);
     137 [ +  + ][ +  + ]:       1952 :   switch (id)
         [ +  + ][ +  + ]
     138                 :            :   {
     139                 :        364 :     case InferenceId::SETS_DOWN_CLOSURE:
     140                 :            :     case InferenceId::SETS_MEM_EQ:
     141                 :            :     case InferenceId::SETS_MEM_EQ_CONFLICT:
     142                 :            :     {
     143 [ -  + ][ -  + ]:        364 :       Assert(assumps.size() >= 1);
                 [ -  - ]
     144 [ -  + ][ -  + ]:        364 :       Assert(assumps[0].getKind() == Kind::SET_MEMBER);
                 [ -  - ]
     145 [ +  - ][ +  - ]:        364 :       Assert(assumps.size() == 1 || assumps[1].getKind() == Kind::EQUAL);
         [ -  + ][ -  + ]
                 [ -  - ]
     146                 :            :       // (and (set.member x S) (= S (op T1 T2))) =>
     147                 :            :       // rewrite((set.member x (op T1 T2)))
     148                 :            :       // this holds by applying the equality as a substitution to the first
     149                 :            :       // assumption and rewriting.
     150                 :        364 :       std::vector<Node> exp(assumps.begin() + 1, assumps.end());
     151                 :        364 :       Node aelim = psb.applyPredElim(assumps[0], exp);
     152                 :        364 :       success = true;
     153         [ +  + ]:        364 :       if (!CDProof::isSame(aelim, conc))
     154                 :            :       {
     155                 :         11 :         success = psb.applyPredTransform(aelim, conc, {});
     156                 :            :       }
     157                 :            :       // should never fail
     158 [ -  + ][ -  + ]:        364 :       Assert(success);
                 [ -  - ]
     159                 :        364 :     }
     160                 :        364 :     break;
     161                 :        386 :     case InferenceId::SETS_UP_CLOSURE:
     162                 :            :     case InferenceId::SETS_UP_CLOSURE_2:
     163                 :            :     {
     164                 :        386 :       NodeManager* nm = nodeManager();
     165                 :            :       // An example inference is:
     166                 :            :       // (set.member x A) ^ (set.member y B) ^ (= x y) => (set.member x k)
     167                 :            :       // where k is the purification skolem for (set.inter A B).
     168 [ -  + ][ -  + ]:        386 :       Assert(conc.getKind() == Kind::SET_MEMBER);
                 [ -  - ]
     169                 :        386 :       Node so = SkolemManager::getUnpurifiedForm(conc[1]);
     170         [ +  - ]:        386 :       Trace("sets-ipc") << "Unpurified form " << so << std::endl;
     171                 :            :       // We first compute the single step rewriting of the conclusion.
     172                 :            :       // For the above example, memor would be:
     173                 :            :       // (and (set.member x A) (set.member x B)).
     174                 :        772 :       Node memo = nm->mkNode(Kind::SET_MEMBER, conc[0], so);
     175                 :        386 :       Node memor = d_tsr->rewriteMembershipBinaryOp(memo);
     176         [ +  - ]:        772 :       Trace("sets-ipc") << "Single step rewriting of membership " << memor
     177                 :        386 :                         << std::endl;
     178 [ -  + ][ -  + ]:        386 :       Assert(memo != memor);
                 [ -  - ]
     179                 :            :       // collect the memberships in the premise
     180                 :        386 :       std::vector<Node> assumpMem;
     181                 :        386 :       std::vector<Node> assumpOther;
     182                 :            :       // We now partition the antecedant to the membership
     183                 :            :       // part (assumpMem) and the substitution part (assumpOther). The
     184                 :            :       // membership part will be equivalent via rewriting to the conclusion.
     185         [ +  + ]:       1225 :       for (const Node& a : assumps)
     186                 :            :       {
     187         [ +  + ]:        839 :         Node aa = a.getKind() == Kind::NOT ? a[0] : a;
     188         [ +  + ]:        839 :         if (aa.getKind() == Kind::SET_MEMBER)
     189                 :            :         {
     190                 :        599 :           assumpMem.push_back(a);
     191                 :            :         }
     192                 :            :         else
     193                 :            :         {
     194                 :        240 :           assumpOther.push_back(a);
     195                 :            :         }
     196                 :        839 :       }
     197 [ +  + ][ +  - ]:        386 :       Assert(assumpMem.size() == 1 || assumpMem.size() == 2);
         [ -  + ][ -  + ]
                 [ -  - ]
     198                 :        386 :       Node msrc;
     199                 :            :       // Use AND_INTRO to put the memberships together if necessary.
     200         [ +  + ]:        386 :       if (assumpMem.size() == 2)
     201                 :            :       {
     202                 :        213 :         msrc = nm->mkAnd(assumpMem);
     203                 :        213 :         psb.addStep(ProofRule::AND_INTRO, {assumpMem}, {}, msrc);
     204                 :            :       }
     205                 :            :       else
     206                 :            :       {
     207                 :        173 :         msrc = assumpMem[0];
     208                 :            :       }
     209                 :            :       // Now, prove the equivalence between the memberships and the
     210                 :            :       // conclusion, possibly using the substituion in assumpOther.
     211                 :        386 :       bool isOr = (memor.getKind() == Kind::OR);
     212         [ +  + ]:        386 :       size_t ntgts = isOr ? 2 : 1;
     213         [ +  - ]:        477 :       for (size_t i = 0; i < ntgts; i++)
     214                 :            :       {
     215         [ +  + ]:        477 :         Node mtgt = isOr ? memor[i] : memor;
     216         [ +  - ]:        477 :         Trace("sets-ipc") << "...try target " << mtgt << std::endl;
     217         [ +  + ]:        477 :         if (psb.applyPredTransform(msrc, mtgt, assumpOther))
     218                 :            :         {
     219                 :        386 :           success = true;
     220         [ +  + ]:        386 :           if (isOr)
     221                 :            :           {
     222                 :            :             // if union, we get the desired (left or right) conclusion
     223                 :        346 :             success = psb.applyPredIntro(memor, {mtgt}, MethodId::SB_FORMULA);
     224                 :            :             // should never fail
     225 [ -  + ][ -  + ]:        173 :             Assert(success);
                 [ -  - ]
     226                 :            :           }
     227         [ +  - ]:        386 :           Trace("sets-ipc") << "......success" << std::endl;
     228                 :        386 :           break;
     229                 :            :         }
     230         [ +  + ]:        477 :       }
     231                 :            :       // If successful, we have proven:
     232                 :            :       //
     233                 :            :       // (set.member x A)   (set.member y B)
     234                 :            :       // --------------------------------------- AND_INTRO
     235                 :            :       // (and (set.member x A) (set.member y B))    (= x y)
     236                 :            :       // ------------------------------------------------- MACRO_SR_PRED_TRANS
     237                 :            :       // (set.member x (set.inter A B))
     238         [ -  + ]:        386 :       if (!success)
     239                 :            :       {
     240                 :          0 :         Assert(success);
     241                 :          0 :         break;
     242                 :            :       }
     243                 :            :       // If successful, go back and show memor holds.
     244         [ +  - ]:        772 :       Trace("sets-ipc") << "* Prove transform " << memor << " to " << memo
     245                 :        386 :                         << std::endl;
     246         [ -  + ]:        386 :       if (!psb.applyPredTransform(memor, memo, {}))
     247                 :            :       {
     248                 :            :         // should never fail
     249                 :          0 :         success = false;
     250                 :          0 :         Assert(success);
     251                 :          0 :         break;
     252                 :            :       }
     253         [ +  - ]:        386 :       if (so != conc[1])
     254                 :            :       {
     255                 :        386 :         std::vector<Node> ceqs;
     256                 :        772 :         Node ceq = conc[0].eqNode(conc[0]);
     257                 :        772 :         psb.addStep(ProofRule::REFL, {}, {conc[0]}, ceq);
     258                 :        386 :         ceqs.push_back(ceq);
     259                 :        386 :         ceq = so.eqNode(conc[1]);
     260         [ +  - ]:        772 :         Trace("sets-ipc") << "* Prove equal (by original forms) " << ceq
     261                 :        386 :                           << std::endl;
     262 [ +  + ][ -  + ]:        772 :         if (!psb.addStep(ProofRule::MACRO_SR_PRED_INTRO, {}, {ceq}, ceq))
                 [ -  - ]
     263                 :            :         {
     264                 :            :           // should never fail
     265                 :          0 :           success = false;
     266                 :          0 :           Assert(success);
     267                 :          0 :           break;
     268                 :            :         }
     269                 :        386 :         ceqs.push_back(ceq);
     270                 :        386 :         std::vector<Node> cargs;
     271                 :        386 :         Node cequiv = memo.eqNode(conc);
     272                 :        386 :         ProofRule cr = expr::getCongRule(memo, cargs);
     273         [ -  + ]:        386 :         if (!psb.addStep(cr, ceqs, cargs, cequiv))
     274                 :            :         {
     275                 :            :           // should never fail
     276                 :          0 :           success = false;
     277                 :          0 :           Assert(success);
     278                 :          0 :           break;
     279                 :            :         }
     280 [ +  + ][ -  + ]:       1158 :         if (!psb.addStep(ProofRule::EQ_RESOLVE, {memo, cequiv}, {}, conc))
                 [ -  - ]
     281                 :            :         {
     282                 :            :           // should never fail
     283                 :          0 :           success = false;
     284                 :          0 :           Assert(success);
     285                 :          0 :           break;
     286                 :            :         }
     287 [ +  - ][ +  - ]:        386 :       }
         [ +  - ][ +  - ]
     288                 :            :       // Final proof now is,using A^B as shorthand for (set.inter A B):
     289                 :            :       //
     290                 :            :       //                    ----- REFL  ---------- MACRO_SR_PRED_INTRO
     291                 :            :       // ...                x = x       A^B = k
     292                 :            :       // ------------------ -------------------------------------- CONG
     293                 :            :       // (set.member x A^B) (set.member x A^B) = (set.member x k)
     294                 :            :       // --------------------------------------------------------- EQ_RESOLVE
     295                 :            :       // (set.member x k)
     296                 :            :       //
     297                 :            :       // where ... is the proof from above.
     298 [ +  - ][ +  - ]:        386 :     }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     299                 :        386 :     break;
     300                 :         36 :     case InferenceId::SETS_SKOLEM:
     301                 :            :     {
     302 [ -  + ][ -  + ]:         36 :       Assert(assumps.empty());
                 [ -  - ]
     303                 :         36 :       success = psb.applyPredIntro(conc, {});
     304 [ -  + ][ -  + ]:         36 :       Assert(success);
                 [ -  - ]
     305                 :            :     }
     306                 :         36 :     break;
     307                 :        158 :     case InferenceId::SETS_DEQ:
     308                 :            :     {
     309 [ -  + ][ -  + ]:        158 :       Assert(assumps.size() == 1);
                 [ -  - ]
     310                 :        158 :       Node exp = assumps[0];
     311                 :            :       // ensure we are properly ordered
     312                 :        158 :       Assert(exp.getKind() == Kind::NOT && exp[0].getKind() == Kind::EQUAL
     313                 :            :              && exp[0][0] < exp[0][1]);
     314                 :        632 :       Node res = psb.tryStep(ProofRule::SETS_EXT, {exp}, {}, conc);
     315                 :        158 :       success = CDProof::isSame(res, conc);
     316 [ -  + ][ -  + ]:        158 :       Assert(success);
                 [ -  - ]
     317                 :        158 :     }
     318                 :        158 :     break;
     319                 :         32 :     case InferenceId::SETS_SINGLETON_EQ:
     320                 :            :     {
     321                 :            :       // SINGLETON_INJ
     322 [ -  + ][ -  + ]:         32 :       Assert(assumps.size() == 1);
                 [ -  - ]
     323                 :            :       Node res =
     324                 :        128 :           psb.tryStep(ProofRule::SETS_SINGLETON_INJ, {assumps[0]}, {}, conc);
     325                 :         32 :       success = CDProof::isSame(res, conc);
     326 [ -  + ][ -  + ]:         32 :       Assert(success);
                 [ -  - ]
     327                 :         32 :     }
     328                 :         32 :     break;
     329                 :         24 :     case InferenceId::SETS_FILTER_UP:
     330                 :            :     case InferenceId::SETS_FILTER_DOWN:
     331                 :            :     {
     332                 :         24 :       Node mem = assumps[0];
     333         [ +  + ]:         24 :       if (assumps.size() == 2)
     334                 :            :       {
     335                 :            :         // Transform based on the second equality A = B:
     336                 :            :         //
     337                 :            :         //                  ------ REFL
     338                 :            :         //                   x = x               A = B
     339                 :            :         //                  ----------------------------------- CONG
     340                 :            :         // (set.member x A) (set.member x A) = (set.member x B)
     341                 :            :         // ---------------------------------------------------- EQ_RESOLVE
     342                 :            :         // (set.member x B)
     343 [ -  + ][ -  + ]:          8 :         Assert(assumps[0].getKind() == Kind::SET_MEMBER);
                 [ -  - ]
     344 [ -  + ][ -  + ]:          8 :         Assert(assumps[1].getKind() == Kind::EQUAL);
                 [ -  - ]
     345                 :         32 :         Node refl = psb.tryStep(ProofRule::REFL, {}, {assumps[0][0]});
     346                 :          8 :         std::vector<Node> cargs;
     347                 :          8 :         ProofRule cr = expr::getCongRule(assumps[0], cargs);
     348                 :          8 :         Node aeq = assumps[1];
     349         [ +  - ]:          8 :         if (aeq[1] == assumps[0][1])
     350                 :            :         {
     351                 :            :           // flip?
     352                 :          8 :           aeq = aeq[1].eqNode(aeq[0]);
     353                 :         16 :           psb.tryStep(ProofRule::SYMM, {assumps[1]}, {});
     354                 :            :         }
     355                 :         40 :         Node eq = psb.tryStep(cr, {refl, aeq}, cargs);
     356         [ +  - ]:         16 :         Trace("sets-ipc") << "...via CONG is " << eq << ", now try with " << mem
     357                 :          8 :                           << std::endl;
     358 [ +  + ][ -  - ]:         24 :         mem = psb.tryStep(ProofRule::EQ_RESOLVE, {mem, eq}, {});
     359 [ -  + ][ -  + ]:          8 :         Assert(!mem.isNull());
                 [ -  - ]
     360                 :          8 :       }
     361                 :         48 :       ProofRule pr = (id == InferenceId::SETS_FILTER_UP)
     362         [ +  + ]:         24 :                          ? ProofRule::SETS_FILTER_UP
     363                 :            :                          : ProofRule::SETS_FILTER_DOWN;
     364                 :         24 :       std::vector<Node> pfArgs;
     365         [ +  + ]:         24 :       if (id == InferenceId::SETS_FILTER_UP)
     366                 :            :       {
     367                 :         16 :         Assert(conc.getKind() == Kind::EQUAL
     368                 :            :                && conc[0].getKind() == Kind::SET_MEMBER
     369                 :            :                && conc[0][1].getKind() == Kind::SET_FILTER);
     370                 :         32 :         Node pred = conc[0][1][0];
     371                 :         16 :         pfArgs.push_back(pred);
     372                 :         16 :       }
     373                 :         96 :       Node res = psb.tryStep(pr, {mem}, pfArgs);
     374         [ +  - ]:         48 :       Trace("sets-ipc") << "Filter rule " << id << " returns " << res
     375                 :         24 :                         << ", expects " << conc << std::endl;
     376                 :         24 :       success = CDProof::isSame(res, conc);
     377 [ -  + ][ -  + ]:         24 :       Assert(success);
                 [ -  - ]
     378                 :         24 :     }
     379                 :         24 :     break;
     380                 :         85 :     case InferenceId::SETS_EQ_MEM_CONFLICT:
     381                 :            :     case InferenceId::SETS_EQ_MEM:
     382                 :            :     {
     383                 :            :       // Handles cases:
     384                 :            :       // (and (= S set.empty) (set.member x S)) => false
     385                 :            :       // (and (= S (set.singleton y)) (set.member x S)) => (= x y)
     386 [ -  + ][ -  + ]:         85 :       Assert(assumps.size()==2);
                 [ -  - ]
     387 [ -  + ][ -  + ]:         85 :       Assert(assumps[0].getKind() == Kind::EQUAL);
                 [ -  - ]
     388 [ -  + ][ -  + ]:         85 :       Assert(assumps[1].getKind() == Kind::SET_MEMBER);
                 [ -  - ]
     389                 :        170 :       success = psb.applyPredTransform(assumps[1], conc, {assumps[0]});
     390                 :            :     }
     391                 :         85 :       break;
     392                 :        867 :     case InferenceId::SETS_EQ_CONFLICT:
     393         [ +  - ]:        867 :     default: Trace("sets-ipc") << "Unhandled " << id; break;
     394                 :            :   }
     395         [ +  + ]:       1952 :   if (success)
     396                 :            :   {
     397         [ -  + ]:       1085 :     if (!cdp.addSteps(psb))
     398                 :            :     {
     399                 :            :       // should not fail if success was computed correctly above
     400                 :          0 :       DebugUnhandled();
     401                 :            :       success = false;
     402                 :            :     }
     403                 :            :   }
     404         [ +  - ]:       1952 :   Trace("sets-ipc") << "...success = " << success << std::endl;
     405                 :       1952 :   return success;
     406                 :       1952 : }
     407                 :            : 
     408                 :          8 : std::string InferProofCons::identify() const { return "sets::InferProofCons"; }
     409                 :            : 
     410                 :            : }  // namespace sets
     411                 :            : }  // namespace theory
     412                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14