1 /********************* */
2 /*! \file cvc_printer.cpp
4 ** Top contributors (to current version):
5 ** Morgan Deters, Dejan Jovanovic, Andrew Reynolds
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2016 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(std::ostream
& out
, TNode n
, int toDepth
, bool types
, size_t dag
) const throw() {
47 DagificationVisitor
dv(dag
);
48 NodeVisitor
<DagificationVisitor
> visitor
;
50 const theory::SubstitutionMap
& lets
= dv
.getLets();
54 for(theory::SubstitutionMap::const_iterator i
= lets
.begin();
62 toStream(out
, (*i
).second
, toDepth
, types
, false);
64 toStream(out
, (*i
).first
, toDepth
, types
, false);
68 Node body
= dv
.getDagifiedBody();
69 toStream(out
, body
, toDepth
, types
, false);
71 toStream(out
, n
, toDepth
, types
, false);
75 void CvcPrinter::toStream(std::ostream
& out
, TNode n
, int depth
, bool types
, bool bracket
) const throw() {
83 if(n
.getKind() == kind::NULL_EXPR
) {
91 if(n
.getAttribute(expr::VarNameAttr(), s
)) {
94 if(n
.getKind() == kind::VARIABLE
) {
97 out
<< n
.getKind() << '_';
102 // print the whole type, but not *its* type
104 n
.getType().toStream(out
, language::output::LANG_CVC4
);
110 if(n
.getMetaKind() == kind::metakind::CONSTANT
) {
111 switch(n
.getKind()) {
112 case kind::BITVECTOR_TYPE
:
113 out
<< "BITVECTOR(" << n
.getConst
<BitVectorSize
>().size
<< ")";
115 case kind::CONST_BITVECTOR
: {
116 const BitVector
& bv
= n
.getConst
<BitVector
>();
117 const Integer
& x
= bv
.getValue();
119 unsigned n
= bv
.getSize();
121 out
<< (x
.testBit(n
) ? '1' : '0');
125 case kind::CONST_BOOLEAN
:
126 // the default would print "1" or "0" for bool, that's not correct
128 out
<< (n
.getConst
<bool>() ? "TRUE" : "FALSE");
130 case kind::CONST_RATIONAL
: {
131 const Rational
& rat
= n
.getConst
<Rational
>();
132 if(rat
.isIntegral()) {
133 out
<< rat
.getNumerator();
135 out
<< '(' << rat
.getNumerator() << '/' << rat
.getDenominator() << ')';
139 case kind::SUBRANGE_TYPE
:
140 out
<< '[' << n
.getConst
<SubrangeBounds
>() << ']';
142 case kind::SUBTYPE_TYPE
:
143 out
<< "SUBTYPE(" << n
.getConst
<Predicate
>() << ")";
145 case kind::TYPE_CONSTANT
:
146 switch(TypeConstant tc
= n
.getConst
<TypeConstant
>()) {
165 case kind::DATATYPE_TYPE
: {
166 const Datatype
& dt
= (NodeManager::currentNM()->getDatatypeForIndex( n
.getConst
< DatatypeIndexConstant
>().getIndex() ));
169 for (unsigned i
= 0; i
< dt
[0].getNumArgs(); ++ i
) {
173 Type t
= ((SelectorType
)dt
[0][i
].getSelector().getType()).getRangeType();
177 }else if( dt
.isRecord() ){
179 for (unsigned i
= 0; i
< dt
[0].getNumArgs(); ++ i
) {
183 Type t
= ((SelectorType
)dt
[0][i
].getSelector().getType()).getRangeType();
184 out
<< dt
[0][i
].getSelector() << ":" << t
;
194 out
<< "{} :: " << n
.getConst
<EmptySet
>().getType();
197 case kind::STORE_ALL
: {
198 const ArrayStoreAll
& asa
= n
.getConst
<ArrayStoreAll
>();
199 out
<< "ARRAY(" << asa
.getType().getIndexType() << " OF "
200 << asa
.getType().getConstituentType() << ") : " << asa
.getExpr();
205 // Fall back to whatever operator<< does on underlying type; we
206 // might luck out and print something reasonable.
207 kind::metakind::NodeValueConstPrinter::toStream(out
, n
);
219 //The default operation type is PREFIX
222 stringstream op
; // operation (such as '+')
224 switch(n
.getKind()) {
233 toStream(out
, n
[0], depth
, types
, true);
235 toStream(out
, n
[1], depth
, types
, true);
237 toStream(out
, n
[2], depth
, types
, true);
241 case kind::SEXPR_TYPE
:
243 for (unsigned i
= 0; i
< n
.getNumChildren(); ++ i
) {
247 toStream(out
, n
[i
], depth
, types
, false);
257 toStream(out
, n
[0], depth
, types
, true);
259 toStream(out
, n
[1], depth
, types
, true);
264 toStream(op
, n
.getOperator(), depth
, types
, true);
267 case kind::DISTINCT
: // chain and distinct not supported directly in CVC4, blast them away with the rewriter
268 toStream(out
, theory::Rewriter::rewrite(n
), depth
, types
, true);
270 case kind::SORT_TYPE
:
273 if(n
.getAttribute(expr::VarNameAttr(), name
)) {
308 toStream(op
, n
.getOperator(), depth
, types
, false);
310 case kind::CARDINALITY_CONSTRAINT
:
311 case kind::COMBINED_CARDINALITY_CONSTRAINT
:
312 out
<< "CARDINALITY_CONSTRAINT";
315 case kind::FUNCTION_TYPE
:
316 if (n
.getNumChildren() > 1) {
317 if (n
.getNumChildren() > 2) {
320 for (unsigned i
= 1; i
< n
.getNumChildren(); ++i
) {
324 toStream(out
, n
[i
- 1], depth
, types
, false);
326 if (n
.getNumChildren() > 2) {
331 toStream(out
, n
[n
.getNumChildren() - 1], depth
, types
, false);
336 case kind::PARAMETRIC_DATATYPE
: {
337 const Datatype
& dt
= (NodeManager::currentNM()->getDatatypeForIndex( n
[0].getConst
< DatatypeIndexConstant
>().getIndex() ));
338 out
<< dt
.getName() << '[';
339 for(unsigned i
= 1; i
< n
.getNumChildren(); ++i
) {
349 case kind::APPLY_TYPE_ASCRIPTION
: {
350 toStream(out
, n
[0], depth
, types
, false);
352 TypeNode t
= TypeNode::fromType(n
.getOperator().getConst
<AscriptionType
>().getType());
353 out
<< (t
.isFunctionLike() ? t
.getRangeType() : t
);
357 case kind::APPLY_CONSTRUCTOR
: {
358 TypeNode t
= n
.getType();
360 if( n
.getNumChildren()==1 ){
363 }else if( t
.isRecord() ){
364 const Record
& rec
= t
.getRecord();
366 TNode::iterator i
= n
.begin();
368 const Record::FieldVector
& fields
= rec
.getFields();
369 for(Record::FieldVector::const_iterator j
= fields
.begin(); j
!= fields
.end(); ++i
, ++j
) {
373 out
<< (*j
).first
<< " := ";
374 toStream(out
, *i
, depth
, types
, false);
380 toStream(op
, n
.getOperator(), depth
, types
, false);
384 case kind::APPLY_SELECTOR
:
385 case kind::APPLY_SELECTOR_TOTAL
: {
386 TypeNode t
= n
.getType();
388 toStream(out
, n
[0], depth
, types
, true);
389 out
<< '.' << Datatype::indexOf( n
.getOperator().toExpr() );
390 }else if( t
.isRecord() ){
391 toStream(out
, n
[0], depth
, types
, true);
392 const Record
& rec
= t
.getRecord();
393 unsigned index
= Datatype::indexOf( n
.getOperator().toExpr() );
394 std::pair
<std::string
, Type
> fld
= rec
[index
];
395 out
<< '.' << fld
.first
;
397 toStream(op
, n
.getOperator(), depth
, types
, false);
401 case kind::APPLY_TESTER
:
402 toStream(op
, n
.getOperator(), depth
, types
, false);
404 case kind::CONSTRUCTOR_TYPE
:
405 case kind::SELECTOR_TYPE
:
406 if(n
.getNumChildren() > 1) {
407 if(n
.getNumChildren() > 2) {
410 for(unsigned i
= 0; i
< n
.getNumChildren() - 1; ++i
) {
414 toStream(out
, n
[i
], depth
, types
, false);
416 if(n
.getNumChildren() > 2) {
421 toStream(out
, n
[n
.getNumChildren() - 1], depth
, types
, false);
423 case kind::TESTER_TYPE
:
424 toStream(out
, n
[0], depth
, types
, false);
425 out
<< " -> BOOLEAN";
428 case kind::TUPLE_UPDATE
:
429 toStream(out
, n
[0], depth
, types
, true);
430 out
<< " WITH ." << n
.getOperator().getConst
<TupleUpdate
>().getIndex() << " := ";
431 toStream(out
, n
[1], depth
, types
, true);
434 case kind::RECORD_UPDATE
:
435 toStream(out
, n
[0], depth
, types
, true);
436 out
<< " WITH ." << n
.getOperator().getConst
<RecordUpdate
>().getField() << " := ";
437 toStream(out
, n
[1], depth
, types
, true);
442 case kind::ARRAY_TYPE
:
444 toStream(out
, n
[0], depth
, types
, false);
446 toStream(out
, n
[1], depth
, types
, false);
450 toStream(out
, n
[0], depth
, types
, true);
452 toStream(out
, n
[1], depth
, types
, false);
459 while(stk
.top()[0].getKind() == kind::STORE
) {
460 stk
.push(stk
.top()[0]);
466 toStream(out
, x
[0], depth
, types
, false);
468 toStream(out
, x
[1], depth
, types
, false);
470 toStream(out
, x
[2], depth
, types
, false);
472 while(!stk
.empty()) {
475 toStream(out
, x
[1], depth
, types
, false);
477 toStream(out
, x
[2], depth
, types
, false);
508 case kind::INTS_DIVISION
:
512 case kind::INTS_MODULUS
:
540 case kind::IS_INTEGER
:
544 case kind::TO_INTEGER
:
549 // ignore, there is no to-real in CVC language
550 toStream(out
, n
[0], depth
, types
, false);
552 case kind::DIVISIBLE
:
554 toStream(out
, n
[0], depth
, types
, false);
555 out
<< ", " << n
.getOperator().getConst
<Divisible
>().k
<< ")";
559 case kind::BITVECTOR_XOR
:
562 case kind::BITVECTOR_NAND
:
565 case kind::BITVECTOR_NOR
:
568 case kind::BITVECTOR_XNOR
:
571 case kind::BITVECTOR_COMP
:
574 case kind::BITVECTOR_UDIV
:
577 case kind::BITVECTOR_UDIV_TOTAL
:
578 op
<< "BVUDIV_TOTAL";
580 case kind::BITVECTOR_UREM
:
583 case kind::BITVECTOR_UREM_TOTAL
:
584 op
<< "BVUREM_TOTAL";
586 case kind::BITVECTOR_SDIV
:
589 case kind::BITVECTOR_SREM
:
592 case kind::BITVECTOR_SMOD
:
595 case kind::BITVECTOR_SHL
:
598 case kind::BITVECTOR_LSHR
:
601 case kind::BITVECTOR_ASHR
:
604 case kind::BITVECTOR_ULT
:
607 case kind::BITVECTOR_ULE
:
610 case kind::BITVECTOR_UGT
:
613 case kind::BITVECTOR_UGE
:
616 case kind::BITVECTOR_SLT
:
619 case kind::BITVECTOR_SLE
:
622 case kind::BITVECTOR_SGT
:
625 case kind::BITVECTOR_SGE
:
628 case kind::BITVECTOR_NEG
:
631 case kind::BITVECTOR_NOT
:
634 case kind::BITVECTOR_AND
:
638 case kind::BITVECTOR_OR
:
642 case kind::BITVECTOR_CONCAT
:
646 case kind::BITVECTOR_PLUS
: {
647 // This interprets a BITVECTOR_PLUS as a bvadd in SMT-LIB
648 Assert(n
.getType().isBitVector());
649 unsigned numc
= n
.getNumChildren()-2;
651 while (child
< numc
) {
653 out
<< BitVectorType(n
.getType().toType()).getSize();
655 toStream(out
, n
[child
], depth
, types
, false);
660 out
<< BitVectorType(n
.getType().toType()).getSize();
662 toStream(out
, n
[child
], depth
, types
, false);
664 toStream(out
, n
[child
+ 1], depth
, types
, false);
673 case kind::BITVECTOR_SUB
:
675 Assert(n
.getType().isBitVector());
676 out
<< BitVectorType(n
.getType().toType()).getSize();
678 toStream(out
, n
[0], depth
, types
, false);
680 toStream(out
, n
[1], depth
, types
, false);
684 case kind::BITVECTOR_MULT
: {
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_EXTRACT
:
711 op
<< n
.getOperator().getConst
<BitVectorExtract
>();
714 case kind::BITVECTOR_BITOF
:
715 op
<< n
.getOperator().getConst
<BitVectorBitOf
>();
718 case kind::BITVECTOR_REPEAT
:
720 toStream(out
, n
[0], depth
, types
, false);
721 out
<< ", " << n
.getOperator().getConst
<BitVectorRepeat
>() << ')';
724 case kind::BITVECTOR_ZERO_EXTEND
:
725 out
<< "BVZEROEXTEND(";
726 toStream(out
, n
[0], depth
, types
, false);
727 out
<< ", " << n
.getOperator().getConst
<BitVectorZeroExtend
>() << ')';
730 case kind::BITVECTOR_SIGN_EXTEND
:
732 toStream(out
, n
[0], depth
, types
, false);
733 out
<< ", " << BitVectorType(n
.getType().toType()).getSize() << ')';
736 case kind::BITVECTOR_ROTATE_LEFT
:
738 toStream(out
, n
[0], depth
, types
, false);
739 out
<< ", " << n
.getOperator().getConst
<BitVectorRotateLeft
>() << ')';
742 case kind::BITVECTOR_ROTATE_RIGHT
:
744 toStream(out
, n
[0], depth
, types
, false);
745 out
<< ", " << n
.getOperator().getConst
<BitVectorRotateRight
>() << ')';
752 toStream(out
, n
[0], depth
, types
, false);
759 case kind::INTERSECTION
:
783 case kind::TRANSPOSE
:
791 case kind::SINGLETON
:
793 toStream(out
, n
[0], depth
, types
, false);
803 toStream(out
, n
[i
++], depth
, types
, false);
804 for(;i
+1 < n
.getNumChildren(); ++i
) {
806 toStream(out
, n
[i
], depth
, types
, false);
809 toStream(out
, n
[i
], depth
, types
, true);
818 toStream(out
, n
[0], depth
, types
, false);
827 toStream(out
, n
[0], depth
, types
, false);
829 toStream(out
, n
[1], depth
, types
, false);
831 // TODO: user patterns?
835 toStream(out
, n
[0], depth
, types
, false);
837 toStream(out
, n
[1], depth
, types
, false);
839 // TODO: user patterns?
841 case kind::INST_CONSTANT
:
842 out
<< "INST_CONSTANT";
844 case kind::BOUND_VAR_LIST
:
846 for(size_t i
= 0; i
< n
.getNumChildren(); ++i
) {
850 toStream(out
, n
[i
], -1, true, false); // ascribe types
854 case kind::INST_PATTERN
:
855 out
<< "INST_PATTERN";
857 case kind::INST_PATTERN_LIST
:
858 out
<< "INST_PATTERN_LIST";
862 Warning() << "Kind printing not implemented for the case of " << n
.getKind() << endl
;
868 out
<< op
.str() << '(';
880 for (unsigned i
= 0; i
< n
.getNumChildren(); ++ i
) {
882 if (opType
== INFIX
) {
883 out
<< ' ' << op
.str() << ' ';
888 toStream(out
, n
[i
], depth
, types
, opType
== INFIX
);
901 out
<< ')' << op
.str();
905 }/* CvcPrinter::toStream(TNode) */
908 static bool tryToStream(std::ostream
& out
, const Command
* c
, bool cvc3Mode
) throw();
910 void CvcPrinter::toStream(std::ostream
& out
, const Command
* c
,
911 int toDepth
, bool types
, size_t dag
) const throw() {
912 expr::ExprSetDepth::Scope
sdScope(out
, toDepth
);
913 expr::ExprPrintTypes::Scope
ptScope(out
, types
);
914 expr::ExprDag::Scope
dagScope(out
, dag
);
916 if(tryToStream
<AssertCommand
>(out
, c
, d_cvc3Mode
) ||
917 tryToStream
<PushCommand
>(out
, c
, d_cvc3Mode
) ||
918 tryToStream
<PopCommand
>(out
, c
, d_cvc3Mode
) ||
919 tryToStream
<CheckSatCommand
>(out
, c
, d_cvc3Mode
) ||
920 tryToStream
<QueryCommand
>(out
, c
, d_cvc3Mode
) ||
921 tryToStream
<ResetCommand
>(out
, c
, d_cvc3Mode
) ||
922 tryToStream
<ResetAssertionsCommand
>(out
, c
, d_cvc3Mode
) ||
923 tryToStream
<QuitCommand
>(out
, c
, d_cvc3Mode
) ||
924 tryToStream
<DeclarationSequence
>(out
, c
, d_cvc3Mode
) ||
925 tryToStream
<CommandSequence
>(out
, c
, d_cvc3Mode
) ||
926 tryToStream
<DeclareFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
927 tryToStream
<DeclareTypeCommand
>(out
, c
, d_cvc3Mode
) ||
928 tryToStream
<DefineTypeCommand
>(out
, c
, d_cvc3Mode
) ||
929 tryToStream
<DefineNamedFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
930 tryToStream
<DefineFunctionCommand
>(out
, c
, d_cvc3Mode
) ||
931 tryToStream
<SimplifyCommand
>(out
, c
, d_cvc3Mode
) ||
932 tryToStream
<GetValueCommand
>(out
, c
, d_cvc3Mode
) ||
933 tryToStream
<GetModelCommand
>(out
, c
, d_cvc3Mode
) ||
934 tryToStream
<GetAssignmentCommand
>(out
, c
, d_cvc3Mode
) ||
935 tryToStream
<GetAssertionsCommand
>(out
, c
, d_cvc3Mode
) ||
936 tryToStream
<GetProofCommand
>(out
, c
, d_cvc3Mode
) ||
937 tryToStream
<GetUnsatCoreCommand
>(out
, c
, d_cvc3Mode
) ||
938 tryToStream
<SetBenchmarkStatusCommand
>(out
, c
, d_cvc3Mode
) ||
939 tryToStream
<SetBenchmarkLogicCommand
>(out
, c
, d_cvc3Mode
) ||
940 tryToStream
<SetInfoCommand
>(out
, c
, d_cvc3Mode
) ||
941 tryToStream
<GetInfoCommand
>(out
, c
, d_cvc3Mode
) ||
942 tryToStream
<SetOptionCommand
>(out
, c
, d_cvc3Mode
) ||
943 tryToStream
<GetOptionCommand
>(out
, c
, d_cvc3Mode
) ||
944 tryToStream
<DatatypeDeclarationCommand
>(out
, c
, d_cvc3Mode
) ||
945 tryToStream
<CommentCommand
>(out
, c
, d_cvc3Mode
) ||
946 tryToStream
<EmptyCommand
>(out
, c
, d_cvc3Mode
) ||
947 tryToStream
<EchoCommand
>(out
, c
, d_cvc3Mode
)) {
951 out
<< "ERROR: don't know how to print a Command of class: "
952 << typeid(*c
).name() << endl
;
954 }/* CvcPrinter::toStream(Command*) */
957 static bool tryToStream(std::ostream
& out
, const CommandStatus
* s
, bool cvc3Mode
) throw();
959 void CvcPrinter::toStream(std::ostream
& out
, const CommandStatus
* s
) const throw() {
961 if(tryToStream
<CommandSuccess
>(out
, s
, d_cvc3Mode
) ||
962 tryToStream
<CommandFailure
>(out
, s
, d_cvc3Mode
) ||
963 tryToStream
<CommandUnsupported
>(out
, s
, d_cvc3Mode
) ||
964 tryToStream
<CommandInterrupted
>(out
, s
, d_cvc3Mode
)) {
968 out
<< "ERROR: don't know how to print a CommandStatus of class: "
969 << typeid(*s
).name() << endl
;
971 }/* CvcPrinter::toStream(CommandStatus*) */
973 void CvcPrinter::toStream(std::ostream
& out
, const Model
& m
, const Command
* c
) const throw() {
974 const theory::TheoryModel
& tm
= (const theory::TheoryModel
&) m
;
975 if(dynamic_cast<const DeclareTypeCommand
*>(c
) != NULL
) {
976 TypeNode tn
= TypeNode::fromType( ((const DeclareTypeCommand
*)c
)->getType() );
977 if( options::modelUninterpDtEnum() && tn
.isSort() &&
978 tm
.d_rep_set
.d_type_reps
.find( tn
)!=tm
.d_rep_set
.d_type_reps
.end() ){
979 out
<< "DATATYPE" << std::endl
;
980 out
<< " " << dynamic_cast<const DeclareTypeCommand
*>(c
)->getSymbol() << " = ";
981 for( size_t i
=0; i
<(*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
.size(); i
++ ){
985 out
<< (*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
[i
] << " ";
987 out
<< std::endl
<< "END;" << std::endl
;
990 // print the cardinality
991 if( tm
.d_rep_set
.d_type_reps
.find( tn
)!=tm
.d_rep_set
.d_type_reps
.end() ){
992 out
<< "% cardinality of " << tn
<< " is " << (*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
.size() << std::endl
;
995 out
<< c
<< std::endl
;
997 // print the representatives
998 if( tm
.d_rep_set
.d_type_reps
.find( tn
)!=tm
.d_rep_set
.d_type_reps
.end() ){
999 for( size_t i
=0; i
<(*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
.size(); i
++ ){
1000 if( (*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
[i
].isVar() ){
1001 out
<< (*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
[i
] << " : " << tn
<< ";" << std::endl
;
1003 out
<< "% rep: " << (*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
[i
] << std::endl
;
1009 } else if(dynamic_cast<const DeclareFunctionCommand
*>(c
) != NULL
) {
1010 Node n
= Node::fromExpr( ((const DeclareFunctionCommand
*)c
)->getFunction() );
1011 if(n
.getKind() == kind::SKOLEM
) {
1012 // don't print out internal stuff
1015 TypeNode tn
= n
.getType();
1017 if( tn
.isFunction() || tn
.isPredicate() ){
1019 for( size_t i
=0; i
<tn
.getNumChildren()-1; i
++ ){
1020 if( i
>0 ) out
<< ", ";
1023 out
<< ") -> " << tn
.getRangeType();
1027 Node val
= Node::fromExpr(tm
.getSmtEngine()->getValue(n
.toExpr()));
1028 if( options::modelUninterpDtEnum() && val
.getKind() == kind::STORE
) {
1029 TypeNode tn
= val
[1].getType();
1030 if (tn
.isSort() && tm
.d_rep_set
.d_type_reps
.find( tn
)!=tm
.d_rep_set
.d_type_reps
.end() ){
1031 Cardinality
indexCard((*tm
.d_rep_set
.d_type_reps
.find(tn
)).second
.size());
1032 val
= theory::arrays::TheoryArraysRewriter::normalizeConstant( val
, indexCard
);
1035 out
<< " = " << val
<< ";" << std::endl
;
1038 //for table format (work in progress)
1039 bool printedModel = false;
1040 if( tn.isFunction() ){
1041 if( options::modelFormatMode()==MODEL_FORMAT_MODE_TABLE ){
1042 //specialized table format for functions
1043 RepSetIterator riter( &d_rep_set );
1044 riter.setFunctionDomain( n );
1045 while( !riter.isFinished() ){
1046 std::vector< Node > children;
1047 children.push_back( n );
1048 for( int i=0; i<riter.getNumTerms(); i++ ){
1049 children.push_back( riter.getTerm( i ) );
1051 Node nn = NodeManager::currentNM()->mkNode( APPLY_UF, children );
1052 Node val = getValue( nn );
1056 printedModel = true;
1061 out
<< c
<< std::endl
;
1065 static void toStream(std::ostream
& out
, const AssertCommand
* c
, bool cvc3Mode
) throw() {
1066 out
<< "ASSERT " << c
->getExpr() << ";";
1069 static void toStream(std::ostream
& out
, const PushCommand
* c
, bool cvc3Mode
) throw() {
1073 static void toStream(std::ostream
& out
, const PopCommand
* c
, bool cvc3Mode
) throw() {
1077 static void toStream(std::ostream
& out
, const CheckSatCommand
* c
, bool cvc3Mode
) throw() {
1078 Expr e
= c
->getExpr();
1083 out
<< "CHECKSAT " << e
<< ";";
1092 static void toStream(std::ostream
& out
, const QueryCommand
* c
, bool cvc3Mode
) throw() {
1093 Expr e
= c
->getExpr();
1098 out
<< "QUERY " << e
<< ";";
1100 out
<< "QUERY TRUE;";
1107 static void toStream(std::ostream
& out
, const ResetCommand
* c
, bool cvc3Mode
) throw() {
1111 static void toStream(std::ostream
& out
, const ResetAssertionsCommand
* c
, bool cvc3Mode
) throw() {
1112 out
<< "RESET ASSERTIONS;";
1115 static void toStream(std::ostream
& out
, const QuitCommand
* c
, bool cvc3Mode
) throw() {
1119 static void toStream(std::ostream
& out
, const CommandSequence
* c
, bool cvc3Mode
) throw() {
1120 for(CommandSequence::const_iterator i
= c
->begin();
1127 static void toStream(std::ostream
& out
, const DeclarationSequence
* c
, bool cvc3Mode
) throw() {
1128 DeclarationSequence::const_iterator i
= c
->begin();
1130 DeclarationDefinitionCommand
* dd
=
1131 static_cast<DeclarationDefinitionCommand
*>(*i
++);
1133 out
<< dd
->getSymbol() << ", ";
1141 static void toStream(std::ostream
& out
, const DeclareFunctionCommand
* c
, bool cvc3Mode
) throw() {
1142 out
<< c
->getSymbol() << " : " << c
->getType() << ";";
1145 static void toStream(std::ostream
& out
, const DefineFunctionCommand
* c
, bool cvc3Mode
) throw() {
1146 Expr func
= c
->getFunction();
1147 const vector
<Expr
>& formals
= c
->getFormals();
1148 Expr formula
= c
->getFormula();
1149 out
<< func
<< " : " << func
.getType() << " = ";
1150 if(formals
.size() > 0) {
1152 vector
<Expr
>::const_iterator i
= formals
.begin();
1153 while(i
!= formals
.end()) {
1154 out
<< (*i
) << ":" << (*i
).getType();
1155 if(++i
!= formals
.end()) {
1161 out
<< formula
<< ";";
1164 static void toStream(std::ostream
& out
, const DeclareTypeCommand
* c
, bool cvc3Mode
) throw() {
1165 if(c
->getArity() > 0) {
1167 out
<< "ERROR: Don't know how to print parameterized type declaration "
1168 "in CVC language." << endl
;
1170 out
<< c
->getSymbol() << " : TYPE;";
1174 static void toStream(std::ostream
& out
, const DefineTypeCommand
* c
, bool cvc3Mode
) throw() {
1175 if(c
->getParameters().size() > 0) {
1176 out
<< "ERROR: Don't know how to print parameterized type definition "
1177 "in CVC language:" << endl
<< c
->toString() << endl
;
1179 out
<< c
->getSymbol() << " : TYPE = " << c
->getType() << ";";
1183 static void toStream(std::ostream
& out
, const DefineNamedFunctionCommand
* c
, bool cvc3Mode
) throw() {
1184 toStream(out
, static_cast<const DefineFunctionCommand
*>(c
), cvc3Mode
);
1187 static void toStream(std::ostream
& out
, const SimplifyCommand
* c
, bool cvc3Mode
) throw() {
1188 out
<< "TRANSFORM " << c
->getTerm() << ";";
1191 static void toStream(std::ostream
& out
, const GetValueCommand
* c
, bool cvc3Mode
) throw() {
1192 const vector
<Expr
>& terms
= c
->getTerms();
1193 Assert(!terms
.empty());
1194 out
<< "GET_VALUE ";
1195 copy(terms
.begin(), terms
.end() - 1, ostream_iterator
<Expr
>(out
, ";\nGET_VALUE "));
1196 out
<< terms
.back() << ";";
1199 static void toStream(std::ostream
& out
, const GetModelCommand
* c
, bool cvc3Mode
) throw() {
1200 out
<< "COUNTERMODEL;";
1203 static void toStream(std::ostream
& out
, const GetAssignmentCommand
* c
, bool cvc3Mode
) throw() {
1204 out
<< "% (get-assignment)";
1207 static void toStream(std::ostream
& out
, const GetAssertionsCommand
* c
, bool cvc3Mode
) throw() {
1211 static void toStream(std::ostream
& out
, const GetProofCommand
* c
, bool cvc3Mode
) throw() {
1212 out
<< "DUMP_PROOF;";
1215 static void toStream(std::ostream
& out
, const GetUnsatCoreCommand
* c
, bool cvc3Mode
) throw() {
1216 out
<< "DUMP_UNSAT_CORE;";
1219 static void toStream(std::ostream
& out
, const SetBenchmarkStatusCommand
* c
, bool cvc3Mode
) throw() {
1220 out
<< "% (set-info :status " << c
->getStatus() << ")";
1223 static void toStream(std::ostream
& out
, const SetBenchmarkLogicCommand
* c
, bool cvc3Mode
) throw() {
1224 out
<< "OPTION \"logic\" \"" << c
->getLogic() << "\";";
1227 static void toStream(std::ostream
& out
, const SetInfoCommand
* c
, bool cvc3Mode
) throw() {
1228 out
<< "% (set-info " << c
->getFlag() << " ";
1229 OutputLanguage language
=
1230 cvc3Mode
? language::output::LANG_CVC3
: language::output::LANG_CVC4
;
1231 SExpr::toStream(out
, c
->getSExpr(), language
);
1235 static void toStream(std::ostream
& out
, const GetInfoCommand
* c
, bool cvc3Mode
) throw() {
1236 out
<< "% (get-info " << c
->getFlag() << ")";
1239 static void toStream(std::ostream
& out
, const SetOptionCommand
* c
, bool cvc3Mode
) throw() {
1240 out
<< "OPTION \"" << c
->getFlag() << "\" ";
1241 SExpr::toStream(out
, c
->getSExpr(), language::output::LANG_CVC4
);
1245 static void toStream(std::ostream
& out
, const GetOptionCommand
* c
, bool cvc3Mode
) throw() {
1246 out
<< "% (get-option " << c
->getFlag() << ")";
1249 static void toStream(std::ostream
& out
, const DatatypeDeclarationCommand
* c
, bool cvc3Mode
) throw() {
1250 const vector
<DatatypeType
>& datatypes
= c
->getDatatypes();
1251 out
<< "DATATYPE" << endl
;
1252 bool firstDatatype
= true;
1253 for(vector
<DatatypeType
>::const_iterator i
= datatypes
.begin(),
1254 i_end
= datatypes
.end();
1257 if(! firstDatatype
) {
1260 const Datatype
& dt
= (*i
).getDatatype();
1261 out
<< " " << dt
.getName();
1262 if(dt
.isParametric()) {
1264 for(size_t j
= 0; j
< dt
.getNumParameters(); ++j
) {
1268 out
<< dt
.getParameter(j
);
1273 bool firstConstructor
= true;
1274 for(Datatype::const_iterator j
= dt
.begin(); j
!= dt
.end(); ++j
) {
1275 if(! firstConstructor
) {
1278 firstConstructor
= false;
1279 const DatatypeConstructor
& c
= *j
;
1281 if(c
.getNumArgs() > 0) {
1283 bool firstSelector
= true;
1284 for(DatatypeConstructor::const_iterator k
= c
.begin(); k
!= c
.end(); ++k
) {
1285 if(! firstSelector
) {
1288 firstSelector
= false;
1289 const DatatypeConstructorArg
& selector
= *k
;
1290 Type t
= SelectorType(selector
.getType()).getRangeType();
1291 if( t
.isDatatype() ){
1292 const Datatype
& sdt
= ((DatatypeType
)t
).getDatatype();
1293 out
<< selector
.getName() << ": " << sdt
.getName();
1295 out
<< selector
.getName() << ": " << t
;
1302 out
<< endl
<< "END;";
1305 static void toStream(std::ostream
& out
, const CommentCommand
* c
, bool cvc3Mode
) throw() {
1306 out
<< "% " << c
->getComment();
1309 static void toStream(std::ostream
& out
, const EmptyCommand
* c
, bool cvc3Mode
) throw() {
1312 static void toStream(std::ostream
& out
, const EchoCommand
* c
, bool cvc3Mode
) throw() {
1313 out
<< "ECHO \"" << c
->getOutput() << "\";";
1317 static bool tryToStream(std::ostream
& out
, const Command
* c
, bool cvc3Mode
) throw() {
1318 if(typeid(*c
) == typeid(T
)) {
1319 toStream(out
, dynamic_cast<const T
*>(c
), cvc3Mode
);
1325 static void toStream(std::ostream
& out
, const CommandSuccess
* s
, bool cvc3Mode
) throw() {
1326 if(Command::printsuccess::getPrintSuccess(out
)) {
1327 out
<< "OK" << endl
;
1331 static void toStream(std::ostream
& out
, const CommandUnsupported
* s
, bool cvc3Mode
) throw() {
1332 out
<< "UNSUPPORTED" << endl
;
1335 static void toStream(std::ostream
& out
, const CommandInterrupted
* s
, bool cvc3Mode
) throw() {
1336 out
<< "INTERRUPTED" << endl
;
1339 static void toStream(std::ostream
& out
, const CommandFailure
* s
, bool cvc3Mode
) throw() {
1340 out
<< s
->getMessage() << endl
;
1344 static bool tryToStream(std::ostream
& out
, const CommandStatus
* s
, bool cvc3Mode
) throw() {
1345 if(typeid(*s
) == typeid(T
)) {
1346 toStream(out
, dynamic_cast<const T
*>(s
), cvc3Mode
);
1352 }/* CVC4::printer::cvc namespace */
1353 }/* CVC4::printer namespace */
1354 }/* CVC4 namespace */