GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 584 708 82.5 %
Date: 2021-05-21 Branches: 1808 3650 49.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Andres Noetzli, Haniel Barbosa
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
 * Implementation of setting default options.
14
 */
15
16
#include "smt/set_defaults.h"
17
18
#include <sstream>
19
20
#include "base/output.h"
21
#include "options/arith_options.h"
22
#include "options/arrays_options.h"
23
#include "options/base_options.h"
24
#include "options/booleans_options.h"
25
#include "options/bv_options.h"
26
#include "options/datatypes_options.h"
27
#include "options/decision_options.h"
28
#include "options/language.h"
29
#include "options/main_options.h"
30
#include "options/open_ostream.h"
31
#include "options/option_exception.h"
32
#include "options/printer_options.h"
33
#include "options/proof_options.h"
34
#include "options/prop_options.h"
35
#include "options/quantifiers_options.h"
36
#include "options/sep_options.h"
37
#include "options/set_language.h"
38
#include "options/smt_options.h"
39
#include "options/strings_options.h"
40
#include "options/theory_options.h"
41
#include "options/uf_options.h"
42
#include "smt/logic_exception.h"
43
#include "theory/theory.h"
44
45
using namespace cvc5::theory;
46
47
namespace cvc5 {
48
namespace smt {
49
50
8954
void setDefaults(LogicInfo& logic, bool isInternalSubsolver)
51
{
52
8954
  Options& opts = Options::current();
53
  // implied options
54
21953
  if (options::debugCheckModels())
55
  {
56
52478
    opts.set(options::checkModels, true);
57
  }
58
311366
  if (options::checkModels() || options::dumpModels())
59
  {
60
1247
    opts.set(options::produceModels, true);
61
  }
62
8954
  if (options::checkModels())
63
  {
64
18832
    opts.set(options::produceAssignments, true);
65
  }
66
  // unsat cores and proofs shenanigans
67
8954
  if (options::dumpUnsatCoresFull())
68
  {
69
302710
    opts.set(options::dumpUnsatCores, true);
70
  }
71
49390
  if (options::checkUnsatCores() || options::dumpUnsatCores()
72
8003
      || options::unsatAssumptions()
73
16946
      || options::unsatCoresMode() != options::UnsatCoresMode::OFF)
74
  {
75
2000
    opts.set(options::unsatCores, true);
76
  }
77
17908
  if (options::unsatCores()
78
8954
      && options::unsatCoresMode() == options::UnsatCoresMode::OFF)
79
  {
80
962
    if (opts.wasSetByUser(options::unsatCoresMode))
81
    {
82
      Notice()
83
          << "Overriding OFF unsat-core mode since cores were requested.\n";
84
    }
85
962
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::ASSUMPTIONS);
86
  }
87
88
337655
  if (options::checkProofs() || options::dumpProofs())
89
  {
90
1126
    opts.set(options::produceProofs, true);
91
  }
92
93
17908
  if (options::produceProofs()
94
8954
      && options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF)
95
  {
96
1174
    if (opts.wasSetByUser(options::unsatCoresMode))
97
    {
98
      Notice() << "Forcing full-proof mode for unsat cores mode since proofs "
99
                  "were requested.\n";
100
    }
101
    // enable unsat cores, because they are available as a consequence of proofs
102
1174
    opts.set(options::unsatCores, true);
103
1174
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::FULL_PROOF);
104
  }
105
106
  // set proofs on if not yet set
107
8954
  if (options::unsatCores() && !options::produceProofs())
108
  {
109
1913
    if (opts.wasSetByUser(options::produceProofs))
110
    {
111
2
      Notice()
112
          << "Forcing proof production since new unsat cores were requested.\n";
113
    }
114
1913
    opts.set(options::produceProofs, true);
115
  }
116
117
  // if unsat cores are disabled, then unsat cores mode should be OFF
118
8954
  Assert(options::unsatCores()
119
         == (options::unsatCoresMode() != options::UnsatCoresMode::OFF));
120
121
17908
  if (opts.wasSetByUser(options::bitvectorAigSimplifications))
122
  {
123
    Notice() << "SmtEngine: setting bitvectorAig" << std::endl;
124
1937
    opts.set(options::bitvectorAig, true);
125
  }
126
17908
  if (opts.wasSetByUser(options::bitvectorAlgebraicBudget))
127
  {
128
    Notice() << "SmtEngine: setting bitvectorAlgebraicSolver" << std::endl;
129
8912
    opts.set(options::bitvectorAlgebraicSolver, true);
130
  }
131
132
8954
  bool isSygus = language::isInputLangSygus(options::inputLanguage());
133
8954
  bool usesSygus = isSygus;
134
135
8954
  if (options::bitblastMode() == options::BitblastMode::EAGER)
136
  {
137
64
    if (options::produceModels()
138
32
        && (logic.isTheoryEnabled(THEORY_ARRAYS)
139
7
            || logic.isTheoryEnabled(THEORY_UF)))
140
    {
141
      if (opts.wasSetByUser(options::bitblastMode)
142
          || opts.wasSetByUser(options::produceModels))
143
      {
144
        throw OptionException(std::string(
145
            "Eager bit-blasting currently does not support model generation "
146
            "for the combination of bit-vectors with arrays or uinterpreted "
147
            "functions. Try --bitblast=lazy"));
148
      }
149
      Notice() << "SmtEngine: setting bit-blast mode to lazy to support model"
150
               << "generation" << std::endl;
151
      opts.set(options::bitblastMode, options::BitblastMode::LAZY);
152
    }
153
32
    else if (!options::incrementalSolving())
154
    {
155
26
      opts.set(options::ackermann, true);
156
    }
157
158
32
    if (options::incrementalSolving() && !logic.isPure(THEORY_BV))
159
    {
160
      throw OptionException(
161
          "Incremental eager bit-blasting is currently "
162
          "only supported for QF_BV. Try --bitblast=lazy.");
163
    }
164
  }
165
166
  /* Only BVSolver::LAZY natively supports int2bv and nat2bv, for other solvers
167
   * we need to eagerly eliminate the operators. */
168
56866
  if (options::bvSolver() == options::BVSolver::SIMPLE
169
8954
      || options::bvSolver() == options::BVSolver::BITBLAST)
170
  {
171
69
    opts.set(options::bvLazyReduceExtf, false);
172
997
    opts.set(options::bvLazyRewriteExtf, false);
173
  }
174
175
  /* Disable bit-level propagation by default for the BITBLAST solver. */
176
8954
  if (options::bvSolver() == options::BVSolver::BITBLAST)
177
  {
178
8912
    opts.set(options::bitvectorPropagate, false);
179
  }
180
181
8954
  if (options::solveIntAsBV() > 0)
182
  {
183
    // not compatible with incremental
184
8
    if (options::incrementalSolving())
185
    {
186
      throw OptionException(
187
          "solving integers as bitvectors is currently not supported "
188
          "when solving incrementally.");
189
    }
190
    // Int to BV currently always eliminates arithmetic completely (or otherwise
191
    // fails). Thus, it is safe to eliminate arithmetic. Also, bit-vectors
192
    // are required.
193
8
    logic = logic.getUnlockedCopy();
194
8
    logic.enableTheory(THEORY_BV);
195
8
    logic.disableTheory(THEORY_ARITH);
196
8
    logic.lock();
197
  }
198
199
8954
  if (options::solveBVAsInt() != options::SolveBVAsIntMode::OFF)
200
  {
201
125
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
202
    {
203
      throw OptionException(
204
          "solving bitvectors as integers is incompatible with --bool-to-bv.");
205
    }
206
125
    if (options::BVAndIntegerGranularity() > 8)
207
    {
208
      /**
209
       * The granularity sets the size of the ITE in each element
210
       * of the sum that is generated for bitwise operators.
211
       * The size of the ITE is 2^{2*granularity}.
212
       * Since we don't want to introduce ITEs with unbounded size,
213
       * we bound the granularity.
214
       */
215
      throw OptionException("solve-bv-as-int accepts values from 0 to 8.");
216
    }
217
125
    if (logic.isTheoryEnabled(THEORY_BV))
218
    {
219
121
      logic = logic.getUnlockedCopy();
220
121
      logic.enableTheory(THEORY_ARITH);
221
121
      logic.arithNonLinear();
222
121
      logic.lock();
223
    }
224
  }
225
226
  // set options about ackermannization
227
17958
  if (options::ackermann() && options::produceModels()
228
8967
      && (logic.isTheoryEnabled(THEORY_ARRAYS)
229
9
          || logic.isTheoryEnabled(THEORY_UF)))
230
  {
231
4
    if (opts.wasSetByUser(options::produceModels))
232
    {
233
      throw OptionException(std::string(
234
          "Ackermannization currently does not support model generation."));
235
    }
236
4
    Notice() << "SmtEngine: turn off ackermannization to support model"
237
             << "generation" << std::endl;
238
4
    opts.set(options::ackermann, false);
239
  }
240
241
8954
  if (options::ackermann())
242
  {
243
46
    if (options::incrementalSolving())
244
    {
245
      throw OptionException(
246
          "Incremental Ackermannization is currently not supported.");
247
    }
248
249
46
    if (logic.isQuantified())
250
    {
251
      throw LogicException("Cannot use Ackermannization on quantified formula");
252
    }
253
254
46
    if (logic.isTheoryEnabled(THEORY_UF))
255
    {
256
24
      logic = logic.getUnlockedCopy();
257
24
      logic.disableTheory(THEORY_UF);
258
24
      logic.lock();
259
    }
260
46
    if (logic.isTheoryEnabled(THEORY_ARRAYS))
261
    {
262
6
      logic = logic.getUnlockedCopy();
263
6
      logic.disableTheory(THEORY_ARRAYS);
264
6
      logic.lock();
265
    }
266
  }
267
268
  // --ite-simp is an experimental option designed for QF_LIA/nec. This
269
  // technique is experimental. This benchmark set also requires removing ITEs
270
  // during preprocessing, before repeating simplification. Hence, we enable
271
  // this by default.
272
8954
  if (options::doITESimp())
273
  {
274
2
    if (!opts.wasSetByUser(options::earlyIteRemoval))
275
    {
276
2
      opts.set(options::earlyIteRemoval, true);
277
    }
278
  }
279
280
  // Set default options associated with strings-exp. We also set these options
281
  // if we are using eager string preprocessing, which may introduce quantified
282
  // formulas at preprocess time.
283
8954
  if (!logic.hasEverything() && logic.isTheoryEnabled(THEORY_STRINGS))
284
  {
285
    // If the user explicitly set a logic that includes strings, but is not
286
    // the generic "ALL" logic, then enable stringsExp.
287
131872
    opts.set(options::stringExp, true);
288
  }
289
8954
  if (options::stringExp() || !options::stringLazyPreproc())
290
  {
291
    // We require quantifiers since extended functions reduce using them.
292
1030
    if (!logic.isQuantified())
293
    {
294
484
      logic = logic.getUnlockedCopy();
295
484
      logic.enableQuantifiers();
296
484
      logic.lock();
297
968
      Trace("smt") << "turning on quantifier logic, for strings-exp"
298
484
                   << std::endl;
299
    }
300
    // We require bounded quantifier handling.
301
47960
    if (!opts.wasSetByUser(options::fmfBound))
302
    {
303
1028
      opts.set(options::fmfBound, true);
304
1028
      Trace("smt") << "turning on fmf-bound-int, for strings-exp" << std::endl;
305
    }
306
    // Note we allow E-matching by default to support combinations of sequences
307
    // and quantifiers.
308
  }
309
  // whether we must disable proofs
310
8954
  bool disableProofs = false;
311
8954
  if (options::globalNegate())
312
  {
313
    // When global negate answers "unsat", it is not due to showing a set of
314
    // formulas is unsat. Thus, proofs do not apply.
315
6
    disableProofs = true;
316
  }
317
318
  // new unsat core specific restrictions for proofs
319
17908
  if (options::unsatCores()
320
8954
      && options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF)
321
  {
322
    // no fine-graininess
323
1903
    if (!opts.wasSetByUser(options::proofGranularityMode))
324
    {
325
1903
      opts.set(options::proofGranularityMode, options::ProofGranularityMode::OFF);
326
    }
327
  }
328
329
17935
  if (options::arraysExp())
330
  {
331
12
    if (!logic.isQuantified())
332
    {
333
4
      logic = logic.getUnlockedCopy();
334
4
      logic.enableQuantifiers();
335
4
      logic.lock();
336
    }
337
    // Allows to answer sat more often by default.
338
12
    if (!opts.wasSetByUser(options::fmfBound))
339
    {
340
12
      opts.set(options::fmfBound, true);
341
12
      Trace("smt") << "turning on fmf-bound, for arrays-exp" << std::endl;
342
    }
343
  }
344
345
  // sygus inference may require datatypes
346
8954
  if (!isInternalSubsolver)
347
  {
348
13460
    if (options::produceAbducts()
349
6715
        || options::produceInterpols() != options::ProduceInterpols::NONE
350
13435
        || options::sygusInference() || options::sygusRewSynthInput())
351
    {
352
      // since we are trying to recast as sygus, we assume the input is sygus
353
89
      usesSygus = true;
354
    }
355
34048
    else if (options::sygusInst())
356
    {
357
      // sygus instantiation uses sygus, but it is not a sygus problem
358
17
      usesSygus = true;
359
    }
360
  }
361
362
  // We now know whether the input uses sygus. Update the logic to incorporate
363
  // the theories we need internally for handling sygus problems.
364
8954
  if (usesSygus)
365
  {
366
819
    logic = logic.getUnlockedCopy();
367
819
    logic.enableSygus();
368
819
    logic.lock();
369
819
    if (isSygus)
370
    {
371
      // When sygus answers "unsat", it is not due to showing a set of
372
      // formulas is unsat in the standard way. Thus, proofs do not apply.
373
713
      disableProofs = true;
374
    }
375
  }
376
377
  // if we requiring disabling proofs, disable them now
378
8954
  if (disableProofs && options::produceProofs())
379
  {
380
1
    opts.set(options::unsatCores, false);
381
1
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::OFF);
382
1
    if (options::produceProofs())
383
    {
384
1
      Notice() << "SmtEngine: turning off produce-proofs." << std::endl;
385
    }
386
1
    opts.set(options::produceProofs, false);
387
1
    opts.set(options::checkProofs, false);
388
1
    opts.set(options::proofEagerChecking, false);
389
  }
