3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-18 01:02:15 +00:00

merge with master

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-03-25 14:57:01 -07:00
commit c513f3ca09
883 changed files with 13979 additions and 16480 deletions

View file

@ -52,7 +52,7 @@ struct bit_blaster_model_converter : public model_converter {
m_newbits.push_back(f);
}
virtual ~bit_blaster_model_converter() {
~bit_blaster_model_converter() override {
}
void collect_bits(obj_hashtable<func_decl> & bits) {
@ -123,7 +123,7 @@ struct bit_blaster_model_converter : public model_converter {
SASSERT(is_uninterp_const(bit));
func_decl * bit_decl = to_app(bit)->get_decl();
expr * bit_val = old_model->get_const_interp(bit_decl);
if (bit_val == 0) {
if (bit_val == nullptr) {
goto bail;
}
if (m().is_true(bit_val))
@ -141,7 +141,7 @@ struct bit_blaster_model_converter : public model_converter {
func_decl * bit_decl = to_app(bit)->get_decl();
expr * bit_val = old_model->get_const_interp(bit_decl);
// remark: if old_model does not assign bit_val, then assume it is false.
if (bit_val == 0) {
if (bit_val == nullptr) {
goto bail;
}
if (!util.is_zero(bit_val))

View file

@ -110,21 +110,21 @@ public:
m_imp = alloc(imp, m, m_rewriter, p);
}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
SASSERT(!m_rewriter); // assume translation isn't used where rewriter is external.
return alloc(bit_blaster_tactic, m, 0, m_params);
return alloc(bit_blaster_tactic, m, nullptr, m_params);
}
virtual ~bit_blaster_tactic() {
~bit_blaster_tactic() override {
dealloc(m_imp);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_params = p;
m_imp->updt_params(p);
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
insert_max_memory(r);
insert_max_steps(r);
r.insert("blast_mul", CPK_BOOL, "(default: true) bit-blast multipliers (and dividers, remainders).");
@ -133,8 +133,8 @@ public:
r.insert("blast_full", CPK_BOOL, "(default: false) bit-blast any term with bit-vector sort, this option will make E-matching ineffective in any pattern containing bit-vector terms.");
}
virtual void operator()(goal_ref const & g,
goal_ref_buffer & result) {
void operator()(goal_ref const & g,
goal_ref_buffer & result) override {
try {
(*m_imp)(g, result);
}
@ -143,7 +143,7 @@ public:
}
}
virtual void cleanup() {
void cleanup() override {
imp * d = alloc(imp, m_imp->m(), m_rewriter, m_params);
std::swap(d, m_imp);
dealloc(d);
@ -158,7 +158,7 @@ public:
tactic * mk_bit_blaster_tactic(ast_manager & m, params_ref const & p) {
return clean(alloc(bit_blaster_tactic, m, 0, p));
return clean(alloc(bit_blaster_tactic, m, nullptr, p));
}
tactic * mk_bit_blaster_tactic(ast_manager & m, bit_blaster_rewriter* rw, params_ref const & p) {

View file

@ -107,7 +107,7 @@ class bv1_blaster_tactic : public tactic {
sort * b = butil().mk_sort(1);
ptr_buffer<expr> bits;
for (unsigned i = 0; i < bv_size; i++) {
bits.push_back(m().mk_fresh_const(0, b));
bits.push_back(m().mk_fresh_const(nullptr, b));
m_newbits.push_back(to_app(bits.back())->get_decl());
}
r = butil().mk_concat(bits.size(), bits.c_ptr());
@ -255,7 +255,7 @@ class bv1_blaster_tactic : public tactic {
}
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
result_pr = 0;
result_pr = nullptr;
if (num == 0 && f->get_family_id() == null_family_id && butil().is_bv_sort(f->get_range())) {
mk_const(f, result);
return BR_DONE;
@ -424,20 +424,20 @@ public:
m_imp = alloc(imp, m, p);
}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(bv1_blaster_tactic, m, m_params);
}
virtual ~bv1_blaster_tactic() {
~bv1_blaster_tactic() override {
dealloc(m_imp);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_params = p;
m_imp->m_rw.cfg().updt_params(p);
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
insert_max_memory(r);
insert_max_steps(r);
}
@ -452,12 +452,12 @@ public:
It also does not support quantifiers.
Return a model_converter that converts any model for the updated set into a model for the old set.
*/
virtual void operator()(goal_ref const & g,
goal_ref_buffer & result) {
void operator()(goal_ref const & g,
goal_ref_buffer & result) override {
(*m_imp)(g, result);
}
virtual void cleanup() {
void cleanup() override {
imp * d = alloc(imp, m_imp->m(), m_params);
std::swap(d, m_imp);
dealloc(d);
@ -475,7 +475,7 @@ tactic * mk_bv1_blaster_tactic(ast_manager & m, params_ref const & p) {
class is_qfbv_eq_probe : public probe {
public:
virtual result operator()(goal const & g) {
result operator()(goal const & g) override {
bv1_blaster_tactic t(g.m());
return t.is_target(g);

View file

@ -68,7 +68,7 @@ struct bv_bound_chk_rewriter_cfg : public default_rewriter_cfg {
}
br_status reduce_app_core(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
result_pr = 0;
result_pr = nullptr;
const family_id fid = f->get_family_id();
if (fid != m_b_rw.get_fid()) return BR_FAILED;
bv_bounds bvb(m());
@ -111,7 +111,7 @@ struct bv_bound_chk_rewriter : public rewriter_tpl<bv_bound_chk_rewriter_cfg> {
updt_params(p);
}
virtual ~bv_bound_chk_rewriter() {}
~bv_bound_chk_rewriter() override {}
void updt_params(params_ref const & _p) {
m_cfg.updt_params(_p);
@ -135,13 +135,13 @@ class bv_bound_chk_tactic : public tactic {
bv_bound_chk_stats m_stats;
public:
bv_bound_chk_tactic(ast_manager & m, params_ref const & p);
virtual ~bv_bound_chk_tactic();
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
virtual tactic * translate(ast_manager & m);
virtual void updt_params(params_ref const & p);
void cleanup();
void collect_statistics(statistics & st) const;
void reset_statistics();
~bv_bound_chk_tactic() override;
tactic * translate(ast_manager & m) override;
void updt_params(params_ref const & p) override;
void cleanup() override;
void collect_statistics(statistics & st) const override;
void reset_statistics() override;
};
class bv_bound_chk_tactic::imp {

View file

@ -194,7 +194,7 @@ namespace {
bool is_bound(expr *e, expr*& v, interval& b) const {
uint64 n;
expr *lhs = 0, *rhs = 0;
expr *lhs = nullptr, *rhs = nullptr;
unsigned sz;
if (m_bv.is_bv_ule(e, lhs, rhs)) {
@ -305,7 +305,7 @@ namespace {
updt_params(p);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_propagate_eq = p.get_bool("propagate_eq", false);
}
@ -313,7 +313,7 @@ namespace {
r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
}
virtual ~bv_bounds_simplifier() {
~bv_bounds_simplifier() override {
for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) {
dealloc(m_expr_vars[i]);
}
@ -322,7 +322,7 @@ namespace {
}
}
virtual bool assert_expr(expr * t, bool sign) {
bool assert_expr(expr * t, bool sign) override {
while (m.is_not(t, t)) {
sign = !sign;
}
@ -353,7 +353,7 @@ namespace {
return true;
}
virtual bool simplify(expr* t, expr_ref& result) {
bool simplify(expr* t, expr_ref& result) override {
expr* t1;
interval b;
@ -382,7 +382,7 @@ namespace {
}
interval ctx, intr;
result = 0;
result = nullptr;
if (b.is_full() && b.tight) {
result = m.mk_true();
@ -465,7 +465,7 @@ namespace {
return false;
}
virtual bool may_simplify(expr* t) {
bool may_simplify(expr* t) override {
if (m_bv.is_numeral(t))
return false;
@ -504,7 +504,7 @@ namespace {
return false;
}
virtual void pop(unsigned num_scopes) {
void pop(unsigned num_scopes) override {
TRACE("bv", tout << "pop: " << num_scopes << "\n";);
if (m_scopes.empty())
return;
@ -526,11 +526,11 @@ namespace {
m_scopes.shrink(target);
}
virtual simplifier * translate(ast_manager & m) {
simplifier * translate(ast_manager & m) override {
return alloc(bv_bounds_simplifier, m, m_params);
}
virtual unsigned scope_level() const {
unsigned scope_level() const override {
return m_scopes.size();
}
};
@ -561,7 +561,7 @@ namespace {
bool is_bound(expr *e, expr*& v, interval& b) const {
uint64 n;
expr *lhs = 0, *rhs = 0;
expr *lhs = nullptr, *rhs = nullptr;
unsigned sz = 0;
if (m_bv.is_bv_ule(e, lhs, rhs)) {
@ -622,7 +622,7 @@ namespace {
r.insert("propagate-eq", CPK_BOOL, "(default: false) propagate equalities from inequalities");
}
virtual ~dom_bv_bounds_simplifier() {
~dom_bv_bounds_simplifier() override {
for (unsigned i = 0, e = m_expr_vars.size(); i < e; ++i) {
dealloc(m_expr_vars[i]);
}
@ -631,7 +631,7 @@ namespace {
}
}
virtual bool assert_expr(expr * t, bool sign) {
bool assert_expr(expr * t, bool sign) override {
while (m.is_not(t, t)) {
sign = !sign;
}
@ -662,7 +662,7 @@ namespace {
return true;
}
virtual void operator()(expr_ref& r) {
void operator()(expr_ref& r) override {
expr* t1, * t = r;
interval b;
@ -781,7 +781,7 @@ namespace {
return false;
}
virtual void pop(unsigned num_scopes) {
void pop(unsigned num_scopes) override {
TRACE("bv", tout << "pop: " << num_scopes << "\n";);
if (m_scopes.empty())
return;
@ -803,11 +803,11 @@ namespace {
m_scopes.shrink(target);
}
virtual dom_simplifier * translate(ast_manager & m) {
dom_simplifier * translate(ast_manager & m) override {
return alloc(dom_bv_bounds_simplifier, m, m_params);
}
virtual unsigned scope_level() const {
unsigned scope_level() const override {
return m_scopes.size();
}

View file

@ -33,15 +33,15 @@ class bv_size_reduction_tactic : public tactic {
public:
bv_size_reduction_tactic(ast_manager & m);
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(bv_size_reduction_tactic, m);
}
virtual ~bv_size_reduction_tactic();
~bv_size_reduction_tactic() override;
virtual void operator()(goal_ref const & g, goal_ref_buffer & result);
void operator()(goal_ref const & g, goal_ref_buffer & result) override;
virtual void cleanup();
void cleanup() override;
};
tactic * mk_bv_size_reduction_tactic(ast_manager & m, params_ref const & p) {
@ -183,8 +183,8 @@ struct bv_size_reduction_tactic::imp {
return;
TRACE("before_bv_size_reduction", g.display(tout););
m_produce_models = g.models_enabled();
mc = 0;
m_mc = 0;
mc = nullptr;
m_mc = nullptr;
unsigned num_reduced = 0;
{
tactic_report report("bv-size-reduction", g);
@ -210,11 +210,11 @@ struct bv_size_reduction_tactic::imp {
unsigned bv_sz = m_util.get_bv_size(v);
numeral l = m_util.norm(it->m_value, bv_sz, true);
obj_map<app, numeral>::obj_map_entry * entry = m_signed_uppers.find_core(v);
if (entry != 0) {
if (entry != nullptr) {
numeral u = m_util.norm(entry->get_data().m_value, bv_sz, true);
TRACE("bv_size_reduction", tout << l << " <= " << v->get_decl()->get_name() << " <= " << u << "\n";);
expr * new_def = 0;
app * new_const = 0;
expr * new_def = nullptr;
app * new_const = nullptr;
if (l > u) {
g.assert_expr(m.mk_false());
return;
@ -234,7 +234,7 @@ struct bv_size_reduction_tactic::imp {
unsigned i_nb = l_nb;
TRACE("bv_size_reduction", tout << " l <= " << v->get_decl()->get_name() << " <= u <= 0 " << " --> " << i_nb << " bits\n";);
if (i_nb < v_nb) {
new_const = m.mk_fresh_const(0, m_util.mk_sort(i_nb));
new_const = m.mk_fresh_const(nullptr, m_util.mk_sort(i_nb));
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(-1), v_nb - i_nb), new_const);
}
}
@ -244,7 +244,7 @@ struct bv_size_reduction_tactic::imp {
unsigned i_nb = ((l_nb > u_nb) ? l_nb : u_nb) + 1;
TRACE("bv_size_reduction", tout << " l <= " << v->get_decl()->get_name() << " <= 0 <= u " << " --> " << i_nb << " bits\n";);
if (i_nb < v_nb) {
new_const = m.mk_fresh_const(0, m_util.mk_sort(i_nb));
new_const = m.mk_fresh_const(nullptr, m_util.mk_sort(i_nb));
new_def = m_util.mk_sign_extend(v_nb - i_nb, new_const);
}
}
@ -255,7 +255,7 @@ struct bv_size_reduction_tactic::imp {
unsigned v_nb = m_util.get_bv_size(v);
TRACE("bv_size_reduction", tout << l << " <= " << v->get_decl()->get_name() << " <= " << u << " --> " << u_nb << " bits\n";);
if (u_nb < v_nb) {
new_const = m.mk_fresh_const(0, m_util.mk_sort(u_nb));
new_const = m.mk_fresh_const(nullptr, m_util.mk_sort(u_nb));
new_def = m_util.mk_concat(m_util.mk_numeral(numeral(0), v_nb - u_nb), new_const);
}
}
@ -364,8 +364,8 @@ struct bv_size_reduction_tactic::imp {
if (m_fmc) {
mc = concat(m_fmc.get(), mc.get());
}
m_mc = 0;
m_fmc = 0;
m_mc = nullptr;
m_fmc = nullptr;
}
report_tactic_progress(":bv-reduced", num_reduced);
TRACE("after_bv_size_reduction", g.display(tout); if (m_mc) m_mc->display(tout););
@ -397,8 +397,8 @@ void bv_size_reduction_tactic::operator()(goal_ref const & g,
void bv_size_reduction_tactic::cleanup() {
imp * d = alloc(imp, m_imp->m);
std::swap(d, m_imp);
dealloc(d);
ast_manager & m = m_imp->m;
m_imp->~imp();
new (m_imp) imp(m);
}

View file

@ -37,7 +37,7 @@ bvarray2uf_rewriter_cfg::bvarray2uf_rewriter_cfg(ast_manager & m, params_ref con
m_bindings(m),
m_bv_util(m),
m_array_util(m),
m_fmc(0),
m_fmc(nullptr),
extra_assertions(m) {
updt_params(p);
// We need to make sure that the mananger has the BV and array plugins loaded.
@ -107,7 +107,7 @@ func_decl_ref bvarray2uf_rewriter_cfg::mk_uf_for_array(expr * e) {
if (m_array_util.is_as_array(e))
return func_decl_ref(static_cast<func_decl*>(to_app(e)->get_decl()->get_parameter(0).get_ast()), m_manager);
else {
func_decl * bv_f = 0;
func_decl * bv_f = nullptr;
if (!m_arrays_fs.find(e, bv_f)) {
sort * domain = get_index_sort(e);
sort * range = get_value_sort(e);
@ -182,7 +182,7 @@ br_status bvarray2uf_rewriter_cfg::reduce_app(func_decl * f, unsigned num, expr
func_decl_ref itefd(m_manager);
e = m_manager.mk_ite(c, f_ta, f_fa);
func_decl * bv_f = 0;
func_decl * bv_f = nullptr;
if (!m_arrays_fs.find(f_a, bv_f)) {
sort * domain = get_index_sort(args[1]);
sort * range = get_value_sort(args[1]);

View file

@ -110,29 +110,29 @@ public:
m_imp = alloc(imp, m, p);
}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(bvarray2uf_tactic, m, m_params);
}
virtual ~bvarray2uf_tactic() {
~bvarray2uf_tactic() override {
dealloc(m_imp);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_params = p;
m_imp->updt_params(p);
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
insert_produce_models(r);
}
virtual void operator()(goal_ref const & in,
goal_ref_buffer & result) {
void operator()(goal_ref const & in,
goal_ref_buffer & result) override {
(*m_imp)(in, result);
}
virtual void cleanup() {
void cleanup() override {
ast_manager & m = m_imp->m();
imp * d = alloc(imp, m, m_params);
std::swap(d, m_imp);

View file

@ -93,8 +93,8 @@ class dt2bv_tactic : public tactic {
struct sort_pred : public i_sort_pred {
dt2bv_tactic& m_t;
sort_pred(dt2bv_tactic& t): m_t(t) {}
virtual ~sort_pred() {}
virtual bool operator()(sort* s) {
~sort_pred() override {}
bool operator()(sort* s) override {
return m_t.m_fd_sorts.contains(s);
}
};
@ -105,17 +105,17 @@ public:
dt2bv_tactic(ast_manager& m, params_ref const& p):
m(m), m_params(p), m_dt(m), m_bv(m), m_is_fd(*this) {}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(dt2bv_tactic, m, m_params);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
}
virtual void operator()(goal_ref const & g, goal_ref_buffer & result) {
void operator()(goal_ref const & g, goal_ref_buffer & result) override {
bool produce_proofs = g->proofs_enabled();
tactic_report report("dt2bv", *g);
unsigned size = g->size();
@ -158,7 +158,7 @@ public:
SASSERT(g->is_well_sorted());
}
virtual void cleanup() {
void cleanup() override {
m_fd_sorts.reset();
m_non_fd_sorts.reset();
}

View file

@ -52,7 +52,7 @@ class elim_small_bv_tactic : public tactic {
m_bindings(_m),
m_num_eliminated(0) {
updt_params(p);
m_goal = 0;
m_goal = nullptr;
m_max_steps = UINT_MAX;
}
@ -77,13 +77,13 @@ class elim_small_bv_tactic : public tactic {
expr_ref res(m);
expr_ref_vector substitution(m);
substitution.resize(num_decls, 0);
substitution.resize(num_decls, nullptr);
substitution[num_decls - idx - 1] = replacement;
// (VAR 0) is in the first position of substitution; (VAR num_decls-1) is in the last position.
for (unsigned i = 0; i < max_var_idx_p1; i++)
substitution.push_back(0);
substitution.push_back(nullptr);
// (VAR num_decls) ... (VAR num_decls+sz-1); are in positions num_decls .. num_decls+sz-1
@ -175,7 +175,7 @@ class elim_small_bv_tactic : public tactic {
TRACE("elim_small_bv", tout << "elimination result: " << mk_ismt2_pp(result, m) << std::endl; );
result_pr = 0; // proofs NIY
result_pr = nullptr; // proofs NIY
m_bindings.shrink(old_sz);
return true;
}
@ -263,31 +263,31 @@ public:
m_imp = alloc(imp, m, p);
}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(elim_small_bv_tactic, m, m_params);
}
virtual ~elim_small_bv_tactic() {
~elim_small_bv_tactic() override {
dealloc(m_imp);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_params = p;
m_imp->m_rw.cfg().updt_params(p);
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
insert_max_memory(r);
insert_max_steps(r);
r.insert("max_bits", CPK_UINT, "(default: 4) maximum bit-vector size of quantified bit-vectors to be eliminated.");
}
virtual void operator()(goal_ref const & in,
goal_ref_buffer & result) {
void operator()(goal_ref const & in,
goal_ref_buffer & result) override {
(*m_imp)(in, result);
}
virtual void cleanup() {
void cleanup() override {
ast_manager & m = m_imp->m;
m_imp->~imp();
m_imp = new (m_imp) imp(m, m_params);

View file

@ -84,7 +84,7 @@ class max_bv_sharing_tactic : public tactic {
return m().mk_app(f, arg1, arg2);
if (s.contains(expr_pair(arg2, arg1)))
return m().mk_app(f, arg2, arg1);
return 0;
return nullptr;
}
struct ref_count_lt {
@ -106,10 +106,10 @@ class max_bv_sharing_tactic : public tactic {
ptr_buffer<expr, 128> _args;
bool first = false;
expr * num = 0;
expr * num = nullptr;
for (unsigned i = 0; i < num_args; i++) {
expr * arg = args[i];
if (num == 0 && m_util.is_numeral(arg)) {
if (num == nullptr && m_util.is_numeral(arg)) {
if (i == 0) first = true;
num = arg;
}
@ -128,7 +128,7 @@ class max_bv_sharing_tactic : public tactic {
for (unsigned i = 0; i < num_args - 1; i++) {
for (unsigned j = i + 1; j < num_args; j++) {
expr * r = reuse(s, f, _args[i], _args[j]);
if (r != 0) {
if (r != nullptr) {
TRACE("bv_sharing_detail", tout << "reusing args: " << i << " " << j << "\n";);
_args[i] = r;
SASSERT(num_args > 1);
@ -186,7 +186,7 @@ class max_bv_sharing_tactic : public tactic {
}
num_args = j;
if (num_args == 1) {
if (num == 0) {
if (num == nullptr) {
result = _args[0];
}
else {
@ -209,7 +209,7 @@ class max_bv_sharing_tactic : public tactic {
case OP_BMUL:
case OP_BOR:
case OP_BXOR:
result_pr = 0;
result_pr = nullptr;
return reduce_ac_app(f, num, args, result);
default:
return BR_FAILED;
@ -274,35 +274,36 @@ public:
m_imp = alloc(imp, m, p);
}
virtual tactic * translate(ast_manager & m) {
tactic * translate(ast_manager & m) override {
return alloc(max_bv_sharing_tactic, m, m_params);
}
virtual ~max_bv_sharing_tactic() {
~max_bv_sharing_tactic() override {
dealloc(m_imp);
}
virtual void updt_params(params_ref const & p) {
void updt_params(params_ref const & p) override {
m_params = p;
m_imp->m_rw.cfg().updt_params(p);
}
virtual void collect_param_descrs(param_descrs & r) {
void collect_param_descrs(param_descrs & r) override {
insert_max_memory(r);
insert_max_steps(r);
r.insert("max_args", CPK_UINT,
"(default: 128) maximum number of arguments (per application) that will be considered by the greedy (quadratic) heuristic.");
}
virtual void operator()(goal_ref const & in,
goal_ref_buffer & result) {
void operator()(goal_ref const & in,
goal_ref_buffer & result) override {
(*m_imp)(in, result);
}
virtual void cleanup() {
imp * d = alloc(imp, m_imp->m(), m_params);
std::swap(d, m_imp);
dealloc(d);
void cleanup() override {
ast_manager & m = m_imp->m();
params_ref p = std::move(m_params);
m_imp->~imp();
new (m_imp) imp(m, p);
}
};