#pragma once
#include "math/lp/nla_defs.h"
#include "math/lp/lp_settings.h"
#include "util/hashtable.h"
#include "util/trail.h"
#include <cstring>
namespace nla {
class nla_throttle {
public:
enum throttle_kind {
ORDER_LEMMA, BINOMIAL_SIGN_LEMMA, MONOTONE_LEMMA, TANGENT_LEMMA };
private:
struct signature {
unsigned m_values[8];
signature() {
std::memset(m_values, 0, sizeof(m_values));
}
bool operator==(const signature& other) const {
return std::memcmp(m_values, other.m_values, sizeof(m_values)) == 0;
}
};
struct signature_hash {
unsigned operator()(const signature& s) const {
unsigned hash = 0;
for (int i = 0; i < 8; i++) {
hash = combine_hash(hash, s.m_values[i]);
}
return hash;
}
};
hashtable<signature, signature_hash, default_eq<signature>> m_seen;
trail_stack& m_trail;
lp::statistics& m_stats;
public:
nla_throttle(trail_stack& trail, lp::statistics& stats) : m_trail(trail), m_stats(stats) {}
bool insert_new(throttle_kind k, lpvar mvar, bool is_lt);
bool insert_new(throttle_kind k, lpvar xy_var, lpvar x, lpvar y, int sign, int sy);
bool insert_new(throttle_kind k, lpvar ac_var, lpvar a, const rational& c_sign, lpvar c,
lpvar bd_var, lpvar b_var, const rational& d_sign, lpvar d, llc ab_cmp);
bool insert_new(throttle_kind k, lpvar monic_var, lpvar x_var, lpvar y_var, bool below, int plane_type);
bool insert_new(throttle_kind k, lpvar monic_var, lpvar x_var, lpvar y_var, bool below);
private:
bool insert_new_impl(const signature& sig);
static unsigned pack_rational_sign(const rational& r) {
return r.is_pos() ? 1 : (r.is_neg() ? 255 : 0);
}
static unsigned normalize_sign(int sign) {
return static_cast<unsigned>(sign + 127);
}
};
}