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 : 14726283 : Node mkMultTerm(const Rational& multiplicity, TNode monomial) 24 : : { 25 : 14726283 : NodeManager* nm = monomial.getNodeManager(); 26 [ + + ]: 14726283 : if (monomial.isConst()) 27 : : { 28 : 2005301 : return mkConst(nm, multiplicity * monomial.getConst<Rational>()); 29 : : } 30 [ + + ]: 12720982 : if (multiplicity.isOne()) 31 : : { 32 : 7765682 : return monomial; 33 : : } 34 : 4955300 : return NodeManager::mkNode(Kind::MULT, mkConst(nm, multiplicity), monomial); 35 : : } 36 : : 37 : 13758400 : Node mkMultTerm(const RealAlgebraicNumber& multiplicity, TNode monomial) 38 : : { 39 : 13758400 : NodeManager* nm = monomial.getNodeManager(); 40 : 13758400 : Node mterm = mkConst(nm, multiplicity); 41 [ + + ]: 13758400 : if (mterm.isConst()) 42 : : { 43 : 13758314 : 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 : 13758400 : } 63 : : 64 : 1156088 : Node mkMultTerm(NodeManager* nm, 65 : : const RealAlgebraicNumber& multiplicity, 66 : : std::vector<Node>&& monomial) 67 : : { 68 [ + + ]: 1156088 : if (monomial.empty()) 69 : : { 70 : 188073 : return mkConst(nm, multiplicity); 71 : : } 72 : 968015 : Node mterm = mkConst(nm, multiplicity); 73 [ + + ]: 968015 : if (mterm.isConst()) 74 : : { 75 : 967969 : std::sort(monomial.begin(), monomial.end(), rewriter::LeafNodeComparator()); 76 : : return mkMultTerm(mterm.getConst<Rational>(), 77 : 967969 : 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 : 968015 : } 84 : : 85 [ + + ]: 11791666 : TNode removeToReal(TNode t) { return t.getKind() == Kind::TO_REAL ? t[0] : t; } 86 : : 87 : 3798467 : Node maybeEnsureReal(TypeNode tn, TNode t) 88 : : { 89 : : // if we require being a real 90 [ + + ]: 3798467 : if (tn.isReal()) 91 : : { 92 : 1109498 : return ensureReal(t); 93 : : } 94 : 2688969 : return t; 95 : : } 96 : : 97 : 1723488 : Node ensureReal(TNode t) 98 : : { 99 [ + + ]: 1723488 : if (t.getType().isInteger()) 100 : : { 101 [ + + ]: 204008 : if (t.isConst()) 102 : : { 103 : : // short-circuit 104 : 195828 : Node ret = t.getNodeManager()->mkConstReal(t.getConst<Rational>()); 105 [ - + ][ - + ]: 195828 : Assert(ret.getType().isReal()); [ - - ] 106 : 195828 : return ret; 107 : 195828 : } 108 [ + - ]: 8180 : Trace("arith-rewriter-debug") << "maybeEnsureReal: " << t << std::endl; 109 : 8180 : return NodeManager::mkNode(Kind::TO_REAL, t); 110 : : } 111 : 1519480 : return t; 112 : : } 113 : : 114 : : } // namespace rewriter 115 : : } // namespace arith 116 : : } // namespace theory 117 : : } // namespace cvc5::internal