1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Morgan Deters, Tim King, Andrew Reynolds |
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 |
|
* A class giving information about a logic (group a theory modules |
14 |
|
* and configuration information) |
15 |
|
*/ |
16 |
|
#include "theory/logic_info.h" |
17 |
|
|
18 |
|
#include <cstring> |
19 |
|
#include <iostream> |
20 |
|
#include <sstream> |
21 |
|
#include <string> |
22 |
|
|
23 |
|
#include "base/check.h" |
24 |
|
#include "base/configuration.h" |
25 |
|
#include "expr/kind.h" |
26 |
|
|
27 |
|
using namespace std; |
28 |
|
using namespace cvc5::theory; |
29 |
|
|
30 |
|
namespace cvc5 { |
31 |
|
|
32 |
95528 |
LogicInfo::LogicInfo() |
33 |
|
: d_logicString(""), |
34 |
|
d_theories(THEORY_LAST, false), |
35 |
|
d_sharingTheories(0), |
36 |
|
d_integers(true), |
37 |
|
d_reals(true), |
38 |
|
d_transcendentals(true), |
39 |
|
d_linear(false), |
40 |
|
d_differenceLogic(false), |
41 |
|
d_cardinalityConstraints(false), |
42 |
|
d_higherOrder(false), |
43 |
95528 |
d_locked(false) |
44 |
|
{ |
45 |
1337392 |
for (TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) |
46 |
|
{ |
47 |
1241864 |
enableTheory(id); |
48 |
|
} |
49 |
95528 |
} |
50 |
|
|
51 |
11040 |
LogicInfo::LogicInfo(std::string logicString) |
52 |
|
: d_logicString(""), |
53 |
|
d_theories(THEORY_LAST, false), |
54 |
|
d_sharingTheories(0), |
55 |
|
d_integers(false), |
56 |
|
d_reals(false), |
57 |
|
d_transcendentals(false), |
58 |
|
d_linear(false), |
59 |
|
d_differenceLogic(false), |
60 |
|
d_cardinalityConstraints(false), |
61 |
|
d_higherOrder(false), |
62 |
11042 |
d_locked(false) |
63 |
|
{ |
64 |
11042 |
setLogicString(logicString); |
65 |
11038 |
lock(); |
66 |
11038 |
} |
67 |
|
|
68 |
12303 |
LogicInfo::LogicInfo(const char* logicString) |
69 |
|
: d_logicString(""), |
70 |
|
d_theories(THEORY_LAST, false), |
71 |
|
d_sharingTheories(0), |
72 |
|
d_integers(false), |
73 |
|
d_reals(false), |
74 |
|
d_transcendentals(false), |
75 |
|
d_linear(false), |
76 |
|
d_differenceLogic(false), |
77 |
|
d_cardinalityConstraints(false), |
78 |
|
d_higherOrder(false), |
79 |
12303 |
d_locked(false) |
80 |
|
{ |
81 |
12303 |
setLogicString(logicString); |
82 |
12303 |
lock(); |
83 |
12303 |
} |
84 |
|
|
85 |
|
/** Is sharing enabled for this logic? */ |
86 |
66641502 |
bool LogicInfo::isSharingEnabled() const { |
87 |
66641502 |
PrettyCheckArgument(d_locked, *this, |
88 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
89 |
66641502 |
return d_sharingTheories > 1; |
90 |
|
} |
91 |
|
|
92 |
|
|
93 |
|
/** Is the given theory module active in this logic? */ |
94 |
82143644 |
bool LogicInfo::isTheoryEnabled(theory::TheoryId theory) const { |
95 |
82143644 |
PrettyCheckArgument(d_locked, *this, |
96 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
97 |
82143628 |
return d_theories[theory]; |
98 |
|
} |
99 |
|
|
100 |
|
/** Is this a quantified logic? */ |
101 |
222300 |
bool LogicInfo::isQuantified() const { |
102 |
222300 |
PrettyCheckArgument(d_locked, *this, |
103 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
104 |
222298 |
return isTheoryEnabled(theory::THEORY_QUANTIFIERS); |
105 |
|
} |
106 |
|
|
107 |
|
/** Is this a higher-order logic? */ |
108 |
2953941 |
bool LogicInfo::isHigherOrder() const |
109 |
|
{ |
110 |
2953941 |
PrettyCheckArgument(d_locked, |
111 |
|
*this, |
112 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
113 |
2953941 |
return d_higherOrder; |
114 |
|
} |
115 |
|
|
116 |
31484 |
bool LogicInfo::hasEverything() const |
117 |
|
{ |
118 |
31484 |
PrettyCheckArgument(d_locked, |
119 |
|
*this, |
120 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
121 |
62968 |
LogicInfo everything; |
122 |
31484 |
everything.enableEverything(isHigherOrder()); |
123 |
31484 |
everything.lock(); |
124 |
62968 |
return (*this == everything); |
125 |
|
} |
126 |
|
|
127 |
|
/** Is this the all-exclusive logic? (Here, that means propositional logic) */ |
128 |
52 |
bool LogicInfo::hasNothing() const { |
129 |
52 |
PrettyCheckArgument(d_locked, *this, |
130 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
131 |
104 |
LogicInfo nothing(""); |
132 |
52 |
nothing.lock(); |
133 |
104 |
return *this == nothing; |
134 |
|
} |
135 |
|
|
136 |
94165 |
bool LogicInfo::isPure(theory::TheoryId theory) const { |
137 |
94165 |
PrettyCheckArgument(d_locked, *this, |
138 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
139 |
|
// the third and fourth conjucts are really just to rule out the misleading |
140 |
|
// case where you ask isPure(THEORY_BOOL) and get true even in e.g. QF_LIA |
141 |
179189 |
return isTheoryEnabled(theory) && !isSharingEnabled() && |
142 |
126686 |
( !isTrueTheory(theory) || d_sharingTheories == 1 ) && |
143 |
104809 |
( isTrueTheory(theory) || d_sharingTheories == 0 ); |
144 |
|
} |
145 |
|
|
146 |
16644 |
bool LogicInfo::areIntegersUsed() const { |
147 |
16644 |
PrettyCheckArgument(d_locked, *this, |
148 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
149 |
16642 |
PrettyCheckArgument( |
150 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
151 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether integers are used"); |
152 |
16638 |
return d_integers; |
153 |
|
} |
154 |
|
|
155 |
8640 |
bool LogicInfo::areRealsUsed() const { |
156 |
8640 |
PrettyCheckArgument(d_locked, *this, |
157 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
158 |
8638 |
PrettyCheckArgument( |
159 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
160 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether reals are used"); |
161 |
8634 |
return d_reals; |
162 |
|
} |
163 |
|
|
164 |
12733 |
bool LogicInfo::areTranscendentalsUsed() const |
165 |
|
{ |
166 |
12733 |
PrettyCheckArgument(d_locked, |
167 |
|
*this, |
168 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
169 |
12733 |
PrettyCheckArgument(isTheoryEnabled(theory::THEORY_ARITH), |
170 |
|
*this, |
171 |
|
"Arithmetic not used in this LogicInfo; cannot ask " |
172 |
|
"whether transcendentals are used"); |
173 |
12729 |
return d_transcendentals; |
174 |
|
} |
175 |
|
|
176 |
190105 |
bool LogicInfo::isLinear() const { |
177 |
190105 |
PrettyCheckArgument(d_locked, *this, |
178 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
179 |
190103 |
PrettyCheckArgument( |
180 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
181 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether it's linear"); |
182 |
190099 |
return d_linear || d_differenceLogic; |
183 |
|
} |
184 |
|
|
185 |
8275 |
bool LogicInfo::isDifferenceLogic() const { |
186 |
8275 |
PrettyCheckArgument(d_locked, *this, |
187 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
188 |
8275 |
PrettyCheckArgument( |
189 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
190 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether it's difference logic"); |
191 |
8271 |
return d_differenceLogic; |
192 |
|
} |
193 |
|
|
194 |
12788 |
bool LogicInfo::hasCardinalityConstraints() const { |
195 |
12788 |
PrettyCheckArgument(d_locked, *this, |
196 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
197 |
12788 |
return d_cardinalityConstraints; |
198 |
|
} |
199 |
|
|
200 |
|
|
201 |
49887 |
bool LogicInfo::operator==(const LogicInfo& other) const { |
202 |
49887 |
PrettyCheckArgument(isLocked() && other.isLocked(), *this, |
203 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
204 |
393478 |
for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) { |
205 |
378146 |
if(d_theories[id] != other.d_theories[id]) { |
206 |
34555 |
return false; |
207 |
|
} |
208 |
|
} |
209 |
|
|
210 |
15332 |
PrettyCheckArgument(d_sharingTheories == other.d_sharingTheories, *this, |
211 |
|
"LogicInfo internal inconsistency"); |
212 |
30620 |
if (d_cardinalityConstraints != other.d_cardinalityConstraints || |
213 |
15288 |
d_higherOrder != other.d_higherOrder ) |
214 |
|
{ |
215 |
68 |
return false; |
216 |
|
} |
217 |
15264 |
if(isTheoryEnabled(theory::THEORY_ARITH)) { |
218 |
29825 |
return d_integers == other.d_integers && d_reals == other.d_reals |
219 |
14531 |
&& d_transcendentals == other.d_transcendentals |
220 |
14369 |
&& d_linear == other.d_linear |
221 |
29345 |
&& d_differenceLogic == other.d_differenceLogic; |
222 |
|
} |
223 |
66 |
return true; |
224 |
|
} |
225 |
|
|
226 |
7044 |
bool LogicInfo::operator<=(const LogicInfo& other) const { |
227 |
7044 |
PrettyCheckArgument(isLocked() && other.isLocked(), *this, |
228 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
229 |
63594 |
for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) { |
230 |
60672 |
if(d_theories[id] && !other.d_theories[id]) { |
231 |
4122 |
return false; |
232 |
|
} |
233 |
|
} |
234 |
2922 |
PrettyCheckArgument(d_sharingTheories <= other.d_sharingTheories, *this, |
235 |
|
"LogicInfo internal inconsistency"); |
236 |
5868 |
bool res = (!d_cardinalityConstraints || other.d_cardinalityConstraints) |
237 |
5820 |
&& (!d_higherOrder || other.d_higherOrder); |
238 |
2922 |
if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) { |
239 |
4128 |
return (!d_integers || other.d_integers) && (!d_reals || other.d_reals) |
240 |
1722 |
&& (!d_transcendentals || other.d_transcendentals) |
241 |
1704 |
&& (d_linear || !other.d_linear) |
242 |
4038 |
&& (d_differenceLogic || !other.d_differenceLogic) && res; |
243 |
|
} else { |
244 |
288 |
return res; |
245 |
|
} |
246 |
|
} |
247 |
|
|
248 |
6510 |
bool LogicInfo::operator>=(const LogicInfo& other) const { |
249 |
6510 |
PrettyCheckArgument(isLocked() && other.isLocked(), *this, |
250 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
251 |
59092 |
for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) { |
252 |
56338 |
if(!d_theories[id] && other.d_theories[id]) { |
253 |
3756 |
return false; |
254 |
|
} |
255 |
|
} |
256 |
2754 |
PrettyCheckArgument(d_sharingTheories >= other.d_sharingTheories, *this, |
257 |
|
"LogicInfo internal inconsistency"); |
258 |
8232 |
bool res = (d_cardinalityConstraints || !other.d_cardinalityConstraints) |
259 |
5490 |
&& (d_higherOrder || !other.d_higherOrder); |
260 |
2754 |
if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) { |
261 |
3186 |
return (d_integers || !other.d_integers) && (d_reals || !other.d_reals) |
262 |
1594 |
&& (d_transcendentals || !other.d_transcendentals) |
263 |
1582 |
&& (!d_linear || other.d_linear) |
264 |
3800 |
&& (!d_differenceLogic || other.d_differenceLogic) && res; |
265 |
|
} else { |
266 |
264 |
return res; |
267 |
|
} |
268 |
|
} |
269 |
|
|
270 |
9871 |
std::string LogicInfo::getLogicString() const { |
271 |
9871 |
PrettyCheckArgument( |
272 |
|
d_locked, *this, |
273 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
274 |
9869 |
if(d_logicString == "") { |
275 |
5468 |
LogicInfo qf_all_supported; |
276 |
2734 |
qf_all_supported.disableQuantifiers(); |
277 |
2734 |
qf_all_supported.lock(); |
278 |
5468 |
stringstream ss; |
279 |
2734 |
if (isHigherOrder()) |
280 |
|
{ |
281 |
24 |
ss << "HO_"; |
282 |
|
} |
283 |
2734 |
if (!isQuantified()) |
284 |
|
{ |
285 |
107 |
ss << "QF_"; |
286 |
|
} |
287 |
2734 |
if (*this == qf_all_supported || hasEverything()) |
288 |
|
{ |
289 |
1777 |
ss << "ALL"; |
290 |
|
} |
291 |
|
else |
292 |
|
{ |
293 |
957 |
size_t seen = 0; // make sure we support all the active theories |
294 |
957 |
if (d_theories[THEORY_SEP]) |
295 |
|
{ |
296 |
8 |
ss << "SEP_"; |
297 |
8 |
++seen; |
298 |
|
} |
299 |
957 |
if(d_theories[THEORY_ARRAYS]) { |
300 |
25 |
ss << (d_sharingTheories == 1 ? "AX" : "A"); |
301 |
25 |
++seen; |
302 |
|
} |
303 |
957 |
if(d_theories[THEORY_UF]) { |
304 |
558 |
ss << "UF"; |
305 |
558 |
++seen; |
306 |
|
} |
307 |
957 |
if( d_cardinalityConstraints ){ |
308 |
|
ss << "C"; |
309 |
|
} |
310 |
957 |
if(d_theories[THEORY_BV]) { |
311 |
221 |
ss << "BV"; |
312 |
221 |
++seen; |
313 |
|
} |
314 |
957 |
if(d_theories[THEORY_FP]) { |
315 |
10 |
ss << "FP"; |
316 |
10 |
++seen; |
317 |
|
} |
318 |
957 |
if(d_theories[THEORY_DATATYPES]) { |
319 |
524 |
ss << "DT"; |
320 |
524 |
++seen; |
321 |
|
} |
322 |
957 |
if(d_theories[THEORY_STRINGS]) { |
323 |
365 |
ss << "S"; |
324 |
365 |
++seen; |
325 |
|
} |
326 |
957 |
if(d_theories[THEORY_ARITH]) { |
327 |
806 |
if(isDifferenceLogic()) { |
328 |
|
ss << (areIntegersUsed() ? "I" : ""); |
329 |
|
ss << (areRealsUsed() ? "R" : ""); |
330 |
|
ss << "DL"; |
331 |
|
} else { |
332 |
806 |
ss << (isLinear() ? "L" : "N"); |
333 |
806 |
ss << (areIntegersUsed() ? "I" : ""); |
334 |
806 |
ss << (areRealsUsed() ? "R" : ""); |
335 |
806 |
ss << "A"; |
336 |
806 |
ss << (areTranscendentalsUsed() ? "T" : ""); |
337 |
|
} |
338 |
806 |
++seen; |
339 |
|
} |
340 |
957 |
if(d_theories[THEORY_SETS]) { |
341 |
2 |
ss << "FS"; |
342 |
2 |
++seen; |
343 |
|
} |
344 |
957 |
if (d_theories[THEORY_BAGS]) |
345 |
|
{ |
346 |
2 |
ss << "FB"; |
347 |
2 |
++seen; |
348 |
|
} |
349 |
957 |
if(seen != d_sharingTheories) { |
350 |
|
Unhandled() |
351 |
|
<< "can't extract a logic string from LogicInfo; at least one " |
352 |
|
"active theory is unknown to LogicInfo::getLogicString() !"; |
353 |
|
} |
354 |
|
|
355 |
957 |
if(seen == 0) { |
356 |
|
ss << "SAT"; |
357 |
|
} |
358 |
|
} |
359 |
2734 |
d_logicString = ss.str(); |
360 |
|
} |
361 |
9869 |
return d_logicString; |
362 |
|
} |
363 |
|
|
364 |
23343 |
void LogicInfo::setLogicString(std::string logicString) |
365 |
|
{ |
366 |
23343 |
PrettyCheckArgument(!d_locked, *this, |
367 |
|
"This LogicInfo is locked, and cannot be modified"); |
368 |
326802 |
for(TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) { |
369 |
303459 |
d_theories[id] = false;// ensure it's cleared |
370 |
|
} |
371 |
23343 |
d_sharingTheories = 0; |
372 |
|
|
373 |
|
// Below, ONLY use enableTheory()/disableTheory() rather than |
374 |
|
// accessing d_theories[] directly. This makes sure to set up |
375 |
|
// sharing properly. |
376 |
|
|
377 |
23343 |
enableTheory(THEORY_BUILTIN); |
378 |
23343 |
enableTheory(THEORY_BOOL); |
379 |
|
|
380 |
23343 |
const char* p = logicString.c_str(); |
381 |
23343 |
if (!strncmp(p, "HO_", 3)) |
382 |
|
{ |
383 |
275 |
enableHigherOrder(); |
384 |
275 |
p += 3; |
385 |
|
} |
386 |
23343 |
if(*p == '\0') { |
387 |
|
// propositional logic only; we're done. |
388 |
23289 |
} else if(!strcmp(p, "QF_SAT")) { |
389 |
|
// propositional logic only; we're done. |
390 |
20 |
p += 6; |
391 |
23269 |
} else if(!strcmp(p, "SAT")) { |
392 |
|
// quantified Boolean formulas only; we're done. |
393 |
30 |
enableQuantifiers(); |
394 |
30 |
p += 3; |
395 |
23239 |
} else if(!strcmp(p, "QF_ALL")) { |
396 |
|
// the "all theories included" logic, no quantifiers. |
397 |
353 |
enableEverything(d_higherOrder); |
398 |
353 |
disableQuantifiers(); |
399 |
353 |
arithNonLinear(); |
400 |
353 |
p += 6; |
401 |
22886 |
} else if(!strcmp(p, "ALL")) { |
402 |
|
// the "all theories included" logic, with quantifiers. |
403 |
3009 |
enableEverything(d_higherOrder); |
404 |
3009 |
enableQuantifiers(); |
405 |
3009 |
arithNonLinear(); |
406 |
3009 |
p += 3; |
407 |
|
} |
408 |
19877 |
else if (!strcmp(p, "HORN")) |
409 |
|
{ |
410 |
|
// the HORN logic |
411 |
|
enableEverything(d_higherOrder); |
412 |
|
enableQuantifiers(); |
413 |
|
arithNonLinear(); |
414 |
|
p += 4; |
415 |
|
} else { |
416 |
19877 |
if(!strncmp(p, "QF_", 3)) { |
417 |
17192 |
disableQuantifiers(); |
418 |
17192 |
p += 3; |
419 |
|
} else { |
420 |
2685 |
enableQuantifiers(); |
421 |
|
} |
422 |
19877 |
if (!strncmp(p, "SEP_", 4)) |
423 |
|
{ |
424 |
8 |
enableSeparationLogic(); |
425 |
8 |
p += 4; |
426 |
|
} |
427 |
19877 |
if(!strncmp(p, "AX", 2)) { |
428 |
50 |
enableTheory(THEORY_ARRAYS); |
429 |
50 |
p += 2; |
430 |
|
} else { |
431 |
19827 |
if(*p == 'A') { |
432 |
1998 |
enableTheory(THEORY_ARRAYS); |
433 |
1998 |
++p; |
434 |
|
} |
435 |
19827 |
if(!strncmp(p, "UF", 2)) { |
436 |
13938 |
enableTheory(THEORY_UF); |
437 |
13938 |
p += 2; |
438 |
|
} |
439 |
19827 |
if(!strncmp(p, "C", 1 )) { |
440 |
54 |
d_cardinalityConstraints = true; |
441 |
54 |
p += 1; |
442 |
|
} |
443 |
|
// allow BV or DT in either order |
444 |
19827 |
if(!strncmp(p, "BV", 2)) { |
445 |
2690 |
enableTheory(THEORY_BV); |
446 |
2690 |
p += 2; |
447 |
|
} |
448 |
19827 |
if(!strncmp(p, "FP", 2)) { |
449 |
118 |
enableTheory(THEORY_FP); |
450 |
118 |
p += 2; |
451 |
|
} |
452 |
19827 |
if(!strncmp(p, "DT", 2)) { |
453 |
126 |
enableTheory(THEORY_DATATYPES); |
454 |
126 |
p += 2; |
455 |
|
} |
456 |
19827 |
if(!d_theories[THEORY_BV] && !strncmp(p, "BV", 2)) { |
457 |
|
enableTheory(THEORY_BV); |
458 |
|
p += 2; |
459 |
|
} |
460 |
19827 |
if(*p == 'S') { |
461 |
870 |
enableTheory(THEORY_STRINGS); |
462 |
870 |
++p; |
463 |
|
} |
464 |
19827 |
if(!strncmp(p, "IDL", 3)) { |
465 |
227 |
enableIntegers(); |
466 |
227 |
disableReals(); |
467 |
227 |
arithOnlyDifference(); |
468 |
227 |
p += 3; |
469 |
19600 |
} else if(!strncmp(p, "RDL", 3)) { |
470 |
118 |
disableIntegers(); |
471 |
118 |
enableReals(); |
472 |
118 |
arithOnlyDifference(); |
473 |
118 |
p += 3; |
474 |
19482 |
} else if(!strncmp(p, "IRDL", 4)) { |
475 |
|
// "IRDL" ?! --not very useful, but getLogicString() can produce |
476 |
|
// that string, so we really had better be able to read it back in. |
477 |
|
enableIntegers(); |
478 |
|
enableReals(); |
479 |
|
arithOnlyDifference(); |
480 |
|
p += 4; |
481 |
19482 |
} else if(!strncmp(p, "LIA", 3)) { |
482 |
2918 |
enableIntegers(); |
483 |
2918 |
disableReals(); |
484 |
2918 |
arithOnlyLinear(); |
485 |
2918 |
p += 3; |
486 |
16564 |
} else if(!strncmp(p, "LRA", 3)) { |
487 |
980 |
disableIntegers(); |
488 |
980 |
enableReals(); |
489 |
980 |
arithOnlyLinear(); |
490 |
980 |
p += 3; |
491 |
15584 |
} else if(!strncmp(p, "LIRA", 4)) { |
492 |
416 |
enableIntegers(); |
493 |
416 |
enableReals(); |
494 |
416 |
arithOnlyLinear(); |
495 |
416 |
p += 4; |
496 |
15168 |
} else if(!strncmp(p, "NIA", 3)) { |
497 |
748 |
enableIntegers(); |
498 |
748 |
disableReals(); |
499 |
748 |
arithNonLinear(); |
500 |
748 |
p += 3; |
501 |
14420 |
} else if(!strncmp(p, "NRA", 3)) { |
502 |
10507 |
disableIntegers(); |
503 |
10507 |
enableReals(); |
504 |
10507 |
arithNonLinear(); |
505 |
10507 |
p += 3; |
506 |
10507 |
if (*p == 'T') |
507 |
|
{ |
508 |
196 |
arithTranscendentals(); |
509 |
196 |
p += 1; |
510 |
|
} |
511 |
3913 |
} else if(!strncmp(p, "NIRA", 4)) { |
512 |
290 |
enableIntegers(); |
513 |
290 |
enableReals(); |
514 |
290 |
arithNonLinear(); |
515 |
290 |
p += 4; |
516 |
290 |
if (*p == 'T') |
517 |
|
{ |
518 |
6 |
arithTranscendentals(); |
519 |
6 |
p += 1; |
520 |
|
} |
521 |
|
} |
522 |
19827 |
if(!strncmp(p, "FS", 2)) { |
523 |
158 |
enableTheory(THEORY_SETS); |
524 |
158 |
p += 2; |
525 |
|
} |
526 |
|
} |
527 |
|
} |
528 |
|
|
529 |
23343 |
if (d_theories[THEORY_FP]) |
530 |
|
{ |
531 |
|
// THEORY_BV is needed for bit-blasting. |
532 |
|
// We have to set this here rather than in expandDefinition as it |
533 |
|
// is possible to create variables without any theory specific |
534 |
|
// operations, so expandDefinition won't be called. |
535 |
3480 |
enableTheory(THEORY_BV); |
536 |
|
} |
537 |
|
|
538 |
23343 |
if(*p != '\0') { |
539 |
4 |
stringstream err; |
540 |
2 |
err << "LogicInfo::setLogicString(): "; |
541 |
2 |
if(p == logicString) { |
542 |
|
err << "cannot parse logic string: " << logicString; |
543 |
|
} else { |
544 |
2 |
err << "junk (\"" << p << "\") at end of logic string: " << logicString; |
545 |
|
} |
546 |
2 |
IllegalArgument(logicString, err.str().c_str()); |
547 |
|
} |
548 |
|
|
549 |
|
// ensure a getLogic() returns the same thing as was set |
550 |
23341 |
d_logicString = logicString; |
551 |
23341 |
} |
552 |
|
|
553 |
34848 |
void LogicInfo::enableEverything(bool enableHigherOrder) |
554 |
|
{ |
555 |
34848 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
556 |
34848 |
*this = LogicInfo(); |
557 |
34848 |
this->d_higherOrder = enableHigherOrder; |
558 |
34848 |
} |
559 |
|
|
560 |
2 |
void LogicInfo::disableEverything() { |
561 |
2 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
562 |
2 |
*this = LogicInfo(""); |
563 |
2 |
} |
564 |
|
|
565 |
1339108 |
void LogicInfo::enableTheory(theory::TheoryId theory) { |
566 |
1339108 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
567 |
1339108 |
if(!d_theories[theory]) { |
568 |
1329691 |
if(isTrueTheory(theory)) { |
569 |
993144 |
++d_sharingTheories; |
570 |
|
} |
571 |
1329691 |
d_logicString = ""; |
572 |
1329691 |
d_theories[theory] = true; |
573 |
|
} |
574 |
1339108 |
} |
575 |
|
|
576 |
31975 |
void LogicInfo::disableTheory(theory::TheoryId theory) { |
577 |
31975 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
578 |
31965 |
if(d_theories[theory]) { |
579 |
3162 |
if(isTrueTheory(theory)) { |
580 |
73 |
Assert(d_sharingTheories > 0); |
581 |
73 |
--d_sharingTheories; |
582 |
|
} |
583 |
3162 |
if(theory == THEORY_BUILTIN || |
584 |
|
theory == THEORY_BOOL) { |
585 |
|
return; |
586 |
|
} |
587 |
3162 |
d_logicString = ""; |
588 |
3162 |
d_theories[theory] = false; |
589 |
|
} |
590 |
|
} |
591 |
|
|
592 |
634 |
void LogicInfo::enableSygus() |
593 |
|
{ |
594 |
634 |
enableQuantifiers(); |
595 |
634 |
enableTheory(THEORY_UF); |
596 |
634 |
enableTheory(THEORY_DATATYPES); |
597 |
634 |
enableIntegers(); |
598 |
634 |
} |
599 |
|
|
600 |
8 |
void LogicInfo::enableSeparationLogic() |
601 |
|
{ |
602 |
8 |
enableTheory(THEORY_SEP); |
603 |
8 |
enableTheory(THEORY_UF); |
604 |
8 |
enableTheory(THEORY_SETS); |
605 |
8 |
} |
606 |
|
|
607 |
5366 |
void LogicInfo::enableIntegers() { |
608 |
5366 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
609 |
5364 |
d_logicString = ""; |
610 |
5364 |
enableTheory(THEORY_ARITH); |
611 |
5364 |
d_integers = true; |
612 |
5364 |
} |
613 |
|
|
614 |
11609 |
void LogicInfo::disableIntegers() { |
615 |
11609 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
616 |
11607 |
d_logicString = ""; |
617 |
11607 |
d_integers = false; |
618 |
11607 |
if(!d_reals) { |
619 |
11605 |
disableTheory(THEORY_ARITH); |
620 |
|
} |
621 |
11607 |
} |
622 |
|
|
623 |
12311 |
void LogicInfo::enableReals() { |
624 |
12311 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
625 |
12311 |
d_logicString = ""; |
626 |
12311 |
enableTheory(THEORY_ARITH); |
627 |
12311 |
d_reals = true; |
628 |
12311 |
} |
629 |
|
|
630 |
3897 |
void LogicInfo::disableReals() { |
631 |
3897 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
632 |
3895 |
d_logicString = ""; |
633 |
3895 |
d_reals = false; |
634 |
3895 |
if(!d_integers) { |
635 |
|
disableTheory(THEORY_ARITH); |
636 |
|
} |
637 |
3895 |
} |
638 |
|
|
639 |
202 |
void LogicInfo::arithTranscendentals() |
640 |
|
{ |
641 |
202 |
PrettyCheckArgument( |
642 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
643 |
202 |
d_logicString = ""; |
644 |
202 |
d_transcendentals = true; |
645 |
202 |
if (!d_reals) |
646 |
|
{ |
647 |
|
enableReals(); |
648 |
|
} |
649 |
202 |
if (d_linear) |
650 |
|
{ |
651 |
|
arithNonLinear(); |
652 |
|
} |
653 |
202 |
} |
654 |
|
|
655 |
345 |
void LogicInfo::arithOnlyDifference() { |
656 |
345 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
657 |
345 |
d_logicString = ""; |
658 |
345 |
d_linear = true; |
659 |
345 |
d_differenceLogic = true; |
660 |
345 |
d_transcendentals = false; |
661 |
345 |
} |
662 |
|
|
663 |
4447 |
void LogicInfo::arithOnlyLinear() { |
664 |
4447 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
665 |
4445 |
d_logicString = ""; |
666 |
4445 |
d_linear = true; |
667 |
4445 |
d_differenceLogic = false; |
668 |
4445 |
d_transcendentals = false; |
669 |
4445 |
} |
670 |
|
|
671 |
15080 |
void LogicInfo::arithNonLinear() { |
672 |
15080 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
673 |
15080 |
d_logicString = ""; |
674 |
15080 |
d_linear = false; |
675 |
15080 |
d_differenceLogic = false; |
676 |
15080 |
} |
677 |
|
|
678 |
|
void LogicInfo::enableCardinalityConstraints() |
679 |
|
{ |
680 |
|
PrettyCheckArgument( |
681 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
682 |
|
d_logicString = ""; |
683 |
|
d_cardinalityConstraints = true; |
684 |
|
} |
685 |
|
|
686 |
|
void LogicInfo::disableCardinalityConstraints() |
687 |
|
{ |
688 |
|
PrettyCheckArgument( |
689 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
690 |
|
d_logicString = ""; |
691 |
|
d_cardinalityConstraints = false; |
692 |
|
} |
693 |
|
|
694 |
277 |
void LogicInfo::enableHigherOrder() |
695 |
|
{ |
696 |
277 |
PrettyCheckArgument( |
697 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
698 |
277 |
d_logicString = ""; |
699 |
277 |
d_higherOrder = true; |
700 |
277 |
} |
701 |
|
|
702 |
|
void LogicInfo::disableHigherOrder() |
703 |
|
{ |
704 |
|
PrettyCheckArgument( |
705 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
706 |
|
d_logicString = ""; |
707 |
|
d_higherOrder = false; |
708 |
|
} |
709 |
|
|
710 |
6992 |
LogicInfo LogicInfo::getUnlockedCopy() const { |
711 |
6992 |
if(d_locked) { |
712 |
13984 |
LogicInfo info = *this; |
713 |
6992 |
info.d_locked = false; |
714 |
6992 |
return info; |
715 |
|
} else { |
716 |
|
return *this; |
717 |
|
} |
718 |
|
} |
719 |
|
|
720 |
2352 |
std::ostream& operator<<(std::ostream& out, const LogicInfo& logic) { |
721 |
2352 |
return out << logic.getLogicString(); |
722 |
|
} |
723 |
|
|
724 |
29340 |
} // namespace cvc5 |