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 : : * Implementation of bit-vector conversions solver. 11 : : */ 12 : : 13 : : #include "theory/uf/conversions_solver.h" 14 : : 15 : : #include "options/uf_options.h" 16 : : #include "theory/arith/arith_utilities.h" 17 : : #include "theory/theory_inference_manager.h" 18 : : #include "theory/theory_model.h" 19 : : #include "theory/theory_state.h" 20 : : 21 : : using namespace cvc5::internal::kind; 22 : : 23 : : namespace cvc5::internal { 24 : : namespace theory { 25 : : namespace uf { 26 : : 27 : 67 : ConversionsSolver::ConversionsSolver(Env& env, 28 : : TheoryState& state, 29 : 67 : TheoryInferenceManager& im) 30 : : : EnvObj(env), 31 : 67 : d_state(state), 32 : 67 : d_im(im), 33 : 67 : d_preRegistered(userContext()), 34 : 134 : d_reduced(userContext()) 35 : : { 36 : 67 : } 37 : : 38 : 134 : ConversionsSolver::~ConversionsSolver() {} 39 : : 40 : 117 : void ConversionsSolver::preRegisterTerm(TNode term) 41 : : { 42 : 117 : d_preRegistered.push_back(term); 43 : 117 : } 44 : : 45 : 93 : void ConversionsSolver::check() 46 : : { 47 [ + - ]: 93 : Trace("bv-convs") << "Bitvector conversion terms : " << std::endl; 48 [ + - ]: 186 : Trace("bv-convs") << "ConversionsSolver: Check reductions for " 49 : 93 : << d_preRegistered.size() << " terms" << std::endl; 50 : : // check reductions for all bv conversion terms 51 [ + + ]: 288 : for (const Node& a : d_preRegistered) 52 : : { 53 : 195 : checkReduction(a); 54 : : } 55 : 93 : } 56 : : 57 : 195 : void ConversionsSolver::checkReduction(Node n) 58 : : { 59 [ + - ]: 195 : Trace("bv-convs") << "Check reduction " << n << std::endl; 60 [ + + ]: 195 : if (d_reduced.find(n) != d_reduced.end()) 61 : : { 62 [ + - ]: 82 : Trace("bv-convs") << "...already reduced" << std::endl; 63 : 104 : return; 64 : : } 65 : : // check whether it already has the correct value in the model? 66 : 113 : Node val = d_state.getModel()->getValue(n); 67 : 226 : Node uval = d_state.getRepresentative(n); 68 [ + - ]: 113 : Trace("bv-convs-debug") << " model value = " << val << std::endl; 69 [ + - ]: 113 : Trace("bv-convs-debug") << " rep = " << uval << std::endl; 70 [ + + ]: 113 : if (val == uval) 71 : : { 72 : : // "model-based reduction" strategy, do not reduce things that already have 73 : : // correct model values 74 [ + - ]: 14 : Trace("bv-convs") << "...already correct in model" << std::endl; 75 : 14 : return; 76 : : } 77 [ + + ]: 99 : if (options().uf.modelBasedArithBvConv) 78 : : { 79 : 16 : Node argval = d_state.getModel()->getValue(n[0]); 80 [ + - ]: 8 : Trace("bv-convs-debug") << " arg value = " << argval << std::endl; 81 : 16 : Node eval = rewrite(NodeManager::mkNode(n.getOperator(), argval)); 82 [ + - ]: 8 : Trace("bv-convs-debug") << " evaluated = " << eval << std::endl; 83 : 24 : Node lem = NodeManager::mkNode(Kind::IMPLIES, 84 : 16 : {n[0].eqNode(argval), n.eqNode(eval)}); 85 : 8 : d_im.lemma(lem, InferenceId::UF_ARITH_BV_CONV_VALUE_REFINE); 86 : 8 : return; 87 : 8 : } 88 : : 89 : 91 : Node lem; 90 : 91 : Kind k = n.getKind(); 91 [ + + ]: 91 : if (k == Kind::BITVECTOR_UBV_TO_INT) 92 : : { 93 : 41 : lem = arith::eliminateBv2Nat(n); 94 : : } 95 [ + - ]: 50 : else if (k == Kind::INT_TO_BITVECTOR) 96 : : { 97 : 50 : lem = arith::eliminateInt2Bv(n); 98 : : } 99 : 91 : lem = n.eqNode(lem); 100 : 91 : d_im.lemma(lem, InferenceId::UF_ARITH_BV_CONV_REDUCTION); 101 : 91 : d_reduced.insert(n); 102 [ + - ]: 91 : Trace("bv-convs") << "...do reduction" << std::endl; 103 [ + + ][ + + ]: 135 : } 104 : : 105 : : } // namespace uf 106 : : } // namespace theory 107 : : } // namespace cvc5::internal