GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/options/options_handler.cpp Lines: 115 216 53.2 %
Date: 2021-11-07 Branches: 111 466 23.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Aina Niemetz, Tim King, Mathias Preiner
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Interface for custom handlers and predicates options.
14
 */
15
16
#include "options/options_handler.h"
17
18
#include <cerrno>
19
#include <iostream>
20
#include <ostream>
21
#include <string>
22
23
#include "base/check.h"
24
#include "base/configuration.h"
25
#include "base/configuration_private.h"
26
#include "base/cvc5config.h"
27
#include "base/exception.h"
28
#include "base/modal_exception.h"
29
#include "base/output.h"
30
#include "expr/expr_iomanip.h"
31
#include "lib/strtok_r.h"
32
#include "options/base_options.h"
33
#include "options/bv_options.h"
34
#include "options/decision_options.h"
35
#include "options/language.h"
36
#include "options/option_exception.h"
37
#include "options/set_language.h"
38
#include "options/smt_options.h"
39
#include "options/theory_options.h"
40
#include "smt/command.h"
41
#include "util/didyoumean.h"
42
43
namespace cvc5 {
44
namespace options {
45
46
// helper functions
47
namespace {
48
49
static void printTags(const std::vector<std::string>& tags)
50
{
51
  std::cout << "available tags:";
52
  for (const auto& t : tags)
53
  {
54
    std::cout << "  " << t << std::endl;
55
  }
56
  std::cout << std::endl;
57
}
58
59
std::string suggestTags(const std::vector<std::string>& validTags,
60
                        std::string inputTag,
61
                        const std::vector<std::string>& additionalTags)
62
{
63
  DidYouMean didYouMean;
64
  didYouMean.addWords(validTags);
65
  didYouMean.addWords(additionalTags);
66
  return didYouMean.getMatchAsString(inputTag);
67
}
68
69
}  // namespace
70
71
30748
OptionsHandler::OptionsHandler(Options* options) : d_options(options) { }
72
73
1
void OptionsHandler::setErrStream(const std::string& flag, const ManagedErr& me)
74
{
75
1
  Debug.setStream(me);
76
1
  Warning.setStream(me);
77
1
  CVC5Message.setStream(me);
78
1
  Trace.setStream(me);
79
1
}
80
81
17635
Language OptionsHandler::stringToLanguage(const std::string& flag,
82
                                          const std::string& optarg)
83
{
84
17635
  if (optarg == "help")
85
  {
86
    *d_options->base.out << R"FOOBAR(
87
Languages currently supported as arguments to the -L / --lang option:
88
  auto                           attempt to automatically determine language
89
  smt | smtlib | smt2 |
90
  smt2.6 | smtlib2.6             SMT-LIB format 2.6 with support for the strings standard
91
  tptp                           TPTP format (cnf, fof and tff)
92
  sygus | sygus2                 SyGuS version 2.0
93
94
Languages currently supported as arguments to the --output-lang option:
95
  auto                           match output language to input language
96
  smt | smtlib | smt2 |
97
  smt2.6 | smtlib2.6             SMT-LIB format 2.6 with support for the strings standard
98
  tptp                           TPTP format
99
  ast                            internal format (simple syntax trees)
100
)FOOBAR" << std::endl;
101
    std::exit(1);
102
    return Language::LANG_AUTO;
103
  }
104
105
  try
106
  {
107
17635
    return language::toLanguage(optarg);
108
  }
109
  catch (OptionException& oe)
110
  {
111
    throw OptionException("Error in " + flag + ": " + oe.getMessage()
112
                          + "\nTry --lang help");
113
  }
114
115
  Unreachable();
116
}
117
118
11032
void OptionsHandler::languageIsNotAST(const std::string& flag, Language lang)
119
{
120
11032
  if (lang == Language::LANG_AST)
121
  {
122
    throw OptionException("Language LANG_AST is not allowed for " + flag);
123
  }
124
11032
}
125
126
6603
void OptionsHandler::applyOutputLanguage(const std::string& flag, Language lang)
127
{
128
6603
  d_options->base.out << language::SetLanguage(lang);
129
6603
}
130
131
219
void OptionsHandler::setVerbosity(const std::string& flag, int value)
132
{
133
219
  if(Configuration::isMuzzledBuild()) {
134
    DebugChannel.setStream(&cvc5::null_os);
135
    TraceChannel.setStream(&cvc5::null_os);
136
    MessageChannel.setStream(&cvc5::null_os);
137
    WarningChannel.setStream(&cvc5::null_os);
138
  } else {
139
219
    if(value < 0) {
140
210
      MessageChannel.setStream(&cvc5::null_os);
141
210
      WarningChannel.setStream(&cvc5::null_os);
142
    } else {
143
9
      MessageChannel.setStream(&std::cout);
144
9
      WarningChannel.setStream(&std::cerr);
145
    }
146
  }
147
219
}
148
149
210
void OptionsHandler::decreaseVerbosity(const std::string& flag)
150
{
151
210
  d_options->base.verbosity -= 1;
152
210
  setVerbosity(flag, d_options->base.verbosity);
153
210
}
154
155
3
void OptionsHandler::increaseVerbosity(const std::string& flag)
156
{
157
3
  d_options->base.verbosity += 1;
158
3
  setVerbosity(flag, d_options->base.verbosity);
159
3
}
160
161
2
void OptionsHandler::setStats(const std::string& flag, bool value)
162
{
163
#ifndef CVC5_STATISTICS_ON
164
  if (value)
165
  {
166
    std::stringstream ss;
167
    ss << "option `" << flag
168
       << "' requires a statistics-enabled build of cvc5; this binary was not "
169
          "built with statistics support";
170
    throw OptionException(ss.str());
171
  }
172
#endif /* CVC5_STATISTICS_ON */
173
2
  if (!value)
174
  {
175
2
    d_options->base.statisticsAll = false;
176
2
    d_options->base.statisticsEveryQuery = false;
177
2
    d_options->base.statisticsExpert = false;
178
  }
179
2
}
180
181
2
void OptionsHandler::setStatsDetail(const std::string& flag, bool value)
182
{
183
#ifndef CVC5_STATISTICS_ON
184
  if (value)
185
  {
186
    std::stringstream ss;
187
    ss << "option `" << flag
188
       << "' requires a statistics-enabled build of cvc5; this binary was not "
189
          "built with statistics support";
190
    throw OptionException(ss.str());
191
  }
192
#endif /* CVC5_STATISTICS_ON */
193
2
  if (value)
194
  {
195
2
    d_options->base.statistics = true;
196
  }
197
2
}
198
199
1
void OptionsHandler::enableTraceTag(const std::string& flag,
200
                                    const std::string& optarg)
201
{
202
1
  if(!Configuration::isTracingBuild())
203
  {
204
    throw OptionException("trace tags not available in non-tracing builds");
205
  }
206
1
  else if(!Configuration::isTraceTag(optarg.c_str()))
207
  {
208
    if (optarg == "help")
209
    {
210
      printTags(Configuration::getTraceTags());
211
      std::exit(0);
212
    }
213
214
    throw OptionException(
215
        std::string("trace tag ") + optarg + std::string(" not available.")
216
        + suggestTags(Configuration::getTraceTags(), optarg, {}));
217
  }
218
1
  Trace.on(optarg);
219
1
}
220
221
void OptionsHandler::enableDebugTag(const std::string& flag,
222
                                    const std::string& optarg)
223
{
224
  if (!Configuration::isDebugBuild())
225
  {
226
    throw OptionException("debug tags not available in non-debug builds");
227
  }
228
  else if (!Configuration::isTracingBuild())
229
  {
230
    throw OptionException("debug tags not available in non-tracing builds");
231
  }
232
233
  if (!Configuration::isDebugTag(optarg.c_str())
234
      && !Configuration::isTraceTag(optarg.c_str()))
235
  {
236
    if (optarg == "help")
237
    {
238
      printTags(Configuration::getDebugTags());
239
      std::exit(0);
240
    }
241
242
    throw OptionException(std::string("debug tag ") + optarg
243
                          + std::string(" not available.")
244
                          + suggestTags(Configuration::getDebugTags(),
245
                                        optarg,
246
                                        Configuration::getTraceTags()));
247
  }
248
  Debug.on(optarg);
249
  Trace.on(optarg);
250
}
251
252
11
void OptionsHandler::enableOutputTag(const std::string& flag,
253
                                     const std::string& optarg)
254
{
255
11
  size_t tagid = static_cast<size_t>(stringToOutputTag(optarg));
256
11
  Assert(d_options->base.outputTagHolder.size() > tagid)
257
      << "Output tag is larger than the bitset that holds it.";
258
11
  d_options->base.outputTagHolder.set(tagid);
259
11
}
260
261
30
void OptionsHandler::setPrintSuccess(const std::string& flag, bool value)
262
{
263
30
  Debug.getStream() << Command::printsuccess(value);
264
30
  Trace.getStream() << Command::printsuccess(value);
265
30
  CVC5Message.getStream() << Command::printsuccess(value);
266
30
  Warning.getStream() << Command::printsuccess(value);
267
30
  *d_options->base.out << Command::printsuccess(value);
268
30
}
269
270
void OptionsHandler::setResourceWeight(const std::string& flag,
271
                                       const std::string& optarg)
272
{
273
  d_options->base.resourceWeightHolder.emplace_back(optarg);
274
}
275
276
16
void OptionsHandler::checkBvSatSolver(const std::string& flag, SatSolverMode m)
277
{
278
16
  if (m == SatSolverMode::CRYPTOMINISAT
279
16
      && !Configuration::isBuiltWithCryptominisat())
280
  {
281
    std::stringstream ss;
282
    ss << "option `" << flag
283
       << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
284
          "with CryptoMiniSat support";
285
    throw OptionException(ss.str());
286
  }
287
288
16
  if (m == SatSolverMode::KISSAT && !Configuration::isBuiltWithKissat())
289
  {
290
    std::stringstream ss;
291
    ss << "option `" << flag
292
       << "' requires a Kissat build of cvc5; this binary was not built with "
293
          "Kissat support";
294
    throw OptionException(ss.str());
295
  }
296
297
16
  if (d_options->bv.bvSolver != options::BVSolver::BITBLAST
298
      && (m == SatSolverMode::CRYPTOMINISAT || m == SatSolverMode::CADICAL
299
          || m == SatSolverMode::KISSAT))
300
  {
301
    if (d_options->bv.bitblastMode == options::BitblastMode::LAZY
302
        && d_options->bv.bitblastModeWasSetByUser)
303
    {
304
      std::string sat_solver;
305
      if (m == options::SatSolverMode::CADICAL)
306
      {
307
        sat_solver = "CaDiCaL";
308
      }
309
      else if (m == options::SatSolverMode::KISSAT)
310
      {
311
        sat_solver = "Kissat";
312
      }
313
      else
314
      {
315
        Assert(m == options::SatSolverMode::CRYPTOMINISAT);
316
        sat_solver = "CryptoMiniSat";
317
      }
318
      throw OptionException(sat_solver
319
                            + " does not support lazy bit-blasting.\n"
320
                            + "Try --bv-sat-solver=minisat");
321
    }
322
    if (!d_options->bv.bitvectorToBoolWasSetByUser)
323
    {
324
      d_options->bv.bitvectorToBool = true;
325
    }
326
  }
327
16
}
328
329
void OptionsHandler::setBitblastAig(const std::string& flag, bool arg)
330
{
331
  if(arg) {
332
    if (d_options->bv.bitblastModeWasSetByUser) {
333
      if (d_options->bv.bitblastMode != options::BitblastMode::EAGER)
334
      {
335
        throw OptionException("bitblast-aig must be used with eager bitblaster");
336
      }
337
    } else {
338
      d_options->bv.bitblastMode = options::BitblastMode::EAGER;
339
    }
340
  }
341
}
342
343
void OptionsHandler::setDefaultExprDepth(const std::string& flag, int depth)
344
{
345
  Debug.getStream() << expr::ExprSetDepth(depth);
346
  Trace.getStream() << expr::ExprSetDepth(depth);
347
  CVC5Message.getStream() << expr::ExprSetDepth(depth);
348
  Warning.getStream() << expr::ExprSetDepth(depth);
349
}
350
351
3
void OptionsHandler::setDefaultDagThresh(const std::string& flag, int dag)
352
{
353
3
  Debug.getStream() << expr::ExprDag(dag);
354
3
  Trace.getStream() << expr::ExprDag(dag);
355
3
  CVC5Message.getStream() << expr::ExprDag(dag);
356
3
  Warning.getStream() << expr::ExprDag(dag);
357
3
}
358
359
60016
static void print_config(const char* str, std::string config)
360
{
361
120032
  std::string s(str);
362
60016
  unsigned sz = 14;
363
60016
  if (s.size() < sz) s.resize(sz, ' ');
364
60016
  std::cout << s << ": " << config << std::endl;
365
60016
}
366
367
51832
static void print_config_cond(const char* str, bool cond = false)
368
{
369
51832
  print_config(str, cond ? "yes" : "no");
370
51832
}
371
372
2728
void OptionsHandler::showConfiguration(const std::string& flag)
373
{
374
2728
  std::cout << Configuration::about() << std::endl;
375
376
2728
  print_config("version", Configuration::getVersionString());
377
2728
  if (Configuration::isGitBuild())
378
  {
379
2728
    print_config("scm", Configuration::getGitInfo());
380
  }
381
  else
382
  {
383
    print_config_cond("scm", false);
384
  }
385
386
2728
  std::cout << std::endl;
387
388
2728
  std::stringstream ss;
389
2728
  ss << Configuration::getVersionString();
390
2728
  print_config("library", ss.str());
391
392
2728
  std::cout << std::endl;
393
394
2728
  print_config_cond("debug code", Configuration::isDebugBuild());
395
2728
  print_config_cond("statistics", Configuration::isStatisticsBuild());
396
2728
  print_config_cond("tracing", Configuration::isTracingBuild());
397
2728
  print_config_cond("dumping", Configuration::isDumpingBuild());
398
2728
  print_config_cond("muzzled", Configuration::isMuzzledBuild());
399
2728
  print_config_cond("assertions", Configuration::isAssertionBuild());
400
2728
  print_config_cond("coverage", Configuration::isCoverageBuild());
401
2728
  print_config_cond("profiling", Configuration::isProfilingBuild());
402
2728
  print_config_cond("asan", Configuration::isAsanBuild());
403
2728
  print_config_cond("ubsan", Configuration::isUbsanBuild());
404
2728
  print_config_cond("tsan", Configuration::isTsanBuild());
405
2728
  print_config_cond("competition", Configuration::isCompetitionBuild());
406
407
2728
  std::cout << std::endl;
408
409
2728
  print_config_cond("cln", Configuration::isBuiltWithCln());
410
2728
  print_config_cond("glpk", Configuration::isBuiltWithGlpk());
411
2728
  print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
412
2728
  print_config_cond("gmp", Configuration::isBuiltWithGmp());
413
2728
  print_config_cond("kissat", Configuration::isBuiltWithKissat());
414
2728
  print_config_cond("poly", Configuration::isBuiltWithPoly());
415
2728
  print_config_cond("editline", Configuration::isBuiltWithEditline());
416
417
2728
  std::exit(0);
418
}
419
420
void OptionsHandler::showCopyright(const std::string& flag)
421
{
422
  std::cout << Configuration::copyright() << std::endl;
423
  std::exit(0);
424
}
425
426
1
void OptionsHandler::showVersion(const std::string& flag)
427
{
428
1
  d_options->base.out << Configuration::about() << std::endl;
429
1
  std::exit(0);
430
}
431
432
void OptionsHandler::showDebugTags(const std::string& flag)
433
{
434
  if (!Configuration::isDebugBuild())
435
  {
436
    throw OptionException("debug tags not available in non-debug builds");
437
  }
438
  else if (!Configuration::isTracingBuild())
439
  {
440
    throw OptionException("debug tags not available in non-tracing builds");
441
  }
442
  printTags(Configuration::getDebugTags());
443
  std::exit(0);
444
}
445
446
void OptionsHandler::showTraceTags(const std::string& flag)
447
{
448
  if (!Configuration::isTracingBuild())
449
  {
450
    throw OptionException("trace tags not available in non-tracing build");
451
  }
452
  printTags(Configuration::getTraceTags());
453
  std::exit(0);
454
}
455
456
}  // namespace options
457
31137
}  // namespace cvc5