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 : 14456255 : Node mkMultTerm(const Rational& multiplicity, TNode monomial) 24 : : { 25 : 14456255 : NodeManager* nm = monomial.getNodeManager(); 26 [ + + ]: 14456255 : if (monomial.isConst()) 27 : : { 28 : 1970213 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 29 : : } 30 [ + + ]: 12486042 : if (multiplicity.isOne()) 31 : : { 32 : 7615735 : return monomial; 33 : : } 34 : 4870307 : return NodeManager::mkNode(Kind::MULT, mkConst(nm, multiplicity), monomial); 35 : : } 36 : : 37 : 13478857 : Node mkMultTerm(const RealAlgebraicNumber& multiplicity, TNode monomial) 38 : : { 39 : 13478857 : NodeManager* nm = monomial.getNodeManager(); 40 : 13478857 : Node mterm = mkConst(nm, multiplicity); 41 [ + + ]: 13478857 : if (mterm.isConst()) 42 : : { 43 : 13478771 : 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 52 [ + - ][ - + ]: 16 : || monomial.getKind() == Kind::NONLINEAR_MULT) [ - + ] 53 : : { 54 : 0 : prod.insert(prod.end(), monomial.begin(), monomial.end()); 55 : : } 56 : : else 57 : : { 58 : 16 : prod.emplace_back(monomial); 59 : : } 60 [ - + ][ - + ]: 16 : Assert(prod.size() >= 2); [ - - ] 61 : 16 : return nm->mkNode(Kind::NONLINEAR_MULT, prod); 62 : 13478857 : } 63 : : 64 : 1163081 : Node mkMultTerm(NodeManager* nm, 65 : : const RealAlgebraicNumber& multiplicity, 66 : : std::vector<Node>&& monomial) 67 : : { 68 [ + + ]: 1163081 : if (monomial.empty()) 69 : : { 70 : 185551 : return mkConst(nm, multiplicity); 71 : : } 72 : 977530 : Node mterm = mkConst(nm, multiplicity); 73 [ + + ]: 977530 : if (mterm.isConst()) 74 : : { 75 : 977484 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 76 : : return mkMultTerm(mterm.getConst<Rational>(), 77 : 977484 : mkNonlinearMult(nm, monomial)); 78 : : } 79 : 46 : monomial.emplace_back(mterm); 80 : 46 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 81 [ - + ][ - + ]: 46 : Assert(monomial.size() >= 2); [ - - ] 82 : 46 : return nm->mkNode(Kind::NONLINEAR_MULT, monomial); 83 : 977530 : } 84 : : 85 [ + + ]: 11522134 : TNode removeToReal(TNode t) { return t.getKind() == Kind::TO_REAL ? t[0] : t; } 86 : : 87 : 3764319 : Node maybeEnsureReal(TypeNode tn, TNode t) 88 : : { 89 : : // if we require being a real 90 [ + + ]: 3764319 : if (tn.isReal()) 91 : : { 92 : 1079586 : return ensureReal(t); 93 : : } 94 : 2684733 : return t; 95 : : } 96 : : 97 : 1647042 : Node ensureReal(TNode t) 98 : : { 99 [ + + ]: 1647042 : if (t.getType().isInteger()) 100 : : { 101 [ + + ]: 187654 : if (t.isConst()) 102 : : { 103 : : // short-circuit 104 : 180404 : Node ret = t.getNodeManager()->mkConstReal(t.getConst<Rational>()); 105 [ - + ][ - + ]: 180404 : Assert(ret.getType().isReal()); [ - - ] 106 : 180404 : return ret; 107 : 180404 : } 108 [ + - ]: 7250 : Trace("arith-rewriter-debug") << "maybeEnsureReal: " << t << std::endl; 109 : 7250 : return NodeManager::mkNode(Kind::TO_REAL, t); 110 : : } 111 : 1459388 : return t; 112 : : } 113 : : 114 : : } // namespace rewriter 115 : : } // namespace arith 116 : : } // namespace theory 117 : : } // namespace cvc5::internal