390
391
  // sygus core connective requires unsat cores
392
19456
  if (options::sygusCoreConnective())
393
  {
394
72
    opts.set(options::unsatCores, true);
395
72
    if (options::unsatCoresMode() == options::UnsatCoresMode::OFF)
396
    {
397
5
      opts.set(options::unsatCoresMode, options::UnsatCoresMode::ASSUMPTIONS);
398
    }
399
  }
400
401
33875
  if ((options::checkModels() || options::checkSynthSol()
402
7067
       || options::produceAbducts()
403
6746
       || options::produceInterpols() != options::ProduceInterpols::NONE
404
13293
       || options::modelCoresMode() != options::ModelCoresMode::NONE
405
13306
       || options::blockModelsMode() != options::BlockModelsMode::NONE
406
6610
       || options::produceProofs())
407
14324
      && !options::produceAssertions())
408
  {
409
3462
    Notice() << "SmtEngine: turning on produce-assertions to support "
410
1
             << "option requiring assertions." << std::endl;
411
3461
    opts.set(options::produceAssertions, true);
412
  }
413
414
  // whether we want to force safe unsat cores, i.e., if we are in the default
415
  // ASSUMPTIONS mode, since other ones are experimental
416
  bool safeUnsatCores =
417
8954
      options::unsatCoresMode() == options::UnsatCoresMode::ASSUMPTIONS;
