1 /********************* */
4 ** Original author: Morgan Deters
5 ** Major contributors: none
6 ** Minor contributors (to current version): Dejan Jovanovic
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2013 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
12 ** \brief A class giving information about a logic (group a theory modules
13 ** and configuration information)
15 ** A class giving information about a logic (group of theory modules and
16 ** configuration information).
19 #include "cvc4_public.h"
21 #ifndef __CVC4__LOGIC_INFO_H
22 #define __CVC4__LOGIC_INFO_H
26 #include "expr/kind.h"
31 * A LogicInfo instance describes a collection of theory modules and some
32 * basic configuration about them. Conceptually, it provides a background
33 * context for all operations in CVC4. Typically, when CVC4's SmtEngine
34 * is created, it is issued a setLogic() command indicating features of the
35 * assertions and queries to follow---for example, whether quantifiers are
36 * used, whether integers or reals (or both) will be used, etc.
38 * Most places in CVC4 will only ever need to access a const reference to an
39 * instance of this class. Such an instance is generally set by the SmtEngine
40 * when setLogic() is called. However, mutating member functions are also
41 * provided by this class so that it can be used as a more general mechanism
42 * (e.g., for communicating to the SmtEngine which theories should be used,
43 * rather than having to provide an SMT-LIB string).
45 class CVC4_PUBLIC LogicInfo
{
46 mutable std::string d_logicString
; /**< an SMT-LIB-like logic string */
47 std::vector
<bool> d_theories
; /**< set of active theories */
48 size_t d_sharingTheories
; /**< count of theories that need sharing */
51 bool d_integers
; /**< are integers used in this logic? */
52 bool d_reals
; /**< are reals used in this logic? */
53 bool d_linear
; /**< linear-only arithmetic in this logic? */
54 bool d_differenceLogic
; /**< difference-only arithmetic in this logic? */
56 bool d_locked
; /**< is this LogicInfo instance locked (and thus immutable)? */
59 * Returns true iff this is a "true" theory (one that must be worried
62 static inline bool isTrueTheory(theory::TheoryId theory
) {
64 case theory::THEORY_BUILTIN
:
65 case theory::THEORY_BOOL
:
66 case theory::THEORY_QUANTIFIERS
:
76 * Constructs a LogicInfo for the most general logic (quantifiers, all
77 * background theory modules, ...).
82 * Construct a LogicInfo from an SMT-LIB-like logic string.
83 * Throws an IllegalArgumentException if the logic string cannot
86 LogicInfo(std::string logicString
) throw(IllegalArgumentException
);
89 * Construct a LogicInfo from an SMT-LIB-like logic string.
90 * Throws an IllegalArgumentException if the logic string cannot
93 LogicInfo(const char* logicString
) throw(IllegalArgumentException
);
98 * Get an SMT-LIB-like logic string. These are only guaranteed to
99 * be SMT-LIB-compliant if an SMT-LIB-compliant string was used in
100 * the constructor and no mutating functions were called.
102 std::string
getLogicString() const;
104 /** Is sharing enabled for this logic? */
105 bool isSharingEnabled() const {
106 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
107 return d_sharingTheories
> 1;
110 /** Is the given theory module active in this logic? */
111 bool isTheoryEnabled(theory::TheoryId theory
) const {
112 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
113 return d_theories
[theory
];
116 /** Is this a quantified logic? */
117 bool isQuantified() const {
118 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
119 return isTheoryEnabled(theory::THEORY_QUANTIFIERS
);
122 /** Is this the all-inclusive logic? */
123 bool hasEverything() const {
124 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
125 LogicInfo everything
;
127 return *this == everything
;
130 /** Is this the all-exclusive logic? (Here, that means propositional logic) */
131 bool hasNothing() const {
132 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
133 LogicInfo
nothing("");
135 return *this == nothing
;
139 * Is this a pure logic (only one "true" background theory). Quantifiers
140 * can exist in such logics though; to test for quantifier-free purity,
141 * use "isPure(theory) && !isQuantified()".
143 bool isPure(theory::TheoryId theory
) const {
144 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
145 // the third and fourth conjucts are really just to rule out the misleading
146 // case where you ask isPure(THEORY_BOOL) and get true even in e.g. QF_LIA
147 return isTheoryEnabled(theory
) && !isSharingEnabled() &&
148 ( !isTrueTheory(theory
) || d_sharingTheories
== 1 ) &&
149 ( isTrueTheory(theory
) || d_sharingTheories
== 0 );
152 // these are for arithmetic
154 /** Are integers in this logic? */
155 bool areIntegersUsed() const {
156 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
157 CheckArgument(isTheoryEnabled(theory::THEORY_ARITH
), *this, "Arithmetic not used in this LogicInfo; cannot ask whether integers are used");
160 /** Are reals in this logic? */
161 bool areRealsUsed() const {
162 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
163 CheckArgument(isTheoryEnabled(theory::THEORY_ARITH
), *this, "Arithmetic not used in this LogicInfo; cannot ask whether reals are used");
166 /** Does this logic only linear arithmetic? */
167 bool isLinear() const {
168 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
169 CheckArgument(isTheoryEnabled(theory::THEORY_ARITH
), *this, "Arithmetic not used in this LogicInfo; cannot ask whether it's linear");
170 return d_linear
|| d_differenceLogic
;
172 /** Does this logic only permit difference reasoning? (implies linear) */
173 bool isDifferenceLogic() const {
174 CheckArgument(d_locked
, *this, "This LogicInfo isn't locked yet, and cannot be queried");
175 CheckArgument(isTheoryEnabled(theory::THEORY_ARITH
), *this, "Arithmetic not used in this LogicInfo; cannot ask whether it's difference logic");
176 return d_differenceLogic
;
182 * Initialize the LogicInfo with an SMT-LIB-like logic string.
183 * Throws an IllegalArgumentException if the string can't be
186 void setLogicString(std::string logicString
) throw(IllegalArgumentException
);
189 * Enable all functionality. All theories, plus quantifiers, will be
192 void enableEverything();
195 * Disable all functionality. The result will be a LogicInfo with
196 * the BUILTIN and BOOLEAN theories enabled only ("QF_SAT").
198 void disableEverything();
201 * Enable the given theory module.
203 void enableTheory(theory::TheoryId theory
);
206 * Disable the given theory module. THEORY_BUILTIN and THEORY_BOOL cannot
207 * be disabled (and if given here, the request will be silently ignored).
209 void disableTheory(theory::TheoryId theory
);
212 * Quantifiers are a special case, since two theory modules handle them.
214 void enableQuantifiers() {
215 enableTheory(theory::THEORY_QUANTIFIERS
);
219 * Quantifiers are a special case, since two theory modules handle them.
221 void disableQuantifiers() {
222 disableTheory(theory::THEORY_QUANTIFIERS
);
225 // these are for arithmetic
227 /** Enable the use of integers in this logic. */
228 void enableIntegers();
229 /** Disable the use of integers in this logic. */
230 void disableIntegers();
231 /** Enable the use of reals in this logic. */
233 /** Disable the use of reals in this logic. */
235 /** Only permit difference arithmetic in this logic. */
236 void arithOnlyDifference();
237 /** Only permit linear arithmetic in this logic. */
238 void arithOnlyLinear();
239 /** Permit nonlinear arithmetic in this logic. */
240 void arithNonLinear();
242 // LOCKING FUNCTIONALITY
244 /** Lock this LogicInfo, disabling further mutation and allowing queries */
245 void lock() { d_locked
= true; }
246 /** Check whether this LogicInfo is locked, disallowing further mutation */
247 bool isLocked() const { return d_locked
; }
248 /** Get a copy of this LogicInfo that is identical, but unlocked */
249 LogicInfo
getUnlockedCopy() const;
253 /** Are these two LogicInfos equal? */
254 bool operator==(const LogicInfo
& other
) const {
255 CheckArgument(isLocked() && other
.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
256 for(theory::TheoryId id
= theory::THEORY_FIRST
; id
< theory::THEORY_LAST
; ++id
) {
257 if(d_theories
[id
] != other
.d_theories
[id
]) {
261 CheckArgument(d_sharingTheories
== other
.d_sharingTheories
, *this, "LogicInfo internal inconsistency");
262 if(isTheoryEnabled(theory::THEORY_ARITH
)) {
264 d_integers
== other
.d_integers
&&
265 d_reals
== other
.d_reals
&&
266 d_linear
== other
.d_linear
&&
267 d_differenceLogic
== other
.d_differenceLogic
;
272 /** Are these two LogicInfos disequal? */
273 bool operator!=(const LogicInfo
& other
) const {
274 return !(*this == other
);
276 /** Is this LogicInfo "greater than" (does it contain everything and more) the other? */
277 bool operator>(const LogicInfo
& other
) const {
278 return *this >= other
&& *this != other
;
280 /** Is this LogicInfo "less than" (does it contain strictly less) the other? */
281 bool operator<(const LogicInfo
& other
) const {
282 return *this <= other
&& *this != other
;
284 /** Is this LogicInfo "less than or equal" the other? */
285 bool operator<=(const LogicInfo
& other
) const {
286 CheckArgument(isLocked() && other
.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
287 for(theory::TheoryId id
= theory::THEORY_FIRST
; id
< theory::THEORY_LAST
; ++id
) {
288 if(d_theories
[id
] && !other
.d_theories
[id
]) {
292 CheckArgument(d_sharingTheories
<= other
.d_sharingTheories
, *this, "LogicInfo internal inconsistency");
293 if(isTheoryEnabled(theory::THEORY_ARITH
) && other
.isTheoryEnabled(theory::THEORY_ARITH
)) {
295 (!d_integers
|| other
.d_integers
) &&
296 (!d_reals
|| other
.d_reals
) &&
297 (d_linear
|| !other
.d_linear
) &&
298 (d_differenceLogic
|| !other
.d_differenceLogic
);
303 /** Is this LogicInfo "greater than or equal" the other? */
304 bool operator>=(const LogicInfo
& other
) const {
305 CheckArgument(isLocked() && other
.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
306 for(theory::TheoryId id
= theory::THEORY_FIRST
; id
< theory::THEORY_LAST
; ++id
) {
307 if(!d_theories
[id
] && other
.d_theories
[id
]) {
311 CheckArgument(d_sharingTheories
>= other
.d_sharingTheories
, *this, "LogicInfo internal inconsistency");
312 if(isTheoryEnabled(theory::THEORY_ARITH
) && other
.isTheoryEnabled(theory::THEORY_ARITH
)) {
314 (d_integers
|| !other
.d_integers
) &&
315 (d_reals
|| !other
.d_reals
) &&
316 (!d_linear
|| other
.d_linear
) &&
317 (!d_differenceLogic
|| other
.d_differenceLogic
);
323 /** Are two LogicInfos comparable? That is, is one of <= or > true? */
324 bool isComparableTo(const LogicInfo
& other
) const {
325 return *this <= other
|| *this >= other
;
328 };/* class LogicInfo */
330 std::ostream
& operator<<(std::ostream
& out
, const LogicInfo
& logic
) CVC4_PUBLIC
;
332 }/* CVC4 namespace */
334 #endif /* __CVC4__LOGIC_INFO_H */