1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Andrew Reynolds, Andres Noetzli, Morgan Deters |
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 |
|
* Definitions of SMT2 constants. |
14 |
|
*/ |
15 |
|
#include "parser/smt2/smt2.h" |
16 |
|
|
17 |
|
#include <algorithm> |
18 |
|
|
19 |
|
#include "base/check.h" |
20 |
|
#include "options/base_options.h" |
21 |
|
#include "options/options.h" |
22 |
|
#include "options/options_public.h" |
23 |
|
#include "parser/antlr_input.h" |
24 |
|
#include "parser/parser.h" |
25 |
|
#include "parser/smt2/smt2_input.h" |
26 |
|
|
27 |
|
// ANTLR defines these, which is really bad! |
28 |
|
#undef true |
29 |
|
#undef false |
30 |
|
|
31 |
|
namespace cvc5 { |
32 |
|
namespace parser { |
33 |
|
|
34 |
5409 |
Smt2::Smt2(api::Solver* solver, |
35 |
|
SymbolManager* sm, |
36 |
|
bool strictMode, |
37 |
5409 |
bool parseOnly) |
38 |
|
: Parser(solver, sm, strictMode, parseOnly), |
39 |
|
d_logicSet(false), |
40 |
5409 |
d_seenSetLogic(false) |
41 |
|
{ |
42 |
5409 |
} |
43 |
|
|
44 |
10818 |
Smt2::~Smt2() {} |
45 |
|
|
46 |
5410 |
void Smt2::addArithmeticOperators() { |
47 |
5410 |
addOperator(api::PLUS, "+"); |
48 |
5410 |
addOperator(api::MINUS, "-"); |
49 |
|
// api::MINUS is converted to api::UMINUS if there is only a single operand |
50 |
5410 |
Parser::addOperator(api::UMINUS); |
51 |
5410 |
addOperator(api::MULT, "*"); |
52 |
5410 |
addOperator(api::LT, "<"); |
53 |
5410 |
addOperator(api::LEQ, "<="); |
54 |
5410 |
addOperator(api::GT, ">"); |
55 |
5410 |
addOperator(api::GEQ, ">="); |
56 |
|
|
57 |
5410 |
if (!strictModeEnabled()) |
58 |
|
{ |
59 |
|
// NOTE: this operator is non-standard |
60 |
5406 |
addOperator(api::POW, "^"); |
61 |
|
} |
62 |
5410 |
} |
63 |
|
|
64 |
1630 |
void Smt2::addTranscendentalOperators() |
65 |
|
{ |
66 |
1630 |
addOperator(api::EXPONENTIAL, "exp"); |
67 |
1630 |
addOperator(api::SINE, "sin"); |
68 |
1630 |
addOperator(api::COSINE, "cos"); |
69 |
1630 |
addOperator(api::TANGENT, "tan"); |
70 |
1630 |
addOperator(api::COSECANT, "csc"); |
71 |
1630 |
addOperator(api::SECANT, "sec"); |
72 |
1630 |
addOperator(api::COTANGENT, "cot"); |
73 |
1630 |
addOperator(api::ARCSINE, "arcsin"); |
74 |
1630 |
addOperator(api::ARCCOSINE, "arccos"); |
75 |
1630 |
addOperator(api::ARCTANGENT, "arctan"); |
76 |
1630 |
addOperator(api::ARCCOSECANT, "arccsc"); |
77 |
1630 |
addOperator(api::ARCSECANT, "arcsec"); |
78 |
1630 |
addOperator(api::ARCCOTANGENT, "arccot"); |
79 |
1630 |
addOperator(api::SQRT, "sqrt"); |
80 |
1630 |
} |
81 |
|
|
82 |
2317 |
void Smt2::addQuantifiersOperators() |
83 |
|
{ |
84 |
2317 |
} |
85 |
|
|
86 |
2766 |
void Smt2::addBitvectorOperators() { |
87 |
2766 |
addOperator(api::BITVECTOR_CONCAT, "concat"); |
88 |
2766 |
addOperator(api::BITVECTOR_NOT, "bvnot"); |
89 |
2766 |
addOperator(api::BITVECTOR_AND, "bvand"); |
90 |
2766 |
addOperator(api::BITVECTOR_OR, "bvor"); |
91 |
2766 |
addOperator(api::BITVECTOR_NEG, "bvneg"); |
92 |
2766 |
addOperator(api::BITVECTOR_ADD, "bvadd"); |
93 |
2766 |
addOperator(api::BITVECTOR_MULT, "bvmul"); |
94 |
2766 |
addOperator(api::BITVECTOR_UDIV, "bvudiv"); |
95 |
2766 |
addOperator(api::BITVECTOR_UREM, "bvurem"); |
96 |
2766 |
addOperator(api::BITVECTOR_SHL, "bvshl"); |
97 |
2766 |
addOperator(api::BITVECTOR_LSHR, "bvlshr"); |
98 |
2766 |
addOperator(api::BITVECTOR_ULT, "bvult"); |
99 |
2766 |
addOperator(api::BITVECTOR_NAND, "bvnand"); |
100 |
2766 |
addOperator(api::BITVECTOR_NOR, "bvnor"); |
101 |
2766 |
addOperator(api::BITVECTOR_XOR, "bvxor"); |
102 |
2766 |
addOperator(api::BITVECTOR_XNOR, "bvxnor"); |
103 |
2766 |
addOperator(api::BITVECTOR_COMP, "bvcomp"); |
104 |
2766 |
addOperator(api::BITVECTOR_SUB, "bvsub"); |
105 |
2766 |
addOperator(api::BITVECTOR_SDIV, "bvsdiv"); |
106 |
2766 |
addOperator(api::BITVECTOR_SREM, "bvsrem"); |
107 |
2766 |
addOperator(api::BITVECTOR_SMOD, "bvsmod"); |
108 |
2766 |
addOperator(api::BITVECTOR_ASHR, "bvashr"); |
109 |
2766 |
addOperator(api::BITVECTOR_ULE, "bvule"); |
110 |
2766 |
addOperator(api::BITVECTOR_UGT, "bvugt"); |
111 |
2766 |
addOperator(api::BITVECTOR_UGE, "bvuge"); |
112 |
2766 |
addOperator(api::BITVECTOR_SLT, "bvslt"); |
113 |
2766 |
addOperator(api::BITVECTOR_SLE, "bvsle"); |
114 |
2766 |
addOperator(api::BITVECTOR_SGT, "bvsgt"); |
115 |
2766 |
addOperator(api::BITVECTOR_SGE, "bvsge"); |
116 |
2766 |
addOperator(api::BITVECTOR_REDOR, "bvredor"); |
117 |
2766 |
addOperator(api::BITVECTOR_REDAND, "bvredand"); |
118 |
|
|
119 |
2766 |
addIndexedOperator(api::BITVECTOR_EXTRACT, api::BITVECTOR_EXTRACT, "extract"); |
120 |
2766 |
addIndexedOperator(api::BITVECTOR_REPEAT, api::BITVECTOR_REPEAT, "repeat"); |
121 |
2766 |
addIndexedOperator( |
122 |
|
api::BITVECTOR_ZERO_EXTEND, api::BITVECTOR_ZERO_EXTEND, "zero_extend"); |
123 |
2766 |
addIndexedOperator( |
124 |
|
api::BITVECTOR_SIGN_EXTEND, api::BITVECTOR_SIGN_EXTEND, "sign_extend"); |
125 |
2766 |
addIndexedOperator( |
126 |
|
api::BITVECTOR_ROTATE_LEFT, api::BITVECTOR_ROTATE_LEFT, "rotate_left"); |
127 |
2766 |
addIndexedOperator( |
128 |
|
api::BITVECTOR_ROTATE_RIGHT, api::BITVECTOR_ROTATE_RIGHT, "rotate_right"); |
129 |
2766 |
} |
130 |
|
|
131 |
1595 |
void Smt2::addDatatypesOperators() |
132 |
|
{ |
133 |
1595 |
Parser::addOperator(api::APPLY_CONSTRUCTOR); |
134 |
1595 |
Parser::addOperator(api::APPLY_TESTER); |
135 |
1595 |
Parser::addOperator(api::APPLY_SELECTOR); |
136 |
|
|
137 |
1595 |
if (!strictModeEnabled()) |
138 |
|
{ |
139 |
1595 |
Parser::addOperator(api::APPLY_UPDATER); |
140 |
1595 |
addOperator(api::DT_SIZE, "dt.size"); |
141 |
|
} |
142 |
1595 |
} |
143 |
|
|
144 |
1968 |
void Smt2::addStringOperators() { |
145 |
3936 |
defineVar( |
146 |
|
"re.all", |
147 |
3936 |
getSolver()->mkTerm(api::REGEXP_STAR, getSolver()->mkRegexpSigma())); |
148 |
1968 |
addOperator(api::STRING_CONCAT, "str.++"); |
149 |
1968 |
addOperator(api::STRING_LENGTH, "str.len"); |
150 |
1968 |
addOperator(api::STRING_SUBSTR, "str.substr"); |
151 |
1968 |
addOperator(api::STRING_CONTAINS, "str.contains"); |
152 |
1968 |
addOperator(api::STRING_CHARAT, "str.at"); |
153 |
1968 |
addOperator(api::STRING_INDEXOF, "str.indexof"); |
154 |
1968 |
addOperator(api::STRING_REPLACE, "str.replace"); |
155 |
1968 |
addOperator(api::STRING_PREFIX, "str.prefixof"); |
156 |
1968 |
addOperator(api::STRING_SUFFIX, "str.suffixof"); |
157 |
1968 |
addOperator(api::STRING_FROM_CODE, "str.from_code"); |
158 |
1968 |
addOperator(api::STRING_IS_DIGIT, "str.is_digit"); |
159 |
1968 |
addOperator(api::STRING_REPLACE_RE, "str.replace_re"); |
160 |
1968 |
addOperator(api::STRING_REPLACE_RE_ALL, "str.replace_re_all"); |
161 |
1968 |
if (!strictModeEnabled()) |
162 |
|
{ |
163 |
1968 |
addOperator(api::STRING_INDEXOF_RE, "str.indexof_re"); |
164 |
1968 |
addOperator(api::STRING_UPDATE, "str.update"); |
165 |
1968 |
addOperator(api::STRING_TOLOWER, "str.tolower"); |
166 |
1968 |
addOperator(api::STRING_TOUPPER, "str.toupper"); |
167 |
1968 |
addOperator(api::STRING_REV, "str.rev"); |
168 |
|
// sequence versions |
169 |
1968 |
addOperator(api::SEQ_CONCAT, "seq.++"); |
170 |
1968 |
addOperator(api::SEQ_LENGTH, "seq.len"); |
171 |
1968 |
addOperator(api::SEQ_EXTRACT, "seq.extract"); |
172 |
1968 |
addOperator(api::SEQ_UPDATE, "seq.update"); |
173 |
1968 |
addOperator(api::SEQ_AT, "seq.at"); |
174 |
1968 |
addOperator(api::SEQ_CONTAINS, "seq.contains"); |
175 |
1968 |
addOperator(api::SEQ_INDEXOF, "seq.indexof"); |
176 |
1968 |
addOperator(api::SEQ_REPLACE, "seq.replace"); |
177 |
1968 |
addOperator(api::SEQ_PREFIX, "seq.prefixof"); |
178 |
1968 |
addOperator(api::SEQ_SUFFIX, "seq.suffixof"); |
179 |
1968 |
addOperator(api::SEQ_REV, "seq.rev"); |
180 |
1968 |
addOperator(api::SEQ_REPLACE_ALL, "seq.replace_all"); |
181 |
1968 |
addOperator(api::SEQ_UNIT, "seq.unit"); |
182 |
1968 |
addOperator(api::SEQ_NTH, "seq.nth"); |
183 |
|
} |
184 |
1968 |
addOperator(api::STRING_FROM_INT, "str.from_int"); |
185 |
1968 |
addOperator(api::STRING_TO_INT, "str.to_int"); |
186 |
1968 |
addOperator(api::STRING_IN_REGEXP, "str.in_re"); |
187 |
1968 |
addOperator(api::STRING_TO_REGEXP, "str.to_re"); |
188 |
1968 |
addOperator(api::STRING_TO_CODE, "str.to_code"); |
189 |
1968 |
addOperator(api::STRING_REPLACE_ALL, "str.replace_all"); |
190 |
|
|
191 |
1968 |
addOperator(api::REGEXP_CONCAT, "re.++"); |
192 |
1968 |
addOperator(api::REGEXP_UNION, "re.union"); |
193 |
1968 |
addOperator(api::REGEXP_INTER, "re.inter"); |
194 |
1968 |
addOperator(api::REGEXP_STAR, "re.*"); |
195 |
1968 |
addOperator(api::REGEXP_PLUS, "re.+"); |
196 |
1968 |
addOperator(api::REGEXP_OPT, "re.opt"); |
197 |
1968 |
addIndexedOperator(api::REGEXP_REPEAT, api::REGEXP_REPEAT, "re.^"); |
198 |
1968 |
addIndexedOperator(api::REGEXP_LOOP, api::REGEXP_LOOP, "re.loop"); |
199 |
1968 |
addOperator(api::REGEXP_RANGE, "re.range"); |
200 |
1968 |
addOperator(api::REGEXP_COMPLEMENT, "re.comp"); |
201 |
1968 |
addOperator(api::REGEXP_DIFF, "re.diff"); |
202 |
1968 |
addOperator(api::STRING_LT, "str.<"); |
203 |
1968 |
addOperator(api::STRING_LEQ, "str.<="); |
204 |
1968 |
} |
205 |
|
|
206 |
1592 |
void Smt2::addFloatingPointOperators() { |
207 |
1592 |
addOperator(api::FLOATINGPOINT_FP, "fp"); |
208 |
1592 |
addOperator(api::FLOATINGPOINT_EQ, "fp.eq"); |
209 |
1592 |
addOperator(api::FLOATINGPOINT_ABS, "fp.abs"); |
210 |
1592 |
addOperator(api::FLOATINGPOINT_NEG, "fp.neg"); |
211 |
1592 |
addOperator(api::FLOATINGPOINT_ADD, "fp.add"); |
212 |
1592 |
addOperator(api::FLOATINGPOINT_SUB, "fp.sub"); |
213 |
1592 |
addOperator(api::FLOATINGPOINT_MULT, "fp.mul"); |
214 |
1592 |
addOperator(api::FLOATINGPOINT_DIV, "fp.div"); |
215 |
1592 |
addOperator(api::FLOATINGPOINT_FMA, "fp.fma"); |
216 |
1592 |
addOperator(api::FLOATINGPOINT_SQRT, "fp.sqrt"); |
217 |
1592 |
addOperator(api::FLOATINGPOINT_REM, "fp.rem"); |
218 |
1592 |
addOperator(api::FLOATINGPOINT_RTI, "fp.roundToIntegral"); |
219 |
1592 |
addOperator(api::FLOATINGPOINT_MIN, "fp.min"); |
220 |
1592 |
addOperator(api::FLOATINGPOINT_MAX, "fp.max"); |
221 |
1592 |
addOperator(api::FLOATINGPOINT_LEQ, "fp.leq"); |
222 |
1592 |
addOperator(api::FLOATINGPOINT_LT, "fp.lt"); |
223 |
1592 |
addOperator(api::FLOATINGPOINT_GEQ, "fp.geq"); |
224 |
1592 |
addOperator(api::FLOATINGPOINT_GT, "fp.gt"); |
225 |
1592 |
addOperator(api::FLOATINGPOINT_ISN, "fp.isNormal"); |
226 |
1592 |
addOperator(api::FLOATINGPOINT_ISSN, "fp.isSubnormal"); |
227 |
1592 |
addOperator(api::FLOATINGPOINT_ISZ, "fp.isZero"); |
228 |
1592 |
addOperator(api::FLOATINGPOINT_ISINF, "fp.isInfinite"); |
229 |
1592 |
addOperator(api::FLOATINGPOINT_ISNAN, "fp.isNaN"); |
230 |
1592 |
addOperator(api::FLOATINGPOINT_ISNEG, "fp.isNegative"); |
231 |
1592 |
addOperator(api::FLOATINGPOINT_ISPOS, "fp.isPositive"); |
232 |
1592 |
addOperator(api::FLOATINGPOINT_TO_REAL, "fp.to_real"); |
233 |
|
|
234 |
1592 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_GENERIC, |
235 |
|
api::FLOATINGPOINT_TO_FP_GENERIC, |
236 |
|
"to_fp"); |
237 |
1592 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, |
238 |
|
api::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, |
239 |
|
"to_fp_unsigned"); |
240 |
1592 |
addIndexedOperator( |
241 |
|
api::FLOATINGPOINT_TO_UBV, api::FLOATINGPOINT_TO_UBV, "fp.to_ubv"); |
242 |
1592 |
addIndexedOperator( |
243 |
|
api::FLOATINGPOINT_TO_SBV, api::FLOATINGPOINT_TO_SBV, "fp.to_sbv"); |
244 |
|
|
245 |
1592 |
if (!strictModeEnabled()) |
246 |
|
{ |
247 |
1590 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, |
248 |
|
api::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, |
249 |
|
"to_fp_bv"); |
250 |
1590 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_FLOATINGPOINT, |
251 |
|
api::FLOATINGPOINT_TO_FP_FLOATINGPOINT, |
252 |
|
"to_fp_fp"); |
253 |
1590 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_REAL, |
254 |
|
api::FLOATINGPOINT_TO_FP_REAL, |
255 |
|
"to_fp_real"); |
256 |
1590 |
addIndexedOperator(api::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, |
257 |
|
api::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, |
258 |
|
"to_fp_signed"); |
259 |
|
} |
260 |
1592 |
} |
261 |
|
|
262 |
1537 |
void Smt2::addSepOperators() { |
263 |
1537 |
addOperator(api::SEP_STAR, "sep"); |
264 |
1537 |
addOperator(api::SEP_PTO, "pto"); |
265 |
1537 |
addOperator(api::SEP_WAND, "wand"); |
266 |
1537 |
addOperator(api::SEP_EMP, "emp"); |
267 |
1537 |
Parser::addOperator(api::SEP_STAR); |
268 |
1537 |
Parser::addOperator(api::SEP_PTO); |
269 |
1537 |
Parser::addOperator(api::SEP_WAND); |
270 |
1537 |
Parser::addOperator(api::SEP_EMP); |
271 |
1537 |
} |
272 |
|
|
273 |
5371 |
void Smt2::addCoreSymbols() |
274 |
|
{ |
275 |
5371 |
defineType("Bool", d_solver->getBooleanSort(), true, true); |
276 |
5371 |
defineVar("true", d_solver->mkTrue(), true, true); |
277 |
5371 |
defineVar("false", d_solver->mkFalse(), true, true); |
278 |
5371 |
addOperator(api::AND, "and"); |
279 |
5371 |
addOperator(api::DISTINCT, "distinct"); |
280 |
5371 |
addOperator(api::EQUAL, "="); |
281 |
5371 |
addOperator(api::IMPLIES, "=>"); |
282 |
5371 |
addOperator(api::ITE, "ite"); |
283 |
5371 |
addOperator(api::NOT, "not"); |
284 |
5371 |
addOperator(api::OR, "or"); |
285 |
5371 |
addOperator(api::XOR, "xor"); |
286 |
5371 |
} |
287 |
|
|
288 |
417040 |
void Smt2::addOperator(api::Kind kind, const std::string& name) |
289 |
|
{ |
290 |
834080 |
Debug("parser") << "Smt2::addOperator( " << kind << ", " << name << " )" |
291 |
417040 |
<< std::endl; |
292 |
417040 |
Parser::addOperator(kind); |
293 |
417040 |
operatorKindMap[name] = kind; |
294 |
417040 |
} |
295 |
|
|
296 |
41846 |
void Smt2::addIndexedOperator(api::Kind tKind, |
297 |
|
api::Kind opKind, |
298 |
|
const std::string& name) |
299 |
|
{ |
300 |
41846 |
Parser::addOperator(tKind); |
301 |
41846 |
d_indexedOpKindMap[name] = opKind; |
302 |
41846 |
} |
303 |
|
|
304 |
2934115 |
api::Kind Smt2::getOperatorKind(const std::string& name) const |
305 |
|
{ |
306 |
|
// precondition: isOperatorEnabled(name) |
307 |
2934115 |
return operatorKindMap.find(name)->second; |
308 |
|
} |
309 |
|
|
310 |
3437263 |
bool Smt2::isOperatorEnabled(const std::string& name) const { |
311 |
3437263 |
return operatorKindMap.find(name) != operatorKindMap.end(); |
312 |
|
} |
313 |
|
|
314 |
40434 |
bool Smt2::isTheoryEnabled(theory::TheoryId theory) const |
315 |
|
{ |
316 |
40434 |
return d_logic.isTheoryEnabled(theory); |
317 |
|
} |
318 |
|
|
319 |
2936367 |
bool Smt2::isHoEnabled() const { return d_logic.isHigherOrder(); } |
320 |
|
|
321 |
261278 |
bool Smt2::logicIsSet() { |
322 |
261278 |
return d_logicSet; |
323 |
|
} |
324 |
|
|
325 |
3531766 |
api::Term Smt2::getExpressionForNameAndType(const std::string& name, |
326 |
|
api::Sort t) |
327 |
|
{ |
328 |
3531766 |
if (isAbstractValue(name)) |
329 |
|
{ |
330 |
|
return mkAbstractValue(name); |
331 |
|
} |
332 |
3531766 |
return Parser::getExpressionForNameAndType(name, t); |
333 |
|
} |
334 |
|
|
335 |
2166 |
bool Smt2::getTesterName(api::Term cons, std::string& name) |
336 |
|
{ |
337 |
2166 |
if ((v2_6() || sygus_v2()) && strictModeEnabled()) |
338 |
|
{ |
339 |
|
// 2.6 or above uses indexed tester symbols, if we are in strict mode, |
340 |
|
// we do not automatically define is-cons for constructor cons. |
341 |
|
return false; |
342 |
|
} |
343 |
4332 |
std::stringstream ss; |
344 |
2166 |
ss << "is-" << cons; |
345 |
2166 |
name = ss.str(); |
346 |
2166 |
return true; |
347 |
|
} |
348 |
|
|
349 |
89013 |
api::Term Smt2::mkIndexedConstant(const std::string& name, |
350 |
|
const std::vector<uint64_t>& numerals) |
351 |
|
{ |
352 |
89013 |
if (d_logic.isTheoryEnabled(theory::THEORY_FP)) |
353 |
|
{ |
354 |
1088 |
if (name == "+oo") |
355 |
|
{ |
356 |
4 |
return d_solver->mkPosInf(numerals[0], numerals[1]); |
357 |
|
} |
358 |
1084 |
else if (name == "-oo") |
359 |
|
{ |
360 |
2 |
return d_solver->mkNegInf(numerals[0], numerals[1]); |
361 |
|
} |
362 |
1082 |
else if (name == "NaN") |
363 |
|
{ |
364 |
2 |
return d_solver->mkNaN(numerals[0], numerals[1]); |
365 |
|
} |
366 |
1080 |
else if (name == "+zero") |
367 |
|
{ |
368 |
5 |
return d_solver->mkPosZero(numerals[0], numerals[1]); |
369 |
|
} |
370 |
1075 |
else if (name == "-zero") |
371 |
|
{ |
372 |
2 |
return d_solver->mkNegZero(numerals[0], numerals[1]); |
373 |
|
} |
374 |
|
} |
375 |
|
|
376 |
88998 |
if (d_logic.isTheoryEnabled(theory::THEORY_BV) && name.find("bv") == 0) |
377 |
|
{ |
378 |
177996 |
std::string bvStr = name.substr(2); |
379 |
88998 |
return d_solver->mkBitVector(numerals[0], bvStr, 10); |
380 |
|
} |
381 |
|
|
382 |
|
// NOTE: Theory parametric constants go here |
383 |
|
|
384 |
|
parseError(std::string("Unknown indexed literal `") + name + "'"); |
385 |
|
return api::Term(); |
386 |
|
} |
387 |
|
|
388 |
76422 |
api::Op Smt2::mkIndexedOp(const std::string& name, |
389 |
|
const std::vector<uint64_t>& numerals) |
390 |
|
{ |
391 |
76422 |
const auto& kIt = d_indexedOpKindMap.find(name); |
392 |
76422 |
if (kIt != d_indexedOpKindMap.end()) |
393 |
|
{ |
394 |
76422 |
api::Kind k = (*kIt).second; |
395 |
76422 |
if (numerals.size() == 1) |
396 |
|
{ |
397 |
64172 |
return d_solver->mkOp(k, numerals[0]); |
398 |
|
} |
399 |
12250 |
else if (numerals.size() == 2) |
400 |
|
{ |
401 |
12250 |
return d_solver->mkOp(k, numerals[0], numerals[1]); |
402 |
|
} |
403 |
|
} |
404 |
|
|
405 |
|
parseError(std::string("Unknown indexed function `") + name + "'"); |
406 |
|
return api::Op(); |
407 |
|
} |
408 |
|
|
409 |
150 |
api::Term Smt2::bindDefineFunRec( |
410 |
|
const std::string& fname, |
411 |
|
const std::vector<std::pair<std::string, api::Sort>>& sortedVarNames, |
412 |
|
api::Sort t, |
413 |
|
std::vector<api::Term>& flattenVars) |
414 |
|
{ |
415 |
300 |
std::vector<api::Sort> sorts; |
416 |
454 |
for (const std::pair<std::string, api::Sort>& svn : sortedVarNames) |
417 |
|
{ |
418 |
304 |
sorts.push_back(svn.second); |
419 |
|
} |
420 |
|
|
421 |
|
// make the flattened function type, add bound variables |
422 |
|
// to flattenVars if the defined function was given a function return type. |
423 |
300 |
api::Sort ft = mkFlatFunctionType(sorts, t, flattenVars); |
424 |
|
|
425 |
|
// allow overloading |
426 |
300 |
return bindVar(fname, ft, false, true); |
427 |
|
} |
428 |
|
|
429 |
150 |
void Smt2::pushDefineFunRecScope( |
430 |
|
const std::vector<std::pair<std::string, api::Sort>>& sortedVarNames, |
431 |
|
api::Term func, |
432 |
|
const std::vector<api::Term>& flattenVars, |
433 |
|
std::vector<api::Term>& bvs) |
434 |
|
{ |
435 |
150 |
pushScope(); |
436 |
|
|
437 |
|
// bound variables are those that are explicitly named in the preamble |
438 |
|
// of the define-fun(s)-rec command, we define them here |
439 |
454 |
for (const std::pair<std::string, api::Sort>& svn : sortedVarNames) |
440 |
|
{ |
441 |
608 |
api::Term v = bindBoundVar(svn.first, svn.second); |
442 |
304 |
bvs.push_back(v); |
443 |
|
} |
444 |
|
|
445 |
150 |
bvs.insert(bvs.end(), flattenVars.begin(), flattenVars.end()); |
446 |
150 |
} |
447 |
|
|
448 |
41 |
void Smt2::reset() { |
449 |
41 |
d_logicSet = false; |
450 |
41 |
d_seenSetLogic = false; |
451 |
41 |
d_logic = LogicInfo(); |
452 |
41 |
operatorKindMap.clear(); |
453 |
41 |
d_lastNamedTerm = std::pair<api::Term, std::string>(); |
454 |
41 |
} |
455 |
|
|
456 |
14 |
std::unique_ptr<Command> Smt2::invConstraint( |
457 |
|
const std::vector<std::string>& names) |
458 |
|
{ |
459 |
14 |
checkThatLogicIsSet(); |
460 |
14 |
Debug("parser-sygus") << "Sygus : define sygus funs..." << std::endl; |
461 |
14 |
Debug("parser-sygus") << "Sygus : read inv-constraint..." << std::endl; |
462 |
|
|
463 |
14 |
if (names.size() != 4) |
464 |
|
{ |
465 |
|
parseError( |
466 |
|
"Bad syntax for inv-constraint: expected 4 " |
467 |
|
"arguments."); |
468 |
|
} |
469 |
|
|
470 |
28 |
std::vector<api::Term> terms; |
471 |
70 |
for (const std::string& name : names) |
472 |
|
{ |
473 |
56 |
if (!isDeclared(name)) |
474 |
|
{ |
475 |
|
std::stringstream ss; |
476 |
|
ss << "Function " << name << " in inv-constraint is not defined."; |
477 |
|
parseError(ss.str()); |
478 |
|
} |
479 |
|
|
480 |
56 |
terms.push_back(getVariable(name)); |
481 |
|
} |
482 |
|
|
483 |
28 |
return std::unique_ptr<Command>(new SygusInvConstraintCommand(terms)); |
484 |
|
} |
485 |
|
|
486 |
5377 |
Command* Smt2::setLogic(std::string name, bool fromCommand) |
487 |
|
{ |
488 |
5377 |
if (fromCommand) |
489 |
|
{ |
490 |
5309 |
if (d_seenSetLogic) |
491 |
|
{ |
492 |
2 |
parseError("Only one set-logic is allowed."); |
493 |
|
} |
494 |
5308 |
d_seenSetLogic = true; |
495 |
|
|
496 |
5308 |
if (logicIsForced()) |
497 |
|
{ |
498 |
|
// If the logic is forced, we ignore all set-logic requests from commands. |
499 |
5 |
return new EmptyCommand(); |
500 |
|
} |
501 |
|
} |
502 |
|
|
503 |
5371 |
d_logicSet = true; |
504 |
5371 |
d_logic = name; |
505 |
|
|
506 |
|
// if sygus is enabled, we must enable UF, datatypes, and integer arithmetic |
507 |
5371 |
if(sygus()) { |
508 |
194 |
if (!d_logic.isQuantified()) |
509 |
|
{ |
510 |
|
warning("Logics in sygus are assumed to contain quantifiers."); |
511 |
|
warning("Omit QF_ from the logic to avoid this warning."); |
512 |
|
} |
513 |
|
} |
514 |
|
|
515 |
|
// Core theory belongs to every logic |
516 |
5371 |
addCoreSymbols(); |
517 |
|
|
518 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_UF)) { |
519 |
2928 |
Parser::addOperator(api::APPLY_UF); |
520 |
|
|
521 |
2928 |
if (!strictModeEnabled() && d_logic.hasCardinalityConstraints()) |
522 |
|
{ |
523 |
22 |
addOperator(api::CARDINALITY_CONSTRAINT, "fmf.card"); |
524 |
22 |
addOperator(api::CARDINALITY_VALUE, "fmf.card.val"); |
525 |
|
} |
526 |
|
} |
527 |
|
|
528 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_ARITH)) { |
529 |
3724 |
if(d_logic.areIntegersUsed()) { |
530 |
3199 |
defineType("Int", d_solver->getIntegerSort(), true, true); |
531 |
3199 |
addArithmeticOperators(); |
532 |
3199 |
if (!strictModeEnabled() || !d_logic.isLinear()) |
533 |
|
{ |
534 |
3195 |
addOperator(api::INTS_DIVISION, "div"); |
535 |
3195 |
addOperator(api::INTS_MODULUS, "mod"); |
536 |
3195 |
addOperator(api::ABS, "abs"); |
537 |
|
} |
538 |
3199 |
addIndexedOperator(api::DIVISIBLE, api::DIVISIBLE, "divisible"); |
539 |
|
} |
540 |
|
|
541 |
3724 |
if (d_logic.areRealsUsed()) |
542 |
|
{ |
543 |
2211 |
defineType("Real", d_solver->getRealSort(), true, true); |
544 |
2211 |
addArithmeticOperators(); |
545 |
2211 |
addOperator(api::DIVISION, "/"); |
546 |
2211 |
if (!strictModeEnabled()) |
547 |
|
{ |
548 |
2211 |
addOperator(api::ABS, "abs"); |
549 |
|
} |
550 |
|
} |
551 |
|
|
552 |
3724 |
if (d_logic.areIntegersUsed() && d_logic.areRealsUsed()) |
553 |
|
{ |
554 |
1686 |
addOperator(api::TO_INTEGER, "to_int"); |
555 |
1686 |
addOperator(api::IS_INTEGER, "is_int"); |
556 |
1686 |
addOperator(api::TO_REAL, "to_real"); |
557 |
|
} |
558 |
|
|
559 |
3724 |
if (d_logic.areTranscendentalsUsed()) |
560 |
|
{ |
561 |
1630 |
defineVar("real.pi", d_solver->mkTerm(api::PI)); |
562 |
1630 |
addTranscendentalOperators(); |
563 |
|
} |
564 |
3724 |
if (!strictModeEnabled()) |
565 |
|
{ |
566 |
|
// integer version of AND |
567 |
3720 |
addIndexedOperator(api::IAND, api::IAND, "iand"); |
568 |
|
// pow2 |
569 |
3720 |
addOperator(api::POW2, "int.pow2"); |
570 |
|
} |
571 |
|
} |
572 |
|
|
573 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_ARRAYS)) { |
574 |
2160 |
addOperator(api::SELECT, "select"); |
575 |
2160 |
addOperator(api::STORE, "store"); |
576 |
2160 |
addOperator(api::EQ_RANGE, "eqrange"); |
577 |
|
} |
578 |
|
|
579 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_BV)) { |
580 |
2766 |
addBitvectorOperators(); |
581 |
|
|
582 |
8293 |
if (!strictModeEnabled() && d_logic.isTheoryEnabled(theory::THEORY_ARITH) |
583 |
4439 |
&& d_logic.areIntegersUsed()) |
584 |
|
{ |
585 |
|
// Conversions between bit-vectors and integers |
586 |
1667 |
addOperator(api::BITVECTOR_TO_NAT, "bv2nat"); |
587 |
1667 |
addIndexedOperator( |
588 |
|
api::INT_TO_BITVECTOR, api::INT_TO_BITVECTOR, "int2bv"); |
589 |
|
} |
590 |
|
} |
591 |
|
|
592 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_DATATYPES)) { |
593 |
3190 |
const std::vector<api::Sort> types; |
594 |
1595 |
defineType("Tuple", d_solver->mkTupleSort(types), true, true); |
595 |
1595 |
addDatatypesOperators(); |
596 |
|
} |
597 |
|
|
598 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_SETS)) { |
599 |
1615 |
defineVar("emptyset", d_solver->mkEmptySet(d_solver->getNullSort())); |
600 |
|
// the Boolean sort is a placeholder here since we don't have type info |
601 |
|
// without type annotation |
602 |
1615 |
defineVar("univset", d_solver->mkUniverseSet(d_solver->getBooleanSort())); |
603 |
|
|
604 |
1615 |
addOperator(api::UNION, "union"); |
605 |
1615 |
addOperator(api::INTERSECTION, "intersection"); |
606 |
1615 |
addOperator(api::SETMINUS, "setminus"); |
607 |
1615 |
addOperator(api::SUBSET, "subset"); |
608 |
1615 |
addOperator(api::MEMBER, "member"); |
609 |
1615 |
addOperator(api::SINGLETON, "singleton"); |
610 |
1615 |
addOperator(api::INSERT, "insert"); |
611 |
1615 |
addOperator(api::CARD, "card"); |
612 |
1615 |
addOperator(api::COMPLEMENT, "complement"); |
613 |
1615 |
addOperator(api::CHOOSE, "choose"); |
614 |
1615 |
addOperator(api::IS_SINGLETON, "is_singleton"); |
615 |
1615 |
addOperator(api::JOIN, "join"); |
616 |
1615 |
addOperator(api::PRODUCT, "product"); |
617 |
1615 |
addOperator(api::TRANSPOSE, "transpose"); |
618 |
1615 |
addOperator(api::TCLOSURE, "tclosure"); |
619 |
|
} |
620 |
|
|
621 |
5371 |
if (d_logic.isTheoryEnabled(theory::THEORY_BAGS)) |
622 |
|
{ |
623 |
1533 |
defineVar("emptybag", d_solver->mkEmptyBag(d_solver->getNullSort())); |
624 |
1533 |
addOperator(api::UNION_MAX, "union_max"); |
625 |
1533 |
addOperator(api::UNION_DISJOINT, "union_disjoint"); |
626 |
1533 |
addOperator(api::INTERSECTION_MIN, "intersection_min"); |
627 |
1533 |
addOperator(api::DIFFERENCE_SUBTRACT, "difference_subtract"); |
628 |
1533 |
addOperator(api::DIFFERENCE_REMOVE, "difference_remove"); |
629 |
1533 |
addOperator(api::SUBBAG, "subbag"); |
630 |
1533 |
addOperator(api::BAG_COUNT, "bag.count"); |
631 |
1533 |
addOperator(api::DUPLICATE_REMOVAL, "duplicate_removal"); |
632 |
1533 |
addOperator(api::MK_BAG, "bag"); |
633 |
1533 |
addOperator(api::BAG_CARD, "bag.card"); |
634 |
1533 |
addOperator(api::BAG_CHOOSE, "bag.choose"); |
635 |
1533 |
addOperator(api::BAG_IS_SINGLETON, "bag.is_singleton"); |
636 |
1533 |
addOperator(api::BAG_FROM_SET, "bag.from_set"); |
637 |
1533 |
addOperator(api::BAG_TO_SET, "bag.to_set"); |
638 |
|
} |
639 |
5371 |
if(d_logic.isTheoryEnabled(theory::THEORY_STRINGS)) { |
640 |
1968 |
defineType("String", d_solver->getStringSort(), true, true); |
641 |
1968 |
defineType("RegLan", d_solver->getRegExpSort(), true, true); |
642 |
1968 |
defineType("Int", d_solver->getIntegerSort(), true, true); |
643 |
|
|
644 |
1968 |
defineVar("re.none", d_solver->mkRegexpEmpty()); |
645 |
1968 |
defineVar("re.allchar", d_solver->mkRegexpSigma()); |
646 |
|
|
647 |
|
// Boolean is a placeholder |
648 |
3936 |
defineVar("seq.empty", |
649 |
3936 |
d_solver->mkEmptySequence(d_solver->getBooleanSort())); |
650 |
|
|
651 |
1968 |
addStringOperators(); |
652 |
|
} |
653 |
|
|
654 |
5371 |
if(d_logic.isQuantified()) { |
655 |
2317 |
addQuantifiersOperators(); |
656 |
|
} |
657 |
|
|
658 |
5371 |
if (d_logic.isTheoryEnabled(theory::THEORY_FP)) { |
659 |
1592 |
defineType("RoundingMode", d_solver->getRoundingModeSort(), true, true); |
660 |
1592 |
defineType("Float16", d_solver->mkFloatingPointSort(5, 11), true, true); |
661 |
1592 |
defineType("Float32", d_solver->mkFloatingPointSort(8, 24), true, true); |
662 |
1592 |
defineType("Float64", d_solver->mkFloatingPointSort(11, 53), true, true); |
663 |
1592 |
defineType("Float128", d_solver->mkFloatingPointSort(15, 113), true, true); |
664 |
|
|
665 |
1592 |
defineVar("RNE", d_solver->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_EVEN)); |
666 |
3184 |
defineVar("roundNearestTiesToEven", |
667 |
3184 |
d_solver->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_EVEN)); |
668 |
1592 |
defineVar("RNA", d_solver->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_AWAY)); |
669 |
3184 |
defineVar("roundNearestTiesToAway", |
670 |
3184 |
d_solver->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_AWAY)); |
671 |
1592 |
defineVar("RTP", d_solver->mkRoundingMode(api::ROUND_TOWARD_POSITIVE)); |
672 |
3184 |
defineVar("roundTowardPositive", |
673 |
3184 |
d_solver->mkRoundingMode(api::ROUND_TOWARD_POSITIVE)); |
674 |
1592 |
defineVar("RTN", d_solver->mkRoundingMode(api::ROUND_TOWARD_NEGATIVE)); |
675 |
3184 |
defineVar("roundTowardNegative", |
676 |
3184 |
d_solver->mkRoundingMode(api::ROUND_TOWARD_NEGATIVE)); |
677 |
1592 |
defineVar("RTZ", d_solver->mkRoundingMode(api::ROUND_TOWARD_ZERO)); |
678 |
3184 |
defineVar("roundTowardZero", |
679 |
3184 |
d_solver->mkRoundingMode(api::ROUND_TOWARD_ZERO)); |
680 |
|
|
681 |
1592 |
addFloatingPointOperators(); |
682 |
|
} |
683 |
|
|
684 |
5371 |
if (d_logic.isTheoryEnabled(theory::THEORY_SEP)) { |
685 |
|
// the Boolean sort is a placeholder here since we don't have type info |
686 |
|
// without type annotation |
687 |
1537 |
defineVar("sep.nil", d_solver->mkSepNil(d_solver->getBooleanSort())); |
688 |
|
|
689 |
1537 |
addSepOperators(); |
690 |
|
} |
691 |
|
|
692 |
10742 |
std::string logic = sygus() ? d_logic.getLogicString() : name; |
693 |
5371 |
if (!fromCommand) |
694 |
|
{ |
695 |
|
// If not from a command, just set the logic directly. Notice this is |
696 |
|
// important since we do not want to enqueue a set-logic command and |
697 |
|
// fully initialize the underlying SmtEngine in the meantime before the |
698 |
|
// command has a chance to execute, which would lead to an error. |
699 |
68 |
d_solver->setLogic(logic); |
700 |
68 |
return nullptr; |
701 |
|
} |
702 |
5303 |
Command* cmd = new SetBenchmarkLogicCommand(logic); |
703 |
5303 |
return cmd; |
704 |
|
} /* Smt2::setLogic() */ |
705 |
|
|
706 |
153 |
api::Grammar* Smt2::mkGrammar(const std::vector<api::Term>& boundVars, |
707 |
|
const std::vector<api::Term>& ntSymbols) |
708 |
|
{ |
709 |
153 |
d_allocGrammars.emplace_back( |
710 |
306 |
new api::Grammar(d_solver->mkSygusGrammar(boundVars, ntSymbols))); |
711 |
153 |
return d_allocGrammars.back().get(); |
712 |
|
} |
713 |
|
|
714 |
236143 |
bool Smt2::sygus() const |
715 |
|
{ |
716 |
236143 |
InputLanguage ilang = getLanguage(); |
717 |
236143 |
return ilang == language::input::LANG_SYGUS_V2; |
718 |
|
} |
719 |
|
|
720 |
121 |
bool Smt2::sygus_v2() const |
721 |
|
{ |
722 |
121 |
return getLanguage() == language::input::LANG_SYGUS_V2; |
723 |
|
} |
724 |
|
|
725 |
261278 |
void Smt2::checkThatLogicIsSet() |
726 |
|
{ |
727 |
261278 |
if (!logicIsSet()) |
728 |
|
{ |
729 |
72 |
if (strictModeEnabled()) |
730 |
|
{ |
731 |
8 |
parseError("set-logic must appear before this point."); |
732 |
|
} |
733 |
|
else |
734 |
|
{ |
735 |
|
// the calls to setLogic below set the logic on the solver directly |
736 |
68 |
if (logicIsForced()) |
737 |
|
{ |
738 |
8 |
setLogic(getForcedLogic(), false); |
739 |
|
} |
740 |
|
else |
741 |
|
{ |
742 |
60 |
warning("No set-logic command was given before this point."); |
743 |
60 |
warning("cvc5 will make all theories available."); |
744 |
60 |
warning( |
745 |
|
"Consider setting a stricter logic for (likely) better " |
746 |
|
"performance."); |
747 |
60 |
warning("To suppress this warning in the future use (set-logic ALL)."); |
748 |
|
|
749 |
60 |
setLogic("ALL", false); |
750 |
|
} |
751 |
|
} |
752 |
|
} |
753 |
261274 |
} |
754 |
|
|
755 |
3693 |
void Smt2::checkLogicAllowsFreeSorts() |
756 |
|
{ |
757 |
7386 |
if (!d_logic.isTheoryEnabled(theory::THEORY_UF) |
758 |
34 |
&& !d_logic.isTheoryEnabled(theory::THEORY_ARRAYS) |
759 |
|
&& !d_logic.isTheoryEnabled(theory::THEORY_DATATYPES) |
760 |
|
&& !d_logic.isTheoryEnabled(theory::THEORY_SETS) |
761 |
3693 |
&& !d_logic.isTheoryEnabled(theory::THEORY_BAGS)) |
762 |
|
{ |
763 |
|
parseErrorLogic("Free sort symbols not allowed in "); |
764 |
|
} |
765 |
3693 |
} |
766 |
|
|
767 |
14398 |
void Smt2::checkLogicAllowsFunctions() |
768 |
|
{ |
769 |
14398 |
if (!d_logic.isTheoryEnabled(theory::THEORY_UF) && !isHoEnabled()) |
770 |
|
{ |
771 |
|
parseError( |
772 |
|
"Functions (of non-zero arity) cannot " |
773 |
|
"be declared in logic " |
774 |
|
+ d_logic.getLogicString() |
775 |
|
+ ". Try including UF or adding the prefix HO_."); |
776 |
|
} |
777 |
14398 |
} |
778 |
|
|
779 |
|
/* The include are managed in the lexer but called in the parser */ |
780 |
|
// Inspired by http://www.antlr3.org/api/C/interop.html |
781 |
|
|
782 |
|
static bool newInputStream(const std::string& filename, pANTLR3_LEXER lexer) { |
783 |
|
Debug("parser") << "Including " << filename << std::endl; |
784 |
|
// Create a new input stream and take advantage of built in stream stacking |
785 |
|
// in C target runtime. |
786 |
|
// |
787 |
|
pANTLR3_INPUT_STREAM in; |
788 |
|
#ifdef CVC5_ANTLR3_OLD_INPUT_STREAM |
789 |
|
in = antlr3AsciiFileStreamNew((pANTLR3_UINT8) filename.c_str()); |
790 |
|
#else /* CVC5_ANTLR3_OLD_INPUT_STREAM */ |
791 |
|
in = antlr3FileStreamNew((pANTLR3_UINT8) filename.c_str(), ANTLR3_ENC_8BIT); |
792 |
|
#endif /* CVC5_ANTLR3_OLD_INPUT_STREAM */ |
793 |
|
if( in == NULL ) { |
794 |
|
Debug("parser") << "Can't open " << filename << std::endl; |
795 |
|
return false; |
796 |
|
} |
797 |
|
// Same thing as the predefined PUSHSTREAM(in); |
798 |
|
lexer->pushCharStream(lexer, in); |
799 |
|
// restart it |
800 |
|
//lexer->rec->state->tokenStartCharIndex = -10; |
801 |
|
//lexer->emit(lexer); |
802 |
|
|
803 |
|
// Note that the input stream is not closed when it EOFs, I don't bother |
804 |
|
// to do it here, but it is up to you to track streams created like this |
805 |
|
// and destroy them when the whole parse session is complete. Remember that you |
806 |
|
// don't want to do this until all tokens have been manipulated all the way through |
807 |
|
// your tree parsers etc as the token does not store the text it just refers |
808 |
|
// back to the input stream and trying to get the text for it will abort if you |
809 |
|
// close the input stream too early. |
810 |
|
|
811 |
|
//TODO what said before |
812 |
|
return true; |
813 |
|
} |
814 |
|
|
815 |
|
void Smt2::includeFile(const std::string& filename) { |
816 |
|
// security for online version |
817 |
|
if(!canIncludeFile()) { |
818 |
|
parseError("include-file feature was disabled for this run."); |
819 |
|
} |
820 |
|
|
821 |
|
// Get the lexer |
822 |
|
AntlrInput* ai = static_cast<AntlrInput*>(getInput()); |
823 |
|
pANTLR3_LEXER lexer = ai->getAntlr3Lexer(); |
824 |
|
// get the name of the current stream "Does it work inside an include?" |
825 |
|
const std::string inputName = ai->getInputStreamName(); |
826 |
|
|
827 |
|
// Find the directory of the current input file |
828 |
|
std::string path; |
829 |
|
size_t pos = inputName.rfind('/'); |
830 |
|
if(pos != std::string::npos) { |
831 |
|
path = std::string(inputName, 0, pos + 1); |
832 |
|
} |
833 |
|
path.append(filename); |
834 |
|
if(!newInputStream(path, lexer)) { |
835 |
|
parseError("Couldn't open include file `" + path + "'"); |
836 |
|
} |
837 |
|
} |
838 |
10949692 |
bool Smt2::isAbstractValue(const std::string& name) |
839 |
|
{ |
840 |
21169204 |
return name.length() >= 2 && name[0] == '@' && name[1] != '0' |
841 |
10949704 |
&& name.find_first_not_of("0123456789", 1) == std::string::npos; |
842 |
|
} |
843 |
|
|
844 |
|
api::Term Smt2::mkAbstractValue(const std::string& name) |
845 |
|
{ |
846 |
|
Assert(isAbstractValue(name)); |
847 |
|
// remove the '@' |
848 |
|
return d_solver->mkAbstractValue(name.substr(1)); |
849 |
|
} |
850 |
|
|
851 |
777994 |
InputLanguage Smt2::getLanguage() const |
852 |
|
{ |
853 |
777994 |
return d_solver->getOptions().base.inputLanguage; |
854 |
|
} |
855 |
|
|
856 |
355 |
void Smt2::parseOpApplyTypeAscription(ParseOp& p, api::Sort type) |
857 |
|
{ |
858 |
710 |
Debug("parser") << "parseOpApplyTypeAscription : " << p << " " << type |
859 |
355 |
<< std::endl; |
860 |
|
// (as const (Array T1 T2)) |
861 |
355 |
if (p.d_kind == api::CONST_ARRAY) |
862 |
|
{ |
863 |
65 |
if (!type.isArray()) |
864 |
|
{ |
865 |
|
std::stringstream ss; |
866 |
|
ss << "expected array constant term, but cast is not of array type" |
867 |
|
<< std::endl |
868 |
|
<< "cast type: " << type; |
869 |
|
parseError(ss.str()); |
870 |
|
} |
871 |
65 |
p.d_type = type; |
872 |
65 |
return; |
873 |
|
} |
874 |
290 |
if (p.d_expr.isNull()) |
875 |
|
{ |
876 |
580 |
Trace("parser-overloading") |
877 |
290 |
<< "Getting variable expression with name " << p.d_name << " and type " |
878 |
290 |
<< type << std::endl; |
879 |
|
// get the variable expression for the type |
880 |
290 |
if (isDeclared(p.d_name, SYM_VARIABLE)) |
881 |
|
{ |
882 |
290 |
p.d_expr = getExpressionForNameAndType(p.d_name, type); |
883 |
290 |
p.d_name = std::string(""); |
884 |
|
} |
885 |
290 |
if (p.d_expr.isNull()) |
886 |
|
{ |
887 |
|
std::stringstream ss; |
888 |
|
ss << "Could not resolve expression with name " << p.d_name |
889 |
|
<< " and type " << type << std::endl; |
890 |
|
parseError(ss.str()); |
891 |
|
} |
892 |
|
} |
893 |
290 |
Trace("parser-qid") << "Resolve ascription " << type << " on " << p.d_expr; |
894 |
290 |
Trace("parser-qid") << " " << p.d_expr.getKind() << " " << p.d_expr.getSort(); |
895 |
290 |
Trace("parser-qid") << std::endl; |
896 |
|
// otherwise, we process the type ascription |
897 |
290 |
p.d_expr = applyTypeAscription(p.d_expr, type); |
898 |
|
} |
899 |
|
|
900 |
3531773 |
api::Term Smt2::parseOpToExpr(ParseOp& p) |
901 |
|
{ |
902 |
3531773 |
Debug("parser") << "parseOpToExpr: " << p << std::endl; |
903 |
3531773 |
api::Term expr; |
904 |
3531773 |
if (p.d_kind != api::NULL_EXPR || !p.d_type.isNull()) |
905 |
|
{ |
906 |
|
parseError( |
907 |
|
"Bad syntax for qualified identifier operator in term position."); |
908 |
|
} |
909 |
3531773 |
else if (!p.d_expr.isNull()) |
910 |
|
{ |
911 |
288 |
expr = p.d_expr; |
912 |
|
} |
913 |
3531485 |
else if (!isDeclared(p.d_name, SYM_VARIABLE)) |
914 |
|
{ |
915 |
18 |
std::stringstream ss; |
916 |
9 |
ss << "Symbol " << p.d_name << " is not declared."; |
917 |
18 |
parseError(ss.str()); |
918 |
|
} |
919 |
|
else |
920 |
|
{ |
921 |
3531476 |
expr = getExpressionForName(p.d_name); |
922 |
|
} |
923 |
3531764 |
Assert(!expr.isNull()); |
924 |
3531764 |
return expr; |
925 |
|
} |
926 |
|
|
927 |
3336909 |
api::Term Smt2::applyParseOp(ParseOp& p, std::vector<api::Term>& args) |
928 |
|
{ |
929 |
3336909 |
bool isBuiltinOperator = false; |
930 |
|
// the builtin kind of the overall return expression |
931 |
3336909 |
api::Kind kind = api::NULL_EXPR; |
932 |
|
// First phase: process the operator |
933 |
3336909 |
if (Debug.isOn("parser")) |
934 |
|
{ |
935 |
|
Debug("parser") << "applyParseOp: " << p << " to:" << std::endl; |
936 |
|
for (std::vector<api::Term>::iterator i = args.begin(); i != args.end(); |
937 |
|
++i) |
938 |
|
{ |
939 |
|
Debug("parser") << "++ " << *i << std::endl; |
940 |
|
} |
941 |
|
} |
942 |
6673818 |
api::Op op; |
943 |
3336909 |
if (p.d_kind != api::NULL_EXPR) |
944 |
|
{ |
945 |
|
// It is a special case, e.g. tupSel or array constant specification. |
946 |
|
// We have to wait until the arguments are parsed to resolve it. |
947 |
|
} |
948 |
3336838 |
else if (!p.d_expr.isNull()) |
949 |
|
{ |
950 |
|
// An explicit operator, e.g. an apply function |
951 |
1424 |
api::Kind fkind = getKindForFunction(p.d_expr); |
952 |
1424 |
if (fkind != api::UNDEFINED_KIND) |
953 |
|
{ |
954 |
|
// Some operators may require a specific kind. |
955 |
|
// Testers are handled differently than other indexed operators, |
956 |
|
// since they require a kind. |
957 |
1424 |
kind = fkind; |
958 |
2848 |
Debug("parser") << "Got function kind " << kind << " for expression " |
959 |
1424 |
<< std::endl; |
960 |
|
} |
961 |
1424 |
args.insert(args.begin(), p.d_expr); |
962 |
|
} |
963 |
3335414 |
else if (!p.d_op.isNull()) |
964 |
|
{ |
965 |
|
// it was given an operator |
966 |
76421 |
op = p.d_op; |
967 |
|
} |
968 |
|
else |
969 |
|
{ |
970 |
3258993 |
isBuiltinOperator = isOperatorEnabled(p.d_name); |
971 |
3258993 |
if (isBuiltinOperator) |
972 |
|
{ |
973 |
|
// a builtin operator, convert to kind |
974 |
2934115 |
kind = getOperatorKind(p.d_name); |
975 |
|
} |
976 |
|
else |
977 |
|
{ |
978 |
|
// A non-built-in function application, get the expression |
979 |
324900 |
checkDeclaration(p.d_name, CHECK_DECLARED, SYM_VARIABLE); |
980 |
649712 |
api::Term v = getVariable(p.d_name); |
981 |
324856 |
if (!v.isNull()) |
982 |
|
{ |
983 |
324784 |
checkFunctionLike(v); |
984 |
324780 |
kind = getKindForFunction(v); |
985 |
324780 |
args.insert(args.begin(), v); |
986 |
|
} |
987 |
|
else |
988 |
|
{ |
989 |
|
// Overloaded symbol? |
990 |
|
// Could not find the expression. It may be an overloaded symbol, |
991 |
|
// in which case we may find it after knowing the types of its |
992 |
|
// arguments. |
993 |
148 |
std::vector<api::Sort> argTypes; |
994 |
172 |
for (std::vector<api::Term>::iterator i = args.begin(); i != args.end(); |
995 |
|
++i) |
996 |
|
{ |
997 |
98 |
argTypes.push_back((*i).getSort()); |
998 |
|
} |
999 |
148 |
api::Term fop = getOverloadedFunctionForTypes(p.d_name, argTypes); |
1000 |
74 |
if (!fop.isNull()) |
1001 |
|
{ |
1002 |
74 |
checkFunctionLike(fop); |
1003 |
74 |
kind = getKindForFunction(fop); |
1004 |
74 |
args.insert(args.begin(), fop); |
1005 |
|
} |
1006 |
|
else |
1007 |
|
{ |
1008 |
|
parseError( |
1009 |
|
"Cannot find unambiguous overloaded function for argument " |
1010 |
|
"types."); |
1011 |
|
} |
1012 |
|
} |
1013 |
|
} |
1014 |
|
} |
1015 |
|
// handle special cases |
1016 |
3336885 |
if (p.d_kind == api::CONST_ARRAY && !p.d_type.isNull()) |
1017 |
|
{ |
1018 |
65 |
if (args.size() != 1) |
1019 |
|
{ |
1020 |
|
parseError("Too many arguments to array constant."); |
1021 |
|
} |
1022 |
130 |
api::Term constVal = args[0]; |
1023 |
|
|
1024 |
|
// To parse array constants taking reals whose values are specified by |
1025 |
|
// rationals, e.g. ((as const (Array Int Real)) (/ 1 3)), we must handle |
1026 |
|
// the fact that (/ 1 3) is the division of constants 1 and 3, and not |
1027 |
|
// the resulting constant rational value. Thus, we must construct the |
1028 |
|
// resulting rational here. This also is applied for integral real values |
1029 |
|
// like 5.0 which are converted to (/ 5 1) to distinguish them from |
1030 |
|
// integer constants. We must ensure numerator and denominator are |
1031 |
|
// constant and the denominator is non-zero. |
1032 |
65 |
if (constVal.getKind() == api::DIVISION) |
1033 |
|
{ |
1034 |
4 |
std::stringstream sdiv; |
1035 |
2 |
sdiv << constVal[0] << "/" << constVal[1]; |
1036 |
2 |
constVal = d_solver->mkReal(sdiv.str()); |
1037 |
|
} |
1038 |
|
|
1039 |
65 |
if (!p.d_type.getArrayElementSort().isComparableTo(constVal.getSort())) |
1040 |
|
{ |
1041 |
|
std::stringstream ss; |
1042 |
|
ss << "type mismatch inside array constant term:" << std::endl |
1043 |
|
<< "array type: " << p.d_type << std::endl |
1044 |
|
<< "expected const type: " << p.d_type.getArrayElementSort() |
1045 |
|
<< std::endl |
1046 |
|
<< "computed const type: " << constVal.getSort(); |
1047 |
|
parseError(ss.str()); |
1048 |
|
} |
1049 |
130 |
api::Term ret = d_solver->mkConstArray(p.d_type, constVal); |
1050 |
65 |
Debug("parser") << "applyParseOp: return store all " << ret << std::endl; |
1051 |
65 |
return ret; |
1052 |
|
} |
1053 |
3336820 |
else if (p.d_kind == api::APPLY_SELECTOR && !p.d_expr.isNull()) |
1054 |
|
{ |
1055 |
|
// tuple selector case |
1056 |
4 |
if (!p.d_expr.isUInt64Value()) |
1057 |
|
{ |
1058 |
|
parseError("index of tupSel is larger than size of uint64_t"); |
1059 |
|
} |
1060 |
4 |
uint64_t n = p.d_expr.getUInt64Value(); |
1061 |
4 |
if (args.size() != 1) |
1062 |
|
{ |
1063 |
|
parseError("tupSel should only be applied to one tuple argument"); |
1064 |
|
} |
1065 |
8 |
api::Sort t = args[0].getSort(); |
1066 |
4 |
if (!t.isTuple()) |
1067 |
|
{ |
1068 |
|
parseError("tupSel applied to non-tuple"); |
1069 |
|
} |
1070 |
4 |
size_t length = t.getTupleLength(); |
1071 |
4 |
if (n >= length) |
1072 |
|
{ |
1073 |
|
std::stringstream ss; |
1074 |
|
ss << "tuple is of length " << length << "; cannot access index " << n; |
1075 |
|
parseError(ss.str()); |
1076 |
|
} |
1077 |
8 |
const api::Datatype& dt = t.getDatatype(); |
1078 |
4 |
api::Term ret = d_solver->mkTerm( |
1079 |
8 |
api::APPLY_SELECTOR, dt[0][n].getSelectorTerm(), args[0]); |
1080 |
4 |
Debug("parser") << "applyParseOp: return selector " << ret << std::endl; |
1081 |
4 |
return ret; |
1082 |
|
} |
1083 |
3336816 |
else if (p.d_kind == api::TUPLE_PROJECT) |
1084 |
|
{ |
1085 |
4 |
api::Term ret = d_solver->mkTerm(p.d_op, args[0]); |
1086 |
2 |
Debug("parser") << "applyParseOp: return projection " << ret << std::endl; |
1087 |
2 |
return ret; |
1088 |
|
} |
1089 |
3336814 |
else if (p.d_kind != api::NULL_EXPR) |
1090 |
|
{ |
1091 |
|
// it should not have an expression or type specified at this point |
1092 |
|
if (!p.d_expr.isNull() || !p.d_type.isNull()) |
1093 |
|
{ |
1094 |
|
std::stringstream ss; |
1095 |
|
ss << "Could not process parsed qualified identifier kind " << p.d_kind; |
1096 |
|
parseError(ss.str()); |
1097 |
|
} |
1098 |
|
// otherwise it is a simple application |
1099 |
|
kind = p.d_kind; |
1100 |
|
} |
1101 |
3336814 |
else if (isBuiltinOperator) |
1102 |
|
{ |
1103 |
2934115 |
if (!isHoEnabled() && (kind == api::EQUAL || kind == api::DISTINCT)) |
1104 |
|
{ |
1105 |
|
// need hol if these operators are applied over function args |
1106 |
725210 |
for (std::vector<api::Term>::iterator i = args.begin(); i != args.end(); |
1107 |
|
++i) |
1108 |
|
{ |
1109 |
485479 |
if ((*i).getSort().isFunction()) |
1110 |
|
{ |
1111 |
|
parseError( |
1112 |
|
"Cannot apply equalty to functions unless logic is prefixed by " |
1113 |
|
"HO_."); |
1114 |
|
} |
1115 |
|
} |
1116 |
|
} |
1117 |
8802258 |
if (!strictModeEnabled() && (kind == api::AND || kind == api::OR) |
1118 |
3784224 |
&& args.size() == 1) |
1119 |
|
{ |
1120 |
|
// Unary AND/OR can be replaced with the argument. |
1121 |
81 |
Debug("parser") << "applyParseOp: return unary " << args[0] << std::endl; |
1122 |
81 |
return args[0]; |
1123 |
|
} |
1124 |
2934034 |
else if (kind == api::MINUS && args.size() == 1) |
1125 |
|
{ |
1126 |
240896 |
api::Term ret = d_solver->mkTerm(api::UMINUS, args[0]); |
1127 |
120448 |
Debug("parser") << "applyParseOp: return uminus " << ret << std::endl; |
1128 |
120448 |
return ret; |
1129 |
|
} |
1130 |
2813586 |
if (kind == api::EQ_RANGE && d_solver->getOption("arrays-exp") != "true") |
1131 |
|
{ |
1132 |
|
parseError( |
1133 |
|
"eqrange predicate requires option --arrays-exp to be enabled."); |
1134 |
|
} |
1135 |
2813586 |
if (kind == api::SINGLETON && args.size() == 1) |
1136 |
|
{ |
1137 |
386 |
api::Term ret = d_solver->mkTerm(api::SINGLETON, args[0]); |
1138 |
193 |
Debug("parser") << "applyParseOp: return singleton " << ret << std::endl; |
1139 |
193 |
return ret; |
1140 |
|
} |
1141 |
5626786 |
api::Term ret = d_solver->mkTerm(kind, args); |
1142 |
5626786 |
Debug("parser") << "applyParseOp: return default builtin " << ret |
1143 |
2813393 |
<< std::endl; |
1144 |
2813393 |
return ret; |
1145 |
|
} |
1146 |
|
|
1147 |
402699 |
if (args.size() >= 2) |
1148 |
|
{ |
1149 |
|
// may be partially applied function, in this case we use HO_APPLY |
1150 |
652523 |
api::Sort argt = args[0].getSort(); |
1151 |
326415 |
if (argt.isFunction()) |
1152 |
|
{ |
1153 |
310077 |
unsigned arity = argt.getFunctionArity(); |
1154 |
310077 |
if (args.size() - 1 < arity) |
1155 |
|
{ |
1156 |
307 |
if (!isHoEnabled()) |
1157 |
|
{ |
1158 |
|
parseError( |
1159 |
|
"Cannot partially apply functions unless logic is prefixed by " |
1160 |
|
"HO_."); |
1161 |
|
} |
1162 |
307 |
Debug("parser") << "Partial application of " << args[0]; |
1163 |
307 |
Debug("parser") << " : #argTypes = " << arity; |
1164 |
307 |
Debug("parser") << ", #args = " << args.size() - 1 << std::endl; |
1165 |
614 |
api::Term ret = d_solver->mkTerm(api::HO_APPLY, args); |
1166 |
614 |
Debug("parser") << "applyParseOp: return curry higher order " << ret |
1167 |
307 |
<< std::endl; |
1168 |
|
// must curry the partial application |
1169 |
307 |
return ret; |
1170 |
|
} |
1171 |
|
} |
1172 |
|
} |
1173 |
402392 |
if (!op.isNull()) |
1174 |
|
{ |
1175 |
152841 |
api::Term ret = d_solver->mkTerm(op, args); |
1176 |
76420 |
Debug("parser") << "applyParseOp: return op : " << ret << std::endl; |
1177 |
76420 |
return ret; |
1178 |
|
} |
1179 |
325971 |
if (kind == api::NULL_EXPR) |
1180 |
|
{ |
1181 |
|
// should never happen in the new API |
1182 |
|
parseError("do not know how to process parse op"); |
1183 |
|
} |
1184 |
651942 |
Debug("parser") << "Try default term construction for kind " << kind |
1185 |
325971 |
<< " #args = " << args.size() << "..." << std::endl; |
1186 |
651941 |
api::Term ret = d_solver->mkTerm(kind, args); |
1187 |
325970 |
Debug("parser") << "applyParseOp: return : " << ret << std::endl; |
1188 |
325970 |
return ret; |
1189 |
|
} |
1190 |
|
|
1191 |
4673 |
void Smt2::notifyNamedExpression(api::Term& expr, std::string name) |
1192 |
|
{ |
1193 |
4673 |
checkUserSymbol(name); |
1194 |
|
// remember the expression name in the symbol manager |
1195 |
9346 |
if (getSymbolManager()->setExpressionName(expr, name, false) |
1196 |
4673 |
== NamingResult::ERROR_IN_BINDER) |
1197 |
|
{ |
1198 |
2 |
parseError( |
1199 |
|
"Cannot name a term in a binder (e.g., quantifiers, definitions)"); |
1200 |
|
} |
1201 |
|
// define the variable |
1202 |
4672 |
defineVar(name, expr); |
1203 |
|
// set the last named term, which ensures that we catch when assertions are |
1204 |
|
// named |
1205 |
4672 |
setLastNamedTerm(expr, name); |
1206 |
4672 |
} |
1207 |
|
|
1208 |
|
api::Term Smt2::mkAnd(const std::vector<api::Term>& es) |
1209 |
|
{ |
1210 |
|
if (es.size() == 0) |
1211 |
|
{ |
1212 |
|
return d_solver->mkTrue(); |
1213 |
|
} |
1214 |
|
else if (es.size() == 1) |
1215 |
|
{ |
1216 |
|
return es[0]; |
1217 |
|
} |
1218 |
|
else |
1219 |
|
{ |
1220 |
|
return d_solver->mkTerm(api::AND, es); |
1221 |
|
} |
1222 |
|
} |
1223 |
|
|
1224 |
|
} // namespace parser |
1225 |
29265 |
} // namespace cvc5 |