1 /******************************************************************************
2 * Top contributors (to current version):
3 * Andrew Reynolds, Morgan Deters, Abdalrhman Mohamed
5 * This file is part of the cvc5 project.
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 * ****************************************************************************
13 * The pretty-printer interface for the SMT2 output language.
16 #include "printer/smt2/smt2_printer.h"
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"
65 static void toStreamRational(std::ostream
& out
,
70 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.
98 Rational abs_r
= (-r
);
99 out
<< "(- " << abs_r
.getNumerator();
100 out
<< ") " << abs_r
.getDenominator();
104 out
<< r
.getNumerator();
105 out
<< ' ' << r
.getDenominator();
111 void Smt2Printer::toStream(std::ostream
& out
,
117 LetBinding
lbind(dag
+ 1);
118 toStreamWithLetify(out
, n
, toDepth
, &lbind
);
120 toStream(out
, n
, toDepth
);
124 void Smt2Printer::toStreamWithLetify(std::ostream
& out
,
127 LetBinding
* lbind
) const
129 if (lbind
== nullptr)
131 toStream(out
, n
, toDepth
);
134 std::stringstream cparen
;
135 std::vector
<Node
> letList
;
136 lbind
->letify(n
, letList
);
137 if (!letList
.empty())
139 std::map
<Node
, uint32_t>::const_iterator it
;
140 for (size_t i
= 0, nlets
= letList
.size(); i
< nlets
; i
++)
142 Node nl
= letList
[i
];
144 uint32_t id
= lbind
->getId(nl
);
145 out
<< "_let_" << id
<< " ";
146 Node nlc
= lbind
->convert(nl
, "_let_", false);
147 toStream(out
, nlc
, toDepth
, lbind
);
152 Node nc
= lbind
->convert(n
, "_let_");
153 // print the body, passing the lbind object
154 toStream(out
, nc
, toDepth
, lbind
);
159 void Smt2Printer::toStream(std::ostream
& out
,
162 LetBinding
* lbind
) const
165 if(n
.getKind() == kind::NULL_EXPR
) {
170 NodeManager
* nm
= NodeManager::currentNM();
172 if(n
.getMetaKind() == kind::metakind::CONSTANT
) {
173 switch(n
.getKind()) {
174 case kind::TYPE_CONSTANT
:
175 switch(n
.getConst
<TypeConstant
>()) {
176 case BOOLEAN_TYPE
: out
<< "Bool"; break;
177 case REAL_TYPE
: out
<< "Real"; break;
178 case INTEGER_TYPE
: out
<< "Int"; break;
179 case STRING_TYPE
: out
<< "String"; break;
180 case REGEXP_TYPE
: out
<< "RegLan"; break;
181 case ROUNDINGMODE_TYPE
: out
<< "RoundingMode"; break;
183 // fall back on whatever operator<< does on underlying type; we
184 // might luck out and be SMT-LIB v2 compliant
185 n
.constToStream(out
);
188 case kind::BITVECTOR_TYPE
:
189 out
<< "(_ BitVec " << n
.getConst
<BitVectorSize
>().d_size
<< ")";
191 case kind::FLOATINGPOINT_TYPE
:
192 out
<< "(_ FloatingPoint "
193 << n
.getConst
<FloatingPointSize
>().exponentWidth() << " "
194 << n
.getConst
<FloatingPointSize
>().significandWidth() << ")";
196 case kind::CONST_BITVECTOR
:
198 const BitVector
& bv
= n
.getConst
<BitVector
>();
199 if (options::bvPrintConstsAsIndexedSymbols())
201 out
<< "(_ bv" << bv
.getValue() << " " << bv
.getSize() << ")";
205 out
<< "#b" << bv
.toString();
209 case kind::CONST_FLOATINGPOINT
:
211 out
<< n
.getConst
<FloatingPoint
>().toString(
212 options::bvPrintConstsAsIndexedSymbols());
215 case kind::CONST_ROUNDINGMODE
:
216 switch (n
.getConst
<RoundingMode
>()) {
217 case RoundingMode::ROUND_NEAREST_TIES_TO_EVEN
:
218 out
<< "roundNearestTiesToEven";
220 case RoundingMode::ROUND_NEAREST_TIES_TO_AWAY
:
221 out
<< "roundNearestTiesToAway";
223 case RoundingMode::ROUND_TOWARD_POSITIVE
:
224 out
<< "roundTowardPositive";
226 case RoundingMode::ROUND_TOWARD_NEGATIVE
:
227 out
<< "roundTowardNegative";
229 case RoundingMode::ROUND_TOWARD_ZERO
: out
<< "roundTowardZero"; break;
231 Unreachable() << "Invalid value of rounding mode constant ("
232 << n
.getConst
<RoundingMode
>() << ")";
235 case kind::CONST_BOOLEAN
:
236 // the default would print "1" or "0" for bool, that's not correct
238 out
<< (n
.getConst
<bool>() ? "true" : "false");
241 out
<< smtKindString(n
.getConst
<Kind
>(), d_variant
);
243 case kind::CONST_RATIONAL
: {
244 const Rational
& r
= n
.getConst
<Rational
>();
245 toStreamRational(out
, r
, false, d_variant
);
249 case kind::CONST_STRING
: {
250 std::string s
= n
.getConst
<String
>().toString();
252 for(size_t i
= 0; i
< s
.size(); ++i
) {
263 case kind::CONST_SEQUENCE
:
265 const Sequence
& sn
= n
.getConst
<Sequence
>();
266 const std::vector
<Node
>& snvec
= sn
.getVec();
269 out
<< "(as seq.empty ";
270 toStreamType(out
, n
.getType());
273 else if (snvec
.size() > 1)
276 for (const Node
& snvc
: snvec
)
278 out
<< " (seq.unit " << snvc
<< ")";
284 out
<< "(seq.unit " << snvec
[0] << ")";
289 case kind::STORE_ALL
: {
290 ArrayStoreAll asa
= n
.getConst
<ArrayStoreAll
>();
291 out
<< "((as const ";
292 toStreamType(out
, asa
.getType());
293 out
<< ") " << asa
.getValue() << ")";
297 case kind::DATATYPE_TYPE
:
299 const DType
& dt
= (NodeManager::currentNM()->getDTypeForIndex(
300 n
.getConst
<DatatypeIndexConstant
>().getIndex()));
303 unsigned int nargs
= dt
[0].getNumArgs();
311 for (unsigned int i
= 0; i
< nargs
; i
++)
314 toStreamType(out
, dt
[0][i
].getRangeType());
321 out
<< cvc5::quoteSymbol(dt
.getName());
326 case kind::UNINTERPRETED_CONSTANT
: {
327 const UninterpretedConstant
& uc
= n
.getConst
<UninterpretedConstant
>();
328 std::stringstream ss
;
329 ss
<< "(as @" << uc
<< " " << n
.getType() << ")";
333 case kind::SET_EMPTY
:
334 out
<< "(as set.empty ";
335 toStreamType(out
, n
.getConst
<EmptySet
>().getType());
339 case kind::BAG_EMPTY
:
340 out
<< "(as bag.empty ";
341 toStreamType(out
, n
.getConst
<EmptyBag
>().getType());
344 case kind::BITVECTOR_EXTRACT_OP
:
346 BitVectorExtract p
= n
.getConst
<BitVectorExtract
>();
347 out
<< "(_ extract " << p
.d_high
<< ' ' << p
.d_low
<< ")";
350 case kind::BITVECTOR_REPEAT_OP
:
351 out
<< "(_ repeat " << n
.getConst
<BitVectorRepeat
>().d_repeatAmount
354 case kind::BITVECTOR_ZERO_EXTEND_OP
:
355 out
<< "(_ zero_extend "
356 << n
.getConst
<BitVectorZeroExtend
>().d_zeroExtendAmount
<< ")";
358 case kind::BITVECTOR_SIGN_EXTEND_OP
:
359 out
<< "(_ sign_extend "
360 << n
.getConst
<BitVectorSignExtend
>().d_signExtendAmount
<< ")";
362 case kind::BITVECTOR_ROTATE_LEFT_OP
:
363 out
<< "(_ rotate_left "
364 << n
.getConst
<BitVectorRotateLeft
>().d_rotateLeftAmount
<< ")";
366 case kind::BITVECTOR_ROTATE_RIGHT_OP
:
367 out
<< "(_ rotate_right "
368 << n
.getConst
<BitVectorRotateRight
>().d_rotateRightAmount
<< ")";
370 case kind::INT_TO_BITVECTOR_OP
:
371 out
<< "(_ int2bv " << n
.getConst
<IntToBitVector
>().d_size
<< ")";
373 case kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR_OP
:
375 << n
.getConst
<FloatingPointToFPIEEEBitVector
>()
379 << n
.getConst
<FloatingPointToFPIEEEBitVector
>()
384 case kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT_OP
:
386 << n
.getConst
<FloatingPointToFPFloatingPoint
>()
390 << n
.getConst
<FloatingPointToFPFloatingPoint
>()
395 case kind::FLOATINGPOINT_TO_FP_REAL_OP
:
397 << n
.getConst
<FloatingPointToFPReal
>().getSize().exponentWidth()
399 << n
.getConst
<FloatingPointToFPReal
>().getSize().significandWidth()
402 case kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR_OP
:
404 << n
.getConst
<FloatingPointToFPSignedBitVector
>()
408 << n
.getConst
<FloatingPointToFPSignedBitVector
>()
413 case kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR_OP
:
414 out
<< "(_ to_fp_unsigned "
415 << n
.getConst
<FloatingPointToFPUnsignedBitVector
>()
419 << n
.getConst
<FloatingPointToFPUnsignedBitVector
>()
424 case kind::FLOATINGPOINT_TO_FP_GENERIC_OP
:
426 << n
.getConst
<FloatingPointToFPGeneric
>().getSize().exponentWidth()
428 << n
.getConst
<FloatingPointToFPGeneric
>().getSize().significandWidth()
431 case kind::FLOATINGPOINT_TO_UBV_OP
:
432 out
<< "(_ fp.to_ubv "
433 << n
.getConst
<FloatingPointToUBV
>().d_bv_size
.d_size
<< ")";
435 case kind::FLOATINGPOINT_TO_SBV_OP
:
436 out
<< "(_ fp.to_sbv "
437 << n
.getConst
<FloatingPointToSBV
>().d_bv_size
.d_size
<< ")";
439 case kind::FLOATINGPOINT_TO_UBV_TOTAL_OP
:
440 out
<< "(_ fp.to_ubv_total "
441 << n
.getConst
<FloatingPointToUBVTotal
>().d_bv_size
.d_size
<< ")";
443 case kind::FLOATINGPOINT_TO_SBV_TOTAL_OP
:
444 out
<< "(_ fp.to_sbv_total "
445 << n
.getConst
<FloatingPointToSBVTotal
>().d_bv_size
.d_size
<< ")";
447 case kind::REGEXP_REPEAT_OP
:
448 out
<< "(_ re.^ " << n
.getConst
<RegExpRepeat
>().d_repeatAmount
<< ")";
450 case kind::REGEXP_LOOP_OP
:
451 out
<< "(_ re.loop " << n
.getConst
<RegExpLoop
>().d_loopMinOcc
<< " "
452 << n
.getConst
<RegExpLoop
>().d_loopMaxOcc
<< ")";
455 // fall back on whatever operator<< does on underlying type; we
456 // might luck out and be SMT-LIB v2 compliant
457 n
.constToStream(out
);
463 if(n
.getKind() == kind::SORT_TYPE
) {
465 if(n
.getNumChildren() != 0) {
468 if(n
.getAttribute(expr::VarNameAttr(), name
)) {
469 out
<< cvc5::quoteSymbol(name
);
471 if(n
.getNumChildren() != 0) {
472 for(unsigned i
= 0; i
< n
.getNumChildren(); ++i
) {
474 toStream(out
, n
[i
], toDepth
);
481 // determine if we are printing out a type ascription, store the argument of
482 // the type ascription into type_asc_arg.
483 Kind k
= n
.getKind();
486 if (k
== kind::APPLY_TYPE_ASCRIPTION
)
488 force_nt
= n
.getOperator().getConst
<AscriptionType
>().getType();
491 else if (k
== kind::CAST_TO_REAL
)
493 force_nt
= nm
->realType();
496 if (!type_asc_arg
.isNull())
498 if (force_nt
.isRealOrInt())
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 bool is_int
= force_nt
.isInteger();
505 // If constant rational, print as special case
506 if (type_asc_arg
.getKind() == kind::CONST_RATIONAL
)
508 const Rational
& r
= type_asc_arg
.getConst
<Rational
>();
509 toStreamRational(out
, r
, !is_int
, d_variant
);
514 << smtKindString(is_int
? kind::TO_INTEGER
: kind::DIVISION
,
517 toStream(out
, type_asc_arg
, toDepth
, lbind
);
527 // use type ascription
529 toStream(out
, type_asc_arg
, toDepth
< 0 ? toDepth
: toDepth
- 1, lbind
);
530 out
<< " " << force_nt
<< ")";
539 if (n
.getAttribute(expr::VarNameAttr(), s
))
541 out
<< cvc5::quoteSymbol(s
);
545 if (n
.getKind() == kind::VARIABLE
)
551 out
<< n
.getKind() << '_';
558 bool stillNeedToPrintParams
= true;
559 bool forceBinary
= false; // force N-ary to binary when outputing children
561 if (n
.getNumChildren() != 0 && k
!= kind::CONSTRUCTOR_TYPE
)
567 case kind::FUNCTION_TYPE
:
572 toStream(out
, nc
, toDepth
);
576 case kind::SEXPR
: break;
579 case kind::APPLY_UF
: break;
582 if (!options::flattenHOChains())
586 // collapse "@" chains, i.e.
588 // ((a b) c) --> (a b c)
590 // (((a b) ((c d) e)) f) --> (a b (c d e) f)
593 std::vector
<Node
> args
;
594 while (head
.getKind() == kind::HO_APPLY
)
596 args
.insert(args
.begin(), head
[1]);
599 toStream(out
, head
, toDepth
, lbind
);
600 for (unsigned i
= 0, size
= args
.size(); i
< size
; ++i
)
603 toStream(out
, args
[i
], toDepth
, lbind
);
610 out
<< smtKindString(k
, d_variant
) << " ";
611 toStream(out
, n
[0], toDepth
, lbind
);
613 for (size_t i
= 1, nchild
= n
.getNumChildren(); i
< nchild
; i
++)
619 toStream(out
, n
[i
], toDepth
, lbind
);
623 case kind::MATCH_BIND_CASE
:
625 toStream(out
, n
[1], toDepth
, lbind
);
627 toStream(out
, n
[2], toDepth
, lbind
);
630 case kind::MATCH_CASE
:
636 out
<< "(_ iand " << n
.getOperator().getConst
<IntAnd
>().d_size
<< ") ";
637 stillNeedToPrintParams
= false;
640 case kind::DIVISIBLE
:
641 out
<< "(_ divisible " << n
.getOperator().getConst
<Divisible
>().k
<< ")";
642 stillNeedToPrintParams
= false;
644 case kind::INDEXED_ROOT_PREDICATE_OP
:
646 const IndexedRootPredicate
& irp
= n
.getConst
<IndexedRootPredicate
>();
647 out
<< "(_ root_predicate " << irp
.d_index
<< ")";
652 case kind::REGEXP_REPEAT
:
653 case kind::REGEXP_LOOP
:
655 out
<< n
.getOperator() << ' ';
656 stillNeedToPrintParams
= false;
661 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
:
668 out
<< smtKindString(k
, d_variant
) << " ";
673 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 toStream(out
, n
.getOperator(), toDepth
, nullptr);
682 stillNeedToPrintParams
= false;
684 case kind::BITVECTOR_BITOF
:
685 out
<< "(_ bitOf " << n
.getOperator().getConst
<BitVectorBitOf
>().d_bitIndex
687 stillNeedToPrintParams
= false;
691 case kind::SET_SINGLETON
:
693 out
<< smtKindString(k
, d_variant
) << " ";
694 TypeNode elemType
= n
.getType().getSetElementType();
696 out
, n
[0], toDepth
< 0 ? toDepth
: toDepth
- 1, elemType
);
701 case kind::SET_UNIVERSE
: out
<< "(as set.universe " << n
.getType() << ")"; break;
706 // print (bag (BAG_MAKE_OP Real) 1 3) as (bag 1.0 3)
707 out
<< smtKindString(k
, d_variant
) << " ";
708 TypeNode elemType
= n
.getType().getBagElementType();
710 out
, n
[0], toDepth
< 0 ? toDepth
: toDepth
- 1, elemType
);
711 out
<< " " << n
[1] << ")";
716 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 out
<< n
.getOperator() << ' ';
725 stillNeedToPrintParams
= false;
728 case kind::APPLY_CONSTRUCTOR
:
730 const DType
& dt
= DType::datatypeOf(n
.getOperator());
733 stillNeedToPrintParams
= false;
734 out
<< "tuple" << ( dt
[0].getNumArgs()==0 ? "" : " ");
738 case kind::TUPLE_PROJECT
:
740 TupleProjectOp op
= n
.getOperator().getConst
<TupleProjectOp
>();
741 if (op
.getIndices().empty())
743 // e.g. (tuple_project tuple)
744 out
<< "project " << n
[0] << ")";
748 // e.g. ((_ tuple_project 2 4 4) tuple)
749 out
<< "(_ tuple_project" << op
<< ") " << n
[0] << ")";
753 case kind::CONSTRUCTOR_TYPE
:
755 out
<< n
[n
.getNumChildren()-1];
759 case kind::APPLY_SELECTOR
:
761 Node op
= n
.getOperator();
762 const DType
& dt
= DType::datatypeOf(op
);
765 stillNeedToPrintParams
= false;
766 out
<< "(_ tuple_select " << DType::indexOf(op
) << ") ";
770 case kind::APPLY_TESTER
:
772 stillNeedToPrintParams
= false;
773 Node op
= n
.getOperator();
774 size_t cindex
= DType::indexOf(op
);
775 const DType
& dt
= DType::datatypeOf(op
);
778 out
, dt
[cindex
].getConstructor(), toDepth
< 0 ? toDepth
: toDepth
- 1);
782 case kind::APPLY_UPDATER
:
784 stillNeedToPrintParams
= false;
785 Node op
= n
.getOperator();
786 size_t index
= DType::indexOf(op
);
787 const DType
& dt
= DType::datatypeOf(op
);
788 size_t cindex
= DType::cindexOf(op
);
791 stillNeedToPrintParams
= false;
792 out
<< "(_ tuple_update " << DType::indexOf(op
) << ") ";
798 dt
[cindex
][index
].getSelector(),
799 toDepth
< 0 ? toDepth
: toDepth
- 1);
804 case kind::APPLY_SELECTOR_TOTAL
:
805 case kind::PARAMETRIC_DATATYPE
: break;
809 out
<< "(as sep.nil " << n
.getType() << ")";
812 // cardinality constraints.
813 case kind::CARDINALITY_CONSTRAINT
:
814 out
<< "(_ fmf.card ";
815 out
<< n
.getOperator().getConst
<CardinalityConstraint
>().getType();
817 out
<< n
.getOperator().getConst
<CardinalityConstraint
>().getUpperBound();
827 out
<< smtKindString(k
, d_variant
) << " ";
828 // do not letify the bound variable list
829 toStream(out
, n
[0], toDepth
, nullptr);
831 std::stringstream annot
;
832 if (n
.getNumChildren() == 3)
835 for (const Node
& nc
: n
[2])
837 if (nc
.getKind() == kind::INST_PATTERN
)
840 annot
<< ":pattern ";
841 toStream(annot
, nc
, toDepth
, nullptr);
844 else if (nc
.getKind() == kind::INST_NO_PATTERN
)
847 annot
<< ":no-pattern ";
848 toStream(annot
, nc
, toDepth
, nullptr);
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 size_t dag
= lbind
== nullptr ? 0 : lbind
->getThreshold()-1;
856 toStream(out
, n
[1], toDepth
- 1, dag
);
857 out
<< annot
.str() << ")";
861 case kind::BOUND_VAR_LIST
:
863 // the left parenthesis is already printed (before the switch)
864 for (TNode::iterator i
= n
.begin(), iend
= n
.end(); i
!= iend
;)
867 toStream(out
, *i
, toDepth
< 0 ? toDepth
: toDepth
- 1);
869 out
<< (*i
).getType();
879 case kind::INST_PATTERN
:
880 case kind::INST_NO_PATTERN
:
881 case kind::INST_PATTERN_LIST
: break;
883 // by default, print the kind using the smtKindString utility
884 out
<< smtKindString(k
, d_variant
) << " ";
887 if( n
.getMetaKind() == kind::metakind::PARAMETERIZED
&&
888 stillNeedToPrintParams
) {
891 out
, n
.getOperator(), toDepth
< 0 ? toDepth
: toDepth
- 1, lbind
);
895 if(n
.getNumChildren() > 0) {
901 for(size_t i
= 0, c
= 1; i
< n
.getNumChildren(); ) {
903 toStream(out
, n
[i
], toDepth
< 0 ? toDepth
: toDepth
- c
, lbind
);
907 if(++i
< n
.getNumChildren()) {
908 if(forceBinary
&& i
< n
.getNumChildren() - 1) {
909 // not going to work properly for parameterized kinds!
910 Assert(n
.getMetaKind() != kind::metakind::PARAMETERIZED
);
911 out
<< " (" << smtKindString(n
.getKind(), d_variant
) << ' ';
919 if (n
.getNumChildren() != 0)
921 out
<< parens
.str() << ')';
925 void Smt2Printer::toStreamCastToType(std::ostream
& out
,
931 if (n
.getType().isInteger() && !tn
.isInteger())
934 // probably due to subtyping integers and reals, cast it
935 nasc
= NodeManager::currentNM()->mkNode(kind::CAST_TO_REAL
, n
);
941 toStream(out
, nasc
, toDepth
);
944 std::string
Smt2Printer::smtKindString(Kind k
, Variant v
)
948 case kind::EQUAL
: return "=";
949 case kind::DISTINCT
: return "distinct";
950 case kind::SEXPR
: break;
953 case kind::NOT
: return "not";
954 case kind::AND
: return "and";
955 case kind::IMPLIES
: return "=>";
956 case kind::OR
: return "or";
957 case kind::XOR
: return "xor";
958 case kind::ITE
: return "ite";
961 case kind::APPLY_UF
: break;
963 case kind::LAMBDA
: return "lambda";
964 case kind::MATCH
: return "match";
965 case kind::WITNESS
: return "witness";
968 case kind::PLUS
: return "+";
970 case kind::NONLINEAR_MULT
: return "*";
971 case kind::IAND
: return "iand";
972 case kind::POW2
: return "int.pow2";
973 case kind::EXPONENTIAL
: return "exp";
974 case kind::SINE
: return "sin";
975 case kind::COSINE
: return "cos";
976 case kind::TANGENT
: return "tan";
977 case kind::COSECANT
: return "csc";
978 case kind::SECANT
: return "sec";
979 case kind::COTANGENT
: return "cot";
980 case kind::ARCSINE
: return "arcsin";
981 case kind::ARCCOSINE
: return "arccos";
982 case kind::ARCTANGENT
: return "arctan";
983 case kind::ARCCOSECANT
: return "arccsc";
984 case kind::ARCSECANT
: return "arcsec";
985 case kind::ARCCOTANGENT
: return "arccot";
986 case kind::PI
: return "real.pi";
987 case kind::SQRT
: return "sqrt";
988 case kind::MINUS
: return "-";
989 case kind::UMINUS
: return "-";
990 case kind::LT
: return "<";
991 case kind::LEQ
: return "<=";
992 case kind::GT
: return ">";
993 case kind::GEQ
: return ">=";
995 case kind::DIVISION_TOTAL
: return "/";
996 case kind::INTS_DIVISION_TOTAL
:
997 case kind::INTS_DIVISION
: return "div";
998 case kind::INTS_MODULUS_TOTAL
:
999 case kind::INTS_MODULUS
: return "mod";
1000 case kind::ABS
: return "abs";
1001 case kind::IS_INTEGER
: return "is_int";
1002 case kind::TO_INTEGER
: return "to_int";
1003 case kind::TO_REAL
: return "to_real";
1004 case kind::POW
: return "^";
1007 case kind::SELECT
: return "select";
1008 case kind::STORE
: return "store";
1009 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 case kind::EQ_RANGE
:
1016 case kind::BITVECTOR_CONCAT
: return "concat";
1017 case kind::BITVECTOR_AND
: return "bvand";
1018 case kind::BITVECTOR_OR
: return "bvor";
1019 case kind::BITVECTOR_XOR
: return "bvxor";
1020 case kind::BITVECTOR_NOT
: return "bvnot";
1021 case kind::BITVECTOR_NAND
: return "bvnand";
1022 case kind::BITVECTOR_NOR
: return "bvnor";
1023 case kind::BITVECTOR_XNOR
: return "bvxnor";
1024 case kind::BITVECTOR_COMP
: return "bvcomp";
1025 case kind::BITVECTOR_MULT
: return "bvmul";
1026 case kind::BITVECTOR_ADD
: return "bvadd";
1027 case kind::BITVECTOR_SUB
: return "bvsub";
1028 case kind::BITVECTOR_NEG
: return "bvneg";
1029 case kind::BITVECTOR_UDIV
: return "bvudiv";
1030 case kind::BITVECTOR_UREM
: return "bvurem";
1031 case kind::BITVECTOR_SDIV
: return "bvsdiv";
1032 case kind::BITVECTOR_SREM
: return "bvsrem";
1033 case kind::BITVECTOR_SMOD
: return "bvsmod";
1034 case kind::BITVECTOR_SHL
: return "bvshl";
1035 case kind::BITVECTOR_LSHR
: return "bvlshr";
1036 case kind::BITVECTOR_ASHR
: return "bvashr";
1037 case kind::BITVECTOR_ULT
: return "bvult";
1038 case kind::BITVECTOR_ULE
: return "bvule";
1039 case kind::BITVECTOR_UGT
: return "bvugt";
1040 case kind::BITVECTOR_UGE
: return "bvuge";
1041 case kind::BITVECTOR_SLT
: return "bvslt";
1042 case kind::BITVECTOR_SLE
: return "bvsle";
1043 case kind::BITVECTOR_SGT
: return "bvsgt";
1044 case kind::BITVECTOR_SGE
: return "bvsge";
1045 case kind::BITVECTOR_TO_NAT
: return "bv2nat";
1046 case kind::BITVECTOR_REDOR
: return "bvredor";
1047 case kind::BITVECTOR_REDAND
: return "bvredand";
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";
1059 case kind::APPLY_TESTER
: return "is";
1060 case kind::APPLY_UPDATER
: return "update";
1063 case kind::SET_UNION
: return "set.union";
1064 case kind::SET_INTER
: return "set.inter";
1065 case kind::SET_MINUS
: return "set.minus";
1066 case kind::SET_SUBSET
: return "set.subset";
1067 case kind::SET_MEMBER
: return "set.member";
1068 case kind::SET_TYPE
: return "Set";
1069 case kind::SET_SINGLETON
: return "set.singleton";
1070 case kind::SET_INSERT
: return "set.insert";
1071 case kind::SET_COMPLEMENT
: return "set.complement";
1072 case kind::SET_CARD
: return "set.card";
1073 case kind::SET_COMPREHENSION
: return "set.comprehension";
1074 case kind::SET_CHOOSE
: return "set.choose";
1075 case kind::SET_IS_SINGLETON
: return "set.is_singleton";
1076 case kind::SET_MAP
: return "set.map";
1077 case kind::RELATION_JOIN
: return "rel.join";
1078 case kind::RELATION_PRODUCT
: return "rel.product";
1079 case kind::RELATION_TRANSPOSE
: return "rel.transpose";
1080 case kind::RELATION_TCLOSURE
: return "rel.tclosure";
1081 case kind::RELATION_IDEN
: return "rel.iden";
1082 case kind::RELATION_JOIN_IMAGE
: return "rel.join_image";
1085 case kind::BAG_TYPE
: return "Bag";
1086 case kind::BAG_UNION_MAX
: return "bag.union_max";
1087 case kind::BAG_UNION_DISJOINT
: return "bag.union_disjoint";
1088 case kind::BAG_INTER_MIN
: return "bag.inter_min";
1089 case kind::BAG_DIFFERENCE_SUBTRACT
: return "bag.difference_subtract";
1090 case kind::BAG_DIFFERENCE_REMOVE
: return "bag.difference_remove";
1091 case kind::BAG_SUBBAG
: return "bag.subbag";
1092 case kind::BAG_COUNT
: return "bag.count";
1093 case kind::BAG_DUPLICATE_REMOVAL
: return "bag.duplicate_removal";
1094 case kind::BAG_MAKE
: return "bag";
1095 case kind::BAG_CARD
: return "bag.card";
1096 case kind::BAG_CHOOSE
: return "bag.choose";
1097 case kind::BAG_IS_SINGLETON
: return "bag.is_singleton";
1098 case kind::BAG_FROM_SET
: return "bag.from_set";
1099 case kind::BAG_TO_SET
: return "bag.to_set";
1100 case kind::BAG_MAP
: return "bag.map";
1101 case kind::BAG_FOLD
: return "bag.fold";
1104 case kind::FLOATINGPOINT_FP
: return "fp";
1105 case kind::FLOATINGPOINT_EQ
: return "fp.eq";
1106 case kind::FLOATINGPOINT_ABS
: return "fp.abs";
1107 case kind::FLOATINGPOINT_NEG
: return "fp.neg";
1108 case kind::FLOATINGPOINT_ADD
: return "fp.add";
1109 case kind::FLOATINGPOINT_SUB
: return "fp.sub";
1110 case kind::FLOATINGPOINT_MULT
: return "fp.mul";
1111 case kind::FLOATINGPOINT_DIV
: return "fp.div";
1112 case kind::FLOATINGPOINT_FMA
: return "fp.fma";
1113 case kind::FLOATINGPOINT_SQRT
: return "fp.sqrt";
1114 case kind::FLOATINGPOINT_REM
: return "fp.rem";
1115 case kind::FLOATINGPOINT_RTI
: return "fp.roundToIntegral";
1116 case kind::FLOATINGPOINT_MIN
: return "fp.min";
1117 case kind::FLOATINGPOINT_MAX
: return "fp.max";
1118 case kind::FLOATINGPOINT_MIN_TOTAL
: return "fp.min_total";
1119 case kind::FLOATINGPOINT_MAX_TOTAL
: return "fp.max_total";
1121 case kind::FLOATINGPOINT_LEQ
: return "fp.leq";
1122 case kind::FLOATINGPOINT_LT
: return "fp.lt";
1123 case kind::FLOATINGPOINT_GEQ
: return "fp.geq";
1124 case kind::FLOATINGPOINT_GT
: return "fp.gt";
1126 case kind::FLOATINGPOINT_ISN
: return "fp.isNormal";
1127 case kind::FLOATINGPOINT_ISSN
: return "fp.isSubnormal";
1128 case kind::FLOATINGPOINT_ISZ
: return "fp.isZero";
1129 case kind::FLOATINGPOINT_ISINF
: return "fp.isInfinite";
1130 case kind::FLOATINGPOINT_ISNAN
: return "fp.isNaN";
1131 case kind::FLOATINGPOINT_ISNEG
: return "fp.isNegative";
1132 case kind::FLOATINGPOINT_ISPOS
: return "fp.isPositive";
1134 case kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
: return "to_fp";
1135 case kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT
: return "to_fp";
1136 case kind::FLOATINGPOINT_TO_FP_REAL
: return "to_fp";
1137 case kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
: return "to_fp";
1138 case kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
: return "to_fp_unsigned";
1139 case kind::FLOATINGPOINT_TO_FP_GENERIC
: return "to_fp_unsigned";
1140 case kind::FLOATINGPOINT_TO_UBV
: return "fp.to_ubv";
1141 case kind::FLOATINGPOINT_TO_UBV_TOTAL
: return "fp.to_ubv_total";
1142 case kind::FLOATINGPOINT_TO_SBV
: return "fp.to_sbv";
1143 case kind::FLOATINGPOINT_TO_SBV_TOTAL
: return "fp.to_sbv_total";
1144 case kind::FLOATINGPOINT_TO_REAL
: return "fp.to_real";
1145 case kind::FLOATINGPOINT_TO_REAL_TOTAL
: return "fp.to_real_total";
1147 case kind::FLOATINGPOINT_COMPONENT_NAN
: return "NAN";
1148 case kind::FLOATINGPOINT_COMPONENT_INF
: return "INF";
1149 case kind::FLOATINGPOINT_COMPONENT_ZERO
: return "ZERO";
1150 case kind::FLOATINGPOINT_COMPONENT_SIGN
: return "SIGN";
1151 case kind::FLOATINGPOINT_COMPONENT_EXPONENT
: return "EXPONENT";
1152 case kind::FLOATINGPOINT_COMPONENT_SIGNIFICAND
: return "SIGNIFICAND";
1153 case kind::ROUNDINGMODE_BITBLAST
:
1154 return "RMBITBLAST";
1157 case kind::STRING_CONCAT
: return "str.++";
1158 case kind::STRING_LENGTH
: return "str.len";
1159 case kind::STRING_SUBSTR
: return "str.substr" ;
1160 case kind::STRING_UPDATE
: return "str.update";
1161 case kind::STRING_CONTAINS
: return "str.contains";
1162 case kind::STRING_CHARAT
: return "str.at" ;
1163 case kind::STRING_INDEXOF
: return "str.indexof";
1164 case kind::STRING_INDEXOF_RE
: return "str.indexof_re";
1165 case kind::STRING_REPLACE
: return "str.replace";
1166 case kind::STRING_REPLACE_ALL
: return "str.replace_all";
1167 case kind::STRING_REPLACE_RE
: return "str.replace_re";
1168 case kind::STRING_REPLACE_RE_ALL
: return "str.replace_re_all";
1169 case kind::STRING_TOLOWER
: return "str.tolower";
1170 case kind::STRING_TOUPPER
: return "str.toupper";
1171 case kind::STRING_REV
: return "str.rev";
1172 case kind::STRING_PREFIX
: return "str.prefixof" ;
1173 case kind::STRING_SUFFIX
: return "str.suffixof" ;
1174 case kind::STRING_LEQ
: return "str.<=";
1175 case kind::STRING_LT
: return "str.<";
1176 case kind::STRING_FROM_CODE
: return "str.from_code";
1177 case kind::STRING_TO_CODE
: return "str.to_code";
1178 case Kind::STRING_IS_DIGIT
: return "str.is_digit";
1179 case kind::STRING_ITOS
: return "str.from_int";
1180 case kind::STRING_STOI
: return "str.to_int";
1181 case kind::STRING_IN_REGEXP
: return "str.in_re";
1182 case kind::STRING_TO_REGEXP
: return "str.to_re";
1183 case kind::REGEXP_NONE
: return "re.none";
1184 case kind::REGEXP_ALLCHAR
: return "re.allchar";
1185 case kind::REGEXP_CONCAT
: return "re.++";
1186 case kind::REGEXP_UNION
: return "re.union";
1187 case kind::REGEXP_INTER
: return "re.inter";
1188 case kind::REGEXP_STAR
: return "re.*";
1189 case kind::REGEXP_PLUS
: return "re.+";
1190 case kind::REGEXP_OPT
: return "re.opt";
1191 case kind::REGEXP_RANGE
: return "re.range";
1192 case kind::REGEXP_REPEAT
: return "re.^";
1193 case kind::REGEXP_LOOP
: return "re.loop";
1194 case kind::REGEXP_COMPLEMENT
: return "re.comp";
1195 case kind::REGEXP_DIFF
: return "re.diff";
1196 case kind::SEQUENCE_TYPE
: return "Seq";
1197 case kind::SEQ_UNIT
: return "seq.unit";
1198 case kind::SEQ_NTH
: return "seq.nth";
1201 case kind::SEP_STAR
: return "sep";
1202 case kind::SEP_PTO
: return "pto";
1203 case kind::SEP_WAND
: return "wand";
1204 case kind::SEP_EMP
: return "sep.emp";
1207 case kind::FORALL
: return "forall";
1208 case kind::EXISTS
: return "exists";
1211 ; /* fall through */
1214 // fall back on however the kind prints itself; this probably
1215 // won't be SMT-LIB v2 compliant, but it will be clear from the
1216 // output that support for the kind needs to be added here.
1217 // no SMT way to print these
1218 return kind::kindToString(k
);
1221 void Smt2Printer::toStreamType(std::ostream
& out
, TypeNode tn
) const
1223 // we currently must call TypeNode::toStream here.
1228 static bool tryToStream(std::ostream
& out
, const Command
* c
);
1230 static bool tryToStream(std::ostream
& out
, const Command
* c
, Variant v
);
1233 static bool tryToStream(std::ostream
& out
, const CommandStatus
* s
, Variant v
);
1235 void Smt2Printer::toStream(std::ostream
& out
, const CommandStatus
* s
) const
1237 if (tryToStream
<CommandSuccess
>(out
, s
, d_variant
) ||
1238 tryToStream
<CommandFailure
>(out
, s
, d_variant
) ||
1239 tryToStream
<CommandRecoverableFailure
>(out
, s
, d_variant
) ||
1240 tryToStream
<CommandUnsupported
>(out
, s
, d_variant
) ||
1241 tryToStream
<CommandInterrupted
>(out
, s
, d_variant
)) {
1245 out
<< "ERROR: don't know how to print a CommandStatus of class: "
1246 << typeid(*s
).name() << endl
;
1248 }/* Smt2Printer::toStream(CommandStatus*) */
1250 void Smt2Printer::toStream(std::ostream
& out
, const UnsatCore
& core
) const
1252 out
<< "(" << std::endl
;
1253 if (core
.useNames())
1256 const std::vector
<std::string
>& cnames
= core
.getCoreNames();
1257 for (const std::string
& cn
: cnames
)
1259 out
<< cvc5::quoteSymbol(cn
) << std::endl
;
1264 // otherwise, use the formulas
1265 for (UnsatCore::const_iterator i
= core
.begin(); i
!= core
.end(); ++i
)
1271 }/* Smt2Printer::toStream(UnsatCore, map<Expr, string>) */
1273 void Smt2Printer::toStream(std::ostream
& out
, const smt::Model
& m
) const
1277 // don't need to print approximations since they are built into choice
1278 // functions in the values of variables.
1279 this->Printer::toStream(out
, m
);
1281 //print the heap model, if it exists
1283 if (m
.getHeapModel(h
, neq
))
1285 // description of the heap+what nil is equal to fully describes model
1286 out
<< "(heap" << endl
;
1289 out
<< ")" << std::endl
;
1293 void Smt2Printer::toStreamModelSort(std::ostream
& out
,
1295 const std::vector
<Node
>& elements
) const
1299 out
<< "ERROR: don't know how to print non uninterpreted sort in model: "
1303 // print the cardinality
1304 out
<< "; cardinality of " << tn
<< " is " << elements
.size() << endl
;
1305 if (options::modelUninterpPrint()
1306 == options::ModelUninterpPrintMode::DeclSortAndFun
)
1308 toStreamCmdDeclareType(out
, tn
);
1310 // print the representatives
1311 for (const Node
& trn
: elements
)
1315 if (options::modelUninterpPrint()
1316 == options::ModelUninterpPrintMode::DeclSortAndFun
1317 || options::modelUninterpPrint()
1318 == options::ModelUninterpPrintMode::DeclFun
)
1320 out
<< "(declare-fun " << trn
<< " () " << tn
<< ")" << endl
;
1325 out
<< "; rep: " << trn
<< endl
;
1330 void Smt2Printer::toStreamModelTerm(std::ostream
& out
,
1332 const Node
& value
) const
1334 if (value
.getKind() == kind::LAMBDA
)
1336 TypeNode rangeType
= n
.getType().getRangeType();
1337 out
<< "(define-fun " << n
<< " " << value
[0] << " " << rangeType
<< " ";
1338 // call toStream and force its type to be proper
1339 toStreamCastToType(out
, value
[1], -1, rangeType
);
1344 out
<< "(define-fun " << n
<< " () " << n
.getType() << " ";
1345 // call toStream and force its type to be proper
1346 toStreamCastToType(out
, value
, -1, n
.getType());
1351 void Smt2Printer::toStreamCmdAssert(std::ostream
& out
, Node n
) const
1353 out
<< "(assert " << n
<< ')' << std::endl
;
1356 void Smt2Printer::toStreamCmdPush(std::ostream
& out
) const
1358 out
<< "(push 1)" << std::endl
;
1361 void Smt2Printer::toStreamCmdPop(std::ostream
& out
) const
1363 out
<< "(pop 1)" << std::endl
;
1366 void Smt2Printer::toStreamCmdCheckSat(std::ostream
& out
) const
1368 out
<< "(check-sat)" << std::endl
;
1371 void Smt2Printer::toStreamCmdCheckSatAssuming(
1372 std::ostream
& out
, const std::vector
<Node
>& nodes
) const
1374 out
<< "(check-sat-assuming ( ";
1375 copy(nodes
.begin(), nodes
.end(), ostream_iterator
<Node
>(out
, " "));
1376 out
<< "))" << std::endl
;
1379 void Smt2Printer::toStreamCmdQuery(std::ostream
& out
, Node n
) const
1383 toStreamCmdCheckSatAssuming(out
, {n
});
1387 toStreamCmdCheckSat(out
);
1391 void Smt2Printer::toStreamCmdReset(std::ostream
& out
) const
1393 out
<< "(reset)" << std::endl
;
1396 void Smt2Printer::toStreamCmdResetAssertions(std::ostream
& out
) const
1398 out
<< "(reset-assertions)" << std::endl
;
1401 void Smt2Printer::toStreamCmdQuit(std::ostream
& out
) const
1403 out
<< "(exit)" << std::endl
;
1406 void Smt2Printer::toStreamCmdCommandSequence(
1407 std::ostream
& out
, const std::vector
<Command
*>& sequence
) const
1409 for (Command
* i
: sequence
)
1415 void Smt2Printer::toStreamCmdDeclarationSequence(
1416 std::ostream
& out
, const std::vector
<Command
*>& sequence
) const
1418 toStreamCmdCommandSequence(out
, sequence
);
1421 void Smt2Printer::toStreamCmdDeclareFunction(std::ostream
& out
,
1422 const std::string
& id
,
1423 TypeNode type
) const
1425 out
<< "(declare-fun " << cvc5::quoteSymbol(id
) << " (";
1426 if (type
.isFunction())
1428 const vector
<TypeNode
> argTypes
= type
.getArgTypes();
1429 if (argTypes
.size() > 0)
1431 copy(argTypes
.begin(),
1433 ostream_iterator
<TypeNode
>(out
, " "));
1434 out
<< argTypes
.back();
1436 type
= type
.getRangeType();
1439 out
<< ") " << type
<< ')' << std::endl
;
1442 void Smt2Printer::toStreamCmdDeclarePool(
1444 const std::string
& id
,
1446 const std::vector
<Node
>& initValue
) const
1448 out
<< "(declare-pool " << cvc5::quoteSymbol(id
) << ' ' << type
<< " (";
1449 for (size_t i
= 0, n
= initValue
.size(); i
< n
; ++i
)
1454 out
<< initValue
[i
];
1456 out
<< "))" << std::endl
;
1459 void Smt2Printer::toStreamCmdDefineFunction(std::ostream
& out
,
1460 const std::string
& id
,
1461 const std::vector
<Node
>& formals
,
1465 out
<< "(define-fun " << id
<< " (";
1466 if (!formals
.empty())
1468 vector
<Node
>::const_iterator i
= formals
.cbegin();
1471 out
<< "(" << (*i
) << " " << (*i
).getType() << ")";
1473 if (i
!= formals
.cend())
1483 out
<< ") " << range
<< ' ' << formula
<< ')' << std::endl
;
1486 void Smt2Printer::toStreamCmdDefineFunctionRec(
1488 const std::vector
<Node
>& funcs
,
1489 const std::vector
<std::vector
<Node
>>& formals
,
1490 const std::vector
<Node
>& formulas
) const
1492 out
<< "(define-fun";
1493 if (funcs
.size() > 1)
1498 if (funcs
.size() > 1)
1502 for (unsigned i
= 0, size
= funcs
.size(); i
< size
; i
++)
1504 if (funcs
.size() > 1)
1512 out
<< funcs
[i
] << " (";
1513 // print its type signature
1514 vector
<Node
>::const_iterator itf
= formals
[i
].cbegin();
1515 while (itf
!= formals
[i
].cend())
1517 out
<< "(" << (*itf
) << " " << (*itf
).getType() << ")";
1519 if (itf
!= formals
[i
].cend())
1524 TypeNode type
= funcs
[i
].getType();
1525 if (type
.isFunction())
1527 type
= type
.getRangeType();
1529 out
<< ") " << type
;
1530 if (funcs
.size() > 1)
1535 if (funcs
.size() > 1)
1543 for (unsigned i
= 0, size
= formulas
.size(); i
< size
; i
++)
1551 if (funcs
.size() > 1)
1555 out
<< ")" << std::endl
;
1558 void Smt2Printer::toStreamCmdDeclareType(std::ostream
& out
,
1559 TypeNode type
) const
1561 Assert(type
.isSort() || type
.isSortConstructor());
1562 size_t arity
= type
.isSortConstructor() ? type
.getSortConstructorArity() : 0;
1563 out
<< "(declare-sort " << type
<< " " << arity
<< ")" << std::endl
;
1566 void Smt2Printer::toStreamCmdDefineType(std::ostream
& out
,
1567 const std::string
& id
,
1568 const std::vector
<TypeNode
>& params
,
1571 out
<< "(define-sort " << cvc5::quoteSymbol(id
) << " (";
1572 if (params
.size() > 0)
1575 params
.begin(), params
.end() - 1, ostream_iterator
<TypeNode
>(out
, " "));
1576 out
<< params
.back();
1578 out
<< ") " << t
<< ")" << std::endl
;
1581 void Smt2Printer::toStreamCmdSimplify(std::ostream
& out
, Node n
) const
1583 out
<< "(simplify " << n
<< ')' << std::endl
;
1586 void Smt2Printer::toStreamCmdGetValue(std::ostream
& out
,
1587 const std::vector
<Node
>& nodes
) const
1589 out
<< "(get-value ( ";
1590 copy(nodes
.begin(), nodes
.end(), ostream_iterator
<Node
>(out
, " "));
1591 out
<< "))" << std::endl
;
1594 void Smt2Printer::toStreamCmdGetModel(std::ostream
& out
) const
1596 out
<< "(get-model)" << std::endl
;
1599 void Smt2Printer::toStreamCmdBlockModel(std::ostream
& out
) const
1601 out
<< "(block-model)" << std::endl
;
1604 void Smt2Printer::toStreamCmdBlockModelValues(
1605 std::ostream
& out
, const std::vector
<Node
>& nodes
) const
1607 out
<< "(block-model-values (";
1608 for (size_t i
= 0, n
= nodes
.size(); i
< n
; ++i
)
1616 out
<< "))" << std::endl
;
1619 void Smt2Printer::toStreamCmdGetAssignment(std::ostream
& out
) const
1621 out
<< "(get-assignment)" << std::endl
;
1624 void Smt2Printer::toStreamCmdGetAssertions(std::ostream
& out
) const
1626 out
<< "(get-assertions)" << std::endl
;
1629 void Smt2Printer::toStreamCmdGetProof(std::ostream
& out
) const
1631 out
<< "(get-proof)" << std::endl
;
1634 void Smt2Printer::toStreamCmdGetUnsatAssumptions(std::ostream
& out
) const
1636 out
<< "(get-unsat-assumptions)" << std::endl
;
1639 void Smt2Printer::toStreamCmdGetUnsatCore(std::ostream
& out
) const
1641 out
<< "(get-unsat-core)" << std::endl
;
1644 void Smt2Printer::toStreamCmdGetDifficulty(std::ostream
& out
) const
1646 out
<< "(get-difficulty)" << std::endl
;
1649 void Smt2Printer::toStreamCmdSetBenchmarkLogic(std::ostream
& out
,
1650 const std::string
& logic
) const
1652 out
<< "(set-logic " << logic
<< ')' << std::endl
;
1655 void Smt2Printer::toStreamCmdSetInfo(std::ostream
& out
,
1656 const std::string
& flag
,
1657 const std::string
& value
) const
1659 out
<< "(set-info :" << flag
<< " " << value
<< ")" << std::endl
;
1662 void Smt2Printer::toStreamCmdGetInfo(std::ostream
& out
,
1663 const std::string
& flag
) const
1665 out
<< "(get-info :" << flag
<< ')' << std::endl
;
1668 void Smt2Printer::toStreamCmdSetOption(std::ostream
& out
,
1669 const std::string
& flag
,
1670 const std::string
& value
) const
1672 out
<< "(set-option :" << flag
<< ' ' << value
<< ')' << std::endl
;
1675 void Smt2Printer::toStreamCmdGetOption(std::ostream
& out
,
1676 const std::string
& flag
) const
1678 out
<< "(get-option :" << flag
<< ')' << std::endl
;
1681 void Smt2Printer::toStream(std::ostream
& out
, const DType
& dt
) const
1683 for (size_t i
= 0, ncons
= dt
.getNumConstructors(); i
< ncons
; i
++)
1685 const DTypeConstructor
& cons
= dt
[i
];
1690 out
<< "(" << cvc5::quoteSymbol(cons
.getName());
1691 for (size_t j
= 0, nargs
= cons
.getNumArgs(); j
< nargs
; j
++)
1693 const DTypeSelector
& arg
= cons
[j
];
1694 out
<< " (" << arg
.getSelector() << " " << arg
.getRangeType() << ")";
1700 void Smt2Printer::toStreamCmdDatatypeDeclaration(
1701 std::ostream
& out
, const std::vector
<TypeNode
>& datatypes
) const
1703 Assert(!datatypes
.empty());
1704 Assert(datatypes
[0].isDatatype());
1705 const DType
& d0
= datatypes
[0].getDType();
1708 // not necessary to print tuples
1709 Assert(datatypes
.size() == 1);
1713 if (d0
.isCodatatype())
1719 for (const TypeNode
& t
: datatypes
)
1721 Assert(t
.isDatatype());
1722 const DType
& d
= t
.getDType();
1723 out
<< "(" << cvc5::quoteSymbol(d
.getName());
1724 out
<< " " << d
.getNumParameters() << ")";
1727 for (const TypeNode
& t
: datatypes
)
1729 Assert(t
.isDatatype());
1730 const DType
& d
= t
.getDType();
1731 if (d
.isParametric())
1734 for (unsigned p
= 0, nparam
= d
.getNumParameters(); p
< nparam
; p
++)
1736 out
<< (p
> 0 ? " " : "") << d
.getParameter(p
);
1743 if (d
.isParametric())
1749 out
<< ")" << std::endl
;
1752 void Smt2Printer::toStreamCmdDeclareHeap(std::ostream
& out
,
1754 TypeNode dataType
) const
1756 out
<< "(declare-heap (" << locType
<< " " << dataType
<< "))" << std::endl
;
1759 void Smt2Printer::toStreamCmdEmpty(std::ostream
& out
,
1760 const std::string
& name
) const
1765 void Smt2Printer::toStreamCmdEcho(std::ostream
& out
,
1766 const std::string
& output
) const
1768 out
<< "(echo " << cvc5::quoteString(output
) << ')' << std::endl
;
1772 --------------------------------------------------------------------------
1773 Handling SyGuS commands
1774 --------------------------------------------------------------------------
1777 std::string
Smt2Printer::sygusGrammarString(const TypeNode
& t
)
1779 std::stringstream out
;
1780 if (!t
.isNull() && t
.isDatatype() && t
.getDType().isSygus())
1782 std::stringstream types_predecl
, types_list
;
1783 std::set
<TypeNode
> grammarTypes
;
1784 std::list
<TypeNode
> typesToPrint
;
1785 grammarTypes
.insert(t
);
1786 typesToPrint
.push_back(t
);
1787 NodeManager
* nm
= NodeManager::currentNM();
1788 // for each datatype in grammar
1791 // constructors in order
1794 TypeNode curr
= typesToPrint
.front();
1795 typesToPrint
.pop_front();
1796 Assert(curr
.isDatatype() && curr
.getDType().isSygus());
1797 const DType
& dt
= curr
.getDType();
1798 types_list
<< '(' << dt
.getName() << ' ' << dt
.getSygusType() << " (";
1799 types_predecl
<< '(' << dt
.getName() << ' ' << dt
.getSygusType() << ") ";
1800 if (dt
.getSygusAllowConst())
1802 types_list
<< "(Constant " << dt
.getSygusType() << ") ";
1804 for (size_t i
= 0, ncons
= dt
.getNumConstructors(); i
< ncons
; i
++)
1806 const DTypeConstructor
& cons
= dt
[i
];
1807 // make a sygus term
1808 std::vector
<Node
> cchildren
;
1809 cchildren
.push_back(cons
.getConstructor());
1810 for (size_t j
= 0, nargs
= cons
.getNumArgs(); j
< nargs
; j
++)
1812 TypeNode argType
= cons
[j
].getRangeType();
1813 std::stringstream ss
;
1815 Node bv
= nm
->mkBoundVar(ss
.str(), argType
);
1816 cchildren
.push_back(bv
);
1817 // if fresh type, store it for later processing
1818 if (grammarTypes
.insert(argType
).second
)
1820 typesToPrint
.push_back(argType
);
1823 Node consToPrint
= nm
->mkNode(kind::APPLY_CONSTRUCTOR
, cchildren
);
1824 // now, print it using the conversion to builtin with external
1825 types_list
<< theory::datatypes::utils::sygusToBuiltin(consToPrint
,
1829 types_list
<< "))\n";
1830 } while (!typesToPrint
.empty());
1832 out
<< "\n(" << types_predecl
.str() << ")\n(" << types_list
.str() << ')';
1837 void Smt2Printer::toStreamCmdSynthFun(std::ostream
& out
,
1839 const std::vector
<Node
>& vars
,
1841 TypeNode sygusType
) const
1843 out
<< '(' << (isInv
? "synth-inv " : "synth-fun ") << f
<< ' ' << '(';
1846 // print variable list
1847 std::vector
<Node
>::const_iterator i
= vars
.cbegin(), i_end
= vars
.cend();
1848 out
<< '(' << *i
<< ' ' << i
->getType() << ')';
1852 out
<< " (" << *i
<< ' ' << i
->getType() << ')';
1857 // if not invariant-to-synthesize, print return type
1860 TypeNode ftn
= f
.getType();
1861 TypeNode range
= ftn
.isFunction() ? ftn
.getRangeType() : ftn
;
1862 out
<< ' ' << range
;
1865 // print grammar, if any
1866 if (!sygusType
.isNull())
1868 out
<< sygusGrammarString(sygusType
);
1870 out
<< ')' << std::endl
;
1873 void Smt2Printer::toStreamCmdDeclareVar(std::ostream
& out
,
1875 TypeNode type
) const
1877 out
<< "(declare-var " << var
<< ' ' << type
<< ')' << std::endl
;
1880 void Smt2Printer::toStreamCmdConstraint(std::ostream
& out
, Node n
) const
1882 out
<< "(constraint " << n
<< ')' << std::endl
;
1885 void Smt2Printer::toStreamCmdAssume(std::ostream
& out
, Node n
) const
1887 out
<< "(assume " << n
<< ')' << std::endl
;
1890 void Smt2Printer::toStreamCmdInvConstraint(
1891 std::ostream
& out
, Node inv
, Node pre
, Node trans
, Node post
) const
1893 out
<< "(inv-constraint " << inv
<< ' ' << pre
<< ' ' << trans
<< ' ' << post
1894 << ')' << std::endl
;
1897 void Smt2Printer::toStreamCmdCheckSynth(std::ostream
& out
) const
1899 out
<< "(check-synth)" << std::endl
;
1902 void Smt2Printer::toStreamCmdGetInterpol(std::ostream
& out
,
1903 const std::string
& name
,
1905 TypeNode sygusType
) const
1907 out
<< "(get-interpol " << cvc5::quoteSymbol(name
) << ' ' << conj
;
1908 if (!sygusType
.isNull())
1910 out
<< ' ' << sygusGrammarString(sygusType
);
1912 out
<< ')' << std::endl
;
1915 void Smt2Printer::toStreamCmdGetAbduct(std::ostream
& out
,
1916 const std::string
& name
,
1918 TypeNode sygusType
) const
1920 out
<< "(get-abduct ";
1924 // print grammar, if any
1925 if (!sygusType
.isNull())
1927 out
<< sygusGrammarString(sygusType
);
1929 out
<< ')' << std::endl
;
1932 void Smt2Printer::toStreamCmdGetQuantifierElimination(std::ostream
& out
,
1936 out
<< '(' << (doFull
? "get-qe" : "get-qe-disjunct") << ' ' << n
<< ')'
1941 --------------------------------------------------------------------------
1942 End of Handling SyGuS commands
1943 --------------------------------------------------------------------------
1947 static bool tryToStream(std::ostream
& out
, const Command
* c
)
1949 if(typeid(*c
) == typeid(T
)) {
1950 toStream(out
, dynamic_cast<const T
*>(c
));
1957 static bool tryToStream(std::ostream
& out
, const Command
* c
, Variant v
)
1959 if(typeid(*c
) == typeid(T
)) {
1960 toStream(out
, dynamic_cast<const T
*>(c
), v
);
1966 static void toStream(std::ostream
& out
, const CommandSuccess
* s
, Variant v
)
1968 if(Command::printsuccess::getPrintSuccess(out
)) {
1969 out
<< "success" << endl
;
1973 static void toStream(std::ostream
& out
, const CommandInterrupted
* s
, Variant v
)
1975 out
<< "interrupted" << endl
;
1978 static void toStream(std::ostream
& out
, const CommandUnsupported
* s
, Variant v
)
1980 #ifdef CVC5_COMPETITION_MODE
1981 // if in competition mode, lie and say we're ok
1982 // (we have nothing to lose by saying success, and everything to lose
1983 // if we say "unsupported")
1984 out
<< "success" << endl
;
1985 #else /* CVC5_COMPETITION_MODE */
1986 out
<< "unsupported" << endl
;
1987 #endif /* CVC5_COMPETITION_MODE */
1990 static void errorToStream(std::ostream
& out
, std::string message
, Variant v
)
1992 out
<< "(error " << cvc5::quoteString(message
) << ')' << endl
;
1995 static void toStream(std::ostream
& out
, const CommandFailure
* s
, Variant v
) {
1996 errorToStream(out
, s
->getMessage(), v
);
1999 static void toStream(std::ostream
& out
, const CommandRecoverableFailure
* s
,
2001 errorToStream(out
, s
->getMessage(), v
);
2005 static bool tryToStream(std::ostream
& out
, const CommandStatus
* s
, Variant v
)
2007 if(typeid(*s
) == typeid(T
)) {
2008 toStream(out
, dynamic_cast<const T
*>(s
), v
);
2015 } // namespace printer