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 : : * Base classes for decision strategies used by theory solvers 11 : : * for use in the DecisionManager of TheoryEngine. 12 : : */ 13 : : 14 : : #include "cvc5_private.h" 15 : : 16 : : #ifndef CVC5__THEORY__DECISION_STRATEGY__H 17 : : #define CVC5__THEORY__DECISION_STRATEGY__H 18 : : 19 : : #include "context/cdo.h" 20 : : #include "expr/node.h" 21 : : #include "smt/env_obj.h" 22 : : #include "theory/valuation.h" 23 : : 24 : : namespace cvc5::internal { 25 : : namespace theory { 26 : : 27 : : /** 28 : : * Virtual base class for decision strategies. 29 : : */ 30 : : class DecisionStrategy : protected EnvObj 31 : : { 32 : : public: 33 : 67174 : DecisionStrategy(Env& env) : EnvObj(env) {} 34 : 66610 : virtual ~DecisionStrategy() {} 35 : : /** 36 : : * Initalize this strategy, This is called once per satisfiability call by 37 : : * the DecisionManager, prior to using this strategy. 38 : : */ 39 : : virtual void initialize() = 0; 40 : : /** 41 : : * If this method returns a non-null node n, then n is the required next 42 : : * decision of this strategy. It must be the case that n is a literal in 43 : : * the current CNF stream. 44 : : */ 45 : : virtual Node getNextDecisionRequest() = 0; 46 : : /** identify this strategy (for debugging) */ 47 : : virtual std::string identify() const = 0; 48 : : }; 49 : : 50 : : /** 51 : : * Decision strategy finite model finding. 52 : : * 53 : : * This is a virtual base class for decision strategies that follow the 54 : : * "finite model finding" pattern for decisions. Such strategies have the 55 : : * distinguishing feature that they are interested in a stream of literals 56 : : * L_1, L_2, L_3, ... and so on. At any given time, they request that L_i is 57 : : * asserted true for a minimal i. 58 : : * 59 : : * To enforce this strategy, this class maintains a SAT-context dependent 60 : : * index d_curr_literal, which corresponds to the minimal index of a literal 61 : : * in the above list that is not asserted false. A call to 62 : : * getNextDecisionRequest increments this value until we find a literal L_j 63 : : * that is not assigned false. If L_j is unassigned, we return it as a decision, 64 : : * otherwise we return no decisions. 65 : : */ 66 : : class DecisionStrategyFmf : public DecisionStrategy 67 : : { 68 : : public: 69 : : DecisionStrategyFmf(Env& env, Valuation valuation); 70 : 15952 : virtual ~DecisionStrategyFmf() {} 71 : : /** initialize */ 72 : : void initialize() override; 73 : : /** get next decision request */ 74 : : Node getNextDecisionRequest() override; 75 : : /** Make the n^th literal of this strategy */ 76 : : virtual Node mkLiteral(unsigned n) = 0; 77 : : /** 78 : : * This method returns true iff there exists a (minimal) i such that L_i 79 : : * is a literal allocated by this class, and is asserted true in the current 80 : : * context. If it returns true, the argument i is set to this i. 81 : : */ 82 : : bool getAssertedLiteralIndex(unsigned& i) const; 83 : : /** 84 : : * This method returns the literal L_i allocated by this class that 85 : : * has been asserted true in the current context and is such that i is 86 : : * minimal. It returns null if no such literals exist. 87 : : */ 88 : : Node getAssertedLiteral(); 89 : : /** Get the n^th literal of this strategy */ 90 : : Node getLiteral(unsigned lit); 91 : : 92 : : protected: 93 : : /** 94 : : * The valuation of this class, used for knowing what literals are asserted, 95 : : * and with what polarity. 96 : : */ 97 : : Valuation d_valuation; 98 : : /** 99 : : * The (SAT-context-dependent) flag that is true if there exists a literal 100 : : * of this class that is asserted true in the current context, according to 101 : : * d_valuation. 102 : : */ 103 : : context::CDO<bool> d_has_curr_literal; 104 : : /** 105 : : * The (SAT-context-dependent) index of the current literal of this strategy. 106 : : * This corresponds to the first literal that is not asserted false in the 107 : : * current context, according to d_valuation. 108 : : */ 109 : : context::CDO<unsigned> d_curr_literal; 110 : : /** the list of literals of this strategy */ 111 : : std::vector<Node> d_literals; 112 : : }; 113 : : 114 : : /** 115 : : * Special case of above where we only wish to allocate a single literal L_1. 116 : : */ 117 : : class DecisionStrategySingleton : public DecisionStrategyFmf 118 : : { 119 : : public: 120 : : DecisionStrategySingleton(Env& env, 121 : : const char* name, 122 : : Node lit, 123 : : Valuation valuation); 124 : : /** 125 : : * Make the n^th literal of this strategy. This method returns d_literal if 126 : : * n=0, null otherwise. 127 : : */ 128 : : Node mkLiteral(unsigned n) override; 129 : : /** Get single literal */ 130 : : Node getSingleLiteral(); 131 : : /** identify */ 132 : 0 : std::string identify() const override { return d_name; } 133 : : 134 : : private: 135 : : /** the name of this strategy */ 136 : : std::string d_name; 137 : : /** the literal to decide on */ 138 : : Node d_literal; 139 : : }; 140 : : 141 : : /** 142 : : * Special case of above where we only wish to allocate a (dynamic) vector 143 : : * of literals. 144 : : */ 145 : : class DecisionStrategyVector : public DecisionStrategyFmf 146 : : { 147 : : public: 148 : : DecisionStrategyVector(Env& env, const char* name, Valuation valuation); 149 : : /** 150 : : * Make the n^th literal of this strategy. This method returns d_literal if 151 : : * n=0, null otherwise. 152 : : */ 153 : : Node mkLiteral(unsigned n) override; 154 : : /** identify */ 155 : 0 : std::string identify() const override { return d_name; } 156 : : /** Add that literal n should be decided after the current list of literals */ 157 : : void addLiteral(const Node& n); 158 : : 159 : : private: 160 : : /** the name of this strategy */ 161 : : std::string d_name; 162 : : /** the literal to decide on */ 163 : : std::vector<Node> d_literals; 164 : : }; 165 : : 166 : : } // namespace theory 167 : : } // namespace cvc5::internal 168 : : 169 : : #endif /* CVC5__THEORY__DECISION_STRATEGY__H */