GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/options/options_handler.cpp Lines: 134 296 45.3 %
Date: 2021-09-29 Branches: 140 582 24.1 %

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 <ostream>
20
#include <string>
21
22
#include "base/check.h"
23
#include "base/configuration.h"
24
#include "base/configuration_private.h"
25
#include "base/cvc5config.h"
26
#include "base/exception.h"
27
#include "base/modal_exception.h"
28
#include "base/output.h"
29
#include "expr/expr_iomanip.h"
30
#include "lib/strtok_r.h"
31
#include "options/base_options.h"
32
#include "options/bv_options.h"
33
#include "options/decision_options.h"
34
#include "options/didyoumean.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 "smt/dump.h"
42
43
namespace cvc5 {
44
namespace options {
45
46
// helper functions
47
namespace {
48
49
void throwLazyBBUnsupported(options::SatSolverMode m)
50
{
51
  std::string sat_solver;
52
  if (m == options::SatSolverMode::CADICAL)
53
  {
54
    sat_solver = "CaDiCaL";
55
  }
56
  else if (m == options::SatSolverMode::KISSAT)
57
  {
58
    sat_solver = "Kissat";
59
  }
60
  else
61
  {
62
    Assert(m == options::SatSolverMode::CRYPTOMINISAT);
63
    sat_solver = "CryptoMiniSat";
64
  }
65
  std::string indent(25, ' ');
66
  throw OptionException(sat_solver + " does not support lazy bit-blasting.\n"
67
                        + indent + "Try --bv-sat-solver=minisat");
68
}
69
70
}  // namespace
71
72
18087
OptionsHandler::OptionsHandler(Options* options) : d_options(options) { }
73
74
uint64_t OptionsHandler::limitHandler(const std::string& option,
75
                                      const std::string& flag,
76
                                      const std::string& optarg)
77
{
78
  uint64_t ms;
79
  std::istringstream convert(optarg);
80
  if (!(convert >> ms))
81
  {
82
    throw OptionException("option `" + option
83
                          + "` requires a number as an argument");
84
  }
85
  return ms;
86
}
87
88
void OptionsHandler::setResourceWeight(const std::string& option,
89
                                       const std::string& flag,
90
                                       const std::string& optarg)
91
{
92
  d_options->base.resourceWeightHolder.emplace_back(optarg);
93
}
94
95
// theory/quantifiers/options_handlers.h
96
97
1
void OptionsHandler::checkInstWhenMode(const std::string& option,
98
                                       const std::string& flag,
99
                                       InstWhenMode mode)
100
{
101
1
  if (mode == InstWhenMode::PRE_FULL)
102
  {
103
    throw OptionException(std::string("Mode pre-full for ") + option
104
                          + " is not supported in this release.");
105
  }
106
1
}
107
108
// theory/bv/options_handlers.h
109
void OptionsHandler::abcEnabledBuild(const std::string& option,
110
                                     const std::string& flag,
111
                                     bool value)
112
{
113
#ifndef CVC5_USE_ABC
114
  if(value) {
115
    std::stringstream ss;
116
    ss << "option `" << option
117
       << "' requires an abc-enabled build of cvc5; this binary was not built "
118
          "with abc support";
119
    throw OptionException(ss.str());
120
  }
121
#endif /* CVC5_USE_ABC */
122
}
123
124
void OptionsHandler::abcEnabledBuild(const std::string& option,
125
                                     const std::string& flag,
126
                                     const std::string& value)
127
{
128
#ifndef CVC5_USE_ABC
129
  if(!value.empty()) {
130
    std::stringstream ss;
131
    ss << "option `" << option
132
       << "' requires an abc-enabled build of cvc5; this binary was not built "
133
          "with abc support";
134
    throw OptionException(ss.str());
135
  }
136
#endif /* CVC5_USE_ABC */
137
}
138
139
8
void OptionsHandler::checkBvSatSolver(const std::string& option,
140
                                      const std::string& flag,
141
                                      SatSolverMode m)
142
{
143
8
  if (m == SatSolverMode::CRYPTOMINISAT
144
8
      && !Configuration::isBuiltWithCryptominisat())
145
  {
146
    std::stringstream ss;
147
    ss << "option `" << option
148
       << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
149
          "with CryptoMiniSat support";
150
    throw OptionException(ss.str());
151
  }
152
153
8
  if (m == SatSolverMode::KISSAT && !Configuration::isBuiltWithKissat())
154
  {
155
    std::stringstream ss;
156
    ss << "option `" << option
157
       << "' requires a Kissat build of cvc5; this binary was not built with "
158
          "Kissat support";
159
    throw OptionException(ss.str());
160
  }
161
162
8
  if (d_options->bv.bvSolver != options::BVSolver::BITBLAST
163
      && (m == SatSolverMode::CRYPTOMINISAT || m == SatSolverMode::CADICAL
164
          || m == SatSolverMode::KISSAT))
165
  {
166
    if (d_options->bv.bitblastMode == options::BitblastMode::LAZY
167
        && d_options->bv.bitblastModeWasSetByUser)
168
    {
169
      throwLazyBBUnsupported(m);
170
    }
171
    options::bv::setDefaultBitvectorToBool(*d_options, true);
172
  }
173
8
}
174
175
void OptionsHandler::checkBitblastMode(const std::string& option,
176
                                       const std::string& flag,
177
                                       BitblastMode m)
178
{
179
  if (m == options::BitblastMode::LAZY)
180
  {
181
    options::bv::setDefaultBitvectorPropagate(*d_options, true);
182
    options::bv::setDefaultBitvectorEqualitySolver(*d_options, true);
183
    options::bv::setDefaultBitvectorInequalitySolver(*d_options, true);
184
    options::bv::setDefaultBitvectorAlgebraicSolver(*d_options, true);
185
    if (d_options->bv.bvSatSolver != options::SatSolverMode::MINISAT)
186
    {
187
      throwLazyBBUnsupported(d_options->bv.bvSatSolver);
188
    }
189
  }
190
  else if (m == BitblastMode::EAGER)
191
  {
192
    options::bv::setDefaultBitvectorToBool(*d_options, true);
193
  }
194
}
195
196
void OptionsHandler::setBitblastAig(const std::string& option,
197
                                    const std::string& flag,
198
                                    bool arg)
199
{
200
  if(arg) {
201
    if (d_options->bv.bitblastModeWasSetByUser) {
202
      if (d_options->bv.bitblastMode != options::BitblastMode::EAGER)
203
      {
204
        throw OptionException("bitblast-aig must be used with eager bitblaster");
205
      }
206
    } else {
207
      options::BitblastMode mode = stringToBitblastMode("eager");
208
      d_options->bv.bitblastMode = mode;
209
    }
210
  }
211
}
212
213
28
void OptionsHandler::setProduceAssertions(const std::string& option,
214
                                          const std::string& flag,
215
                                          bool value)
216
{
217
28
  d_options->smt.produceAssertions = value;
218
28
  d_options->smt.interactiveMode = value;
219
28
}
220
221
4
void OptionsHandler::setStats(const std::string& option,
222
                              const std::string& flag,
223
                              bool value)
224
{
225
#ifndef CVC5_STATISTICS_ON
226
  if (value)
227
  {
228
    std::stringstream ss;
229
    ss << "option `" << flag
230
       << "' requires a statistics-enabled build of cvc5; this binary was not "
231
          "built with statistics support";
232
    throw OptionException(ss.str());
233
  }
234
#endif /* CVC5_STATISTICS_ON */
235
8
  std::string opt = option;
236
4
  if (option.substr(0, 2) == "--")
237
  {
238
    opt = opt.substr(2);
239
  }
240
4
  if (value)
241
  {
242
2
    if (opt == options::base::statisticsAll__name)
243
    {
244
1
      d_options->base.statistics = true;
245
    }
246
1
    else if (opt == options::base::statisticsEveryQuery__name)
247
    {
248
      d_options->base.statistics = true;
249
    }
250
1
    else if (opt == options::base::statisticsExpert__name)
251
    {
252
1
      d_options->base.statistics = true;
253
    }
254
  }
255
  else
256
  {
257
2
    if (opt == options::base::statistics__name)
258
    {
259
2
      d_options->base.statisticsAll = false;
260
2
      d_options->base.statisticsEveryQuery = false;
261
2
      d_options->base.statisticsExpert = false;
262
    }
263
  }
264
4
}
265
266
void OptionsHandler::threadN(const std::string& option, const std::string& flag)
267
{
268
  throw OptionException(flag + " is not a real option by itself.  Use e.g. --thread0=\"--random-seed=10 --random-freq=0.02\" --thread1=\"--random-seed=20 --random-freq=0.05\"");
269
}
270
271
// expr/options_handlers.h
272
void OptionsHandler::setDefaultExprDepth(const std::string& option,
273
                                         const std::string& flag,
274
                                         int depth)
275
{
276
  Debug.getStream() << expr::ExprSetDepth(depth);
277
  Trace.getStream() << expr::ExprSetDepth(depth);
278
  Notice.getStream() << expr::ExprSetDepth(depth);
279
  Chat.getStream() << expr::ExprSetDepth(depth);
280
  CVC5Message.getStream() << expr::ExprSetDepth(depth);
281
  Warning.getStream() << expr::ExprSetDepth(depth);
282
}
283
284
2
void OptionsHandler::setDefaultDagThresh(const std::string& option,
285
                                         const std::string& flag,
286
                                         int dag)
287
{
288
2
  Debug.getStream() << expr::ExprDag(dag);
289
2
  Trace.getStream() << expr::ExprDag(dag);
290
2
  Notice.getStream() << expr::ExprDag(dag);
291
2
  Chat.getStream() << expr::ExprDag(dag);
292
2
  CVC5Message.getStream() << expr::ExprDag(dag);
293
2
  Warning.getStream() << expr::ExprDag(dag);
294
2
  Dump.getStream() << expr::ExprDag(dag);
295
2
}
296
297
// main/options_handlers.h
298
299
60421
static void print_config (const char * str, std::string config) {
300
120842
  std::string s(str);
301
60421
  unsigned sz = 14;
302
60421
  if (s.size() < sz) s.resize(sz, ' ');
303
60421
  std::cout << s << ": " << config << std::endl;
304
60421
}
305
306
52540
static void print_config_cond (const char * str, bool cond = false) {
307
52540
  print_config(str, cond ? "yes" : "no");
308
52540
}
309
310
void OptionsHandler::copyright(const std::string& option,
311
                               const std::string& flag)
312
{
313
  std::cout << Configuration::copyright() << std::endl;
314
  exit(0);
315
}
316
317
2627
void OptionsHandler::showConfiguration(const std::string& option,
318
                                       const std::string& flag)
319
{
320
2627
  std::cout << Configuration::about() << std::endl;
321
322
2627
  print_config ("version", Configuration::getVersionString());
323
324
2627
  if(Configuration::isGitBuild()) {
325
2627
    const char* branchName = Configuration::getGitBranchName();
326
2627
    if(*branchName == '\0')  { branchName = "-"; }
327
5254
    std::stringstream ss;
328
    ss << "git ["
329
       << branchName << " "
330
5254
       << std::string(Configuration::getGitCommit()).substr(0, 8)
331
2627
       << (Configuration::hasGitModifications() ? " (with modifications)" : "")
332
7881
       << "]";
333
2627
    print_config("scm", ss.str());
334
  } else {
335
    print_config_cond("scm", false);
336
  }
337
338
2627
  std::cout << std::endl;
339
340
2627
  std::stringstream ss;
341
2627
  ss << Configuration::getVersionMajor() << "."
342
2627
     << Configuration::getVersionMinor() << "."
343
2627
     << Configuration::getVersionRelease();
344
2627
  print_config("library", ss.str());
345
346
2627
  std::cout << std::endl;
347
348
2627
  print_config_cond("debug code", Configuration::isDebugBuild());
349
2627
  print_config_cond("statistics", Configuration::isStatisticsBuild());
350
2627
  print_config_cond("tracing", Configuration::isTracingBuild());
351
2627
  print_config_cond("dumping", Configuration::isDumpingBuild());
352
2627
  print_config_cond("muzzled", Configuration::isMuzzledBuild());
353
2627
  print_config_cond("assertions", Configuration::isAssertionBuild());
354
2627
  print_config_cond("coverage", Configuration::isCoverageBuild());
355
2627
  print_config_cond("profiling", Configuration::isProfilingBuild());
356
2627
  print_config_cond("asan", Configuration::isAsanBuild());
357
2627
  print_config_cond("ubsan", Configuration::isUbsanBuild());
358
2627
  print_config_cond("tsan", Configuration::isTsanBuild());
359
2627
  print_config_cond("competition", Configuration::isCompetitionBuild());
360
361
2627
  std::cout << std::endl;
362
363
2627
  print_config_cond("abc", Configuration::isBuiltWithAbc());
364
2627
  print_config_cond("cln", Configuration::isBuiltWithCln());
365
2627
  print_config_cond("glpk", Configuration::isBuiltWithGlpk());
366
2627
  print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
367
2627
  print_config_cond("gmp", Configuration::isBuiltWithGmp());
368
2627
  print_config_cond("kissat", Configuration::isBuiltWithKissat());
369
2627
  print_config_cond("poly", Configuration::isBuiltWithPoly());
370
2627
  print_config_cond("editline", Configuration::isBuiltWithEditline());
371
372
2627
  exit(0);
373
}
374
375
static void printTags(const std::vector<std::string>& tags)
376
{
377
  std::cout << "available tags:";
378
  for (const auto& t : tags)
379
  {
380
    std::cout << "  " << t << std::endl;
381
  }
382
  std::cout << std::endl;
383
}
384
385
void OptionsHandler::showDebugTags(const std::string& option,
386
                                   const std::string& flag)
387
{
388
  if (!Configuration::isDebugBuild())
389
  {
390
    throw OptionException("debug tags not available in non-debug builds");
391
  }
392
  else if (!Configuration::isTracingBuild())
393
  {
394
    throw OptionException("debug tags not available in non-tracing builds");
395
  }
396
  printTags(Configuration::getDebugTags());
397
  std::exit(0);
398
}
399
400
void OptionsHandler::showTraceTags(const std::string& option,
401
                                   const std::string& flag)
402
{
403
  if (!Configuration::isTracingBuild())
404
  {
405
    throw OptionException("trace tags not available in non-tracing build");
406
  }
407
  printTags(Configuration::getTraceTags());
408
  std::exit(0);
409
}
410
411
static std::string suggestTags(const std::vector<std::string>& validTags,
412
                               std::string inputTag,
413
                               const std::vector<std::string>& additionalTags)
414
{
415
  DidYouMean didYouMean;
416
  didYouMean.addWords(validTags);
417
  didYouMean.addWords(additionalTags);
418
  return didYouMean.getMatchAsString(inputTag);
419
}
420
421
void OptionsHandler::enableTraceTag(const std::string& option,
422
                                    const std::string& flag,
423
                                    const std::string& optarg)
424
{
425
  if(!Configuration::isTracingBuild())
426
  {
427
    throw OptionException("trace tags not available in non-tracing builds");
428
  }
429
  else if (!Configuration::isTraceTag(optarg))
430
  {
431
    if (optarg == "help")
432
    {
433
      printTags(Configuration::getTraceTags());
434
      std::exit(0);
435
    }
436
437
    throw OptionException(
438
        std::string("trace tag ") + optarg + std::string(" not available.")
439
        + suggestTags(Configuration::getTraceTags(), optarg, {}));
440
  }
441
  Trace.on(optarg);
442
}
443
444
void OptionsHandler::enableDebugTag(const std::string& option,
445
                                    const std::string& flag,
446
                                    const std::string& optarg)
447
{
448
  if (!Configuration::isDebugBuild())
449
  {
450
    throw OptionException("debug tags not available in non-debug builds");
451
  }
452
  else if (!Configuration::isTracingBuild())
453
  {
454
    throw OptionException("debug tags not available in non-tracing builds");
455
  }
456
457
  if (!Configuration::isDebugTag(optarg) && !Configuration::isTraceTag(optarg))
458
  {
459
    if (optarg == "help")
460
    {
461
      printTags(Configuration::getDebugTags());
462
      std::exit(0);
463
    }
464
465
    throw OptionException(std::string("debug tag ") + optarg
466
                          + std::string(" not available.")
467
                          + suggestTags(Configuration::getDebugTags(),
468
                                        optarg,
469
                                        Configuration::getTraceTags()));
470
  }
471
  Debug.on(optarg);
472
  Trace.on(optarg);
473
}
474
475
5
void OptionsHandler::enableOutputTag(const std::string& option,
476
                                     const std::string& flag,
477
                                     const std::string& optarg)
478
{
479
10
  d_options->base.outputTagHolder.set(
480
5
      static_cast<size_t>(stringToOutputTag(optarg)));
481
5
}
482
483
8093
Language OptionsHandler::stringToLanguage(const std::string& option,
484
                                          const std::string& flag,
485
                                          const std::string& optarg)
486
{
487
8093
  if(optarg == "help") {
488
    d_options->base.languageHelp = true;
489
    return Language::LANG_AUTO;
490
  }
491
492
  try {
493
8093
    return language::toLanguage(optarg);
494
  } catch(OptionException& oe) {
495
    throw OptionException("Error in " + option + ": " + oe.getMessage()
496
                          + "\nTry --lang help");
497
  }
498
499
  Unreachable();
500
}
501
502
3911
void OptionsHandler::applyOutputLanguage(const std::string& option,
503
                                         const std::string& flag,
504
                                         Language lang)
505
{
506
3911
  d_options->base.out << language::SetLanguage(lang);
507
3911
}
508
509
4182
void OptionsHandler::languageIsNotAST(const std::string& option,
510
                                      const std::string& flag,
511
                                      Language lang)
512
{
513
4182
  if (lang == Language::LANG_AST)
514
  {
515
    throw OptionException("Language LANG_AST is not allowed for " + flag);
516
  }
517
4182
}
518
519
void OptionsHandler::setDumpStream(const std::string& option,
520
                                   const std::string& flag,
521
                                   const ManagedOut& mo)
522
{
523
#ifdef CVC5_DUMPING
524
  Dump.setStream(mo);
525
#else  /* CVC5_DUMPING */
526
  throw OptionException(
527
      "The dumping feature was disabled in this build of cvc5.");
528
#endif /* CVC5_DUMPING */
529
}
530
void OptionsHandler::setErrStream(const std::string& option,
531
                                  const std::string& flag,
532
                                  const ManagedErr& me)
533
{
534
  Debug.setStream(me);
535
  Warning.setStream(me);
536
  CVC5Message.setStream(me);
537
  Notice.setStream(me);
538
  Chat.setStream(me);
539
  Trace.setStream(me);
540
}
541
void OptionsHandler::setInStream(const std::string& option,
542
                                 const std::string& flag,
543
                                 const ManagedIn& mi)
544
{
545
}
546
void OptionsHandler::setOutStream(const std::string& option,
547
                                  const std::string& flag,
548
                                  const ManagedOut& mo)
549
{
550
}
551
552
/* options/base_options_handlers.h */
553
174
void OptionsHandler::setVerbosity(const std::string& option,
554
                                  const std::string& flag,
555
                                  int value)
556
{
557
174
  if(Configuration::isMuzzledBuild()) {
558
    DebugChannel.setStream(&cvc5::null_os);
559
    TraceChannel.setStream(&cvc5::null_os);
560
    NoticeChannel.setStream(&cvc5::null_os);
561
    ChatChannel.setStream(&cvc5::null_os);
562
    MessageChannel.setStream(&cvc5::null_os);
563
    WarningChannel.setStream(&cvc5::null_os);
564
  } else {
565
174
    if(value < 2) {
566
172
      ChatChannel.setStream(&cvc5::null_os);
567
    } else {
568
2
      ChatChannel.setStream(&std::cout);
569
    }
570
174
    if(value < 1) {
571
169
      NoticeChannel.setStream(&cvc5::null_os);
572
    } else {
573
5
      NoticeChannel.setStream(&std::cout);
574
    }
575
174
    if(value < 0) {
576
165
      MessageChannel.setStream(&cvc5::null_os);
577
165
      WarningChannel.setStream(&cvc5::null_os);
578
    } else {
579
9
      MessageChannel.setStream(&std::cout);
580
9
      WarningChannel.setStream(&std::cerr);
581
    }
582
  }
583
174
}
584
585
3
void OptionsHandler::increaseVerbosity(const std::string& option,
586
                                       const std::string& flag)
587
{
588
3
  d_options->base.verbosity += 1;
589
3
  setVerbosity(option, flag, d_options->base.verbosity);
590
3
}
591
592
165
void OptionsHandler::decreaseVerbosity(const std::string& option,
593
                                       const std::string& flag)
594
{
595
165
  d_options->base.verbosity -= 1;
596
165
  setVerbosity(option, flag, d_options->base.verbosity);
597
165
}
598
599
2
void OptionsHandler::setDumpMode(const std::string& option,
600
                                 const std::string& flag,
601
                                 const std::string& optarg)
602
{
603
2
  Dump.setDumpFromString(optarg);
604
1
}
605
606
17
void OptionsHandler::setPrintSuccess(const std::string& option,
607
                                     const std::string& flag,
608
                                     bool value)
609
{
610
17
  Debug.getStream() << Command::printsuccess(value);
611
17
  Trace.getStream() << Command::printsuccess(value);
612
17
  Notice.getStream() << Command::printsuccess(value);
613
17
  Chat.getStream() << Command::printsuccess(value);
614
17
  CVC5Message.getStream() << Command::printsuccess(value);
615
17
  Warning.getStream() << Command::printsuccess(value);
616
17
  *d_options->base.out << Command::printsuccess(value);
617
17
}
618
619
}  // namespace options
620
22746
}  // namespace cvc5