GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 674 820 82.2 %
Date: 2021-11-07 Branches: 961 1538 62.5 %

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