mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
convert reduce-args to a simplifier
- convert reduce-args to a simplifier. Currently exposed as reduce-args2 tactic until the old tactic code gets removed. - bug fixes in model_reconstruction trail - allow multiple defs to be added with same pool of removed formulas - fix tracking of function symbols instead of expressions to filter replay - add nla_divisions to track (cheap) divisibility lemmas. -
This commit is contained in:
parent
246d6f7b77
commit
8ea49eed8e
23 changed files with 740 additions and 92 deletions
|
@ -34,6 +34,7 @@ z3_add_component(lp
|
|||
nla_basics_lemmas.cpp
|
||||
nla_common.cpp
|
||||
nla_core.cpp
|
||||
nla_divisions.cpp
|
||||
nla_grobner.cpp
|
||||
nla_intervals.cpp
|
||||
nla_monotone_lemmas.cpp
|
||||
|
|
|
@ -30,6 +30,7 @@ core::core(lp::lar_solver& s, reslimit & lim) :
|
|||
m_order(this),
|
||||
m_monotone(this),
|
||||
m_powers(*this),
|
||||
m_divisions(*this),
|
||||
m_intervals(this, lim),
|
||||
m_monomial_bounds(this),
|
||||
m_horner(this),
|
||||
|
@ -136,6 +137,11 @@ void core::add_monic(lpvar v, unsigned sz, lpvar const* vs) {
|
|||
}
|
||||
m_emons.add(v, m_add_buffer);
|
||||
}
|
||||
|
||||
void core::add_idivision(lpvar r, lpvar x, lpvar y) {
|
||||
m_divisions.add_idivision(r, x, y);
|
||||
}
|
||||
|
||||
|
||||
void core::push() {
|
||||
TRACE("nla_solver_verbose", tout << "\n";);
|
||||
|
@ -1519,6 +1525,9 @@ lbool core::check(vector<lemma>& l_vec) {
|
|||
if (l_vec.empty() && !done())
|
||||
m_basics.basic_lemma(false);
|
||||
|
||||
if (l_vec.empty() && !done())
|
||||
m_divisions.check(l_vec);
|
||||
|
||||
#if 0
|
||||
if (l_vec.empty() && !done() && !run_horner)
|
||||
m_horner.horner_lemmas();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "math/lp/nla_monotone_lemmas.h"
|
||||
#include "math/lp/nla_grobner.h"
|
||||
#include "math/lp/nla_powers.h"
|
||||
#include "math/lp/nla_divisions.h"
|
||||
#include "math/lp/emonics.h"
|
||||
#include "math/lp/nla_settings.h"
|
||||
#include "math/lp/nex.h"
|
||||
|
@ -88,6 +89,7 @@ class core {
|
|||
order m_order;
|
||||
monotone m_monotone;
|
||||
powers m_powers;
|
||||
divisions m_divisions;
|
||||
intervals m_intervals;
|
||||
monomial_bounds m_monomial_bounds;
|
||||
nla_settings m_nla_settings;
|
||||
|
@ -199,8 +201,10 @@ public:
|
|||
void deregister_monic_from_tables(const monic & m, unsigned i);
|
||||
|
||||
void add_monic(lpvar v, unsigned sz, lpvar const* vs);
|
||||
void add_idivision(lpvar r, lpvar x, lpvar y);
|
||||
void push();
|
||||
void pop(unsigned n);
|
||||
trail_stack& trail() { return m_emons.get_trail_stack(); }
|
||||
|
||||
rational mon_value_by_vars(unsigned i) const;
|
||||
rational product_value(const monic & m) const;
|
||||
|
|
65
src/math/lp/nla_divisions.cpp
Normal file
65
src/math/lp/nla_divisions.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nla_divisions.cpp
|
||||
|
||||
Author:
|
||||
Lev Nachmanson (levnach)
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
|
||||
Description:
|
||||
|
||||
Check divisions
|
||||
|
||||
--*/
|
||||
#include "math/lp/nla_core.h"
|
||||
|
||||
namespace nla {
|
||||
|
||||
void divisions::add_idivision(lpvar r, lpvar x, lpvar y) {
|
||||
m_idivisions.push_back({r, x, y});
|
||||
m_core.trail().push(push_back_vector(m_idivisions));
|
||||
}
|
||||
|
||||
typedef lp::lar_term term;
|
||||
|
||||
// y1 >= y2 > 0 & x1 <= x2 => x1/y1 <= x2/y2
|
||||
// y2 <= y1 < 0 & x1 >= x2 => x1/y1 <= x2/y2
|
||||
void divisions::check(vector<lemma>& lemmas) {
|
||||
core& c = m_core;
|
||||
if (c.use_nra_model())
|
||||
return;
|
||||
|
||||
for (auto const & [r, x, y] : m_idivisions) {
|
||||
auto xval = c.val(x);
|
||||
auto yval = c.val(y);
|
||||
auto rval = c.val(r);
|
||||
if (!c.var_is_int(x))
|
||||
continue;
|
||||
if (yval == 0)
|
||||
continue;
|
||||
// idiv semantics
|
||||
if (rval == div(xval, yval))
|
||||
continue;
|
||||
for (auto const& [r2, x2, y2] : m_idivisions) {
|
||||
if (r2 == r)
|
||||
continue;
|
||||
auto x2val = c.val(x2);
|
||||
auto y2val = c.val(y2);
|
||||
auto r2val = c.val(r2);
|
||||
if (yval >= y2val && y2val > 0 && xval <= x2val && rval > r2val) {
|
||||
new_lemma lemma(c, "y1 >= y2 > 0 & x1 <= x2 => x1/y1 <= x2/y2");
|
||||
lemma |= ineq(term(y, rational(-1), y2), llc::LT, rational::zero());
|
||||
lemma |= ineq(y2, llc::LE, rational::zero());
|
||||
lemma |= ineq(term(x, rational(-1), x2), llc::GT, rational::zero());
|
||||
lemma |= ineq(term(r, rational(-1), r2), llc::LE, rational::zero());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
31
src/math/lp/nla_divisions.h
Normal file
31
src/math/lp/nla_divisions.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*++
|
||||
Copyright (c) 2017 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nla_divisions.h
|
||||
|
||||
Author:
|
||||
Lev Nachmanson (levnach)
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
|
||||
Description:
|
||||
Check division constraints.
|
||||
|
||||
--*/
|
||||
|
||||
#include "math/lp/nla_types.h"
|
||||
|
||||
namespace nla {
|
||||
|
||||
class core;
|
||||
|
||||
class divisions {
|
||||
core& m_core;
|
||||
vector<std::tuple<lpvar, lpvar, lpvar>> m_idivisions;
|
||||
public:
|
||||
divisions(core& c):m_core(c) {}
|
||||
void add_idivision(lpvar r, lpvar x, lpvar y);
|
||||
void check(vector<lemma>&);
|
||||
};
|
||||
}
|
|
@ -22,6 +22,10 @@ namespace nla {
|
|||
void solver::add_monic(lpvar v, unsigned sz, lpvar const* vs) {
|
||||
m_core->add_monic(v, sz, vs);
|
||||
}
|
||||
|
||||
void solver::add_idivision(lpvar r, lpvar x, lpvar y) {
|
||||
m_core->add_idivision(r, x, y);
|
||||
}
|
||||
|
||||
bool solver::is_monic_var(lpvar v) const {
|
||||
return m_core->is_monic_var(v);
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace nla {
|
|||
core* m_core;
|
||||
public:
|
||||
void add_monic(lpvar v, unsigned sz, lpvar const* vs);
|
||||
void add_idivision(lpvar r, lpvar x, lpvar y);
|
||||
solver(lp::lar_solver& s, reslimit& limit);
|
||||
~solver();
|
||||
nla_settings& settings();
|
||||
|
|
|
@ -68,8 +68,7 @@ class var_eqs {
|
|||
|
||||
T* m_merge_handler;
|
||||
union_find<var_eqs> m_uf;
|
||||
lp::incremental_vector<std::pair<signed_var, signed_var>>
|
||||
m_trail;
|
||||
lp::incremental_vector<std::pair<signed_var, signed_var>> m_trail;
|
||||
vector<svector<eq_edge>> m_eqs; // signed_var.index() -> the edges adjacent to signed_var.index()
|
||||
|
||||
trail_stack m_stack;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue