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 : : * Inverse rules for bit-vector operators. 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__BV_INVERTER_H 16 : : #define CVC5__BV_INVERTER_H 17 : : 18 : : #include <map> 19 : : #include <unordered_map> 20 : : #include <unordered_set> 21 : : #include <vector> 22 : : 23 : : #include "expr/node.h" 24 : : 25 : : namespace cvc5::internal { 26 : : namespace theory { 27 : : 28 : : class Rewriter; 29 : : 30 : : namespace quantifiers { 31 : : 32 : : /** BvInverterQuery 33 : : * 34 : : * This is a virtual class for queries 35 : : * required by the BvInverter class. 36 : : */ 37 : : class BvInverterQuery 38 : : { 39 : : public: 40 : 3961 : BvInverterQuery() {} 41 : 3961 : virtual ~BvInverterQuery() {} 42 : : /** returns the current model value of n */ 43 : : virtual Node getModelValue(Node n) = 0; 44 : : /** returns a bound variable of type tn */ 45 : : virtual Node getBoundVariable(TypeNode tn) = 0; 46 : : }; 47 : : 48 : : // inverter class 49 : : // TODO : move to theory/bv/ if generally useful? 50 : : class BvInverter 51 : : { 52 : : public: 53 : : BvInverter(Rewriter* r = nullptr); 54 : 71322 : ~BvInverter() {} 55 : : /** get dummy fresh variable of type tn, used as argument for sv */ 56 : : Node getSolveVariable(TypeNode tn); 57 : : 58 : : /** 59 : : * Get path to pv in lit, replace that occurrence by sv and all others by 60 : : * pvs (if pvs is non-null). If return value R is non-null, then : 61 : : * lit.path = pv R.path = sv 62 : : * R.path' = pvs for all lit.path' = pv, where path' != path 63 : : * 64 : : * If the flag projectNl is false, we return the null node if the 65 : : * literal lit is non-linear with respect to pv. 66 : : */ 67 : : Node getPathToPv(Node lit, 68 : : Node pv, 69 : : Node sv, 70 : : Node pvs, 71 : : std::vector<uint32_t>& path, 72 : : bool projectNl); 73 : : 74 : : /** 75 : : * Same as above, but does not linearize lit for pv. 76 : : * Use this version if we know lit is linear wrt pv. 77 : : */ 78 : 34498 : Node getPathToPv(Node lit, Node pv, std::vector<uint32_t>& path) 79 : : { 80 : 34498 : return getPathToPv(lit, pv, pv, Node::null(), path, false); 81 : : } 82 : : 83 : : /** solveBvLit 84 : : * 85 : : * Solve for sv in lit, where lit.path = sv. If this function returns a 86 : : * non-null node t, then sv = t is the solved form of lit. 87 : : * 88 : : * If the BvInverterQuery provided to this function call is null, then 89 : : * the solution returned by this call will not contain WITNESS expressions. 90 : : * If the solved form for lit requires introducing a WITNESS expression, 91 : : * then this call will return null. 92 : : */ 93 : : Node solveBvLit(Node sv, 94 : : Node lit, 95 : : std::vector<uint32_t>& path, 96 : : BvInverterQuery* m); 97 : : 98 : : private: 99 : : /** Helper function for getPathToPv */ 100 : : Node getPathToPv(Node lit, 101 : : Node pv, 102 : : Node sv, 103 : : std::vector<uint32_t>& path, 104 : : std::unordered_set<TNode>& visited); 105 : : 106 : : /** Helper function for getInv. 107 : : * 108 : : * This expects a condition cond where: 109 : : * (exists x. cond) 110 : : * is a BV tautology where x is getSolveVariable( tn ). 111 : : * 112 : : * It returns a term of the form: 113 : : * (witness y. cond { x -> y }) 114 : : * where y is a bound variable and x is getSolveVariable( tn ). 115 : : * 116 : : * In some cases, we may return a term t if cond implies an equality on 117 : : * the solve variable. For example, if cond is x = t where x is 118 : : * getSolveVariable(tn), then we return t instead of introducing the choice 119 : : * function. 120 : : * 121 : : * This function will return the null node if the BvInverterQuery m provided 122 : : * to this call is null. 123 : : */ 124 : : Node getInversionNode(Node cond, TypeNode tn, BvInverterQuery* m); 125 : : /** (Optional) rewriter used as helper in getInversionNode */ 126 : : Rewriter* d_rewriter; 127 : : /** Dummy variables for each type */ 128 : : std::map<TypeNode, Node> d_solve_var; 129 : : }; 130 : : 131 : : } // namespace quantifiers 132 : : } // namespace theory 133 : : } // namespace cvc5::internal 134 : : 135 : : #endif /* CVC5__BV_INVERTER_H */