418
419
  // Disable options incompatible with incremental solving, unsat cores or
420
  // output an error if enabled explicitly. It is also currently incompatible
421
  // with arithmetic, force the option off.
422
8954
  if (options::incrementalSolving() || safeUnsatCores)
423
  {
424
3423
    if (options::unconstrainedSimp())
425
    {
426
      if (opts.wasSetByUser(options::unconstrainedSimp))
427
      {
428
        throw OptionException(
429
            "unconstrained simplification not supported with old unsat "
430
            "cores/incremental solving");
431
      }
432
      Notice() << "SmtEngine: turning off unconstrained simplification to "
433
                  "support old unsat cores/incremental solving"
434
               << std::endl;
435
      opts.set(options::unconstrainedSimp, false);
436
    }
437
  }
438
  else
439
  {
440
    // Turn on unconstrained simplification for QF_AUFBV
441
5531
    if (!opts.wasSetByUser(options::unconstrainedSimp))
442
    {
443
6944
      bool uncSimp = !logic.isQuantified() && !options::produceModels()
444
1132
                     && !options::produceAssignments()
445
1131
                     && !options::checkModels()
446
1131
                     && logic.isTheoryEnabled(THEORY_ARRAYS)
447
166
                     && logic.isTheoryEnabled(THEORY_BV)
448
5509
                     && !logic.isTheoryEnabled(THEORY_ARITH);
449
10850
      Trace("smt") << "setting unconstrained simplification to " << uncSimp
450
5425
                   << std::endl;
451
5425
      opts.set(options::unconstrainedSimp, uncSimp);
452
    }
453
  }
454
455
8954
  if (options::incrementalSolving())
456
  {
457
1611
    if (options::sygusInference())
458
    {
459
      if (opts.wasSetByUser(options::sygusInference))
460
      {
461
        throw OptionException(
462
            "sygus inference not supported with incremental solving");
463
      }
464
      Notice() << "SmtEngine: turning off sygus inference to support "
465
                  "incremental solving"
466
               << std::endl;
467
      opts.set(options::sygusInference, false);
468
    }
469
  }
470
471
8954
  if (options::solveBVAsInt() != options::SolveBVAsIntMode::OFF)
472
  {
473
    /**
474
     * Operations on 1 bits are better handled as Boolean operations
475
     * than as integer operations.
476
     * Therefore, we enable bv-to-bool, which runs before
477
     * the translation to integers.
478
     */
479
125
    opts.set(options::bitvectorToBool, true);
480
  }
481
482
  // Disable options incompatible with unsat cores or output an error if enabled
483
  // explicitly
484
8954
  if (safeUnsatCores)
485
  {
486
1908
    if (options::simplificationMode() != options::SimplificationMode::NONE)
487
    {
488
953
      if (opts.wasSetByUser(options::simplificationMode))
489
      {
490
        throw OptionException(
491
            "simplification not supported with old unsat cores");
492
      }
493
953
      Notice() << "SmtEngine: turning off simplification to support unsat "
494
                  "cores"
495
               << std::endl;
496
953
      opts.set(options::simplificationMode, options::SimplificationMode::NONE);
497
    }
498
499
1908
    if (options::pbRewrites())
500
    {
501
      if (opts.wasSetByUser(options::pbRewrites))
502
      {
503
        throw OptionException(
504
            "pseudoboolean rewrites not supported with old unsat cores");
505
      }
506
      Notice() << "SmtEngine: turning off pseudoboolean rewrites to support "
507
                  "old unsat cores\n";
508
      opts.set(options::pbRewrites, false);
509
    }
510
511
1908
    if (options::sortInference())
512
    {
513
      if (opts.wasSetByUser(options::sortInference))
514
      {
515
        throw OptionException(
516
            "sort inference not supported with old unsat cores");
517
      }
518
      Notice() << "SmtEngine: turning off sort inference to support old unsat "
519
                  "cores\n";
520
      opts.set(options::sortInference, false);
521
    }
522
523
93472
    if (options::preSkolemQuant())
524
    {
525
9
      if (opts.wasSetByUser(options::preSkolemQuant))
526
      {
527
        throw OptionException(
528
            "pre-skolemization not supported with old unsat cores");
529
      }
530
9
      Notice() << "SmtEngine: turning off pre-skolemization to support old "
531
                  "unsat cores\n";
532
9
      opts.set(options::preSkolemQuant, false);
533
    }
534
535
1908
    if (options::bitvectorToBool())
536
    {
537
24
      if (opts.wasSetByUser(options::bitvectorToBool))
538
      {
539
        throw OptionException("bv-to-bool not supported with old unsat cores");
540
      }
541
24
      Notice() << "SmtEngine: turning off bitvector-to-bool to support old "
542
                  "unsat cores\n";
543
24
      opts.set(options::bitvectorToBool, false);
544
    }
545
546
1908
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
547
    {
548
      if (opts.wasSetByUser(options::boolToBitvector))
549
      {
550
        throw OptionException(
551
            "bool-to-bv != off not supported with old unsat cores");
552
      }
553
      Notice()
554
          << "SmtEngine: turning off bool-to-bv to support old unsat cores\n";
555
      opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
556
    }
557
558
1908
    if (options::bvIntroducePow2())
559
    {
560
      if (opts.wasSetByUser(options::bvIntroducePow2))
561
      {
562
        throw OptionException(
563
            "bv-intro-pow2 not supported with old unsat cores");
564
      }
565
      Notice()
566
          << "SmtEngine: turning off bv-intro-pow2 to support old unsat cores";
567
      opts.set(options::bvIntroducePow2, false);
568
    }
569
570
1908
    if (options::repeatSimp())
571
    {
572
      if (opts.wasSetByUser(options::repeatSimp))
573
      {
574
        throw OptionException("repeat-simp not supported with old unsat cores");
575
      }
576
      Notice()
577
          << "SmtEngine: turning off repeat-simp to support old unsat cores\n";
578
      opts.set(options::repeatSimp, false);
579
    }
580
581
1908
    if (options::globalNegate())
582
    {
583
      if (opts.wasSetByUser(options::globalNegate))
584
      {
585
        throw OptionException(
586
            "global-negate not supported with old unsat cores");
587
      }
588
      Notice() << "SmtEngine: turning off global-negate to support old unsat "
589
                  "cores\n";
590
      opts.set(options::globalNegate, false);
591
    }
592
593
1908
    if (options::bitvectorAig())
594
    {
595
      throw OptionException("bitblast-aig not supported with old unsat cores");
596
    }
597
598
1908
    if (options::doITESimp())
599
    {
600
      throw OptionException("ITE simp not supported with old unsat cores");
601
    }
602
  }
603
  else
604
  {
605
    // by default, nonclausal simplification is off for QF_SAT
606
7046
    if (!opts.wasSetByUser(options::simplificationMode))
607
    {
608
7020
      bool qf_sat = logic.isPure(THEORY_BOOL) && !logic.isQuantified();
609
14040
      Trace("smt") << "setting simplification mode to <"
610
7020
                   << logic.getLogicString() << "> " << (!qf_sat) << std::endl;
611
      // simplification=none works better for SMT LIB benchmarks with
612
      // quantifiers, not others opts.set(options::simplificationMode, qf_sat ||
613
      // quantifiers ? options::SimplificationMode::NONE :
614
      // options::SimplificationMode::BATCH);
615
7020
      opts.set(options::simplificationMode, qf_sat
616
14040
                                          ? options::SimplificationMode::NONE
617
                                          : options::SimplificationMode::BATCH);
618
    }
619
  }
620
621
29673
  if (options::cegqiBv() && logic.isQuantified())
622
  {
623
5045
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
624
    {
625
      if (opts.wasSetByUser(options::boolToBitvector))
626
      {
627
        throw OptionException(
628
            "bool-to-bv != off not supported with CBQI BV for quantified "
629
            "logics");
630
      }
631
      Notice() << "SmtEngine: turning off bool-to-bitvector to support CBQI BV"
632
               << std::endl;
633
      opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
634
    }
635
  }
