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 : : * Arithmetic substitution utility. 11 : : */ 12 : : 13 : : #ifndef CVC5__THEORY__ARITH__SUBS_H 14 : : #define CVC5__THEORY__ARITH__SUBS_H 15 : : 16 : : #include <map> 17 : : #include <optional> 18 : : #include <vector> 19 : : 20 : : #include "expr/subs.h" 21 : : #include "expr/term_context.h" 22 : : 23 : : namespace cvc5::internal { 24 : : namespace theory { 25 : : namespace arith { 26 : : 27 : : /** 28 : : * applyArith computes the substitution n { subs }, but with the caveat 29 : : * that subterms of n that belong to a theory other than arithmetic are 30 : : * not traversed. In other words, terms that belong to other theories are 31 : : * treated as atomic variables. For example: 32 : : * (5*f(x) + 7*x ){ x -> 3 } returns 5*f(x) + 7*3. 33 : : * 34 : : * Note that in contrast to the ordinary substitution class, this class allows 35 : : * mixing integers and reals via addArith. 36 : : */ 37 : : class ArithSubs : public Subs 38 : : { 39 : : public: 40 : : /** Add v -> s to the substitution */ 41 : : void addArith(const Node& v, const Node& s); 42 : : /** 43 : : * Return the result of this substitution on n. 44 : : * @param n The node to apply the substitution 45 : : * @param traverseNlMult Whether to traverse applications of NONLINEAR_MULT. 46 : : */ 47 : : Node applyArith(const Node& n, bool traverseNlMult = true) const; 48 : : /** 49 : : * Should traverse, returns true if the above method traverses n. 50 : : */ 51 : : static bool shouldTraverse(const Node& n, bool traverseNlMult = true); 52 : : /** 53 : : * Check if the node n has an arithmetic subterm t. 54 : : * @param n The node to search in 55 : : * @param t The subterm to search for 56 : : * @param traverseNlMult Whether to traverse applications of NONLINEAR_MULT. 57 : : * @return true iff t is a subterm in n 58 : : */ 59 : : static bool hasArithSubterm(TNode n, TNode t, bool traverseNlMult = true); 60 : : }; 61 : : 62 : : /** 63 : : * Arithmetic substitution term context. 64 : : */ 65 : : class ArithSubsTermContext : public TermContext 66 : : { 67 : : public: 68 : 165 : ArithSubsTermContext(bool traverseMult = true) : d_traverseMult(traverseMult) 69 : : { 70 : 165 : } 71 : : /** The initial value: valid. */ 72 : 544 : uint32_t initialValue() const override { return 0; } 73 : : /** Compute the value of the index^th child of t whose hash is tval */ 74 : 7030 : uint32_t computeValue(TNode t, 75 : : uint32_t tval, 76 : : CVC5_UNUSED size_t index) const override 77 : : { 78 [ + + ]: 7030 : if (tval == 0) 79 : : { 80 : : // if we should not traverse, return 1 81 [ + + ]: 5500 : if (!ArithSubs::shouldTraverse(t, d_traverseMult)) 82 : : { 83 : 1140 : return 1; 84 : : } 85 : 4360 : return 0; 86 : : } 87 : 1530 : return tval; 88 : : } 89 : : 90 : : private: 91 : : /** Should we traverse (non-linear) multiplication? */ 92 : : bool d_traverseMult; 93 : : }; 94 : : 95 : : } // namespace arith 96 : : } // namespace theory 97 : : } // namespace cvc5::internal 98 : : 99 : : #endif /* CVC5__THEORY__ARITH__SUBS_H */