GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 586 709 82.7 %
Date: 2021-05-22 Branches: 1811 3650 49.6 %

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
9460
void setDefaults(LogicInfo& logic, bool isInternalSubsolver)
51
{
52
9460
  Options& opts = Options::current();
53
  // implied options
54
22967
  if (options::debugCheckModels())
55
  {
56
56789
    opts.set(options::checkModels, true);
57
  }
58
318852
  if (options::checkModels() || options::dumpModels())
59
  {
60
1250
    opts.set(options::produceModels, true);
61
  }
62
9460
  if (options::checkModels())
63
  {
64
20573
    opts.set(options::produceAssignments, true);
65
  }
66
  // unsat cores and proofs shenanigans
67
9460
  if (options::dumpUnsatCoresFull())
68
  {
69
309545
    opts.set(options::dumpUnsatCores, true);
70
  }
71
53242
  if (options::checkUnsatCores() || options::dumpUnsatCores()
72
8361
      || options::unsatAssumptions()
73
17807
      || options::unsatCoresMode() != options::UnsatCoresMode::OFF)
74
  {
75
2491
    opts.set(options::unsatCores, true);
76
  }
77
18920
  if (options::unsatCores()
78
9460
      && options::unsatCoresMode() == options::UnsatCoresMode::OFF)
79
  {
80
1117
    if (opts.wasSetByUser(options::unsatCoresMode))
81
    {
82
      Notice()
83
          << "Overriding OFF unsat-core mode since cores were requested.\n";
84
    }
85
1117
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::ASSUMPTIONS);
86
  }
87
88
347569
  if (options::checkProofs() || options::dumpProofs())
89
  {
90
1116
    opts.set(options::produceProofs, true);
91
  }
92
93
18920
  if (options::produceProofs()
94
9460
      && options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF)
95
  {
96
1171
    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
1171
    opts.set(options::unsatCores, true);
103
1171
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::FULL_PROOF);
104
  }
105
106
  // set proofs on if not yet set
107
9460
  if (options::unsatCores() && !options::produceProofs())
108
  {
109
2420
    if (opts.wasSetByUser(options::produceProofs))
110
    {
111
16
      Notice()
112
          << "Forcing proof production since new unsat cores were requested.\n";
113
    }
114
2420
    opts.set(options::produceProofs, true);
115
  }
116
117
  // if unsat cores are disabled, then unsat cores mode should be OFF
118
9460
  Assert(options::unsatCores()
119
         == (options::unsatCoresMode() != options::UnsatCoresMode::OFF));
120
121
18920
  if (opts.wasSetByUser(options::bitvectorAigSimplifications))
122
  {
123
    Notice() << "SmtEngine: setting bitvectorAig" << std::endl;
124
2453
    opts.set(options::bitvectorAig, true);
125
  }
126
18920
  if (opts.wasSetByUser(options::bitvectorAlgebraicBudget))
127
  {
128
    Notice() << "SmtEngine: setting bitvectorAlgebraicSolver" << std::endl;
129
9405
    opts.set(options::bitvectorAlgebraicSolver, true);
130
  }
131
132
9460
  bool isSygus = language::isInputLangSygus(options::inputLanguage());
133
9460
  bool usesSygus = isSygus;
134
135
9460
  if (options::bitblastMode() == options::BitblastMode::EAGER)
