3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

merge with master branch

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-09-19 09:39:22 -07:00
commit 651587ce01
1602 changed files with 40496 additions and 27837 deletions

View file

@ -17,7 +17,7 @@ Author:
Notes:
--*/
#include"approx_nat.h"
#include "util/approx_nat.h"
approx_nat::approx_nat(unsigned val) {
m_value = val > m_limit ? UINT_MAX : val;

View file

@ -17,7 +17,7 @@ Revision History:
--*/
#include"approx_set.h"
#include "util/approx_set.h"
void approx_set::display(std::ostream & out) const {
out << "{";

View file

@ -19,7 +19,7 @@ Revision History:
#ifndef APPROX_SET_H_
#define APPROX_SET_H_
#include<iostream>
#include"debug.h"
#include "util/debug.h"
template<typename T> class approx_set_traits;

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef ARRAY_MAP_H_
#define ARRAY_MAP_H_
#include"vector.h"
#include"optional.h"
#include "util/vector.h"
#include "util/optional.h"
/**
\brief Implements a mapping from Key to Data.
@ -63,10 +63,7 @@ class array_map {
}
void really_flush() {
typename vector<optional<entry> >::iterator it = m_map.begin();
typename vector<optional<entry> >::iterator end = m_map.end();
for (; it != end; ++it) {
optional<entry> & e = *it;
for (optional<entry> & e : m_map) {
if (e) {
m_plugin.del_eh(e->m_key, e->m_data);
e.set_invalid();

View file

@ -19,7 +19,7 @@ Revision History:
#ifndef BACKTRACKABLE_SET_H_
#define BACKTRACKABLE_SET_H_
#include"vector.h"
#include "util/vector.h"
template<typename T>
struct default_eh {

View file

@ -16,9 +16,9 @@ Author:
Revision History:
--*/
#include"bit_util.h"
#include"util.h"
#include"debug.h"
#include "util/bit_util.h"
#include "util/util.h"
#include "util/debug.h"
#include <cstring>
/**

View file

@ -17,8 +17,8 @@ Revision History:
--*/
#include<limits.h>
#include"bit_vector.h"
#include"trace.h"
#include "util/bit_vector.h"
#include "util/trace.h"
#define DEFAULT_CAPACITY 2

View file

@ -20,9 +20,9 @@ Revision History:
#define BIT_VECTOR_H_
#include<string.h>
#include"debug.h"
#include"vector.h"
#include"memory_manager.h"
#include "util/debug.h"
#include "util/vector.h"
#include "util/memory_manager.h"
COMPILE_TIME_ASSERT(sizeof(unsigned) == 4);
#define BV_DEFAULT_CAPACITY 2

View file

@ -20,7 +20,7 @@ Revision History:
#define BUFFER_H_
#include<string.h>
#include"memory_manager.h"
#include "util/memory_manager.h"
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
class buffer {

View file

@ -19,7 +19,7 @@ Revision History:
#ifndef CANCEL_EH_H_
#define CANCEL_EH_H_
#include"event_handler.h"
#include "util/event_handler.h"
/**
\brief Generic event handler for invoking cancel method.
@ -31,10 +31,14 @@ class cancel_eh : public event_handler {
public:
cancel_eh(T & o): m_canceled(false), m_obj(o) {}
~cancel_eh() { if (m_canceled) m_obj.dec_cancel(); }
virtual void operator()() {
m_canceled = true;
m_obj.inc_cancel();
virtual void operator()(event_handler_caller_t caller_id) {
if (!m_canceled) {
m_caller_id = caller_id;
m_canceled = true;
m_obj.inc_cancel();
}
}
bool canceled() const { return m_canceled; }
};
#endif

View file

@ -28,11 +28,11 @@ Revision History:
#ifndef CHASHTABLE_H_
#define CHASHTABLE_H_
#include"memory_manager.h"
#include"debug.h"
#include"trace.h"
#include "util/memory_manager.h"
#include "util/debug.h"
#include "util/trace.h"
#ifdef Z3DEBUG
#include"hashtable.h"
#include "util/hashtable.h"
#endif
#define CH_STATISTICS

View file

@ -24,8 +24,8 @@ Revision History:
#ifndef CHECKED_INT64_H_
#define CHECKED_INT64_H_
#include"z3_exception.h"
#include"rational.h"
#include "util/z3_exception.h"
#include "util/rational.h"
template<bool CHECK>
class checked_int64 {

View file

@ -15,7 +15,7 @@ Notes:
--*/
#include<iostream>
#include"cmd_context_types.h"
#include "util/cmd_context_types.h"
std::ostream & operator<<(std::ostream & out, cmd_arg_kind k) {
switch (k) {

View file

@ -17,8 +17,8 @@ Notes:
#ifndef CMD_CONTEXT_TYPES_H_
#define CMD_CONTEXT_TYPES_H_
#include"symbol.h"
#include"z3_exception.h"
#include "util/symbol.h"
#include "util/z3_exception.h"
#include<sstream>
class rational;
class expr;

View file

@ -16,7 +16,7 @@ Author:
Notes:
--*/
#include"common_msgs.h"
#include "util/common_msgs.h"
char const * common_msgs::g_canceled_msg = "canceled";
char const * common_msgs::g_max_memory_msg = "max. memory exceeded";

View file

@ -16,10 +16,10 @@ Author:
Notes:
--*/
#include"cooperate.h"
#include"trace.h"
#include"debug.h"
#include"z3_omp.h"
#include "util/cooperate.h"
#include "util/trace.h"
#include "util/debug.h"
#include "util/z3_omp.h"
struct cooperation_lock {
omp_nest_lock_t m_lock;

View file

@ -21,8 +21,8 @@ Revision History:
#include<unistd.h>
#endif
#include<iostream>
#include"str_hashtable.h"
#include"z3_exception.h"
#include "util/str_hashtable.h"
#include "util/z3_exception.h"
static volatile bool g_enable_assertions = true;

View file

@ -35,8 +35,8 @@ bool assertions_enabled();
# define __has_builtin(x) 0
#endif
#include"error_codes.h"
#include"warning.h"
#include "util/error_codes.h"
#include "util/warning.h"
#ifdef Z3DEBUG
#define DEBUG_CODE(CODE) { CODE } ((void) 0)
@ -90,14 +90,7 @@ bool is_debug_enabled(const char * tag);
exit(-1); \
}
#define MAKE_NAME2(LINE) zofty_ ## LINE
#define MAKE_NAME(LINE) MAKE_NAME2(LINE)
#define DBG_UNIQUE_NAME MAKE_NAME(__LINE__)
#ifdef __GNUC__
#define COMPILE_TIME_ASSERT(expr) extern __attribute__((unused)) char DBG_UNIQUE_NAME[expr]
#else
#define COMPILE_TIME_ASSERT(expr) extern char DBG_UNIQUE_NAME[expr]
#endif
#define COMPILE_TIME_ASSERT(expr) static_assert(expr, "")
void finalize_debug();
/*

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef DEPENDENCY_H_
#define DEPENDENCY_H_
#include"vector.h"
#include"region.h"
#include "util/vector.h"
#include "util/region.h"
template<typename C>
class dependency_manager {

View file

@ -17,8 +17,8 @@ Notes:
#ifndef DICTIONARY_H_
#define DICTIONARY_H_
#include"map.h"
#include"symbol.h"
#include "util/map.h"
#include "util/symbol.h"
template<typename T>
class dictionary : public map<symbol, T, symbol_hash_proc, symbol_eq_proc> {

View file

@ -23,10 +23,10 @@ Revision History:
#include<string>
#include<sstream>
#include<iomanip>
#include"util.h"
#include"debug.h"
#include"hash.h"
#include"params.h"
#include "util/util.h"
#include "util/debug.h"
#include "util/hash.h"
#include "util/params.h"
/**
\brief Create an interface for manipulating double numbers compatible with the one for mpq.

View file

@ -16,11 +16,11 @@ Author:
Notes:
--*/
#include"env_params.h"
#include"params.h"
#include"gparams.h"
#include"util.h"
#include"memory_manager.h"
#include "util/env_params.h"
#include "util/params.h"
#include "util/gparams.h"
#include "util/util.h"
#include "util/memory_manager.h"
void env_params::updt_params() {
params_ref p = gparams::get();

View file

@ -19,10 +19,22 @@ Revision History:
#ifndef EVENT_HANDLER_H_
#define EVENT_HANDLER_H_
enum event_handler_caller_t {
UNSET_EH_CALLER,
CTRL_C_EH_CALLER,
TIMEOUT_EH_CALLER,
RESLIMIT_EH_CALLER,
API_INTERRUPT_EH_CALLER
};
class event_handler {
protected:
event_handler_caller_t m_caller_id;
public:
event_handler(): m_caller_id(UNSET_EH_CALLER) {}
virtual ~event_handler() {}
virtual void operator()() = 0;
virtual void operator()(event_handler_caller_t caller_id) = 0;
event_handler_caller_t caller_id() const { return m_caller_id; }
};
#endif

View file

@ -21,7 +21,7 @@ Revision History:
#define EXT_NUMERAL_H_
#include<iostream>
#include"debug.h"
#include "util/debug.h"
enum ext_numeral_kind { EN_MINUS_INFINITY, EN_NUMERAL, EN_PLUS_INFINITY };

View file

@ -20,7 +20,7 @@ Revision History:
#ifndef F2N_H_
#define F2N_H_
#include"mpf.h"
#include "util/mpf.h"
template<typename fmanager>
class f2n {

View file

@ -20,9 +20,9 @@ Revision History:
--*/
#include<limits.h>
#include"fixed_bit_vector.h"
#include"trace.h"
#include"hash.h"
#include "util/fixed_bit_vector.h"
#include "util/trace.h"
#include "util/hash.h"
void fixed_bit_vector::set(fixed_bit_vector const& other, unsigned hi, unsigned lo) {
if ((lo % 32) == 0) {

View file

@ -22,8 +22,8 @@ Revision History:
#define FIXED_BIT_VECTOR_H_
#include<string.h>
#include"debug.h"
#include"small_object_allocator.h"
#include "util/debug.h"
#include "util/small_object_allocator.h"
class fixed_bit_vector {
friend class fixed_bit_vector_manager;

View file

@ -16,9 +16,9 @@ Author:
Notes:
--*/
#include"gparams.h"
#include"dictionary.h"
#include"trace.h"
#include "util/gparams.h"
#include "util/dictionary.h"
#include "util/trace.h"
extern void gparams_register_modules();

View file

@ -19,7 +19,7 @@ Notes:
#ifndef GPARAMS_H_
#define GPARAMS_H_
#include"params.h"
#include "util/params.h"
class gparams {
struct imp;

View file

@ -17,8 +17,8 @@ Revision History:
--*/
#include"debug.h"
#include"hash.h"
#include "util/debug.h"
#include "util/hash.h"
#include <string.h>
static unsigned read_unsigned(const char *s) {

View file

@ -20,7 +20,7 @@ Revision History:
#define HASH_H_
#include<algorithm>
#include"util.h"
#include "util/util.h"
#define mix(a,b,c) \
{ \

View file

@ -18,12 +18,12 @@ Revision History:
--*/
#ifndef HASHTABLE_H_
#define HASHTABLE_H_
#include"debug.h"
#include "util/debug.h"
#include<ostream>
#include"util.h"
#include "util/util.h"
#include<limits.h>
#include"memory_manager.h"
#include"hash.h"
#include "util/memory_manager.h"
#include "util/hash.h"
#define DEFAULT_HASHTABLE_INITIAL_CAPACITY 8
#define SMALL_TABLE_CAPACITY 64

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef HEAP_H_
#define HEAP_H_
#include"vector.h"
#include"debug.h"
#include "util/vector.h"
#include "util/debug.h"
template<typename LT>
class heap : private LT {

View file

@ -34,7 +34,7 @@ Revision History:
#define USE_INTRINSICS
#endif
#include"hwf.h"
#include "util/hwf.h"
// Note:
// Which FPU will be used is determined by compiler settings. On x64 it's always SSE2,

View file

@ -20,9 +20,9 @@ Revision History:
#define HWF_H_
#include<string>
#include"mpz.h"
#include"mpq.h"
#include"mpf.h" // we use the same rounding modes as mpf's
#include "util/mpz.h"
#include "util/mpq.h"
#include "util/mpf.h"
class hwf {
friend class hwf_manager;

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef ID_GEN_H_
#define ID_GEN_H_
#include"vector.h"
#include"util.h"
#include "util/vector.h"
#include "util/util.h"
class id_gen {
unsigned m_next_id;

View file

@ -20,10 +20,10 @@ Revision History:
#define INF_EPS_RATIONAL_H_
#include<stdlib.h>
#include<string>
#include"debug.h"
#include"vector.h"
#include"rational.h"
#include"inf_rational.h"
#include "util/debug.h"
#include "util/vector.h"
#include "util/rational.h"
#include "util/inf_rational.h"
template<typename Numeral>
class inf_eps_rational {

View file

@ -17,7 +17,7 @@ Revision History:
--*/
#include<sstream>
#include"inf_int_rational.h"
#include "util/inf_int_rational.h"
inf_int_rational inf_int_rational::m_zero;
inf_int_rational inf_int_rational::m_one;

View file

@ -21,9 +21,9 @@ Revision History:
#define INF_INT_RATIONAL_H_
#include<stdlib.h>
#include<string>
#include"debug.h"
#include"vector.h"
#include"rational.h"
#include "util/debug.h"
#include "util/vector.h"
#include "util/rational.h"
class inf_int_rational {

View file

@ -16,7 +16,7 @@ Author:
Revision History:
--*/
#include"inf_rational.h"
#include "util/inf_rational.h"
inf_rational inf_rational::m_zero;
inf_rational inf_rational::m_one;

View file

@ -21,9 +21,9 @@ Revision History:
#define INF_RATIONAL_H_
#include<stdlib.h>
#include<string>
#include"debug.h"
#include"vector.h"
#include"rational.h"
#include "util/debug.h"
#include "util/vector.h"
#include "util/rational.h"
class inf_rational {

View file

@ -17,7 +17,7 @@ Revision History:
--*/
#include"inf_s_integer.h"
#include "util/inf_s_integer.h"
inf_s_integer inf_s_integer::m_zero(0);
inf_s_integer inf_s_integer::m_one(1);

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef INF_S_INTEGER_H_
#define INF_S_INTEGER_H_
#include"s_integer.h"
#include"rational.h"
#include "util/s_integer.h"
#include "util/rational.h"
class inf_s_integer {
static inf_s_integer m_zero;

View file

@ -16,7 +16,7 @@ Author:
Revision History:
--*/
#include"lbool.h"
#include "util/lbool.h"
std::ostream & operator<<(std::ostream & out, lbool b) {
switch(b) {

View file

@ -19,7 +19,7 @@ Revision History:
#ifndef LBOOL_H_
#define LBOOL_H_
#include"util.h"
#include "util/util.h"
typedef enum { l_false = -1, l_undef, l_true } lbool;

View file

@ -19,8 +19,8 @@ Revision History:
#ifndef LIST_H_
#define LIST_H_
#include"buffer.h"
#include"region.h"
#include "util/buffer.h"
#include "util/region.h"
template<typename T>
class list {

View file

@ -3,13 +3,11 @@ z3_add_component(lp
lp_utils.cpp
binary_heap_priority_queue_instances.cpp
binary_heap_upair_queue_instances.cpp
bound_propagator.cpp
lp_bound_propagator.cpp
core_solver_pretty_printer_instances.cpp
dense_matrix_instances.cpp
eta_matrix_instances.cpp
indexed_vector_instances.cpp
int_solver.cpp
lar_solver_instances.cpp
lar_core_solver_instances.cpp
lp_core_solver_base_instances.cpp
lp_dual_core_solver_instances.cpp
@ -20,7 +18,6 @@ z3_add_component(lp
lp_solver_instances.cpp
lu_instances.cpp
matrix_instances.cpp
nra_solver.cpp
permutation_matrix_instances.cpp
quick_xplain.cpp
row_eta_matrix_instances.cpp
@ -31,8 +28,6 @@ z3_add_component(lp
random_updater_instances.cpp
COMPONENT_DEPENDENCIES
util
polynomial
nlsat
PYG_FILES
lp_params.pyg
)

View file

@ -1,8 +1,23 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
#include "util/debug.h"
@ -22,7 +37,7 @@ class binary_heap_priority_queue {
void put_at(unsigned i, unsigned h);
void decrease_priority(unsigned o, T newPriority);
public:
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
bool is_consistent() const;
#endif
public:
@ -60,10 +75,10 @@ public:
/// return the first element of the queue and removes it from the queue
unsigned dequeue();
unsigned peek() const {
lp_assert(m_heap_size > 0);
SASSERT(m_heap_size > 0);
return m_heap[1];
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
void print(std::ostream & out);
#endif
};

View file

@ -1,11 +1,26 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/vector.h"
#include "util/lp/binary_heap_priority_queue.h"
namespace lp {
// is is the child place in heap
// this is the child place in the heap
template <typename T> void binary_heap_priority_queue<T>::swap_with_parent(unsigned i) {
unsigned parent = m_heap[i >> 1];
put_at(i >> 1, m_heap[i]);
@ -29,12 +44,12 @@ template <typename T> void binary_heap_priority_queue<T>::decrease_priority(unsi
}
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename T> bool binary_heap_priority_queue<T>::is_consistent() const {
for (int i = 0; i < m_heap_inverse.size(); i++) {
int i_index = m_heap_inverse[i];
lp_assert(i_index <= static_cast<int>(m_heap_size));
lp_assert(i_index == -1 || m_heap[i_index] == i);
SASSERT(i_index <= static_cast<int>(m_heap_size));
SASSERT(i_index == -1 || m_heap[i_index] == i);
}
for (unsigned i = 1; i < m_heap_size; i++) {
unsigned ch = i << 1;
@ -49,13 +64,14 @@ template <typename T> bool binary_heap_priority_queue<T>::is_consistent() const
return true;
}
#endif
template <typename T> void binary_heap_priority_queue<T>::remove(unsigned o) {
T priority_of_o = m_priorities[o];
int o_in_heap = m_heap_inverse[o];
if (o_in_heap == -1) {
return; // nothing to do
}
lp_assert(static_cast<unsigned>(o_in_heap) <= m_heap_size);
SASSERT(static_cast<unsigned>(o_in_heap) <= m_heap_size);
if (static_cast<unsigned>(o_in_heap) < m_heap_size) {
put_at(o_in_heap, m_heap[m_heap_size--]);
if (m_priorities[m_heap[o_in_heap]] > priority_of_o) {
@ -72,11 +88,11 @@ template <typename T> void binary_heap_priority_queue<T>::remove(unsigned o) {
}
}
} else {
lp_assert(static_cast<unsigned>(o_in_heap) == m_heap_size);
SASSERT(static_cast<unsigned>(o_in_heap) == m_heap_size);
m_heap_size--;
}
m_heap_inverse[o] = -1;
// lp_assert(is_consistent());
// SASSERT(is_consistent());
}
// n is the initial queue capacity.
// The capacity will be enlarged two times automatically if needed
@ -102,7 +118,7 @@ template <typename T> void binary_heap_priority_queue<T>::put_to_heap(unsigned i
template <typename T> void binary_heap_priority_queue<T>::enqueue_new(unsigned o, const T& priority) {
m_heap_size++;
int i = m_heap_size;
lp_assert(o < m_priorities.size());
SASSERT(o < m_priorities.size());
m_priorities[o] = priority;
put_at(i, o);
while (i > 1 && m_priorities[m_heap[i >> 1]] > priority) {
@ -134,7 +150,7 @@ template <typename T> void binary_heap_priority_queue<T>::change_priority_for_ex
/// return the first element of the queue and removes it from the queue
template <typename T> unsigned binary_heap_priority_queue<T>::dequeue_and_get_priority(T & priority) {
lp_assert(m_heap_size != 0);
SASSERT(m_heap_size != 0);
int ret = m_heap[1];
priority = m_priorities[ret];
put_the_last_at_the_top_and_fix_the_heap();
@ -168,13 +184,13 @@ template <typename T> void binary_heap_priority_queue<T>::put_the_last_at_the_to
}
/// return the first element of the queue and removes it from the queue
template <typename T> unsigned binary_heap_priority_queue<T>::dequeue() {
lp_assert(m_heap_size > 0);
SASSERT(m_heap_size > 0);
int ret = m_heap[1];
put_the_last_at_the_top_and_fix_the_heap();
m_heap_inverse[ret] = -1;
return ret;
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename T> void binary_heap_priority_queue<T>::print(std::ostream & out) {
vector<int> index;
vector<T> prs;

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/numeric_pair.h"
#include "util/lp/binary_heap_priority_queue.hpp"
namespace lp {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include <unordered_set>
@ -38,7 +53,7 @@ public:
void enqueue(unsigned i, unsigned j, const T & priority);
void dequeue(unsigned & i, unsigned &j);
T get_priority(unsigned i, unsigned j) const;
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
bool pair_to_index_is_a_bijection() const;
bool available_spots_are_correct() const;
bool is_correct() const {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <set>
#include "util/lp/lp_utils.h"
@ -14,7 +29,7 @@ template <typename T> binary_heap_upair_queue<T>::binary_heap_upair_queue(unsign
template <typename T> unsigned
binary_heap_upair_queue<T>::dequeue_available_spot() {
lp_assert(m_available_spots.empty() == false);
SASSERT(m_available_spots.empty() == false);
unsigned ret = m_available_spots.back();
m_available_spots.pop_back();
return ret;
@ -54,7 +69,7 @@ template <typename T> void binary_heap_upair_queue<T>::enqueue(unsigned i, unsig
m_pairs.resize(new_size);
}
ij_index = dequeue_available_spot();
// lp_assert(ij_index<m_pairs.size() && ij_index_is_new(ij_index));
// SASSERT(ij_index<m_pairs.size() && ij_index_is_new(ij_index));
m_pairs[ij_index] = p;
m_pairs_to_index[p] = ij_index;
} else {
@ -64,7 +79,7 @@ template <typename T> void binary_heap_upair_queue<T>::enqueue(unsigned i, unsig
}
template <typename T> void binary_heap_upair_queue<T>::dequeue(unsigned & i, unsigned &j) {
lp_assert(!m_q.is_empty());
SASSERT(!m_q.is_empty());
unsigned ij_index = m_q.dequeue();
upair & p = m_pairs[ij_index];
i = p.first;
@ -81,7 +96,7 @@ template <typename T> T binary_heap_upair_queue<T>::get_priority(unsigned i, uns
return m_q.get_priority(it->second);
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename T> bool binary_heap_upair_queue<T>::pair_to_index_is_a_bijection() const {
std::set<int> tmp;
for (auto p : m_pairs_to_index) {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/binary_heap_upair_queue.hpp"
namespace lp {
template binary_heap_upair_queue<int>::binary_heap_upair_queue(unsigned int);

View file

@ -1,14 +1,29 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
#include "util/lp/linear_combination_iterator.h"
#include "implied_bound.h"
#include "test_bound_analyzer.h"
#include "util/lp/implied_bound.h"
#include "util/lp/test_bound_analyzer.h"
#include <functional>
#include "util/lp/bound_propagator.h"
#include "util/lp/lp_bound_propagator.h"
// 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.
@ -16,9 +31,9 @@
namespace lp {
class bound_analyzer_on_row {
linear_combination_iterator<mpq> & m_it;
bound_propagator & m_bp;
lp_bound_propagator & m_bp;
unsigned m_row_or_term_index;
int m_column_of_u; // index of an unlimited from above monoid
// -1 means that such a value is not found, -2 means that at least two of such monoids were found
@ -31,7 +46,7 @@ public :
linear_combination_iterator<mpq> &it,
const numeric_pair<mpq>& rs,
unsigned row_or_term_index,
bound_propagator & bp
lp_bound_propagator & bp
)
:
m_it(it),
@ -45,7 +60,7 @@ public :
unsigned j;
void analyze() {
mpq a; unsigned j;
while (((m_column_of_l != -2) || (m_column_of_u != -2)) && m_it.next(a, j))
analyze_bound_on_var_on_coeff(j, a);
@ -91,11 +106,11 @@ public :
}
const impq & ub(unsigned j) const {
lp_assert(upper_bound_is_available(j));
SASSERT(upper_bound_is_available(j));
return m_bp.get_upper_bound(j);
}
const impq & lb(unsigned j) const {
lp_assert(low_bound_is_available(j));
SASSERT(low_bound_is_available(j));
return m_bp.get_low_bound(j);
}
@ -114,29 +129,29 @@ public :
}
return a * lb(j).x;
}
mpq monoid_max(const mpq & a, unsigned j, bool & strict) const {
if (is_pos(a)) {
strict = !is_zero(ub(j).y);
return a * ub(j).x;
}
strict = !is_zero(lb(j).y);
return a * lb(j).x;
}
const mpq & monoid_min_no_mult(bool a_is_pos, unsigned j, bool & strict) const {
if (!a_is_pos) {
strict = !is_zero(ub(j).y);
return ub(j).x;
}
strict = !is_zero(lb(j).y);
return lb(j).x;
}
mpq monoid_max(const mpq & a, unsigned j, bool & strict) const {
if (is_pos(a)) {
strict = !is_zero(ub(j).y);
return a * ub(j).x;
}
strict = !is_zero(lb(j).y);
return a * lb(j).x;
}
const mpq & monoid_min_no_mult(bool a_is_pos, unsigned j, bool & strict) const {
if (!a_is_pos) {
strict = !is_zero(ub(j).y);
return ub(j).x;
}
strict = !is_zero(lb(j).y);
return lb(j).x;
}
mpq monoid_min(const mpq & a, unsigned j, bool& strict) const {
if (is_neg(a)) {
strict = !is_zero(ub(j).y);
return a * ub(j).x;
}
strict = !is_zero(lb(j).y);
return a * lb(j).x;
}
@ -145,15 +160,15 @@ public :
if (is_neg(a)) {
return a * ub(j).x;
}
return a * lb(j).x;
}
void limit_all_monoids_from_above() {
int strict = 0;
mpq total;
lp_assert(is_zero(total));
SASSERT(is_zero(total));
m_it.reset();
mpq a; unsigned j;
while (m_it.next(a, j)) {
@ -166,7 +181,7 @@ public :
m_it.reset();
while (m_it.next(a, j)) {
bool str;
bool a_is_pos = is_pos(a);
bool a_is_pos = is_pos(a);
mpq bound = total / a + monoid_min_no_mult(a_is_pos, j, str);
if (a_is_pos) {
limit_j(j, bound, true, false, strict - static_cast<int>(str) > 0);
@ -180,7 +195,7 @@ public :
void limit_all_monoids_from_below() {
int strict = 0;
mpq total;
lp_assert(is_zero(total));
SASSERT(is_zero(total));
m_it.reset();
mpq a; unsigned j;
while (m_it.next(a, j)) {
@ -192,9 +207,9 @@ public :
m_it.reset();
while (m_it.next(a, j)) {
bool str;
bool a_is_pos = is_pos(a);
mpq bound = total / a + monoid_max_no_mult(a_is_pos, j, str);
bool astrict = strict - static_cast<int>(str) > 0;
bool a_is_pos = is_pos(a);
mpq bound = total / a + monoid_max_no_mult(a_is_pos, j, str);
bool astrict = strict - static_cast<int>(str) > 0;
if (a_is_pos) {
limit_j(j, bound, true, true, astrict);
}
@ -204,7 +219,7 @@ public :
}
}
void limit_monoid_u_from_below() {
// we are going to limit from below the monoid m_column_of_u,
// every other monoid is impossible to limit from below
@ -225,7 +240,7 @@ public :
}
bound /= u_coeff;
if (numeric_traits<impq>::is_pos(u_coeff)) {
limit_j(m_column_of_u, bound, true, true, strict);
} else {
@ -260,7 +275,7 @@ public :
limit_j(m_column_of_l, bound, false, true, strict);
}
}
// // it is the coefficent before the bounded column
// void provide_evidence(bool coeff_is_pos) {
// /*
@ -272,7 +287,7 @@ public :
// mpq a; unsigned j;
// while (it->next(a, j)) {
// if (be.m_j == j) continue;
// lp_assert(bound_is_available(j, is_neg(a) ? low_bound : !low_bound));
// SASSERT(bound_is_available(j, is_neg(a) ? low_bound : !low_bound));
// be.m_vector_of_bound_signatures.emplace_back(a, j, numeric_traits<impq>::
// is_neg(a)? low_bound: !low_bound);
// }
@ -284,27 +299,27 @@ public :
m_bp.try_add_bound(u, j, is_low_bound, coeff_before_j_is_pos, m_row_or_term_index, strict);
}
void advance_u(unsigned j) {
if (m_column_of_u == -1)
m_column_of_u = j;
else
m_column_of_u = -2;
}
void advance_l(unsigned j) {
if (m_column_of_l == -1)
m_column_of_l = j;
else
m_column_of_l = -2;
}
void analyze_bound_on_var_on_coeff(int j, const mpq &a) {
switch (m_bp.get_column_type(j)) {
case column_type::low_bound:
if (numeric_traits<mpq>::is_pos(a))
advance_u(j);
else
else
advance_l(j);
break;
case column_type::upper_bound:
@ -325,7 +340,7 @@ public :
static void analyze_row(linear_combination_iterator<mpq> &it,
const numeric_pair<mpq>& rs,
unsigned row_or_term_index,
bound_propagator & bp
lp_bound_propagator & bp
) {
bound_analyzer_on_row a(it, rs, row_or_term_index, bp);
a.analyze();

View file

@ -1,47 +0,0 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
#include "util/lp/lar_solver.h"
namespace lp {
bound_propagator::bound_propagator(lar_solver & ls):
m_lar_solver(ls) {}
column_type bound_propagator::get_column_type(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_column_types()[j];
}
const impq & bound_propagator::get_low_bound(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_r_low_bounds()[j];
}
const impq & bound_propagator::get_upper_bound(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_r_upper_bounds()[j];
}
void bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) {
j = m_lar_solver.adjust_column_index_to_term_index(j);
lconstraint_kind kind = is_low? GE : LE;
if (strict)
kind = static_cast<lconstraint_kind>(kind / 2);
if (!bound_is_interesting(j, kind, v))
return;
unsigned k; // index to ibounds
if (is_low) {
if (try_get_val(m_improved_low_bounds, j, k)) {
auto & found_bound = m_ibounds[k];
if (v > found_bound.m_bound || (v == found_bound.m_bound && found_bound.m_strict == false && strict))
found_bound = implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict);
} else {
m_improved_low_bounds[j] = m_ibounds.size();
m_ibounds.push_back(implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict));
}
} else { // the upper bound case
if (try_get_val(m_improved_upper_bounds, j, k)) {
auto & found_bound = m_ibounds[k];
if (v < found_bound.m_bound || (v == found_bound.m_bound && found_bound.m_strict == false && strict))
found_bound = implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict);
} else {
m_improved_upper_bounds[j] = m_ibounds.size();
m_ibounds.push_back(implied_bound(v, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict));
}
}
}
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
@ -100,11 +115,11 @@ public:
}
T get_low_bound() const {
lp_assert(m_low_bound_is_set);
SASSERT(m_low_bound_is_set);
return m_low_bound;
}
T get_upper_bound() const {
lp_assert(m_upper_bound_is_set);
SASSERT(m_upper_bound_is_set);
return m_upper_bound;
}
@ -156,7 +171,7 @@ public:
}
T get_fixed_value() const {
lp_assert(m_is_fixed);
SASSERT(m_is_fixed);
return m_fixed_value;
}

View file

@ -1,8 +1,23 @@
#pragma once
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <string>
#include "util/lp/linear_combination_iterator.h"
namespace lp {

View file

@ -1,8 +1,23 @@
/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
Author: Lev Nachmanson
*/
#pragma once
namespace lp {
template <typename V>

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include <limits>
#include <string>

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <limits>
#include <string>
#include <algorithm>
@ -148,7 +163,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::adjust_
case column_type::free_column:
break;
default:
lp_assert(false);
SASSERT(false);
break;
}
}
@ -357,7 +372,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::print_g
unsigned width = m_column_widths[col];
string s = row[col];
int number_of_blanks = width - static_cast<unsigned>(s.size());
lp_assert(number_of_blanks >= 0);
SASSERT(number_of_blanks >= 0);
print_blanks(number_of_blanks, m_out);
m_out << s << ' ';
if (col < row.size() - 1) {
@ -368,7 +383,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::print_g
string rs = T_to_string(rst);
int nb = m_rs_width - static_cast<int>(rs.size());
lp_assert(nb >= 0);
SASSERT(nb >= 0);
print_blanks(nb + 1, m_out);
m_out << rs << std::endl;
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/numeric_pair.h"
#include "util/lp/core_solver_pretty_printer.hpp"
template lp::core_solver_pretty_printer<double, double>::core_solver_pretty_printer(lp::lp_core_solver_base<double, double> &, std::ostream & out);

View file

@ -1,9 +1,24 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
#include "util/vector.h"
#include "util/lp/matrix.h"
namespace lp {
@ -31,7 +46,7 @@ public:
dense_matrix(unsigned m, unsigned n);
dense_matrix operator*=(matrix<T, X> const & a) {
lp_assert(column_count() == a.row_count());
SASSERT(column_count() == a.row_count());
dense_matrix c(row_count(), a.column_count());
for (unsigned i = 0; i < row_count(); i++) {
for (unsigned j = 0; j < a.column_count(); j++) {

View file

@ -1,9 +1,24 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/lp_settings.h"
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
#include "util/vector.h"
#include "util/lp/numeric_pair.h"
#include "util/lp/dense_matrix.h"
@ -170,7 +185,7 @@ template <typename T, typename X> void dense_matrix<T, X>::multiply_row_by_const
template <typename T, typename X>
dense_matrix<T, X> operator* (matrix<T, X> & a, matrix<T, X> & b){
lp_assert(a.column_count() == b.row_count());
SASSERT(a.column_count() == b.row_count());
dense_matrix<T, X> ret(a.row_count(), b.column_count());
for (unsigned i = 0; i < ret.m_m; i++)
for (unsigned j = 0; j< ret.m_n; j++) {

View file

@ -1,10 +1,25 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/lp_settings.h"
#include "util/lp/dense_matrix.hpp"
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
#include "util/vector.h"
template lp::dense_matrix<double, double> lp::operator*<double, double>(lp::matrix<double, double>&, lp::matrix<double, double>&);
template void lp::dense_matrix<double, double>::apply_from_left(vector<double> &);

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
@ -13,20 +28,20 @@ namespace lp {
template <typename T, typename X>
class eta_matrix
: public tail_matrix<T, X> {
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
unsigned m_length;
#endif
unsigned m_column_index;
public:
sparse_vector<T> m_column_vector;
T m_diagonal_element;
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
eta_matrix(unsigned column_index, unsigned length):
#else
eta_matrix(unsigned column_index):
#endif
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
m_length(length),
#endif
m_column_index(column_index) {}
@ -61,7 +76,7 @@ public:
void push_back(unsigned row_index, T val ) {
lp_assert(row_index != m_column_index);
SASSERT(row_index != m_column_index);
m_column_vector.push_back(row_index, val);
}
@ -69,7 +84,7 @@ public:
void apply_from_right(indexed_vector<T> & w);
T get_elem(unsigned i, unsigned j) const;
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
unsigned row_count() const { return m_length; }
unsigned column_count() const { return m_length; }
void set_number_of_rows(unsigned m) { m_length = m; }

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
@ -49,7 +64,7 @@ apply_from_left_local(indexed_vector<L> & w, lp_settings & settings) {
}
template <typename T, typename X>
void eta_matrix<T, X>::apply_from_right(vector<T> & w) {
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
// dense_matrix<T, X> deb(*this);
// auto clone_w = clone_vector<T>(w, get_number_of_rows());
// deb.apply_from_right(clone_w);
@ -59,8 +74,8 @@ void eta_matrix<T, X>::apply_from_right(vector<T> & w) {
t += w[it.first] * it.second;
}
w[m_column_index] = t;
#ifdef LEAN_DEBUG
// lp_assert(vectors_are_equal<T>(clone_w, w, get_number_of_rows()));
#ifdef Z3DEBUG
// SASSERT(vectors_are_equal<T>(clone_w, w, get_number_of_rows()));
// delete clone_w;
#endif
}
@ -68,7 +83,7 @@ template <typename T, typename X>
void eta_matrix<T, X>::apply_from_right(indexed_vector<T> & w) {
if (w.m_index.size() == 0)
return;
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
// vector<T> wcopy(w.m_data);
// apply_from_right(wcopy);
#endif
@ -99,12 +114,12 @@ void eta_matrix<T, X>::apply_from_right(indexed_vector<T> & w) {
}
}
#ifdef LEAN_DEBUG
// lp_assert(w.is_OK());
// lp_assert(vectors_are_equal<T>(wcopy, w.m_data));
#ifdef Z3DEBUG
// SASSERT(w.is_OK());
// SASSERT(vectors_are_equal<T>(wcopy, w.m_data));
#endif
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename T, typename X>
T eta_matrix<T, X>::get_elem(unsigned i, unsigned j) const {
if (j == m_column_index){
@ -120,7 +135,7 @@ T eta_matrix<T, X>::get_elem(unsigned i, unsigned j) const {
template <typename T, typename X>
void eta_matrix<T, X>::conjugate_by_permutation(permutation_matrix<T, X> & p) {
// this = p * this * p(-1)
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
// auto rev = p.get_reverse();
// auto deb = ((*this) * rev);
// deb = p * deb;
@ -129,8 +144,8 @@ void eta_matrix<T, X>::conjugate_by_permutation(permutation_matrix<T, X> & p) {
for (auto & pair : m_column_vector.m_data) {
pair.first = p.get_rev(pair.first);
}
#ifdef LEAN_DEBUG
// lp_assert(deb == *this);
#ifdef Z3DEBUG
// SASSERT(deb == *this);
#endif
}
}

View file

@ -1,12 +1,27 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <memory>
#include "util/vector.h"
#include "util/lp/numeric_pair.h"
#include "util/lp/eta_matrix.hpp"
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template double lp::eta_matrix<double, double>::get_elem(unsigned int, unsigned int) const;
template lp::mpq lp::eta_matrix<lp::mpq, lp::mpq>::get_elem(unsigned int, unsigned int) const;
template lp::mpq lp::eta_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::get_elem(unsigned int, unsigned int) const;

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include <utility>
#include <functional>

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/lp_settings.h"
#include "util/lp/lar_constraints.h"

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
namespace lp {
@ -41,7 +56,7 @@ public:
m_value = val;
}
};
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename X>
bool check_vector_for_small_values(indexed_vector<X> & w, lp_settings & settings) {
for (unsigned i : w.m_index) {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
@ -75,7 +90,16 @@ public:
}
void set_value(const T& value, unsigned index);
void set_value_as_in_dictionary(unsigned index) {
SASSERT(index < m_data.size());
T & loc = m_data[index];
if (is_zero(loc)) {
m_index.push_back(index);
loc = one_of_type<T>(); // use as a characteristic function
}
}
void clear();
void clear_all();
const T& operator[] (unsigned i) const {
@ -152,7 +176,7 @@ public:
}
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
bool is_OK() const;
void print(std::ostream & out);
#endif

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/vector.h"
#include "util/lp/indexed_vector.h"
#include "util/lp/lp_settings.h"
@ -41,13 +56,13 @@ template <typename T>
void indexed_vector<T>::resize(unsigned data_size) {
clear();
m_data.resize(data_size, numeric_traits<T>::zero());
lp_assert(is_OK());
SASSERT(is_OK());
}
template <typename T>
void indexed_vector<T>::set_value(const T& value, unsigned index) {
m_data[index] = value;
lp_assert(std::find(m_index.begin(), m_index.end(), index) == m_index.end());
SASSERT(std::find(m_index.begin(), m_index.end(), index) == m_index.end());
m_index.push_back(index);
}
@ -70,7 +85,7 @@ void indexed_vector<T>::erase_from_index(unsigned j) {
m_index.erase(it);
}
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template <typename T>
bool indexed_vector<T>::is_OK() const {
return true;

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/vector.h"
#include "util/lp/indexed_vector.hpp"
namespace lp {
@ -17,7 +32,7 @@ template void indexed_vector<mpq>::resize(unsigned int);
template void indexed_vector<unsigned>::resize(unsigned int);
template void indexed_vector<mpq>::set_value(const mpq&, unsigned int);
template void indexed_vector<unsigned>::set_value(const unsigned&, unsigned int);
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
template bool indexed_vector<double>::is_OK() const;
template bool indexed_vector<mpq>::is_OK() const;
template bool indexed_vector<lp::numeric_pair<mpq> >::is_OK() const;

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
#include "util/lp/indexed_vector.h"
@ -20,7 +35,7 @@ public:
return m_data[j] >= 0;
}
void insert(unsigned j) {
lp_assert(j < m_data.size());
SASSERT(j < m_data.size());
if (contains(j)) return;
m_data[j] = m_index.size();
m_index.push_back(j);

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,9 @@
#include "util/lp/iterator_on_row.h"
#include "util/lp/int_set.h"
#include "util/lp/lar_term.h"
#include "util/lp/cut_solver.h"
#include "util/lp/lar_constraints.h"
namespace lp {
class lar_solver;
template <typename T, typename X>
@ -35,9 +38,6 @@ public:
int_set m_old_values_set;
vector<impq> m_old_values_data;
unsigned m_branch_cut_counter;
linear_combination_iterator<mpq>* m_iter_on_gomory_row;
unsigned m_gomory_cut_inf_column;
bool m_found_free_var_in_gomory_row;
// methods
int_solver(lar_solver* lp);
@ -46,6 +46,8 @@ public:
// main function to check that solution provided by lar_solver is valid for integral values,
// or provide a way of how it can be adjusted.
lia_move check(lar_term& t, mpq& k, explanation& ex);
bool move_non_basic_column_to_bounds(unsigned j);
lia_move check_wrapper(lar_term& t, mpq& k, explanation& ex);
private:
// how to tighten bounds for integer variables.
@ -77,22 +79,22 @@ private:
explanation & ex);
void fill_explanation_from_fixed_columns(iterator_on_row<mpq> & it, explanation &);
void add_to_explanation_from_fixed_or_boxed_column(unsigned j, explanation &);
void remove_fixed_vars_from_base();
void patch_int_infeasible_columns();
void patch_int_infeasible_non_basic_column(unsigned j);
void patch_int_infeasible_nbasic_columns();
bool get_freedom_interval_for_column(unsigned j, bool & inf_l, impq & l, bool & inf_u, impq & u, mpq & m);
linear_combination_iterator<mpq> * get_column_iterator(unsigned j);
bool lower(unsigned j) const;
bool upper(unsigned j) const;
const impq & lower_bound(unsigned j) const;
const impq & low_bound(unsigned j) const;
const impq & upper_bound(unsigned j) const;
bool is_int(unsigned j) const;
bool is_real(unsigned j) const;
bool is_base(unsigned j) const;
bool is_boxed(unsigned j) const;
bool is_fixed(unsigned j) const;
bool is_free(unsigned j) const;
bool value_is_int(unsigned j) const;
void set_value_for_nbasic_column(unsigned j, const impq & new_val);
void fix_non_base_columns();
void set_value_for_nbasic_column_ignore_old_values(unsigned j, const impq & new_val);
bool non_basic_columns_are_at_bounds() const;
void failed();
bool is_feasible() const;
const impq & get_value(unsigned j) const;
@ -104,36 +106,52 @@ private:
int find_inf_int_base_column();
int find_inf_int_boxed_base_column_with_smallest_range();
lp_settings& settings();
void move_non_base_vars_to_bounds();
bool move_non_basic_columns_to_bounds();
void branch_infeasible_int_var(unsigned);
lia_move mk_gomory_cut(lar_term& t, mpq& k,explanation & ex);
lia_move mk_gomory_cut(lar_term& t, mpq& k,explanation & ex, unsigned inf_col, linear_combination_iterator<mpq>& iter);
lia_move report_conflict_from_gomory_cut(mpq & k);
lia_move report_gomory_cut(lar_term& t, mpq& k, mpq& lcm_den, unsigned num_ints);
void adjust_term_and_k_for_some_ints_case_gomory(lar_term& t, mpq& k, mpq& lcm_den);
void init_check_data();
bool constrain_free_vars(linear_combination_iterator<mpq> * r);
lia_move proceed_with_gomory_cut(lar_term& t, mpq& k, explanation& ex);
int find_next_free_var_in_gomory_row();
bool is_gomory_cut_target();
lia_move proceed_with_gomory_cut(lar_term& t, mpq& k, explanation& ex, unsigned j);
int find_free_var_in_gomory_row(linear_combination_iterator<mpq>& iter);
bool is_gomory_cut_target(linear_combination_iterator<mpq> &iter);
bool at_bound(unsigned j) const;
bool at_lower(unsigned j) const;
bool at_low(unsigned j) const;
bool at_upper(unsigned j) const;
bool has_low(unsigned j) const;
bool has_upper(unsigned j) const;
unsigned row_of_basic_column(unsigned j) const;
inline static bool is_rational(const impq & n) {
return is_zero(n.y);
}
inline static
mpq fractional_part(const impq & n) {
lp_assert(is_rational);
lp_assert(is_rational(n));
return n.x - floor(n.x);
}
void real_case_in_gomory_cut(const mpq & a, unsigned x_j, mpq & k, lar_term& t, explanation & ex);
void int_case_in_gomory_cut(const mpq & a, unsigned x_j, mpq & k, lar_term& t, explanation& ex, mpq & lcm_den);
void real_case_in_gomory_cut(const mpq & a, unsigned x_j, mpq & k, lar_term& t, explanation & ex, unsigned inf_column);
void int_case_in_gomory_cut(const mpq & a, unsigned x_j, mpq & k, lar_term& t, explanation& ex, mpq & lcm_den, unsigned inf_column);
constraint_index column_upper_bound_constraint(unsigned j) const;
constraint_index column_low_bound_constraint(unsigned j) const;
void display_row_info(std::ostream & out, unsigned row_index) const;
void gomory_cut_adjust_t_and_k_for_size_1(const vector<std::pair<mpq, unsigned>> & pol, lar_term & t, mpq &k);
void gomory_cut_adjust_t_and_k_for_size_gt_1(vector<std::pair<mpq, unsigned>> & pol, lar_term & t, mpq &k, unsigned num_ints, mpq &lcm_den);
void gomory_cut_adjust_t_and_k(vector<std::pair<mpq, unsigned>> & pol, lar_term & t, mpq &k, bool num_ints, mpq &lcm_den);
bool current_solution_is_inf_on_cut(const lar_term& t, const mpq& k) const;
public:
bool shift_var(unsigned j, unsigned range);
private:
unsigned random();
bool has_inf_int() const;
lia_move create_branch_on_column(int j, lar_term& t, mpq& k, bool free_column) const;
public:
void display_inf_or_int_inf_columns(std::ostream & out) const;
template <typename T>
void fill_cut_solver(cut_solver<T> & cs);
template <typename T>
void fill_cut_solver_for_constraint(const lar_base_constraint*, cut_solver<T>& );
template <typename T>
void get_int_coeffs_from_constraint(const lar_base_constraint* c, vector<std::pair<T, var_index>>& coeff, T & rs);
};
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/linear_combination_iterator.h"
#include "util/lp/static_matrix.h"

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/linear_combination_iterator.h"
namespace lp {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/iterator_on_indexed_vector.h"
namespace lp {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/linear_combination_iterator.h"
namespace lp {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/linear_combination_iterator.h"
#include "util/lp/numeric_pair.h"

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
@ -25,7 +40,7 @@ inline std::string lconstraint_kind_string(lconstraint_kind t) {
case GT: return std::string(">");
case EQ: return std::string("=");
}
lp_unreachable();
SASSERT(false);
return std::string(); // it is unreachable
}
@ -74,7 +89,7 @@ public:
: lar_base_constraint(kind, right_side), m_coeffs(left_side) {}
lar_constraint(const lar_base_constraint & c) {
lp_assert(false); // should not be called : todo!
SASSERT(false); // should not be called : todo!
}
unsigned size() const {

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
#include <string>
@ -168,9 +183,9 @@ public:
}
void push() {
lp_assert(m_r_solver.basis_heading_is_correct());
lp_assert(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct());
lp_assert(m_column_types.size() == m_r_A.column_count());
SASSERT(m_r_solver.basis_heading_is_correct());
SASSERT(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct());
SASSERT(m_column_types.size() == m_r_A.column_count());
m_stacked_simplex_strategy = settings().simplex_strategy();
m_stacked_simplex_strategy.push();
m_column_types.push();
@ -192,7 +207,7 @@ public:
template <typename K>
void push_vector(stacked_vector<K> & pushed_vector, const vector<K> & vector) {
lp_assert(pushed_vector.size() <= vector.size());
SASSERT(pushed_vector.size() <= vector.size());
for (unsigned i = 0; i < vector.size();i++) {
if (i == pushed_vector.size()) {
pushed_vector.push_back(vector[i]);
@ -242,8 +257,8 @@ public:
pop_basis(k);
m_stacked_simplex_strategy.pop(k);
settings().simplex_strategy() = m_stacked_simplex_strategy;
lp_assert(m_r_solver.basis_heading_is_correct());
lp_assert(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct());
SASSERT(m_r_solver.basis_heading_is_correct());
SASSERT(!need_to_presolve_with_double_solver() || m_d_solver.basis_heading_is_correct());
}
bool need_to_presolve_with_double_solver() const {
@ -304,11 +319,11 @@ public:
break;
default:
lp_assert(false);
SASSERT(false);
}
break;
default:
lp_unreachable();
SASSERT(false);
}
m_r_solver.remove_column_from_inf_set(j);
return true;
@ -317,7 +332,7 @@ public:
void prepare_solver_x_with_signature_tableau(const lar_solution_signature & signature) {
lp_assert(m_r_solver.inf_set_is_correct());
SASSERT(m_r_solver.inf_set_is_correct());
for (auto &t : signature) {
unsigned j = t.first;
if (m_r_heading[j] >= 0)
@ -332,9 +347,9 @@ public:
m_r_solver.m_x[jb] -= delta * m_r_solver.m_A.get_val(cc);
m_r_solver.update_column_in_inf_set(jb);
}
lp_assert(m_r_solver.A_mult_x_is_off() == false);
SASSERT(m_r_solver.A_mult_x_is_off() == false);
}
lp_assert(m_r_solver.inf_set_is_correct());
SASSERT(m_r_solver.inf_set_is_correct());
}
@ -342,7 +357,7 @@ public:
void prepare_solver_x_with_signature(const lar_solution_signature & signature, lp_primal_core_solver<L,K> & s) {
for (auto &t : signature) {
unsigned j = t.first;
lp_assert(m_r_heading[j] < 0);
SASSERT(m_r_heading[j] < 0);
auto pos_type = t.second;
switch (pos_type) {
case at_low_bound:
@ -359,7 +374,7 @@ public:
case not_at_bound:
switch (m_column_types[j]) {
case column_type::free_column:
lp_assert(false); // unreachable
SASSERT(false); // unreachable
case column_type::upper_bound:
s.m_x[j] = s.m_upper_bounds[j];
break;
@ -377,15 +392,15 @@ public:
s.m_x[j] = s.m_low_bounds[j];
break;
default:
lp_assert(false);
SASSERT(false);
}
break;
default:
lp_unreachable();
SASSERT(false);
}
}
lp_assert(is_zero_vector(s.m_b));
SASSERT(is_zero_vector(s.m_b));
s.solve_Ax_eq_b();
}
@ -418,7 +433,7 @@ public:
// the queues of delayed indices
std::queue<unsigned> entr_q, leav_q;
auto * l = cs.m_factorization;
lp_assert(l->get_status() == LU_status::OK);
SASSERT(l->get_status() == LU_status::OK);
for (unsigned i = 0; i < trace_of_basis_change.size(); i+= 2) {
unsigned entering = trace_of_basis_change[i];
unsigned leaving = trace_of_basis_change[i+1];
@ -446,8 +461,8 @@ public:
continue;
}
}
lp_assert(cs.m_basis_heading[entering] < 0);
lp_assert(cs.m_basis_heading[leaving] >= 0);
SASSERT(cs.m_basis_heading[entering] < 0);
SASSERT(cs.m_basis_heading[leaving] >= 0);
if (l->get_status() == LU_status::OK) {
l->prepare_entering(entering, w); // to init vector w
l->replace_column(zero_of_type<L>(), w, cs.m_basis_heading[leaving]);
@ -471,7 +486,7 @@ public:
void solve_on_signature_tableau(const lar_solution_signature & signature, const vector<unsigned> & changes_of_basis) {
r_basis_is_OK();
lp_assert(settings().use_tableau());
SASSERT(settings().use_tableau());
bool r = catch_up_in_lu_tableau(changes_of_basis, m_d_solver.m_basis_heading);
if (!r) { // it is the case where m_d_solver gives a degenerated basis
@ -490,10 +505,10 @@ public:
return;
m_r_solver.stop_tracing_basis_changes();
// and now catch up in the double solver
lp_assert(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2);
SASSERT(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2);
catch_up_in_lu(m_r_solver.m_trace_of_basis_change_vector, m_r_solver.m_basis_heading, m_d_solver);
}
lp_assert(r_basis_is_OK());
SASSERT(r_basis_is_OK());
}
bool adjust_x_of_column(unsigned j) {
@ -507,16 +522,16 @@ public:
}
m_r_solver.snap_column_to_bound_tableau(j);
lp_assert(m_r_solver.column_is_feasible(j));
SASSERT(m_r_solver.column_is_feasible(j));
m_r_solver.m_inf_set.erase(j);
*/
lp_assert(false);
SASSERT(false);
return true;
}
bool catch_up_in_lu_tableau(const vector<unsigned> & trace_of_basis_change, const vector<int> & basis_heading) {
lp_assert(r_basis_is_OK());
SASSERT(r_basis_is_OK());
// the queues of delayed indices
std::queue<unsigned> entr_q, leav_q;
for (unsigned i = 0; i < trace_of_basis_change.size(); i+= 2) {
@ -546,47 +561,47 @@ public:
continue;
}
}
lp_assert(m_r_solver.m_basis_heading[entering] < 0);
lp_assert(m_r_solver.m_basis_heading[leaving] >= 0);
SASSERT(m_r_solver.m_basis_heading[entering] < 0);
SASSERT(m_r_solver.m_basis_heading[leaving] >= 0);
m_r_solver.change_basis_unconditionally(entering, leaving);
if(!m_r_solver.pivot_column_tableau(entering, m_r_solver.m_basis_heading[entering])) {
// unroll the last step
// unroll the last step
m_r_solver.change_basis_unconditionally(leaving, entering);
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
bool t =
#endif
m_r_solver.pivot_column_tableau(leaving, m_r_solver.m_basis_heading[leaving]);
#ifdef LEAN_DEBUG
lp_assert(t);
#ifdef Z3DEBUG
SASSERT(t);
#endif
return false;
}
}
lp_assert(r_basis_is_OK());
SASSERT(r_basis_is_OK());
return true;
}
bool r_basis_is_OK() const {
#ifdef LEAN_DEBUG
#ifdef Z3DEBUG
if (!m_r_solver.m_settings.use_tableau())
return true;
for (unsigned j : m_r_solver.m_basis) {
lp_assert(m_r_solver.m_A.m_columns[j].size() == 1);
lp_assert(m_r_solver.m_A.get_val(m_r_solver.m_A.m_columns[j][0]) == one_of_type<mpq>());
SASSERT(m_r_solver.m_A.m_columns[j].size() == 1);
SASSERT(m_r_solver.m_A.get_val(m_r_solver.m_A.m_columns[j][0]) == one_of_type<mpq>());
}
for (unsigned j =0; j < m_r_solver.m_basis_heading.size(); j++) {
if (m_r_solver.m_basis_heading[j] >= 0) continue;
if (m_r_solver.m_column_types[j] == column_type::fixed) continue;
lp_assert(static_cast<unsigned>(- m_r_solver.m_basis_heading[j] - 1) < m_r_solver.m_column_types.size());
lp_assert( m_r_solver.m_basis_heading[j] <= -1);
SASSERT(static_cast<unsigned>(- m_r_solver.m_basis_heading[j] - 1) < m_r_solver.m_column_types.size());
SASSERT( m_r_solver.m_basis_heading[j] <= -1);
}
#endif
return true;
}
void solve_on_signature(const lar_solution_signature & signature, const vector<unsigned> & changes_of_basis) {
lp_assert(!settings().use_tableau());
SASSERT(!settings().use_tableau());
if (m_r_solver.m_factorization == nullptr) {
for (unsigned j = 0; j < changes_of_basis.size(); j+=2) {
unsigned entering = changes_of_basis[j];
@ -615,7 +630,7 @@ public:
return;
m_r_solver.stop_tracing_basis_changes();
// and now catch up in the double solver
lp_assert(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2);
SASSERT(m_r_solver.total_iterations() >= m_r_solver.m_trace_of_basis_change_vector.size() /2);
catch_up_in_lu(m_r_solver.m_trace_of_basis_change_vector, m_r_solver.m_basis_heading, m_d_solver);
}
}
@ -641,7 +656,7 @@ public:
template <typename L, typename K>
void extract_signature_from_lp_core_solver(const lp_primal_core_solver<L, K> & solver, lar_solution_signature & signature) {
signature.clear();
lp_assert(signature.size() == 0);
SASSERT(signature.size() == 0);
for (unsigned j = 0; j < solver.m_basis_heading.size(); j++) {
if (solver.m_basis_heading[j] < 0) {
signature[j] = solver.get_non_basic_column_value_position(j);
@ -664,7 +679,7 @@ public:
if (upper_bound_is_set(j)) {
const auto & ub = m_r_solver.m_upper_bounds[j];
m_d_upper_bounds[j] = ub.x.get_double() + delta * ub.y.get_double();
lp_assert(!low_bound_is_set(j) || (m_d_upper_bounds[j] >= m_d_low_bounds[j]));
SASSERT(!low_bound_is_set(j) || (m_d_upper_bounds[j] >= m_d_low_bounds[j]));
}
}
}
@ -729,7 +744,7 @@ public:
case column_type::fixed:
return true;
default:
lp_assert(false);
SASSERT(false);
}
return false;
}
@ -744,20 +759,20 @@ public:
case column_type::fixed:
return true;
default:
lp_assert(false);
SASSERT(false);
}
return false;
}
void update_delta(mpq& delta, numeric_pair<mpq> const& l, numeric_pair<mpq> const& u) const {
lp_assert(l <= u);
SASSERT(l <= u);
if (l.x < u.x && l.y > u.y) {
mpq delta1 = (u.x - l.x) / (l.y - u.y);
if (delta1 < delta) {
delta = delta1;
}
}
lp_assert(l.x + delta * l.y <= u.x + delta * u.y);
SASSERT(l.x + delta * l.y <= u.x + delta * u.y);
}
@ -796,37 +811,6 @@ public:
return new iterator_on_indexed_vector<mpq>(m_r_solver.m_ed);
}
}
bool column_is_fixed(unsigned j) const {
return m_column_types()[j] == column_type::fixed ||
( m_column_types()[j] == column_type::boxed &&
m_r_solver.m_low_bounds[j] == m_r_solver.m_upper_bounds[j]);
}
const impq & low_bound(unsigned j) const {
lp_assert(m_column_types()[j] == column_type::fixed ||
m_column_types()[j] == column_type::boxed ||
m_column_types()[j] == column_type::low_bound);
return m_r_low_bounds[j];
}
const impq & upper_bound(unsigned j) const {
lp_assert(m_column_types()[j] == column_type::fixed ||
m_column_types()[j] == column_type::boxed ||
m_column_types()[j] == column_type::upper_bound);
return m_r_upper_bounds[j];
}
const bool column_is_bounded(unsigned j) const {
switch(m_column_types()[j]) {
case column_type::fixed:
case column_type::boxed:
return true;
default:
return false;
}
}
};
}

View file

@ -1,11 +1,41 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <string>
#include "util/vector.h"
#include "util/lp/lar_core_solver.h"
@ -42,9 +72,9 @@ lar_core_solver::lar_core_solver(
column_names){}
void lar_core_solver::init_costs(bool first_time) {
lp_assert(false); // should not be called
// lp_assert(this->m_x.size() >= this->m_n());
// lp_assert(this->m_column_types.size() >= this->m_n());
SASSERT(false); // should not be called
// SASSERT(this->m_x.size() >= this->m_n());
// SASSERT(this->m_column_types.size() >= this->m_n());
// if (first_time)
// this->m_costs.resize(this->m_n());
// X inf = this->m_infeasibility;
@ -54,7 +84,7 @@ void lar_core_solver::init_costs(bool first_time) {
// if (!(first_time || inf >= this->m_infeasibility)) {
// LP_OUT(this->m_settings, "iter = " << this->total_iterations() << std::endl);
// LP_OUT(this->m_settings, "inf was " << T_to_string(inf) << " and now " << T_to_string(this->m_infeasibility) << std::endl);
// lp_assert(false);
// SASSERT(false);
// }
// if (inf == this->m_infeasibility)
// this->m_iters_with_no_cost_growing++;
@ -105,7 +135,7 @@ void lar_core_solver::init_cost_for_column(unsigned j) {
this->m_costs[j] = numeric_traits<T>::zero();
break;
default:
lp_assert(false);
SASSERT(false);
break;
}*/
}
@ -138,14 +168,30 @@ int lar_core_solver::column_is_out_of_bounds(unsigned j) {
return 0;
break;
}*/
lp_assert(false);
SASSERT(false);
return true;
}
void lar_core_solver::calculate_pivot_row(unsigned i) {
m_r_solver.calculate_pivot_row(i);
SASSERT(!m_r_solver.use_tableau());
SASSERT(m_r_solver.m_pivot_row.is_OK());
m_r_solver.m_pivot_row_of_B_1.clear();
m_r_solver.m_pivot_row_of_B_1.resize(m_r_solver.m_m());
m_r_solver.m_pivot_row.clear();
m_r_solver.m_pivot_row.resize(m_r_solver.m_n());
if (m_r_solver.m_settings.use_tableau()) {
unsigned basis_j = m_r_solver.m_basis[i];
for (auto & c : m_r_solver.m_A.m_rows[i]) {
if (c.m_j != basis_j)
m_r_solver.m_pivot_row.set_value(c.get_val(), c.m_j);
}
return;
}
m_r_solver.calculate_pivot_row_of_B_1(i);
m_r_solver.calculate_pivot_row_when_pivot_row_of_B1_is_ready(i);
}
@ -192,7 +238,7 @@ void lar_core_solver::calculate_pivot_row(unsigned i) {
}
void lar_core_solver::fill_not_improvable_zero_sum_from_inf_row() {
lp_assert(m_r_solver.A_mult_x_is_off() == false);
SASSERT(m_r_solver.A_mult_x_is_off() == false);
unsigned bj = m_r_basis[m_r_solver.m_inf_row_index_for_tableau];
m_infeasible_sum_sign = m_r_solver.inf_sign_of_column(bj);
m_infeasible_linear_combination.clear();
@ -227,32 +273,32 @@ void lar_core_solver::fill_not_improvable_zero_sum() {
void lar_core_solver::solve() {
lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
lp_assert(m_r_solver.inf_set_is_correct());
SASSERT(m_r_solver.non_basic_columns_are_set_correctly());
SASSERT(m_r_solver.inf_set_is_correct());
if (m_r_solver.current_x_is_feasible() && m_r_solver.m_look_for_feasible_solution_only) {
m_r_solver.set_status(lp_status::OPTIMAL);
m_r_solver.set_status(OPTIMAL);
return;
}
++settings().st().m_need_to_solve_inf;
lp_assert(!m_r_solver.A_mult_x_is_off());
lp_assert((!settings().use_tableau()) || r_basis_is_OK());
SASSERT(!m_r_solver.A_mult_x_is_off());
SASSERT((!settings().use_tableau()) || r_basis_is_OK());
if (need_to_presolve_with_double_solver()) {
prefix_d();
lar_solution_signature solution_signature;
vector<unsigned> changes_of_basis = find_solution_signature_with_doubles(solution_signature);
if (m_d_solver.get_status() == lp_status::TIME_EXHAUSTED) {
m_r_solver.set_status(lp_status::TIME_EXHAUSTED);
if (m_d_solver.get_status() == TIME_EXHAUSTED) {
m_r_solver.set_status(TIME_EXHAUSTED);
return;
}
if (settings().use_tableau())
solve_on_signature_tableau(solution_signature, changes_of_basis);
else
solve_on_signature(solution_signature, changes_of_basis);
lp_assert(!settings().use_tableau() || r_basis_is_OK());
SASSERT(!settings().use_tableau() || r_basis_is_OK());
} else {
if (!settings().use_tableau()) {
bool snapped = m_r_solver.snap_non_basic_x_to_bound();
lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
SASSERT(m_r_solver.non_basic_columns_are_set_correctly());
if (snapped)
m_r_solver.solve_Ax_eq_b();
}
@ -260,16 +306,16 @@ void lar_core_solver::solve() {
m_r_solver.find_feasible_solution();
else
m_r_solver.solve();
lp_assert(!settings().use_tableau() || r_basis_is_OK());
SASSERT(!settings().use_tableau() || r_basis_is_OK());
}
if (m_r_solver.get_status() == lp_status::INFEASIBLE) {
if (m_r_solver.get_status() == INFEASIBLE) {
fill_not_improvable_zero_sum();
} else if (m_r_solver.get_status() != lp_status::UNBOUNDED) {
m_r_solver.set_status(lp_status::OPTIMAL);
} else if (m_r_solver.get_status() != UNBOUNDED) {
m_r_solver.set_status(OPTIMAL);
}
lp_assert(r_basis_is_OK());
lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
lp_assert(m_r_solver.inf_set_is_correct());
SASSERT(r_basis_is_OK());
SASSERT(m_r_solver.non_basic_columns_are_set_correctly());
SASSERT(m_r_solver.inf_set_is_correct());
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <utility>
#include <memory>
#include <string>

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/indexed_vector.h"
namespace lp {
@ -10,7 +25,7 @@ struct lar_term {
std::unordered_map<unsigned, mpq> m_coeffs;
mpq m_v;
lar_term() {}
void add_monoid(const mpq& c, unsigned j) {
void add_to_map(unsigned j, const mpq& c) {
auto it = m_coeffs.find(j);
if (it == m_coeffs.end()) {
m_coeffs.emplace(j, c);
@ -21,10 +36,6 @@ struct lar_term {
}
}
bool is_empty() const {
return m_coeffs.size() == 0 && is_zero(m_v);
}
unsigned size() const { return static_cast<unsigned>(m_coeffs.size()); }
const std::unordered_map<unsigned, mpq> & coeffs() const {
@ -34,7 +45,7 @@ struct lar_term {
lar_term(const vector<std::pair<mpq, unsigned>>& coeffs,
const mpq & v) : m_v(v) {
for (const auto & p : coeffs) {
add_monoid(p.first, p.second);
add_to_map(p.second, p.first);
}
}
bool operator==(const lar_term & a) const { return false; } // take care not to create identical terms
@ -56,7 +67,7 @@ struct lar_term {
if (it == m_coeffs.end()) return;
const mpq & b = it->second;
for (unsigned it_j :li.m_index) {
add_monoid(- b * li.m_data[it_j], it_j);
add_to_map(it_j, - b * li.m_data[it_j]);
}
m_coeffs.erase(it);
}
@ -64,26 +75,5 @@ struct lar_term {
bool contains(unsigned j) const {
return m_coeffs.find(j) != m_coeffs.end();
}
void negate() {
for (auto & t : m_coeffs)
t.second.neg();
}
template <typename T>
T apply(const vector<T>& x) const {
T ret = T(m_v);
for (const auto & t : m_coeffs) {
ret += t.second * x[t.first];
}
return ret;
}
void clear() {
m_coeffs.clear();
m_v = zero_of_type<mpq>();
}
};
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
namespace lp {
template <typename T>

View file

@ -0,0 +1,67 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include "util/lp/lar_solver.h"
namespace lp {
lp_bound_propagator::lp_bound_propagator(lar_solver & ls):
m_lar_solver(ls) {}
column_type lp_bound_propagator::get_column_type(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_column_types()[j];
}
const impq & lp_bound_propagator::get_low_bound(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_r_low_bounds()[j];
}
const impq & lp_bound_propagator::get_upper_bound(unsigned j) const {
return m_lar_solver.m_mpq_lar_core_solver.m_r_upper_bounds()[j];
}
void lp_bound_propagator::try_add_bound(const mpq & v, unsigned j, bool is_low, bool coeff_before_j_is_pos, unsigned row_or_term_index, bool strict) {
unsigned term_j = m_lar_solver.adjust_column_index_to_term_index(j);
mpq w = v;
if (term_j != j) {
j = term_j;
w += m_lar_solver.get_term(term_j).m_v; // when terms are turned into the columns they "lose" the right side, at this moment they aquire it back
}
lconstraint_kind kind = is_low? GE : LE;
if (strict)
kind = static_cast<lconstraint_kind>(kind / 2);
if (!bound_is_interesting(j, kind, w))
return;
unsigned k; // index to ibounds
if (is_low) {
if (try_get_val(m_improved_low_bounds, j, k)) {
auto & found_bound = m_ibounds[k];
if (w > found_bound.m_bound || (w == found_bound.m_bound && found_bound.m_strict == false && strict))
found_bound = implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict);
} else {
m_improved_low_bounds[j] = m_ibounds.size();
m_ibounds.push_back(implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict));
}
} else { // the upper bound case
if (try_get_val(m_improved_upper_bounds, j, k)) {
auto & found_bound = m_ibounds[k];
if (w < found_bound.m_bound || (w == found_bound.m_bound && found_bound.m_strict == false && strict))
found_bound = implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict);
} else {
m_improved_upper_bounds[j] = m_ibounds.size();
m_ibounds.push_back(implied_bound(w, j, is_low, coeff_before_j_is_pos, row_or_term_index, strict));
}
}
}
}

View file

@ -1,19 +1,34 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/lp_settings.h"
namespace lp {
class lar_solver;
class bound_propagator {
class lp_bound_propagator {
std::unordered_map<unsigned, unsigned> m_improved_low_bounds; // these maps map a column index to the corresponding index in ibounds
std::unordered_map<unsigned, unsigned> m_improved_upper_bounds;
lar_solver & m_lar_solver;
public:
vector<implied_bound> m_ibounds;
public:
bound_propagator(lar_solver & ls);
lp_bound_propagator(lar_solver & ls);
column_type get_column_type(unsigned) const;
const impq & get_low_bound(unsigned) const;
const impq & get_upper_bound(unsigned) const;

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include <set>
#include "util/vector.h"
@ -13,9 +28,6 @@
#include "util/lp/lu.h"
#include "util/lp/permutation_matrix.h"
#include "util/lp/column_namer.h"
#include "util/lp/iterator_on_row.h"
#include "util/lp/iterator_on_pivot_row.h"
namespace lp {
template <typename T, typename X> // X represents the type of the x variable and the bounds
@ -26,14 +38,7 @@ class lp_core_solver_base {
private:
lp_status m_status;
public:
bool current_x_is_feasible() const {
TRACE("feas",
if (m_inf_set.size()) {
tout << "column " << m_inf_set.m_index[0] << " is infeasible" << std::endl;
}
);
return m_inf_set.size() == 0;
}
bool current_x_is_feasible() const { return m_inf_set.size() == 0; }
bool current_x_is_infeasible() const { return m_inf_set.size() != 0; }
int_set m_inf_set;
bool m_using_infeas_costs;
@ -69,12 +74,6 @@ public:
bool m_tracing_basis_changes;
int_set* m_pivoted_rows;
bool m_look_for_feasible_solution_only;
std::function<void (unsigned, const X &)> * m_tracker_of_x_change;
void set_tracker_of_x(std::function<void (unsigned, const X&)>* tracker) {
m_tracker_of_x_change = tracker;
}
void start_tracing_basis_changes() {
m_trace_of_basis_change_vector.resize(0);
m_tracing_basis_changes = true;
@ -198,11 +197,11 @@ public:
bool need_to_pivot_to_basis_tableau() const {
lp_assert(m_A.is_correct());
SASSERT(m_A.is_correct());
unsigned m = m_A.row_count();
for (unsigned i = 0; i < m; i++) {
unsigned bj = m_basis[i];
lp_assert(m_A.m_columns[bj].size() > 0);
SASSERT(m_A.m_columns[bj].size() > 0);
if (m_A.m_columns[bj].size() > 1 || m_A.get_val(m_A.m_columns[bj][0]) != one_of_type<mpq>()) return true;
}
return false;
@ -211,7 +210,7 @@ public:
bool reduced_costs_are_correct_tableau() const {
if (m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows)
return true;
lp_assert(m_A.is_correct());
SASSERT(m_A.is_correct());
if (m_using_infeas_costs) {
if (infeasibility_costs_are_correct() == false) {
std::cout << "infeasibility_costs_are_correct() does not hold" << std::endl;
@ -386,11 +385,11 @@ public:
}
bool make_column_feasible(unsigned j, numeric_pair<mpq> & delta) {
lp_assert(m_basis_heading[j] < 0);
SASSERT(m_basis_heading[j] < 0);
auto & x = m_x[j];
switch (m_column_types[j]) {
case column_type::fixed:
lp_assert(m_low_bounds[j] == m_upper_bounds[j]);
SASSERT(m_low_bounds[j] == m_upper_bounds[j]);
if (x != m_low_bounds[j]) {
delta = m_low_bounds[j] - x;
x = m_low_bounds[j];
@ -426,7 +425,7 @@ public:
case column_type::free_column:
break;
default:
lp_assert(false);
SASSERT(false);
break;
}
return false;
@ -445,7 +444,6 @@ public:
void init_lu();
int pivots_in_column_and_row_are_different(int entering, int leaving) const;
void pivot_fixed_vars_from_basis();
bool pivot_column_general(unsigned j, unsigned j_basic, indexed_vector<T> & w);
bool pivot_for_tableau_on_basis();
bool pivot_row_for_tableau_on_basis(unsigned row);
void init_basic_part_of_basis_heading() {
@ -475,7 +473,7 @@ public:
}
void change_basis_unconditionally(unsigned entering, unsigned leaving) {
lp_assert(m_basis_heading[entering] < 0);
SASSERT(m_basis_heading[entering] < 0);
int place_in_non_basis = -1 - m_basis_heading[entering];
if (static_cast<unsigned>(place_in_non_basis) >= m_nbasis.size()) {
// entering variable in not in m_nbasis, we need to put it back;
@ -494,8 +492,7 @@ public:
}
void change_basis(unsigned entering, unsigned leaving) {
lp_assert(m_basis_heading[entering] < 0);
lp_assert(m_basis_heading[leaving] >= 0);
SASSERT(m_basis_heading[entering] < 0);
int place_in_basis = m_basis_heading[leaving];
int place_in_non_basis = - m_basis_heading[entering] - 1;
@ -536,7 +533,7 @@ public:
case column_type::free_column:
break;
default:
lp_assert(false);
SASSERT(false);
break;
}
return true;
@ -584,10 +581,10 @@ public:
case column_type::free_column:
break;
default:
lp_assert(false);
SASSERT(false);
}
out << "basis heading = " << m_basis_heading[j] << std::endl;
out << "x = " << m_x[j] << std::endl;
std::cout << "basis heading = " << m_basis_heading[j] << std::endl;
std::cout << "x = " << m_x[j] << std::endl;
/*
std::cout << "cost = " << m_costs[j] << std::endl;
std:: cout << "m_d = " << m_d[j] << std::endl;*/
@ -676,28 +673,24 @@ public:
void update_column_in_inf_set(unsigned j) {
if (column_is_feasible(j)) {
remove_column_from_inf_set(j);
m_inf_set.erase(j);
} else {
insert_column_into_inf_set(j);
m_inf_set.insert(j);
}
}
void insert_column_into_inf_set(unsigned j) {
if (m_tracker_of_x_change != nullptr)
(*m_tracker_of_x_change)(j, m_x[j]);
m_inf_set.insert(j);
lp_assert(!column_is_feasible(j));
SASSERT(!column_is_feasible(j));
}
void remove_column_from_inf_set(unsigned j) {
if (m_tracker_of_x_change != nullptr)
(*m_tracker_of_x_change)(j, m_x[j]);
m_inf_set.erase(j);
lp_assert(column_is_feasible(j));
SASSERT(column_is_feasible(j));
}
bool costs_on_nbasis_are_zeros() const {
lp_assert(this->basis_heading_is_correct());
SASSERT(this->basis_heading_is_correct());
for (unsigned j = 0; j < this->m_n(); j++) {
if (this->m_basis_heading[j] < 0)
lp_assert(is_zero(this->m_costs[j]));
SASSERT(is_zero(this->m_costs[j]));
}
return true;
}
@ -708,17 +701,5 @@ public:
const unsigned & iters_with_no_cost_growing() const {
return m_iters_with_no_cost_growing;
}
linear_combination_iterator<T> * get_iterator_on_row(unsigned i) {
if (m_settings.use_tableau())
return new iterator_on_row<T>(m_A.m_rows[i]);
calculate_pivot_row(i);
return new iterator_on_pivot_row<T>(m_pivot_row, m_basis[i]);
}
void calculate_pivot_row(unsigned i);
unsigned get_base_column_in_row(unsigned row_index) const {
return m_basis[row_index];
}
};
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <set>
#include <string>
#include "util/vector.h"
@ -24,7 +39,7 @@ lp_core_solver_base(static_matrix<T, X> & A,
const vector<X> & upper_bound_values):
m_total_iterations(0),
m_iters_with_no_cost_growing(0),
m_status(lp_status::FEASIBLE),
m_status(FEASIBLE),
m_inf_set(A.column_count()),
m_using_infeas_costs(false),
m_pivot_row_of_B_1(A.row_count()),
@ -52,9 +67,8 @@ lp_core_solver_base(static_matrix<T, X> & A,
m_steepest_edge_coefficients(A.column_count()),
m_tracing_basis_changes(false),
m_pivoted_rows(nullptr),
m_look_for_feasible_solution_only(false),
m_tracker_of_x_change(nullptr) {
lp_assert(bounds_for_boxed_are_set_correctly());
m_look_for_feasible_solution_only(false) {
SASSERT(bounds_for_boxed_are_set_correctly());
init();
init_basis_heading_and_non_basic_columns_vector();
}
@ -62,7 +76,7 @@ lp_core_solver_base(static_matrix<T, X> & A,
template <typename T, typename X> void lp_core_solver_base<T, X>::
allocate_basis_heading() { // the rest of initilization will be handled by the factorization class
init_basis_heading_and_non_basic_columns_vector();
lp_assert(basis_heading_is_correct());
SASSERT(basis_heading_is_correct());
}
template <typename T, typename X> void lp_core_solver_base<T, X>::
init() {
@ -128,7 +142,7 @@ solve_yB(vector<T> & y) {
// }
// }
template <typename T, typename X> void lp_core_solver_base<T, X>::solve_Bd(unsigned entering, indexed_vector<T> & column) {
lp_assert(!m_settings.use_tableau());
SASSERT(!m_settings.use_tableau());
if (m_factorization == nullptr) {
init_factorization(m_factorization, m_A, m_basis, m_settings);
}
@ -138,19 +152,19 @@ template <typename T, typename X> void lp_core_solver_base<T, X>::solve_Bd(unsig
template <typename T, typename X> void lp_core_solver_base<T, X>::
solve_Bd(unsigned entering) {
lp_assert(m_ed.is_OK());
SASSERT(m_ed.is_OK());
m_factorization->solve_Bd(entering, m_ed, m_w);
if (this->precise())
m_columns_nz[entering] = m_ed.m_index.size();
lp_assert(m_ed.is_OK());
lp_assert(m_w.is_OK());
#ifdef LEAN_DEBUG
SASSERT(m_ed.is_OK());
SASSERT(m_w.is_OK());
#ifdef Z3DEBUG
// auto B = get_B(*m_factorization, m_basis);
// vector<T> a(m_m());
// m_A.copy_column_to_vector(entering, a);
// vector<T> cd(m_ed.m_data);
// B.apply_from_left(cd, m_settings);
// lp_assert(vectors_are_equal(cd , a));
// SASSERT(vectors_are_equal(cd , a));
#endif
}
@ -209,7 +223,7 @@ restore_m_ed(T * buffer) {
template <typename T, typename X> bool lp_core_solver_base<T, X>::
A_mult_x_is_off() const {
lp_assert(m_x.size() == m_A.column_count());
SASSERT(m_x.size() == m_A.column_count());
if (numeric_traits<T>::precise()) {
for (unsigned i = 0; i < m_m(); i++) {
X delta = m_b[i] - m_A.dot_product_with_row(i, m_x);
@ -245,7 +259,7 @@ A_mult_x_is_off() const {
}
template <typename T, typename X> bool lp_core_solver_base<T, X>::
A_mult_x_is_off_on_index(const vector<unsigned> & index) const {
lp_assert(m_x.size() == m_A.column_count());
SASSERT(m_x.size() == m_A.column_count());
if (numeric_traits<T>::precise()) return false;
#if RUN_A_MULT_X_IS_OFF_FOR_PRECESE
for (unsigned i : index) {
@ -285,13 +299,13 @@ A_mult_x_is_off_on_index(const vector<unsigned> & index) const {
// from page 182 of Istvan Maros's book
template <typename T, typename X> void lp_core_solver_base<T, X>::
calculate_pivot_row_of_B_1(unsigned pivot_row) {
lp_assert(! use_tableau());
lp_assert(m_pivot_row_of_B_1.is_OK());
SASSERT(! use_tableau());
SASSERT(m_pivot_row_of_B_1.is_OK());
m_pivot_row_of_B_1.clear();
m_pivot_row_of_B_1.set_value(numeric_traits<T>::one(), pivot_row);
lp_assert(m_pivot_row_of_B_1.is_OK());
SASSERT(m_pivot_row_of_B_1.is_OK());
m_factorization->solve_yB_with_error_check_indexed(m_pivot_row_of_B_1, m_basis_heading, m_basis, m_settings);
lp_assert(m_pivot_row_of_B_1.is_OK());
SASSERT(m_pivot_row_of_B_1.is_OK());
}
@ -381,11 +395,11 @@ set_non_basic_x_to_correct_bounds() {
break;
case column_type::low_bound:
m_x[j] = m_low_bounds[j];
lp_assert(column_is_dual_feasible(j));
SASSERT(column_is_dual_feasible(j));
break;
case column_type::upper_bound:
m_x[j] = m_upper_bounds[j];
lp_assert(column_is_dual_feasible(j));
SASSERT(column_is_dual_feasible(j));
break;
default:
break;
@ -403,15 +417,15 @@ column_is_dual_feasible(unsigned j) const {
return x_is_at_low_bound(j) && d_is_not_negative(j);
case column_type::upper_bound:
LP_OUT(m_settings, "upper_bound type should be switched to low_bound" << std::endl);
lp_assert(false); // impossible case
SASSERT(false); // impossible case
case column_type::free_column:
return numeric_traits<X>::is_zero(m_d[j]);
default:
LP_OUT(m_settings, "column = " << j << std::endl);
LP_OUT(m_settings, "unexpected column type = " << column_type_to_string(m_column_types[j]) << std::endl);
lp_unreachable();
SASSERT(false);
}
lp_unreachable();
SASSERT(false);
return false;
}
template <typename T, typename X> bool lp_core_solver_base<T, X>::
@ -494,7 +508,7 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feas
return true;
break;
default:
lp_unreachable();
SASSERT(false);
}
return false; // it is unreachable
}
@ -535,7 +549,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
if (!find_x_by_solving()) {
restore_x(entering, tt);
if(A_mult_x_is_off()) {
m_status = lp_status::FLOATING_POINT_ERROR;
m_status = FLOATING_POINT_ERROR;
m_iters_with_no_cost_growing++;
return false;
}
@ -545,7 +559,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
if (m_factorization->get_status() != LU_status::OK) {
std::stringstream s;
// s << "failing refactor on off_result for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations();
m_status = lp_status::FLOATING_POINT_ERROR;
m_status = FLOATING_POINT_ERROR;
return false;
}
return false;
@ -567,19 +581,19 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
init_lu();
if (m_factorization->get_status() != LU_status::OK) {
if (m_look_for_feasible_solution_only && !precise()) {
m_status = lp_status::UNSTABLE;
m_status = UNSTABLE;
delete m_factorization;
m_factorization = nullptr;
return false;
}
// LP_OUT(m_settings, "failing refactor for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations() << std::endl);
restore_x_and_refactor(entering, leaving, tt);
if (m_status == lp_status::FLOATING_POINT_ERROR)
if (m_status == FLOATING_POINT_ERROR)
return false;
lp_assert(!A_mult_x_is_off());
SASSERT(!A_mult_x_is_off());
m_iters_with_no_cost_growing++;
// LP_OUT(m_settings, "rolled back after failing of init_factorization()" << std::endl);
m_status = lp_status::UNSTABLE;
m_status = UNSTABLE;
return false;
}
return true;
@ -588,7 +602,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
template <typename T, typename X> bool lp_core_solver_base<T, X>::
divide_row_by_pivot(unsigned pivot_row, unsigned pivot_col) {
lp_assert(numeric_traits<T>::precise());
SASSERT(numeric_traits<T>::precise());
int pivot_index = -1;
auto & row = m_A.m_rows[pivot_row];
unsigned size = row.size();
@ -629,7 +643,7 @@ pivot_column_tableau(unsigned j, unsigned piv_row_index) {
return false;
if (pivot_col_cell_index != 0) {
lp_assert(column.size() > 1);
SASSERT(column.size() > 1);
// swap the pivot column cell with the head cell
auto c = column[0];
column[0] = column[pivot_col_cell_index];
@ -640,7 +654,7 @@ pivot_column_tableau(unsigned j, unsigned piv_row_index) {
}
while (column.size() > 1) {
auto & c = column.back();
lp_assert(c.m_i != piv_row_index);
SASSERT(c.m_i != piv_row_index);
if(! m_A.pivot_row_to_row_given_cell(piv_row_index, c, j)) {
return false;
}
@ -688,7 +702,7 @@ non_basis_is_correctly_represented_in_heading() const {
}
for (unsigned j = 0; j < m_A.column_count(); j++) {
if (m_basis_heading[j] >= 0) {
lp_assert(static_cast<unsigned>(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j);
SASSERT(static_cast<unsigned>(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j);
}
}
return true;
@ -696,9 +710,9 @@ non_basis_is_correctly_represented_in_heading() const {
template <typename T, typename X> bool lp_core_solver_base<T, X>::
basis_heading_is_correct() const {
lp_assert(m_basis_heading.size() == m_A.column_count());
lp_assert(m_basis.size() == m_A.row_count());
lp_assert(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller
SASSERT(m_basis_heading.size() == m_A.column_count());
SASSERT(m_basis.size() == m_A.row_count());
SASSERT(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller
if (!basis_has_no_doubles()) {
// std::cout << "basis_has_no_doubles" << std::endl;
return false;
@ -842,7 +856,7 @@ solve_Ax_eq_b() {
template <typename T, typename X> void lp_core_solver_base<T, X>::
snap_non_basic_x_to_bound_and_free_to_zeroes() {
for (unsigned j : non_basis()) {
lp_assert(j < m_x.size());
SASSERT(j < m_x.size());
switch (m_column_types[j]) {
case column_type::fixed:
case column_type::boxed:
@ -893,9 +907,9 @@ get_non_basic_column_value_position(unsigned j) const {
case column_type::upper_bound:
return x_is_at_upper_bound(j)? at_upper_bound : not_at_bound;
default:
lp_unreachable();
SASSERT(false);
}
lp_unreachable();
SASSERT(false);
return at_low_bound;
}
@ -924,55 +938,42 @@ template <typename T, typename X> void lp_core_solver_base<T, X>::transpose_row
transpose_basis(i, j);
m_A.transpose_rows(i, j);
}
// j is the new basic column, j_basic - the leaving column
template <typename T, typename X> bool lp_core_solver_base<T, X>::pivot_column_general(unsigned j, unsigned j_basic, indexed_vector<T> & w) {
lp_assert(m_basis_heading[j] < 0);
lp_assert(m_basis_heading[j_basic] >= 0);
unsigned row_index = m_basis_heading[j_basic];
if (m_settings.m_simplex_strategy == simplex_strategy_enum::lu) {
if (m_factorization->need_to_refactor()) {
init_lu();
}
else {
m_factorization->prepare_entering(j, w); // to init vector w
m_factorization->replace_column(zero_of_type<T>(), w, row_index);
}
if (m_factorization->get_status() != LU_status::OK) {
init_lu();
return false;
}
else {
change_basis(j, j_basic);
}
}
else { // the tableau case
if (pivot_column_tableau(j, row_index))
change_basis(j, j_basic);
else return false;
}
return true;
}
template <typename T, typename X> void lp_core_solver_base<T, X>::pivot_fixed_vars_from_basis() {
// run over basis and non-basis at the same time
indexed_vector<T> w(m_basis.size()); // the buffer
unsigned i = 0; // points to basis
for (; i < m_basis.size(); i++) {
unsigned basic_j = m_basis[i];
unsigned j = 0; // points to nonbasis
for (; i < m_basis.size() && j < m_nbasis.size(); i++) {
unsigned ii = m_basis[i];
unsigned jj;
if (get_column_type(basic_j) != column_type::fixed) continue;
T a;
unsigned j;
auto * it = get_iterator_on_row(i);
while (it->next(a, j)) {
if (j == basic_j)
continue;
if (get_column_type(j) != column_type::fixed) {
if (pivot_column_general(j, basic_j, w))
if (get_column_type(ii) != column_type::fixed) continue;
while (j < m_nbasis.size()) {
for (; j < m_nbasis.size(); j++) {
jj = m_nbasis[j];
if (get_column_type(jj) != column_type::fixed)
break;
}
if (j >= m_nbasis.size())
break;
j++;
if (m_factorization->need_to_refactor()) {
change_basis(jj, ii);
init_lu();
} else {
m_factorization->prepare_entering(jj, w); // to init vector w
m_factorization->replace_column(zero_of_type<T>(), w, m_basis_heading[ii]);
change_basis(jj, ii);
}
if (m_factorization->get_status() != LU_status::OK) {
change_basis(ii, jj);
init_lu();
} else {
break;
}
}
delete it;
SASSERT(m_factorization->get_status()== LU_status::OK);
}
}
@ -980,7 +981,7 @@ template <typename T, typename X> bool
lp_core_solver_base<T, X>::infeasibility_costs_are_correct() const {
if (! this->m_using_infeas_costs)
return true;
lp_assert(costs_on_nbasis_are_zeros());
SASSERT(costs_on_nbasis_are_zeros());
for (unsigned j :this->m_basis) {
if (!infeasibility_cost_is_correct_for_column(j)) {
std::cout << "infeasibility_cost_is_correct_for_column does not hold\n";
@ -1025,31 +1026,9 @@ lp_core_solver_base<T, X>::infeasibility_cost_is_correct_for_column(unsigned j)
case column_type::free_column:
return is_zero(this->m_costs[j]);
default:
lp_assert(false);
SASSERT(false);
return true;
}
}
template <typename T, typename X>
void lp_core_solver_base<T, X>::calculate_pivot_row(unsigned i) {
lp_assert(!use_tableau());
lp_assert(m_pivot_row.is_OK());
m_pivot_row_of_B_1.clear();
m_pivot_row_of_B_1.resize(m_m());
m_pivot_row.clear();
m_pivot_row.resize(m_n());
if (m_settings.use_tableau()) {
unsigned basis_j = m_basis[i];
for (auto & c : m_A.m_rows[i]) {
if (c.m_j != basis_j)
m_pivot_row.set_value(c.get_val(), c.m_j);
}
return;
}
calculate_pivot_row_of_B_1(i);
calculate_pivot_row_when_pivot_row_of_B1_is_ready(i);
}
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <utility>
#include <memory>
#include <string>
@ -129,4 +144,3 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::inf_set_is_correct() co
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::infeasibility_costs_are_correct() const;
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq >::infeasibility_costs_are_correct() const;
template bool lp::lp_core_solver_base<double, double >::infeasibility_costs_are_correct() const;
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::calculate_pivot_row(unsigned int);

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/lp/static_matrix.h"
#include "util/lp/lp_core_solver_base.h"

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <algorithm>
#include <string>
#include "util/vector.h"
@ -23,7 +38,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::restore_non_ba
while (j--) {
if (this->m_basis_heading[j] >= 0 ) continue;
if (m_can_enter_basis[j]) {
lp_assert(std::find(nb.begin(), nb.end(), j) == nb.end());
SASSERT(std::find(nb.begin(), nb.end(), j) == nb.end());
nb.push_back(j);
this->m_basis_heading[j] = - static_cast<int>(nb.size());
}
@ -82,25 +97,25 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::start_with_ini
}
template <typename T, typename X> bool lp_dual_core_solver<T, X>::done() {
if (this->get_status() == lp_status::OPTIMAL) {
if (this->get_status() == OPTIMAL) {
return true;
}
if (this->total_iterations() > this->m_settings.max_total_number_of_iterations) { // debug !!!!
this->set_status(lp_status::ITERATIONS_EXHAUSTED);
this->set_status(ITERATIONS_EXHAUSTED);
return true;
}
return false; // todo, need to be more cases
}
template <typename T, typename X> T lp_dual_core_solver<T, X>::get_edge_steepness_for_low_bound(unsigned p) {
lp_assert(this->m_basis_heading[p] >= 0 && static_cast<unsigned>(this->m_basis_heading[p]) < this->m_m());
SASSERT(this->m_basis_heading[p] >= 0 && static_cast<unsigned>(this->m_basis_heading[p]) < this->m_m());
T del = this->m_x[p] - this->m_low_bounds[p];
del *= del;
return del / this->m_betas[this->m_basis_heading[p]];
}
template <typename T, typename X> T lp_dual_core_solver<T, X>::get_edge_steepness_for_upper_bound(unsigned p) {
lp_assert(this->m_basis_heading[p] >= 0 && static_cast<unsigned>(this->m_basis_heading[p]) < this->m_m());
SASSERT(this->m_basis_heading[p] >= 0 && static_cast<unsigned>(this->m_basis_heading[p]) < this->m_m());
T del = this->m_x[p] - this->m_upper_bounds[p];
del *= del;
return del / this->m_betas[this->m_basis_heading[p]];
@ -135,12 +150,12 @@ template <typename T, typename X> T lp_dual_core_solver<T, X>::pricing_for_row(u
return numeric_traits<T>::zero();
break;
case column_type::free_column:
lp_assert(numeric_traits<T>::is_zero(this->m_d[p]));
SASSERT(numeric_traits<T>::is_zero(this->m_d[p]));
return numeric_traits<T>::zero();
default:
lp_unreachable();
SASSERT(false);
}
lp_unreachable();
SASSERT(false);
return numeric_traits<T>::zero();
}
@ -170,8 +185,8 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::pricing_loop(u
}
} while (i != initial_offset_in_rows && rows_left);
if (m_r == -1) {
if (this->get_status() != lp_status::UNSTABLE) {
this->set_status(lp_status::OPTIMAL);
if (this->get_status() != UNSTABLE) {
this->set_status(OPTIMAL);
}
} else {
m_p = this->m_basis[m_r];
@ -181,10 +196,10 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::pricing_loop(u
return;
}
// failure in advance_on_known_p
if (this->get_status() == lp_status::FLOATING_POINT_ERROR) {
if (this->get_status() == FLOATING_POINT_ERROR) {
return;
}
this->set_status(lp_status::UNSTABLE);
this->set_status(UNSTABLE);
m_forbidden_rows.insert(m_r);
}
}
@ -209,9 +224,9 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::advance_on_kno
int pivot_compare_result = this->pivots_in_column_and_row_are_different(m_q, m_p);
if (!pivot_compare_result){;}
else if (pivot_compare_result == 2) { // the sign is changed, cannot continue
lp_unreachable(); // not implemented yet
SASSERT(false); // not implemented yet
} else {
lp_assert(pivot_compare_result == 1);
SASSERT(pivot_compare_result == 1);
this->init_lu();
}
DSE_FTran();
@ -228,21 +243,21 @@ template <typename T, typename X> int lp_dual_core_solver<T, X>::define_sign_of_
if (this->x_above_upper_bound(m_p)) {
return 1;
}
lp_unreachable();
SASSERT(false);
case column_type::low_bound:
if (this->x_below_low_bound(m_p)) {
return -1;
}
lp_unreachable();
SASSERT(false);
case column_type::upper_bound:
if (this->x_above_upper_bound(m_p)) {
return 1;
}
lp_unreachable();
SASSERT(false);
default:
lp_unreachable();
SASSERT(false);
}
lp_unreachable();
SASSERT(false);
return 0;
}
@ -250,10 +265,10 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::can_be_breakpo
if (this->pivot_row_element_is_too_small_for_ratio_test(j)) return false;
switch (this->m_column_types[j]) {
case column_type::low_bound:
lp_assert(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_low_bounds[j]));
SASSERT(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_low_bounds[j]));
return m_sign_of_alpha_r * this->m_pivot_row[j] > 0;
case column_type::upper_bound:
lp_assert(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_upper_bounds[j]));
SASSERT(this->m_settings.abs_val_is_smaller_than_harris_tolerance(this->m_x[j] - this->m_upper_bounds[j]));
return m_sign_of_alpha_r * this->m_pivot_row[j] < 0;
case column_type::boxed:
{
@ -292,23 +307,23 @@ template <typename T, typename X> T lp_dual_core_solver<T, X>::get_delta() {
if (this->x_above_upper_bound(m_p)) {
return this->m_x[m_p] - this->m_upper_bounds[m_p];
}
lp_unreachable();
SASSERT(false);
case column_type::low_bound:
if (this->x_below_low_bound(m_p)) {
return this->m_x[m_p] - this->m_low_bounds[m_p];
}
lp_unreachable();
SASSERT(false);
case column_type::upper_bound:
if (this->x_above_upper_bound(m_p)) {
return get_edge_steepness_for_upper_bound(m_p);
}
lp_unreachable();
SASSERT(false);
case column_type::fixed:
return this->m_x[m_p] - this->m_upper_bounds[m_p];
default:
lp_unreachable();
SASSERT(false);
}
lp_unreachable();
SASSERT(false);
return zero_of_type<T>();
}
@ -355,7 +370,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::update_betas()
template <typename T, typename X> void lp_dual_core_solver<T, X>::apply_flips() {
for (unsigned j : m_flipped_boxed) {
lp_assert(this->x_is_at_bound(j));
SASSERT(this->x_is_at_bound(j));
if (this->x_is_at_low_bound(j)) {
this->m_x[j] = this->m_upper_bounds[j];
} else {
@ -385,7 +400,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::snap_xN_column
case column_type::free_column:
break;
default:
lp_unreachable();
SASSERT(false);
}
}
@ -441,7 +456,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::basis_change_a
return false;
}
lp_assert(d_is_correct());
SASSERT(d_is_correct());
return true;
}
@ -457,7 +472,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::recover_leavin
case free_of_bounds:
this->m_x[m_q] = zero_of_type<X>();
default:
lp_unreachable();
SASSERT(false);
}
}
@ -466,12 +481,12 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::revert_to_prev
this->change_basis_unconditionally(m_p, m_q);
init_factorization(this->m_factorization, this->m_A, this->m_basis, this->m_settings);
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(lp_status::FLOATING_POINT_ERROR); // complete failure
this->set_status(FLOATING_POINT_ERROR); // complete failure
return;
}
recover_leaving();
if (!this->find_x_by_solving()) {
this->set_status(lp_status::FLOATING_POINT_ERROR);
this->set_status(FLOATING_POINT_ERROR);
return;
}
recalculate_xB_and_d();
@ -551,10 +566,10 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::delta_keeps_th
}
template <typename T, typename X> void lp_dual_core_solver<T, X>::set_status_to_tentative_dual_unbounded_or_dual_unbounded() {
if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
this->set_status(lp_status::DUAL_UNBOUNDED);
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) {
this->set_status(DUAL_UNBOUNDED);
} else {
this->set_status(lp_status::TENTATIVE_DUAL_UNBOUNDED);
this->set_status(TENTATIVE_DUAL_UNBOUNDED);
}
}
@ -584,7 +599,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::tight_breakpoi
template <typename T, typename X> T lp_dual_core_solver<T, X>::calculate_harris_delta_on_breakpoint_set() {
bool first_time = true;
T ret = zero_of_type<T>();
lp_assert(m_breakpoint_set.size() > 0);
SASSERT(m_breakpoint_set.size() > 0);
for (auto j : m_breakpoint_set) {
T t;
if (this->x_is_at_low_bound(j)) {
@ -633,7 +648,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::find_q_on_tigh
}
}
m_tight_set.erase(m_q);
lp_assert(m_q != -1);
SASSERT(m_q != -1);
}
template <typename T, typename X> void lp_dual_core_solver<T, X>::find_q_and_tight_set() {
@ -660,7 +675,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::ratio_test() {
set_status_to_tentative_dual_unbounded_or_dual_unbounded();
return false;
}
this->set_status(lp_status::FEASIBLE);
this->set_status(FEASIBLE);
find_q_and_tight_set();
if (!tight_breakpoinst_are_all_boxed()) break;
T del = m_delta - delta_lost_on_flips_of_tight_breakpoints() * initial_delta_sign;
@ -716,19 +731,19 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::update_xb_afte
template <typename T, typename X> void lp_dual_core_solver<T, X>::one_iteration() {
unsigned number_of_rows_to_try = get_number_of_rows_to_try_for_leaving();
unsigned offset_in_rows = this->m_settings.random_next() % this->m_m();
if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) {
number_of_rows_to_try = this->m_m();
} else {
this->set_status(lp_status::FEASIBLE);
this->set_status(FEASIBLE);
}
pricing_loop(number_of_rows_to_try, offset_in_rows);
lp_assert(problem_is_dual_feasible());
SASSERT(problem_is_dual_feasible());
}
template <typename T, typename X> void lp_dual_core_solver<T, X>::solve() { // see the page 35
lp_assert(d_is_correct());
lp_assert(problem_is_dual_feasible());
lp_assert(this->basis_heading_is_correct());
SASSERT(d_is_correct());
SASSERT(problem_is_dual_feasible());
SASSERT(this->basis_heading_is_correct());
this->set_total_iterations(0);
this->iters_with_no_cost_growing() = 0;
do {
@ -736,7 +751,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::solve() { // s
return;
}
one_iteration();
} while (this->get_status() != lp_status::FLOATING_POINT_ERROR && this->get_status() != lp_status::DUAL_UNBOUNDED && this->get_status() != lp_status::OPTIMAL &&
} while (this->get_status() != FLOATING_POINT_ERROR && this->get_status() != DUAL_UNBOUNDED && this->get_status() != OPTIMAL &&
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
&& this->total_iterations() <= this->m_settings.max_total_number_of_iterations);
}

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#include <utility>
#include <memory>
#include <string>

View file

@ -1,7 +1,22 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Lev Nachmanson
*/
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
<name>
Abstract:
<abstract>
Author:
Lev Nachmanson (levnach)
Revision History:
--*/
#pragma once
#include "util/vector.h"
#include "util/lp/lp_utils.h"

Some files were not shown because too many files have changed in this diff Show more