636
637
  // cases where we need produce models
638
17908
  if (!options::produceModels()
639
15040
      && (options::produceAssignments() || options::sygusRewSynthCheck()
640
5797
          || usesSygus))
641
  {
642
274
    Notice() << "SmtEngine: turning on produce-models" << std::endl;
643
274
    opts.set(options::produceModels, true);
644
  }
645
646
  /////////////////////////////////////////////////////////////////////////////
647
  // Theory widening
648
  //
649
  // Some theories imply the use of other theories to handle certain operators,
650
  // e.g. UF to handle partial functions.
651
  /////////////////////////////////////////////////////////////////////////////
652
8954
  bool needsUf = false;
653
  // strings require LIA, UF; widen the logic
654
8954
  if (logic.isTheoryEnabled(THEORY_STRINGS))
655
  {
656
8528
    LogicInfo log(logic.getUnlockedCopy());
657
    // Strings requires arith for length constraints, and also UF
658
4264
    needsUf = true;
659
4264
    if (!logic.isTheoryEnabled(THEORY_ARITH) || logic.isDifferenceLogic())
660
    {
661
127
      Notice()
662
          << "Enabling linear integer arithmetic because strings are enabled"
663
          << std::endl;
664
127
      log.enableTheory(THEORY_ARITH);
665
127
      log.enableIntegers();
666
127
      log.arithOnlyLinear();
667
    }
668
4137
    else if (!logic.areIntegersUsed())
669
    {
670
      Notice() << "Enabling integer arithmetic because strings are enabled"
671
               << std::endl;
672
      log.enableIntegers();
673
    }
674
4264
    logic = log;
675
4264
    logic.lock();
676
  }
677
8954
  if (options::bvAbstraction())
678
  {
679
    // bv abstraction may require UF
680
4
    Notice() << "Enabling UF because bvAbstraction requires it." << std::endl;
681
4
    needsUf = true;
682
  }
683
36150
  else if (options::preSkolemQuantNested()
684
8950
           && opts.wasSetByUser(options::preSkolemQuantNested))
685
  {
686
    // if pre-skolem nested is explictly set, then we require UF. If it is
687
    // not explicitly set, it is disabled below if UF is not present.
688
2
    Notice() << "Enabling UF because preSkolemQuantNested requires it."
689
             << std::endl;
690
2
    needsUf = true;
691
  }
692
8954
  if (needsUf
693
      // Arrays, datatypes and sets permit Boolean terms and thus require UF
694
4684
      || logic.isTheoryEnabled(THEORY_ARRAYS)
695
3958
      || logic.isTheoryEnabled(THEORY_DATATYPES)
696
2779
      || logic.isTheoryEnabled(THEORY_SETS)
697
2706
      || logic.isTheoryEnabled(THEORY_BAGS)
698
      // Non-linear arithmetic requires UF to deal with division/mod because
699
      // their expansion introduces UFs for the division/mod-by-zero case.
700
      // If we are eliminating non-linear arithmetic via solve-int-as-bv,
701
      // then this is not required, since non-linear arithmetic will be
702
      // eliminated altogether (or otherwise fail at preprocessing).
703
2706
      || (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
704
558
          && options::solveIntAsBV() == 0)
705
      // FP requires UF since there are multiple operators that are partially
706
      // defined (see http://smtlib.cs.uiowa.edu/papers/BTRW15.pdf for more
707
      // details).
708
11102
      || logic.isTheoryEnabled(THEORY_FP))
709
  {
710
6866
    if (!logic.isTheoryEnabled(THEORY_UF))
711
    {
712
1680
      LogicInfo log(logic.getUnlockedCopy());
713
840
      if (!needsUf)
714
      {
715
497
        Notice() << "Enabling UF because " << logic << " requires it."
716
                 << std::endl;
717
      }
718
840
      log.enableTheory(THEORY_UF);
719
840
      logic = log;
720
840
      logic.lock();
721
    }
722
  }
723
8954
  if (options::arithMLTrick())
724
  {
725
8
    if (!logic.areIntegersUsed())
726
    {
727
      // enable integers
728
      LogicInfo log(logic.getUnlockedCopy());
729
      Notice() << "Enabling integers because arithMLTrick requires it."
730
               << std::endl;
731
      log.enableIntegers();
732
      logic = log;
733
      logic.lock();
734
    }
735
  }
736
  /////////////////////////////////////////////////////////////////////////////
737
738
  // Set the options for the theoryOf
739
8954
  if (!opts.wasSetByUser(options::theoryOfMode))
740
  {
741
25087
    if (logic.isSharingEnabled() && !logic.isTheoryEnabled(THEORY_BV)
742
2667
        && !logic.isTheoryEnabled(THEORY_STRINGS)
743
2181
        && !logic.isTheoryEnabled(THEORY_SETS)
744
2095
        && !logic.isTheoryEnabled(THEORY_BAGS)
745
11691
        && !(logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
746
648
             && !logic.isQuantified()))
747
    {
748
1699
      Trace("smt") << "setting theoryof-mode to term-based" << std::endl;
749
1699
      opts.set(options::theoryOfMode, options::TheoryOfMode::THEORY_OF_TERM_BASED);
750
    }
751
  }
752
753
  // by default, symmetry breaker is on only for non-incremental QF_UF
754
138364
  if (!opts.wasSetByUser(options::ufSymmetryBreaker))
755
  {
756
9284
    bool qf_uf_noinc = logic.isPure(THEORY_UF) && !logic.isQuantified()
757
9213
                       && !options::incrementalSolving() && !safeUnsatCores;
758
17908
    Trace("smt") << "setting uf symmetry breaker to " << qf_uf_noinc
759
8954
                 << std::endl;
760
8954
    opts.set(options::ufSymmetryBreaker, qf_uf_noinc);
761
  }
762
763
  // If in arrays, set the UF handler to arrays
764
22414
  if (logic.isTheoryEnabled(THEORY_ARRAYS) && !options::ufHo()
765
9255635
      && !options::finiteModelFind()
766
13615
      && (!logic.isQuantified()
767
3771
          || (logic.isQuantified() && !logic.isTheoryEnabled(THEORY_UF))))
768
  {
769
445
    Theory::setUninterpretedSortOwner(THEORY_ARRAYS);
770
  }
771
  else
772
  {
773
8509
    Theory::setUninterpretedSortOwner(THEORY_UF);
774
  }
775
776
8954
  if (!opts.wasSetByUser(options::simplifyWithCareEnabled))
777
  {
778
    bool qf_aufbv =
779
11622
        !logic.isQuantified() && logic.isTheoryEnabled(THEORY_ARRAYS)
780
9403
        && logic.isTheoryEnabled(THEORY_UF) && logic.isTheoryEnabled(THEORY_BV);
781
782
8954
    bool withCare = qf_aufbv;
783
17908
    Trace("smt") << "setting ite simplify with care to " << withCare
784
8954
                 << std::endl;
785
8954
    opts.set(options::simplifyWithCareEnabled, withCare);
786
  }
787
  // Turn off array eager index splitting for QF_AUFLIA
788
35074
  if (!opts.wasSetByUser(options::arraysEagerIndexSplitting))
789
  {
790
20576
    if (not logic.isQuantified() && logic.isTheoryEnabled(THEORY_ARRAYS)
791
449
        && logic.isTheoryEnabled(THEORY_UF)
792
9403
        && logic.isTheoryEnabled(THEORY_ARITH))
793
    {
794
348
      Trace("smt") << "setting array eager index splitting to false"
795
174
                   << std::endl;
796
174
      opts.set(options::arraysEagerIndexSplitting, false);
797
    }
798
  }
799
  // Turn on multiple-pass non-clausal simplification for QF_AUFBV
800
8954
  if (!opts.wasSetByUser(options::repeatSimp))
