3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 20:05:51 +00:00
z3/src/util/lp/test_bound_analyzer.h
Lev Nachmanson 9ba4026bc6 avoid going creating hnf_cuts if all involved vars have integral values
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

add explanations to hnf cuts

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

nits and virtual methods (#68)

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

cleanup from std::cout

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

handle the case when the number of terms is greater than the number of variables in hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

method name's fix

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

restore hnf_cutter to work with m_row_count <= m_column_count

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

tune addition of rational numbers (#70)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

give shorter explanations, call hnf only when have a not integral var

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

overhaul of mpq (#71)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

fix for 32 bit build (#72)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

yes (#74)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* more refactor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

fix the merge

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fixes in maximize_term untested

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fix compilation (#75)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* more refactor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* relax check

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* change for gcc

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2018-06-27 12:16:58 -07:00

274 lines
8.5 KiB
C++

/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#if 0
#pragma once
#include "util/vector.h"
#include "util/lp/implied_bound.h"
#include "util/lp/lp_settings.h"
#include <functional>
// this class is for testing only
// We have an equality : sum by j of row[j]*x[j] = rs
// We try to pin a var by pushing the total by using the variable bounds
// In a loop we drive the partial sum down, denoting the variables of this process by _u.
// In the same loop trying to pin variables by pushing the partial sum up, denoting the variable related to it by _l
// here in addition we assume that all coefficient in the row are positive
namespace lp {
class test_bound_analyzer {
linear_combination_iterator<mpq> & m_it;
std::function<impq (unsigned)>& m_lower_bounds;
std::function<impq (unsigned)>& m_upper_bounds;
std::function<column_type (unsigned)> m_column_types;
vector<implied_bound> & m_implied_bounds;
vector<mpq> m_coeffs;
int m_coeff_sign;
vector<unsigned> m_index;
unsigned m_row_or_term_index;
std::function<bool (unsigned, bool, mpq &, bool & strict)> & m_try_get_found_bound;
public :
// constructor
test_bound_analyzer(linear_combination_iterator<mpq> &it,
std::function<impq (unsigned) > & lower_bounds,
std::function<impq (unsigned)> & upper_bounds,
std::function<column_type (unsigned)> column_types,
vector<implied_bound> & evidence_vector,
unsigned row_or_term_index,
std::function<bool (unsigned, bool, mpq &, bool & strict)> & try_get_found_bound) :
m_it(it),
m_lower_bounds(lower_bounds),
m_upper_bounds(upper_bounds),
m_column_types(column_types),
m_implied_bounds(evidence_vector),
m_row_or_term_index(row_or_term_index),
m_try_get_found_bound(try_get_found_bound)
{
m_it.reset();
unsigned i;
mpq a;
while (m_it.next(a, i) ) {
m_coeffs.push_back(a);
m_index.push_back(i);
}
}
static int sign (const mpq & t) { return is_pos(t) ? 1: -1;}
void analyze() {
// We have the equality sum by j of row[j]*x[j] = m_rs
// We try to pin a var by pushing the total of the partial sum down, denoting the variable of this process by _u.
for (unsigned i = 0; i < m_index.size(); i++) {
analyze_i(i);
}
}
void analyze_i(unsigned i) {
// set the m_coeff_is_pos
m_coeff_sign = sign(m_coeffs[i]);
analyze_i_for_lower(i);
analyze_i_for_upper(i);
}
void analyze_i_for_upper(unsigned i) {
mpq l;
bool strict = false;
lp_assert(is_zero(l));
for (unsigned k = 0; k < m_index.size(); k++) {
if (k == i)
continue;
mpq lb;
bool str;
if (!upper_bound_of_monoid(k, lb, str)) {
return;
}
l += lb;
if (str)
strict = true;
}
l /= m_coeffs[i];
unsigned j = m_index[i];
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::upper_bound:
{
const auto & lb = m_upper_bounds(j);
if (l > lb.x || (l == lb.x && !(is_zero(lb.y) && strict))) {
break; // no improvement on the existing upper bound
}
}
default:
m_implied_bounds.push_back(implied_bound(l, j, false, is_pos(m_coeffs[i]), m_row_or_term_index, strict));
}
}
bool lower_bound_of_monoid(unsigned k, mpq & lb, bool &strict) const {
int s = - m_coeff_sign * sign(m_coeffs[k]);
unsigned j = m_index[k];
if (s > 0) {
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::lower_bound:
lb = -m_coeffs[k] * m_lower_bounds(j).x;
strict = !is_zero(m_lower_bounds(j).y);
return true;
default:
return false;
}
}
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::upper_bound:
lb = -m_coeffs[k] * m_upper_bounds(j).x;
strict = !is_zero(m_upper_bounds(j).y);
return true;
default:
return false;
}
}
bool upper_bound_of_monoid(unsigned k, mpq & lb, bool & strict) const {
int s = - m_coeff_sign * sign(m_coeffs[k]);
unsigned j = m_index[k];
if (s > 0) {
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::upper_bound:
lb = -m_coeffs[k] * m_upper_bounds(j).x;
strict = !is_zero(m_upper_bounds(j).y);
return true;
default:
return false;
}
}
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::lower_bound:
lb = -m_coeffs[k] * m_lower_bounds(j).x;
strict = !is_zero(m_lower_bounds(j).y);
return true;
default:
return false;
}
}
void analyze_i_for_lower(unsigned i) {
mpq l;
lp_assert(is_zero(l));
bool strict = false;
for (unsigned k = 0; k < m_index.size(); k++) {
if (k == i)
continue;
mpq lb;
bool str;
if (!lower_bound_of_monoid(k, lb, str)) {
return;
}
if (str)
strict = true;
l += lb;
}
l /= m_coeffs[i];
unsigned j = m_index[i];
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::lower_bound:
{
const auto & lb = m_lower_bounds(j);
if (l < lb.x || (l == lb.x && !(is_zero(lb.y) && strict))) {
break; // no improvement on the existing upper bound
}
}
default:
m_implied_bounds.push_back(implied_bound(l, j, true, is_pos(m_coeffs[i]), m_row_or_term_index, strict));
}
}
bool lower_bound_is_available(unsigned j) const {
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::lower_bound:
return true;
default:
return false;
}
}
bool upper_bound_is_available(unsigned j) const {
switch(m_column_types(j)) {
case column_type::fixed:
case column_type::boxed:
case column_type::upper_bound:
return true;
default:
return false;
}
}
bool try_get_best_avail_bound(unsigned j, bool is_lower_bound, mpq & best_bound, bool & strict_of_best_bound) const {
if (m_try_get_found_bound(j, is_lower_bound, best_bound, strict_of_best_bound)) {
return true;
}
if (is_lower_bound) {
if (lower_bound_is_available(j)) {
best_bound = m_lower_bounds(j).x;
strict_of_best_bound = !is_zero(m_lower_bounds(j).y);
return true;
}
} else {
if (upper_bound_is_available(j)) {
best_bound = m_upper_bounds(j).x;
strict_of_best_bound = !is_zero(m_lower_bounds(j).y);
return true;
}
}
return false;
}
bool bound_is_new(unsigned j, const mpq& b, bool is_lower_bound, bool strict) const {
mpq best_bound;
bool strict_of_best_bound;
if (try_get_best_avail_bound(j, is_lower_bound, best_bound, strict_of_best_bound)) {
if (is_lower_bound) {
if (b > best_bound || ( b != best_bound && (strict && !strict_of_best_bound))) // the second clouse stands for strong inequality
return true;
} else {
if (b < best_bound || ( b == best_bound && (strict && !strict_of_best_bound)))
return true;
}
return false;
}
return true;
}
};
}
#endif