LCOV - code coverage report
Current view: top level - buildbot/coverage/build/src/theory/arith - arith_proof_utilities.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 58 62 93.5 %
Date: 2026-08-02 10:35:41 Functions: 4 4 100.0 %
Branches: 38 80 47.5 %

           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                 :            :  * Common functions for dealing with proof nodes.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include "theory/arith/arith_proof_utilities.h"
      14                 :            : 
      15                 :            : #include "proof/proof_node_manager.h"
      16                 :            : #include "util/rational.h"
      17                 :            : 
      18                 :            : namespace cvc5::internal {
      19                 :            : namespace theory {
      20                 :            : namespace arith {
      21                 :            : 
      22                 :     663551 : std::vector<Node> getMacroSumUbCoeff(NodeManager* nm,
      23                 :            :                                      const std::vector<Pf>& pfs,
      24                 :            :                                      const std::vector<Node>& coeffs)
      25                 :            : {
      26 [ -  + ][ -  + ]:     663551 :   Assert(pfs.size() == coeffs.size());
                 [ -  - ]
      27                 :            : 
      28                 :     663551 :   std::vector<Node> premises;
      29         [ +  + ]:    2480502 :   for (const Pf& p : pfs)
      30                 :            :   {
      31                 :    1816951 :     premises.push_back(p->getResult());
      32                 :            :   }
      33                 :    1327102 :   return getMacroSumUbCoeff(nm, premises, coeffs);
      34                 :     663551 : }
      35                 :     663601 : std::vector<Node> getMacroSumUbCoeff(NodeManager* nm,
      36                 :            :                                      const std::vector<Node>& premises,
      37                 :            :                                      const std::vector<Node>& coeffs)
      38                 :            : {
      39 [ -  + ][ -  + ]:     663601 :   Assert(premises.size() == coeffs.size());
                 [ -  - ]
      40                 :            : 
      41                 :     663601 :   std::vector<Node> ret;
      42                 :     663601 :   TypeNode itype = nm->integerType();
      43                 :     663601 :   TypeNode rtype = nm->realType();
      44                 :            :   // For each coefficient, we must use a real if the lhs or rhs of the relation
      45                 :            :   // is a real, or if the coefficient is not integral.
      46         [ +  + ]:    2480652 :   for (size_t i = 0, ncoeff = coeffs.size(); i < ncoeff; i++)
      47                 :            :   {
      48 [ -  + ][ -  + ]:    1817051 :     Assert(coeffs[i].isConst());
                 [ -  - ]
      49                 :    1817051 :     Node res = premises[i];
      50                 :    1817051 :     Assert(res.getType().isBoolean() && res.getNumChildren() == 2);
      51                 :    1817051 :     const Rational& r = coeffs[i].getConst<Rational>();
      52                 :    3548485 :     bool isReal = !r.isIntegral() || res[0].getType().isReal()
      53                 :    3548485 :                   || res[1].getType().isReal();
      54         [ +  + ]:    1817051 :     ret.push_back(nm->mkConstRealOrInt(isReal ? rtype : itype, r));
      55                 :    1817051 :   }
      56                 :    1327202 :   return ret;
      57                 :     663601 : }
      58                 :            : 
      59                 :      31127 : Node expandMacroSumUb(NodeManager* nm,
      60                 :            :                       const std::vector<Node>& children,
      61                 :            :                       const std::vector<Node>& args,
      62                 :            :                       CDProof* cdp)
      63                 :            : {
      64         [ -  + ]:      31127 :   if (TraceIsOn("macro::arith"))
      65                 :            :   {
      66         [ -  - ]:          0 :     Trace("macro::arith") << "Expand MACRO_ARITH_SCALE_SUM_UB" << std::endl;
      67         [ -  - ]:          0 :     for (const auto& child : children)
      68                 :            :     {
      69         [ -  - ]:          0 :       Trace("macro::arith") << "  child: " << child << std::endl;
      70                 :            :     }
      71         [ -  - ]:          0 :     Trace("macro::arith") << "   args: " << args << std::endl;
      72                 :            :   }
      73 [ -  + ][ -  + ]:      31127 :   Assert(args.size() == children.size());
                 [ -  - ]
      74                 :      31127 :   ProofStepBuffer steps{cdp->getManager()->getChecker()};
      75                 :            : 
      76                 :            :   // Scale all children, accumulating
      77                 :      31127 :   std::vector<Node> scaledRels;
      78                 :      31127 :   Node one = nm->mkConstInt(Rational(1));
      79         [ +  + ]:     182539 :   for (size_t i = 0; i < children.size(); ++i)
      80                 :            :   {
      81                 :     151412 :     TNode child = children[i];
      82                 :     151412 :     TNode scalar = args[i];
      83         [ +  + ]:     151412 :     if (scalar.getConst<Rational>() == 1)
      84                 :            :     {
      85                 :            :       // if scaled by one, just take original
      86                 :      63464 :       scaledRels.push_back(child);
      87                 :      63464 :       continue;
      88                 :            :     }
      89                 :      87948 :     bool isPos = scalar.getConst<Rational>() > 0;
      90                 :            :     Node scalarCmp =
      91                 :            :         nm->mkNode(isPos ? Kind::GT : Kind::LT,
      92                 :            :                    scalar,
      93         [ +  + ]:     175896 :                    nm->mkConstRealOrInt(scalar.getType(), Rational(0)));
      94                 :            :     // (= scalarCmp true)
      95                 :     351792 :     Node scalarCmpOrTrue = steps.tryStep(ProofRule::EVALUATE, {}, {scalarCmp});
      96 [ -  + ][ -  + ]:      87948 :     Assert(!scalarCmpOrTrue.isNull());
                 [ -  - ]
      97                 :            :     // scalarCmp
      98                 :     175896 :     steps.addStep(ProofRule::TRUE_ELIM, {scalarCmpOrTrue}, {}, scalarCmp);
      99                 :            :     // (and scalarCmp relation)
     100                 :            :     Node scalarCmpAndRel =
     101                 :     439740 :         steps.tryStep(ProofRule::AND_INTRO, {scalarCmp, child}, {});
     102 [ -  + ][ -  + ]:      87948 :     Assert(!scalarCmpAndRel.isNull());
                 [ -  - ]
     103                 :            :     // (=> (and scalarCmp relation) scaled)
     104                 :     175896 :     Node impl = steps.tryStep(
     105                 :            :         isPos ? ProofRule::ARITH_MULT_POS : ProofRule::ARITH_MULT_NEG,
     106                 :            :         {},
     107         [ +  + ]:     263844 :         {scalar, child});
     108 [ -  + ][ -  + ]:      87948 :     Assert(!impl.isNull());
                 [ -  - ]
     109                 :            :     // scaled
     110                 :            :     Node scaled =
     111                 :     439740 :         steps.tryStep(ProofRule::MODUS_PONENS, {scalarCmpAndRel, impl}, {});
     112 [ -  + ][ -  + ]:      87948 :     Assert(!scaled.isNull());
                 [ -  - ]
     113                 :      87948 :     scaledRels.emplace_back(scaled);
     114 [ +  + ][ +  + ]:     214876 :   }
     115                 :            : 
     116                 :      62254 :   Node sumBounds = steps.tryStep(ProofRule::ARITH_SUM_UB, scaledRels, {});
     117                 :      31127 :   cdp->addSteps(steps);
     118         [ +  - ]:      31127 :   Trace("macro::arith") << "Expansion done. Proved: " << sumBounds << std::endl;
     119                 :      62254 :   return sumBounds;
     120                 :      31127 : }
     121                 :            : 
     122                 :    5023783 : std::shared_ptr<ProofNode> ensurePredTransform(ProofNodeManager* pnm,
     123                 :            :                                                std::shared_ptr<ProofNode>& pf,
     124                 :            :                                                const Node& pred)
     125                 :            : {
     126         [ +  + ]:    5023783 :   if (pf->getResult() == pred)
     127                 :            :   {
     128                 :     880985 :     return pf;
     129                 :            :   }
     130                 :            :   // give the predicate as the expected result, which is important for
     131                 :            :   // performance (does not require proof checking).
     132                 :   12428394 :   return pnm->mkNode(ProofRule::MACRO_SR_PRED_TRANSFORM, {pf}, {pred}, pred);
     133                 :            : }
     134                 :            : 
     135                 :            : }  // namespace arith
     136                 :            : }  // namespace theory
     137                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14