801
  {
802
8952
    bool repeatSimp = !logic.isQuantified()
803
2666
                      && (logic.isTheoryEnabled(THEORY_ARRAYS)
804
449
                          && logic.isTheoryEnabled(THEORY_UF)
805
449
                          && logic.isTheoryEnabled(THEORY_BV))
806
9221
                      && !safeUnsatCores;
807
17904
    Trace("smt") << "setting repeat simplification to " << repeatSimp
808
8952
                 << std::endl;
809
8952
    opts.set(options::repeatSimp, repeatSimp);
810
  }
811
812
17908
  if (options::boolToBitvector() == options::BoolToBVMode::ALL
813
8954
      && !logic.isTheoryEnabled(THEORY_BV))
814
  {
815
    if (opts.wasSetByUser(options::boolToBitvector))
816
    {
817
      throw OptionException(
818
          "bool-to-bv=all not supported for non-bitvector logics.");
819
    }
820
    Notice() << "SmtEngine: turning off bool-to-bv for non-bv logic: "
821
             << logic.getLogicString() << std::endl;
822
    opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
823
  }
824
825
17908
  if (!opts.wasSetByUser(options::bvEagerExplanations)
826
8954
      && logic.isTheoryEnabled(THEORY_ARRAYS)
827
13460
      && logic.isTheoryEnabled(THEORY_BV))
828
  {
829
4108
    Trace("smt") << "enabling eager bit-vector explanations " << std::endl;
830
4108
    opts.set(options::bvEagerExplanations, true);
831
  }
832
833
  // Turn on arith rewrite equalities only for pure arithmetic
834
56923
  if (!opts.wasSetByUser(options::arithRewriteEq))
835
  {
836
    bool arithRewriteEq =
837
8948
        logic.isPure(THEORY_ARITH) && logic.isLinear() && !logic.isQuantified();
838
17896
    Trace("smt") << "setting arith rewrite equalities " << arithRewriteEq
839
8948
                 << std::endl;
840
8948
    opts.set(options::arithRewriteEq, arithRewriteEq);
841
  }
842
171092
  if (!opts.wasSetByUser(options::arithHeuristicPivots))
843
  {
844
8954
    int16_t heuristicPivots = 5;
845
8954
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
846
    {
847
444
      if (logic.isDifferenceLogic())
848
      {
849
19
        heuristicPivots = -1;
850
      }
851
425
      else if (!logic.areIntegersUsed())
852
      {
853
199
        heuristicPivots = 0;
854
      }
855
    }
856
17908
    Trace("smt") << "setting arithHeuristicPivots  " << heuristicPivots
857
8954
                 << std::endl;
858
8954
    opts.set(options::arithHeuristicPivots, heuristicPivots);
859
  }
860
396158
  if (!opts.wasSetByUser(options::arithPivotThreshold))
861
  {
862
8954
    uint16_t pivotThreshold = 2;
863
8954
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
864
    {
865
444
      if (logic.isDifferenceLogic())
866
      {
867
19
        pivotThreshold = 16;
868
      }
869
    }
870
17908
    Trace("smt") << "setting arith arithPivotThreshold  " << pivotThreshold
871
8954
                 << std::endl;
872
8954
    opts.set(options::arithPivotThreshold, pivotThreshold);
873
  }
874
130384
  if (!opts.wasSetByUser(options::arithStandardCheckVarOrderPivots))
875
  {
876
8954
    int16_t varOrderPivots = -1;
877
8954
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
878
    {
879
444
      varOrderPivots = 200;
880
    }
881
17908
    Trace("smt") << "setting arithStandardCheckVarOrderPivots  "
882
8954
                 << varOrderPivots << std::endl;
883
8954
    opts.set(options::arithStandardCheckVarOrderPivots, varOrderPivots);
884
  }
885
8954
  if (logic.isPure(THEORY_ARITH) && !logic.areRealsUsed())
886
  {
887
960
    if (!opts.wasSetByUser(options::nlExtTangentPlanesInterleave))
888
    {
889
544
      Trace("smt") << "setting nlExtTangentPlanesInterleave to true"
890
272
                   << std::endl;
891
272
      opts.set(options::nlExtTangentPlanesInterleave, true);
892
    }
893
  }
894
895
  // Set decision mode based on logic (if not set by user)
896
8954
  if (!opts.wasSetByUser(options::decisionMode))
897
  {
898
    options::DecisionMode decMode =
899
        // anything that uses sygus uses internal
900
16903
        usesSygus ? options::DecisionMode::INTERNAL :
901
                  // ALL
902
8055
            logic.hasEverything()
903
12515
                ? options::DecisionMode::JUSTIFICATION
904
                : (  // QF_BV
905
10845
                      (not logic.isQuantified() && logic.isPure(THEORY_BV)) ||
906
                              // QF_AUFBV or QF_ABV or QF_UFBV
907
3767
                              (not logic.isQuantified()
908
1925
                               && (logic.isTheoryEnabled(THEORY_ARRAYS)
909
1496
                                   || logic.isTheoryEnabled(THEORY_UF))
910
1460
                               && logic.isTheoryEnabled(THEORY_BV))
911
3374
                              ||
912
                              // QF_AUFLIA (and may be ends up enabling
913
                              // QF_AUFLRA?)
914
3374
                              (not logic.isQuantified()
915
1532
                               && logic.isTheoryEnabled(THEORY_ARRAYS)
916
172
                               && logic.isTheoryEnabled(THEORY_UF)
917
172
                               && logic.isTheoryEnabled(THEORY_ARITH))
918
3306
                              ||
919
                              // QF_LRA
920
3306
                              (not logic.isQuantified()
921
1464
                               && logic.isPure(THEORY_ARITH) && logic.isLinear()
922
444
                               && !logic.isDifferenceLogic()
923
425
                               && !logic.areIntegersUsed())
924
3107
                              ||
925
                              // Quantifiers
926
4372
                              logic.isQuantified() ||
927
                              // Strings
928
1265
                              logic.isTheoryEnabled(THEORY_STRINGS)
929
7655
                          ? options::DecisionMode::JUSTIFICATION
930
8848
                          : options::DecisionMode::INTERNAL);
931
932
    bool stoponly =
933
        // ALL
934
13929
        logic.hasEverything() || logic.isTheoryEnabled(THEORY_STRINGS)
935
13806
            ? false
936
            : (  // QF_AUFLIA
937
4593
                  (not logic.isQuantified()
938
2618
                   && logic.isTheoryEnabled(THEORY_ARRAYS)
939
429
                   && logic.isTheoryEnabled(THEORY_UF)
940
429
                   && logic.isTheoryEnabled(THEORY_ARITH))
941
                          ||
942
                          // QF_LRA
943
4427
                          (not logic.isQuantified()
944
2452
                           && logic.isPure(THEORY_ARITH) && logic.isLinear()
945
444
                           && !logic.isDifferenceLogic()
946
425
                           && !logic.areIntegersUsed())
947
4427
                      ? true
948
8848
                      : false);
949
950
8848
    Trace("smt") << "setting decision mode to " << decMode << std::endl;
951
8848
    opts.set(options::decisionMode, decMode);
952
8848
    opts.set(options::decisionStopOnly, stoponly);
953
  }
954
8954
  if (options::incrementalSolving())
955
  {
956
    // disable modes not supported by incremental
957
1611
    opts.set(options::sortInference, false);
958
1611
    opts.set(options::ufssFairnessMonotone, false);
959
1611
    opts.set(options::globalNegate, false);
960
1611
    opts.set(options::bvAbstraction, false);
961
1611
    opts.set(options::arithMLTrick, false);
962
  }
963
8954
  if (logic.hasCardinalityConstraints())
964
  {
965
    // must have finite model finding on
966
26
    opts.set(options::finiteModelFind, true);
967
  }
968
969
181317
  if (options::instMaxLevel() != -1)
970
  {
971
4
    Notice() << "SmtEngine: turning off cbqi to support instMaxLevel"
972
             << std::endl;
973
4687072
    opts.set(options::cegqi, false);
974
  }
