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 |
147984 |
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 |
147984 |
d_locked(false) |
44 |
|
{ |
45 |
2071776 |
for (TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) |
46 |
|
{ |
47 |
1923792 |
enableTheory(id); |
48 |
|
} |
49 |
147984 |
} |
50 |
|
|
51 |
13305 |
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 |
13307 |
d_locked(false) |
63 |
|
{ |
64 |
13307 |
setLogicString(logicString); |
65 |
13303 |
lock(); |
66 |
13303 |
} |
67 |
|
|
68 |
17721 |
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 |
17721 |
d_locked(false) |
80 |
|
{ |
81 |
17721 |
setLogicString(logicString); |
82 |
17721 |
lock(); |
83 |
17721 |
} |
84 |
|
|
85 |
|
/** Is sharing enabled for this logic? */ |
86 |
87553663 |
bool LogicInfo::isSharingEnabled() const { |
87 |
87553663 |
PrettyCheckArgument(d_locked, *this, |
88 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
89 |
87553663 |
return d_sharingTheories > 1; |
90 |
|
} |
91 |
|
|
92 |
|
|
93 |
|
/** Is the given theory module active in this logic? */ |
94 |
105271092 |
bool LogicInfo::isTheoryEnabled(theory::TheoryId theory) const { |
95 |
105271092 |
PrettyCheckArgument(d_locked, *this, |
96 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
97 |
105271076 |
return d_theories[theory]; |
98 |
|
} |
99 |
|
|
100 |
|
/** Is this a quantified logic? */ |
101 |
384272 |
bool LogicInfo::isQuantified() const { |
102 |
384272 |
PrettyCheckArgument(d_locked, *this, |
103 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
104 |
384270 |
return isTheoryEnabled(theory::THEORY_QUANTIFIERS); |
105 |
|
} |
106 |
|
|
107 |
|
/** Is this a higher-order logic? */ |
108 |
9542632 |
bool LogicInfo::isHigherOrder() const |
109 |
|
{ |
110 |
9542632 |
PrettyCheckArgument(d_locked, |
111 |
|
*this, |
112 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
113 |
9542632 |
return d_higherOrder; |
114 |
|
} |
115 |
|
|
116 |
47792 |
bool LogicInfo::hasEverything() const |
117 |
|
{ |
118 |
47792 |
PrettyCheckArgument(d_locked, |
119 |
|
*this, |
120 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
121 |
95584 |
LogicInfo everything; |
122 |
47792 |
everything.enableEverything(isHigherOrder()); |
123 |
47792 |
everything.lock(); |
124 |
95584 |
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 |
169368 |
bool LogicInfo::isPure(theory::TheoryId theory) const { |
137 |
169368 |
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 |
324726 |
return isTheoryEnabled(theory) && !isSharingEnabled() && |
142 |
201927 |
( !isTrueTheory(theory) || d_sharingTheories == 1 ) && |
143 |
179435 |
( isTrueTheory(theory) || d_sharingTheories == 0 ); |
144 |
|
} |
145 |
|
|
146 |
34579 |
bool LogicInfo::areIntegersUsed() const { |
147 |
34579 |
PrettyCheckArgument(d_locked, *this, |
148 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
149 |
34577 |
PrettyCheckArgument( |
150 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
151 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether integers are used"); |
152 |
34573 |
return d_integers; |
153 |
|
} |
154 |
|
|
155 |
23735 |
bool LogicInfo::areRealsUsed() const { |
156 |
23735 |
PrettyCheckArgument(d_locked, *this, |
157 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
158 |
23733 |
PrettyCheckArgument( |
159 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
160 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether reals are used"); |
161 |
23729 |
return d_reals; |
162 |
|
} |
163 |
|
|
164 |
20204 |
bool LogicInfo::areTranscendentalsUsed() const |
165 |
|
{ |
166 |
20204 |
PrettyCheckArgument(d_locked, |
167 |
|
*this, |
168 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
169 |
20204 |
PrettyCheckArgument(isTheoryEnabled(theory::THEORY_ARITH), |
170 |
|
*this, |
171 |
|
"Arithmetic not used in this LogicInfo; cannot ask " |
172 |
|
"whether transcendentals are used"); |
173 |
20200 |
return d_transcendentals; |
174 |
|
} |
175 |
|
|
176 |
222050 |
bool LogicInfo::isLinear() const { |
177 |
222050 |
PrettyCheckArgument(d_locked, *this, |
178 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
179 |
222048 |
PrettyCheckArgument( |
180 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
181 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether it's linear"); |
182 |
222044 |
return d_linear || d_differenceLogic; |
183 |
|
} |
184 |
|
|
185 |
13547 |
bool LogicInfo::isDifferenceLogic() const { |
186 |
13547 |
PrettyCheckArgument(d_locked, *this, |
187 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
188 |
13547 |
PrettyCheckArgument( |
189 |
|
isTheoryEnabled(theory::THEORY_ARITH), *this, |
190 |
|
"Arithmetic not used in this LogicInfo; cannot ask whether it's difference logic"); |
191 |
13543 |
return d_differenceLogic; |
192 |
|
} |
193 |
|
|
194 |
15343 |
bool LogicInfo::hasCardinalityConstraints() const { |
195 |
15343 |
PrettyCheckArgument(d_locked, *this, |
196 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
197 |
15343 |
return d_cardinalityConstraints; |
198 |
|
} |
199 |
|
|
200 |
|
|
201 |
72111 |
bool LogicInfo::operator==(const LogicInfo& other) const { |
202 |
72111 |
PrettyCheckArgument(isLocked() && other.isLocked(), *this, |
203 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
204 |
620652 |
for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) { |
205 |
592607 |
if(d_theories[id] != other.d_theories[id]) { |
206 |
44066 |
return false; |
207 |
|
} |
208 |
|
} |
209 |
|
|
210 |
28045 |
PrettyCheckArgument(d_sharingTheories == other.d_sharingTheories, *this, |
211 |
|
"LogicInfo internal inconsistency"); |
212 |
56046 |
if (d_cardinalityConstraints != other.d_cardinalityConstraints || |
213 |
28001 |
d_higherOrder != other.d_higherOrder ) |
214 |
|
{ |
215 |
72 |
return false; |
216 |
|
} |
217 |
27973 |
if(isTheoryEnabled(theory::THEORY_ARITH)) { |
218 |
55242 |
return d_integers == other.d_integers && d_reals == other.d_reals |
219 |
27239 |
&& d_transcendentals == other.d_transcendentals |
220 |
27074 |
&& d_linear == other.d_linear |
221 |
54759 |
&& 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 |
15381 |
std::string LogicInfo::getLogicString() const { |
271 |
15381 |
PrettyCheckArgument( |
272 |
|
d_locked, *this, |
273 |
|
"This LogicInfo isn't locked yet, and cannot be queried"); |
274 |
15379 |
if(d_logicString == "") { |
275 |
6464 |
LogicInfo qf_all_supported; |
276 |
3232 |
qf_all_supported.disableQuantifiers(); |
277 |
3232 |
qf_all_supported.lock(); |
278 |
6464 |
stringstream ss; |
279 |
3232 |
if (isHigherOrder()) |
280 |
|
{ |
281 |
38 |
ss << "HO_"; |
282 |
|
} |
283 |
3232 |
if (!isQuantified()) |
284 |
|
{ |
285 |
435 |
ss << "QF_"; |
286 |
|
} |
287 |
3232 |
if (*this == qf_all_supported || hasEverything()) |
288 |
|
{ |
289 |
1464 |
ss << "ALL"; |
290 |
|
} |
291 |
|
else |
292 |
|
{ |
293 |
1768 |
size_t seen = 0; // make sure we support all the active theories |
294 |
1768 |
if (d_theories[THEORY_SEP]) |
295 |
|
{ |
296 |
8 |
ss << "SEP_"; |
297 |
8 |
++seen; |
298 |
|
} |
299 |
1768 |
if(d_theories[THEORY_ARRAYS]) { |
300 |
83 |
ss << (d_sharingTheories == 1 ? "AX" : "A"); |
301 |
83 |
++seen; |
302 |
|
} |
303 |
1768 |
if(d_theories[THEORY_UF]) { |
304 |
1719 |
ss << "UF"; |
305 |
1719 |
++seen; |
306 |
|
} |
307 |
1768 |
if( d_cardinalityConstraints ){ |
308 |
|
ss << "C"; |
309 |
|
} |
310 |
1768 |
if(d_theories[THEORY_BV]) { |
311 |
346 |
ss << "BV"; |
312 |
346 |
++seen; |
313 |
|
} |
314 |
1768 |
if(d_theories[THEORY_FP]) { |
315 |
54 |
ss << "FP"; |
316 |
54 |
++seen; |
317 |
|
} |
318 |
1768 |
if(d_theories[THEORY_DATATYPES]) { |
319 |
914 |
ss << "DT"; |
320 |
914 |
++seen; |
321 |
|
} |
322 |
1768 |
if(d_theories[THEORY_STRINGS]) { |
323 |
456 |
ss << "S"; |
324 |
456 |
++seen; |
325 |
|
} |
326 |
1768 |
if(d_theories[THEORY_ARITH]) { |
327 |
1650 |
if(isDifferenceLogic()) { |
328 |
|
ss << (areIntegersUsed() ? "I" : ""); |
329 |
|
ss << (areRealsUsed() ? "R" : ""); |
330 |
|
ss << "DL"; |
331 |
|
} else { |
332 |
1650 |
ss << (isLinear() ? "L" : "N"); |
333 |
1650 |
ss << (areIntegersUsed() ? "I" : ""); |
334 |
1650 |
ss << (areRealsUsed() ? "R" : ""); |
335 |
1650 |
ss << "A"; |
336 |
1650 |
ss << (areTranscendentalsUsed() ? "T" : ""); |
337 |
|
} |
338 |
1650 |
++seen; |
339 |
|
} |
340 |
1768 |
if(d_theories[THEORY_SETS]) { |
341 |
12 |
ss << "FS"; |
342 |
12 |
++seen; |
343 |
|
} |
344 |
1768 |
if (d_theories[THEORY_BAGS]) |
345 |
|
{ |
346 |
2 |
ss << "FB"; |
347 |
2 |
++seen; |
348 |
|
} |
349 |
1768 |
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 |
1768 |
if(seen == 0) { |
356 |
|
ss << "SAT"; |
357 |
|
} |
358 |
|
} |
359 |
3232 |
d_logicString = ss.str(); |
360 |
|
} |
361 |
15379 |
return d_logicString; |
362 |
|
} |
363 |
|
|
364 |
31034 |
void LogicInfo::setLogicString(std::string logicString) |
365 |
|
{ |
366 |
31034 |
PrettyCheckArgument(!d_locked, *this, |
367 |
|
"This LogicInfo is locked, and cannot be modified"); |
368 |
434476 |
for(TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) { |
369 |
403442 |
d_theories[id] = false;// ensure it's cleared |
370 |
|
} |
371 |
31034 |
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 |
31034 |
enableTheory(THEORY_BUILTIN); |
378 |
31034 |
enableTheory(THEORY_BOOL); |
379 |
|
|
380 |
31034 |
const char* p = logicString.c_str(); |
381 |
31034 |
if (!strncmp(p, "HO_", 3)) |
382 |
|
{ |
383 |
340 |
enableHigherOrder(); |
384 |
340 |
p += 3; |
385 |
|
} |
386 |
31034 |
if(*p == '\0') { |
387 |
|
// propositional logic only; we're done. |
388 |
30980 |
} else if(!strcmp(p, "QF_SAT")) { |
389 |
|
// propositional logic only; we're done. |
390 |
20 |
p += 6; |
391 |
30960 |
} else if(!strcmp(p, "SAT")) { |
392 |
|
// quantified Boolean formulas only; we're done. |
393 |
32 |
enableQuantifiers(); |
394 |
32 |
p += 3; |
395 |
30928 |
} else if(!strcmp(p, "QF_ALL")) { |
396 |
|
// the "all theories included" logic, no quantifiers. |
397 |
355 |
enableEverything(d_higherOrder); |
398 |
355 |
disableQuantifiers(); |
399 |
355 |
arithNonLinear(); |
400 |
355 |
p += 6; |
401 |
30573 |
} else if(!strcmp(p, "ALL")) { |
402 |
|
// the "all theories included" logic, with quantifiers. |
403 |
4794 |
enableEverything(d_higherOrder); |
404 |
4794 |
enableQuantifiers(); |
405 |
4794 |
arithNonLinear(); |
406 |
4794 |
p += 3; |
407 |
|
} |
408 |
25779 |
else if (!strcmp(p, "HORN")) |
409 |
|
{ |
410 |
|
// the HORN logic |
411 |
|
enableEverything(d_higherOrder); |
412 |
|
enableQuantifiers(); |
413 |
|
arithNonLinear(); |
414 |
|
p += 4; |
415 |
|
} else { |
416 |
25779 |
if(!strncmp(p, "QF_", 3)) { |
417 |
22737 |
disableQuantifiers(); |
418 |
22737 |
p += 3; |
419 |
|
} else { |
420 |
3042 |
enableQuantifiers(); |
421 |
|
} |
422 |
25779 |
if (!strncmp(p, "SEP_", 4)) |
423 |
|
{ |
424 |
8 |
enableSeparationLogic(); |
425 |
8 |
p += 4; |
426 |
|
} |
427 |
25779 |
if(!strncmp(p, "AX", 2)) { |
428 |
50 |
enableTheory(THEORY_ARRAYS); |
429 |
50 |
p += 2; |
430 |
|
} else { |
431 |
25729 |
if(*p == 'A') { |
432 |
2044 |
enableTheory(THEORY_ARRAYS); |
433 |
2044 |
++p; |
434 |
|
} |
435 |
25729 |
if(!strncmp(p, "UF", 2)) { |
436 |
19435 |
enableTheory(THEORY_UF); |
437 |
19435 |
p += 2; |
438 |
|
} |
439 |
25729 |
if(!strncmp(p, "C", 1 )) { |
440 |
58 |
d_cardinalityConstraints = true; |
441 |
58 |
p += 1; |
442 |
|
} |
443 |
|
// allow BV or DT in either order |
444 |
25729 |
if(!strncmp(p, "BV", 2)) { |
445 |
2772 |
enableTheory(THEORY_BV); |
446 |
2772 |
p += 2; |
447 |
|
} |
448 |
25729 |
if(!strncmp(p, "FP", 2)) { |
449 |
122 |
enableTheory(THEORY_FP); |
450 |
122 |
p += 2; |
451 |
|
} |
452 |
25729 |
if(!strncmp(p, "DT", 2)) { |
453 |
140 |
enableTheory(THEORY_DATATYPES); |
454 |
140 |
p += 2; |
455 |
|
} |
456 |
25729 |
if(!d_theories[THEORY_BV] && !strncmp(p, "BV", 2)) { |
457 |
|
enableTheory(THEORY_BV); |
458 |
|
p += 2; |
459 |
|
} |
460 |
25729 |
if(*p == 'S') { |
461 |
956 |
enableTheory(THEORY_STRINGS); |
462 |
956 |
++p; |
463 |
|
} |
464 |
25729 |
if(!strncmp(p, "IDL", 3)) { |
465 |
225 |
enableIntegers(); |
466 |
225 |
disableReals(); |
467 |
225 |
arithOnlyDifference(); |
468 |
225 |
p += 3; |
469 |
25504 |
} else if(!strncmp(p, "RDL", 3)) { |
470 |
118 |
disableIntegers(); |
471 |
118 |
enableReals(); |
472 |
118 |
arithOnlyDifference(); |
473 |
118 |
p += 3; |
474 |
25386 |
} 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 |
25386 |
} else if(!strncmp(p, "LIA", 3)) { |
482 |
3200 |
enableIntegers(); |
483 |
3200 |
disableReals(); |
484 |
3200 |
arithOnlyLinear(); |
485 |
3200 |
p += 3; |
486 |
22186 |
} else if(!strncmp(p, "LRA", 3)) { |
487 |
1013 |
disableIntegers(); |
488 |
1013 |
enableReals(); |
489 |
1013 |
arithOnlyLinear(); |
490 |
1013 |
p += 3; |
491 |
21173 |
} else if(!strncmp(p, "LIRA", 4)) { |
492 |
432 |
enableIntegers(); |
493 |
432 |
enableReals(); |
494 |
432 |
arithOnlyLinear(); |
495 |
432 |
p += 4; |
496 |
20741 |
} else if(!strncmp(p, "NIA", 3)) { |
497 |
778 |
enableIntegers(); |
498 |
778 |
disableReals(); |
499 |
778 |
arithNonLinear(); |
500 |
778 |
p += 3; |
501 |
19963 |
} else if(!strncmp(p, "NRA", 3)) { |
502 |
15941 |
disableIntegers(); |
503 |
15941 |
enableReals(); |
504 |
15941 |
arithNonLinear(); |
505 |
15941 |
p += 3; |
506 |
15941 |
if (*p == 'T') |
507 |
|
{ |
508 |
198 |
arithTranscendentals(); |
509 |
198 |
p += 1; |
510 |
|
} |
511 |
4022 |
} else if(!strncmp(p, "NIRA", 4)) { |
512 |
302 |
enableIntegers(); |
513 |
302 |
enableReals(); |
514 |
302 |
arithNonLinear(); |
515 |
302 |
p += 4; |
516 |
302 |
if (*p == 'T') |
517 |
|
{ |
518 |
6 |
arithTranscendentals(); |
519 |
6 |
p += 1; |
520 |
|
} |
521 |
|
} |
522 |
25729 |
if(!strncmp(p, "FS", 2)) { |
523 |
160 |
enableTheory(THEORY_SETS); |
524 |
160 |
p += 2; |
525 |
|
} |
526 |
|
} |
527 |
|
} |
528 |
|
|
529 |
31034 |
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 |
5271 |
enableTheory(THEORY_BV); |
536 |
|
} |
537 |
|
|
538 |
31034 |
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 |
31032 |
d_logicString = logicString; |
551 |
31032 |
} |
552 |
|
|
553 |
52943 |
void LogicInfo::enableEverything(bool enableHigherOrder) |
554 |
|
{ |
555 |
52943 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
556 |
52943 |
*this = LogicInfo(); |
557 |
52943 |
this->d_higherOrder = enableHigherOrder; |
558 |
52943 |
} |
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 |
2053704 |
void LogicInfo::enableTheory(theory::TheoryId theory) { |
566 |
2053704 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
567 |
2053704 |
if(!d_theories[theory]) { |
568 |
2039349 |
if(isTrueTheory(theory)) { |
569 |
1529658 |
++d_sharingTheories; |
570 |
|
} |
571 |
2039349 |
d_logicString = ""; |
572 |
2039349 |
d_theories[theory] = true; |
573 |
|
} |
574 |
2053704 |
} |
575 |
|
|
576 |
43489 |
void LogicInfo::disableTheory(theory::TheoryId theory) { |
577 |
43489 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
578 |
43479 |
if(d_theories[theory]) { |
579 |
3664 |
if(isTrueTheory(theory)) { |
580 |
75 |
Assert(d_sharingTheories > 0); |
581 |
75 |
--d_sharingTheories; |
582 |
|
} |
583 |
3664 |
if(theory == THEORY_BUILTIN || |
584 |
|
theory == THEORY_BOOL) { |
585 |
|
return; |
586 |
|
} |
587 |
3664 |
d_logicString = ""; |
588 |
3664 |
d_theories[theory] = false; |
589 |
|
} |
590 |
|
} |
591 |
|
|
592 |
1064 |
void LogicInfo::enableSygus() |
593 |
|
{ |
594 |
1064 |
enableQuantifiers(); |
595 |
1064 |
enableTheory(THEORY_UF); |
596 |
1064 |
enableTheory(THEORY_DATATYPES); |
597 |
1064 |
enableIntegers(); |
598 |
1064 |
} |
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 |
6143 |
void LogicInfo::enableIntegers() { |
608 |
6143 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
609 |
6141 |
d_logicString = ""; |
610 |
6141 |
enableTheory(THEORY_ARITH); |
611 |
6141 |
d_integers = true; |
612 |
6141 |
} |
613 |
|
|
614 |
17076 |
void LogicInfo::disableIntegers() { |
615 |
17076 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
616 |
17074 |
d_logicString = ""; |
617 |
17074 |
d_integers = false; |
618 |
17074 |
if(!d_reals) { |
619 |
17072 |
disableTheory(THEORY_ARITH); |
620 |
|
} |
621 |
17074 |
} |
622 |
|
|
623 |
17806 |
void LogicInfo::enableReals() { |
624 |
17806 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
625 |
17806 |
d_logicString = ""; |
626 |
17806 |
enableTheory(THEORY_ARITH); |
627 |
17806 |
d_reals = true; |
628 |
17806 |
} |
629 |
|
|
630 |
4207 |
void LogicInfo::disableReals() { |
631 |
4207 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
632 |
4205 |
d_logicString = ""; |
633 |
4205 |
d_reals = false; |
634 |
4205 |
if(!d_integers) { |
635 |
|
disableTheory(THEORY_ARITH); |
636 |
|
} |
637 |
4205 |
} |
638 |
|
|
639 |
204 |
void LogicInfo::arithTranscendentals() |
640 |
|
{ |
641 |
204 |
PrettyCheckArgument( |
642 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
643 |
204 |
d_logicString = ""; |
644 |
204 |
d_transcendentals = true; |
645 |
204 |
if (!d_reals) |
646 |
|
{ |
647 |
|
enableReals(); |
648 |
|
} |
649 |
204 |
if (d_linear) |
650 |
|
{ |
651 |
|
arithNonLinear(); |
652 |
|
} |
653 |
204 |
} |
654 |
|
|
655 |
343 |
void LogicInfo::arithOnlyDifference() { |
656 |
343 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
657 |
343 |
d_logicString = ""; |
658 |
343 |
d_linear = true; |
659 |
343 |
d_differenceLogic = true; |
660 |
343 |
d_transcendentals = false; |
661 |
343 |
} |
662 |
|
|
663 |
4783 |
void LogicInfo::arithOnlyLinear() { |
664 |
4783 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
665 |
4781 |
d_logicString = ""; |
666 |
4781 |
d_linear = true; |
667 |
4781 |
d_differenceLogic = false; |
668 |
4781 |
d_transcendentals = false; |
669 |
4781 |
} |
670 |
|
|
671 |
22341 |
void LogicInfo::arithNonLinear() { |
672 |
22341 |
PrettyCheckArgument(!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
673 |
22341 |
d_logicString = ""; |
674 |
22341 |
d_linear = false; |
675 |
22341 |
d_differenceLogic = false; |
676 |
22341 |
} |
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 |
342 |
void LogicInfo::enableHigherOrder() |
695 |
|
{ |
696 |
342 |
PrettyCheckArgument( |
697 |
|
!d_locked, *this, "This LogicInfo is locked, and cannot be modified"); |
698 |
342 |
d_logicString = ""; |
699 |
342 |
d_higherOrder = true; |
700 |
342 |
} |
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 |
11892 |
LogicInfo LogicInfo::getUnlockedCopy() const { |
711 |
11892 |
if(d_locked) { |
712 |
23784 |
LogicInfo info = *this; |
713 |
11892 |
info.d_locked = false; |
714 |
11892 |
return info; |
715 |
|
} else { |
716 |
|
return *this; |
717 |
|
} |
718 |
|
} |
719 |
|
|
720 |
2354 |
std::ostream& operator<<(std::ostream& out, const LogicInfo& logic) { |
721 |
2354 |
return out << logic.getLogicString(); |
722 |
|
} |
723 |
|
|
724 |
31125 |
} // namespace cvc5 |