Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS 8 : : * in the top-level source directory and their institutional affiliations. 9 : : * All rights reserved. See the file COPYING in the top-level source 10 : : * directory for licensing information. 11 : : * **************************************************************************** 12 : : * 13 : : * Arithmetic substitution utility. 14 : : */ 15 : : 16 : : #ifndef CVC5__THEORY__ARITH__SUBS_H 17 : : #define CVC5__THEORY__ARITH__SUBS_H 18 : : 19 : : #include <map> 20 : : #include <optional> 21 : : #include <vector> 22 : : 23 : : #include "expr/subs.h" 24 : : #include "expr/term_context.h" 25 : : 26 : : namespace cvc5::internal { 27 : : namespace theory { 28 : : namespace arith { 29 : : 30 : : /** 31 : : * applyArith computes the substitution n { subs }, but with the caveat 32 : : * that subterms of n that belong to a theory other than arithmetic are 33 : : * not traversed. In other words, terms that belong to other theories are 34 : : * treated as atomic variables. For example: 35 : : * (5*f(x) + 7*x ){ x -> 3 } returns 5*f(x) + 7*3. 36 : : * 37 : : * Note that in contrast to the ordinary substitution class, this class allows 38 : : * mixing integers and reals via addArith. 39 : : */ 40 : : class ArithSubs : public Subs 41 : : { 42 : : public: 43 : : /** Add v -> s to the substitution */ 44 : : void addArith(const Node& v, const Node& s); 45 : : /** 46 : : * Return the result of this substitution on n. 47 : : * @param n The node to apply the substitution 48 : : * @param traverseNlMult Whether to traverse applications of NONLINEAR_MULT. 49 : : */ 50 : : Node applyArith(const Node& n, bool traverseNlMult = true) const; 51 : : /** 52 : : * Should traverse, returns true if the above method traverses n. 53 : : */ 54 : : static bool shouldTraverse(const Node& n, bool traverseNlMult = true); 55 : : /** 56 : : * Check if the node n has an arithmetic subterm t. 57 : : * @param n The node to search in 58 : : * @param t The subterm to search for 59 : : * @param traverseNlMult Whether to traverse applications of NONLINEAR_MULT. 60 : : * @return true iff t is a subterm in n 61 : : */ 62 : : static bool hasArithSubterm(TNode n, TNode t, bool traverseNlMult = true); 63 : : }; 64 : : 65 : : /** 66 : : * Arithmetic substitution term context. 67 : : */ 68 : : class ArithSubsTermContext : public TermContext 69 : : { 70 : : public: 71 : 173 : ArithSubsTermContext(bool traverseMult = true) : d_traverseMult(traverseMult) 72 : : { 73 : 173 : } 74 : : /** The initial value: valid. */ 75 : 524 : uint32_t initialValue() const override { return 0; } 76 : : /** Compute the value of the index^th child of t whose hash is tval */ 77 : 8290 : uint32_t computeValue(TNode t, 78 : : uint32_t tval, 79 : : CVC5_UNUSED size_t index) const override 80 : : { 81 [ + + ]: 8290 : if (tval == 0) 82 : : { 83 : : // if we should not traverse, return 1 84 [ + + ]: 5674 : if (!ArithSubs::shouldTraverse(t, d_traverseMult)) 85 : : { 86 : 1230 : return 1; 87 : : } 88 : 4444 : return 0; 89 : : } 90 : 2616 : return tval; 91 : : } 92 : : 93 : : private: 94 : : /** Should we traverse (non-linear) multiplication? */ 95 : : bool d_traverseMult; 96 : : }; 97 : : 98 : : } // namespace arith 99 : : } // namespace theory 100 : : } // namespace cvc5::internal 101 : : 102 : : #endif /* CVC5__THEORY__ARITH__SUBS_H */