GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 657 826 79.5 %
Date: 2021-09-10 Branches: 947 1678 56.4 %

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