GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 598 730 81.9 %
Date: 2021-08-06 Branches: 1333 2466 54.1 %

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