GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 598 730 81.9 %
Date: 2021-08-01 Branches: 1390 2648 52.5 %

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