Painless
A framework to ease parallelization of sequential CDCL SAT solvers
Loading...
Searching...
No Matches
StructuredBva.hpp
1#pragma once
2
3#include <map>
4#include <random>
5
6#include <Eigen/SparseCore>
7
8#include "preprocessors/PreprocessorInterface.hpp"
9#include "utils/Parsers.hpp"
10
11//===============litQueue.h====================
12
14typedef struct
15{
16 int lit;
17 unsigned int occurencesCount;
18} queuePair;
19
20/* Notes from cppreference:
21Note that the Compare parameter is defined such that it returns true if its first argument
22comes before its second argument in a weak ordering. But because the priority queue outputs
23largest elements first, the elements that "come before" are actually output last.
24That is, the front of the queue contains the "last" element according to the weak ordering
25imposed by Compare.
26*/
27bool
28decreasingOrder(const queuePair& lhs, const queuePair& rhs);
29
30bool
31increasingOrder(const queuePair& lhs, const queuePair& rhs);
32
33bool
34randomOrder(const queuePair& lhs, const queuePair& rhs);
35
38{
39 typedef bool (*compareFunc)(const queuePair&, const queuePair&);
40
41 PairCompare(compareFunc func)
42 : func(func)
43 {
44 }
45
47 : func(decreasingOrder)
48 {
49 }
50
51 bool operator()(const queuePair& lhs, const queuePair& rhs) const { return func(lhs, rhs); }
52
53 compareFunc func;
54};
55
56//=============================================
57
58// Occurence lists
59#define REAL_LIT_COUNT(LIT) \
60 ((unsigned int)this->litToClause[LIT_IDX(LIT)].size() + this->litCountAdjustement[LIT_IDX(LIT)])
61
62// Adjacency Matrix
63#define MATRIX_VAR_TO_IDX(LIT) (LIT - 1)
64#define MATRIX_LIT_TO_IDX(LIT) (LIT > 0 ? LIT - 1 : -LIT - 1)
65#define MATRIX_IDX_TO_VAR(IDX) (IDX + 1)
66
68enum class SBVATieBreak
69{
70 NONE = 1,
71 THREEHOPS = 2,
72 MOSTOCCUR = 3,
73 LEASTOCCUR = 4,
74 RANDOM = 5,
75};
76
77/* Do the same as isClauseDeleted ?*/
79{
80 std::vector<int> lits;
81 bool isAddition;
82};
83
94{
95 public:
97 StructuredBVA(int _id, unsigned long maxReplacements, bool shuffleTies);
98
101
102 unsigned int getVariablesCount() override;
103
104 void setSolverInterrupt() override;
105
106 void unsetSolverInterrupt() override;
107
108 SatResult solve(const std::vector<int>& cube = {}) override;
109
110 void addInitialClauses(const std::vector<simpleClause>& clauses, unsigned int nbVariables) override;
111
112 void loadFormula(const char* filename) override;
113
114 void printStatistics() override;
115
116 std::vector<simpleClause> getSimplifiedFormula() override;
117
119 {
120 return { (uint)this->clauses.size() - this->adjacencyDeleted, this->adjacencyDeleted, 0, this->replacementsCount, 0 };
121 }
122
123 int getDivisionVariable() { return 0; }
124
125 void addClause(ClauseExchangePtr clause) { return; }
126
127 void addClauses(const std::vector<ClauseExchangePtr>& clauses) { return; }
128
133 void diversify(const SeedGenerator& getSeed = [](SolverInterface* s) { return s->getSolverId(); });
134
135 void updateAdjacencyMatrix(int var);
136
137 unsigned int getThreeHopHeuristic(int lit1, int lit2);
138
139 /* returns the least occuring literal in a clause c\var */
140 int leastFrequentLiteral(simpleClause& clause, int lit);
141
142 void setTieBreakHeuristic(SBVATieBreak tieBreak);
143
145 {
146 this->tempTieHeuristicCache.clear();
147 this->litCountAdjustement.clear();
148 this->adjacencyMatrix.clear();
149 this->isClauseDeleted.clear();
150 this->litToClause.clear();
151 this->clauses.clear();
152 this->proof.clear();
153
154 this->litCountAdjustement.shrink_to_fit();
155 this->adjacencyMatrix.shrink_to_fit();
156 this->isClauseDeleted.shrink_to_fit();
157 this->litToClause.shrink_to_fit();
158 this->clauses.shrink_to_fit();
159 this->proof.shrink_to_fit();
160 }
161
166 void restoreModel(std::vector<int>& model) override { model.resize(this->varCount - this->replacementsCount); }
167
168 /* TODO factorize using a macro */
169 inline int threeHopTieBreak(const std::vector<int>& ties, const int currentLit)
170 {
171 int lmax = 0;
172 /* How much currentLit.lit is connected to ties[i] */
173 unsigned int maxHeuristicVal = 0;
174 for (int tie : ties) {
175 unsigned int temp = this->getThreeHopHeuristic(currentLit, tie);
176 if (temp > maxHeuristicVal) {
177 maxHeuristicVal = temp;
178 lmax = tie;
179 }
180 }
181 return lmax;
182 }
183
184 inline int mostOccurTieBreak(const std::vector<int>& ties, const int currentLit)
185 {
186 int lmax = 0;
187 /* How much currentLit.lit is connected to ties[i] */
188 unsigned int maxHeuristicVal = 0;
189 for (int tie : ties) {
190 unsigned int temp = REAL_LIT_COUNT(tie);
191 if (temp > maxHeuristicVal) {
192 maxHeuristicVal = temp;
193 lmax = tie;
194 }
195 }
196 return lmax;
197 }
198
199 inline int leastOccurTieBreak(const std::vector<int>& ties, const int currentLit)
200 {
201 int lmax = 0;
202 /* How much currentLit.lit is connected to ties[i] */
203 unsigned int maxHeuristicVal = UINT32_MAX;
204 for (int tie : ties) {
205 unsigned int temp = REAL_LIT_COUNT(tie);
206 if (temp < maxHeuristicVal) {
207 maxHeuristicVal = temp;
208 lmax = tie;
209 }
210 }
211 return lmax;
212 }
213
214 inline int randomTieBreak(const std::vector<int>& ties, const int currentLit)
215 {
216 std::srand(currentLit);
217 return ties[std::rand() % ties.size()];
218 }
219
220 std::vector<int> getModel() override
221 {
222 LOGWARN("BVA cannot solve a formula");
223 return {};
224 }
225
226 private:
227 void printParameters();
228
229 private:
230 std::atomic<bool> stopPreprocessing;
231
233 std::vector<simpleClause> clauses;
234
236 std::vector<bool> isClauseDeleted;
237
239 std::vector<std::vector<unsigned int>> litToClause;
240
242 std::vector<int> litCountAdjustement;
243
245 unsigned int adjacencyMatrixWidth;
246
248 std::vector<Eigen::SparseVector<int>> adjacencyMatrix;
249
251 std::map<int, int> tempTieHeuristicCache;
252
254 std::vector<ProofClause> proof;
255
256 // Options
257 //-------
258 bool generateProof;
259
260 bool preserveModelCount;
261
262 bool shuffleTies;
263
264 PairCompare pairCompare;
265
266 SBVATieBreak tieBreakHeuristic;
267
268 unsigned int maxReplacements;
269
270 std::function<int(const std::vector<int>&, const int)> breakTie;
271
272 // Stats
273 //------
274 unsigned int varCount;
275
276 unsigned int adjacencyDeleted;
277
278 unsigned int replacementsCount;
279
280 unsigned int originalClauseCount;
281
282 // Helpers
283 //--------
284};
285
286namespace Parsers {
287
295{
296 public:
297 SBVAInit(std::vector<std::vector<unsigned int>>& litToClause, std::vector<bool>& isClauseDeleted)
298 : m_litToClause(litToClause)
299 , m_isClauseDeleted(isClauseDeleted)
300 {
301 }
302
303 bool initMembers(unsigned int varCount, unsigned int clauseCount);
304 bool operator()(simpleClause& clause) override;
305
306 private:
307 std::vector<std::vector<unsigned int>>& m_litToClause;
308 std::vector<bool>& m_isClauseDeleted;
309};
310
311}
#define LOGWARN(...)
Log a warning message.
Definition Logger.hpp:137
Defines classes and functions for parsing CNF formulas and processing clauses.
Abstract base class for clause processors.
Definition Parsers.hpp:27
A filter for Structured BVA (Binary Variable Addition)
Definition StructuredBva.hpp:295
bool operator()(simpleClause &clause) override
Process a clause.
bool initMembers(unsigned int varCount, unsigned int clauseCount)
Initialize the processor with problem parameters.
Interface for preprocessor algorithms in SAT solving.
Definition PreprocessorInterface.hpp:40
Interface for a SAT solver with standard features.
Definition SolverInterface.hpp:62
unsigned int getSolverId()
Get the solver ID.
Definition SolverInterface.hpp:178
Structured Binary Variable Addition (SBVA) preprocessing algorithm.
Definition StructuredBva.hpp:94
void restoreModel(std::vector< int > &model) override
Restore the model by removing added clauses.
Definition StructuredBva.hpp:166
void addClause(ClauseExchangePtr clause)
Add a permanent clause to the formula.
Definition StructuredBva.hpp:125
int getDivisionVariable()
Get a variable suitable for search splitting.
Definition StructuredBva.hpp:123
void unsetSolverInterrupt() override
Remove the SAT solving interrupt request.
SatResult solve(const std::vector< int > &cube={}) override
Solve the formula with a given cube.
unsigned int getVariablesCount() override
Get the current number of variables.
void addClauses(const std::vector< ClauseExchangePtr > &clauses)
Add a list of permanent clauses to the formula.
Definition StructuredBva.hpp:127
void releaseMemory()
Release memory used by the preprocessor.
Definition StructuredBva.hpp:144
void addInitialClauses(const std::vector< simpleClause > &clauses, unsigned int nbVariables) override
Add a list of initial clauses to the formula.
void diversify(const SeedGenerator &getSeed=[](SolverInterface *s) { return s->getSolverId();})
Diversify the preprocessor's behavior.
PreprocessorStats getPreprocessorStatistics()
Get statistics about the preprocessing.
Definition StructuredBva.hpp:118
StructuredBVA(int _id, unsigned long maxReplacements, bool shuffleTies)
Constructor.
void setSolverInterrupt() override
Interrupt resolution, solving cannot continue until interrupt is unset.
std::vector< int > getModel() override
Return the model in case of SAT result.
Definition StructuredBva.hpp:220
void printStatistics() override
Print solver statistics.
void loadFormula(const char *filename) override
Load formula from a given dimacs file.
std::vector< simpleClause > getSimplifiedFormula() override
Get the simplified formula after preprocessing.
~StructuredBVA()
Destructor.
SatResult
Enumeration for SAT solver results.
Definition SolverInterface.hpp:39
A set of helper functions for CNF file parsing.
Definition StructuredBva.hpp:286
Functor for the priority queue used in solve()
Definition StructuredBva.hpp:38
Preperocessing technique statistics.
Definition PreprocessorInterface.hpp:14
Definition StructuredBva.hpp:79
queuePair struct used for the priorityQueue in solve
Definition StructuredBva.hpp:15