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 : : * Wrapper around the SAT solver used for bitblasting. 11 : : */ 12 : : 13 : : #include "cvc5_private.h" 14 : : 15 : : #ifndef CVC5__THEORY__BV__BITBLAST__BITBLASTER_H 16 : : #define CVC5__THEORY__BV__BITBLAST__BITBLASTER_H 17 : : 18 : : #include <unordered_map> 19 : : #include <unordered_set> 20 : : #include <vector> 21 : : 22 : : #include "expr/node.h" 23 : : #include "prop/cnf_stream.h" 24 : : #include "prop/registrar.h" 25 : : #include "prop/sat_solver.h" 26 : : #include "prop/sat_solver_types.h" 27 : : #include "theory/bv/bitblast/bitblast_strategies_template.h" 28 : : #include "theory/rewriter.h" 29 : : #include "theory/theory.h" 30 : : #include "theory/valuation.h" 31 : : #include "util/resource_manager.h" 32 : : 33 : : namespace cvc5::internal { 34 : : namespace theory { 35 : : namespace bv { 36 : : 37 : : typedef std::unordered_set<Node> NodeSet; 38 : : typedef std::unordered_set<TNode> TNodeSet; 39 : : 40 : : /** 41 : : * The Bitblaster that manages the mapping between Nodes 42 : : * and their bitwise definition 43 : : * 44 : : */ 45 : : 46 : : template <class T> 47 : : class TBitblaster 48 : : { 49 : : protected: 50 : : typedef std::vector<T> Bits; 51 : : typedef std::unordered_map<Node, Bits> TermDefMap; 52 : : typedef std::unordered_set<TNode> TNodeSet; 53 : : typedef std::unordered_map<Node, Node> ModelCache; 54 : : 55 : : typedef void (*TermBBStrategy)(TNode, Bits&, TBitblaster<T>*); 56 : : typedef T (*AtomBBStrategy)(TNode, TBitblaster<T>*); 57 : : 58 : : // caches and mappings 59 : : TermDefMap d_termCache; 60 : : ModelCache d_modelCache; 61 : : // sat solver used for bitblasting and associated CnfStream 62 : : std::unique_ptr<context::Context> d_nullContext; 63 : : std::unique_ptr<prop::CnfStream> d_cnfStream; 64 : : 65 : : void initAtomBBStrategies(); 66 : : void initTermBBStrategies(); 67 : : 68 : : protected: 69 : : /// function tables for the various bitblasting strategies indexed by node 70 : : /// kind 71 : : TermBBStrategy d_termBBStrategies[static_cast<uint32_t>(Kind::LAST_KIND)]; 72 : : AtomBBStrategy d_atomBBStrategies[static_cast<uint32_t>(Kind::LAST_KIND)]; 73 : : virtual Node getModelFromSatSolver(TNode node, bool fullModel) = 0; 74 : : virtual prop::SatSolver* getSatSolver() = 0; 75 : : 76 : : public: 77 : : TBitblaster(); 78 : 58310 : virtual ~TBitblaster() {} 79 : : virtual void bbAtom(TNode node) = 0; 80 : : virtual void bbTerm(TNode node, Bits& bits) = 0; 81 : : virtual void makeVariable(TNode node, Bits& bits) = 0; 82 : : virtual T getBBAtom(TNode atom) const = 0; 83 : : virtual bool hasBBAtom(TNode atom) const = 0; 84 : : virtual void storeBBAtom(TNode atom, T atom_bb) = 0; 85 : : 86 : : bool hasBBTerm(TNode node) const; 87 : : void getBBTerm(TNode node, Bits& bits) const; 88 : : virtual void storeBBTerm(TNode term, const Bits& bits); 89 : : 90 : : /** 91 : : * Return a constant representing the value of a in the model. 92 : : * If fullModel is true set unconstrained bits to 0. If not return 93 : : * NullNode() for a fully or partially unconstrained. 94 : : * 95 : : */ 96 : : Node getTermModel(TNode node, bool fullModel); 97 : : void invalidateModelCache(); 98 : : }; 99 : : 100 : : // Bitblaster implementation 101 : : 102 : : template <class T> 103 : 58655 : void TBitblaster<T>::initAtomBBStrategies() 104 : : { 105 [ + + ]: 22464865 : for (uint32_t i = 0; i < static_cast<uint32_t>(Kind::LAST_KIND); ++i) 106 : : { 107 : 22406210 : d_atomBBStrategies[i] = UndefinedAtomBBStrategy<T>; 108 : : } 109 : : /// setting default bb strategies for atoms 110 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::EQUAL)] = DefaultEqBB<T>; 111 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ULT)] = 112 : : DefaultUltBB<T>; 113 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ULE)] = 114 : : DefaultUleBB<T>; 115 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_UGT)] = 116 : : DefaultUgtBB<T>; 117 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_UGE)] = 118 : : DefaultUgeBB<T>; 119 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SLT)] = 120 : : DefaultSltBB<T>; 121 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SLE)] = 122 : : DefaultSleBB<T>; 123 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SGT)] = 124 : : DefaultSgtBB<T>; 125 : 58655 : d_atomBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SGE)] = 126 : : DefaultSgeBB<T>; 127 : 58655 : } 128 : : 129 : : template <class T> 130 : 58655 : void TBitblaster<T>::initTermBBStrategies() 131 : : { 132 [ + + ]: 22464865 : for (uint32_t i = 0; i < static_cast<uint32_t>(Kind::LAST_KIND); ++i) 133 : : { 134 : 22406210 : d_termBBStrategies[i] = DefaultVarBB<T>; 135 : : } 136 : : /// setting default bb strategies for terms: 137 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::CONST_BITVECTOR)] = 138 : : DefaultConstBB<T>; 139 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_NOT)] = 140 : : DefaultNotBB<T>; 141 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_CONCAT)] = 142 : : DefaultConcatBB<T>; 143 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_AND)] = 144 : : DefaultAndBB<T>; 145 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_OR)] = 146 : : DefaultOrBB<T>; 147 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_XOR)] = 148 : : DefaultXorBB<T>; 149 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_XNOR)] = 150 : : DefaultXnorBB<T>; 151 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_NAND)] = 152 : : DefaultNandBB<T>; 153 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_NOR)] = 154 : : DefaultNorBB<T>; 155 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_COMP)] = 156 : : DefaultCompBB<T>; 157 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_MULT)] = 158 : : DefaultMultBB<T>; 159 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ADD)] = 160 : : DefaultAddBB<T>; 161 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SUB)] = 162 : : DefaultSubBB<T>; 163 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_NEG)] = 164 : : DefaultNegBB<T>; 165 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_UDIV)] = 166 : : DefaultUdivBB<T>; 167 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_UREM)] = 168 : : DefaultUremBB<T>; 169 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SDIV)] = 170 : : UndefinedTermBBStrategy<T>; 171 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SREM)] = 172 : : UndefinedTermBBStrategy<T>; 173 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SMOD)] = 174 : : UndefinedTermBBStrategy<T>; 175 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SHL)] = 176 : : DefaultShlBB<T>; 177 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_LSHR)] = 178 : : DefaultLshrBB<T>; 179 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ASHR)] = 180 : : DefaultAshrBB<T>; 181 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ULTBV)] = 182 : : DefaultUltbvBB<T>; 183 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SLTBV)] = 184 : : DefaultSltbvBB<T>; 185 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ITE)] = 186 : : DefaultIteBB<T>; 187 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_EXTRACT)] = 188 : : DefaultExtractBB<T>; 189 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_REPEAT)] = 190 : : DefaultRepeatBB<T>; 191 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ZERO_EXTEND)] = 192 : : DefaultZeroExtendBB<T>; 193 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_SIGN_EXTEND)] = 194 : : DefaultSignExtendBB<T>; 195 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ROTATE_RIGHT)] = 196 : : DefaultRotateRightBB<T>; 197 : 58655 : d_termBBStrategies[static_cast<uint32_t>(Kind::BITVECTOR_ROTATE_LEFT)] = 198 : : DefaultRotateLeftBB<T>; 199 : 58655 : } 200 : : 201 : : template <class T> 202 : 58655 : TBitblaster<T>::TBitblaster() 203 : 58655 : : d_termCache(), 204 : 58655 : d_modelCache(), 205 : 58655 : d_nullContext(new context::Context()), 206 : 117310 : d_cnfStream() 207 : : { 208 : 58655 : initAtomBBStrategies(); 209 : 58655 : initTermBBStrategies(); 210 : 58655 : } 211 : : 212 : : template <class T> 213 : 871105 : bool TBitblaster<T>::hasBBTerm(TNode node) const 214 : : { 215 : 871105 : return d_termCache.find(node) != d_termCache.end(); 216 : : } 217 : : template <class T> 218 : 278383 : void TBitblaster<T>::getBBTerm(TNode node, Bits& bits) const 219 : : { 220 [ - + ][ - + ]: 278383 : Assert(hasBBTerm(node)); [ - - ] 221 : 278383 : bits = d_termCache.find(node)->second; 222 : 278383 : } 223 : : 224 : : template <class T> 225 : 0 : void TBitblaster<T>::storeBBTerm(TNode node, const Bits& bits) 226 : : { 227 : 0 : d_termCache.insert(std::make_pair(node, bits)); 228 : 0 : } 229 : : 230 : : template <class T> 231 : : void TBitblaster<T>::invalidateModelCache() 232 : : { 233 : : d_modelCache.clear(); 234 : : } 235 : : 236 : : } // namespace bv 237 : : } // namespace theory 238 : : } // namespace cvc5::internal 239 : : 240 : : #endif /* CVC5__THEORY__BV__BITBLAST__BITBLASTER_H */