Google OR-Tools: ortools/flatzinc/fz.cc Source File

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18#include <cstdlib>

19#include <cstring>

20#if defined(__GNUC__)

21#include <signal.h>

22#endif

23

24#include <iostream>

25#include <ostream>

26#include <string>

27#include <vector>

28

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"

49

51

52ABSL_FLAG(double, time_limit, 0, "time limit in seconds.");

53ABSL_FLAG(bool, search_all_solutions, false, "Search for all solutions.");

54ABSL_FLAG(bool, display_all_solutions, false,

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.");

64ABSL_FLAG(std::string, fz_model_name, "stdin",

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.");

73ABSL_FLAG(bool, ignore_redundant_constraints, false,

74 "Ignore redundant constraints.");

75ABSL_FLAG(bool, ignore_symmetry_breaking_constraints, false,

76 "Ignore symmetry breaking constraints.");

77

79namespace fz {

80

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;

95 }

96 if (strcmp((*argv)[i], "-i") == 0) {

97 (*argv)[i] = print_solutions;

98 }

99 if (strcmp((*argv)[i], "-f") == 0) {

100 (*argv)[i] = free_param;

101 set_free_search = true;

102 }

103 if (strcmp((*argv)[i], "-p") == 0) {

104 (*argv)[i] = threads_param;

105 }

106 if (strcmp((*argv)[i], "-l") == 0) {

107 (*argv)[i] = logging_param;

108 }

109 if (strcmp((*argv)[i], "-s") == 0) {

110 (*argv)[i] = statistics_param;

111 }

112 if (strcmp((*argv)[i], "-r") == 0) {

113 (*argv)[i] = seed_param;

114 }

115 if (strcmp((*argv)[i], "-t") == 0) {

116 (*argv)[i] = time_param;

117 use_time_param = true;

118 }

120 if (strcmp((*argv)[i], "-v") == 0) {

121 (*argv)[i] = logging_param;

122 }

123 }

124 }

125 const char kUsage[] =

126 "Usage: see flags.\nThis program parses and solve a flatzinc problem.";

127

128 absl::SetProgramUsageMessage(kUsage);

129 const std::vector<char*> residual_flags =

130 absl::ParseCommandLine(*argc, *argv);

131 absl::InitializeLog();

132

133

134 if (use_time_param) {

135 absl::SetFlag(&FLAGS_time_limit, absl::GetFlag(FLAGS_time_limit) / 1000.0);

136 }

137

138

139 if (set_free_search && absl::GetFlag(FLAGS_threads) == 0) {

140 absl::SetFlag(&FLAGS_threads, 1);

141 }

142

143 return residual_flags;

144}

145

147 SolverLogger* logger, absl::Duration* parse_duration) {

150

151

152 if (input_is_filename && !absl::EndsWith(input, ".fzn")) {

153 LOG(FATAL) << "Unrecognized flatzinc file: `" << input << "'";

154 }

155

156

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) {

163 } else {

165 }

166

168 SOLVER_LOG(logger, "File ", (input_is_filename ? input : "stdin"),

169 " parsed in ", absl::ToInt64Milliseconds(*parse_duration), " ms");

170

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();

177 }

178 if (ct->is_symmetric_breaking &&

179 absl::GetFlag(FLAGS_ignore_symmetry_breaking_constraints)) {

180 ++num_symmetry_breaking_constraints;

181 ct->MarkAsInactive();

182 }

183 }

184 if (num_redundant_constraints > 0) {

185 SOLVER_LOG(logger, " - ignored redundant constraints: ",

186 num_redundant_constraints);

187 }

188 if (num_symmetry_breaking_constraints > 0) {

189 SOLVER_LOG(logger, " - ignored symmetry breaking constraints: ",

190 num_symmetry_breaking_constraints);

191 }

193

194

198 return model;

199}

200

202 if (multi_line_input.empty()) {

203 std::cout << std::endl;

204 return;

205 }

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;

212 }

213}

214

215}

216}

217

218int main(int argc, char** argv) {

219

220

221 const std::vector<char*> residual_flags =

223

224 std::string input;

225 if (absl::GetFlag(FLAGS_read_from_stdin)) {

226 std::string currentLine;

227 while (std::getline(std::cin, currentLine)) {

228 input.append(currentLine);

229 input.append("\n");

230 }

231 } else {

232 if (residual_flags.empty()) {

233 LOG(ERROR) << "Usage: " << argv[0] << " <file>";

234 return EXIT_FAILURE;

235 }

236 input = residual_flags.back();

237 }

238

242 if (absl::GetFlag(FLAGS_ortools_mode)) {

243 logger->EnableLogging(absl::GetFlag(FLAGS_fz_logging));

244

247 } else {

250 }

251

252 absl::Duration parse_duration;

255 input, !absl::GetFlag(FLAGS_read_from_stdin), logger,

256 &parse_duration);

258

262 parameters.use_free_search = absl::GetFlag(FLAGS_free_search);

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);

271 parameters.check_all_solutions = absl::GetFlag(FLAGS_fz_check_all_solutions);

272

276

277 if (absl::GetFlag(FLAGS_time_limit) > 0 &&

278 parse_duration > absl::Seconds(absl::GetFlag(FLAGS_time_limit))) {

280 SOLVER_LOG(&solution_logger, "%% TIMEOUT");

281 }

283 SOLVER_LOG(logger, "CpSolverResponse summary:");

284 SOLVER_LOG(logger, "status: UNKNOWN");

285 }

286 return EXIT_SUCCESS;

287 }

288

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);

295 return EXIT_SUCCESS;

296}

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)

Definition fz.cc:218

constexpr bool kOrToolsMode

Definition fz.cc:50

absl::string_view Stem(absl::string_view path)

void LogInFlatzincFormat(const std::string &multi_line_input)

Definition fz.cc:201

Model ParseFlatzincModel(const std::string &input, bool input_is_filename, SolverLogger *logger, absl::Duration *parse_duration)

Definition fz.cc:146

bool ParseFlatzincString(const std::string &input, Model *model)

bool ParseFlatzincFile(const std::string &filename, Model *model)

std::vector< char * > FixAndParseParameters(int *argc, char ***argv)

Definition fz.cc:81

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,...)