1 /******************************************************************************
2 * Top contributors (to current version):
3 * Andrew Reynolds, Andres Noetzli, Haniel Barbosa
5 * This file is part of the cvc5 project.
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 * ****************************************************************************
13 * Implementation of setting default options.
16 #include "smt/set_defaults.h"
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"
44 using namespace cvc5::theory
;
49 SetDefaults::SetDefaults(bool isInternalSubsolver
)
50 : d_isInternalSubsolver(isInternalSubsolver
)
54 void SetDefaults::setDefaults(LogicInfo
& logic
, Options
& opts
)
56 // initial changes that are independent of logic, and may impact the logic
58 // now, finalize the logic
59 finalizeLogic(logic
, opts
);
60 // further changes to options based on the logic
61 setDefaultsPost(logic
, opts
);
64 void SetDefaults::setDefaultsPre(Options
& opts
)
67 if (opts
.smt
.debugCheckModels
)
69 opts
.smt
.checkModels
= true;
71 if (opts
.smt
.checkModels
|| opts
.driver
.dumpModels
)
73 opts
.smt
.produceModels
= true;
75 if (opts
.smt
.checkModels
)
77 opts
.smt
.produceAssignments
= true;
79 // unsat cores and proofs shenanigans
80 if (opts
.driver
.dumpDifficulty
)
82 opts
.smt
.produceDifficulty
= true;
84 if (opts
.smt
.produceDifficulty
)
86 if (opts
.smt
.unsatCoresMode
== options::UnsatCoresMode::OFF
)
88 opts
.smt
.unsatCoresMode
= options::UnsatCoresMode::PP_ONLY
;
90 opts
.proof
.proofGranularityMode
= options::ProofGranularityMode::OFF
;
92 if (opts
.smt
.checkUnsatCores
|| opts
.driver
.dumpUnsatCores
93 || opts
.smt
.unsatAssumptions
|| opts
.smt
.minimalUnsatCores
94 || opts
.smt
.unsatCoresMode
!= options::UnsatCoresMode::OFF
)
96 opts
.smt
.unsatCores
= true;
98 if (opts
.smt
.unsatCores
99 && opts
.smt
.unsatCoresMode
== options::UnsatCoresMode::OFF
)
101 if (opts
.smt
.unsatCoresModeWasSetByUser
)
104 << "Overriding OFF unsat-core mode since cores were requested.\n";
106 opts
.smt
.unsatCoresMode
= options::UnsatCoresMode::ASSUMPTIONS
;
109 if (opts
.smt
.checkProofs
|| opts
.driver
.dumpProofs
)
111 opts
.smt
.produceProofs
= true;
114 if (opts
.smt
.produceProofs
115 && opts
.smt
.unsatCoresMode
!= options::UnsatCoresMode::FULL_PROOF
)
117 if (opts
.smt
.unsatCoresModeWasSetByUser
)
119 Notice() << "Forcing full-proof mode for unsat cores mode since proofs "
122 // enable unsat cores, because they are available as a consequence of proofs
123 opts
.smt
.unsatCores
= true;
124 opts
.smt
.unsatCoresMode
= options::UnsatCoresMode::FULL_PROOF
;
127 // set proofs on if not yet set
128 if (opts
.smt
.unsatCores
&& !opts
.smt
.produceProofs
)
130 if (opts
.smt
.produceProofsWasSetByUser
)
133 << "Forcing proof production since new unsat cores were requested.\n";
135 opts
.smt
.produceProofs
= true;
138 // if unsat cores are disabled, then unsat cores mode should be OFF
139 Assert(opts
.smt
.unsatCores
140 == (opts
.smt
.unsatCoresMode
!= options::UnsatCoresMode::OFF
));
142 // new unsat core specific restrictions for proofs
143 if (opts
.smt
.unsatCores
144 && opts
.smt
.unsatCoresMode
!= options::UnsatCoresMode::FULL_PROOF
)
146 // no fine-graininess
147 if (!opts
.proof
.proofGranularityModeWasSetByUser
)
149 opts
.proof
.proofGranularityMode
= options::ProofGranularityMode::OFF
;
153 if (opts
.bv
.bitvectorAigSimplificationsWasSetByUser
)
155 Notice() << "SolverEngine: setting bitvectorAig" << std::endl
;
156 opts
.bv
.bitvectorAig
= true;
158 if (opts
.bv
.bitvectorAlgebraicBudgetWasSetByUser
)
160 Notice() << "SolverEngine: setting bitvectorAlgebraicSolver" << std::endl
;
161 opts
.bv
.bitvectorAlgebraicSolver
= true;
164 // if we requiring disabling proofs, disable them now
165 if (opts
.smt
.produceProofs
)
167 std::stringstream reasonNoProofs
;
168 if (incompatibleWithProofs(opts
, reasonNoProofs
))
170 opts
.smt
.unsatCores
= false;
171 opts
.smt
.unsatCoresMode
= options::UnsatCoresMode::OFF
;
172 Notice() << "SolverEngine: turning off produce-proofs due to "
173 << reasonNoProofs
.str() << "." << std::endl
;
174 opts
.smt
.produceProofs
= false;
175 opts
.smt
.checkProofs
= false;
178 if (d_isInternalSubsolver
)
180 // these options must be disabled on internal subsolvers, as they are
181 // used by the user to rephrase the input.
182 opts
.quantifiers
.sygusInference
= false;
183 opts
.quantifiers
.sygusRewSynthInput
= false;
187 void SetDefaults::finalizeLogic(LogicInfo
& logic
, Options
& opts
) const
189 if (opts
.quantifiers
.sygusInstWasSetByUser
)
193 throw OptionException(std::string(
194 "SyGuS instantiation quantifiers module cannot be enabled "
195 "for SyGuS inputs."));
198 else if (!isSygus(opts
) && logic
.isQuantified()
199 && (logic
.isPure(THEORY_FP
)
200 || (logic
.isPure(THEORY_ARITH
) && !logic
.isLinear())))
202 opts
.quantifiers
.sygusInst
= true;
205 if (opts
.bv
.bitblastMode
== options::BitblastMode::EAGER
)
207 if (opts
.smt
.produceModels
208 && (logic
.isTheoryEnabled(THEORY_ARRAYS
)
209 || logic
.isTheoryEnabled(THEORY_UF
)))
211 if (opts
.bv
.bitblastModeWasSetByUser
212 || opts
.smt
.produceModelsWasSetByUser
)
214 throw OptionException(std::string(
215 "Eager bit-blasting currently does not support model generation "
216 "for the combination of bit-vectors with arrays or uinterpreted "
217 "functions. Try --bitblast=lazy"));
220 << "SolverEngine: setting bit-blast mode to lazy to support model"
221 << "generation" << std::endl
;
222 opts
.bv
.bitblastMode
= options::BitblastMode::LAZY
;
224 else if (!opts
.base
.incrementalSolving
)
226 opts
.smt
.ackermann
= true;
230 if (opts
.smt
.solveIntAsBV
> 0)
232 // Int to BV currently always eliminates arithmetic completely (or otherwise
233 // fails). Thus, it is safe to eliminate arithmetic. Also, bit-vectors
235 logic
= logic
.getUnlockedCopy();
236 logic
.enableTheory(THEORY_BV
);
237 logic
.disableTheory(THEORY_ARITH
);
241 if (opts
.smt
.solveBVAsInt
!= options::SolveBVAsIntMode::OFF
)
243 if (opts
.bv
.boolToBitvector
!= options::BoolToBVMode::OFF
)
245 throw OptionException(
246 "solving bitvectors as integers is incompatible with --bool-to-bv.");
248 if (opts
.smt
.BVAndIntegerGranularity
> 8)
251 * The granularity sets the size of the ITE in each element
252 * of the sum that is generated for bitwise operators.
253 * The size of the ITE is 2^{2*granularity}.
254 * Since we don't want to introduce ITEs with unbounded size,
255 * we bound the granularity.
257 throw OptionException("solve-bv-as-int accepts values from 0 to 8.");
259 if (logic
.isTheoryEnabled(THEORY_BV
))
261 logic
= logic
.getUnlockedCopy();
262 logic
.enableTheory(THEORY_ARITH
);
263 logic
.arithNonLinear();
268 // set options about ackermannization
269 if (opts
.smt
.ackermann
&& opts
.smt
.produceModels
270 && (logic
.isTheoryEnabled(THEORY_ARRAYS
)
271 || logic
.isTheoryEnabled(THEORY_UF
)))
273 if (opts
.smt
.produceModelsWasSetByUser
)
275 throw OptionException(std::string(
276 "Ackermannization currently does not support model generation."));
278 Notice() << "SolverEngine: turn off ackermannization to support model"
279 << "generation" << std::endl
;
280 opts
.smt
.ackermann
= false;
283 if (opts
.smt
.ackermann
)
285 if (logic
.isTheoryEnabled(THEORY_UF
))
287 logic
= logic
.getUnlockedCopy();
288 logic
.disableTheory(THEORY_UF
);
291 if (logic
.isTheoryEnabled(THEORY_ARRAYS
))
293 logic
= logic
.getUnlockedCopy();
294 logic
.disableTheory(THEORY_ARRAYS
);
299 // Set default options associated with strings-exp. We also set these options
300 // if we are using eager string preprocessing, which may introduce quantified
301 // formulas at preprocess time.
303 // We don't want to set this option when we are in logics that contain ALL.
304 if (!logic
.hasEverything() && logic
.isTheoryEnabled(THEORY_STRINGS
))
306 // If the user explicitly set a logic that includes strings, but is not
307 // the generic "ALL" logic, then enable stringsExp.
308 opts
.strings
.stringExp
= true;
309 Trace("smt") << "Turning stringExp on since logic does not have everything "
310 "and string theory is enabled\n";
312 if (opts
.strings
.stringExp
|| !opts
.strings
.stringLazyPreproc
)
314 // We require quantifiers since extended functions reduce using them.
315 if (!logic
.isQuantified())
317 logic
= logic
.getUnlockedCopy();
318 logic
.enableQuantifiers();
320 Trace("smt") << "turning on quantifier logic, for strings-exp"
323 // Note we allow E-matching by default to support combinations of sequences
324 // and quantifiers. We also do not enable fmfBound here, which would
325 // enable bounded integer instantiation for *all* quantifiers. Instead,
326 // the bounded integers module will always process internally generated
327 // quantifiers (those marked with InternalQuantAttribute).
330 if (opts
.arrays
.arraysExp
)
332 if (!logic
.isQuantified())
334 logic
= logic
.getUnlockedCopy();
335 logic
.enableQuantifiers();
340 // We now know whether the input uses sygus. Update the logic to incorporate
341 // the theories we need internally for handling sygus problems.
344 logic
= logic
.getUnlockedCopy();
350 widenLogic(logic
, opts
);
352 // check if we have any options that are not supported with quantified logics
353 if (logic
.isQuantified())
355 std::stringstream reasonNoQuant
;
356 if (incompatibleWithQuantifiers(opts
, reasonNoQuant
))
358 std::stringstream ss
;
359 ss
<< reasonNoQuant
.str() << " not supported in quantified logics.";
360 throw OptionException(ss
.str());
365 void SetDefaults::setDefaultsPost(const LogicInfo
& logic
, Options
& opts
) const
368 // sygus core connective requires unsat cores
369 if (opts
.quantifiers
.sygusCoreConnective
)
371 opts
.smt
.unsatCores
= true;
372 if (opts
.smt
.unsatCoresMode
== options::UnsatCoresMode::OFF
)
374 opts
.smt
.unsatCoresMode
= options::UnsatCoresMode::ASSUMPTIONS
;
378 if ((opts
.smt
.checkModels
|| opts
.smt
.checkSynthSol
|| opts
.smt
.produceAbducts
379 || opts
.smt
.produceInterpols
!= options::ProduceInterpols::NONE
380 || opts
.smt
.modelCoresMode
!= options::ModelCoresMode::NONE
381 || opts
.smt
.blockModelsMode
!= options::BlockModelsMode::NONE
382 || opts
.smt
.produceProofs
)
383 && !opts
.smt
.produceAssertions
)
385 Notice() << "SolverEngine: turning on produce-assertions to support "
386 << "option requiring assertions." << std::endl
;
387 opts
.smt
.produceAssertions
= true;
390 if (opts
.smt
.solveBVAsInt
!= options::SolveBVAsIntMode::OFF
)
393 * Operations on 1 bits are better handled as Boolean operations
394 * than as integer operations.
395 * Therefore, we enable bv-to-bool, which runs before
396 * the translation to integers.
398 opts
.bv
.bitvectorToBool
= true;
401 // Disable options incompatible with incremental solving, or output an error
402 // if enabled explicitly.
403 if (opts
.base
.incrementalSolving
)
405 std::stringstream reasonNoInc
;
406 std::stringstream suggestNoInc
;
407 if (incompatibleWithIncremental(logic
, opts
, reasonNoInc
, suggestNoInc
))
409 std::stringstream ss
;
410 ss
<< reasonNoInc
.str() << " not supported with incremental solving. "
411 << suggestNoInc
.str();
412 throw OptionException(ss
.str());
416 // Disable options incompatible with unsat cores or output an error if enabled
418 if (safeUnsatCores(opts
))
420 // check if the options are not compatible with unsat cores
421 std::stringstream reasonNoUc
;
422 if (incompatibleWithUnsatCores(opts
, reasonNoUc
))
424 std::stringstream ss
;
425 ss
<< reasonNoUc
.str() << " not supported with unsat cores";
426 throw OptionException(ss
.str());
431 // Turn on unconstrained simplification for QF_AUFBV
432 if (!opts
.smt
.unconstrainedSimpWasSetByUser
433 && !opts
.base
.incrementalSolving
)
435 // It is also currently incompatible with arithmetic, force the option
437 bool uncSimp
= !opts
.base
.incrementalSolving
&& !logic
.isQuantified()
438 && !opts
.smt
.produceModels
&& !opts
.smt
.produceAssignments
439 && !opts
.smt
.checkModels
440 && logic
.isTheoryEnabled(THEORY_ARRAYS
)
441 && logic
.isTheoryEnabled(THEORY_BV
)
442 && !logic
.isTheoryEnabled(THEORY_ARITH
);
443 Trace("smt") << "setting unconstrained simplification to " << uncSimp
445 opts
.smt
.unconstrainedSimp
= uncSimp
;
448 // by default, nonclausal simplification is off for QF_SAT
449 if (!opts
.smt
.simplificationModeWasSetByUser
)
451 bool qf_sat
= logic
.isPure(THEORY_BOOL
) && !logic
.isQuantified();
452 Trace("smt") << "setting simplification mode to <"
453 << logic
.getLogicString() << "> " << (!qf_sat
) << std::endl
;
454 // simplification=none works better for SMT LIB benchmarks with
455 // quantifiers, not others opts.set(options::simplificationMode, qf_sat ||
456 // quantifiers ? options::SimplificationMode::NONE :
457 // options::SimplificationMode::BATCH);
458 opts
.smt
.simplificationMode
= qf_sat
? options::SimplificationMode::NONE
459 : options::SimplificationMode::BATCH
;
463 if (opts
.quantifiers
.cegqiBv
&& logic
.isQuantified())
465 if (opts
.bv
.boolToBitvector
!= options::BoolToBVMode::OFF
)
467 if (opts
.bv
.boolToBitvectorWasSetByUser
)
469 throw OptionException(
470 "bool-to-bv != off not supported with CBQI BV for quantified "
474 << "SolverEngine: turning off bool-to-bitvector to support CBQI BV"
476 opts
.bv
.boolToBitvector
= options::BoolToBVMode::OFF
;
480 // cases where we need produce models
481 if (!opts
.smt
.produceModels
482 && (opts
.smt
.produceAssignments
|| opts
.quantifiers
.sygusRewSynthCheck
485 Notice() << "SolverEngine: turning on produce-models" << std::endl
;
486 opts
.smt
.produceModels
= true;
489 // --ite-simp is an experimental option designed for QF_LIA/nec. This
490 // technique is experimental. This benchmark set also requires removing ITEs
491 // during preprocessing, before repeating simplification. Hence, we enable
493 if (opts
.smt
.doITESimp
)
495 if (!opts
.smt
.earlyIteRemovalWasSetByUser
)
497 opts
.smt
.earlyIteRemoval
= true;
501 // Set the options for the theoryOf
502 if (!opts
.theory
.theoryOfModeWasSetByUser
)
504 if (logic
.isSharingEnabled() && !logic
.isTheoryEnabled(THEORY_BV
)
505 && !logic
.isTheoryEnabled(THEORY_STRINGS
)
506 && !logic
.isTheoryEnabled(THEORY_SETS
)
507 && !logic
.isTheoryEnabled(THEORY_BAGS
)
508 && !(logic
.isTheoryEnabled(THEORY_ARITH
) && !logic
.isLinear()
509 && !logic
.isQuantified()))
511 Trace("smt") << "setting theoryof-mode to term-based" << std::endl
;
512 opts
.theory
.theoryOfMode
= options::TheoryOfMode::THEORY_OF_TERM_BASED
;
516 // by default, symmetry breaker is on only for non-incremental QF_UF
517 if (!opts
.uf
.ufSymmetryBreakerWasSetByUser
)
519 bool qf_uf_noinc
= logic
.isPure(THEORY_UF
) && !logic
.isQuantified()
520 && !opts
.base
.incrementalSolving
521 && !safeUnsatCores(opts
);
522 Trace("smt") << "setting uf symmetry breaker to " << qf_uf_noinc
524 opts
.uf
.ufSymmetryBreaker
= qf_uf_noinc
;
527 // If in arrays, set the UF handler to arrays
528 if (logic
.isTheoryEnabled(THEORY_ARRAYS
) && !logic
.isHigherOrder()
529 && !opts
.quantifiers
.finiteModelFind
530 && (!logic
.isQuantified()
531 || (logic
.isQuantified() && !logic
.isTheoryEnabled(THEORY_UF
))))
533 Theory::setUninterpretedSortOwner(THEORY_ARRAYS
);
537 Theory::setUninterpretedSortOwner(THEORY_UF
);
540 if (!opts
.smt
.simplifyWithCareEnabledWasSetByUser
)
543 !logic
.isQuantified() && logic
.isTheoryEnabled(THEORY_ARRAYS
)
544 && logic
.isTheoryEnabled(THEORY_UF
) && logic
.isTheoryEnabled(THEORY_BV
);
546 bool withCare
= qf_aufbv
;
547 Trace("smt") << "setting ite simplify with care to " << withCare
549 opts
.smt
.simplifyWithCareEnabled
= withCare
;
551 // Turn off array eager index splitting for QF_AUFLIA
552 if (!opts
.arrays
.arraysEagerIndexSplittingWasSetByUser
)
554 if (not logic
.isQuantified() && logic
.isTheoryEnabled(THEORY_ARRAYS
)
555 && logic
.isTheoryEnabled(THEORY_UF
)
556 && logic
.isTheoryEnabled(THEORY_ARITH
))
558 Trace("smt") << "setting array eager index splitting to false"
560 opts
.arrays
.arraysEagerIndexSplitting
= false;
563 // Turn on multiple-pass non-clausal simplification for QF_AUFBV
564 if (!opts
.smt
.repeatSimpWasSetByUser
)
566 bool repeatSimp
= !logic
.isQuantified()
567 && (logic
.isTheoryEnabled(THEORY_ARRAYS
)
568 && logic
.isTheoryEnabled(THEORY_UF
)
569 && logic
.isTheoryEnabled(THEORY_BV
))
570 && !safeUnsatCores(opts
);
571 Trace("smt") << "setting repeat simplification to " << repeatSimp
573 opts
.smt
.repeatSimp
= repeatSimp
;
576 /* Disable bit-level propagation by default for the BITBLAST solver. */
577 if (opts
.bv
.bvSolver
== options::BVSolver::BITBLAST
)
579 opts
.bv
.bitvectorPropagate
= false;
582 if (opts
.bv
.boolToBitvector
== options::BoolToBVMode::ALL
583 && !logic
.isTheoryEnabled(THEORY_BV
))
585 if (opts
.bv
.boolToBitvectorWasSetByUser
)
587 throw OptionException(
588 "bool-to-bv=all not supported for non-bitvector logics.");
590 Notice() << "SolverEngine: turning off bool-to-bv for non-bv logic: "
591 << logic
.getLogicString() << std::endl
;
592 opts
.bv
.boolToBitvector
= options::BoolToBVMode::OFF
;
595 if (!opts
.bv
.bvEagerExplanationsWasSetByUser
596 && logic
.isTheoryEnabled(THEORY_ARRAYS
)
597 && logic
.isTheoryEnabled(THEORY_BV
))
599 Trace("smt") << "enabling eager bit-vector explanations " << std::endl
;
600 opts
.bv
.bvEagerExplanations
= true;
603 // Turn on arith rewrite equalities only for pure arithmetic
604 if (!opts
.arith
.arithRewriteEqWasSetByUser
)
606 bool arithRewriteEq
=
607 logic
.isPure(THEORY_ARITH
) && logic
.isLinear() && !logic
.isQuantified();
608 Trace("smt") << "setting arith rewrite equalities " << arithRewriteEq
610 opts
.arith
.arithRewriteEq
= arithRewriteEq
;
612 if (!opts
.arith
.arithHeuristicPivotsWasSetByUser
)
614 int16_t heuristicPivots
= 5;
615 if (logic
.isPure(THEORY_ARITH
) && !logic
.isQuantified())
617 if (logic
.isDifferenceLogic())
619 heuristicPivots
= -1;
621 else if (!logic
.areIntegersUsed())
626 Trace("smt") << "setting arithHeuristicPivots " << heuristicPivots
628 opts
.arith
.arithHeuristicPivots
= heuristicPivots
;
630 if (!opts
.arith
.arithPivotThresholdWasSetByUser
)
632 uint16_t pivotThreshold
= 2;
633 if (logic
.isPure(THEORY_ARITH
) && !logic
.isQuantified())
635 if (logic
.isDifferenceLogic())
640 Trace("smt") << "setting arith arithPivotThreshold " << pivotThreshold
642 opts
.arith
.arithPivotThreshold
= pivotThreshold
;
644 if (!opts
.arith
.arithStandardCheckVarOrderPivotsWasSetByUser
)
646 int16_t varOrderPivots
= -1;
647 if (logic
.isPure(THEORY_ARITH
) && !logic
.isQuantified())
649 varOrderPivots
= 200;
651 Trace("smt") << "setting arithStandardCheckVarOrderPivots "
652 << varOrderPivots
<< std::endl
;
653 opts
.arith
.arithStandardCheckVarOrderPivots
= varOrderPivots
;
655 if (logic
.isPure(THEORY_ARITH
) && !logic
.areRealsUsed())
657 if (!opts
.arith
.nlExtTangentPlanesInterleaveWasSetByUser
)
659 Trace("smt") << "setting nlExtTangentPlanesInterleave to true"
661 opts
.arith
.nlExtTangentPlanesInterleave
= true;
664 if (!opts
.arith
.nlRlvAssertBoundsWasSetByUser
)
666 // use bound inference to determine when bounds are irrelevant only when
667 // the logic is quantifier-free
668 opts
.arith
.nlRlvAssertBounds
= !logic
.isQuantified();
671 // set the default decision mode
672 setDefaultDecisionMode(logic
, opts
);
674 // set up of central equality engine
675 if (opts
.theory
.eeMode
== options::EqEngineMode::CENTRAL
)
677 if (!opts
.arith
.arithEqSolverWasSetByUser
)
679 // use the arithmetic equality solver by default
680 opts
.arith
.arithEqSolver
= true;
683 if (opts
.arith
.arithEqSolver
)
685 if (!opts
.arith
.arithCongManWasSetByUser
)
687 // if we are using the arithmetic equality solver, do not use the
688 // arithmetic congruence manager by default
689 opts
.arith
.arithCongMan
= false;
693 if (logic
.isHigherOrder())
695 if (!opts
.theory
.assignFunctionValues
)
697 // must assign function values
698 opts
.theory
.assignFunctionValues
= true;
702 // set all defaults in the quantifiers theory, which includes sygus
703 setDefaultsQuantifiers(logic
, opts
);
705 // shared selectors are generally not good to combine with standard
706 // quantifier techniques e.g. E-matching
707 if (!opts
.datatypes
.dtSharedSelectorsWasSetByUser
)
709 if (logic
.isQuantified() && !usesSygus(opts
))
711 opts
.datatypes
.dtSharedSelectors
= false;
715 // until bugs 371,431 are fixed
716 if (!opts
.prop
.minisatUseElimWasSetByUser
)
718 // cannot use minisat elimination for logics where a theory solver
719 // introduces new literals into the search. This includes quantifiers
720 // (quantifier instantiation), and the lemma schemas used in non-linear
721 // and sets. We also can't use it if models are enabled.
722 if (logic
.isTheoryEnabled(THEORY_SETS
) || logic
.isTheoryEnabled(THEORY_BAGS
)
723 || logic
.isQuantified() || opts
.smt
.produceModels
724 || opts
.smt
.produceAssignments
|| opts
.smt
.checkModels
725 || (logic
.isTheoryEnabled(THEORY_ARITH
) && !logic
.isLinear()))
727 opts
.prop
.minisatUseElim
= false;
731 if (logic
.isTheoryEnabled(THEORY_ARITH
) && !logic
.isLinear()
732 && opts
.arith
.nlRlvMode
!= options::NlRlvMode::NONE
)
734 if (!opts
.theory
.relevanceFilter
)
736 if (opts
.theory
.relevanceFilterWasSetByUser
)
738 Warning() << "SolverEngine: turning on relevance filtering to support "
740 << opts
.arith
.nlRlvMode
<< std::endl
;
742 // must use relevance filtering techniques
743 opts
.theory
.relevanceFilter
= true;
747 // For now, these array theory optimizations do not support model-building
748 if (opts
.smt
.produceModels
|| opts
.smt
.produceAssignments
749 || opts
.smt
.checkModels
)
751 opts
.arrays
.arraysOptimizeLinear
= false;
754 if (opts
.strings
.stringFMF
&& !opts
.strings
.stringProcessLoopModeWasSetByUser
)
756 Trace("smt") << "settting stringProcessLoopMode to 'simple' since "
757 "--strings-fmf enabled"
759 opts
.strings
.stringProcessLoopMode
= options::ProcessLoopMode::SIMPLE
;
762 // !!! All options that require disabling models go here
763 std::stringstream reasonNoModel
;
764 if (incompatibleWithModels(opts
, reasonNoModel
))
766 std::string sOptNoModel
= reasonNoModel
.str();
767 if (opts
.smt
.produceModels
)
769 if (opts
.smt
.produceModelsWasSetByUser
)
771 std::stringstream ss
;
772 ss
<< "Cannot use " << sOptNoModel
<< " with model generation.";
773 throw OptionException(ss
.str());
775 Notice() << "SolverEngine: turning off produce-models to support "
776 << sOptNoModel
<< std::endl
;
777 opts
.smt
.produceModels
= false;
779 if (opts
.smt
.produceAssignments
)
781 if (opts
.smt
.produceAssignmentsWasSetByUser
)
783 std::stringstream ss
;
784 ss
<< "Cannot use " << sOptNoModel
785 << " with model generation (produce-assignments).";
786 throw OptionException(ss
.str());
788 Notice() << "SolverEngine: turning off produce-assignments to support "
789 << sOptNoModel
<< std::endl
;
790 opts
.smt
.produceAssignments
= false;
792 if (opts
.smt
.checkModels
)
794 if (opts
.smt
.checkModelsWasSetByUser
)
796 std::stringstream ss
;
797 ss
<< "Cannot use " << sOptNoModel
798 << " with model generation (check-models).";
799 throw OptionException(ss
.str());
801 Notice() << "SolverEngine: turning off check-models to support "
802 << sOptNoModel
<< std::endl
;
803 opts
.smt
.checkModels
= false;
807 if (opts
.bv
.bitblastMode
== options::BitblastMode::EAGER
808 && !logic
.isPure(THEORY_BV
) && logic
.getLogicString() != "QF_UFBV"
809 && logic
.getLogicString() != "QF_ABV")
811 throw OptionException(
812 "Eager bit-blasting does not currently support theory combination. "
813 "Note that in a QF_BV problem UF symbols can be introduced for "
815 "Try --bv-div-zero-const to interpret division by zero as a constant.");
819 if (logic
== LogicInfo("QF_UFNRA"))
821 if (!opts
.arith
.nlCad
&& !opts
.arith
.nlCadWasSetByUser
)
823 opts
.arith
.nlCad
= true;
824 if (!opts
.arith
.nlExtWasSetByUser
)
826 opts
.arith
.nlExt
= options::NlExtMode::LIGHT
;
828 if (!opts
.arith
.nlRlvModeWasSetByUser
)
830 opts
.arith
.nlRlvMode
= options::NlRlvMode::INTERLEAVE
;
835 if (opts
.arith
.nlCad
)
837 if (opts
.arith
.nlCadWasSetByUser
)
839 throw OptionException(
840 "Cannot use --nl-cad without configuring with --poly.");
844 Notice() << "Cannot use --nl-cad without configuring with --poly."
846 opts
.arith
.nlCad
= false;
847 opts
.arith
.nlExt
= options::NlExtMode::FULL
;
853 bool SetDefaults::isSygus(const Options
& opts
) const
855 if (language::isLangSygus(opts
.base
.inputLanguage
))
859 if (!d_isInternalSubsolver
)
861 if (opts
.smt
.produceAbducts
862 || opts
.smt
.produceInterpols
!= options::ProduceInterpols::NONE
863 || opts
.quantifiers
.sygusInference
864 || opts
.quantifiers
.sygusRewSynthInput
)
866 // since we are trying to recast as sygus, we assume the input is sygus
873 bool SetDefaults::usesSygus(const Options
& opts
) const
879 if (!d_isInternalSubsolver
&& opts
.quantifiers
.sygusInst
)
881 // sygus instantiation uses sygus, but it is not a sygus problem
887 bool SetDefaults::incompatibleWithProofs(Options
& opts
,
888 std::ostream
& reason
) const
890 if (opts
.quantifiers
.globalNegate
)
892 // When global negate answers "unsat", it is not due to showing a set of
893 // formulas is unsat. Thus, proofs do not apply.
894 reason
<< "global-negate";
899 // When sygus answers "unsat", it is not due to showing a set of
900 // formulas is unsat in the standard way. Thus, proofs do not apply.
904 // options that are automatically set to support proofs
905 if (opts
.bv
.bvAssertInput
)
908 << "Disabling bv-assert-input since it is incompatible with proofs."
910 opts
.bv
.bvAssertInput
= false;
912 // If proofs are required and the user did not specify a specific BV solver,
913 // we make sure to use the proof producing BITBLAST_INTERNAL solver.
914 if (opts
.bv
.bvSolver
!= options::BVSolver::BITBLAST_INTERNAL
915 && !opts
.bv
.bvSolverWasSetByUser
916 && opts
.bv
.bvSatSolver
== options::SatSolverMode::MINISAT
)
918 Notice() << "Forcing internal bit-vector solver due to proof production."
920 opts
.bv
.bvSolver
= options::BVSolver::BITBLAST_INTERNAL
;
925 bool SetDefaults::incompatibleWithModels(const Options
& opts
,
926 std::ostream
& reason
) const
928 if (opts
.smt
.unconstrainedSimpWasSetByUser
&& opts
.smt
.unconstrainedSimp
)
930 reason
<< "unconstrained-simp";
933 else if (opts
.smt
.sortInference
)
935 reason
<< "sort-inference";
938 else if (opts
.prop
.minisatUseElim
)
940 reason
<< "minisat-elimination";
943 else if (opts
.quantifiers
.globalNegate
)
945 reason
<< "global-negate";
951 bool SetDefaults::incompatibleWithIncremental(const LogicInfo
& logic
,
953 std::ostream
& reason
,
954 std::ostream
& suggest
) const
956 if (opts
.smt
.ackermann
)
958 reason
<< "ackermann";
961 if (opts
.smt
.unconstrainedSimp
)
963 if (opts
.smt
.unconstrainedSimpWasSetByUser
)
965 reason
<< "unconstrained simplification";
968 Notice() << "SolverEngine: turning off unconstrained simplification to "
969 "support incremental solving"
971 opts
.smt
.unconstrainedSimp
= false;
973 if (opts
.bv
.bitblastMode
== options::BitblastMode::EAGER
974 && !logic
.isPure(THEORY_BV
))
976 reason
<< "eager bit-blasting in non-QF_BV logic";
977 suggest
<< "Try --bitblast=lazy.";
980 if (opts
.quantifiers
.sygusInference
)
982 if (opts
.quantifiers
.sygusInferenceWasSetByUser
)
984 reason
<< "sygus inference";
987 Notice() << "SolverEngine: turning off sygus inference to support "
988 "incremental solving"
990 opts
.quantifiers
.sygusInference
= false;
992 if (opts
.smt
.solveIntAsBV
> 0)
994 reason
<< "solveIntAsBV";
998 // disable modes not supported by incremental
999 opts
.smt
.sortInference
= false;
1000 opts
.uf
.ufssFairnessMonotone
= false;
1001 opts
.quantifiers
.globalNegate
= false;
1002 opts
.quantifiers
.cegqiNestedQE
= false;
1003 opts
.bv
.bvAbstraction
= false;
1004 opts
.arith
.arithMLTrick
= false;
1009 bool SetDefaults::incompatibleWithUnsatCores(Options
& opts
,
1010 std::ostream
& reason
) const
1012 if (opts
.smt
.simplificationMode
!= options::SimplificationMode::NONE
)
1014 if (opts
.smt
.simplificationModeWasSetByUser
)
1016 reason
<< "simplification";
1019 Notice() << "SolverEngine: turning off simplification to support unsat "
1022 opts
.smt
.simplificationMode
= options::SimplificationMode::NONE
;
1025 if (opts
.smt
.learnedRewrite
)
1027 if (opts
.smt
.learnedRewriteWasSetByUser
)
1029 reason
<< "learned rewrites";
1032 Notice() << "SolverEngine: turning off learned rewrites to support "
1034 opts
.smt
.learnedRewrite
= false;
1037 if (opts
.arith
.pbRewrites
)
1039 if (opts
.arith
.pbRewritesWasSetByUser
)
1041 reason
<< "pseudoboolean rewrites";
1044 Notice() << "SolverEngine: turning off pseudoboolean rewrites to support "
1046 opts
.arith
.pbRewrites
= false;
1049 if (opts
.smt
.sortInference
)
1051 if (opts
.smt
.sortInferenceWasSetByUser
)
1053 reason
<< "sort inference";
1056 Notice() << "SolverEngine: turning off sort inference to support unsat "
1058 opts
.smt
.sortInference
= false;
1061 if (opts
.quantifiers
.preSkolemQuant
)
1063 if (opts
.quantifiers
.preSkolemQuantWasSetByUser
)
1065 reason
<< "pre-skolemization";
1068 Notice() << "SolverEngine: turning off pre-skolemization to support "
1070 opts
.quantifiers
.preSkolemQuant
= false;
1073 if (opts
.bv
.bitvectorToBool
)
1075 if (opts
.bv
.bitvectorToBoolWasSetByUser
)
1077 reason
<< "bv-to-bool";
1080 Notice() << "SolverEngine: turning off bitvector-to-bool to support "
1082 opts
.bv
.bitvectorToBool
= false;
1085 if (opts
.bv
.boolToBitvector
!= options::BoolToBVMode::OFF
)
1087 if (opts
.bv
.boolToBitvectorWasSetByUser
)
1089 reason
<< "bool-to-bv != off";
1092 Notice() << "SolverEngine: turning off bool-to-bv to support unsat cores\n";
1093 opts
.bv
.boolToBitvector
= options::BoolToBVMode::OFF
;
1096 if (opts
.bv
.bvIntroducePow2
)
1098 if (opts
.bv
.bvIntroducePow2WasSetByUser
)
1100 reason
<< "bv-intro-pow2";
1104 << "SolverEngine: turning off bv-intro-pow2 to support unsat cores";
1105 opts
.bv
.bvIntroducePow2
= false;
1108 if (opts
.smt
.repeatSimp
)
1110 if (opts
.smt
.repeatSimpWasSetByUser
)
1112 reason
<< "repeat-simp";
1116 << "SolverEngine: turning off repeat-simp to support unsat cores\n";
1117 opts
.smt
.repeatSimp
= false;
1120 if (opts
.quantifiers
.globalNegate
)
1122 if (opts
.quantifiers
.globalNegateWasSetByUser
)
1124 reason
<< "global-negate";
1127 Notice() << "SolverEngine: turning off global-negate to support unsat "
1129 opts
.quantifiers
.globalNegate
= false;
1132 if (opts
.bv
.bitvectorAig
)
1134 reason
<< "bitblast-aig";
1138 if (opts
.smt
.doITESimp
)
1140 reason
<< "ITE simp";
1143 if (opts
.smt
.unconstrainedSimp
)
1145 if (opts
.smt
.unconstrainedSimpWasSetByUser
)
1147 reason
<< "unconstrained simplification";
1150 Notice() << "SolverEngine: turning off unconstrained simplification to "
1151 "support unsat cores"
1153 opts
.smt
.unconstrainedSimp
= false;
1158 bool SetDefaults::safeUnsatCores(const Options
& opts
) const
1160 // whether we want to force safe unsat cores, i.e., if we are in the default
1161 // ASSUMPTIONS mode or PP_ONLY, since other ones are experimental
1162 return opts
.smt
.unsatCoresMode
== options::UnsatCoresMode::ASSUMPTIONS
1163 || opts
.smt
.unsatCoresMode
== options::UnsatCoresMode::PP_ONLY
;
1166 bool SetDefaults::incompatibleWithQuantifiers(Options
& opts
,
1167 std::ostream
& reason
) const
1169 if (opts
.smt
.ackermann
)
1171 reason
<< "ackermann";
1174 if (opts
.arith
.nlRlvMode
!= options::NlRlvMode::NONE
)
1176 // Theory relevance is incompatible with CEGQI and SyQI, since there is no
1177 // appropriate policy for the relevance of counterexample lemmas (when their
1178 // guard is entailed to be false, the entire lemma is relevant, not just the
1179 // guard). Hence, we throw an option exception if quantifiers are enabled.
1180 reason
<< "--nl-ext-rlv";
1186 void SetDefaults::widenLogic(LogicInfo
& logic
, const Options
& opts
) const
1188 bool needsUf
= false;
1189 // strings require LIA, UF; widen the logic
1190 if (logic
.isTheoryEnabled(THEORY_STRINGS
))
1192 LogicInfo
log(logic
.getUnlockedCopy());
1193 // Strings requires arith for length constraints, and also UF
1195 if (!logic
.isTheoryEnabled(THEORY_ARITH
) || logic
.isDifferenceLogic())
1198 << "Enabling linear integer arithmetic because strings are enabled"
1200 log
.enableTheory(THEORY_ARITH
);
1201 log
.enableIntegers();
1202 log
.arithOnlyLinear();
1204 else if (!logic
.areIntegersUsed())
1206 Notice() << "Enabling integer arithmetic because strings are enabled"
1208 log
.enableIntegers();
1213 if (opts
.bv
.bvAbstraction
)
1215 // bv abstraction may require UF
1216 Notice() << "Enabling UF because bvAbstraction requires it." << std::endl
;
1219 else if (opts
.quantifiers
.preSkolemQuantNested
1220 && opts
.quantifiers
.preSkolemQuantNestedWasSetByUser
)
1222 // if pre-skolem nested is explictly set, then we require UF. If it is
1223 // not explicitly set, it is disabled below if UF is not present.
1224 Notice() << "Enabling UF because preSkolemQuantNested requires it."
1229 // Arrays, datatypes and sets permit Boolean terms and thus require UF
1230 || logic
.isTheoryEnabled(THEORY_ARRAYS
)
1231 || logic
.isTheoryEnabled(THEORY_DATATYPES
)
1232 || logic
.isTheoryEnabled(THEORY_SETS
)
1233 || logic
.isTheoryEnabled(THEORY_BAGS
)
1234 // Non-linear arithmetic requires UF to deal with division/mod because
1235 // their expansion introduces UFs for the division/mod-by-zero case.
1236 // If we are eliminating non-linear arithmetic via solve-int-as-bv,
1237 // then this is not required, since non-linear arithmetic will be
1238 // eliminated altogether (or otherwise fail at preprocessing).
1239 || (logic
.isTheoryEnabled(THEORY_ARITH
) && !logic
.isLinear()
1240 && opts
.smt
.solveIntAsBV
== 0)
1241 // FP requires UF since there are multiple operators that are partially
1242 // defined (see http://smtlib.cs.uiowa.edu/papers/BTRW15.pdf for more
1244 || logic
.isTheoryEnabled(THEORY_FP
))
1246 if (!logic
.isTheoryEnabled(THEORY_UF
))
1248 LogicInfo
log(logic
.getUnlockedCopy());
1251 Notice() << "Enabling UF because " << logic
<< " requires it."
1254 log
.enableTheory(THEORY_UF
);
1259 if (opts
.arith
.arithMLTrick
)
1261 if (!logic
.areIntegersUsed())
1264 LogicInfo
log(logic
.getUnlockedCopy());
1265 Notice() << "Enabling integers because arithMLTrick requires it."
1267 log
.enableIntegers();
1274 void SetDefaults::setDefaultsQuantifiers(const LogicInfo
& logic
,
1275 Options
& opts
) const
1277 if (opts
.arrays
.arraysExp
)
1279 // Allows to answer sat more often by default.
1280 if (!opts
.quantifiers
.fmfBoundWasSetByUser
)
1282 opts
.quantifiers
.fmfBound
= true;
1283 Trace("smt") << "turning on fmf-bound, for arrays-exp" << std::endl
;
1286 if (logic
.hasCardinalityConstraints())
1288 // must have finite model finding on
1289 opts
.quantifiers
.finiteModelFind
= true;
1292 if (opts
.quantifiers
.instMaxLevel
!= -1)
1294 Notice() << "SolverEngine: turning off cbqi to support instMaxLevel"
1296 opts
.quantifiers
.cegqi
= false;
1299 if ((opts
.quantifiers
.fmfBoundLazyWasSetByUser
1300 && opts
.quantifiers
.fmfBoundLazy
)
1301 || (opts
.quantifiers
.fmfBoundIntWasSetByUser
1302 && opts
.quantifiers
.fmfBoundInt
))
1304 opts
.quantifiers
.fmfBound
= true;
1306 << "turning on fmf-bound, for fmf-bound-int or fmf-bound-lazy\n";
1308 // now have determined whether fmfBound is on/off
1309 // apply fmfBound options
1310 if (opts
.quantifiers
.fmfBound
)
1312 if (!opts
.quantifiers
.mbqiModeWasSetByUser
1313 || (opts
.quantifiers
.mbqiMode
!= options::MbqiMode::NONE
1314 && opts
.quantifiers
.mbqiMode
!= options::MbqiMode::FMC
))
1316 // if bounded integers are set, use no MBQI by default
1317 opts
.quantifiers
.mbqiMode
= options::MbqiMode::NONE
;
1319 if (!opts
.quantifiers
.prenexQuantUserWasSetByUser
)
1321 opts
.quantifiers
.prenexQuant
= options::PrenexQuantMode::NONE
;
1324 if (logic
.isHigherOrder())
1326 // if higher-order, then current variants of model-based instantiation
1328 if (opts
.quantifiers
.mbqiMode
!= options::MbqiMode::NONE
)
1330 opts
.quantifiers
.mbqiMode
= options::MbqiMode::NONE
;
1332 if (!opts
.quantifiers
.hoElimStoreAxWasSetByUser
)
1334 // by default, use store axioms only if --ho-elim is set
1335 opts
.quantifiers
.hoElimStoreAx
= opts
.quantifiers
.hoElim
;
1337 // Cannot use macros, since lambda lifting and macro elimination are inverse
1339 if (opts
.quantifiers
.macrosQuant
)
1341 opts
.quantifiers
.macrosQuant
= false;
1343 // HOL is incompatible with fmfBound
1344 if (opts
.quantifiers
.fmfBound
)
1346 if (opts
.quantifiers
.fmfBoundWasSetByUser
1347 || opts
.quantifiers
.fmfBoundLazyWasSetByUser
1348 || opts
.quantifiers
.fmfBoundIntWasSetByUser
)
1350 Notice() << "Disabling bound finite-model finding since it is "
1351 "incompatible with HOL.\n";
1354 opts
.quantifiers
.fmfBound
= false;
1355 Trace("smt") << "turning off fmf-bound, since HOL\n";
1358 if (opts
.quantifiers
.fmfFunWellDefinedRelevant
)
1360 if (!opts
.quantifiers
.fmfFunWellDefinedWasSetByUser
)
1362 opts
.quantifiers
.fmfFunWellDefined
= true;
1365 if (opts
.quantifiers
.fmfFunWellDefined
)
1367 if (!opts
.quantifiers
.finiteModelFindWasSetByUser
)
1369 opts
.quantifiers
.finiteModelFind
= true;
1373 // now, have determined whether finite model find is on/off
1374 // apply finite model finding options
1375 if (opts
.quantifiers
.finiteModelFind
)
1377 // apply conservative quantifiers splitting
1378 if (!opts
.quantifiers
.quantDynamicSplitWasSetByUser
)
1380 opts
.quantifiers
.quantDynamicSplit
= options::QuantDSplitMode::DEFAULT
;
1382 if (!opts
.quantifiers
.eMatchingWasSetByUser
)
1384 opts
.quantifiers
.eMatching
= opts
.quantifiers
.fmfInstEngine
;
1386 if (!opts
.quantifiers
.instWhenModeWasSetByUser
)
1388 // instantiate only on last call
1389 if (opts
.quantifiers
.eMatching
)
1391 opts
.quantifiers
.instWhenMode
= options::InstWhenMode::LAST_CALL
;
1396 // apply sygus options
1397 // if we are attempting to rewrite everything to SyGuS, use sygus()
1398 if (usesSygus(opts
))
1400 setDefaultsSygus(opts
);
1402 // counterexample-guided instantiation for non-sygus
1403 // enable if any possible quantifiers with arithmetic, datatypes or bitvectors
1404 if ((logic
.isQuantified()
1405 && (logic
.isTheoryEnabled(THEORY_ARITH
)
1406 || logic
.isTheoryEnabled(THEORY_DATATYPES
)
1407 || logic
.isTheoryEnabled(THEORY_BV
)
1408 || logic
.isTheoryEnabled(THEORY_FP
)))
1409 || opts
.quantifiers
.cegqiAll
)
1411 if (!opts
.quantifiers
.cegqiWasSetByUser
)
1413 opts
.quantifiers
.cegqi
= true;
1415 // check whether we should apply full cbqi
1416 if (logic
.isPure(THEORY_BV
))
1418 if (!opts
.quantifiers
.cegqiFullEffortWasSetByUser
)
1420 opts
.quantifiers
.cegqiFullEffort
= true;
1424 if (opts
.quantifiers
.cegqi
)
1426 if (logic
.isPure(THEORY_ARITH
) || logic
.isPure(THEORY_BV
))
1428 if (!opts
.quantifiers
.quantConflictFindWasSetByUser
)
1430 opts
.quantifiers
.quantConflictFind
= false;
1432 if (!opts
.quantifiers
.instNoEntailWasSetByUser
)
1434 opts
.quantifiers
.instNoEntail
= false;
1436 if (!opts
.quantifiers
.instWhenModeWasSetByUser
1437 && opts
.quantifiers
.cegqiModel
)
1439 // only instantiation should happen at last call when model is avaiable
1440 opts
.quantifiers
.instWhenMode
= options::InstWhenMode::LAST_CALL
;
1445 // only supported in pure arithmetic or pure BV
1446 opts
.quantifiers
.cegqiNestedQE
= false;
1448 if (opts
.quantifiers
.globalNegate
)
1450 if (!opts
.quantifiers
.prenexQuantWasSetByUser
)
1452 opts
.quantifiers
.prenexQuant
= options::PrenexQuantMode::NONE
;
1456 // implied options...
1457 if (opts
.quantifiers
.qcfModeWasSetByUser
|| opts
.quantifiers
.qcfTConstraint
)
1459 opts
.quantifiers
.quantConflictFind
= true;
1461 if (opts
.quantifiers
.cegqiNestedQE
)
1463 opts
.quantifiers
.prenexQuantUser
= true;
1464 if (!opts
.quantifiers
.preSkolemQuantWasSetByUser
)
1466 opts
.quantifiers
.preSkolemQuant
= true;
1469 // for induction techniques
1470 if (opts
.quantifiers
.quantInduction
)
1472 if (!opts
.quantifiers
.dtStcInductionWasSetByUser
)
1474 opts
.quantifiers
.dtStcInduction
= true;
1476 if (!opts
.quantifiers
.intWfInductionWasSetByUser
)
1478 opts
.quantifiers
.intWfInduction
= true;
1481 if (opts
.quantifiers
.dtStcInduction
)
1483 // try to remove ITEs from quantified formulas
1484 if (!opts
.quantifiers
.iteDtTesterSplitQuantWasSetByUser
)
1486 opts
.quantifiers
.iteDtTesterSplitQuant
= true;
1488 if (!opts
.quantifiers
.iteLiftQuantWasSetByUser
)
1490 opts
.quantifiers
.iteLiftQuant
= options::IteLiftQuantMode::ALL
;
1493 if (opts
.quantifiers
.intWfInduction
)
1495 if (!opts
.quantifiers
.purifyTriggersWasSetByUser
)
1497 opts
.quantifiers
.purifyTriggers
= true;
1500 if (opts
.quantifiers
.conjectureNoFilter
)
1502 if (!opts
.quantifiers
.conjectureFilterActiveTermsWasSetByUser
)
1504 opts
.quantifiers
.conjectureFilterActiveTerms
= false;
1506 if (!opts
.quantifiers
.conjectureFilterCanonicalWasSetByUser
)
1508 opts
.quantifiers
.conjectureFilterCanonical
= false;
1510 if (!opts
.quantifiers
.conjectureFilterModelWasSetByUser
)
1512 opts
.quantifiers
.conjectureFilterModel
= false;
1515 if (opts
.quantifiers
.conjectureGenPerRoundWasSetByUser
)
1517 if (opts
.quantifiers
.conjectureGenPerRound
> 0)
1519 opts
.quantifiers
.conjectureGen
= true;
1523 opts
.quantifiers
.conjectureGen
= false;
1526 // can't pre-skolemize nested quantifiers without UF theory
1527 if (!logic
.isTheoryEnabled(THEORY_UF
) && opts
.quantifiers
.preSkolemQuant
)
1529 if (!opts
.quantifiers
.preSkolemQuantNestedWasSetByUser
)
1531 opts
.quantifiers
.preSkolemQuantNested
= false;
1534 if (!logic
.isTheoryEnabled(THEORY_DATATYPES
))
1536 opts
.quantifiers
.quantDynamicSplit
= options::QuantDSplitMode::NONE
;
1540 void SetDefaults::setDefaultsSygus(Options
& opts
) const
1542 if (!opts
.quantifiers
.sygus
)
1544 Trace("smt") << "turning on sygus" << std::endl
;
1546 opts
.quantifiers
.sygus
= true;
1547 // must use Ferrante/Rackoff for real arithmetic
1548 if (!opts
.quantifiers
.cegqiMidpointWasSetByUser
)
1550 opts
.quantifiers
.cegqiMidpoint
= true;
1552 // must disable cegqi-bv since it may introduce witness terms, which
1553 // cannot appear in synthesis solutions
1554 if (!opts
.quantifiers
.cegqiBvWasSetByUser
)
1556 opts
.quantifiers
.cegqiBv
= false;
1558 if (opts
.quantifiers
.sygusRepairConst
)
1560 if (!opts
.quantifiers
.cegqiWasSetByUser
)
1562 opts
.quantifiers
.cegqi
= true;
1565 if (opts
.quantifiers
.sygusInference
)
1567 // optimization: apply preskolemization, makes it succeed more often
1568 if (!opts
.quantifiers
.preSkolemQuantWasSetByUser
)
1570 opts
.quantifiers
.preSkolemQuant
= true;
1572 if (!opts
.quantifiers
.preSkolemQuantNestedWasSetByUser
)
1574 opts
.quantifiers
.preSkolemQuantNested
= true;
1577 // counterexample-guided instantiation for sygus
1578 if (!opts
.quantifiers
.cegqiSingleInvModeWasSetByUser
)
1580 opts
.quantifiers
.cegqiSingleInvMode
= options::CegqiSingleInvMode::USE
;
1582 if (!opts
.quantifiers
.quantConflictFindWasSetByUser
)
1584 opts
.quantifiers
.quantConflictFind
= false;
1586 if (!opts
.quantifiers
.instNoEntailWasSetByUser
)
1588 opts
.quantifiers
.instNoEntail
= false;
1590 if (!opts
.quantifiers
.cegqiFullEffortWasSetByUser
)
1592 // should use full effort cbqi for single invocation and repair const
1593 opts
.quantifiers
.cegqiFullEffort
= true;
1595 if (opts
.quantifiers
.sygusRew
)
1597 opts
.quantifiers
.sygusRewSynth
= true;
1598 opts
.quantifiers
.sygusRewVerify
= true;
1600 if (opts
.quantifiers
.sygusRewSynthInput
)
1602 // If we are using synthesis rewrite rules from input, we use
1603 // sygusRewSynth after preprocessing. See passes/synth_rew_rules.h for
1604 // details on this technique.
1605 opts
.quantifiers
.sygusRewSynth
= true;
1606 // we should not use the extended rewriter, since we are interested
1607 // in rewrites that are not in the main rewriter
1608 if (!opts
.quantifiers
.sygusExtRewWasSetByUser
)
1610 opts
.quantifiers
.sygusExtRew
= false;
1613 // Whether we must use "basic" sygus algorithms. A non-basic sygus algorithm
1614 // is one that is specialized for returning a single solution. Non-basic
1615 // sygus algorithms currently include the PBE solver, UNIF+PI, static
1616 // template inference for invariant synthesis, and single invocation
1618 bool reqBasicSygus
= false;
1619 if (opts
.smt
.produceAbducts
)
1621 // if doing abduction, we should filter strong solutions
1622 if (!opts
.quantifiers
.sygusFilterSolModeWasSetByUser
)
1624 opts
.quantifiers
.sygusFilterSolMode
= options::SygusFilterSolMode::STRONG
;
1626 // we must use basic sygus algorithms, since e.g. we require checking
1627 // a sygus side condition for consistency with axioms.
1628 reqBasicSygus
= true;
1630 if (opts
.quantifiers
.sygusRewSynth
|| opts
.quantifiers
.sygusRewVerify
1631 || opts
.quantifiers
.sygusQueryGen
)
1633 // rewrite rule synthesis implies that sygus stream must be true
1634 opts
.quantifiers
.sygusStream
= true;
1636 if (opts
.quantifiers
.sygusStream
|| opts
.base
.incrementalSolving
)
1638 // Streaming and incremental mode are incompatible with techniques that
1639 // focus the search towards finding a single solution.
1640 reqBasicSygus
= true;
1642 // Now, disable options for non-basic sygus algorithms, if necessary.
1645 if (!opts
.quantifiers
.sygusUnifPbeWasSetByUser
)
1647 opts
.quantifiers
.sygusUnifPbe
= false;
1649 if (opts
.quantifiers
.sygusUnifPiWasSetByUser
)
1651 opts
.quantifiers
.sygusUnifPi
= options::SygusUnifPiMode::NONE
;
1653 if (!opts
.quantifiers
.sygusInvTemplModeWasSetByUser
)
1655 opts
.quantifiers
.sygusInvTemplMode
= options::SygusInvTemplMode::NONE
;
1657 if (!opts
.quantifiers
.cegqiSingleInvModeWasSetByUser
)
1659 opts
.quantifiers
.cegqiSingleInvMode
= options::CegqiSingleInvMode::NONE
;
1663 if (!opts
.quantifiers
.miniscopeQuantWasSetByUser
)
1665 opts
.quantifiers
.miniscopeQuant
= false;
1667 if (!opts
.quantifiers
.miniscopeQuantFreeVarWasSetByUser
)
1669 opts
.quantifiers
.miniscopeQuantFreeVar
= false;
1671 if (!opts
.quantifiers
.quantSplitWasSetByUser
)
1673 opts
.quantifiers
.quantSplit
= false;
1676 if (!opts
.quantifiers
.macrosQuantWasSetByUser
)
1678 opts
.quantifiers
.macrosQuant
= false;
1681 void SetDefaults::setDefaultDecisionMode(const LogicInfo
& logic
,
1682 Options
& opts
) const
1684 // Set decision mode based on logic (if not set by user)
1685 if (opts
.decision
.decisionModeWasSetByUser
)
1689 options::DecisionMode decMode
=
1690 // anything that uses sygus uses internal
1691 usesSygus(opts
) ? options::DecisionMode::INTERNAL
:
1692 // ALL or its supersets
1693 logic
.hasEverything()
1694 ? options::DecisionMode::JUSTIFICATION
1696 (not logic
.isQuantified() && logic
.isPure(THEORY_BV
)) ||
1697 // QF_AUFBV or QF_ABV or QF_UFBV
1698 (not logic
.isQuantified()
1699 && (logic
.isTheoryEnabled(THEORY_ARRAYS
)
1700 || logic
.isTheoryEnabled(THEORY_UF
))
1701 && logic
.isTheoryEnabled(THEORY_BV
))
1703 // QF_AUFLIA (and may be ends up enabling
1705 (not logic
.isQuantified()
1706 && logic
.isTheoryEnabled(THEORY_ARRAYS
)
1707 && logic
.isTheoryEnabled(THEORY_UF
)
1708 && logic
.isTheoryEnabled(THEORY_ARITH
))
1711 (not logic
.isQuantified()
1712 && logic
.isPure(THEORY_ARITH
) && logic
.isLinear()
1713 && !logic
.isDifferenceLogic()
1714 && !logic
.areIntegersUsed())
1717 logic
.isQuantified() ||
1719 logic
.isTheoryEnabled(THEORY_STRINGS
)
1720 ? options::DecisionMode::JUSTIFICATION
1721 : options::DecisionMode::INTERNAL
);
1724 // ALL or its supersets
1725 logic
.hasEverything() || logic
.isTheoryEnabled(THEORY_STRINGS
)
1728 (not logic
.isQuantified()
1729 && logic
.isTheoryEnabled(THEORY_ARRAYS
)
1730 && logic
.isTheoryEnabled(THEORY_UF
)
1731 && logic
.isTheoryEnabled(THEORY_ARITH
))
1734 (not logic
.isQuantified() && logic
.isPure(THEORY_ARITH
)
1735 && logic
.isLinear() && !logic
.isDifferenceLogic()
1736 && !logic
.areIntegersUsed())
1740 opts
.decision
.decisionMode
= decMode
;
1743 if (opts
.decision
.decisionMode
== options::DecisionMode::JUSTIFICATION
)
1745 opts
.decision
.decisionMode
= options::DecisionMode::STOPONLY
;
1749 Assert(opts
.decision
.decisionMode
== options::DecisionMode::INTERNAL
);
1752 Trace("smt") << "setting decision mode to " << opts
.decision
.decisionMode