#pragma once
#include "util/params.h"
#include "util/lbool.h"
#include "util/statistics.h"
#include "tactic/user_propagator_base.h"
#include "tactic/goal.h"
#include "tactic/tactic_exception.h"
class progress_callback;
typedef ptr_buffer<goal> goal_buffer;
class tactic : public user_propagator::core {
unsigned m_ref_count = 0;
public:
void inc_ref() { m_ref_count++; }
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
virtual void updt_params(params_ref const & p) {}
virtual void collect_param_descrs(param_descrs & r) {}
virtual void operator()(goal_ref const & in, goal_ref_buffer& result) = 0;
virtual void collect_statistics(statistics& st) const { }
virtual void reset_statistics() {}
virtual void cleanup() = 0;
virtual void reset() { cleanup(); }
virtual void set_logic(symbol const & l) {}
virtual void set_progress_callback(progress_callback * callback) {}
virtual tactic * translate(ast_manager & m) = 0;
static void checkpoint(ast_manager& m);
void register_on_clause(void* ctx, user_propagator::on_clause_eh_t& on_clause) override {
throw default_exception("tactic does not support clause logging");
}
void user_propagate_init(
void* ctx,
user_propagator::push_eh_t& push_eh,
user_propagator::pop_eh_t& pop_eh,
user_propagator::fresh_eh_t& fresh_eh) override {
throw default_exception("tactic does not support user propagation");
}
void user_propagate_register_expr(expr* e) override { }
virtual char const* name() const = 0;
protected:
friend class nary_tactical;
friend class binary_tactical;
friend class unary_tactical;
};
typedef ref<tactic> tactic_ref;
typedef sref_vector<tactic> tactic_ref_vector;
typedef sref_buffer<tactic> tactic_ref_buffer;
#define TACTIC_VERBOSITY_LVL 10
class tactic_report {
struct imp;
imp * m_imp;
public:
tactic_report(char const * id, goal const & g);
~tactic_report();
};
void report_tactic_progress(char const * id, unsigned val);
class statistics_report {
tactic* m_tactic = nullptr;
std::function<void(statistics& st)> m_collector;
public:
statistics_report(tactic& t):m_tactic(&t) {}
statistics_report(std::function<void(statistics&)>&& coll): m_collector(std::move(coll)) {}
~statistics_report();
};
class skip_tactic : public tactic {
public:
void operator()(goal_ref const & in, goal_ref_buffer& result) override;
void cleanup() override {}
tactic * translate(ast_manager & m) override { return this; }
char const* name() const override { return "skip"; }
void collect_statistics(statistics& st) const override {}
void user_propagate_initialize_value(expr* var, expr* value) override { }
};
tactic * mk_skip_tactic();
tactic * mk_fail_tactic();
tactic * mk_fail_if_undecided_tactic();
tactic* mk_lazy_tactic(ast_manager& m, params_ref const& p, std::function<tactic*(ast_manager& m, params_ref const& p)>);
tactic * mk_report_verbose_tactic(char const * msg, unsigned lvl);
tactic * mk_trace_tactic(char const * tag);
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result);
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, labels_vec & labels, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
void fail_if_proof_generation(char const * tactic_name, goal_ref const & in);
void fail_if_unsat_core_generation(char const * tactic_name, goal_ref const & in);
void fail_if_model_generation(char const * tactic_name, goal_ref const & in);
void fail_if_has_quantifiers(char const* tactic_name, goal_ref const& in);