975
976
27198
  if ((opts.wasSetByUser(options::fmfBoundLazy) && options::fmfBoundLazy())
977
26880
      || (opts.wasSetByUser(options::fmfBoundInt) && options::fmfBoundInt()))
978
  {
979
18
    opts.set(options::fmfBound, true);
980
  }
981
  // now have determined whether fmfBoundInt is on/off
982
  // apply fmfBoundInt options
983
8954
  if (options::fmfBound())
984
  {
985
46682
    if (!opts.wasSetByUser(options::mbqiMode)
986
2196
        || (options::mbqiMode() != options::MbqiMode::NONE
987
            && options::mbqiMode() != options::MbqiMode::FMC))
988
    {
989
      // if bounded integers are set, use no MBQI by default
990
1098
      opts.set(options::mbqiMode, options::MbqiMode::NONE);
991
    }
992
409340
    if (!opts.wasSetByUser(options::prenexQuant))
993
    {
994
1098
      opts.set(options::prenexQuant, options::PrenexQuantMode::NONE);
995
    }
996
  }
997
8954
  if (options::ufHo())
998
  {
999
    // if higher-order, then current variants of model-based instantiation
1000
    // cannot be used
1001
204
    if (options::mbqiMode() != options::MbqiMode::NONE)
1002
    {
1003
138
      opts.set(options::mbqiMode, options::MbqiMode::NONE);
1004
    }
1005
204
    if (!opts.wasSetByUser(options::hoElimStoreAx))
1006
    {
1007
      // by default, use store axioms only if --ho-elim is set
1008
203
      opts.set(options::hoElimStoreAx, options::hoElim());
1009
    }
1010
28706
    if (!options::assignFunctionValues())
1011
    {
1012
      // must assign function values
1013
2
      opts.set(options::assignFunctionValues, true);
1014
    }
1015
    // Cannot use macros, since lambda lifting and macro elimination are inverse
1016
    // operations.
1017
11015
    if (options::macrosQuant())
1018
    {
1019
      opts.set(options::macrosQuant, false);
1020
    }
1021
  }
1022
29797
  if (options::fmfFunWellDefinedRelevant())
1023
  {
1024
12
    if (!opts.wasSetByUser(options::fmfFunWellDefined))
1025
    {
1026
12
      opts.set(options::fmfFunWellDefined, true);
1027
    }
1028
  }
1029
8954
  if (options::fmfFunWellDefined())
1030
  {
1031
60
    if (!opts.wasSetByUser(options::finiteModelFind))
1032
    {
1033
58
      opts.set(options::finiteModelFind, true);
1034
    }
1035
  }
1036
1037
  // now, have determined whether finite model find is on/off
1038
  // apply finite model finding options
1039
8954
  if (options::finiteModelFind())
1040
  {
1041
    // apply conservative quantifiers splitting
1042
19701
    if (!opts.wasSetByUser(options::quantDynamicSplit))
1043
    {
1044
271
      opts.set(options::quantDynamicSplit, options::QuantDSplitMode::DEFAULT);
1045
    }
1046
7126
    if (!opts.wasSetByUser(options::eMatching))
1047
    {
1048
802
      opts.set(options::eMatching, options::fmfInstEngine());
1049
    }
1050
480381
    if (!opts.wasSetByUser(options::instWhenMode))
1051
    {
1052
      // instantiate only on last call
1053
271
      if (options::eMatching())
1054
      {
1055
8
        opts.set(options::instWhenMode, options::InstWhenMode::LAST_CALL);
1056
      }
1057
    }
1058
  }
1059
1060
  // apply sygus options
1061
  // if we are attempting to rewrite everything to SyGuS, use sygus()
1062
8954
  if (usesSygus)
1063
  {
1064
31034
    if (!options::sygus())
1065
    {
1066
300
      Trace("smt") << "turning on sygus" << std::endl;
1067
    }
1068
819
    opts.set(options::sygus, true);
1069
    // must use Ferrante/Rackoff for real arithmetic
1070
5249
    if (!opts.wasSetByUser(options::cegqiMidpoint))
1071
    {
1072
819
      opts.set(options::cegqiMidpoint, true);
1073
    }
1074
    // must disable cegqi-bv since it may introduce witness terms, which
1075
    // cannot appear in synthesis solutions
1076
819
    if (!opts.wasSetByUser(options::cegqiBv))
1077
    {
1078
816
      opts.set(options::cegqiBv, false);
1079
    }
1080
41208
    if (options::sygusRepairConst())
1081
    {
1082
151
      if (!opts.wasSetByUser(options::cegqi))
1083
      {
1084
151
        opts.set(options::cegqi, true);
1085
      }
1086
    }
1087
819
    if (options::sygusInference())
1088
    {
1089
      // optimization: apply preskolemization, makes it succeed more often
1090
64
      if (!opts.wasSetByUser(options::preSkolemQuant))
1091
      {
1092
64
        opts.set(options::preSkolemQuant, true);
1093
      }
1094
64
      if (!opts.wasSetByUser(options::preSkolemQuantNested))
1095
      {
1096
64
        opts.set(options::preSkolemQuantNested, true);
1097
      }
1098
    }
1099
    // counterexample-guided instantiation for sygus
1100
2992
    if (!opts.wasSetByUser(options::cegqiSingleInvMode))
1101
    {
1102
687
      opts.set(options::cegqiSingleInvMode, options::CegqiSingleInvMode::USE);
1103
    }
1104
82812
    if (!opts.wasSetByUser(options::quantConflictFind))
1105
    {
1106
819
      opts.set(options::quantConflictFind, false);
1107
    }
1108
200595
    if (!opts.wasSetByUser(options::instNoEntail))
1109
    {
1110
819
      opts.set(options::instNoEntail, false);
1111
    }
1112
4003
    if (!opts.wasSetByUser(options::cegqiFullEffort))
1113
    {
1114
      // should use full effort cbqi for single invocation and repair const
1115
819
      opts.set(options::cegqiFullEffort, true);
1116
    }
1117
1644
    if (options::sygusRew())
1118
    {
1119
1913
      opts.set(options::sygusRewSynth, true);
1120
60712
      opts.set(options::sygusRewVerify, true);
1121
    }
1122
819
    if (options::sygusRewSynthInput())
1123
    {
1124
      // If we are using synthesis rewrite rules from input, we use
1125
      // sygusRewSynth after preprocessing. See passes/synth_rew_rules.h for
1126
      // details on this technique.
1127
      opts.set(options::sygusRewSynth, true);
1128
      // we should not use the extended rewriter, since we are interested
1129
      // in rewrites that are not in the main rewriter
1130
211304
      if (!opts.wasSetByUser(options::sygusExtRew))
1131
      {
1132
        opts.set(options::sygusExtRew, false);
1133
      }
1134
    }
1135
    // Whether we must use "basic" sygus algorithms. A non-basic sygus algorithm
1136
    // is one that is specialized for returning a single solution. Non-basic
1137
    // sygus algorithms currently include the PBE solver, UNIF+PI, static
1138
    // template inference for invariant synthesis, and single invocation
1139
    // techniques.
1140
819
    bool reqBasicSygus = false;
1141
819
    if (options::produceAbducts())
1142
    {
1143
      // if doing abduction, we should filter strong solutions
1144
120
      if (!opts.wasSetByUser(options::sygusFilterSolMode))
1145
      {
1146
15
        opts.set(options::sygusFilterSolMode, options::SygusFilterSolMode::STRONG);
1147
      }
1148
      // we must use basic sygus algorithms, since e.g. we require checking
1149
      // a sygus side condition for consistency with axioms.
1150
15
      reqBasicSygus = true;
1151
    }
1152
2450
    if (options::sygusRewSynth() || options::sygusRewVerify()
1153
2516
        || options::sygusQueryGen())
1154
    {
1155
      // rewrite rule synthesis implies that sygus stream must be true
1156
2234
      opts.set(options::sygusStream, true);
1157
    }
1158
819
    if (options::sygusStream() || options::incrementalSolving())
1159
    {
1160
      // Streaming and incremental mode are incompatible with techniques that
1161
      // focus the search towards finding a single solution.
1162
12
      reqBasicSygus = true;
1163
    }
1164
    // Now, disable options for non-basic sygus algorithms, if necessary.
1165
819
    if (reqBasicSygus)
1166
    {
1167
316
      if (!opts.wasSetByUser(options::sygusUnifPbe))
1168
      {
1169
25
        opts.set(options::sygusUnifPbe, false);
1170
      }
1171
3537
      if (opts.wasSetByUser(options::sygusUnifPi))
1172
      {
1173
        opts.set(options::sygusUnifPi, options::SygusUnifPiMode::NONE);
1174
      }
1175
407
      if (!opts.wasSetByUser(options::sygusInvTemplMode))
1176
      {
1177
25
        opts.set(options::sygusInvTemplMode, options::SygusInvTemplMode::NONE);
1178
      }
1179
25
      if (!opts.wasSetByUser(options::cegqiSingleInvMode))
1180
      {
1181
25
        opts.set(options::cegqiSingleInvMode, options::CegqiSingleInvMode::NONE);
1182
      }
1183
    }
1184
5706
    if (!opts.wasSetByUser(options::dtRewriteErrorSel))
1185
    {
1186
819
      opts.set(options::dtRewriteErrorSel, true);
1187
    }
1188
    // do not miniscope
1189
3689
    if (!opts.wasSetByUser(options::miniscopeQuant))
1190
    {
1191
690
      opts.set(options::miniscopeQuant, false);
1192
    }
1193
3655
    if (!opts.wasSetByUser(options::miniscopeQuantFreeVar))
1194
    {
1195
693
      opts.set(options::miniscopeQuantFreeVar, false);
1196
    }
1197
45549
    if (!opts.wasSetByUser(options::quantSplit))
1198
    {
1199
693
      opts.set(options::quantSplit, false);
1200
    }
1201
    // do not do macros
1202
819
    if (!opts.wasSetByUser(options::macrosQuant))
1203
    {
1204
819
      opts.set(options::macrosQuant, false);
1205
    }
1206
    // use tangent planes by default, since we want to put effort into
1207
    // the verification step for sygus queries with non-linear arithmetic
1208
64451
    if (!opts.wasSetByUser(options::nlExtTangentPlanes))
1209
    {
1210
805
      opts.set(options::nlExtTangentPlanes, true);
1211
    }
1212
  }
