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 : 14775364 : Node mkMultTerm(const Rational& multiplicity, TNode monomial) 24 : : { 25 : 14775364 : NodeManager* nm = monomial.getNodeManager(); 26 [ + + ]: 14775364 : if (monomial.isConst()) 27 : : { 28 : 2014119 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 29 : : } 30 [ + + ]: 12761245 : if (multiplicity.isOne()) 31 : : { 32 : 7786854 : return monomial; 33 : : } 34 : 4974391 : return NodeManager::mkNode(Kind::MULT, mkConst(nm, multiplicity), monomial); 35 : : } 36 : : 37 : 13801329 : Node mkMultTerm(const RealAlgebraicNumber& multiplicity, TNode monomial) 38 : : { 39 : 13801329 : NodeManager* nm = monomial.getNodeManager(); 40 : 13801329 : Node mterm = mkConst(nm, multiplicity); 41 [ + + ]: 13801329 : if (mterm.isConst()) 42 : : { 43 : 13801243 : 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 : 13801329 : } 63 : : 64 : 1164728 : Node mkMultTerm(NodeManager* nm, 65 : : const RealAlgebraicNumber& multiplicity, 66 : : std::vector<Node>&& monomial) 67 : : { 68 [ + + ]: 1164728 : if (monomial.empty()) 69 : : { 70 : 190561 : return mkConst(nm, multiplicity); 71 : : } 72 : 974167 : Node mterm = mkConst(nm, multiplicity); 73 [ + + ]: 974167 : if (mterm.isConst()) 74 : : { 75 : 974121 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 76 : : return mkMultTerm(mterm.getConst<Rational>(), 77 : 974121 : 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 : 974167 : } 84 : : 85 [ + + ]: 11869408 : TNode removeToReal(TNode t) { return t.getKind() == Kind::TO_REAL ? t[0] : t; } 86 : : 87 : 3816552 : Node maybeEnsureReal(TypeNode tn, TNode t) 88 : : { 89 : : // if we require being a real 90 [ + + ]: 3816552 : if (tn.isReal()) 91 : : { 92 : 1116606 : return ensureReal(t); 93 : : } 94 : 2699946 : return t; 95 : : } 96 : : 97 : 1731104 : Node ensureReal(TNode t) 98 : : { 99 [ + + ]: 1731104 : if (t.getType().isInteger()) 100 : : { 101 [ + + ]: 204615 : if (t.isConst()) 102 : : { 103 : : // short-circuit 104 : 196399 : Node ret = t.getNodeManager()->mkConstReal(t.getConst<Rational>()); 105 [ - + ][ - + ]: 196399 : Assert(ret.getType().isReal()); [ - - ] 106 : 196399 : return ret; 107 : 196399 : } 108 [ + - ]: 8216 : Trace("arith-rewriter-debug") << "maybeEnsureReal: " << t << std::endl; 109 : 8216 : return NodeManager::mkNode(Kind::TO_REAL, t); 110 : : } 111 : 1526489 : return t; 112 : : } 113 : : 114 : : } // namespace rewriter 115 : : } // namespace arith 116 : : } // namespace theory 117 : : } // namespace cvc5::internal