#pragma once
#include "util/ref.h"
#include "ast/ast_pp_util.h"
#include "model/model.h"
#include "ast/converters/converter.h"
class labels_vec : public svector<symbol> {};
class smt2_pp_environment;
class model_converter : public converter {
protected:
smt2_pp_environment* m_env = nullptr;
bool m_completion = true;
static void display_add(std::ostream& out, smt2_pp_environment& env, ast_manager& m, func_decl* f, expr* e);
void display_add(std::ostream& out, ast_manager& m, func_decl* f, expr* e) const;
void display_del(std::ostream& out, func_decl* f) const;
void display_add(std::ostream& out, ast_manager& m);
public:
void set_completion(bool f) { m_completion = f; }
virtual void operator()(model_ref & m) = 0;
virtual void operator()(labels_vec & r) {}
virtual model_converter * translate(ast_translation & translator) = 0;
virtual void set_env(ast_pp_util* visitor);
virtual void convert_initialize_value(vector<std::pair<expr_ref, expr_ref>> & var2value) { }
virtual void get_units(obj_map<expr, bool>& fmls) { UNREACHABLE(); }
static void display_add(std::ostream& out, smt2_pp_environment& env, model& mdl);
};
typedef ref<model_converter> model_converter_ref;
typedef sref_vector<model_converter> model_converter_ref_vector;
typedef sref_buffer<model_converter> model_converter_ref_buffer;
model_converter * concat(model_converter * mc1, model_converter * mc2);
inline model_converter * concat(model_converter * mc1, model_converter * mc2, model_converter* mc3) {
return concat(mc1, concat(mc2, mc3));
}
model_converter * model2model_converter(model * m);
model_converter * model_and_labels2model_converter(model * m, labels_vec const &r);
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m);
void apply(model_converter_ref & mc, model_ref & m);