1213
  // counterexample-guided instantiation for non-sygus
1214
  // enable if any possible quantifiers with arithmetic, datatypes or bitvectors
1215
17908
  if ((logic.isQuantified()
1216
6286
       && (logic.isTheoryEnabled(THEORY_ARITH)
1217
273
           || logic.isTheoryEnabled(THEORY_DATATYPES)
1218
265
           || logic.isTheoryEnabled(THEORY_BV)
1219
77
           || logic.isTheoryEnabled(THEORY_FP)))
1220
32846
      || options::cegqiAll())
1221
  {
1222
6209
    if (!opts.wasSetByUser(options::cegqi))
1223
    {
1224
6186
      opts.set(options::cegqi, true);
1225
    }
1226
    // check whether we should apply full cbqi
1227
6209
    if (logic.isPure(THEORY_BV))
1228
    {
1229
152
      if (!opts.wasSetByUser(options::cegqiFullEffort))
1230
      {
1231
60
        opts.set(options::cegqiFullEffort, true);
1232
      }
1233
    }
1234
  }
1235
8954
  if (options::cegqi())
1236
  {
1237
6207
    if (options::incrementalSolving())
1238
    {
1239
      // cannot do nested quantifier elimination in incremental mode
1240
23646
      opts.set(options::cegqiNestedQE, false);
1241
    }
1242
6207
    if (logic.isPure(THEORY_ARITH) || logic.isPure(THEORY_BV))
1243
    {
1244
265
      if (!opts.wasSetByUser(options::quantConflictFind))
1245
      {
1246
265
        opts.set(options::quantConflictFind, false);
1247
      }
1248
265
      if (!opts.wasSetByUser(options::instNoEntail))
1249
      {
1250
265
        opts.set(options::instNoEntail, false);
1251
      }
1252
33877
      if (!opts.wasSetByUser(options::instWhenMode) && options::cegqiModel())
1253
      {
1254
        // only instantiation should happen at last call when model is avaiable
1255
265
        opts.set(options::instWhenMode, options::InstWhenMode::LAST_CALL);
1256
      }
1257
    }
1258
    else
1259
    {
1260
      // only supported in pure arithmetic or pure BV
1261
5942
      opts.set(options::cegqiNestedQE, false);
1262
    }
1263
6207
    if (options::globalNegate())
1264
    {
1265
6
      if (!opts.wasSetByUser(options::prenexQuant))
1266
      {
1267
6
        opts.set(options::prenexQuant, options::PrenexQuantMode::NONE);
1268
      }
1269
    }
1270
  }
1271
  // implied options...
1272
40558
  if (options::strictTriggers())
1273
  {
1274
386933
    if (!opts.wasSetByUser(options::userPatternsQuant))
1275
    {
1276
      opts.set(options::userPatternsQuant, options::UserPatMode::TRUST);
1277
    }
1278
  }
1279
239364
  if (opts.wasSetByUser(options::qcfMode) || options::qcfTConstraint())
1280
  {
1281
8
    opts.set(options::quantConflictFind, true);
1282
  }
1283
8954
  if (options::cegqiNestedQE())
1284
  {
1285
1167
    opts.set(options::prenexQuantUser, true);
1286
30
    if (!opts.wasSetByUser(options::preSkolemQuant))
1287
    {
1288
30
      opts.set(options::preSkolemQuant, true);
1289
    }
1290
  }
1291
  // for induction techniques
1292
17915
  if (options::quantInduction())
1293
  {
1294
18421
    if (!opts.wasSetByUser(options::dtStcInduction))
1295
    {
1296
10
      opts.set(options::dtStcInduction, true);
1297
    }
1298
14479
    if (!opts.wasSetByUser(options::intWfInduction))
1299
    {
1300
10
      opts.set(options::intWfInduction, true);
1301
    }
1302
  }
1303
8954
  if (options::dtStcInduction())
1304
  {
1305
    // try to remove ITEs from quantified formulas
1306
214210
    if (!opts.wasSetByUser(options::iteDtTesterSplitQuant))
1307
    {
1308
10
      opts.set(options::iteDtTesterSplitQuant, true);
1309
    }
1310
308414
    if (!opts.wasSetByUser(options::iteLiftQuant))
1311
    {
1312
10
      opts.set(options::iteLiftQuant, options::IteLiftQuantMode::ALL);
1313
    }
1314
  }
1315
8954
  if (options::intWfInduction())
1316
  {
1317
59014
    if (!opts.wasSetByUser(options::purifyTriggers))
1318
    {
1319
18
      opts.set(options::purifyTriggers, true);
1320
    }
1321
  }
1322
17910
  if (options::conjectureNoFilter())
1323
  {
1324
3255
    if (!opts.wasSetByUser(options::conjectureFilterActiveTerms))
1325
    {
1326
4
      opts.set(options::conjectureFilterActiveTerms, false);
1327
    }
1328
6604
    if (!opts.wasSetByUser(options::conjectureFilterCanonical))
1329
    {
1330
4
      opts.set(options::conjectureFilterCanonical, false);
1331
    }
1332
14600
    if (!opts.wasSetByUser(options::conjectureFilterModel))
1333
    {
1334
      opts.set(options::conjectureFilterModel, false);
1335
    }
1336
  }
1337
18678
  if (opts.wasSetByUser(options::conjectureGenPerRound))
1338
  {
1339
    if (options::conjectureGenPerRound() > 0)
1340
    {
1341
6294
      opts.set(options::conjectureGen, true);
1342
    }
1343
    else
1344
    {
1345
      opts.set(options::conjectureGen, false);
1346
    }
1347
  }
1348
  // can't pre-skolemize nested quantifiers without UF theory
