GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/printer/smt2/smt2_printer.cpp Lines: 869 1183 73.5 %
Date: 2021-11-07 Branches: 1391 3038 45.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Morgan Deters, Abdalrhman Mohamed
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
 * The pretty-printer interface for the SMT2 output language.
14
 */
15
16
#include "printer/smt2/smt2_printer.h"
17
18
#include <iostream>
19
#include <list>
20
#include <string>
21
#include <typeinfo>
22
#include <vector>
23
24
#include "api/cpp/cvc5.h"
25
#include "expr/array_store_all.h"
26
#include "expr/ascription_type.h"
27
#include "expr/cardinality_constraint.h"
28
#include "expr/datatype_index.h"
29
#include "expr/dtype.h"
30
#include "expr/dtype_cons.h"
31
#include "expr/emptybag.h"
32
#include "expr/emptyset.h"
33
#include "expr/node_manager_attributes.h"
34
#include "expr/node_visitor.h"
35
#include "expr/sequence.h"
36
#include "expr/uninterpreted_constant.h"
37
#include "options/bv_options.h"
38
#include "options/language.h"
39
#include "options/printer_options.h"
40
#include "options/smt_options.h"
41
#include "printer/let_binding.h"
42
#include "proof/unsat_core.h"
43
#include "smt/command.h"
44
#include "smt_util/boolean_simplification.h"
45
#include "theory/arrays/theory_arrays_rewriter.h"
46
#include "theory/datatypes/sygus_datatype_utils.h"
47
#include "theory/datatypes/tuple_project_op.h"
48
#include "theory/quantifiers/quantifiers_attributes.h"
49
#include "theory/theory_model.h"
50
#include "util/bitvector.h"
51
#include "util/divisible.h"
52
#include "util/floatingpoint.h"
53
#include "util/iand.h"
54
#include "util/indexed_root_predicate.h"
55
#include "util/regexp.h"
56
#include "util/smt2_quote_string.h"
57
#include "util/string.h"
58
59
using namespace std;
60
61
namespace cvc5 {
62
namespace printer {
63
namespace smt2 {
64
65
410120
static void toStreamRational(std::ostream& out,
66
                             const Rational& r,
67
                             bool decimal,
68
                             Variant v)
69
{
70
410120
  bool neg = r.sgn() < 0;
71
  // Print the rational, possibly as decimal.
72
  // Notice that we print (/ (- 5) 3) instead of (- (/ 5 3)),
73
  // the former is compliant with real values in the smt lib standard.
74
410120
  if (r.isIntegral())
75
  {
76
399234
    if (neg)
77
    {
78
110071
      out << "(- " << -r;
79
    }
80
    else
81
    {
82
289163
      out << r;
83
    }
84
399234
    if (decimal)
85
    {
86
1307
      out << ".0";
87
    }
88
399234
    if (neg)
89
    {
90
110071
      out << ")";
91
    }
92
  }
93
  else
94
  {
95
10886
    out << "(/ ";
96
10886
    if (neg)
97
    {
98
11174
      Rational abs_r = (-r);
99
5587
      out << "(- " << abs_r.getNumerator();
100
5587
      out << ") " << abs_r.getDenominator();
101
    }
102
    else
103
    {
104
5299
      out << r.getNumerator();
105
5299
      out << ' ' << r.getDenominator();
106
    }
107
10886
    out << ')';
108
  }
109
410120
}
110
111
262571
void Smt2Printer::toStream(std::ostream& out,
112
                           TNode n,
113
                           int toDepth,
114
                           size_t dag) const
115
{
116
262571
  if(dag != 0) {
117
399380
    LetBinding lbind(dag + 1);
118
199704
    toStreamWithLetify(out, n, toDepth, &lbind);
119
  } else {
120
62881
    toStream(out, n, toDepth);
121
  }
122
262557
}
123
124
199690
void Smt2Printer::toStreamWithLetify(std::ostream& out,
125
                                     Node n,
126
                                     int toDepth,
127
                                     LetBinding* lbind) const
128
{
129
199690
  if (lbind == nullptr)
130
  {
131
    toStream(out, n, toDepth);
132
    return;
133
  }
134
399380
  std::stringstream cparen;
135
399380
  std::vector<Node> letList;
136
199690
  lbind->letify(n, letList);
137
199690
  if (!letList.empty())
138
  {
139
59513
    std::map<Node, uint32_t>::const_iterator it;
140
331365
    for (size_t i = 0, nlets = letList.size(); i < nlets; i++)
141
    {
142
543704
      Node nl = letList[i];
143
271852
      out << "(let ((";
144
271852
      uint32_t id = lbind->getId(nl);
145
271852
      out << "_let_" << id << " ";
146
543704
      Node nlc = lbind->convert(nl, "_let_", false);
147
271852
      toStream(out, nlc, toDepth, lbind);
148
271852
      out << ")) ";
149
271852
      cparen << ")";
150
    }
151
  }
152
399380
  Node nc = lbind->convert(n, "_let_");
153
  // print the body, passing the lbind object
154
199676
  toStream(out, nc, toDepth, lbind);
155
199676
  out << cparen.str();
156
199676
  lbind->popScope();
157
}
158
159
5482199
void Smt2Printer::toStream(std::ostream& out,
160
                           TNode n,
161
                           int toDepth,
162
                           LetBinding* lbind) const
163
{
164
  // null
165
5482199
  if(n.getKind() == kind::NULL_EXPR) {
166
    out << "null";
167
3241909
    return;
168
  }
169
170
5482199
  NodeManager* nm = NodeManager::currentNM();
171
  // constant
172
5482199
  if(n.getMetaKind() == kind::metakind::CONSTANT) {
173
625804
    switch(n.getKind()) {
174
25673
    case kind::TYPE_CONSTANT:
175
25673
      switch(n.getConst<TypeConstant>()) {
176
5985
      case BOOLEAN_TYPE: out << "Bool"; break;
177
971
      case REAL_TYPE: out << "Real"; break;
178
17867
      case INTEGER_TYPE: out << "Int"; break;
179
775
      case STRING_TYPE: out << "String"; break;
180
8
      case REGEXP_TYPE: out << "RegLan"; break;
181
67
      case ROUNDINGMODE_TYPE: out << "RoundingMode"; break;
182
      default:
183
        // fall back on whatever operator<< does on underlying type; we
184
        // might luck out and be SMT-LIB v2 compliant
185
        kind::metakind::NodeValueConstPrinter::toStream(out, n);
186
      }
187
25673
      break;
188
5533
    case kind::BITVECTOR_TYPE:
189
5533
      out << "(_ BitVec " << n.getConst<BitVectorSize>().d_size << ")";
190
5533
      break;
191
243
    case kind::FLOATINGPOINT_TYPE:
192
243
      out << "(_ FloatingPoint "
193
243
          << n.getConst<FloatingPointSize>().exponentWidth() << " "
194
243
          << n.getConst<FloatingPointSize>().significandWidth() << ")";
195
243
      break;
196
29221
    case kind::CONST_BITVECTOR:
197
    {
198
29221
      const BitVector& bv = n.getConst<BitVector>();
199
29221
      if (options::bvPrintConstsAsIndexedSymbols())
200
      {
201
5
        out << "(_ bv" << bv.getValue() << " " << bv.getSize() << ")";
202
      }
203
      else
204
      {
205
29216
        out << "#b" << bv.toString();
206
      }
207
29221
      break;
208
    }
209
24
    case kind::CONST_FLOATINGPOINT:
210
    {
211
48
      out << n.getConst<FloatingPoint>().toString(
212
24
          options::bvPrintConstsAsIndexedSymbols());
213
24
      break;
214
    }
215
147
    case kind::CONST_ROUNDINGMODE:
216
147
      switch (n.getConst<RoundingMode>()) {
217
125
        case RoundingMode::ROUND_NEAREST_TIES_TO_EVEN:
218
125
          out << "roundNearestTiesToEven";
219
125
          break;
220
9
        case RoundingMode::ROUND_NEAREST_TIES_TO_AWAY:
221
9
          out << "roundNearestTiesToAway";
222
9
          break;
223
2
        case RoundingMode::ROUND_TOWARD_POSITIVE:
224
2
          out << "roundTowardPositive";
225
2
          break;
226
2
        case RoundingMode::ROUND_TOWARD_NEGATIVE:
227
2
          out << "roundTowardNegative";
228
2
          break;
229
9
        case RoundingMode::ROUND_TOWARD_ZERO: out << "roundTowardZero"; break;
230
        default:
231
          Unreachable() << "Invalid value of rounding mode constant ("
232
                        << n.getConst<RoundingMode>() << ")";
233
      }
234
147
      break;
235
124620
    case kind::CONST_BOOLEAN:
236
      // the default would print "1" or "0" for bool, that's not correct
237
      // for our purposes
238
124620
      out << (n.getConst<bool>() ? "true" : "false");
239
124620
      break;
240
    case kind::BUILTIN:
241
      out << smtKindString(n.getConst<Kind>(), d_variant);
242
      break;
243
408813
    case kind::CONST_RATIONAL: {
244
408813
      const Rational& r = n.getConst<Rational>();
245
408813
      toStreamRational(out, r, false, d_variant);
246
408813
      break;
247
    }
248
249
8599
    case kind::CONST_STRING: {
250
17198
      std::string s = n.getConst<String>().toString();
251
8599
      out << '"';
252
26338
      for(size_t i = 0; i < s.size(); ++i) {
253
17739
        char c = s[i];
254
17739
        if(c == '"') {
255
24
          out << "\"\"";
256
        } else {
257
17715
          out << c;
258
        }
259
      }
260
8599
      out << '"';
261
8599
      break;
262
    }
263
32
    case kind::CONST_SEQUENCE:
264
    {
265
32
      const Sequence& sn = n.getConst<Sequence>();
266
32
      const std::vector<Node>& snvec = sn.getVec();
267
32
      if (snvec.empty())
268
      {
269
19
        out << "(as seq.empty ";
270
19
        toStreamType(out, n.getType());
271
19
        out << ")";
272
      }
273
13
      else if (snvec.size() > 1)
274
      {
275
7
        out << "(seq.++";
276
41
        for (const Node& snvc : snvec)
277
        {
278
34
          out << " (seq.unit " << snvc << ")";
279
        }
280
7
        out << ")";
281
      }
282
      else
283
      {
284
6
        out << "(seq.unit " << snvec[0] << ")";
285
      }
286
32
      break;
287
    }
288
289
105
    case kind::STORE_ALL: {
290
210
      ArrayStoreAll asa = n.getConst<ArrayStoreAll>();
291
105
      out << "((as const ";
292
105
      toStreamType(out, asa.getType());
293
105
      out << ") " << asa.getValue() << ")";
294
105
      break;
295
    }
296
297
5246
    case kind::DATATYPE_TYPE:
298
    {
299
      const DType& dt = (NodeManager::currentNM()->getDTypeForIndex(
300
5246
          n.getConst<DatatypeIndexConstant>().getIndex()));
301
5246
      if (dt.isTuple())
302
      {
303
61
        unsigned int nargs = dt[0].getNumArgs();
304
61
        if (nargs == 0)
305
        {
306
3
          out << "Tuple";
307
        }
308
        else
309
        {
310
58
          out << "(Tuple";
311
151
          for (unsigned int i = 0; i < nargs; i++)
312
          {
313
93
            out << " ";
314
93
            toStreamType(out, dt[0][i].getRangeType());
315
          }
316
58
          out << ")";
317
        }
318
      }
319
      else
320
      {
321
5185
        out << cvc5::quoteSymbol(dt.getName());
322
      }
323
5246
      break;
324
    }
325
326
15
    case kind::UNINTERPRETED_CONSTANT: {
327
15
      const UninterpretedConstant& uc = n.getConst<UninterpretedConstant>();
328
30
      std::stringstream ss;
329
15
      ss << "(as @" << uc << " " << n.getType() << ")";
330
15
      out << ss.str();
331
15
      break;
332
    }
333
216
    case kind::EMPTYSET:
334
216
      out << "(as emptyset ";
335
216
      toStreamType(out, n.getConst<EmptySet>().getType());
336
216
      out << ")";
337
216
      break;
338
339
19
    case kind::EMPTYBAG:
340
19
      out << "(as emptybag ";
341
19
      toStreamType(out, n.getConst<EmptyBag>().getType());
342
19
      out << ")";
343
19
      break;
344
2778
    case kind::BITVECTOR_EXTRACT_OP:
345
    {
346
2778
      BitVectorExtract p = n.getConst<BitVectorExtract>();
347
2778
      out << "(_ extract " << p.d_high << ' ' << p.d_low << ")";
348
2778
      break;
349
    }
350
300
    case kind::BITVECTOR_REPEAT_OP:
351
300
      out << "(_ repeat " << n.getConst<BitVectorRepeat>().d_repeatAmount
352
300
          << ")";
353
300
      break;
354
6352
    case kind::BITVECTOR_ZERO_EXTEND_OP:
355
6352
      out << "(_ zero_extend "
356
6352
          << n.getConst<BitVectorZeroExtend>().d_zeroExtendAmount << ")";
357
6352
      break;
358
6938
    case kind::BITVECTOR_SIGN_EXTEND_OP:
359
6938
      out << "(_ sign_extend "
360
6938
          << n.getConst<BitVectorSignExtend>().d_signExtendAmount << ")";
361
6938
      break;
362
240
    case kind::BITVECTOR_ROTATE_LEFT_OP:
363
240
      out << "(_ rotate_left "
364
240
          << n.getConst<BitVectorRotateLeft>().d_rotateLeftAmount << ")";
365
240
      break;
366
272
    case kind::BITVECTOR_ROTATE_RIGHT_OP:
367
272
      out << "(_ rotate_right "
368
272
          << n.getConst<BitVectorRotateRight>().d_rotateRightAmount << ")";
369
272
      break;
370
275
    case kind::INT_TO_BITVECTOR_OP:
371
275
      out << "(_ int2bv " << n.getConst<IntToBitVector>().d_size << ")";
372
275
      break;
373
6
    case kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR_OP:
374
6
      out << "(_ to_fp "
375
6
          << n.getConst<FloatingPointToFPIEEEBitVector>()
376
12
                 .getSize()
377
6
                 .exponentWidth()
378
6
          << ' '
379
6
          << n.getConst<FloatingPointToFPIEEEBitVector>()
380
12
                 .getSize()
381
6
                 .significandWidth()
382
6
          << ")";
383
6
      break;
384
1
    case kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT_OP:
385
1
      out << "(_ to_fp "
386
1
          << n.getConst<FloatingPointToFPFloatingPoint>()
387
2
                 .getSize()
388
1
                 .exponentWidth()
389
1
          << ' '
390
1
          << n.getConst<FloatingPointToFPFloatingPoint>()
391
2
                 .getSize()
392
1
                 .significandWidth()
393
1
          << ")";
394
1
      break;
395
9
    case kind::FLOATINGPOINT_TO_FP_REAL_OP:
396
9
      out << "(_ to_fp "
397
18
          << n.getConst<FloatingPointToFPReal>().getSize().exponentWidth()
398
9
          << ' '
399
18
          << n.getConst<FloatingPointToFPReal>().getSize().significandWidth()
400
9
          << ")";
401
9
      break;
402
    case kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR_OP:
403
      out << "(_ to_fp "
404
          << n.getConst<FloatingPointToFPSignedBitVector>()
405
                 .getSize()
406
                 .exponentWidth()
407
          << ' '
408
          << n.getConst<FloatingPointToFPSignedBitVector>()
409
                 .getSize()
410
                 .significandWidth()
411
          << ")";
412
      break;
413
7
    case kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR_OP:
414
7
      out << "(_ to_fp_unsigned "
415
7
          << n.getConst<FloatingPointToFPUnsignedBitVector>()
416
14
                 .getSize()
417
7
                 .exponentWidth()
418
7
          << ' '
419
7
          << n.getConst<FloatingPointToFPUnsignedBitVector>()
420
14
                 .getSize()
421
7
                 .significandWidth()
422
7
          << ")";
423
7
      break;
424
71
    case kind::FLOATINGPOINT_TO_FP_GENERIC_OP:
425
71
      out << "(_ to_fp "
426
142
          << n.getConst<FloatingPointToFPGeneric>().getSize().exponentWidth()
427
71
          << ' '
428
142
          << n.getConst<FloatingPointToFPGeneric>().getSize().significandWidth()
429
71
          << ")";
430
71
      break;
431
    case kind::FLOATINGPOINT_TO_UBV_OP:
432
      out << "(_ fp.to_ubv "
433
          << n.getConst<FloatingPointToUBV>().d_bv_size.d_size << ")";
434
      break;
435
2
    case kind::FLOATINGPOINT_TO_SBV_OP:
436
2
      out << "(_ fp.to_sbv "
437
2
          << n.getConst<FloatingPointToSBV>().d_bv_size.d_size << ")";
438
2
      break;
439
    case kind::FLOATINGPOINT_TO_UBV_TOTAL_OP:
440
      out << "(_ fp.to_ubv_total "
441
          << n.getConst<FloatingPointToUBVTotal>().d_bv_size.d_size << ")";
442
      break;
443
    case kind::FLOATINGPOINT_TO_SBV_TOTAL_OP:
444
      out << "(_ fp.to_sbv_total "
445
          << n.getConst<FloatingPointToSBVTotal>().d_bv_size.d_size << ")";
446
      break;
447
7
    case kind::REGEXP_REPEAT_OP:
448
7
      out << "(_ re.^ " << n.getConst<RegExpRepeat>().d_repeatAmount << ")";
449
7
      break;
450
32
    case kind::REGEXP_LOOP_OP:
451
32
      out << "(_ re.loop " << n.getConst<RegExpLoop>().d_loopMinOcc << " "
452
32
          << n.getConst<RegExpLoop>().d_loopMaxOcc << ")";
453
32
      break;
454
8
    default:
455
      // fall back on whatever operator<< does on underlying type; we
456
      // might luck out and be SMT-LIB v2 compliant
457
8
      kind::metakind::NodeValueConstPrinter::toStream(out, n);
458
    }
459
460
625804
    return;
461
  }
462
463
4856395
  if(n.getKind() == kind::SORT_TYPE) {
464
30296
    string name;
465
15148
    if(n.getNumChildren() != 0) {
466
83
      out << '(';
467
    }
468
15148
    if(n.getAttribute(expr::VarNameAttr(), name)) {
469
15148
      out << cvc5::quoteSymbol(name);
470
    }
471
15148
    if(n.getNumChildren() != 0) {
472
173
      for(unsigned i = 0; i < n.getNumChildren(); ++i) {
473
90
	      out << ' ';
474
90
              toStream(out, n[i], toDepth);
475
      }
476
83
      out << ')';
477
    }
478
15148
    return;
479
  }
480
481
  // determine if we are printing out a type ascription, store the argument of
482
  // the type ascription into type_asc_arg.
483
4841247
  Kind k = n.getKind();
484
7081537
  Node type_asc_arg;
485
7081537
  TypeNode force_nt;
486
4841247
  if (k == kind::APPLY_TYPE_ASCRIPTION)
487
  {
488
60
    force_nt = n.getOperator().getConst<AscriptionType>().getType();
489
60
    type_asc_arg = n[0];
490
  }
491
4841187
  else if (k == kind::CAST_TO_REAL)
492
  {
493
1307
    force_nt = nm->realType();
494
1307
    type_asc_arg = n[0];
495
  }
496
4841247
  if (!type_asc_arg.isNull())
497
  {
498
1367
    if (force_nt.isReal())
499
    {
500
      // we prefer using (/ x 1) instead of (to_real x) here.
501
      // the reason is that (/ x 1) is SMT-LIB compliant when x is a constant
502
      // or the logic is non-linear, whereas (to_real x) is compliant when
503
      // the logic is mixed int/real. The former occurs more frequently.
504
1307
      bool is_int = force_nt.isInteger();
505
      // If constant rational, print as special case
506
1307
      if (type_asc_arg.getKind() == kind::CONST_RATIONAL)
507
      {
508
1307
        const Rational& r = type_asc_arg.getConst<Rational>();
509
1307
        toStreamRational(out, r, !is_int, d_variant);
510
      }
511
      else
512
      {
513
        out << "("
514
            << smtKindString(is_int ? kind::TO_INTEGER : kind::DIVISION,
515
                             d_variant)
516
            << " ";
517
        toStream(out, type_asc_arg, toDepth, lbind);
518
        if (!is_int)
519
        {
520
          out << " 1";
521
        }
522
        out << ")";
523
      }
524
    }
525
    else
526
    {
527
      // use type ascription
528
60
      out << "(as ";
529
60
      toStream(out, type_asc_arg, toDepth < 0 ? toDepth : toDepth - 1, lbind);
530
60
      out << " " << force_nt << ")";
531
    }
532
1367
    return;
533
  }
534
535
  // variable
536
4839880
  if (n.isVar())
537
  {
538
5152476
    string s;
539
2576238
    if (n.getAttribute(expr::VarNameAttr(), s))
540
    {
541
2571223
      out << cvc5::quoteSymbol(s);
542
    }
543
    else
544
    {
545
5015
      if (n.getKind() == kind::VARIABLE)
546
      {
547
        out << "var_";
548
      }
549
      else
550
      {
551
5015
        out << n.getKind() << '_';
552
      }
553
5015
      out << n.getId();
554
    }
555
2576238
    return;
556
  }
557
558
2263642
  bool stillNeedToPrintParams = true;
559
2263642
  bool forceBinary = false; // force N-ary to binary when outputing children
560
  // operator
561
2263642
  if (n.getNumChildren() != 0 && k != kind::CONSTRUCTOR_TYPE)
562
  {
563
2260392
    out << '(';
564
  }
565
2263642
  switch(k) {
566
    // builtin theory
567
1600
    case kind::FUNCTION_TYPE:
568
1600
      out << "->";
569
6443
      for (Node nc : n)
570
      {
571
4843
        out << " ";
572
4843
        toStream(out, nc, toDepth);
573
1600
      }
574
1600
      out << ")";
575
1600
      return;
576
484724
    case kind::SEXPR: break;
577
578
    // uf theory
579
108835
    case kind::APPLY_UF: break;
580
    // higher-order
581
341
    case kind::HO_APPLY:
582
341
      if (!options::flattenHOChains())
583
      {
584
341
        break;
585
      }
586
      // collapse "@" chains, i.e.
587
      //
588
      // ((a b) c) --> (a b c)
589
      //
590
      // (((a b) ((c d) e)) f) --> (a b (c d e) f)
591
      {
592
        Node head = n;
593
        std::vector<Node> args;
594
        while (head.getKind() == kind::HO_APPLY)
595
        {
596
          args.insert(args.begin(), head[1]);
597
          head = head[0];
598
        }
599
        toStream(out, head, toDepth, lbind);
600
        for (unsigned i = 0, size = args.size(); i < size; ++i)
601
        {
602
          out << " ";
603
          toStream(out, args[i], toDepth, lbind);
604
        }
605
        out << ")";
606
      }
607
      return;
608
609
8
    case kind::MATCH:
610
8
      out << smtKindString(k, d_variant) << " ";
611
8
      toStream(out, n[0], toDepth, lbind);
612
8
      out << " (";
613
26
      for (size_t i = 1, nchild = n.getNumChildren(); i < nchild; i++)
614
      {
615
18
        if (i > 1)
616
        {
617
10
          out << " ";
618
        }
619
18
        toStream(out, n[i], toDepth, lbind);
620
8
      }
621
8
      out << "))";
622
8
      return;
623
6
    case kind::MATCH_BIND_CASE:
624
      // ignore the binder
625
6
      toStream(out, n[1], toDepth, lbind);
626
6
      out << " ";
627
6
      toStream(out, n[2], toDepth, lbind);
628
6
      out << ")";
629
6
      return;
630
12
    case kind::MATCH_CASE:
631
      // do nothing
632
12
      break;
633
634
    // arith theory
635
58
    case kind::IAND:
636
58
      out << "(_ iand " << n.getOperator().getConst<IntAnd>().d_size << ") ";
637
58
      stillNeedToPrintParams = false;
638
58
      break;
639
640
    case kind::DIVISIBLE:
641
      out << "(_ divisible " << n.getOperator().getConst<Divisible>().k << ")";
642
      stillNeedToPrintParams = false;
643
      break;
644
    case kind::INDEXED_ROOT_PREDICATE_OP:
645
    {
646
      const IndexedRootPredicate& irp = n.getConst<IndexedRootPredicate>();
647
      out << "(_ root_predicate " << irp.d_index << ")";
648
      break;
649
    }
650
651
  // string theory
652
39
  case kind::REGEXP_REPEAT:
653
  case kind::REGEXP_LOOP:
654
  {
655
39
    out << n.getOperator() << ' ';
656
39
    stillNeedToPrintParams = false;
657
39
    break;
658
  }
659
660
    // bv theory
661
10044
  case kind::BITVECTOR_CONCAT:
662
  case kind::BITVECTOR_AND:
663
  case kind::BITVECTOR_OR:
664
  case kind::BITVECTOR_XOR:
665
  case kind::BITVECTOR_MULT:
666
  case kind::BITVECTOR_ADD:
667
  {
668
10044
    out << smtKindString(k, d_variant) << " ";
669
10044
    forceBinary = true;
670
  }
671
10044
  break;
672
673
17151
  case kind::BITVECTOR_EXTRACT:
674
  case kind::BITVECTOR_REPEAT:
675
  case kind::BITVECTOR_ZERO_EXTEND:
676
  case kind::BITVECTOR_SIGN_EXTEND:
677
  case kind::BITVECTOR_ROTATE_LEFT:
678
  case kind::BITVECTOR_ROTATE_RIGHT:
679
  case kind::INT_TO_BITVECTOR:
680
17151
    toStream(out, n.getOperator(), toDepth, nullptr);
681
17151
    out << ' ';
682
17151
    stillNeedToPrintParams = false;
683
17151
    break;
684
  case kind::BITVECTOR_BITOF:
685
    out << "(_ bitOf " << n.getOperator().getConst<BitVectorBitOf>().d_bitIndex
686
        << ") ";
687
    stillNeedToPrintParams = false;
688
    break;
689
690
  // sets
691
520
  case kind::SINGLETON:
692
  {
693
520
    out << smtKindString(k, d_variant) << " ";
694
1040
    TypeNode elemType = n.getType().getSetElementType();
695
520
    toStreamCastToType(
696
        out, n[0], toDepth < 0 ? toDepth : toDepth - 1, elemType);
697
520
    out << ")";
698
520
    return;
699
  }
700
  break;
701
81
  case kind::UNIVERSE_SET:out << "(as univset " << n.getType() << ")";break;
702
703
  // bags
704
92
  case kind::MK_BAG:
705
  {
706
    // print (bag (mkBag_op Real) 1 3) as (bag 1.0 3)
707
92
    out << smtKindString(k, d_variant) << " ";
708
184
    TypeNode elemType = n.getType().getBagElementType();
709
92
    toStreamCastToType(
710
        out, n[0], toDepth < 0 ? toDepth : toDepth - 1, elemType);
711
92
    out << " " << n[1] << ")";
712
92
    return;
713
  }
714
715
  // fp theory
716
96
  case kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR:
717
  case kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT:
718
  case kind::FLOATINGPOINT_TO_FP_REAL:
719
  case kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR:
720
  case kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR:
721
  case kind::FLOATINGPOINT_TO_FP_GENERIC:
722
  case kind::FLOATINGPOINT_TO_UBV:
723
  case kind::FLOATINGPOINT_TO_SBV:
724
96
    out << n.getOperator() << ' ';
725
96
    stillNeedToPrintParams = false;
726
96
    break;
727
728
11496
  case kind::APPLY_CONSTRUCTOR:
729
  {
730
11496
    const DType& dt = DType::datatypeOf(n.getOperator());
731
11496
    if (dt.isTuple())
732
    {
733
1404
      stillNeedToPrintParams = false;
734
1404
      out << "tuple" << ( dt[0].getNumArgs()==0 ? "" : " ");
735
    }
736
11496
    break;
737
  }
738
10
  case kind::TUPLE_PROJECT:
739
  {
740
20
    TupleProjectOp op = n.getOperator().getConst<TupleProjectOp>();
741
10
    if (op.getIndices().empty())
742
    {
743
      // e.g. (tuple_project tuple)
744
2
      out << "project " << n[0] << ")";
745
    }
746
    else
747
    {
748
      // e.g. ((_ tuple_project 2 4 4) tuple)
749
8
      out << "(_ tuple_project" << op << ") " << n[0] << ")";
750
    }
751
10
    return;
752
  }
753
52
  case kind::CONSTRUCTOR_TYPE:
754
  {
755
52
    out << n[n.getNumChildren()-1];
756
52
    return;
757
    break;
758
  }
759
3207
  case kind::APPLY_SELECTOR:
760
  {
761
6414
    Node op = n.getOperator();
762
3207
    const DType& dt = DType::datatypeOf(op);
763
3207
    if (dt.isTuple())
764
    {
765
46
      stillNeedToPrintParams = false;
766
46
      out << "(_ tuple_select " << DType::indexOf(op) << ") ";
767
3207
    }
768
  }
769
3207
  break;
770
875
  case kind::APPLY_TESTER:
771
  {
772
875
    stillNeedToPrintParams = false;
773
1750
    Node op = n.getOperator();
774
875
    size_t cindex = DType::indexOf(op);
775
875
    const DType& dt = DType::datatypeOf(op);
776
875
    out << "(_ is ";
777
1750
    toStream(
778
1750
        out, dt[cindex].getConstructor(), toDepth < 0 ? toDepth : toDepth - 1);
779
1750
    out << ") ";
780
  }
781
875
  break;
782
37
  case kind::APPLY_UPDATER:
783
  {
784
37
    stillNeedToPrintParams = false;
785
74
    Node op = n.getOperator();
786
37
    size_t index = DType::indexOf(op);
787
37
    const DType& dt = DType::datatypeOf(op);
788
37
    size_t cindex = DType::cindexOf(op);
789
37
    if (dt.isTuple())
790
    {
791
10
      stillNeedToPrintParams = false;
792
10
      out << "(_ tuple_update " << DType::indexOf(op) << ") ";
793
    }
794
    else
795
    {
796
27
      out << "(_ update ";
797
54
      toStream(out,
798
54
               dt[cindex][index].getSelector(),
799
               toDepth < 0 ? toDepth : toDepth - 1);
800
27
      out << ") ";
801
37
    }
802
  }
803
37
  break;
804
758
  case kind::APPLY_SELECTOR_TOTAL:
805
758
  case kind::PARAMETRIC_DATATYPE: break;
806
807
  // separation logic
808
116
  case kind::SEP_NIL:
809
116
    out << "(as sep.nil " << n.getType() << ")";
810
116
    break;
811
812
  // cardinality constraints.
813
27
  case kind::CARDINALITY_CONSTRAINT:
814
27
    out << "(_ fmf.card ";
815
27
    out << n.getOperator().getConst<CardinalityConstraint>().getType();
816
27
    out << " ";
817
27
    out << n.getOperator().getConst<CardinalityConstraint>().getUpperBound();
818
27
    out << ")";
819
27
    return;
820
821
    // quantifiers
822
9756
  case kind::FORALL:
823
  case kind::EXISTS:
824
  case kind::LAMBDA:
825
  case kind::WITNESS:
826
  {
827
9756
    out << smtKindString(k, d_variant) << " ";
828
    // do not letify the bound variable list
829
9756
    toStream(out, n[0], toDepth, nullptr);
830
9756
    out << " ";
831
19512
    std::stringstream annot;
832
9756
    if (n.getNumChildren() == 3)
833
    {
834
1217
      annot << " ";
835
2526
      for (const Node& nc : n[2])
836
      {
837
1309
        if (nc.getKind() == kind::INST_PATTERN)
838
        {
839
1132
          out << "(! ";
840
1132
          annot << ":pattern ";
841
1132
          toStream(annot, nc, toDepth, nullptr);
842
1132
          annot << ") ";
843
        }
844
177
        else if (nc.getKind() == kind::INST_NO_PATTERN)
845
        {
846
          out << "(! ";
847
          annot << ":no-pattern ";
848
          toStream(annot, nc, toDepth, nullptr);
849
          annot << ") ";
850
        }
851
      }
852
    }
853
    // Use a fresh let binder, since using existing let symbols may violate
854
    // scoping issues for let-bound variables, see explanation in let_binding.h.
855
9756
    size_t dag = lbind == nullptr ? 0 : lbind->getThreshold()-1;
856
9756
    toStream(out, n[1], toDepth - 1, dag);
857
9756
    out << annot.str() << ")";
858
9756
    return;
859
    break;
860
  }
861
11281
  case kind::BOUND_VAR_LIST:
862
  {
863
    // the left parenthesis is already printed (before the switch)
864
32520
    for (TNode::iterator i = n.begin(), iend = n.end(); i != iend;)
865
    {
866
21239
      out << '(';
867
21239
      toStream(out, *i, toDepth < 0 ? toDepth : toDepth - 1);
868
21239
      out << ' ';
869
21239
      out << (*i).getType();
870
21239
      out << ')';
871
21239
      if (++i != iend)
872
      {
873
9958
        out << ' ';
874
      }
875
    }
876
11281
    out << ')';
877
11281
    return;
878
  }
879
1132
  case kind::INST_PATTERN:
880
  case kind::INST_NO_PATTERN:
881
1132
  case kind::INST_PATTERN_LIST: break;
882
1601288
  default:
883
    // by default, print the kind using the smtKindString utility
884
1601288
    out << smtKindString(k, d_variant) << " ";
885
1601288
    break;
886
  }
887
2240290
  if( n.getMetaKind() == kind::metakind::PARAMETERIZED &&
888
      stillNeedToPrintParams ) {
889
122759
    if(toDepth != 0) {
890
245518
      toStream(
891
245518
          out, n.getOperator(), toDepth < 0 ? toDepth : toDepth - 1, lbind);
892
    } else {
893
      out << "(...)";
894
    }
895
122759
    if(n.getNumChildren() > 0) {
896
120808
      out << ' ';
897
    }
898
  }
899
4480580
  stringstream parens;
900
901
7009464
  for(size_t i = 0, c = 1; i < n.getNumChildren(); ) {
902
4769174
    if(toDepth != 0) {
903
4769174
      toStream(out, n[i], toDepth < 0 ? toDepth : toDepth - c, lbind);
904
    } else {
905
      out << "(...)";
906
    }
907
4769174
    if(++i < n.getNumChildren()) {
908
2532055
      if(forceBinary && i < n.getNumChildren() - 1) {
909
        // not going to work properly for parameterized kinds!
910
592
        Assert(n.getMetaKind() != kind::metakind::PARAMETERIZED);
911
592
        out << " (" << smtKindString(n.getKind(), d_variant) << ' ';
912
592
        parens << ')';
913
592
        ++c;
914
      } else {
915
2531463
        out << ' ';
916
      }
917
    }
918
  }
919
2240290
  if (n.getNumChildren() != 0)
920
  {
921
2237119
    out << parens.str() << ')';
922
  }
923
}
924
925
646
void Smt2Printer::toStreamCastToType(std::ostream& out,
926
                                     TNode n,
927
                                     int toDepth,
928
                                     TypeNode tn) const
929
{
930
1292
  Node nasc;
931
646
  if (n.getType().isInteger() && !tn.isInteger())
932
  {
933
7
    Assert(tn.isReal());
934
    // probably due to subtyping integers and reals, cast it
935
7
    nasc = NodeManager::currentNM()->mkNode(kind::CAST_TO_REAL, n);
936
  }
937
  else
938
  {
939
639
    nasc = n;
940
  }
941
646
  toStream(out, nasc, toDepth);
942
646
}
943
944
1622305
std::string Smt2Printer::smtKindString(Kind k, Variant v)
945
{
946
1622305
  switch(k) {
947
    // builtin theory
948
198812
  case kind::EQUAL: return "=";
949
8126
  case kind::DISTINCT: return "distinct";
950
  case kind::SEXPR: break;
951
952
    // bool theory
953
265427
  case kind::NOT: return "not";
954
270282
  case kind::AND: return "and";
955
54718
  case kind::IMPLIES: return "=>";
956
344668
  case kind::OR: return "or";
957
5804
  case kind::XOR: return "xor";
958
55011
  case kind::ITE: return "ite";
959
960
    // uf theory
961
  case kind::APPLY_UF: break;
962
963
1299
  case kind::LAMBDA: return "lambda";
964
8
  case kind::MATCH: return "match";
965
2
  case kind::WITNESS: return "witness";
966
967
  // arith theory
968
77895
  case kind::PLUS: return "+";
969
106052
  case kind::MULT:
970
106052
  case kind::NONLINEAR_MULT: return "*";
971
  case kind::IAND: return "iand";
972
21
  case kind::POW2: return "int.pow2";
973
66
  case kind::EXPONENTIAL: return "exp";
974
338
  case kind::SINE: return "sin";
975
36
  case kind::COSINE: return "cos";
976
4
  case kind::TANGENT: return "tan";
977
2
  case kind::COSECANT: return "csc";
978
2
  case kind::SECANT: return "sec";
979
4
  case kind::COTANGENT: return "cot";
980
2
  case kind::ARCSINE: return "arcsin";
981
2
  case kind::ARCCOSINE: return "arccos";
982
5
  case kind::ARCTANGENT: return "arctan";
983
  case kind::ARCCOSECANT: return "arccsc";
984
  case kind::ARCSECANT: return "arcsec";
985
  case kind::ARCCOTANGENT: return "arccot";
986
300
  case kind::PI: return "real.pi";
987
44
  case kind::SQRT: return "sqrt";
988
14966
  case kind::MINUS: return "-";
989
27367
  case kind::UMINUS: return "-";
990
30926
  case kind::LT: return "<";
991
8715
  case kind::LEQ: return "<=";
992
6361
  case kind::GT: return ">";
993
55079
  case kind::GEQ: return ">=";
994
1013
  case kind::DIVISION:
995
1013
  case kind::DIVISION_TOTAL: return "/";
996
290
  case kind::INTS_DIVISION_TOTAL:
997
290
  case kind::INTS_DIVISION: return "div";
998
117
  case kind::INTS_MODULUS_TOTAL:
999
117
  case kind::INTS_MODULUS: return "mod";
1000
6
  case kind::ABS: return "abs";
1001
129
  case kind::IS_INTEGER: return "is_int";
1002
31
  case kind::TO_INTEGER: return "to_int";
1003
26
  case kind::TO_REAL: return "to_real";
1004
15
  case kind::POW: return "^";
1005
1006
    // arrays theory
1007
1966
  case kind::SELECT: return "select";
1008
1272
  case kind::STORE: return "store";
1009
459
  case kind::ARRAY_TYPE: return "Array";
1010
  case kind::PARTIAL_SELECT_0: return "partial_select_0";
1011
  case kind::PARTIAL_SELECT_1: return "partial_select_1";
1012
26
  case kind::EQ_RANGE:
1013
26
    return "eqrange";
1014
1015
    // bv theory
1016
2259
  case kind::BITVECTOR_CONCAT: return "concat";
1017
1435
  case kind::BITVECTOR_AND: return "bvand";
1018
640
  case kind::BITVECTOR_OR: return "bvor";
1019
378
  case kind::BITVECTOR_XOR: return "bvxor";
1020
1023
  case kind::BITVECTOR_NOT: return "bvnot";
1021
242
  case kind::BITVECTOR_NAND: return "bvnand";
1022
292
  case kind::BITVECTOR_NOR: return "bvnor";
1023
356
  case kind::BITVECTOR_XNOR: return "bvxnor";
1024
461
  case kind::BITVECTOR_COMP: return "bvcomp";
1025
2172
  case kind::BITVECTOR_MULT: return "bvmul";
1026
3752
  case kind::BITVECTOR_ADD: return "bvadd";
1027
474
  case kind::BITVECTOR_SUB: return "bvsub";
1028
754
  case kind::BITVECTOR_NEG: return "bvneg";
1029
209
  case kind::BITVECTOR_UDIV: return "bvudiv";
1030
115
  case kind::BITVECTOR_UREM: return "bvurem";
1031
82
  case kind::BITVECTOR_SDIV: return "bvsdiv";
1032
22
  case kind::BITVECTOR_SREM: return "bvsrem";
1033
46
  case kind::BITVECTOR_SMOD: return "bvsmod";
1034
886
  case kind::BITVECTOR_SHL: return "bvshl";
1035
861
  case kind::BITVECTOR_LSHR: return "bvlshr";
1036
416
  case kind::BITVECTOR_ASHR: return "bvashr";
1037
3218
  case kind::BITVECTOR_ULT: return "bvult";
1038
1942
  case kind::BITVECTOR_ULE: return "bvule";
1039
2107
  case kind::BITVECTOR_UGT: return "bvugt";
1040
1956
  case kind::BITVECTOR_UGE: return "bvuge";
1041
4468
  case kind::BITVECTOR_SLT: return "bvslt";
1042
2040
  case kind::BITVECTOR_SLE: return "bvsle";
1043
2594
  case kind::BITVECTOR_SGT: return "bvsgt";
1044
2982
  case kind::BITVECTOR_SGE: return "bvsge";
1045
154
  case kind::BITVECTOR_TO_NAT: return "bv2nat";
1046
  case kind::BITVECTOR_REDOR: return "bvredor";
1047
  case kind::BITVECTOR_REDAND: return "bvredand";
1048
1049
  case kind::BITVECTOR_EXTRACT: return "extract";
1050
  case kind::BITVECTOR_REPEAT: return "repeat";
1051
  case kind::BITVECTOR_ZERO_EXTEND: return "zero_extend";
1052
  case kind::BITVECTOR_SIGN_EXTEND: return "sign_extend";
1053
  case kind::BITVECTOR_ROTATE_LEFT: return "rotate_left";
1054
  case kind::BITVECTOR_ROTATE_RIGHT: return "rotate_right";
1055
  case kind::INT_TO_BITVECTOR: return "int2bv";
1056
  case kind::BITVECTOR_BB_TERM: return "bbT";
1057
1058
  // datatypes theory
1059
  case kind::APPLY_TESTER: return "is";
1060
  case kind::APPLY_UPDATER: return "update";
1061
1062
  // set theory
1063
504
  case kind::UNION: return "union";
1064
133
  case kind::INTERSECTION: return "intersection";
1065
109
  case kind::SETMINUS: return "setminus";
1066
98
  case kind::SUBSET: return "subset";
1067
1605
  case kind::MEMBER: return "member";
1068
751
  case kind::SET_TYPE: return "Set";
1069
520
  case kind::SINGLETON: return "singleton";
1070
22
  case kind::INSERT: return "insert";
1071
18
  case kind::COMPLEMENT: return "complement";
1072
391
  case kind::CARD: return "card";
1073
13
  case kind::COMPREHENSION: return "comprehension";
1074
26
  case kind::CHOOSE: return "choose";
1075
13
  case kind::IS_SINGLETON: return "is_singleton";
1076
279
  case kind::JOIN: return "join";
1077
31
  case kind::PRODUCT: return "product";
1078
72
  case kind::TRANSPOSE: return "transpose";
1079
49
  case kind::TCLOSURE: return "tclosure";
1080
7
  case kind::IDEN: return "iden";
1081
49
  case kind::JOIN_IMAGE: return "join_image";
1082
1083
  // bag theory
1084
21
  case kind::BAG_TYPE: return "Bag";
1085
22
  case kind::UNION_MAX: return "union_max";
1086
27
  case kind::UNION_DISJOINT: return "union_disjoint";
1087
11
  case kind::INTERSECTION_MIN: return "intersection_min";
1088
8
  case kind::DIFFERENCE_SUBTRACT: return "difference_subtract";
1089
8
  case kind::DIFFERENCE_REMOVE: return "difference_remove";
1090
6
  case kind::SUBBAG: return "subbag";
1091
71
  case kind::BAG_COUNT: return "bag.count";
1092
12
  case kind::DUPLICATE_REMOVAL: return "duplicate_removal";
1093
92
  case kind::MK_BAG: return "bag";
1094
  case kind::BAG_CARD: return "bag.card";
1095
  case kind::BAG_CHOOSE: return "bag.choose";
1096
  case kind::BAG_IS_SINGLETON: return "bag.is_singleton";
1097
  case kind::BAG_FROM_SET: return "bag.from_set";
1098
  case kind::BAG_TO_SET: return "bag.to_set";
1099
8
  case kind::BAG_MAP: return "bag.map";
1100
1101
    // fp theory
1102
16
  case kind::FLOATINGPOINT_FP: return "fp";
1103
6
  case kind::FLOATINGPOINT_EQ: return "fp.eq";
1104
13
  case kind::FLOATINGPOINT_ABS: return "fp.abs";
1105
31
  case kind::FLOATINGPOINT_NEG: return "fp.neg";
1106
72
  case kind::FLOATINGPOINT_ADD: return "fp.add";
1107
17
  case kind::FLOATINGPOINT_SUB: return "fp.sub";
1108
46
  case kind::FLOATINGPOINT_MULT: return "fp.mul";
1109
21
  case kind::FLOATINGPOINT_DIV: return "fp.div";
1110
  case kind::FLOATINGPOINT_FMA: return "fp.fma";
1111
1
  case kind::FLOATINGPOINT_SQRT: return "fp.sqrt";
1112
17
  case kind::FLOATINGPOINT_REM: return "fp.rem";
1113
8
  case kind::FLOATINGPOINT_RTI: return "fp.roundToIntegral";
1114
  case kind::FLOATINGPOINT_MIN: return "fp.min";
1115
  case kind::FLOATINGPOINT_MAX: return "fp.max";
1116
  case kind::FLOATINGPOINT_MIN_TOTAL: return "fp.min_total";
1117
  case kind::FLOATINGPOINT_MAX_TOTAL: return "fp.max_total";
1118
1119
140
  case kind::FLOATINGPOINT_LEQ: return "fp.leq";
1120
78
  case kind::FLOATINGPOINT_LT: return "fp.lt";
1121
10
  case kind::FLOATINGPOINT_GEQ: return "fp.geq";
1122
4
  case kind::FLOATINGPOINT_GT: return "fp.gt";
1123
1124
1
  case kind::FLOATINGPOINT_ISN: return "fp.isNormal";
1125
4
  case kind::FLOATINGPOINT_ISSN: return "fp.isSubnormal";
1126
2
  case kind::FLOATINGPOINT_ISZ: return "fp.isZero";
1127
  case kind::FLOATINGPOINT_ISINF: return "fp.isInfinite";
1128
19
  case kind::FLOATINGPOINT_ISNAN: return "fp.isNaN";
1129
3
  case kind::FLOATINGPOINT_ISNEG: return "fp.isNegative";
1130
3
  case kind::FLOATINGPOINT_ISPOS: return "fp.isPositive";
1131
1132
  case kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR: return "to_fp";
1133
  case kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT: return "to_fp";
1134
  case kind::FLOATINGPOINT_TO_FP_REAL: return "to_fp";
1135
  case kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR: return "to_fp";
1136
  case kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR: return "to_fp_unsigned";
1137
  case kind::FLOATINGPOINT_TO_FP_GENERIC: return "to_fp_unsigned";
1138
  case kind::FLOATINGPOINT_TO_UBV: return "fp.to_ubv";
1139
  case kind::FLOATINGPOINT_TO_UBV_TOTAL: return "fp.to_ubv_total";
1140
  case kind::FLOATINGPOINT_TO_SBV: return "fp.to_sbv";
1141
  case kind::FLOATINGPOINT_TO_SBV_TOTAL: return "fp.to_sbv_total";
1142
14
  case kind::FLOATINGPOINT_TO_REAL: return "fp.to_real";
1143
  case kind::FLOATINGPOINT_TO_REAL_TOTAL: return "fp.to_real_total";
1144
1145
  case kind::FLOATINGPOINT_COMPONENT_NAN: return "NAN";
1146
  case kind::FLOATINGPOINT_COMPONENT_INF: return "INF";
1147
  case kind::FLOATINGPOINT_COMPONENT_ZERO: return "ZERO";
1148
  case kind::FLOATINGPOINT_COMPONENT_SIGN: return "SIGN";
1149
  case kind::FLOATINGPOINT_COMPONENT_EXPONENT: return "EXPONENT";
1150
  case kind::FLOATINGPOINT_COMPONENT_SIGNIFICAND: return "SIGNIFICAND";
1151
  case kind::ROUNDINGMODE_BITBLAST:
1152
    return "RMBITBLAST";
1153
1154
  //string theory
1155
1303
  case kind::STRING_CONCAT: return "str.++";
1156
15800
  case kind::STRING_LENGTH: return "str.len";
1157
3685
  case kind::STRING_SUBSTR: return "str.substr" ;
1158
29
  case kind::STRING_UPDATE: return "str.update";
1159
466
  case kind::STRING_CONTAINS: return "str.contains";
1160
86
  case kind::STRING_CHARAT: return "str.at" ;
1161
495
  case kind::STRING_INDEXOF: return "str.indexof";
1162
57
  case kind::STRING_INDEXOF_RE: return "str.indexof_re";
1163
2080
  case kind::STRING_REPLACE: return "str.replace";
1164
46
  case kind::STRING_REPLACE_ALL: return "str.replace_all";
1165
100
  case kind::STRING_REPLACE_RE: return "str.replace_re";
1166
29
  case kind::STRING_REPLACE_RE_ALL: return "str.replace_re_all";
1167
18
  case kind::STRING_TOLOWER: return "str.tolower";
1168
7
  case kind::STRING_TOUPPER: return "str.toupper";
1169
55
  case kind::STRING_REV: return "str.rev";
1170
82
  case kind::STRING_PREFIX: return "str.prefixof" ;
1171
28
  case kind::STRING_SUFFIX: return "str.suffixof" ;
1172
28
  case kind::STRING_LEQ: return "str.<=";
1173
16
  case kind::STRING_LT: return "str.<";
1174
45
  case kind::STRING_FROM_CODE: return "str.from_code";
1175
2319
  case kind::STRING_TO_CODE: return "str.to_code";
1176
8
  case Kind::STRING_IS_DIGIT: return "str.is_digit";
1177
176
  case kind::STRING_ITOS: return "str.from_int";
1178
72
  case kind::STRING_STOI: return "str.to_int";
1179
597
  case kind::STRING_IN_REGEXP: return "str.in_re";
1180
1178
  case kind::STRING_TO_REGEXP: return "str.to_re";
1181
77
  case kind::REGEXP_EMPTY: return "re.none";
1182
610
  case kind::REGEXP_SIGMA: return "re.allchar";
1183
631
  case kind::REGEXP_CONCAT: return "re.++";
1184
238
  case kind::REGEXP_UNION: return "re.union";
1185
22
  case kind::REGEXP_INTER: return "re.inter";
1186
552
  case kind::REGEXP_STAR: return "re.*";
1187
35
  case kind::REGEXP_PLUS: return "re.+";
1188
31
  case kind::REGEXP_OPT: return "re.opt";
1189
272
  case kind::REGEXP_RANGE: return "re.range";
1190
  case kind::REGEXP_REPEAT: return "re.^";
1191
  case kind::REGEXP_LOOP: return "re.loop";
1192
41
  case kind::REGEXP_COMPLEMENT: return "re.comp";
1193
22
  case kind::REGEXP_DIFF: return "re.diff";
1194
42
  case kind::SEQUENCE_TYPE: return "Seq";
1195
113
  case kind::SEQ_UNIT: return "seq.unit";
1196
103
  case kind::SEQ_NTH: return "seq.nth";
1197
1198
  //sep theory
1199
68
  case kind::SEP_STAR: return "sep";
1200
152
  case kind::SEP_PTO: return "pto";
1201
5
  case kind::SEP_WAND: return "wand";
1202
30
  case kind::SEP_EMP: return "sep.emp";
1203
1204
  // quantifiers
1205
7279
  case kind::FORALL: return "forall";
1206
1176
  case kind::EXISTS: return "exists";
1207
1208
469
  default:
1209
    ; /* fall through */
1210
  }
1211
1212
  // fall back on however the kind prints itself; this probably
1213
  // won't be SMT-LIB v2 compliant, but it will be clear from the
1214
  // output that support for the kind needs to be added here.
1215
  // no SMT way to print these
1216
469
  return kind::kindToString(k);
1217
}
1218
1219
452
void Smt2Printer::toStreamType(std::ostream& out, TypeNode tn) const
1220
{
1221
  // we currently must call TypeNode::toStream here.
1222
452
  tn.toStream(out, Language::LANG_SMTLIB_V2_6);
1223
452
}
1224
1225
template <class T>
1226
static bool tryToStream(std::ostream& out, const Command* c);
1227
template <class T>
1228
static bool tryToStream(std::ostream& out, const Command* c, Variant v);
1229
1230
template <class T>
1231
static bool tryToStream(std::ostream& out, const CommandStatus* s, Variant v);
1232
1233
224650
void Smt2Printer::toStream(std::ostream& out, const CommandStatus* s) const
1234
{
1235
449368
  if (tryToStream<CommandSuccess>(out, s, d_variant) ||
1236
88
      tryToStream<CommandFailure>(out, s, d_variant) ||
1237
24
      tryToStream<CommandRecoverableFailure>(out, s, d_variant) ||
1238
224654
      tryToStream<CommandUnsupported>(out, s, d_variant) ||
1239
      tryToStream<CommandInterrupted>(out, s, d_variant)) {
1240
224650
    return;
1241
  }
1242
1243
  out << "ERROR: don't know how to print a CommandStatus of class: "
1244
      << typeid(*s).name() << endl;
1245
1246
}/* Smt2Printer::toStream(CommandStatus*) */
1247
1248
12
void Smt2Printer::toStream(std::ostream& out, const UnsatCore& core) const
1249
{
1250
12
  out << "(" << std::endl;
1251
12
  if (core.useNames())
1252
  {
1253
    // use the names
1254
9
    const std::vector<std::string>& cnames = core.getCoreNames();
1255
28
    for (const std::string& cn : cnames)
1256
    {
1257
19
      out << cvc5::quoteSymbol(cn) << std::endl;
1258
    }
1259
  }
1260
  else
1261
  {
1262
    // otherwise, use the formulas
1263
6
    for (UnsatCore::const_iterator i = core.begin(); i != core.end(); ++i)
1264
    {
1265
3
      out << *i << endl;
1266
    }
1267
  }
1268
12
  out << ")" << endl;
1269
12
}/* Smt2Printer::toStream(UnsatCore, map<Expr, string>) */
1270
1271
29
void Smt2Printer::toStream(std::ostream& out, const smt::Model& m) const
1272
{
1273
  //print the model
1274
29
  out << "(" << endl;
1275
  // don't need to print approximations since they are built into choice
1276
  // functions in the values of variables.
1277
29
  this->Printer::toStream(out, m);
1278
29
  out << ")" << endl;
1279
  //print the heap model, if it exists
1280
58
  Node h, neq;
1281
29
  if (m.getHeapModel(h, neq))
1282
  {
1283
    // description of the heap+what nil is equal to fully describes model
1284
    out << "(heap" << endl;
1285
    out << h << endl;
1286
    out << neq << endl;
1287
    out << ")" << std::endl;
1288
  }
1289
29
}
1290
1291
6
void Smt2Printer::toStreamModelSort(std::ostream& out,
1292
                                    TypeNode tn,
1293
                                    const std::vector<Node>& elements) const
1294
{
1295
6
  if (!tn.isSort())
1296
  {
1297
    out << "ERROR: don't know how to print non uninterpreted sort in model: "
1298
        << tn << std::endl;
1299
    return;
1300
  }
1301
  // print the cardinality
1302
6
  out << "; cardinality of " << tn << " is " << elements.size() << endl;
1303
12
  if (options::modelUninterpPrint()
1304
6
      == options::ModelUninterpPrintMode::DeclSortAndFun)
1305
  {
1306
    toStreamCmdDeclareType(out, tn);
1307
  }
1308
  // print the representatives
1309
14
  for (const Node& trn : elements)
1310
  {
1311
8
    if (trn.isVar())
1312
    {
1313
8
      if (options::modelUninterpPrint()
1314
              == options::ModelUninterpPrintMode::DeclSortAndFun
1315
4
          || options::modelUninterpPrint()
1316
                 == options::ModelUninterpPrintMode::DeclFun)
1317
      {
1318
2
        out << "(declare-fun " << trn << " () " << tn << ")" << endl;
1319
      }
1320
    }
1321
    else
1322
    {
1323
4
      out << "; rep: " << trn << endl;
1324
    }
1325
  }
1326
}
1327
1328
34
void Smt2Printer::toStreamModelTerm(std::ostream& out,
1329
                                    const Node& n,
1330
                                    const Node& value) const
1331
{
1332
34
  if (value.getKind() == kind::LAMBDA)
1333
  {
1334
6
    TypeNode rangeType = n.getType().getRangeType();
1335
3
    out << "(define-fun " << n << " " << value[0] << " " << rangeType << " ";
1336
    // call toStream and force its type to be proper
1337
3
    toStreamCastToType(out, value[1], -1, rangeType);
1338
3
    out << ")" << endl;
1339
  }
1340
  else
1341
  {
1342
31
    out << "(define-fun " << n << " () " << n.getType() << " ";
1343
    // call toStream and force its type to be proper
1344
31
    toStreamCastToType(out, value, -1, n.getType());
1345
31
    out << ")" << endl;
1346
  }
1347
34
}
1348
1349
11
void Smt2Printer::toStreamCmdAssert(std::ostream& out, Node n) const
1350
{
1351
11
  out << "(assert " << n << ')' << std::endl;
1352
11
}
1353
1354
void Smt2Printer::toStreamCmdPush(std::ostream& out) const
1355
{
1356
  out << "(push 1)" << std::endl;
1357
}
1358
1359
void Smt2Printer::toStreamCmdPop(std::ostream& out) const
1360
{
1361
  out << "(pop 1)" << std::endl;
1362
}
1363
1364
2
void Smt2Printer::toStreamCmdCheckSat(std::ostream& out) const
1365
{
1366
2
  out << "(check-sat)" << std::endl;
1367
2
}
1368
1369
2
void Smt2Printer::toStreamCmdCheckSatAssuming(
1370
    std::ostream& out, const std::vector<Node>& nodes) const
1371
{
1372
2
  out << "(check-sat-assuming ( ";
1373
2
  copy(nodes.begin(), nodes.end(), ostream_iterator<Node>(out, " "));
1374
2
  out << "))" << std::endl;
1375
2
}
1376
1377
void Smt2Printer::toStreamCmdQuery(std::ostream& out, Node n) const
1378
{
1379
  if (!n.isNull())
1380
  {
1381
    toStreamCmdCheckSatAssuming(out, {n});
1382
  }
1383
  else
1384
  {
1385
    toStreamCmdCheckSat(out);
1386
  }
1387
}
1388
1389
void Smt2Printer::toStreamCmdReset(std::ostream& out) const
1390
{
1391
  out << "(reset)" << std::endl;
1392
}
1393
1394
void Smt2Printer::toStreamCmdResetAssertions(std::ostream& out) const
1395
{
1396
  out << "(reset-assertions)" << std::endl;
1397
}
1398
1399
void Smt2Printer::toStreamCmdQuit(std::ostream& out) const
1400
{
1401
  out << "(exit)" << std::endl;
1402
}
1403
1404
void Smt2Printer::toStreamCmdCommandSequence(
1405
    std::ostream& out, const std::vector<Command*>& sequence) const
1406
{
1407
  for (Command* i : sequence)
1408
  {
1409
    out << *i;
1410
  }
1411
}
1412
1413
void Smt2Printer::toStreamCmdDeclarationSequence(
1414
    std::ostream& out, const std::vector<Command*>& sequence) const
1415
{
1416
  toStreamCmdCommandSequence(out, sequence);
1417
}
1418
1419
9
void Smt2Printer::toStreamCmdDeclareFunction(std::ostream& out,
1420
                                             const std::string& id,
1421
                                             TypeNode type) const
1422
{
1423
9
  out << "(declare-fun " << cvc5::quoteSymbol(id) << " (";
1424
9
  if (type.isFunction())
1425
  {
1426
    const vector<TypeNode> argTypes = type.getArgTypes();
1427
    if (argTypes.size() > 0)
1428
    {
1429
      copy(argTypes.begin(),
1430
           argTypes.end() - 1,
1431
           ostream_iterator<TypeNode>(out, " "));
1432
      out << argTypes.back();
1433
    }
1434
    type = type.getRangeType();
1435
  }
1436
1437
9
  out << ") " << type << ')' << std::endl;
1438
9
}
1439
1440
void Smt2Printer::toStreamCmdDeclarePool(
1441
    std::ostream& out,
1442
    const std::string& id,
1443
    TypeNode type,
1444
    const std::vector<Node>& initValue) const
1445
{
1446
  out << "(declare-pool " << cvc5::quoteSymbol(id) << ' ' << type << " (";
1447
  for (size_t i = 0, n = initValue.size(); i < n; ++i)
1448
  {
1449
    if (i != 0) {
1450
      out << ' ';
1451
    }
1452
    out << initValue[i];
1453
  }
1454
  out << "))" << std::endl;
1455
}
1456
1457
13
void Smt2Printer::toStreamCmdDefineFunction(std::ostream& out,
1458
                                            const std::string& id,
1459
                                            const std::vector<Node>& formals,
1460
                                            TypeNode range,
1461
                                            Node formula) const
1462
{
1463
13
  out << "(define-fun " << id << " (";
1464
13
  if (!formals.empty())
1465
  {
1466
11
    vector<Node>::const_iterator i = formals.cbegin();
1467
    for (;;)
1468
    {
1469
25
      out << "(" << (*i) << " " << (*i).getType() << ")";
1470
18
      ++i;
1471
18
      if (i != formals.cend())
1472
      {
1473
7
        out << " ";
1474
      }
1475
      else
1476
      {
1477
11
        break;
1478
      }
1479
    }
1480
  }
1481
13
  out << ") " << range << ' ' << formula << ')' << std::endl;
1482
13
}
1483
1484
void Smt2Printer::toStreamCmdDefineFunctionRec(
1485
    std::ostream& out,
1486
    const std::vector<Node>& funcs,
1487
    const std::vector<std::vector<Node>>& formals,
1488
    const std::vector<Node>& formulas) const
1489
{
1490
  out << "(define-fun";
1491
  if (funcs.size() > 1)
1492
  {
1493
    out << "s";
1494
  }
1495
  out << "-rec ";
1496
  if (funcs.size() > 1)
1497
  {
1498
    out << "(";
1499
  }
1500
  for (unsigned i = 0, size = funcs.size(); i < size; i++)
1501
  {
1502
    if (funcs.size() > 1)
1503
    {
1504
      if (i > 0)
1505
      {
1506
        out << " ";
1507
      }
1508
      out << "(";
1509
    }
1510
    out << funcs[i] << " (";
1511
    // print its type signature
1512
    vector<Node>::const_iterator itf = formals[i].cbegin();
1513
    while (itf != formals[i].cend())
1514
    {
1515
      out << "(" << (*itf) << " " << (*itf).getType() << ")";
1516
      ++itf;
1517
      if (itf != formals[i].cend())
1518
      {
1519
        out << " ";
1520
      }
1521
    }
1522
    TypeNode type = funcs[i].getType();
1523
    if (type.isFunction())
1524
    {
1525
      type = type.getRangeType();
1526
    }
1527
    out << ") " << type;
1528
    if (funcs.size() > 1)
1529
    {
1530
      out << ")";
1531
    }
1532
  }
1533
  if (funcs.size() > 1)
1534
  {
1535
    out << ") (";
1536
  }
1537
  else
1538
  {
1539
    out << " ";
1540
  }
1541
  for (unsigned i = 0, size = formulas.size(); i < size; i++)
1542
  {
1543
    if (i > 0)
1544
    {
1545
      out << " ";
1546
    }
1547
    out << formulas[i];
1548
  }
1549
  if (funcs.size() > 1)
1550
  {
1551
    out << ")";
1552
  }
1553
  out << ")" << std::endl;
1554
}
1555
1556
void Smt2Printer::toStreamCmdDeclareType(std::ostream& out,
1557
                                         TypeNode type) const
1558
{
1559
  Assert(type.isSort() || type.isSortConstructor());
1560
  size_t arity = type.isSortConstructor() ? type.getSortConstructorArity() : 0;
1561
  out << "(declare-sort " << type << " " << arity << ")" << std::endl;
1562
}
1563
1564
void Smt2Printer::toStreamCmdDefineType(std::ostream& out,
1565
                                        const std::string& id,
1566
                                        const std::vector<TypeNode>& params,
1567
                                        TypeNode t) const
1568
{
1569
  out << "(define-sort " << cvc5::quoteSymbol(id) << " (";
1570
  if (params.size() > 0)
1571
  {
1572
    copy(
1573
        params.begin(), params.end() - 1, ostream_iterator<TypeNode>(out, " "));
1574
    out << params.back();
1575
  }
1576
  out << ") " << t << ")" << std::endl;
1577
}
1578
1579
void Smt2Printer::toStreamCmdSimplify(std::ostream& out, Node n) const
1580
{
1581
  out << "(simplify " << n << ')' << std::endl;
1582
}
1583
1584
void Smt2Printer::toStreamCmdGetValue(std::ostream& out,
1585
                                      const std::vector<Node>& nodes) const
1586
{
1587
  out << "(get-value ( ";
1588
  copy(nodes.begin(), nodes.end(), ostream_iterator<Node>(out, " "));
1589
  out << "))" << std::endl;
1590
}
1591
1592
void Smt2Printer::toStreamCmdGetModel(std::ostream& out) const
1593
{
1594
  out << "(get-model)" << std::endl;
1595
}
1596
1597
void Smt2Printer::toStreamCmdBlockModel(std::ostream& out) const
1598
{
1599
  out << "(block-model)" << std::endl;
1600
}
1601
1602
void Smt2Printer::toStreamCmdBlockModelValues(
1603
    std::ostream& out, const std::vector<Node>& nodes) const
1604
{
1605
  out << "(block-model-values (";
1606
  for (size_t i = 0, n = nodes.size(); i < n; ++i)
1607
  {
1608
    if (i != 0)
1609
    {
1610
      out << ' ';
1611
    }
1612
    out << nodes[i];
1613
  }
1614
  out << "))" << std::endl;
1615
}
1616
1617
void Smt2Printer::toStreamCmdGetAssignment(std::ostream& out) const
1618
{
1619
  out << "(get-assignment)" << std::endl;
1620
}
1621
1622
void Smt2Printer::toStreamCmdGetAssertions(std::ostream& out) const
1623
{
1624
  out << "(get-assertions)" << std::endl;
1625
}
1626
1627
void Smt2Printer::toStreamCmdGetProof(std::ostream& out) const
1628
{
1629
  out << "(get-proof)" << std::endl;
1630
}
1631
1632
void Smt2Printer::toStreamCmdGetUnsatAssumptions(std::ostream& out) const
1633
{
1634
  out << "(get-unsat-assumptions)" << std::endl;
1635
}
1636
1637
void Smt2Printer::toStreamCmdGetUnsatCore(std::ostream& out) const
1638
{
1639
  out << "(get-unsat-core)" << std::endl;
1640
}
1641
1642
void Smt2Printer::toStreamCmdGetDifficulty(std::ostream& out) const
1643
{
1644
  out << "(get-difficulty)" << std::endl;
1645
}
1646
1647
7
void Smt2Printer::toStreamCmdSetBenchmarkLogic(std::ostream& out,
1648
                                               const std::string& logic) const
1649
{
1650
7
  out << "(set-logic " << logic << ')' << std::endl;
1651
7
}
1652
1653
void Smt2Printer::toStreamCmdSetInfo(std::ostream& out,
1654
                                     const std::string& flag,
1655
                                     const std::string& value) const
1656
{
1657
  out << "(set-info :" << flag << " " << value << ")" << std::endl;
1658
}
1659
1660
11
void Smt2Printer::toStreamCmdGetInfo(std::ostream& out,
1661
                                     const std::string& flag) const
1662
{
1663
11
  out << "(get-info :" << flag << ')' << std::endl;
1664
11
}
1665
1666
4
void Smt2Printer::toStreamCmdSetOption(std::ostream& out,
1667
                                       const std::string& flag,
1668
                                       const std::string& value) const
1669
{
1670
4
  out << "(set-option :" << flag << ' ' << value << ')' << std::endl;
1671
4
}
1672
1673
void Smt2Printer::toStreamCmdGetOption(std::ostream& out,
1674
                                       const std::string& flag) const
1675
{
1676
  out << "(get-option :" << flag << ')' << std::endl;
1677
}
1678
1679
2
void Smt2Printer::toStream(std::ostream& out, const DType& dt) const
1680
{
1681
6
  for (size_t i = 0, ncons = dt.getNumConstructors(); i < ncons; i++)
1682
  {
1683
4
    const DTypeConstructor& cons = dt[i];
1684
4
    if (i != 0)
1685
    {
1686
2
      out << " ";
1687
    }
1688
4
    out << "(" << cvc5::quoteSymbol(cons.getName());
1689
6
    for (size_t j = 0, nargs = cons.getNumArgs(); j < nargs; j++)
1690
    {
1691
2
      const DTypeSelector& arg = cons[j];
1692
2
      out << " (" << arg.getSelector() << " " << arg.getRangeType() << ")";
1693
    }
1694
4
    out << ")";
1695
  }
1696
2
}
1697
1698
2
void Smt2Printer::toStreamCmdDatatypeDeclaration(
1699
    std::ostream& out, const std::vector<TypeNode>& datatypes) const
1700
{
1701
2
  Assert(!datatypes.empty());
1702
2
  Assert(datatypes[0].isDatatype());
1703
2
  const DType& d0 = datatypes[0].getDType();
1704
2
  if (d0.isTuple())
1705
  {
1706
    // not necessary to print tuples
1707
    Assert(datatypes.size() == 1);
1708
    return;
1709
  }
1710
2
  out << "(declare-";
1711
2
  if (d0.isCodatatype())
1712
  {
1713
    out << "co";
1714
  }
1715
2
  out << "datatypes";
1716
2
  out << " (";
1717
4
  for (const TypeNode& t : datatypes)
1718
  {
1719
2
    Assert(t.isDatatype());
1720
2
    const DType& d = t.getDType();
1721
2
    out << "(" << cvc5::quoteSymbol(d.getName());
1722
2
    out << " " << d.getNumParameters() << ")";
1723
  }
1724
2
  out << ") (";
1725
4
  for (const TypeNode& t : datatypes)
1726
  {
1727
2
    Assert(t.isDatatype());
1728
2
    const DType& d = t.getDType();
1729
2
    if (d.isParametric())
1730
    {
1731
      out << "(par (";
1732
      for (unsigned p = 0, nparam = d.getNumParameters(); p < nparam; p++)
1733
      {
1734
        out << (p > 0 ? " " : "") << d.getParameter(p);
1735
      }
1736
      out << ")";
1737
    }
1738
2
    out << "(";
1739
2
    toStream(out, d);
1740
2
    out << ")";
1741
2
    if (d.isParametric())
1742
    {
1743
      out << ")";
1744
    }
1745
  }
1746
2
  out << ")";
1747
2
  out << ")" << std::endl;
1748
}
1749
1750
void Smt2Printer::toStreamCmdDeclareHeap(std::ostream& out,
1751
                                         TypeNode locType,
1752
                                         TypeNode dataType) const
1753
{
1754
  out << "(declare-heap (" << locType << " " << dataType << "))" << std::endl;
1755
}
1756
1757
void Smt2Printer::toStreamCmdEmpty(std::ostream& out,
1758
                                   const std::string& name) const
1759
{
1760
  out << std::endl;
1761
}
1762
1763
void Smt2Printer::toStreamCmdEcho(std::ostream& out,
1764
                                  const std::string& output) const
1765
{
1766
  out << "(echo " << cvc5::quoteString(output) << ')' << std::endl;
1767
}
1768
1769
/*
1770
   --------------------------------------------------------------------------
1771
    Handling SyGuS commands
1772
   --------------------------------------------------------------------------
1773
*/
1774
1775
3
std::string Smt2Printer::sygusGrammarString(const TypeNode& t)
1776
{
1777
6
  std::stringstream out;
1778
3
  if (!t.isNull() && t.isDatatype() && t.getDType().isSygus())
1779
  {
1780
6
    std::stringstream types_predecl, types_list;
1781
6
    std::set<TypeNode> grammarTypes;
1782
6
    std::list<TypeNode> typesToPrint;
1783
3
    grammarTypes.insert(t);
1784
3
    typesToPrint.push_back(t);
1785
3
    NodeManager* nm = NodeManager::currentNM();
1786
    // for each datatype in grammar
1787
    //   name
1788
    //   sygus type
1789
    //   constructors in order
1790
2
    do
1791
    {
1792
10
      TypeNode curr = typesToPrint.front();
1793
5
      typesToPrint.pop_front();
1794
5
      Assert(curr.isDatatype() && curr.getDType().isSygus());
1795
5
      const DType& dt = curr.getDType();
1796
5
      types_list << '(' << dt.getName() << ' ' << dt.getSygusType() << " (";
1797
5
      types_predecl << '(' << dt.getName() << ' ' << dt.getSygusType() << ") ";
1798
5
      if (dt.getSygusAllowConst())
1799
      {
1800
4
        types_list << "(Constant " << dt.getSygusType() << ") ";
1801
      }
1802
34
      for (size_t i = 0, ncons = dt.getNumConstructors(); i < ncons; i++)
1803
      {
1804
29
        const DTypeConstructor& cons = dt[i];
1805
        // make a sygus term
1806
58
        std::vector<Node> cchildren;
1807
29
        cchildren.push_back(cons.getConstructor());
1808
61
        for (size_t j = 0, nargs = cons.getNumArgs(); j < nargs; j++)
1809
        {
1810
64
          TypeNode argType = cons[j].getRangeType();
1811
64
          std::stringstream ss;
1812
32
          ss << argType;
1813
64
          Node bv = nm->mkBoundVar(ss.str(), argType);
1814
32
          cchildren.push_back(bv);
1815
          // if fresh type, store it for later processing
1816
32
          if (grammarTypes.insert(argType).second)
1817
          {
1818
2
            typesToPrint.push_back(argType);
1819
          }
1820
        }
1821
58
        Node consToPrint = nm->mkNode(kind::APPLY_CONSTRUCTOR, cchildren);
1822
        // now, print it using the conversion to builtin with external
1823
87
        types_list << theory::datatypes::utils::sygusToBuiltin(consToPrint,
1824
58
                                                               true);
1825
29
        types_list << ' ';
1826
      }
1827
5
      types_list << "))\n";
1828
5
    } while (!typesToPrint.empty());
1829
1830
3
    out << "\n(" << types_predecl.str() << ")\n(" << types_list.str() << ')';
1831
  }
1832
6
  return out.str();
1833
}
1834
1835
2
void Smt2Printer::toStreamCmdSynthFun(std::ostream& out,
1836
                                      Node f,
1837
                                      const std::vector<Node>& vars,
1838
                                      bool isInv,
1839
                                      TypeNode sygusType) const
1840
{
1841
2
  out << '(' << (isInv ? "synth-inv " : "synth-fun ") << f << ' ' << '(';
1842
2
  if (!vars.empty())
1843
  {
1844
    // print variable list
1845
2
    std::vector<Node>::const_iterator i = vars.cbegin(), i_end = vars.cend();
1846
2
    out << '(' << *i << ' ' << i->getType() << ')';
1847
2
    ++i;
1848
2
    while (i != i_end)
1849
    {
1850
      out << " (" << *i << ' ' << i->getType() << ')';
1851
      ++i;
1852
    }
1853
  }
1854
2
  out << ')';
1855
  // if not invariant-to-synthesize, print return type
1856
2
  if (!isInv)
1857
  {
1858
2
    TypeNode ftn = f.getType();
1859
2
    TypeNode range = ftn.isFunction() ? ftn.getRangeType() : ftn;
1860
1
    out << ' ' << range;
1861
  }
1862
2
  out << '\n';
1863
  // print grammar, if any
1864
2
  if (!sygusType.isNull())
1865
  {
1866
1
    out << sygusGrammarString(sygusType);
1867
  }
1868
2
  out << ')' << std::endl;
1869
2
}
1870
1871
1
void Smt2Printer::toStreamCmdDeclareVar(std::ostream& out,
1872
                                        Node var,
1873
                                        TypeNode type) const
1874
{
1875
1
  out << "(declare-var " << var << ' ' << type << ')' << std::endl;
1876
1
}
1877
1878
1
void Smt2Printer::toStreamCmdConstraint(std::ostream& out, Node n) const
1879
{
1880
1
  out << "(constraint " << n << ')' << std::endl;
1881
1
}
1882
1883
void Smt2Printer::toStreamCmdAssume(std::ostream& out, Node n) const
1884
{
1885
  out << "(assume " << n << ')' << std::endl;
1886
}
1887
1888
1
void Smt2Printer::toStreamCmdInvConstraint(
1889
    std::ostream& out, Node inv, Node pre, Node trans, Node post) const
1890
{
1891
2
  out << "(inv-constraint " << inv << ' ' << pre << ' ' << trans << ' ' << post
1892
1
      << ')' << std::endl;
1893
1
}
1894
1895
1
void Smt2Printer::toStreamCmdCheckSynth(std::ostream& out) const
1896
{
1897
1
  out << "(check-synth)" << std::endl;
1898
1
}
1899
1900
void Smt2Printer::toStreamCmdGetInterpol(std::ostream& out,
1901
                                         const std::string& name,
1902
                                         Node conj,
1903
                                         TypeNode sygusType) const
1904
{
1905
  out << "(get-interpol " << cvc5::quoteSymbol(name) << ' ' << conj;
1906
  if (!sygusType.isNull())
1907
  {
1908
    out << ' ' << sygusGrammarString(sygusType);
1909
  }
1910
  out << ')' << std::endl;
1911
}
1912
1913
void Smt2Printer::toStreamCmdGetAbduct(std::ostream& out,
1914
                                       const std::string& name,
1915
                                       Node conj,
1916
                                       TypeNode sygusType) const
1917
{
1918
  out << "(get-abduct ";
1919
  out << name << ' ';
1920
  out << conj << ' ';
1921
1922
  // print grammar, if any
1923
  if (!sygusType.isNull())
1924
  {
1925
    out << sygusGrammarString(sygusType);
1926
  }
1927
  out << ')' << std::endl;
1928
}
1929
1930
void Smt2Printer::toStreamCmdGetQuantifierElimination(std::ostream& out,
1931
                                                      Node n,
1932
                                                      bool doFull) const
1933
{
1934
  out << '(' << (doFull ? "get-qe" : "get-qe-disjunct") << ' ' << n << ')'
1935
      << std::endl;
1936
}
1937
1938
/*
1939
   --------------------------------------------------------------------------
1940
    End of Handling SyGuS commands
1941
   --------------------------------------------------------------------------
1942
*/
1943
1944
template <class T>
1945
static bool tryToStream(std::ostream& out, const Command* c)
1946
{
1947
  if(typeid(*c) == typeid(T)) {
1948
    toStream(out, dynamic_cast<const T*>(c));
1949
    return true;
1950
  }
1951
  return false;
1952
}
1953
1954
template <class T>
1955
static bool tryToStream(std::ostream& out, const Command* c, Variant v)
1956
{
1957
  if(typeid(*c) == typeid(T)) {
1958
    toStream(out, dynamic_cast<const T*>(c), v);
1959
    return true;
1960
  }
1961
  return false;
1962
}
1963
1964
224582
static void toStream(std::ostream& out, const CommandSuccess* s, Variant v)
1965
{
1966
224582
  if(Command::printsuccess::getPrintSuccess(out)) {
1967
18
    out << "success" << endl;
1968
  }
1969
224582
}
1970
1971
static void toStream(std::ostream& out, const CommandInterrupted* s, Variant v)
1972
{
1973
  out << "interrupted" << endl;
1974
}
1975
1976
4
static void toStream(std::ostream& out, const CommandUnsupported* s, Variant v)
1977
{
1978
#ifdef CVC5_COMPETITION_MODE
1979
  // if in competition mode, lie and say we're ok
1980
  // (we have nothing to lose by saying success, and everything to lose
1981
  // if we say "unsupported")
1982
  out << "success" << endl;
1983
#else  /* CVC5_COMPETITION_MODE */
1984
4
  out << "unsupported" << endl;
1985
#endif /* CVC5_COMPETITION_MODE */
1986
4
}
1987
1988
64
static void errorToStream(std::ostream& out, std::string message, Variant v)
1989
{
1990
64
  out << "(error " << cvc5::quoteString(message) << ')' << endl;
1991
64
}
1992
1993
48
static void toStream(std::ostream& out, const CommandFailure* s, Variant v) {
1994
48
  errorToStream(out, s->getMessage(), v);
1995
48
}
1996
1997
16
static void toStream(std::ostream& out, const CommandRecoverableFailure* s,
1998
                     Variant v) {
1999
16
  errorToStream(out, s->getMessage(), v);
2000
16
}
2001
2002
template <class T>
2003
224742
static bool tryToStream(std::ostream& out, const CommandStatus* s, Variant v)
2004
{
2005
224742
  if(typeid(*s) == typeid(T)) {
2006
224650
    toStream(out, dynamic_cast<const T*>(s), v);
2007
224650
    return true;
2008
  }
2009
92
  return false;
2010
}
2011
2012
}  // namespace smt2
2013
}  // namespace printer
2014
31137
}  // namespace cvc5