#pragma once
#include "ast/rewriter/seq_rewriter.h"
#include "ast/seq/seq_view.h"
#include "ast/rewriter/guard_set.h"
#include "util/lbool.h"
#include "util/obj_hashtable.h"
#include "util/statistics.h"
class seq_eq_approx {
struct statistics {
unsigned m_checks = 0;
unsigned m_unsupported = 0; unsigned m_giveup = 0; unsigned m_refuted = 0;
unsigned m_states = 0; };
public:
typedef vector<seq::view_vector> segments;
private:
ast_manager& m;
seq_rewriter& m_rw;
seq::transition_mode m_mode;
statistics m_stats;
obj_map<expr, seq::view_vector> m_views; expr_ref_vector m_pin; ptr_vector<expr> m_used; guard_set::cache m_rp_cache;
unsigned m_max_states;
unsigned m_budget = 0;
lbool m_last_result = l_undef;
seq_util& u() const { return m_rw.u(); }
seq_util::rex& re() const { return m_rw.u().re; }
lbool nullable(expr* r);
expr_ref_pair_vector const& cofactors(expr* r);
bool out_of_budget();
void add_segment(expr* r, segments& out);
lbool segment_done(seq::view_vector const& views, ptr_vector<expr> const& states);
public:
seq_eq_approx(seq_rewriter& rw, unsigned max_states = 1u << 14,
seq::transition_mode mode = seq::transition_mode::light_antimirov_tm) :
m(rw.m()), m_rw(rw), m_mode(mode), m_pin(rw.m()), m_rp_cache(rw.m()),
m_max_states(max_states) {}
void collect_statistics(::statistics& st) const;
std::ostream& display(std::ostream& out) const;
void add_view(expr* t, seq::view const& v);
void set_views(expr* t, seq::view_vector const& views);
void unset_views(expr* t);
void reset_views();
seq::view_vector const* get_views(expr* t) const;
unsigned num_terms() const { return m_views.size(); }
void to_segments(expr* term, segments& out);
lbool intersect_nonempty(segments const& lhs, segments const& rhs);
lbool check(expr* lhs, expr* rhs);
lbool check(expr* eq);
ptr_vector<expr> const& used() const { return m_used; }
void set_max_states(unsigned n) { m_max_states = n; }
unsigned max_states() const { return m_max_states; }
lbool last_result() const { return m_last_result; }
};