136
  {
137
84
    if (options::produceModels()
138
42
        && (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
42
    else if (!options::incrementalSolving())
154
    {
155
32
      opts.set(options::ackermann, true);
156
    }
157
158
42
    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
60389
  if (options::bvSolver() == options::BVSolver::SIMPLE
169
9460
      || options::bvSolver() == options::BVSolver::BITBLAST)
170
  {
171
87
    opts.set(options::bvLazyReduceExtf, false);
172
1234
    opts.set(options::bvLazyRewriteExtf, false);
173
  }
174
175
  /* Disable bit-level propagation by default for the BITBLAST solver. */
176
9460
  if (options::bvSolver() == options::BVSolver::BITBLAST)
177
  {
178
9405
    opts.set(options::bitvectorPropagate, false);
179
  }
180
181
9460
  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
9460
  if (options::solveBVAsInt() != options::SolveBVAsIntMode::OFF)
200
  {
201
159
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
202
    {
203
      throw OptionException(
204
          "solving bitvectors as integers is incompatible with --bool-to-bv.");
205
    }
206
159
    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
159
    if (logic.isTheoryEnabled(THEORY_BV))
218
    {
219
155
      logic = logic.getUnlockedCopy();
220
155
      logic.enableTheory(THEORY_ARITH);
221
155
      logic.arithNonLinear();
222
155
      logic.lock();
223
    }
224
  }
225
226
  // set options about ackermannization
227
18990
  if (options::ackermann() && options::produceModels()
228
9473
      && (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
9460
  if (options::ackermann())
242
  {
243
66
    if (options::incrementalSolving())
244
    {
245
      throw OptionException(
246
          "Incremental Ackermannization is currently not supported.");
247
    }
248
249
66
    if (logic.isQuantified())
250
    {
251
      throw LogicException("Cannot use Ackermannization on quantified formula");
252
    }
253
254
66
    if (logic.isTheoryEnabled(THEORY_UF))
255
    {
256
33
      logic = logic.getUnlockedCopy();
257
33
      logic.disableTheory(THEORY_UF);
258
33
      logic.lock();
259
    }
260
66
    if (logic.isTheoryEnabled(THEORY_ARRAYS))
261
    {
262
7
      logic = logic.getUnlockedCopy();
263
7
      logic.disableTheory(THEORY_ARRAYS);
264
7
      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
9460
  if (options::doITESimp())
273
  {
274
3
    if (!opts.wasSetByUser(options::earlyIteRemoval))
275
    {
276
3
      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
9460
  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
134017
    opts.set(options::stringExp, true);
288
  }
289
9460
  if (options::stringExp() || !options::stringLazyPreproc())
290
  {
291
    // We require quantifiers since extended functions reduce using them.
292
1031
    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
49764
    if (!opts.wasSetByUser(options::fmfBound))
302
    {
303
1029
      opts.set(options::fmfBound, true);
304
1029
      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
9460
  bool disableProofs = false;
311
9460
  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
18920
  if (options::unsatCores()
320
9460
      && options::unsatCoresMode() != options::UnsatCoresMode::FULL_PROOF)
321
  {
322
    // no fine-graininess
323
2409
    if (!opts.wasSetByUser(options::proofGranularityMode))
324
    {
325
2409
      opts.set(options::proofGranularityMode, options::ProofGranularityMode::OFF);
326
    }
327
  }
328
329
18947
  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
9460
  if (!isInternalSubsolver)
347
  {
348
13770
    if (options::produceAbducts()
349
6870
        || options::produceInterpols() != options::ProduceInterpols::NONE
350
13745
        || options::sygusInference() || options::sygusRewSynthInput())
351
    {
352
      // since we are trying to recast as sygus, we assume the input is sygus
353
83
      isSygus = true;
354
83
      usesSygus = true;
355
    }
356
35284
    else if (options::sygusInst())
357
    {
358
      // sygus instantiation uses sygus, but it is not a sygus problem
359
17
      usesSygus = true;
360
    }
361
  }
362
363
  // We now know whether the input uses sygus. Update the logic to incorporate
364
  // the theories we need internally for handling sygus problems.
365
9460
  if (usesSygus)
366
  {
367
813
    logic = logic.getUnlockedCopy();
368
813
    logic.enableSygus();
369
813
    logic.lock();
370
813
    if (isSygus)
371
    {
372
      // When sygus answers "unsat", it is not due to showing a set of
373
      // formulas is unsat in the standard way. Thus, proofs do not apply.
374
796
      disableProofs = true;
375
    }
376
  }
377
378
  // if we requiring disabling proofs, disable them now
379
9460
  if (disableProofs && options::produceProofs())
380
  {
381
8
    opts.set(options::unsatCores, false);
382
8
    opts.set(options::unsatCoresMode, options::UnsatCoresMode::OFF);
383
8
    if (options::produceProofs())
384
    {
385
8
      Notice() << "SmtEngine: turning off produce-proofs." << std::endl;
386
    }
387
8
    opts.set(options::produceProofs, false);
388
8
    opts.set(options::checkProofs, false);
389
8
    opts.set(options::proofEagerChecking, false);
390
  }
391
392
  // sygus core connective requires unsat cores
393
20454
  if (options::sygusCoreConnective())
394
  {
395
72
    opts.set(options::unsatCores, true);
396
72
    if (options::unsatCoresMode() == options::UnsatCoresMode::OFF)
397
    {
398
5
      opts.set(options::unsatCoresMode, options::UnsatCoresMode::ASSUMPTIONS);
399
    }
400
  }
401
402
35893
  if ((options::checkModels() || options::checkSynthSol()
403
7565
       || options::produceAbducts()
404
7244
       || options::produceInterpols() != options::ProduceInterpols::NONE
405
14289
       || options::modelCoresMode() != options::ModelCoresMode::NONE
406
14307
       || options::blockModelsMode() != options::BlockModelsMode::NONE
407
7106
       || options::produceProofs())
408
15319
      && !options::produceAssertions())
409
  {
410
3610
    Notice() << "SmtEngine: turning on produce-assertions to support "
411
1
             << "option requiring assertions." << std::endl;
412
3609
    opts.set(options::produceAssertions, true);
413
  }
414
415
  // whether we want to force safe unsat cores, i.e., if we are in the default
416
  // ASSUMPTIONS mode, since other ones are experimental
417
  bool safeUnsatCores =
418
9460
      options::unsatCoresMode() == options::UnsatCoresMode::ASSUMPTIONS;
419
420
  // Disable options incompatible with incremental solving, unsat cores or
421
  // output an error if enabled explicitly. It is also currently incompatible
422
  // with arithmetic, force the option off.
423
9460
  if (options::incrementalSolving() || safeUnsatCores)
424
  {
425
3929
    if (options::unconstrainedSimp())
426
    {
427
      if (opts.wasSetByUser(options::unconstrainedSimp))
428
      {
429
        throw OptionException(
430
            "unconstrained simplification not supported with old unsat "
431
            "cores/incremental solving");
432
      }
433
      Notice() << "SmtEngine: turning off unconstrained simplification to "
434
                  "support old unsat cores/incremental solving"
435
               << std::endl;
436
      opts.set(options::unconstrainedSimp, false);
437
    }
438
  }
439
  else
440
  {
441
    // Turn on unconstrained simplification for QF_AUFBV
442
5531
    if (!opts.wasSetByUser(options::unconstrainedSimp))
443
    {
444
6944
      bool uncSimp = !logic.isQuantified() && !options::produceModels()
445
1132
                     && !options::produceAssignments()
446
1131
                     && !options::checkModels()
447
1131
                     && logic.isTheoryEnabled(THEORY_ARRAYS)
448
166
                     && logic.isTheoryEnabled(THEORY_BV)
449
5509
                     && !logic.isTheoryEnabled(THEORY_ARITH);
450
10850
      Trace("smt") << "setting unconstrained simplification to " << uncSimp
451
5425
                   << std::endl;
452
5425
      opts.set(options::unconstrainedSimp, uncSimp);
453
    }
454
  }
455
456
9460
  if (options::incrementalSolving())
457
  {
458
2048
    if (options::sygusInference())
459
    {
460
      if (opts.wasSetByUser(options::sygusInference))
461
      {
462
        throw OptionException(
463
            "sygus inference not supported with incremental solving");
464
      }
465
      Notice() << "SmtEngine: turning off sygus inference to support "
466
                  "incremental solving"
467
               << std::endl;
468
      opts.set(options::sygusInference, false);
469
    }
470
  }
471
472
9460
  if (options::solveBVAsInt() != options::SolveBVAsIntMode::OFF)
473
  {
474
    /**
475
     * Operations on 1 bits are better handled as Boolean operations
476
     * than as integer operations.
477
     * Therefore, we enable bv-to-bool, which runs before
478
     * the translation to integers.
479
     */
480
159
    opts.set(options::bitvectorToBool, true);
481
  }
482
483
  // Disable options incompatible with unsat cores or output an error if enabled
484
  // explicitly
485
9460
  if (safeUnsatCores)
486
  {
487
2414
    if (options::simplificationMode() != options::SimplificationMode::NONE)
488
    {
489
1105
      if (opts.wasSetByUser(options::simplificationMode))
490
      {
491
        throw OptionException(
492
            "simplification not supported with old unsat cores");
493
      }
494
1105
      Notice() << "SmtEngine: turning off simplification to support unsat "
495
                  "cores"
496
               << std::endl;
497
1105
      opts.set(options::simplificationMode, options::SimplificationMode::NONE);
498
    }
499
500
2414
    if (options::pbRewrites())
501
    {
502
      if (opts.wasSetByUser(options::pbRewrites))
503
      {
504
        throw OptionException(
505
            "pseudoboolean rewrites not supported with old unsat cores");
506
      }
507
      Notice() << "SmtEngine: turning off pseudoboolean rewrites to support "
508
                  "old unsat cores\n";
509
      opts.set(options::pbRewrites, false);
510
    }
511
512
2414
    if (options::sortInference())
513
    {
514
      if (opts.wasSetByUser(options::sortInference))
515
      {
516
        throw OptionException(
517
            "sort inference not supported with old unsat cores");
518
      }
519
      Notice() << "SmtEngine: turning off sort inference to support old unsat "
520
                  "cores\n";
521
      opts.set(options::sortInference, false);
522
    }
523
524
97139
    if (options::preSkolemQuant())
525
    {
526
3
      if (opts.wasSetByUser(options::preSkolemQuant))
527
      {
528
        throw OptionException(
529
            "pre-skolemization not supported with old unsat cores");
530
      }
531
3
      Notice() << "SmtEngine: turning off pre-skolemization to support old "
532
                  "unsat cores\n";
533
3
      opts.set(options::preSkolemQuant, false);
534
    }
535
536
2414
    if (options::bitvectorToBool())
537
    {
538
62
      if (opts.wasSetByUser(options::bitvectorToBool))
539
      {
540
        throw OptionException("bv-to-bool not supported with old unsat cores");
541
      }
542
62
      Notice() << "SmtEngine: turning off bitvector-to-bool to support old "
543
                  "unsat cores\n";
544
62
      opts.set(options::bitvectorToBool, false);
545
    }
546
547
2414
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
548
    {
549
      if (opts.wasSetByUser(options::boolToBitvector))
550
      {
551
        throw OptionException(
552
            "bool-to-bv != off not supported with old unsat cores");
553
      }
554
      Notice()
555
          << "SmtEngine: turning off bool-to-bv to support old unsat cores\n";
556
      opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
557
    }
558
559
2414
    if (options::bvIntroducePow2())
560
    {
561
      if (opts.wasSetByUser(options::bvIntroducePow2))
562
      {
563
        throw OptionException(
564
            "bv-intro-pow2 not supported with old unsat cores");
565
      }
566
      Notice()
567
          << "SmtEngine: turning off bv-intro-pow2 to support old unsat cores";
568
      opts.set(options::bvIntroducePow2, false);
569
    }
570
571
2414
    if (options::repeatSimp())
572
    {
573
      if (opts.wasSetByUser(options::repeatSimp))
574
      {
575
        throw OptionException("repeat-simp not supported with old unsat cores");
576
      }
577
      Notice()
578
          << "SmtEngine: turning off repeat-simp to support old unsat cores\n";
579
      opts.set(options::repeatSimp, false);
580
    }
581
582
2414
    if (options::globalNegate())
583
    {
584
      if (opts.wasSetByUser(options::globalNegate))
585
      {
586
        throw OptionException(
587
            "global-negate not supported with old unsat cores");
588
      }
589
      Notice() << "SmtEngine: turning off global-negate to support old unsat "
590
                  "cores\n";
591
      opts.set(options::globalNegate, false);
592
    }
593
594
2414
    if (options::bitvectorAig())
595
    {
596
      throw OptionException("bitblast-aig not supported with old unsat cores");
597
    }
598
599
2414
    if (options::doITESimp())
600
    {
601
1
      throw OptionException("ITE simp not supported with old unsat cores");
602
    }
603
  }
604
  else
605
  {
606
    // by default, nonclausal simplification is off for QF_SAT
607
7046
    if (!opts.wasSetByUser(options::simplificationMode))
608
    {
609
7020
      bool qf_sat = logic.isPure(THEORY_BOOL) && !logic.isQuantified();
610
14040
      Trace("smt") << "setting simplification mode to <"
611
7020
                   << logic.getLogicString() << "> " << (!qf_sat) << std::endl;
612
      // simplification=none works better for SMT LIB benchmarks with
613
      // quantifiers, not others opts.set(options::simplificationMode, qf_sat ||
614
      // quantifiers ? options::SimplificationMode::NONE :
615
      // options::SimplificationMode::BATCH);
616
7020
      opts.set(options::simplificationMode, qf_sat
617
14040
                                          ? options::SimplificationMode::NONE
618
                                          : options::SimplificationMode::BATCH);
619
    }
620
  }
621
622
30786
  if (options::cegqiBv() && logic.isQuantified())
623
  {
624
5180
    if (options::boolToBitvector() != options::BoolToBVMode::OFF)
625
    {
626
      if (opts.wasSetByUser(options::boolToBitvector))
627
      {
628
        throw OptionException(
629
            "bool-to-bv != off not supported with CBQI BV for quantified "
630
            "logics");
631
      }
632
      Notice() << "SmtEngine: turning off bool-to-bitvector to support CBQI BV"
633
               << std::endl;
634
      opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
635
    }
636
  }
637
638
  // cases where we need produce models
639
18918
  if (!options::produceModels()
640
16047
      && (options::produceAssignments() || options::sygusRewSynthCheck()
641
6305
          || usesSygus))
642
  {
643
268
    Notice() << "SmtEngine: turning on produce-models" << std::endl;
644
268
    opts.set(options::produceModels, true);
645
  }
646
647
  /////////////////////////////////////////////////////////////////////////////
648
  // Theory widening
649
  //
650
  // Some theories imply the use of other theories to handle certain operators,
651
  // e.g. UF to handle partial functions.
652
  /////////////////////////////////////////////////////////////////////////////
653
9459
  bool needsUf = false;
654
  // strings require LIA, UF; widen the logic
655
9459
  if (logic.isTheoryEnabled(THEORY_STRINGS))
656
  {
657
8716
    LogicInfo log(logic.getUnlockedCopy());
658
    // Strings requires arith for length constraints, and also UF
659
4358
    needsUf = true;
660
4358
    if (!logic.isTheoryEnabled(THEORY_ARITH) || logic.isDifferenceLogic())
661
    {
662
127
      Notice()
663
          << "Enabling linear integer arithmetic because strings are enabled"
664
          << std::endl;
665
127
      log.enableTheory(THEORY_ARITH);
666
127
      log.enableIntegers();
667
127
      log.arithOnlyLinear();
668
    }
669
4231
    else if (!logic.areIntegersUsed())
670
    {
671
      Notice() << "Enabling integer arithmetic because strings are enabled"
672
               << std::endl;
673
      log.enableIntegers();
674
    }
675
4358
    logic = log;
676
4358
    logic.lock();
677
  }
678
9459
  if (options::bvAbstraction())
679
  {
680
    // bv abstraction may require UF
681
4
    Notice() << "Enabling UF because bvAbstraction requires it." << std::endl;
682
4
    needsUf = true;
683
  }
684
38147
  else if (options::preSkolemQuantNested()
685
9455
           && opts.wasSetByUser(options::preSkolemQuantNested))
686
  {
687
    // if pre-skolem nested is explictly set, then we require UF. If it is
688
    // not explicitly set, it is disabled below if UF is not present.
689
2
    Notice() << "Enabling UF because preSkolemQuantNested requires it."
690
             << std::endl;
691
2
    needsUf = true;
692
  }
693
9459
  if (needsUf
694
      // Arrays, datatypes and sets permit Boolean terms and thus require UF
695
5095
      || logic.isTheoryEnabled(THEORY_ARRAYS)
696
4363
      || logic.isTheoryEnabled(THEORY_DATATYPES)
697
3183
      || logic.isTheoryEnabled(THEORY_SETS)
698
3108
      || logic.isTheoryEnabled(THEORY_BAGS)
699
      // Non-linear arithmetic requires UF to deal with division/mod because
700
      // their expansion introduces UFs for the division/mod-by-zero case.
701
      // If we are eliminating non-linear arithmetic via solve-int-as-bv,
702
      // then this is not required, since non-linear arithmetic will be
703
      // eliminated altogether (or otherwise fail at preprocessing).
704
3108
      || (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
705
598
          && options::solveIntAsBV() == 0)
706
      // FP requires UF since there are multiple operators that are partially
707
      // defined (see http://smtlib.cs.uiowa.edu/papers/BTRW15.pdf for more
708
      // details).
709
11969
      || logic.isTheoryEnabled(THEORY_FP))
710
  {
711
7009
    if (!logic.isTheoryEnabled(THEORY_UF))
712
    {
713
1724
      LogicInfo log(logic.getUnlockedCopy());
714
862
      if (!needsUf)
715
      {
716
517
        Notice() << "Enabling UF because " << logic << " requires it."
717
                 << std::endl;
718
      }
719
862
      log.enableTheory(THEORY_UF);
720
862
      logic = log;
721
862
      logic.lock();
722
    }
723
  }
724
9459
  if (options::arithMLTrick())
725
  {
726
8
    if (!logic.areIntegersUsed())
727
    {
728
      // enable integers
729
      LogicInfo log(logic.getUnlockedCopy());
730
      Notice() << "Enabling integers because arithMLTrick requires it."
731
               << std::endl;
732
      log.enableIntegers();
733
      logic = log;
734
      logic.lock();
735
    }
736
  }
737
  /////////////////////////////////////////////////////////////////////////////
738
739
  // Set the options for the theoryOf
740
9459
  if (!opts.wasSetByUser(options::theoryOfMode))
741
  {
742
26277
    if (logic.isSharingEnabled() && !logic.isTheoryEnabled(THEORY_BV)
743
2723
        && !logic.isTheoryEnabled(THEORY_STRINGS)
744
2233
        && !logic.isTheoryEnabled(THEORY_SETS)
745
2147
        && !logic.isTheoryEnabled(THEORY_BAGS)
746
12265
        && !(logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
747
665
             && !logic.isQuantified()))
748
    {
749
1735
      Trace("smt") << "setting theoryof-mode to term-based" << std::endl;
750
1735
      opts.set(options::theoryOfMode, options::TheoryOfMode::THEORY_OF_TERM_BASED);
751
    }
752
  }
753
754
  // by default, symmetry breaker is on only for non-incremental QF_UF
755
146759
  if (!opts.wasSetByUser(options::ufSymmetryBreaker))
756
  {
757
9803
    bool qf_uf_noinc = logic.isPure(THEORY_UF) && !logic.isQuantified()
758
9720
                       && !options::incrementalSolving() && !safeUnsatCores;
759
18918
    Trace("smt") << "setting uf symmetry breaker to " << qf_uf_noinc
760
9459
                 << std::endl;
761
9459
    opts.set(options::ufSymmetryBreaker, qf_uf_noinc);
762
  }
763
764
  // If in arrays, set the UF handler to arrays
765
23520
  if (logic.isTheoryEnabled(THEORY_ARRAYS) && !options::ufHo()
766
9530228
      && !options::finiteModelFind()
767
14224
      && (!logic.isQuantified()
768
3863
          || (logic.isQuantified() && !logic.isTheoryEnabled(THEORY_UF))))
769
  {
770
451
    Theory::setUninterpretedSortOwner(THEORY_ARRAYS);
771
  }
772
  else
773
  {
774
9008
    Theory::setUninterpretedSortOwner(THEORY_UF);
775
  }
776
777
9459
  if (!opts.wasSetByUser(options::simplifyWithCareEnabled))
778
  {
779
    bool qf_aufbv =
780
12505
        !logic.isQuantified() && logic.isTheoryEnabled(THEORY_ARRAYS)
781
9914
        && logic.isTheoryEnabled(THEORY_UF) && logic.isTheoryEnabled(THEORY_BV);
782
783
9459
    bool withCare = qf_aufbv;
784
18918
    Trace("smt") << "setting ite simplify with care to " << withCare
785
9459
                 << std::endl;
786
9459
    opts.set(options::simplifyWithCareEnabled, withCare);
787
  }
788
  // Turn off array eager index splitting for QF_AUFLIA
789
36086
  if (!opts.wasSetByUser(options::arraysEagerIndexSplitting))
790
  {
791
21964
    if (not logic.isQuantified() && logic.isTheoryEnabled(THEORY_ARRAYS)
792
455
        && logic.isTheoryEnabled(THEORY_UF)
793
9914
        && logic.isTheoryEnabled(THEORY_ARITH))
794
    {
795
352
      Trace("smt") << "setting array eager index splitting to false"
796
176
                   << std::endl;
797
176
      opts.set(options::arraysEagerIndexSplitting, false);
798
    }
799
  }
800
  // Turn on multiple-pass non-clausal simplification for QF_AUFBV
801
9459
  if (!opts.wasSetByUser(options::repeatSimp))
802
  {
803
9457
    bool repeatSimp = !logic.isQuantified()
804
3044
                      && (logic.isTheoryEnabled(THEORY_ARRAYS)
805
455
                          && logic.isTheoryEnabled(THEORY_UF)
806
455
                          && logic.isTheoryEnabled(THEORY_BV))
807
9730
                      && !safeUnsatCores;
808
18914
    Trace("smt") << "setting repeat simplification to " << repeatSimp
809
9457
                 << std::endl;
810
9457
    opts.set(options::repeatSimp, repeatSimp);
811
  }
812
813
18918
  if (options::boolToBitvector() == options::BoolToBVMode::ALL
814
9459
      && !logic.isTheoryEnabled(THEORY_BV))
815
  {
816
    if (opts.wasSetByUser(options::boolToBitvector))
817
    {
818
      throw OptionException(
819
          "bool-to-bv=all not supported for non-bitvector logics.");
820
    }
821
    Notice() << "SmtEngine: turning off bool-to-bv for non-bv logic: "
822
             << logic.getLogicString() << std::endl;
823
    opts.set(options::boolToBitvector, options::BoolToBVMode::OFF);
824
  }
825
826
18918
  if (!opts.wasSetByUser(options::bvEagerExplanations)
827
9459
      && logic.isTheoryEnabled(THEORY_ARRAYS)
828
14061
      && logic.isTheoryEnabled(THEORY_BV))
829
  {
830
4202
    Trace("smt") << "enabling eager bit-vector explanations " << std::endl;
831
4202
    opts.set(options::bvEagerExplanations, true);
832
  }
833
834
  // Turn on arith rewrite equalities only for pure arithmetic
835
59874
  if (!opts.wasSetByUser(options::arithRewriteEq))
836
  {
837
    bool arithRewriteEq =
838
9450
        logic.isPure(THEORY_ARITH) && logic.isLinear() && !logic.isQuantified();
839
18900
    Trace("smt") << "setting arith rewrite equalities " << arithRewriteEq
840
9450
                 << std::endl;
841
9450
    opts.set(options::arithRewriteEq, arithRewriteEq);
842
  }
843
182079
  if (!opts.wasSetByUser(options::arithHeuristicPivots))
844
  {
845
9459
    int16_t heuristicPivots = 5;
846
9459
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
847
    {
848
732
      if (logic.isDifferenceLogic())
849
      {
850
19
        heuristicPivots = -1;
851
      }
852
713
      else if (!logic.areIntegersUsed())
853
      {
854
248
        heuristicPivots = 0;
855
      }
856
    }
857
18918
    Trace("smt") << "setting arithHeuristicPivots  " << heuristicPivots
858
9459
                 << std::endl;
859
9459
    opts.set(options::arithHeuristicPivots, heuristicPivots);
860
  }
861
415457
  if (!opts.wasSetByUser(options::arithPivotThreshold))
862
  {
863
9459
    uint16_t pivotThreshold = 2;
864
9459
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
865
    {
866
732
      if (logic.isDifferenceLogic())
867
      {
868
19
        pivotThreshold = 16;
869
      }
870
    }
871
18918
    Trace("smt") << "setting arith arithPivotThreshold  " << pivotThreshold
872
9459
                 << std::endl;
873
9459
    opts.set(options::arithPivotThreshold, pivotThreshold);
874
  }
875
139477
  if (!opts.wasSetByUser(options::arithStandardCheckVarOrderPivots))
876
  {
877
9459
    int16_t varOrderPivots = -1;
878
9459
    if (logic.isPure(THEORY_ARITH) && !logic.isQuantified())
879
    {
880
732
      varOrderPivots = 200;
881
    }
882
18918
    Trace("smt") << "setting arithStandardCheckVarOrderPivots  "
883
9459
                 << varOrderPivots << std::endl;
884
9459
    opts.set(options::arithStandardCheckVarOrderPivots, varOrderPivots);
885
  }
886
9459
  if (logic.isPure(THEORY_ARITH) && !logic.areRealsUsed())
887
  {
888
1659
    if (!opts.wasSetByUser(options::nlExtTangentPlanesInterleave))
889
    {
890
1010
      Trace("smt") << "setting nlExtTangentPlanesInterleave to true"
891
505
                   << std::endl;
892
505
      opts.set(options::nlExtTangentPlanesInterleave, true);
893
    }
894
  }
895
896
  // Set decision mode based on logic (if not set by user)
897
9459
  if (!opts.wasSetByUser(options::decisionMode))
898
  {
899
    options::DecisionMode decMode =
900
        // anything that uses sygus uses internal
901
17915
        usesSygus ? options::DecisionMode::INTERNAL :
902
                  // ALL
903
8564
            logic.hasEverything()
904
13438
                ? options::DecisionMode::JUSTIFICATION
905
                : (  // QF_BV
906
12029
                      (not logic.isQuantified() && logic.isPure(THEORY_BV)) ||
907
                              // QF_AUFBV or QF_ABV or QF_UFBV
908
4161
                              (not logic.isQuantified()
909
2281
                               && (logic.isTheoryEnabled(THEORY_ARRAYS)
910
1846
                                   || logic.isTheoryEnabled(THEORY_UF))
911
1523
                               && logic.isTheoryEnabled(THEORY_BV))
912
3742
                              ||
913
                              // QF_AUFLIA (and may be ends up enabling
914
                              // QF_AUFLRA?)
915
3742
                              (not logic.isQuantified()
916
1862
                               && logic.isTheoryEnabled(THEORY_ARRAYS)
917
174
                               && logic.isTheoryEnabled(THEORY_UF)
918
174
                               && logic.isTheoryEnabled(THEORY_ARITH))
919
3672
                              ||
920
                              // QF_LRA
921
3672
                              (not logic.isQuantified()
922
1792
                               && logic.isPure(THEORY_ARITH) && logic.isLinear()
923
732
                               && !logic.isDifferenceLogic()
924
713
                               && !logic.areIntegersUsed())
925
3424
                              ||
926
                              // Quantifiers
927
4968
                              logic.isQuantified() ||
928
                              // Strings
929
1544
                              logic.isTheoryEnabled(THEORY_STRINGS)
930
8204
                          ? options::DecisionMode::JUSTIFICATION
931
9351
                          : options::DecisionMode::INTERNAL);
932
933
    bool stoponly =
934
        // ALL
935
14845
        logic.hasEverything() || logic.isTheoryEnabled(THEORY_STRINGS)
936
14769
            ? false
937
            : (  // QF_AUFLIA
938
5002
                  (not logic.isQuantified()
939
2994
                   && logic.isTheoryEnabled(THEORY_ARRAYS)
940
435
                   && logic.isTheoryEnabled(THEORY_UF)
941
435
                   && logic.isTheoryEnabled(THEORY_ARITH))
942
                          ||
943
                          // QF_LRA
944
4834
                          (not logic.isQuantified()
945
2826
                           && logic.isPure(THEORY_ARITH) && logic.isLinear()
946
732
                           && !logic.isDifferenceLogic()
947
713
                           && !logic.areIntegersUsed())
948
4834
                      ? true
949
9351
                      : false);
950
951
9351
    Trace("smt") << "setting decision mode to " << decMode << std::endl;
952
9351
    opts.set(options::decisionMode, decMode);
953
9351
    opts.set(options::decisionStopOnly, stoponly);
954
  }
955
9459
  if (options::incrementalSolving())
956
  {
957
    // disable modes not supported by incremental
958
2048
    opts.set(options::sortInference, false);
959
2048
    opts.set(options::ufssFairnessMonotone, false);
960
2048
    opts.set(options::globalNegate, false);
961
2048
    opts.set(options::bvAbstraction, false);
962
2048
    opts.set(options::arithMLTrick, false);
963
  }
964
9459
  if (logic.hasCardinalityConstraints())
965
  {
966
    // must have finite model finding on
967
26
    opts.set(options::finiteModelFind, true);
968
  }
969
970
185731
  if (options::instMaxLevel() != -1)
971
  {
972
4
    Notice() << "SmtEngine: turning off cbqi to support instMaxLevel"
973
             << std::endl;
974
4702709
    opts.set(options::cegqi, false);
975
  }
976
977
28714
  if ((opts.wasSetByUser(options::fmfBoundLazy) && options::fmfBoundLazy())
978
28395
      || (opts.wasSetByUser(options::fmfBoundInt) && options::fmfBoundInt()))
979
  {
980
18
    opts.set(options::fmfBound, true);
981
  }
982
  // now have determined whether fmfBoundInt is on/off
983
  // apply fmfBoundInt options
984
9459
  if (options::fmfBound())
985
  {
986
47933
    if (!opts.wasSetByUser(options::mbqiMode)
987
2194
        || (options::mbqiMode() != options::MbqiMode::NONE
988
            && options::mbqiMode() != options::MbqiMode::FMC))
989
    {
990
      // if bounded integers are set, use no MBQI by default
991
1097
      opts.set(options::mbqiMode, options::MbqiMode::NONE);
992
    }
993
412423
    if (!opts.wasSetByUser(options::prenexQuant))
994
    {
995
1097
      opts.set(options::prenexQuant, options::PrenexQuantMode::NONE);
996
    }
997
  }
998
9459
  if (options::ufHo())
999
  {
1000
    // if higher-order, then current variants of model-based instantiation
1001
    // cannot be used
1002
200
    if (options::mbqiMode() != options::MbqiMode::NONE)
1003
    {
1004
137
      opts.set(options::mbqiMode, options::MbqiMode::NONE);
1005
    }
1006
200
    if (!opts.wasSetByUser(options::hoElimStoreAx))
1007
    {
1008
      // by default, use store axioms only if --ho-elim is set
1009
199
      opts.set(options::hoElimStoreAx, options::hoElim());
1010
    }
1011
29306
    if (!options::assignFunctionValues())
1012
    {
1013
      // must assign function values
1014
2
      opts.set(options::assignFunctionValues, true);
1015
    }
1016
    // Cannot use macros, since lambda lifting and macro elimination are inverse
1017
    // operations.
1018
11502
    if (options::macrosQuant())
1019
    {
1020
      opts.set(options::macrosQuant, false);
1021
    }
1022
  }
1023
30849
  if (options::fmfFunWellDefinedRelevant())
1024
  {
1025
12
    if (!opts.wasSetByUser(options::fmfFunWellDefined))
1026
    {
1027
12
      opts.set(options::fmfFunWellDefined, true);
1028
    }
1029
  }
1030
9459
  if (options::fmfFunWellDefined())
1031
  {
1032
69
    if (!opts.wasSetByUser(options::finiteModelFind))
1033
    {
1034
67
      opts.set(options::finiteModelFind, true);
1035
    }
1036
  }
1037
1038
  // now, have determined whether finite model find is on/off
1039
  // apply finite model finding options
1040
9459
  if (options::finiteModelFind())
1041
  {
1042
    // apply conservative quantifiers splitting
1043
20367
    if (!opts.wasSetByUser(options::quantDynamicSplit))
1044
    {
1045
282
      opts.set(options::quantDynamicSplit, options::QuantDSplitMode::DEFAULT);
1046
    }
1047
7286
    if (!opts.wasSetByUser(options::eMatching))
1048
    {
1049
835
      opts.set(options::eMatching, options::fmfInstEngine());
1050
    }
1051
485647
    if (!opts.wasSetByUser(options::instWhenMode))
1052
    {
1053
      // instantiate only on last call
1054
282
      if (options::eMatching())
1055
      {
1056
8
        opts.set(options::instWhenMode, options::InstWhenMode::LAST_CALL);
1057
      }
1058
    }
1059
  }
1060
1061
  // apply sygus options
1062
  // if we are attempting to rewrite everything to SyGuS, use sygus()
1063
9459
  if (usesSygus)
1064
  {
1065
32043
    if (!options::sygus())
1066
    {
1067
294
      Trace("smt") << "turning on sygus" << std::endl;
1068
    }
1069
813
    opts.set(options::sygus, true);
1070
    // must use Ferrante/Rackoff for real arithmetic
1071
5247
    if (!opts.wasSetByUser(options::cegqiMidpoint))
1072
    {
1073
813
      opts.set(options::cegqiMidpoint, true);
1074
    }
1075
    // must disable cegqi-bv since it may introduce witness terms, which
1076
    // cannot appear in synthesis solutions
1077
813
    if (!opts.wasSetByUser(options::cegqiBv))
1078
    {
1079
810
      opts.set(options::cegqiBv, false);
1080
    }
1081
41181
    if (options::sygusRepairConst())
1082
    {
1083
151
      if (!opts.wasSetByUser(options::cegqi))
1084
      {
1085
151
        opts.set(options::cegqi, true);
1086
      }
1087
    }
1088
813
    if (options::sygusInference())
1089
    {
1090
      // optimization: apply preskolemization, makes it succeed more often
1091
58
      if (!opts.wasSetByUser(options::preSkolemQuant))
1092
      {
1093
58
        opts.set(options::preSkolemQuant, true);
1094
      }
1095
58
      if (!opts.wasSetByUser(options::preSkolemQuantNested))
1096
      {
1097
58
        opts.set(options::preSkolemQuantNested, true);
1098
      }
1099
    }
1100
    // counterexample-guided instantiation for sygus
1101
2967
    if (!opts.wasSetByUser(options::cegqiSingleInvMode))
1102
    {
1103
681
      opts.set(options::cegqiSingleInvMode, options::CegqiSingleInvMode::USE);
1104
    }
1105
83963
    if (!opts.wasSetByUser(options::quantConflictFind))
1106
    {
1107
813
      opts.set(options::quantConflictFind, false);
1108
    }
1109
201316
    if (!opts.wasSetByUser(options::instNoEntail))
1110
    {
1111
813
      opts.set(options::instNoEntail, false);
1112
    }
1113
3985
    if (!opts.wasSetByUser(options::cegqiFullEffort))
1114
    {
1115
      // should use full effort cbqi for single invocation and repair const
1116
813
      opts.set(options::cegqiFullEffort, true);
1117
    }
1118
1632
    if (options::sygusRew())
1119
    {
1120
1903
      opts.set(options::sygusRewSynth, true);
1121
60788
      opts.set(options::sygusRewVerify, true);
1122
    }
1123
813
    if (options::sygusRewSynthInput())
1124
    {
1125
      // If we are using synthesis rewrite rules from input, we use
1126
      // sygusRewSynth after preprocessing. See passes/synth_rew_rules.h for
1127
      // details on this technique.
1128
      opts.set(options::sygusRewSynth, true);
1129
      // we should not use the extended rewriter, since we are interested
1130
      // in rewrites that are not in the main rewriter
1131
211304
      if (!opts.wasSetByUser(options::sygusExtRew))
1132
      {
1133
        opts.set(options::sygusExtRew, false);
1134
      }
1135
    }
1136
    // Whether we must use "basic" sygus algorithms. A non-basic sygus algorithm
1137
    // is one that is specialized for returning a single solution. Non-basic
1138
    // sygus algorithms currently include the PBE solver, UNIF+PI, static
1139
    // template inference for invariant synthesis, and single invocation
1140
    // techniques.
1141
813
    bool reqBasicSygus = false;
1142
813
    if (options::produceAbducts())
1143
    {
1144
      // if doing abduction, we should filter strong solutions
1145
116
      if (!opts.wasSetByUser(options::sygusFilterSolMode))
1146
      {
1147
15
        opts.set(options::sygusFilterSolMode, options::SygusFilterSolMode::STRONG);
1148
      }
1149
      // we must use basic sygus algorithms, since e.g. we require checking
1150
      // a sygus side condition for consistency with axioms.
1151
15
      reqBasicSygus = true;
1152
    }
1153
2432
    if (options::sygusRewSynth() || options::sygusRewVerify()
1154
2494
        || options::sygusQueryGen())
1155
    {
1156
      // rewrite rule synthesis implies that sygus stream must be true
1157
2227
      opts.set(options::sygusStream, true);
1158
    }
1159
813
    if (options::sygusStream() || options::incrementalSolving())
1160
    {
1161
      // Streaming and incremental mode are incompatible with techniques that
1162
      // focus the search towards finding a single solution.
1163
12
      reqBasicSygus = true;
1164
    }
1165
    // Now, disable options for non-basic sygus algorithms, if necessary.
1166
813
    if (reqBasicSygus)
1167
    {
1168
314
      if (!opts.wasSetByUser(options::sygusUnifPbe))
1169
      {
1170
25
        opts.set(options::sygusUnifPbe, false);
1171
      }
1172
3498
      if (opts.wasSetByUser(options::sygusUnifPi))
1173
      {
1174
        opts.set(options::sygusUnifPi, options::SygusUnifPiMode::NONE);
1175
      }
1176
403
      if (!opts.wasSetByUser(options::sygusInvTemplMode))
1177
      {
1178
25
        opts.set(options::sygusInvTemplMode, options::SygusInvTemplMode::NONE);
1179
      }
1180
25
      if (!opts.wasSetByUser(options::cegqiSingleInvMode))
1181
      {
1182
25
        opts.set(options::cegqiSingleInvMode, options::CegqiSingleInvMode::NONE);
1183
      }
1184
    }
1185
6310
    if (!opts.wasSetByUser(options::dtRewriteErrorSel))
1186
    {
1187
813
      opts.set(options::dtRewriteErrorSel, true);
1188
    }
1189
    // do not miniscope
1190
3677
    if (!opts.wasSetByUser(options::miniscopeQuant))
1191
    {
1192
685
      opts.set(options::miniscopeQuant, false);
1193
    }
1194
3635
    if (!opts.wasSetByUser(options::miniscopeQuantFreeVar))
1195
    {
1196
687
      opts.set(options::miniscopeQuantFreeVar, false);
1197
    }
1198
45607
    if (!opts.wasSetByUser(options::quantSplit))
1199
    {
1200
687
      opts.set(options::quantSplit, false);
1201
    }
1202
    // do not do macros
1203
813
    if (!opts.wasSetByUser(options::macrosQuant))
1204
    {
1205
813
      opts.set(options::macrosQuant, false);
1206
    }
1207
    // use tangent planes by default, since we want to put effort into
1208
    // the verification step for sygus queries with non-linear arithmetic
1209
64934
    if (!opts.wasSetByUser(options::nlExtTangentPlanes))
1210
    {
1211
799
      opts.set(options::nlExtTangentPlanes, true);
1212
    }
1213
  }
1214
  // counterexample-guided instantiation for non-sygus
1215
  // enable if any possible quantifiers with arithmetic, datatypes or bitvectors
1216
18918
  if ((logic.isQuantified()
1217
6413
       && (logic.isTheoryEnabled(THEORY_ARITH)
1218
285
           || logic.isTheoryEnabled(THEORY_DATATYPES)
1219
277
           || logic.isTheoryEnabled(THEORY_BV)
1220
89
           || logic.isTheoryEnabled(THEORY_FP)))
1221
34208
      || options::cegqiAll())
1222
  {
1223
6324
    if (!opts.wasSetByUser(options::cegqi))
1224
    {
1225
6301
      opts.set(options::cegqi, true);
1226
    }
1227
    // check whether we should apply full cbqi
1228
6324
    if (logic.isPure(THEORY_BV))
1229
    {
1230
152
      if (!opts.wasSetByUser(options::cegqiFullEffort))
1231
      {
1232
60
        opts.set(options::cegqiFullEffort, true);
1233
      }
1234
    }
1235
  }
1236
9459
  if (options::cegqi())
1237
  {
1238
6322
    if (options::incrementalSolving())
1239
    {
1240
      // cannot do nested quantifier elimination in incremental mode
1241
24595
      opts.set(options::cegqiNestedQE, false);
1242
    }
1243
6322
    if (logic.isPure(THEORY_ARITH) || logic.isPure(THEORY_BV))
1244
    {
1245
265
      if (!opts.wasSetByUser(options::quantConflictFind))
1246
      {
1247
265
        opts.set(options::quantConflictFind, false);
1248
      }
1249
265
      if (!opts.wasSetByUser(options::instNoEntail))
1250
      {
1251
265
        opts.set(options::instNoEntail, false);
1252
      }
1253
34065
      if (!opts.wasSetByUser(options::instWhenMode) && options::cegqiModel())
1254
      {
1255
        // only instantiation should happen at last call when model is avaiable
1256
265
        opts.set(options::instWhenMode, options::InstWhenMode::LAST_CALL);
1257
      }
1258
    }
1259
    else
1260
    {
1261
      // only supported in pure arithmetic or pure BV
1262
6057
      opts.set(options::cegqiNestedQE, false);
1263
    }
1264
6322
    if (options::globalNegate())
1265
    {
1266
6
      if (!opts.wasSetByUser(options::prenexQuant))
1267
      {
1268
6
        opts.set(options::prenexQuant, options::PrenexQuantMode::NONE);
1269
      }
1270
    }
1271
  }
1272
  // implied options...
1273
41623
  if (options::strictTriggers())
1274
  {
1275
387685
    if (!opts.wasSetByUser(options::userPatternsQuant))
1276
    {
1277
      opts.set(options::userPatternsQuant, options::UserPatMode::TRUST);
1278
    }
1279
  }
1280
242545
  if (opts.wasSetByUser(options::qcfMode) || options::qcfTConstraint())
1281
  {
1282
8
    opts.set(options::quantConflictFind, true);
1283
  }
1284
9459
  if (options::cegqiNestedQE())
1285
  {
1286
1167
    opts.set(options::prenexQuantUser, true);
1287
30
    if (!opts.wasSetByUser(options::preSkolemQuant))
1288
    {
1289
30
      opts.set(options::preSkolemQuant, true);
1290
    }
1291
  }
1292
  // for induction techniques
1293
18926
  if (options::quantInduction())
1294
  {
1295
18971
    if (!opts.wasSetByUser(options::dtStcInduction))
1296
    {
1297
14
      opts.set(options::dtStcInduction, true);
1298
    }
1299
14996
    if (!opts.wasSetByUser(options::intWfInduction))
1300
    {
1301
14
      opts.set(options::intWfInduction, true);
1302
    }
1303
  }
1304
9459
  if (options::dtStcInduction())
1305
  {
1306
    // try to remove ITEs from quantified formulas
1307
214702
    if (!opts.wasSetByUser(options::iteDtTesterSplitQuant))
1308
    {
1309
14
      opts.set(options::iteDtTesterSplitQuant, true);
1310
    }
1311
308879
    if (!opts.wasSetByUser(options::iteLiftQuant))
1312
    {
1313
14
      opts.set(options::iteLiftQuant, options::IteLiftQuantMode::ALL);
1314
    }
1315
  }
1316
9459
  if (options::intWfInduction())
1317
  {
1318
59098
    if (!opts.wasSetByUser(options::purifyTriggers))
1319
    {
1320
20
      opts.set(options::purifyTriggers, true);
1321
    }
1322
  }
1323
18920
  if (options::conjectureNoFilter())
1324
  {
1325
3255
    if (!opts.wasSetByUser(options::conjectureFilterActiveTerms))
1326
    {
1327
4
      opts.set(options::conjectureFilterActiveTerms, false);
1328
    }
1329
6604
    if (!opts.wasSetByUser(options::conjectureFilterCanonical))
1330
    {
1331
4
      opts.set(options::conjectureFilterCanonical, false);
1332
    }
1333
14600
    if (!opts.wasSetByUser(options::conjectureFilterModel))
1334
    {
1335
      opts.set(options::conjectureFilterModel, false);
1336
    }
1337
  }
1338
19616
  if (opts.wasSetByUser(options::conjectureGenPerRound))
1339
  {
1340
    if (options::conjectureGenPerRound() > 0)
1341
    {
1342
6420
      opts.set(options::conjectureGen, true);
1343
    }
1344
    else
1345
    {
1346
      opts.set(options::conjectureGen, false);
1347
    }
1348
  }
1349
  // can't pre-skolemize nested quantifiers without UF theory
1350
9459
  if (!logic.isTheoryEnabled(THEORY_UF) && options::preSkolemQuant())
1351
  {
1352
30
    if (!opts.wasSetByUser(options::preSkolemQuantNested))
1353
    {
1354
30
      opts.set(options::preSkolemQuantNested, false);
1355
    }
1356
  }
1357
9459
  if (!logic.isTheoryEnabled(THEORY_DATATYPES))
1358
  {
1359
4274
    opts.set(options::quantDynamicSplit, options::QuantDSplitMode::NONE);
1360
  }
1361
1362
  // until bugs 371,431 are fixed
1363
9459
  if (!opts.wasSetByUser(options::minisatUseElim))
1364
  {
1365
    // cannot use minisat elimination for logics where a theory solver
1366
    // introduces new literals into the search. This includes quantifiers
1367
    // (quantifier instantiation), and the lemma schemas used in non-linear
1368
    // and sets. We also can't use it if models are enabled.
1369
18918
    if (logic.isTheoryEnabled(THEORY_SETS)
1370
5492
        || logic.isTheoryEnabled(THEORY_BAGS)
1371
5492
        || logic.isQuantified()
1372
2965
        || options::produceModels() || options::produceAssignments()
1373
2424
        || options::checkModels()
1374
11883
        || (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()))
1375
    {
1376
7449
      opts.set(options::minisatUseElim, false);
1377
    }
1378
  }
1379
1380
26736
  if (logic.isTheoryEnabled(THEORY_ARITH) && !logic.isLinear()
1381
25001
      && options::nlRlvMode() != options::NlRlvMode::NONE)
1382
  {
1383
9553
    if (!options::relevanceFilter())
1384
    {
1385
22
      if (opts.wasSetByUser(options::relevanceFilter))
1386
      {
1387
        Warning() << "SmtEngine: turning on relevance filtering to support "
1388
                     "--nl-ext-rlv="
1389
                  << options::nlRlvMode() << std::endl;
1390
      }
1391
      // must use relevance filtering techniques
1392
22
      opts.set(options::relevanceFilter, true);
1393
    }
1394
  }
1395
1396
  // For now, these array theory optimizations do not support model-building
1397
24959
  if (options::produceModels() || options::produceAssignments()
1398
15500
      || options::checkModels())
1399
  {
1400
42884
    opts.set(options::arraysOptimizeLinear, false);
1401
  }
1402
1403
28325
  if (!options::bitvectorEqualitySolver())
1404
  {
1405
2
    if (options::bvLazyRewriteExtf())
1406
    {
1407
2
      if (opts.wasSetByUser(options::bvLazyRewriteExtf))
1408
      {
1409
        throw OptionException(
1410
            "--bv-lazy-rewrite-extf requires --bv-eq-solver to be set");
1411
      }
1412
    }
1413
4
    Trace("smt")
1414
2
        << "disabling bvLazyRewriteExtf since equality solver is disabled"
1415
2
        << std::endl;
1416
2
    opts.set(options::bvLazyRewriteExtf, false);
1417
  }
1418
1419
112565
  if (options::stringFMF() && !opts.wasSetByUser(options::stringProcessLoopMode))
1420
  {
1421
92
    Trace("smt") << "settting stringProcessLoopMode to 'simple' since "
1422
46
                    "--strings-fmf enabled"
1423
46
                 << std::endl;
1424
46
    opts.set(options::stringProcessLoopMode, options::ProcessLoopMode::SIMPLE);
1425
  }
1426
1427
  // !!! All options that require disabling models go here
1428
9459
  bool disableModels = false;
1429
18918
  std::string sOptNoModel;
1430
9459
  if (opts.wasSetByUser(options::unconstrainedSimp) && options::unconstrainedSimp())
1431
  {
1432
104
    disableModels = true;
1433
104
    sOptNoModel = "unconstrained-simp";
1434
  }
1435
9355
  else if (options::sortInference())
1436
  {
1437
20
    disableModels = true;
1438
20
    sOptNoModel = "sort-inference";
1439
  }
1440
9335
  else if (options::minisatUseElim())
1441
  {
1442
1947
    disableModels = true;
1443
1947
    sOptNoModel = "minisat-elimination";
1444
  }
1445
7388
  else if (options::globalNegate())
1446
  {
1447
6
    disableModels = true;
1448
6
    sOptNoModel = "global-negate";
1449
  }
1450
9459
  if (disableModels)
1451
  {
1452
2077
    if (options::produceModels())
1453
    {
1454
47
      if (opts.wasSetByUser(options::produceModels))
1455
      {
1456
        std::stringstream ss;
1457
        ss << "Cannot use " << sOptNoModel << " with model generation.";
1458
        throw OptionException(ss.str());
1459
      }
1460
47
      Notice() << "SmtEngine: turning off produce-models to support "
1461
               << sOptNoModel << std::endl;
1462
47
      opts.set(options::produceModels, false);
1463
    }
1464
2077
    if (options::produceAssignments())
1465
    {
1466
46
      if (opts.wasSetByUser(options::produceAssignments))
1467
      {
1468
        std::stringstream ss;
1469
        ss << "Cannot use " << sOptNoModel
1470
           << " with model generation (produce-assignments).";
1471
        throw OptionException(ss.str());
1472
      }
1473
46
      Notice() << "SmtEngine: turning off produce-assignments to support "
1474
               << sOptNoModel << std::endl;
1475
46
      opts.set(options::produceAssignments, false);
1476
    }
1477
2077
    if (options::checkModels())
1478
    {
1479
46
      if (opts.wasSetByUser(options::checkModels))
1480
      {
1481
        std::stringstream ss;
1482
        ss << "Cannot use " << sOptNoModel
1483
           << " with model generation (check-models).";
1484
        throw OptionException(ss.str());
1485
      }
1486
46
      Notice() << "SmtEngine: turning off check-models to support "
1487
               << sOptNoModel << std::endl;
1488
46
      opts.set(options::checkModels, false);
1489
    }
1490
  }
1491
1492
18918
  if (options::bitblastMode() == options::BitblastMode::EAGER
1493
9501
      && !logic.isPure(THEORY_BV) && logic.getLogicString() != "QF_UFBV"
1494
18918
      && logic.getLogicString() != "QF_ABV")
1495
  {
1496
    throw OptionException(
1497
        "Eager bit-blasting does not currently support theory combination. "
1498
        "Note that in a QF_BV problem UF symbols can be introduced for "
1499
        "division. "
1500
        "Try --bv-div-zero-const to interpret division by zero as a constant.");
1501
  }
1502
1503
9459
  if (logic == LogicInfo("QF_UFNRA"))
1504
  {
1505
#ifdef CVC5_USE_POLY
1506
1570
    if (!options::nlCad() && !opts.wasSetByUser(options::nlCad))
1507
    {
1508
100
      opts.set(options::nlCad, true);
1509
2461
      if (!opts.wasSetByUser(options::nlExt))
1510
      {
1511
48
        opts.set(options::nlExt, options::NlExtMode::LIGHT);
1512
      }
1513
100
      if (!opts.wasSetByUser(options::nlRlvMode))
1514
      {
1515
100
        opts.set(options::nlRlvMode, options::NlRlvMode::INTERLEAVE);
1516
      }
1517
    }
1518
#endif
1519
  }
1520
#ifndef CVC5_USE_POLY
1521
  if (options::nlCad())
1522
  {
1523
    if (opts.wasSetByUser(options::nlCad))
1524
    {
1525
      std::stringstream ss;
1526
      ss << "Cannot use " << options::nlCad.name << " without configuring with --poly.";
1527
      throw OptionException(ss.str());
1528
    }
1529
    else
1530
    {
1531
      Notice() << "Cannot use --" << options::nlCad.name
1532
               << " without configuring with --poly." << std::endl;
1533
      opts.set(options::nlCad, false);
1534
      opts.set(options::nlExt, options::NlExtMode::FULL);
1535
    }
1536
  }
1537
#endif
1538
9459
}
1539
1540
}  // namespace smt
1541
20320189
}  // namespace cvc5