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 : 13162321 : Node mkMultTerm(const Rational& multiplicity, TNode monomial) 24 : : { 25 : 13162321 : NodeManager* nm = monomial.getNodeManager(); 26 [ + + ]: 13162321 : if (monomial.isConst()) 27 : : { 28 : 1836284 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 29 : : } 30 [ + + ]: 11326037 : if (multiplicity.isOne()) 31 : : { 32 : 6961484 : return monomial; 33 : : } 34 : 4364553 : return NodeManager::mkNode(Kind::MULT, mkConst(nm, multiplicity), monomial); 35 : : } 36 : : 37 : 12213696 : Node mkMultTerm(const RealAlgebraicNumber& multiplicity, TNode monomial) 38 : : { 39 : 12213696 : NodeManager* nm = monomial.getNodeManager(); 40 : 12213696 : Node mterm = mkConst(nm, multiplicity); 41 [ + + ]: 12213696 : if (mterm.isConst()) 42 : : { 43 : 12213610 : 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 : 12213696 : } 63 : : 64 : 1133002 : Node mkMultTerm(NodeManager* nm, 65 : : const RealAlgebraicNumber& multiplicity, 66 : : std::vector<Node>&& monomial) 67 : : { 68 [ + + ]: 1133002 : if (monomial.empty()) 69 : : { 70 : 184245 : return mkConst(nm, multiplicity); 71 : : } 72 : 948757 : Node mterm = mkConst(nm, multiplicity); 73 [ + + ]: 948757 : if (mterm.isConst()) 74 : : { 75 : 948711 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 76 : : return mkMultTerm(mterm.getConst<Rational>(), 77 : 948711 : 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 : 948757 : } 84 : : 85 [ + + ]: 10661080 : TNode removeToReal(TNode t) { return t.getKind() == Kind::TO_REAL ? t[0] : t; } 86 : : 87 : 3518100 : Node maybeEnsureReal(TypeNode tn, TNode t) 88 : : { 89 : : // if we require being a real 90 [ + + ]: 3518100 : if (tn.isReal()) 91 : : { 92 : 1019040 : return ensureReal(t); 93 : : } 94 : 2499060 : return t; 95 : : } 96 : : 97 : 1591726 : Node ensureReal(TNode t) 98 : : { 99 [ + + ]: 1591726 : if (t.getType().isInteger()) 100 : : { 101 [ + + ]: 188685 : if (t.isConst()) 102 : : { 103 : : // short-circuit 104 : 181339 : Node ret = t.getNodeManager()->mkConstReal(t.getConst<Rational>()); 105 [ - + ][ - + ]: 181339 : Assert(ret.getType().isReal()); [ - - ] 106 : 181339 : return ret; 107 : 181339 : } 108 [ + - ]: 7346 : Trace("arith-rewriter-debug") << "maybeEnsureReal: " << t << std::endl; 109 : 7346 : return NodeManager::mkNode(Kind::TO_REAL, t); 110 : : } 111 : 1403041 : return t; 112 : : } 113 : : 114 : : } // namespace rewriter 115 : : } // namespace arith 116 : : } // namespace theory 117 : : } // namespace cvc5::internal