mirror of
https://github.com/Z3Prover/z3
synced 2025-04-14 04:48:45 +00:00
167 lines
6.5 KiB
C++
167 lines
6.5 KiB
C++
/*++
|
|
Copyright (c) 2017 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
<name>
|
|
|
|
Abstract:
|
|
|
|
<abstract>
|
|
|
|
Author:
|
|
Nikolaj Bjorner (nbjorner)
|
|
Lev Nachmanson (levnach)
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
#pragma once
|
|
|
|
#include "math/lp/nla_common.h"
|
|
#include "math/lp/nex.h"
|
|
#include "math/lp/nex_creator.h"
|
|
//#include "util/dependency.h"
|
|
|
|
namespace nla {
|
|
class core;
|
|
|
|
struct grobner_stats {
|
|
long m_simplify;
|
|
long m_superpose;
|
|
long m_compute_basis;
|
|
long m_num_processed;
|
|
void reset() { memset(this, 0, sizeof(grobner_stats)); }
|
|
grobner_stats() { reset(); }
|
|
};
|
|
|
|
class grobner : common {
|
|
class equation {
|
|
unsigned m_bidx; //!< position at m_equations_to_delete
|
|
nex * m_expr; // simplified expressionted monomials
|
|
ci_dependency * m_dep; //!< justification for the equality
|
|
public:
|
|
unsigned get_num_monomials() const {
|
|
switch(m_expr->type()) {
|
|
case expr_type::VAR: return 1;
|
|
case expr_type::SCALAR: return 0;
|
|
case expr_type::MUL: return 1;
|
|
case expr_type::SUM: return m_expr->size();
|
|
default: return 0;
|
|
}
|
|
}
|
|
// can return not a nex_mul
|
|
nex* get_monomial(unsigned idx) const {
|
|
switch(m_expr->type()) {
|
|
case expr_type::VAR:
|
|
case expr_type::SCALAR: UNREACHABLE();;
|
|
case expr_type::MUL:
|
|
SASSERT(idx == 0);
|
|
return m_expr;
|
|
case expr_type::SUM:
|
|
return (*to_sum(m_expr))[idx];
|
|
default: return 0;
|
|
}
|
|
}
|
|
nex* & expr() { return m_expr; }
|
|
const nex* expr() const { return m_expr; }
|
|
ci_dependency * dep() const { return m_dep; }
|
|
ci_dependency *& dep() { return m_dep; }
|
|
unsigned hash() const { return m_bidx; }
|
|
friend class grobner;
|
|
};
|
|
|
|
typedef obj_hashtable<equation> equation_set;
|
|
typedef ptr_vector<equation> equation_vector;
|
|
|
|
// fields
|
|
equation_vector m_equations_to_delete;
|
|
lp::int_set m_rows;
|
|
grobner_stats m_stats;
|
|
equation_set m_to_superpose;
|
|
equation_set m_to_simplify;
|
|
bool m_nl_gb_exhausted;
|
|
ptr_vector<nex> m_allocated;
|
|
lp::int_set m_tmp_var_set;
|
|
region m_alloc;
|
|
ci_value_manager m_val_manager;
|
|
mutable ci_dependency_manager m_dep_manager;
|
|
nex_lt m_lt;
|
|
bool m_changed_leading_term;
|
|
unsigned m_reported;
|
|
bool m_look_for_fixed_vars_in_rows;
|
|
public:
|
|
grobner(core *, intervals *);
|
|
void grobner_lemmas();
|
|
~grobner();
|
|
private:
|
|
void find_nl_cluster();
|
|
void prepare_rows_and_active_vars();
|
|
void add_var_and_its_factors_to_q_and_collect_new_rows(lpvar j, std::queue<lpvar>& q);
|
|
void init();
|
|
void compute_basis();
|
|
void update_statistics();
|
|
bool push_calculation_forward(ptr_vector<equation>& eqs, unsigned&);
|
|
void compute_basis_init();
|
|
bool compute_basis_loop();
|
|
bool compute_basis_step();
|
|
bool simplify_source_target(equation * source, equation * target);
|
|
equation* simplify_using_to_superpose(equation*);
|
|
bool simplify_target_monomials(equation * source, equation * target);
|
|
void process_simplified_target(equation* target, ptr_buffer<equation>& to_remove);
|
|
bool simplify_to_superpose_with_eq(equation*);
|
|
void simplify_m_to_simplify(equation*);
|
|
equation* pick_next();
|
|
void set_gb_exhausted();
|
|
bool canceled() const;
|
|
void superpose(equation * eq1, equation * eq2);
|
|
void superpose(equation * eq);
|
|
bool find_b_c(const nex *ab, const nex* ac, nex_mul*& b, nex_mul*& c);
|
|
bool find_b_c_check_only(const nex* ab, const nex* ac) const;
|
|
bool is_trivial(equation* ) const;
|
|
bool is_simpler(equation * eq1, equation * eq2);
|
|
void del_equations(unsigned old_size);
|
|
void del_equation(equation * eq);
|
|
void display_equations(std::ostream & out, equation_set const & v, char const * header) const;
|
|
std::ostream& display_equation(std::ostream & out, const equation & eq) const;
|
|
|
|
void display_matrix(std::ostream & out) const;
|
|
std::ostream& display(std::ostream & out) const;
|
|
bool try_to_modify_eqs(ptr_vector<equation>& eqs, unsigned& next_weight);
|
|
bool internalize_gb_eq(equation*);
|
|
void add_row(unsigned);
|
|
void assert_eq_0(nex*, ci_dependency * dep);
|
|
void init_equation(equation* eq, nex*, ci_dependency* d);
|
|
|
|
std::ostream& display_dependency(std::ostream& out, ci_dependency*) const;
|
|
void insert_to_simplify(equation *eq) {
|
|
TRACE("nla_grobner", display_equation(tout, *eq););
|
|
m_to_simplify.insert(eq);
|
|
}
|
|
void insert_to_superpose(equation *eq) {
|
|
SASSERT(m_nex_creator.is_simplified(*eq->expr()));
|
|
TRACE("nla_grobner", display_equation(tout, *eq););
|
|
m_to_superpose.insert(eq);
|
|
}
|
|
void simplify_equations_in_m_to_simplify();
|
|
const nex * get_highest_monomial(const nex * e) const;
|
|
ci_dependency* dep_from_vector(svector<lp::constraint_index> & fixed_vars_constraints);
|
|
bool simplify_target_monomials_sum(equation *, equation *, nex_sum*, const nex*);
|
|
unsigned find_divisible(nex_sum*, const nex*) const;
|
|
void simplify_target_monomials_sum_j(equation *, equation *, nex_sum*, const nex*, unsigned);
|
|
nex_mul * divide_ignore_coeffs(nex* ej, const nex*);
|
|
bool divide_ignore_coeffs_check_only(nex* , const nex*) const;
|
|
bool divide_ignore_coeffs_check_only_nex_mul(nex_mul* , const nex*) const;
|
|
nex_mul * divide_ignore_coeffs_perform(nex* , const nex*);
|
|
nex_mul * divide_ignore_coeffs_perform_nex_mul(nex_mul* , const nex*);
|
|
nex * expr_superpose(nex* e1, nex* e2, const nex* ab, const nex* ac, nex_mul* b, nex_mul* c);
|
|
void add_mul_skip_first(nex_sum* r, const rational& beta, nex *e, nex_mul* c);
|
|
bool done() const;
|
|
void check_eq(equation*);
|
|
void register_report();
|
|
std::unordered_set<lpvar> get_vars_of_expr_with_opening_terms(const nex *e );
|
|
unsigned num_of_equations() const { return m_to_simplify.size() + m_to_superpose.size(); }
|
|
}; // end of grobner
|
|
}
|