GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 663 833 79.6 %
Date: 2021-09-15 Branches: 955 1688 56.6 %

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