/*++ Copyright (c) 2019 Microsoft Corporation Module Name: display_dimacs.h Abstract: Display expressions in DIMACS format. Author: Nikolaj Bjorner (nbjorner0 2019-01-24 Revision History: --*/ #include "ast.h" #include "display_dimacs.h" std::ostream& display_dimacs(std::ostream& out, expr_ref_vector const& fmls, bool include_names) { ast_manager& m = fmls.m(); unsigned_vector expr2var; ptr_vector exprs; unsigned num_vars = 0; unsigned num_cls = fmls.size(); bool is_from_dimacs = true; for (expr * f : fmls) { unsigned num_lits; expr * const * lits; if (m.is_or(f)) { num_lits = to_app(f)->get_num_args(); lits = to_app(f)->get_args(); } else { num_lits = 1; lits = &f; } for (unsigned j = 0; j < num_lits; j++) { expr * l = lits[j]; if (m.is_not(l)) l = to_app(l)->get_arg(0); if (!is_uninterp_const(l)) { is_from_dimacs = false; break; } symbol const& s = to_app(l)->get_decl()->get_name(); if (s.is_numerical() && s.get_num() > 0) { if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) { ++num_vars; expr2var.setx(l->get_id(), s.get_num(), UINT_MAX); exprs.setx(l->get_id(), l, nullptr); } continue; } is_from_dimacs = false; break; } if (!is_from_dimacs) { num_vars = 0; expr2var.reset(); exprs.reset(); break; } } if (!is_from_dimacs) { for (expr * f : fmls) { unsigned num_lits; expr * const * lits; if (m.is_or(f)) { num_lits = to_app(f)->get_num_args(); lits = to_app(f)->get_args(); } else { num_lits = 1; lits = &f; } for (unsigned j = 0; j < num_lits; j++) { expr * l = lits[j]; if (m.is_not(l)) l = to_app(l)->get_arg(0); if (expr2var.get(l->get_id(), UINT_MAX) == UINT_MAX) { num_vars++; expr2var.setx(l->get_id(), num_vars, UINT_MAX); exprs.setx(l->get_id(), l, nullptr); } } } } out << "p cnf " << num_vars << " " << num_cls << "\n"; for (expr* f : fmls) { unsigned num_lits; expr * const * lits; if (m.is_or(f)) { num_lits = to_app(f)->get_num_args(); lits = to_app(f)->get_args(); } else { num_lits = 1; lits = &f; } for (unsigned j = 0; j < num_lits; j++) { expr * l = lits[j]; if (m.is_not(l)) { out << "-"; l = to_app(l)->get_arg(0); } SASSERT(exprs[l->get_id()]); out << expr2var[l->get_id()] << " "; } out << "0\n"; } if (include_names && !is_from_dimacs) { for (expr* e : exprs) { if (e && is_app(e)) { symbol const& n = to_app(e)->get_decl()->get_name(); out << "c " << expr2var[e->get_id()] << " " << n << "\n"; } } } return out; }