1349
8954
  if (!logic.isTheoryEnabled(THEORY_UF) && options::preSkolemQuant())
1350
  {
1351
30
    if (!opts.wasSetByUser(options::preSkolemQuantNested))
1352
    {
1353
30
      opts.set(options::preSkolemQuantNested, false);
1354
    }
1355
  }
1356
8954
  if (!logic.isTheoryEnabled(THEORY_DATATYPES))
1357
  {
1358
3860
    opts.set(options::quantDynamicSplit, options::QuantDSplitMode::NONE);
1359
  }
1360
1361
  // until bugs 371,431 are fixed
1362
8954
  if (!opts.wasSetByUser(options::minisatUseElim))
1363
  {
1364
    // cannot use minisat elimination for logics where a theory solver
1365
    // introduces new literals into the search. This includes quantifiers
1366
    // (quantifier instantiation), and the lemma schemas used in non-linear
1367
    // and sets. We also can't use it if models are enabled.
1368
17908
    if (logic.isTheoryEnabled(THEORY_SETS)
1369
5079
        || logic.isTheoryEnabled(THEORY_BAGS)
1370
5079
        || logic.isQuantified()
1371
2589
        || options::produceModels() || options::produceAssignments()
1372
2051
        || options::checkModels()
1373
11005
        || (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()))
1374
    {
1375
7284
      opts.set(options::minisatUseElim, false);
1376
    }
1377
  }
1378
1379
25264
  if (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
1380
24096
      && options::nlRlvMode() != options::NlRlvMode::NONE)
1381
  {
1382
9040
    if (!options::relevanceFilter())
1383
    {
1384
20
      if (opts.wasSetByUser(options::relevanceFilter))
1385
      {
1386
        Warning() << "SmtEngine: turning on relevance filtering to support "
1387
                     "--nl-ext-rlv="
1388
                  << options::nlRlvMode() << std::endl;
1389
      }
1390
      // must use relevance filtering techniques
1391
20
      opts.set(options::relevanceFilter, true);
1392
    }
1393
  }
1394
1395
  // For now, these array theory optimizations do not support model-building
1396
23435
  if (options::produceModels() || options::produceAssignments()
1397
14481
      || options::checkModels())
1398
  {
1399
42777
    opts.set(options::arraysOptimizeLinear, false);
1400
  }
1401
1402
26822
  if (!options::bitvectorEqualitySolver())
1403
  {
1404
2
    if (options::bvLazyRewriteExtf())
1405
    {
1406
2
      if (opts.wasSetByUser(options::bvLazyRewriteExtf))
1407
      {
1408
        throw OptionException(
1409
            "--bv-lazy-rewrite-extf requires --bv-eq-solver to be set");
1410
      }
1411
    }
1412
4
    Trace("smt")
1413
2
        << "disabling bvLazyRewriteExtf since equality solver is disabled"
1414
2
        << std::endl;
1415
2
    opts.set(options::bvLazyRewriteExtf, false);
1416
  }
1417
1418
108021
  if (options::stringFMF() && !opts.wasSetByUser(options::stringProcessLoopMode))
1419
  {
1420
84
    Trace("smt") << "settting stringProcessLoopMode to 'simple' since "
1421
42
                    "--strings-fmf enabled"
1422
42
                 << std::endl;
1423
42
    opts.set(options::stringProcessLoopMode, options::ProcessLoopMode::SIMPLE);
1424
  }
1425
1426
  // !!! All options that require disabling models go here
1427
8954
  bool disableModels = false;
1428
17908
  std::string sOptNoModel;
1429
8954
  if (opts.wasSetByUser(options::unconstrainedSimp) && options::unconstrainedSimp())
1430
  {
1431
104
    disableModels = true;
1432
104
    sOptNoModel = "unconstrained-simp";
1433
  }
1434
8850
  else if (options::sortInference())
1435
  {
1436
20
    disableModels = true;
1437
20
    sOptNoModel = "sort-inference";
1438
  }
1439
8830
  else if (options::minisatUseElim())
1440
  {
1441
1607
    disableModels = true;
1442
1607
    sOptNoModel = "minisat-elimination";
1443
  }
1444
7223
  else if (options::globalNegate())
1445
  {
1446
6
    disableModels = true;
1447
6
    sOptNoModel = "global-negate";
1448
  }
1449
8954
  if (disableModels)
1450
  {
1451
1737
    if (options::produceModels())
1452
    {
1453
47
      if (opts.wasSetByUser(options::produceModels))
1454
      {
1455
        std::stringstream ss;
1456
        ss << "Cannot use " << sOptNoModel << " with model generation.";
1457
        throw OptionException(ss.str());
1458
      }
1459
47
      Notice() << "SmtEngine: turning off produce-models to support "
1460
               << sOptNoModel << std::endl;
1461
47
      opts.set(options::produceModels, false);
1462
    }
1463
1737
    if (options::produceAssignments())
1464
    {
1465
46
      if (opts.wasSetByUser(options::produceAssignments))
1466
      {
1467
        std::stringstream ss;
1468
        ss << "Cannot use " << sOptNoModel
1469
           << " with model generation (produce-assignments).";
1470
        throw OptionException(ss.str());
1471
      }
1472
46
      Notice() << "SmtEngine: turning off produce-assignments to support "
1473
               << sOptNoModel << std::endl;
1474
46
      opts.set(options::produceAssignments, false);
1475
    }
1476
1737
    if (options::checkModels())
1477
    {
1478
46
      if (opts.wasSetByUser(options::checkModels))
1479
      {
1480
        std::stringstream ss;
1481
        ss << "Cannot use " << sOptNoModel
1482
           << " with model generation (check-models).";
1483
        throw OptionException(ss.str());
1484
      }
1485
46
      Notice() << "SmtEngine: turning off check-models to support "
1486
               << sOptNoModel << std::endl;
1487
46
      opts.set(options::checkModels, false);
1488
    }
1489
  }
1490
1491
17908
  if (options::bitblastMode() == options::BitblastMode::EAGER
1492
8986
      && !logic.isPure(THEORY_BV) && logic.getLogicString() != "QF_UFBV"
1493
17908
      && logic.getLogicString() != "QF_ABV")
1494
  {
1495
    throw OptionException(
1496
        "Eager bit-blasting does not currently support theory combination. "
1497
        "Note that in a QF_BV problem UF symbols can be introduced for "
1498
        "division. "
1499
        "Try --bv-div-zero-const to interpret division by zero as a constant.");
1500
  }
1501
1502
8954
  if (logic == LogicInfo("QF_UFNRA"))
1503
  {
1504
#ifdef CVC5_USE_POLY
1505
1533
    if (!options::nlCad() && !opts.wasSetByUser(options::nlCad))
1506
    {
1507
98
      opts.set(options::nlCad, true);
1508
2408
      if (!opts.wasSetByUser(options::nlExt))
1509
      {
1510
46
        opts.set(options::nlExt, options::NlExtMode::LIGHT);
1511
      }
1512
98
      if (!opts.wasSetByUser(options::nlRlvMode))
1513
      {
1514
98
        opts.set(options::nlRlvMode, options::NlRlvMode::INTERLEAVE);
1515
      }
1516
    }
1517
#endif
1518
  }
1519
#ifndef CVC5_USE_POLY
1520
  if (options::nlCad())
1521
  {
1522
    if (opts.wasSetByUser(options::nlCad))
1523
    {
1524
      std::stringstream ss;
1525
      ss << "Cannot use " << options::nlCad.name << " without configuring with --poly.";
1526
      throw OptionException(ss.str());
1527
    }
1528
    else
1529
    {
1530
      Notice() << "Cannot use --" << options::nlCad.name
1531
               << " without configuring with --poly." << std::endl;
1532
      opts.set(options::nlCad, false);
1533
      opts.set(options::nlExt, options::NlExtMode::FULL);
1534
    }
1535
  }
1536
#endif
1537
8954
}
1538
1539
}  // namespace smt
1540
19893979
}  // namespace cvc5