GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 601 733 82.0 %
Date: 2021-08-20 Branches: 967 1760 54.9 %

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