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 a finite model finding decision strategy for strings. 11 : : */ 12 : : 13 : : #include "theory/strings/strings_fmf.h" 14 : : 15 : : #include "theory/trust_substitutions.h" 16 : : #include "util/rational.h" 17 : : 18 : : using namespace std; 19 : : using namespace cvc5::context; 20 : : using namespace cvc5::internal::kind; 21 : : 22 : : namespace cvc5::internal { 23 : : namespace theory { 24 : : namespace strings { 25 : : 26 : 28700 : StringsFmf::StringsFmf(Env& env, Valuation valuation, TermRegistry& tr) 27 : 28700 : : EnvObj(env), d_sslds(nullptr), d_valuation(valuation), d_termReg(tr) 28 : : { 29 : 28700 : } 30 : : 31 : 28687 : StringsFmf::~StringsFmf() {} 32 : : 33 : 85 : void StringsFmf::presolve() 34 : : { 35 : 85 : d_sslds.reset(new StringSumLengthDecisionStrategy(d_env, d_valuation)); 36 [ + - ]: 170 : Trace("strings-dstrat-reg") 37 : 85 : << "presolve: register decision strategy." << std::endl; 38 : 85 : const NodeSet& ivars = d_termReg.getInputVars(); 39 : 85 : std::vector<Node> inputVars; 40 : 85 : SubstitutionMap& tls = d_env.getTopLevelSubstitutions().get(); 41 [ + + ]: 237 : for (NodeSet::const_iterator itr = ivars.begin(); itr != ivars.end(); ++itr) 42 : : { 43 : 152 : Node var = *itr; 44 : : // ensure we haven't solved for it? 45 [ + - ]: 152 : if (var == tls.apply(var)) 46 : : { 47 : 152 : inputVars.push_back(var); 48 : : } 49 : 152 : } 50 : 85 : d_sslds->initialize(inputVars); 51 : 85 : } 52 : : 53 : 85 : DecisionStrategy* StringsFmf::getDecisionStrategy() const 54 : : { 55 : 85 : return d_sslds.get(); 56 : : } 57 : : 58 : 85 : StringsFmf::StringSumLengthDecisionStrategy::StringSumLengthDecisionStrategy( 59 : 85 : Env& env, Valuation valuation) 60 : 85 : : DecisionStrategyFmf(env, valuation), d_inputVarLsum(userContext()) 61 : : { 62 : 85 : } 63 : : 64 : 0 : bool StringsFmf::StringSumLengthDecisionStrategy::isInitialized() 65 : : { 66 : 0 : return !d_inputVarLsum.get().isNull(); 67 : : } 68 : : 69 : 85 : void StringsFmf::StringSumLengthDecisionStrategy::initialize( 70 : : const std::vector<Node>& vars) 71 : : { 72 [ + - ][ + + ]: 85 : if (d_inputVarLsum.get().isNull() && !vars.empty()) [ + + ] 73 : : { 74 : 72 : NodeManager* nm = nodeManager(); 75 : 72 : std::vector<Node> sum; 76 [ + + ]: 224 : for (const Node& v : vars) 77 : : { 78 : 152 : sum.push_back(nm->mkNode(Kind::STRING_LENGTH, v)); 79 : : } 80 [ + + ]: 72 : Node sumn = sum.size() == 1 ? sum[0] : nm->mkNode(Kind::ADD, sum); 81 : 72 : d_inputVarLsum.set(sumn); 82 : 72 : } 83 : 85 : } 84 : : 85 : 304 : Node StringsFmf::StringSumLengthDecisionStrategy::mkLiteral(unsigned i) 86 : : { 87 [ - + ]: 304 : if (d_inputVarLsum.get().isNull()) 88 : : { 89 : 0 : return Node::null(); 90 : : } 91 : 304 : NodeManager* nm = nodeManager(); 92 : : Node lit = 93 : 608 : nm->mkNode(Kind::LEQ, d_inputVarLsum.get(), nm->mkConstInt(Rational(i))); 94 [ + - ]: 304 : Trace("strings-fmf") << "StringsFMF::mkLiteral: " << lit << std::endl; 95 : 304 : return lit; 96 : 304 : } 97 : 0 : std::string StringsFmf::StringSumLengthDecisionStrategy::identify() const 98 : : { 99 : 0 : return std::string("string_sum_len"); 100 : : } 101 : : 102 : : } // namespace strings 103 : : } // namespace theory 104 : : } // namespace cvc5::internal