1 /********************* */
2 /*! \file cvc_printer.cpp
4 ** Top contributors (to current version):
5 ** Morgan Deters, Dejan Jovanovic, Tim King
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2018 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.\endverbatim
12 ** \brief The pretty-printer interface for the CVC output language
14 ** The pretty-printer interface for the CVC output language.
17 #include "printer/cvc/cvc_printer.h"
27 #include "expr/expr.h" // for ExprSetDepth etc..
28 #include "expr/node_manager_attributes.h" // for VarNameAttr
29 #include "options/language.h" // for LANG_AST
30 #include "printer/dagification_visitor.h"
31 #include "options/smt_options.h"
32 #include "smt/command.h"
33 #include "smt/smt_engine.h"
34 #include "smt_util/node_visitor.h"
35 #include "theory/arrays/theory_arrays_rewriter.h"
36 #include "theory/substitutions.h"
37 #include "theory/theory_model.h"
45 void CvcPrinter::toStream(
46 std::ostream
& out
, TNode n
, int toDepth
, bool types
, size_t dag
) const
49 DagificationVisitor
dv(dag
);
50 NodeVisitor
<DagificationVisitor
> visitor
;
52 const theory::SubstitutionMap
& lets
= dv
.getLets();
56 for(theory::SubstitutionMap::const_iterator i
= lets
.begin();
64 toStream(out
, (*i
).second
, toDepth
, types
, false);
66 toStream(out
, (*i
).first
, toDepth
, types
, false);
70 Node body
= dv
.getDagifiedBody();
71 toStream(out
, body
, toDepth
, types
, false);
73 toStream(out
, n
, toDepth
, types
, false);
77 void toStreamRational(std::ostream
& out
, Node n
, bool forceRational
)
79 Assert(n
.getKind() == kind::CONST_RATIONAL
);
80 const Rational
& rat
= n
.getConst
<Rational
>();
81 if (rat
.isIntegral() && !forceRational
)
83 out
<< rat
.getNumerator();
87 out
<< '(' << rat
.getNumerator() << '/' << rat
.getDenominator() << ')';
91 void CvcPrinter::toStream(
92 std::ostream
& out
, TNode n
, int depth
, bool types
, bool bracket
) const
101 if(n
.getKind() == kind::NULL_EXPR
) {
109 if(n
.getAttribute(expr::VarNameAttr(), s
)) {
112 if(n
.getKind() == kind::VARIABLE
) {
115 out
<< n
.getKind() << '_';
120 // print the whole type, but not *its* type
122 n
.getType().toStream(out
, language::output::LANG_CVC4
);
126 if(n
.isNullaryOp()) {
127 if( n
.getKind() == kind::UNIVERSE_SET
){
128 out
<< "UNIVERSE :: " << n
.getType();
137 if(n
.getMetaKind() == kind::metakind::CONSTANT
) {
138 switch(n
.getKind()) {
139 case kind::BITVECTOR_TYPE
:
140 out
<< "BITVECTOR(" << n
.getConst
<BitVectorSize
>().size
<< ")";
142 case kind::CONST_BITVECTOR
: {
143 const BitVector
& bv
= n
.getConst
<BitVector
>();
144 const Integer
& x
= bv
.getValue();
146 unsigned n
= bv
.getSize();
148 out
<< (x
.testBit(n
) ? '1' : '0');
152 case kind::CONST_BOOLEAN
:
153 // the default would print "1" or "0" for bool, that's not correct
155 out
<< (n
.getConst
<bool>() ? "TRUE" : "FALSE");
157 case kind::CONST_RATIONAL
: {
158 toStreamRational(out
, n
, false);
161 case kind::TYPE_CONSTANT
:
162 switch(TypeConstant tc
= n
.getConst
<TypeConstant
>()) {
181 case kind::DATATYPE_TYPE
: {
182 const Datatype
& dt
= (NodeManager::currentNM()->getDatatypeForIndex( n
.getConst
< DatatypeIndexConstant
>().getIndex() ));
185 for (unsigned i
= 0; i
< dt
[0].getNumArgs(); ++ i
) {
189 Type t
= ((SelectorType
)dt
[0][i
].getSelector().getType()).getRangeType();
193 }else if( dt
.isRecord() ){
195 for (unsigned i
= 0; i
< dt
[0].getNumArgs(); ++ i
) {
199 Type t
= ((SelectorType
)dt
[0][i
].getSelector().getType()).getRangeType();
200 out
<< dt
[0][i
].getSelector() << ":" << t
;
210 out
<< "{} :: " << n
.getConst
<EmptySet
>().getType();
213 case kind::STORE_ALL
: {
214 const ArrayStoreAll
& asa
= n
.getConst
<ArrayStoreAll
>();
215 out
<< "ARRAY(" << asa
.getType().getIndexType() << " OF "
216 << asa
.getType().getConstituentType() << ") : " << asa
.getExpr();
221 // Fall back to whatever operator<< does on underlying type; we
222 // might luck out and print something reasonable.
223 kind::metakind::NodeValueConstPrinter::toStream(out
, n
);
235 //The default operation type is PREFIX
238 stringstream op
; // operation (such as '+')
240 switch(n
.getKind()) {
244 if( n
[0].getType().isBoolean() ){
253 toStream(out
, n
[0], depth
, types
, true);
255 toStream(out
, n
[1], depth
, types
, true);
257 toStream(out
, n
[2], depth
, types
, true);
261 case kind::SEXPR_TYPE
:
263 for (unsigned i
= 0; i
< n
.getNumChildren(); ++ i
) {
267 toStream(out
, n
[i
], depth
, types
, false);
277 toStream(out
, n
[0], depth
, types
, true);
279 toStream(out
, n
[1], depth
, types
, true);
284 toStream(op
, n
.getOperator(), depth
, types
, true);
287 case kind::DISTINCT
: // chain and distinct not supported directly in CVC4, blast them away with the rewriter
288 toStream(out
, theory::Rewriter::rewrite(n
), depth
, types
, true);
290 case kind::SORT_TYPE
:
293 if(n
.getAttribute(expr::VarNameAttr(), name
)) {
324 toStream(op
, n
.getOperator(), depth
, types
, false);
326 case kind::CARDINALITY_CONSTRAINT
:
327 case kind::COMBINED_CARDINALITY_CONSTRAINT
:
328 out
<< "CARDINALITY_CONSTRAINT";
331 case kind::FUNCTION_TYPE
:
332 if (n
.getNumChildren() > 1) {
333 if (n
.getNumChildren() > 2) {
336 for (unsigned i
= 1; i
< n
.getNumChildren(); ++i
) {
340 toStream(out
, n
[i
- 1], depth
, types
, false);
342 if (n
.getNumChildren() > 2) {
347 toStream(out
, n
[n
.getNumChildren() - 1], depth
, types
, false);
352 case kind::PARAMETRIC_DATATYPE
: {
353 const Datatype
& dt
= (NodeManager::currentNM()->getDatatypeForIndex( n
[0].getConst
< DatatypeIndexConstant
>().getIndex() ));
354 out
<< dt
.getName() << '[';
355 for(unsigned i
= 1; i
< n
.getNumChildren(); ++i
) {
365 case kind::APPLY_TYPE_ASCRIPTION
: {
366 toStream(out
, n
[0], depth
, types
, false);
368 TypeNode t
= TypeNode::fromType(n
.getOperator().getConst
<AscriptionType
>().getType());
369 out
<< (t
.isFunctionLike() ? t
.getRangeType() : t
);
373 case kind::APPLY_CONSTRUCTOR
: {
374 TypeNode t
= n
.getType();
376 if( n
.getNumChildren()==1 ){
379 }else if( t
.isRecord() ){
380 const Record
& rec
= t
.getRecord();
382 TNode::iterator i
= n
.begin();
384 const Record::FieldVector
& fields
= rec
.getFields();
385 for(Record::FieldVector::const_iterator j
= fields
.begin(); j
!= fields
.end(); ++i
, ++j
) {
389 out
<< (*j
).first
<< " := ";
390 toStream(out
, *i
, depth
, types
, false);
396 toStream(op
, n
.getOperator(), depth
, types
, false);
397 if (n
.getNumChildren() == 0)
399 // for datatype constants d, we print "d" and not "d()"
406 case kind::APPLY_SELECTOR
:
407 case kind::APPLY_SELECTOR_TOTAL
: {
408 TypeNode t
= n
[0].getType();
409 Node opn
= n
.getOperator();
411 toStream(out
, n
[0], depth
, types
, true);
412 const Datatype
& dt
= ((DatatypeType
)t
.toType()).getDatatype();
413 int sindex
= dt
[0].getSelectorIndexInternal( opn
.toExpr() );
415 out
<< '.' << sindex
;
417 toStream(op
, opn
, depth
, types
, false);
421 case kind::APPLY_TESTER
: {
422 Assert( !n
.getType().isTuple() && !n
.getType().isRecord() );
424 unsigned cindex
= Datatype::indexOf(n
.getOperator().toExpr());
425 const Datatype
& dt
= Datatype::datatypeOf(n
.getOperator().toExpr());
426 toStream(op
, Node::fromExpr(dt
[cindex
].getConstructor()), depth
, types
, false);
429 case kind::CONSTRUCTOR_TYPE
:
430 case kind::SELECTOR_TYPE
:
431 if(n
.getNumChildren() > 1) {
432 if(n
.getNumChildren() > 2) {
435 for(unsigned i
= 0; i
< n
.getNumChildren() - 1; ++i
) {
439 toStream(out
, n
[i
], depth
, types
, false);
441 if(n
.getNumChildren() > 2) {
446 toStream(out
, n
[n
.getNumChildren() - 1], depth
, types
, false);
448 case kind::TESTER_TYPE
:
449 toStream(out
, n
[0], depth
, types
, false);
450 out
<< " -> BOOLEAN";
453 case kind::TUPLE_UPDATE
:
454 toStream(out
, n
[0], depth
, types
, true);
455 out
<< " WITH ." << n
.getOperator().getConst
<TupleUpdate
>().getIndex() << " := ";
456 toStream(out
, n
[1], depth
, types
, true);
459 case kind::RECORD_UPDATE
:
460 toStream(out
, n
[0], depth
, types
, true);
461 out
<< " WITH ." << n
.getOperator().getConst
<RecordUpdate
>().getField() << " := ";
462 toStream(out
, n
[1], depth
, types
, true);
467 case kind::ARRAY_TYPE
:
469 toStream(out
, n
[0], depth
, types
, false);
471 toStream(out
, n
[1], depth
, types
, false);
475 toStream(out
, n
[0], depth
, types
, true);
477 toStream(out
, n
[1], depth
, types
, false);
484 while(stk
.top()[0].getKind() == kind::STORE
) {
485 stk
.push(stk
.top()[0]);
491 toStream(out
, x
[0], depth
, types
, false);
493 toStream(out
, x
[1], depth
, types
, false);
495 toStream(out
, x
[2], depth
, types
, false);
497 while(!stk
.empty()) {
500 toStream(out
, x
[1], depth
, types
, false);
502 toStream(out
, x
[2], depth
, types
, false);
518 case kind::NONLINEAR_MULT
:
531 case kind::DIVISION_TOTAL
:
535 case kind::INTS_DIVISION
:
536 case kind::INTS_DIVISION_TOTAL
:
540 case kind::INTS_MODULUS
:
541 case kind::INTS_MODULUS_TOTAL
:
569 case kind::IS_INTEGER
:
573 case kind::TO_INTEGER
:
578 if (n
[0].getKind() == kind::CONST_RATIONAL
)
580 // print the constant as a rational
581 toStreamRational(out
, n
[0], true);
585 // ignore, there is no to-real in CVC language
586 toStream(out
, n
[0], depth
, types
, false);
589 case kind::DIVISIBLE
:
591 toStream(out
, n
[0], depth
, types
, false);
592 out
<< ", " << n
.getOperator().getConst
<Divisible
>().k
<< ")";
596 case kind::BITVECTOR_XOR
:
599 case kind::BITVECTOR_NAND
:
602 case kind::BITVECTOR_NOR
:
605 case kind::BITVECTOR_XNOR
:
608 case kind::BITVECTOR_COMP
:
611 case kind::BITVECTOR_UDIV
:
614 case kind::BITVECTOR_UDIV_TOTAL
:
615 op
<< "BVUDIV_TOTAL";
617 case kind::BITVECTOR_UREM
:
620 case kind::BITVECTOR_UREM_TOTAL
:
621 op
<< "BVUREM_TOTAL";
623 case kind::BITVECTOR_SDIV
:
626 case kind::BITVECTOR_SREM
:
629 case kind::BITVECTOR_SMOD
:
632 case kind::BITVECTOR_SHL
:
635 case kind::BITVECTOR_LSHR
:
638 case kind::BITVECTOR_ASHR
:
641 case kind::BITVECTOR_ULT
:
644 case kind::BITVECTOR_ULE
:
647 case kind::BITVECTOR_UGT
:
650 case kind::BITVECTOR_UGE
:
653 case kind::BITVECTOR_SLT
:
656 case kind::BITVECTOR_SLE
:
659 case kind::BITVECTOR_SGT
:
662 case kind::BITVECTOR_SGE
:
665 case kind::BITVECTOR_NEG
:
668 case kind::BITVECTOR_NOT
:
671 case kind::BITVECTOR_AND
:
675 case kind::BITVECTOR_OR
:
679 case kind::BITVECTOR_CONCAT
:
683 case kind::BITVECTOR_PLUS
: {
684 // This interprets a BITVECTOR_PLUS as a bvadd in SMT-LIB
685 Assert(n
.getType().isBitVector());
686 unsigned numc
= n
.getNumChildren()-2;
688 while (child
< numc
) {
690 out
<< BitVectorType(n
.getType().toType()).getSize();
692 toStream(out
, n
[child
], depth
, types
, false);
697 out
<< BitVectorType(n
.getType().toType()).getSize();
699 toStream(out
, n
[child
], depth
, types
, false);
701 toStream(out
, n
[child
+ 1], depth
, types
, false);
710 case kind::BITVECTOR_SUB
:
712 Assert(n
.getType().isBitVector());
713 out
<< BitVectorType(n
.getType().toType()).getSize();
715 toStream(out
, n
[0], depth
, types
, false);
717 toStream(out
, n
[1], depth
, types
, false);
721 case kind::BITVECTOR_MULT
: {
722 Assert(n
.getType().isBitVector());
723 unsigned numc
= n
.getNumChildren()-2;
725 while (child
< numc
) {
727 out
<< BitVectorType(n
.getType().toType()).getSize();
729 toStream(out
, n
[child
], depth
, types
, false);
734 out
<< BitVectorType(n
.getType().toType()).getSize();
736 toStream(out
, n
[child
], depth
, types
, false);
738 toStream(out
, n
[child
+ 1], depth
, types
, false);
747 case kind::BITVECTOR_EXTRACT
:
748 op
<< n
.getOperator().getConst
<BitVectorExtract
>();
751 case kind::BITVECTOR_BITOF
:
752 op
<< n
.getOperator().getConst
<BitVectorBitOf
>();
755 case kind::BITVECTOR_REPEAT
:
757 toStream(out
, n
[0], depth
, types
, false);
758 out
<< ", " << n
.getOperator().getConst
<BitVectorRepeat
>() << ')';
761 case kind::BITVECTOR_ZERO_EXTEND
:
762 out
<< "BVZEROEXTEND(";
763 toStream(out
, n
[0], depth
, types
, false);
764 out
<< ", " << n
.getOperator().getConst
<BitVectorZeroExtend
>() << ')';
767 case kind::BITVECTOR_SIGN_EXTEND
:
769 toStream(out
, n
[0], depth
, types
, false);
770 out
<< ", " << BitVectorType(n
.getType().toType()).getSize() << ')';
773 case kind::BITVECTOR_ROTATE_LEFT
:
775 toStream(out
, n
[0], depth
, types
, false);
776 out
<< ", " << n
.getOperator().getConst
<BitVectorRotateLeft
>() << ')';
779 case kind::BITVECTOR_ROTATE_RIGHT
:
781 toStream(out
, n
[0], depth
, types
, false);
782 out
<< ", " << n
.getOperator().getConst
<BitVectorRotateRight
>() << ')';
789 toStream(out
, n
[0], depth
, types
, false);
796 case kind::INTERSECTION
:
812 case kind::COMPLEMENT
:
824 case kind::TRANSPOSE
:
836 case kind::JOIN_IMAGE
:
840 case kind::SINGLETON
:
842 toStream(out
, n
[0], depth
, types
, false);
852 toStream(out
, n
[i
++], depth
, types
, false);
853 for(;i
+1 < n
.getNumChildren(); ++i
) {
855 toStream(out
, n
[i
], depth
, types
, false);
858 toStream(out
, n
[i
], depth
, types
, true);
867 toStream(out
, n
[0], depth
, types
, false);
876 toStream(out
, n
[0], depth
, types
, false);
878 toStream(out
, n
[1], depth
, types
, false);
880 // TODO: user patterns?
884 toStream(out
, n
[0], depth
, types
, false);
886 toStream(out
, n
[1], depth
, types
, false);
888 // TODO: user patterns?
890 case kind::INST_CONSTANT
:
891 out
<< "INST_CONSTANT";
893 case kind::BOUND_VAR_LIST
:
895 for(size_t i
= 0; i
< n
.getNumChildren(); ++i
) {
899 toStream(out
, n
[i
], -1, true, false); // ascribe types
903 case kind::INST_PATTERN
:
904 out
<< "INST_PATTERN";
906 case kind::INST_PATTERN_LIST
:
907 out
<< "INST_PATTERN_LIST";
911 case kind::STRING_CONCAT
:
914 case kind::STRING_CHARAT
:
917 case kind::STRING_LENGTH
:
922 Warning() << "Kind printing not implemented for the case of " << n
.getKind() << endl
;
929 if (n
.getNumChildren() > 0)
944 for (unsigned i
= 0; i
< n
.getNumChildren(); ++ i
) {
946 if (opType
== INFIX
) {
947 out
<< ' ' << op
.str() << ' ';
952 toStream(out
, n
[i
], depth
, types
, opType
== INFIX
);
957 if (n
.getNumChildren() > 0)
968 out
<< ')' << op
.str();
972 }/* CvcPrinter::toStream(TNode) */
975 static bool tryToStream(std::ostream
& out
, const Command
* c
, bool cvc3Mode
);
977 void CvcPrinter::toStream(std::ostream
& out
,
983 expr::ExprSetDepth::Scope
sdScope(out
, toDepth
);
984 expr::ExprPrintTypes::Scope
ptScope(out
, types
);
985 expr::ExprDag::Scope
dagScope(out
, dag
);
987 if(tryToStream
<AssertCommand
>(out
, c
, d_cvc3Mode
) ||
988 tryToStream
<PushCommand
>(out
, c
, d_cvc3Mode
) ||
989 tryToStream
<PopCommand
>(out
, c
, d_cvc3Mode
) ||
990 tryToStream
<CheckSatCommand
>(out
, c
, d_cvc3Mode
) ||
991 tryToStream
<CheckSatAssumingCommand
>(out
, c
, d_cvc3Mode
) ||
992 tryToStream
<QueryCommand
>(out
, c
, d_cvc3Mode
) ||
993 tryToStream
<ResetCommand
>(out
, c
, d_cvc3Mode
) ||
994 tryToStream
<ResetAssertionsCommand
>(out
, c
, d_cvc3Mode
) ||
995 tryToStream
<QuitCommand
>(out
, c
, d_cvc3Mode
) ||
996 tryToStream
<DeclarationSequence
>(out
, c
, d_cvc3Mode
) ||
997 tryToStream
<CommandSequence
>(out
, c
, d_cvc3Mode
) ||
998 tryToStream
<DeclareFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
999 tryToStream
<DeclareTypeCommand
>(out
, c
, d_cvc3Mode
) ||
1000 tryToStream
<DefineTypeCommand
>(out
, c
, d_cvc3Mode
) ||
1001 tryToStream
<DefineNamedFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
1002 tryToStream
<DefineFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
1003 tryToStream
<SimplifyCommand
>(out
, c
, d_cvc3Mode
) ||
1004 tryToStream
<GetValueCommand
>(out
, c
, d_cvc3Mode
) ||
1005 tryToStream
<GetModelCommand
>(out
, c
, d_cvc3Mode
) ||
1006 tryToStream
<GetAssignmentCommand
>(out
, c
, d_cvc3Mode
) ||
1007 tryToStream
<GetAssertionsCommand
>(out
, c
, d_cvc3Mode
) ||
1008 tryToStream
<GetProofCommand
>(out
, c
, d_cvc3Mode
) ||
1009 tryToStream
<GetUnsatCoreCommand
>(out
, c
, d_cvc3Mode
) ||
1010 tryToStream
<SetBenchmarkStatusCommand
>(out
, c
, d_cvc3Mode
) ||
1011 tryToStream
<SetBenchmarkLogicCommand
>(out
, c
, d_cvc3Mode
) ||
1012 tryToStream
<SetInfoCommand
>(out
, c
, d_cvc3Mode
) ||
1013 tryToStream
<GetInfoCommand
>(out
, c
, d_cvc3Mode
) ||
1014 tryToStream
<SetOptionCommand
>(out
, c
, d_cvc3Mode
) ||
1015 tryToStream
<GetOptionCommand
>(out
, c
, d_cvc3Mode
) ||
1016 tryToStream
<DatatypeDeclarationCommand
>(out
, c
, d_cvc3Mode
) ||
1017 tryToStream
<CommentCommand
>(out
, c
, d_cvc3Mode
) ||
1018 tryToStream
<EmptyCommand
>(out
, c
, d_cvc3Mode
) ||
1019 tryToStream
<EchoCommand
>(out
, c
, d_cvc3Mode
)) {
1023 out
<< "ERROR: don't know how to print a Command of class: "
1024 << typeid(*c
).name() << endl
;
1026 }/* CvcPrinter::toStream(Command*) */
1029 static bool tryToStream(std::ostream
& out
,
1030 const CommandStatus
* s
,
1033 void CvcPrinter::toStream(std::ostream
& out
, const CommandStatus
* s
) const
1035 if(tryToStream
<CommandSuccess
>(out
, s
, d_cvc3Mode
) ||
1036 tryToStream
<CommandFailure
>(out
, s
, d_cvc3Mode
) ||
1037 tryToStream
<CommandUnsupported
>(out
, s
, d_cvc3Mode
) ||
1038 tryToStream
<CommandInterrupted
>(out
, s
, d_cvc3Mode
)) {
1042 out
<< "ERROR: don't know how to print a CommandStatus of class: "
1043 << typeid(*s
).name() << endl
;
1045 }/* CvcPrinter::toStream(CommandStatus*) */
1049 void DeclareTypeCommandToStream(std::ostream
& out
,
1050 const theory::TheoryModel
& model
,
1051 const DeclareTypeCommand
& command
)
1053 TypeNode type_node
= TypeNode::fromType(command
.getType());
1054 const std::vector
<Node
>* type_reps
=
1055 model
.getRepSet()->getTypeRepsOrNull(type_node
);
1056 if (options::modelUninterpDtEnum() && type_node
.isSort()
1057 && type_reps
!= nullptr)
1059 out
<< "DATATYPE" << std::endl
;
1060 out
<< " " << command
.getSymbol() << " = ";
1061 for (size_t i
= 0; i
< type_reps
->size(); i
++)
1067 out
<< (*type_reps
)[i
] << " ";
1069 out
<< std::endl
<< "END;" << std::endl
;
1071 else if (type_node
.isSort() && type_reps
!= nullptr)
1073 out
<< "% cardinality of " << type_node
<< " is " << type_reps
->size()
1075 out
<< command
<< std::endl
;
1076 for (Node type_rep
: *type_reps
)
1078 if (type_rep
.isVar())
1080 out
<< type_rep
<< " : " << type_node
<< ";" << std::endl
;
1084 out
<< "% rep: " << type_rep
<< std::endl
;
1090 out
<< command
<< std::endl
;
1094 void DeclareFunctionCommandToStream(std::ostream
& out
,
1095 const theory::TheoryModel
& model
,
1096 const DeclareFunctionCommand
& command
)
1098 Node n
= Node::fromExpr(command
.getFunction());
1099 if (n
.getKind() == kind::SKOLEM
)
1101 // don't print out internal stuff
1104 TypeNode tn
= n
.getType();
1106 if (tn
.isFunction() || tn
.isPredicate())
1109 for (size_t i
= 0; i
< tn
.getNumChildren() - 1; i
++)
1117 out
<< ") -> " << tn
.getRangeType();
1123 Node val
= Node::fromExpr(model
.getSmtEngine()->getValue(n
.toExpr()));
1124 if (options::modelUninterpDtEnum() && val
.getKind() == kind::STORE
)
1126 TypeNode type_node
= val
[1].getType();
1129 if (const std::vector
<Node
>* type_reps
=
1130 model
.getRepSet()->getTypeRepsOrNull(type_node
))
1132 Cardinality
indexCard(type_reps
->size());
1133 val
= theory::arrays::TheoryArraysRewriter::normalizeConstant(
1138 out
<< " = " << val
<< ";" << std::endl
;
1143 void CvcPrinter::toStream(std::ostream
& out
,
1145 const Command
* command
) const
1147 const auto* theory_model
= dynamic_cast<const theory::TheoryModel
*>(&model
);
1148 AlwaysAssert(theory_model
!= nullptr);
1149 if (const auto* declare_type_command
=
1150 dynamic_cast<const DeclareTypeCommand
*>(command
))
1152 DeclareTypeCommandToStream(out
, *theory_model
, *declare_type_command
);
1154 else if (const auto* dfc
=
1155 dynamic_cast<const DeclareFunctionCommand
*>(command
))
1157 DeclareFunctionCommandToStream(out
, *theory_model
, *dfc
);
1161 out
<< command
<< std::endl
;
1165 static void toStream(std::ostream
& out
, const AssertCommand
* c
, bool cvc3Mode
)
1167 out
<< "ASSERT " << c
->getExpr() << ";";
1170 static void toStream(std::ostream
& out
, const PushCommand
* c
, bool cvc3Mode
)
1175 static void toStream(std::ostream
& out
, const PopCommand
* c
, bool cvc3Mode
)
1180 static void toStream(std::ostream
& out
, const CheckSatCommand
* c
, bool cvc3Mode
)
1182 Expr e
= c
->getExpr();
1187 out
<< "CHECKSAT " << e
<< ";";
1196 static void toStream(std::ostream
& out
,
1197 const CheckSatAssumingCommand
* c
,
1200 const vector
<Expr
>& exprs
= c
->getTerms();
1206 if (exprs
.size() > 0)
1208 out
<< " " << exprs
[0];
1209 for (size_t i
= 1, n
= exprs
.size(); i
< n
; ++i
)
1211 out
<< " AND " << exprs
[i
];
1221 static void toStream(std::ostream
& out
, const QueryCommand
* c
, bool cvc3Mode
)
1223 Expr e
= c
->getExpr();
1228 out
<< "QUERY " << e
<< ";";
1230 out
<< "QUERY TRUE;";
1237 static void toStream(std::ostream
& out
, const ResetCommand
* c
, bool cvc3Mode
)
1242 static void toStream(std::ostream
& out
,
1243 const ResetAssertionsCommand
* c
,
1246 out
<< "RESET ASSERTIONS;";
1249 static void toStream(std::ostream
& out
, const QuitCommand
* c
, bool cvc3Mode
)
1254 static void toStream(std::ostream
& out
, const CommandSequence
* c
, bool cvc3Mode
)
1256 for(CommandSequence::const_iterator i
= c
->begin();
1263 static void toStream(std::ostream
& out
,
1264 const DeclarationSequence
* c
,
1267 DeclarationSequence::const_iterator i
= c
->begin();
1269 DeclarationDefinitionCommand
* dd
=
1270 static_cast<DeclarationDefinitionCommand
*>(*i
++);
1272 out
<< dd
->getSymbol() << ", ";
1280 static void toStream(std::ostream
& out
,
1281 const DeclareFunctionCommand
* c
,
1284 out
<< c
->getSymbol() << " : " << c
->getType() << ";";
1287 static void toStream(std::ostream
& out
,
1288 const DefineFunctionCommand
* c
,
1291 Expr func
= c
->getFunction();
1292 const vector
<Expr
>& formals
= c
->getFormals();
1293 Expr formula
= c
->getFormula();
1294 out
<< func
<< " : " << func
.getType() << " = ";
1295 if(formals
.size() > 0) {
1297 vector
<Expr
>::const_iterator i
= formals
.begin();
1298 while(i
!= formals
.end()) {
1299 out
<< (*i
) << ":" << (*i
).getType();
1300 if(++i
!= formals
.end()) {
1306 out
<< formula
<< ";";
1309 static void toStream(std::ostream
& out
,
1310 const DeclareTypeCommand
* c
,
1313 if(c
->getArity() > 0) {
1315 out
<< "ERROR: Don't know how to print parameterized type declaration "
1316 "in CVC language." << endl
;
1318 out
<< c
->getSymbol() << " : TYPE;";
1322 static void toStream(std::ostream
& out
,
1323 const DefineTypeCommand
* c
,
1326 if(c
->getParameters().size() > 0) {
1327 out
<< "ERROR: Don't know how to print parameterized type definition "
1328 "in CVC language:" << endl
<< c
->toString() << endl
;
1330 out
<< c
->getSymbol() << " : TYPE = " << c
->getType() << ";";
1334 static void toStream(std::ostream
& out
,
1335 const DefineNamedFunctionCommand
* c
,
1338 toStream(out
, static_cast<const DefineFunctionCommand
*>(c
), cvc3Mode
);
1341 static void toStream(std::ostream
& out
, const SimplifyCommand
* c
, bool cvc3Mode
)
1343 out
<< "TRANSFORM " << c
->getTerm() << ";";
1346 static void toStream(std::ostream
& out
, const GetValueCommand
* c
, bool cvc3Mode
)
1348 const vector
<Expr
>& terms
= c
->getTerms();
1349 Assert(!terms
.empty());
1350 out
<< "GET_VALUE ";
1351 copy(terms
.begin(), terms
.end() - 1, ostream_iterator
<Expr
>(out
, ";\nGET_VALUE "));
1352 out
<< terms
.back() << ";";
1355 static void toStream(std::ostream
& out
, const GetModelCommand
* c
, bool cvc3Mode
)
1357 out
<< "COUNTERMODEL;";
1360 static void toStream(std::ostream
& out
,
1361 const GetAssignmentCommand
* c
,
1364 out
<< "% (get-assignment)";
1367 static void toStream(std::ostream
& out
,
1368 const GetAssertionsCommand
* c
,
1374 static void toStream(std::ostream
& out
, const GetProofCommand
* c
, bool cvc3Mode
)
1376 out
<< "DUMP_PROOF;";
1379 static void toStream(std::ostream
& out
,
1380 const GetUnsatCoreCommand
* c
,
1383 out
<< "DUMP_UNSAT_CORE;";
1386 static void toStream(std::ostream
& out
,
1387 const SetBenchmarkStatusCommand
* c
,
1390 out
<< "% (set-info :status " << c
->getStatus() << ")";
1393 static void toStream(std::ostream
& out
,
1394 const SetBenchmarkLogicCommand
* c
,
1397 out
<< "OPTION \"logic\" \"" << c
->getLogic() << "\";";
1400 static void toStream(std::ostream
& out
, const SetInfoCommand
* c
, bool cvc3Mode
)
1402 out
<< "% (set-info " << c
->getFlag() << " ";
1403 OutputLanguage language
=
1404 cvc3Mode
? language::output::LANG_CVC3
: language::output::LANG_CVC4
;
1405 SExpr::toStream(out
, c
->getSExpr(), language
);
1409 static void toStream(std::ostream
& out
, const GetInfoCommand
* c
, bool cvc3Mode
)
1411 out
<< "% (get-info " << c
->getFlag() << ")";
1414 static void toStream(std::ostream
& out
,
1415 const SetOptionCommand
* c
,
1418 out
<< "OPTION \"" << c
->getFlag() << "\" ";
1419 SExpr::toStream(out
, c
->getSExpr(), language::output::LANG_CVC4
);
1423 static void toStream(std::ostream
& out
,
1424 const GetOptionCommand
* c
,
1427 out
<< "% (get-option " << c
->getFlag() << ")";
1430 static void toStream(std::ostream
& out
,
1431 const DatatypeDeclarationCommand
* c
,
1434 const vector
<DatatypeType
>& datatypes
= c
->getDatatypes();
1435 //do not print tuple/datatype internal declarations
1436 if( datatypes
.size()!=1 || ( !datatypes
[0].getDatatype().isTuple() && !datatypes
[0].getDatatype().isRecord() ) ){
1437 out
<< "DATATYPE" << endl
;
1438 bool firstDatatype
= true;
1439 for(vector
<DatatypeType
>::const_iterator i
= datatypes
.begin(),
1440 i_end
= datatypes
.end();
1443 if(! firstDatatype
) {
1446 const Datatype
& dt
= (*i
).getDatatype();
1447 out
<< " " << dt
.getName();
1448 if(dt
.isParametric()) {
1450 for(size_t j
= 0; j
< dt
.getNumParameters(); ++j
) {
1454 out
<< dt
.getParameter(j
);
1459 bool firstConstructor
= true;
1460 for(Datatype::const_iterator j
= dt
.begin(); j
!= dt
.end(); ++j
) {
1461 if(! firstConstructor
) {
1464 firstConstructor
= false;
1465 const DatatypeConstructor
& c
= *j
;
1467 if(c
.getNumArgs() > 0) {
1469 bool firstSelector
= true;
1470 for(DatatypeConstructor::const_iterator k
= c
.begin(); k
!= c
.end(); ++k
) {
1471 if(! firstSelector
) {
1474 firstSelector
= false;
1475 const DatatypeConstructorArg
& selector
= *k
;
1476 Type t
= SelectorType(selector
.getType()).getRangeType();
1477 if( t
.isDatatype() ){
1478 const Datatype
& sdt
= ((DatatypeType
)t
).getDatatype();
1479 out
<< selector
.getName() << ": " << sdt
.getName();
1481 out
<< selector
.getName() << ": " << t
;
1487 firstDatatype
= false;
1489 out
<< endl
<< "END;";
1493 static void toStream(std::ostream
& out
, const CommentCommand
* c
, bool cvc3Mode
)
1495 out
<< "% " << c
->getComment();
1498 static void toStream(std::ostream
& out
, const EmptyCommand
* c
, bool cvc3Mode
) {}
1500 static void toStream(std::ostream
& out
, const EchoCommand
* c
, bool cvc3Mode
)
1502 out
<< "ECHO \"" << c
->getOutput() << "\";";
1506 static bool tryToStream(std::ostream
& out
, const Command
* c
, bool cvc3Mode
)
1508 if(typeid(*c
) == typeid(T
)) {
1509 toStream(out
, dynamic_cast<const T
*>(c
), cvc3Mode
);
1515 static void toStream(std::ostream
& out
, const CommandSuccess
* s
, bool cvc3Mode
)
1517 if(Command::printsuccess::getPrintSuccess(out
)) {
1518 out
<< "OK" << endl
;
1522 static void toStream(std::ostream
& out
,
1523 const CommandUnsupported
* s
,
1526 out
<< "UNSUPPORTED" << endl
;
1529 static void toStream(std::ostream
& out
,
1530 const CommandInterrupted
* s
,
1533 out
<< "INTERRUPTED" << endl
;
1536 static void toStream(std::ostream
& out
, const CommandFailure
* s
, bool cvc3Mode
)
1538 out
<< s
->getMessage() << endl
;
1542 static bool tryToStream(std::ostream
& out
,
1543 const CommandStatus
* s
,
1546 if(typeid(*s
) == typeid(T
)) {
1547 toStream(out
, dynamic_cast<const T
*>(s
), cvc3Mode
);
1553 }/* CVC4::printer::cvc namespace */
1554 }/* CVC4::printer namespace */
1555 }/* CVC4 namespace */