From 4987fc9800830d37d22c7e4f31a3f258146cdf66 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Tue, 18 May 2021 11:36:22 -0500 Subject: [PATCH] Fix smt2 printing (#6558) This fixes bugs related to the smt2 printer where we rely on stream operators for recursive printing calls for certain parts of terms. Notice that a call to `out << n;` within `SmtPrinter::toStream(...)` is wrong since then recursively `n` is printed with the current output language. This means that if one were to ask to print a term in SMT2 format and the output language is not SMT2, then the above call would print `n` in a different format. This is required to fix bugs in the LFSC proof converter, which explicitly changes the output format to SMT2. --- src/printer/smt2/smt2_printer.cpp | 29 +++++++++++++++++++++++------ src/printer/smt2/smt2_printer.h | 2 ++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp index eb80bd5a2..72d7fca89 100644 --- a/src/printer/smt2/smt2_printer.cpp +++ b/src/printer/smt2/smt2_printer.cpp @@ -245,7 +245,9 @@ void Smt2Printer::toStream(std::ostream& out, const std::vector& snvec = sn.getVec(); if (snvec.empty()) { - out << "(as seq.empty " << n.getType() << ")"; + out << "(as seq.empty "; + toStreamType(out, n.getType()); + out << ")"; } if (snvec.size() > 1) { @@ -264,7 +266,9 @@ void Smt2Printer::toStream(std::ostream& out, case kind::STORE_ALL: { ArrayStoreAll asa = n.getConst(); - out << "((as const " << asa.getType() << ") " << asa.getValue() << ")"; + out << "((as const "; + toStreamType(out, asa.getType()); + out << ") " << asa.getValue() << ")"; break; } @@ -284,7 +288,8 @@ void Smt2Printer::toStream(std::ostream& out, out << "(Tuple"; for (unsigned int i = 0; i < nargs; i++) { - out << " " << dt[0][i].getRangeType(); + out << " "; + toStreamType(out, dt[0][i].getRangeType()); } out << ")"; } @@ -305,11 +310,15 @@ void Smt2Printer::toStream(std::ostream& out, } case kind::EMPTYSET: - out << "(as emptyset " << n.getConst().getType() << ")"; + out << "(as emptyset "; + toStreamType(out, n.getConst().getType()); + out << ")"; break; case kind::EMPTYBAG: - out << "(as emptybag " << n.getConst().getType() << ")"; + out << "(as emptybag "; + toStreamType(out, n.getConst().getType()); + out << ")"; break; case kind::BITVECTOR_EXTRACT_OP: { @@ -774,7 +783,8 @@ void Smt2Printer::toStream(std::ostream& out, case kind::BITVECTOR_ROTATE_LEFT: case kind::BITVECTOR_ROTATE_RIGHT: case kind::INT_TO_BITVECTOR: - out << n.getOperator() << ' '; + toStream(out, n.getOperator(), toDepth, nullptr); + out << ' '; stillNeedToPrintParams = false; break; @@ -1176,6 +1186,7 @@ std::string Smt2Printer::smtKindString(Kind k, Variant v) case kind::BITVECTOR_SIGN_EXTEND: return "sign_extend"; case kind::BITVECTOR_ROTATE_LEFT: return "rotate_left"; case kind::BITVECTOR_ROTATE_RIGHT: return "rotate_right"; + case kind::INT_TO_BITVECTOR: return "int2bv"; case kind::UNION: return "union"; case kind::INTERSECTION: return "intersection"; @@ -1325,6 +1336,12 @@ std::string Smt2Printer::smtKindString(Kind k, Variant v) return kind::kindToString(k); } +void Smt2Printer::toStreamType(std::ostream& out, TypeNode tn) const +{ + // we currently must call TypeNode::toStream here. + tn.toStream(out, language::output::LANG_SMTLIB_V2_6); +} + template static bool tryToStream(std::ostream& out, const Command* c); template diff --git a/src/printer/smt2/smt2_printer.h b/src/printer/smt2/smt2_printer.h index 4921566d1..15f45a10e 100644 --- a/src/printer/smt2/smt2_printer.h +++ b/src/printer/smt2/smt2_printer.h @@ -235,6 +235,8 @@ class Smt2Printer : public cvc5::Printer TNode n, int toDepth, LetBinding* lbind = nullptr) const; + /** To stream type node, which ensures tn is printed in smt2 format */ + void toStreamType(std::ostream& out, TypeNode tn) const; /** * To stream, with a forced type. This method is used in some corner cases * to force a node n to be printed as if it had type tn. This is used e.g. -- 2.30.2