29#include "absl/flags/flag.h"
30#include "absl/flags/parse.h"
31#include "absl/flags/usage.h"
32#include "absl/log/check.h"
33#include "absl/log/flags.h"
34#include "absl/log/initialize.h"
35#include "absl/log/log.h"
36#include "absl/strings/match.h"
37#include "absl/strings/str_split.h"
38#include "absl/strings/string_view.h"
39#include "absl/time/time.h"
40#include "google/protobuf/text_format.h"
52ABSL_FLAG(
double, time_limit, 0,
"time limit in seconds.");
53ABSL_FLAG(
bool, search_all_solutions,
false,
"Search for all solutions.");
55 "Display all improving solutions.");
57 "If false, the solver must follow the defined search."
58 "If true, other search are allowed.");
59ABSL_FLAG(
int, threads, 0,
"Number of threads the solver will use.");
60ABSL_FLAG(
bool, statistics,
false,
"Print solver statistics after search.");
62 "Read the FlatZinc from stdin, not from a file.");
65 "Define problem name when reading from stdin.");
66ABSL_FLAG(std::string, params,
"",
"SatParameters as a text proto.");
68 "Print logging information from the flatzinc interpreter.");
70 "Display solutions in the flatzinc format");
72 "Checks all solutions returned by the solver.");
74 "Ignore redundant constraints.");
75ABSL_FLAG(
bool, ignore_symmetry_breaking_constraints,
false,
76 "Ignore symmetry breaking constraints.");
82 char all_param[] =
"--search_all_solutions";
83 char print_solutions[] =
"--display_all_solutions";
84 char free_param[] =
"--free_search";
85 char threads_param[] =
"--threads";
86 char logging_param[] =
"--fz_logging";
87 char statistics_param[] =
"--statistics";
88 char seed_param[] =
"--fz_seed";
89 char time_param[] =
"--time_limit";
90 bool use_time_param =
false;
91 bool set_free_search =
false;
92 for (
int i = 1; i < *argc; ++i) {
93 if (strcmp((*argv)[i],
"-a") == 0) {
94 (*argv)[i] = all_param;
96 if (strcmp((*argv)[i],
"-i") == 0) {
97 (*argv)[i] = print_solutions;
99 if (strcmp((*argv)[i],
"-f") == 0) {
100 (*argv)[i] = free_param;
101 set_free_search =
true;
103 if (strcmp((*argv)[i],
"-p") == 0) {
104 (*argv)[i] = threads_param;
106 if (strcmp((*argv)[i],
"-l") == 0) {
107 (*argv)[i] = logging_param;
109 if (strcmp((*argv)[i],
"-s") == 0) {
110 (*argv)[i] = statistics_param;
112 if (strcmp((*argv)[i],
"-r") == 0) {
113 (*argv)[i] = seed_param;
115 if (strcmp((*argv)[i],
"-t") == 0) {
116 (*argv)[i] = time_param;
117 use_time_param =
true;
120 if (strcmp((*argv)[i],
"-v") == 0) {
121 (*argv)[i] = logging_param;
126 "Usage: see flags.\nThis program parses and solve a flatzinc problem.";
128 absl::SetProgramUsageMessage(
kUsage);
129 const std::vector<char*> residual_flags =
130 absl::ParseCommandLine(*argc, *argv);
131 absl::InitializeLog();
134 if (use_time_param) {
135 absl::SetFlag(&FLAGS_time_limit, absl::GetFlag(FLAGS_time_limit) / 1000.0);
139 if (set_free_search && absl::GetFlag(FLAGS_threads) == 0) {
140 absl::SetFlag(&FLAGS_threads, 1);
143 return residual_flags;
152 if (input_is_filename && !absl::EndsWith(
input,
".fzn")) {
153 LOG(FATAL) <<
"Unrecognized flatzinc file: `" <<
input <<
"'";
157 const std::string problem_name = input_is_filename
159 : absl::GetFlag(FLAGS_fz_model_name);
160 Model model(problem_name);
161 if (input_is_filename) {
169 " parsed in ", absl::ToInt64Milliseconds(*parse_duration),
" ms");
171 int num_redundant_constraints = 0;
172 int num_symmetry_breaking_constraints = 0;
174 if (ct->is_redundant && absl::GetFlag(FLAGS_ignore_redundant_constraints)) {
175 ++num_redundant_constraints;
176 ct->MarkAsInactive();
178 if (ct->is_symmetric_breaking &&
179 absl::GetFlag(FLAGS_ignore_symmetry_breaking_constraints)) {
180 ++num_symmetry_breaking_constraints;
181 ct->MarkAsInactive();
184 if (num_redundant_constraints > 0) {
185 SOLVER_LOG(logger,
" - ignored redundant constraints: ",
186 num_redundant_constraints);
188 if (num_symmetry_breaking_constraints > 0) {
189 SOLVER_LOG(logger,
" - ignored symmetry breaking constraints: ",
190 num_symmetry_breaking_constraints);
202 if (multi_line_input.empty()) {
203 std::cout << std::endl;
206 const absl::string_view flatzinc_prefix =
207 absl::GetFlag(FLAGS_ortools_mode) ?
"%% " :
"";
208 const std::vector<absl::string_view> lines =
209 absl::StrSplit(multi_line_input,
'\n');
210 for (
const absl::string_view& line : lines) {
211 std::cout << flatzinc_prefix << line << std::endl;
218int main(
int argc,
char** argv) {
221 const std::vector<char*> residual_flags =
225 if (absl::GetFlag(FLAGS_read_from_stdin)) {
226 std::string currentLine;
227 while (std::getline(std::cin, currentLine)) {
228 input.append(currentLine);
232 if (residual_flags.empty()) {
233 LOG(ERROR) <<
"Usage: " << argv[0] <<
" <file>";
236 input = residual_flags.back();
242 if (absl::GetFlag(FLAGS_ortools_mode)) {
252 absl::Duration parse_duration;
255 input, !absl::GetFlag(FLAGS_read_from_stdin), logger,
264 absl::GetFlag(FLAGS_fz_logging) || !absl::GetFlag(FLAGS_ortools_mode);
265 parameters.
random_seed = absl::GetFlag(FLAGS_fz_seed);
269 absl::GetFlag(FLAGS_time_limit) - absl::ToInt64Seconds(parse_duration);
270 parameters.
ortools_mode = absl::GetFlag(FLAGS_ortools_mode);
277 if (absl::GetFlag(FLAGS_time_limit) > 0 &&
278 parse_duration > absl::Seconds(absl::GetFlag(FLAGS_time_limit))) {
283 SOLVER_LOG(logger,
"CpSolverResponse summary:");
290 CHECK(google::protobuf::TextFormat::ParseFromString(
291 absl::GetFlag(FLAGS_params), &flag_parameters))
292 << absl::GetFlag(FLAGS_params);
294 model, parameters, flag_parameters, &sat_model, &solution_logger);
absl::Duration GetDuration() const
void EnableLogging(bool enable)
void SetLogToStdOut(bool enable)
void AddInfoLoggingCallback(std::function< void(const std::string &message)> callback)
void PrintStatistics() const
const std::vector< Constraint * > & constraints() const
ABSL_FLAG(double, time_limit, 0, "time limit in seconds.")
int main(int argc, char **argv)
constexpr bool kOrToolsMode
absl::string_view Stem(absl::string_view path)
void LogInFlatzincFormat(const std::string &multi_line_input)
Model ParseFlatzincModel(const std::string &input, bool input_is_filename, SolverLogger *logger, absl::Duration *parse_duration)
bool ParseFlatzincString(const std::string &input, Model *model)
bool ParseFlatzincFile(const std::string &filename, Model *model)
std::vector< char * > FixAndParseParameters(int *argc, char ***argv)
CpSolverResponse SolveFzWithCpModelProto(const fz::Model &fz_model, const fz::FlatzincSatParameters &p, const SatParameters &sat_params, Model *sat_model, SolverLogger *solution_logger)
void ProcessFloatingPointOVariablesAndObjective(fz::Model *fz_model)
static int input(yyscan_t yyscanner)
static const char kUsage[]
bool search_all_solutions
double max_time_in_seconds
bool display_all_solutions
#define SOLVER_LOG(logger,...)