GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/parser/smt2/smt2.cpp Lines: 590 674 87.5 %
Date: 2021-05-22 Branches: 979 2064 47.4 %

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