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 : : * Utilities for nodes in the arithmetic rewriter. 11 : : */ 12 : : 13 : : #include "theory/arith/rewriter/node_utils.h" 14 : : 15 : : #include "base/check.h" 16 : : #include "theory/arith/rewriter/ordering.h" 17 : : 18 : : namespace cvc5::internal { 19 : : namespace theory { 20 : : namespace arith { 21 : : namespace rewriter { 22 : : 23 : 13114682 : Node mkMultTerm(const Rational& multiplicity, TNode monomial) 24 : : { 25 : 13114682 : NodeManager* nm = monomial.getNodeManager(); 26 [ + + ]: 13114682 : if (monomial.isConst()) 27 : : { 28 : 1834593 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 29 : : } 30 [ + + ]: 11280089 : if (multiplicity.isOne()) 31 : : { 32 : 6931866 : return monomial; 33 : : } 34 : 4348223 : return NodeManager::mkNode(Kind::MULT, mkConst(nm, multiplicity), monomial); 35 : : } 36 : : 37 : 12171029 : Node mkMultTerm(const RealAlgebraicNumber& multiplicity, TNode monomial) 38 : : { 39 : 12171029 : NodeManager* nm = monomial.getNodeManager(); 40 : 12171029 : Node mterm = mkConst(nm, multiplicity); 41 [ + + ]: 12171029 : if (mterm.isConst()) 42 : : { 43 : 12170943 : return mkMultTerm(mterm.getConst<Rational>(), monomial); 44 : : } 45 [ + + ]: 86 : if (monomial.isConst()) 46 : : { 47 : 140 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 48 : : } 49 : 16 : std::vector<Node> prod; 50 : 16 : prod.emplace_back(mterm); 51 [ + - ][ - + ]: 16 : if (monomial.getKind() == Kind::MULT || monomial.getKind() == Kind::NONLINEAR_MULT) [ - + ] 52 : : { 53 : 0 : prod.insert(prod.end(), monomial.begin(), monomial.end()); 54 : : } 55 : : else 56 : : { 57 : 16 : prod.emplace_back(monomial); 58 : : } 59 [ - + ][ - + ]: 16 : Assert(prod.size() >= 2); [ - - ] 60 : 16 : return nm->mkNode(Kind::NONLINEAR_MULT, prod); 61 : 12171029 : } 62 : : 63 : 1127189 : Node mkMultTerm(NodeManager* nm, 64 : : const RealAlgebraicNumber& multiplicity, 65 : : std::vector<Node>&& monomial) 66 : : { 67 [ + + ]: 1127189 : if (monomial.empty()) 68 : : { 69 : 183404 : return mkConst(nm, multiplicity); 70 : : } 71 : 943785 : Node mterm = mkConst(nm, multiplicity); 72 [ + + ]: 943785 : if (mterm.isConst()) 73 : : { 74 : 943739 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 75 : : return mkMultTerm(mterm.getConst<Rational>(), 76 : 943739 : mkNonlinearMult(nm, monomial)); 77 : : } 78 : 46 : monomial.emplace_back(mterm); 79 : 46 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 80 [ - + ][ - + ]: 46 : Assert(monomial.size() >= 2); [ - - ] 81 : 46 : return nm->mkNode(Kind::NONLINEAR_MULT, monomial); 82 : 943785 : } 83 : : 84 [ + + ]: 10626222 : TNode removeToReal(TNode t) { return t.getKind() == Kind::TO_REAL ? t[0] : t; } 85 : : 86 : 3506382 : Node maybeEnsureReal(TypeNode tn, TNode t) 87 : : { 88 : : // if we require being a real 89 [ + + ]: 3506382 : if (tn.isReal()) 90 : : { 91 : 1019895 : return ensureReal(t); 92 : : } 93 : 2486487 : return t; 94 : : } 95 : : 96 : 1592901 : Node ensureReal(TNode t) 97 : : { 98 [ + + ]: 1592901 : if (t.getType().isInteger()) 99 : : { 100 [ + + ]: 188852 : if (t.isConst()) 101 : : { 102 : : // short-circuit 103 : 181496 : Node ret = t.getNodeManager()->mkConstReal(t.getConst<Rational>()); 104 [ - + ][ - + ]: 181496 : Assert(ret.getType().isReal()); [ - - ] 105 : 181496 : return ret; 106 : 181496 : } 107 [ + - ]: 7356 : Trace("arith-rewriter-debug") << "maybeEnsureReal: " << t << std::endl; 108 : 7356 : return NodeManager::mkNode(Kind::TO_REAL, t); 109 : : } 110 : 1404049 : return t; 111 : : } 112 : : 113 : : } // namespace rewriter 114 : : } // namespace arith 115 : : } // namespace theory 116 : : } // namespace cvc5::internal