GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/smt/set_defaults.cpp Lines: 602 736 81.8 %
Date: 2021-08-17 Branches: 968 1764 54.9 %

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