Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
sat_sweeping.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef ORTOOLS_SAT_SAT_SWEEPING_H_
15#define ORTOOLS_SAT_SAT_SWEEPING_H_
16
17#include <cstdint>
18#include <functional>
19#include <utility>
20#include <vector>
21
22#include "absl/container/flat_hash_map.h"
23#include "absl/types/span.h"
25#include "ortools/sat/clause.h"
27#include "ortools/sat/model.h"
30#include "ortools/sat/util.h"
32
33namespace operations_research {
34namespace sat {
35
36// This is a heuristic to find pairs of equivalent literals as described in [1].
37// The idea is to pick a random variable and define a neighborhood of clauses
38// and variables close to this variable. Next we define a local model containing
39// only those variables and clauses. Since this model is just a smaller portion
40// of the original model, we can expect it to have several feasible solutions.
41// Each solution we find reduces the set of possible equivalent variables. For
42// example, finding two solutions {l1=0, l2=0, ...} and {l1=0, l2=1, ...}
43// implies that `l1` and `l2` are not equivalent. This is done systematically by
44// keeping a partitioning of variables into potential clusters, and solving the
45// local model each time with the right assumptions to either refine a partition
46// or prove that a pair of literals are equivalent. This continue until we are
47// sure to have found all the equivalences.
48//
49// [1] "Clausal Equivalence Sweeping", Armin Biere, Katalin Fazekas, Mathias
50// Fleury, Nils Froleyks, 2025.
52 public:
54 : sat_solver_(model->GetOrCreate<SatSolver>()),
55 implication_graph_(model->GetOrCreate<BinaryImplicationGraph>()),
56 clause_manager_(model->GetOrCreate<ClauseManager>()),
57 global_time_limit_(model->GetOrCreate<TimeLimit>()),
58 random_(model->GetOrCreate<ModelRandomGenerator>()) {}
59
60 // Do one round of equivalence SAT sweeping.
61 // `run_inprocessing` is a function that is called on the model before solving
62 // it for the first time. It is useful to call inprocessing without creating a
63 // dependency cycle.
64 bool DoOneRound(std::function<void(Model*)> run_inprocessing);
65
66 private:
67 std::vector<absl::Span<const Literal>> GetNeighborhood(BooleanVariable var);
68 void LoadClausesInModel(absl::Span<const SatClause* const> clauses, Model* m);
69
70 SatSolver* sat_solver_;
71 BinaryImplicationGraph* implication_graph_;
72 ClauseManager* clause_manager_;
73 TimeLimit* global_time_limit_;
74 ModelRandomGenerator* random_;
75
76 int max_num_clauses_ = 52000;
77 int max_num_boolean_variables_ = 2000;
78
79 // We compute the occurrence graph once at the beginning of each round.
82
83 absl::flat_hash_map<BooleanVariable, BooleanVariable>
84 big_model_to_small_model_;
86 small_model_to_big_model_;
87};
88
89// Do a full SAT sweeping on the model defined by the clauses.
90// The `status` of the result is either FEASIBLE, INFEASIBLE or LIMIT_REACHED.
91// If the result is LIMIT_REACHED, the returned clauses are valid, but they are
92// not exhaustive. If the result is FEASIBLE, all possible binary clauses that
93// define equivalences and all possible unary clauses of the model are
94// guaranteed to be either in the `clauses` input or in the output. Many binary
95// clauses that are not equivalences will be returned too, but not necessarily
96// all of them. This call increases the deterministic time of the `time_limit`.
98 // Literals that if are set to false make the problem unsat.
99 std::vector<Literal> unary_clauses;
100 // Pairs of literals that if are both set to false make the problem unsat.
101 // We filter out the clauses that are already in the input.
102 std::vector<std::pair<Literal, Literal>> binary_clauses;
103 // TODO(user): also return small clauses of size > 2?
105};
107 const CompactVectorVector<int, Literal>& clauses, TimeLimit* time_limit,
108 std::function<void(Model*)> configure_model_before_first_solve);
109
110} // namespace sat
111} // namespace operations_research
112
113#endif // ORTOOLS_SAT_SAT_SWEEPING_H_
bool DoOneRound(std::function< void(Model *)> run_inprocessing)
SatSweepingResult DoFullSatSweeping(const CompactVectorVector< int, Literal > &clauses, TimeLimit *time_limit, std::function< void(Model *)> configure_model_before_first_solve)
OR-Tools root namespace.
std::vector< std::pair< Literal, Literal > > binary_clauses