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