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:
commit
651587ce01
1602 changed files with 40496 additions and 27837 deletions
|
@ -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;
|
||||
|
|
|
@ -17,7 +17,7 @@ Revision History:
|
|||
|
||||
--*/
|
||||
|
||||
#include"approx_set.h"
|
||||
#include "util/approx_set.h"
|
||||
|
||||
void approx_set::display(std::ostream & out) const {
|
||||
out << "{";
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
/*
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ Revision History:
|
|||
#ifndef F2N_H_
|
||||
#define F2N_H_
|
||||
|
||||
#include"mpf.h"
|
||||
#include "util/mpf.h"
|
||||
|
||||
template<typename fmanager>
|
||||
class f2n {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ Notes:
|
|||
#ifndef GPARAMS_H_
|
||||
#define GPARAMS_H_
|
||||
|
||||
#include"params.h"
|
||||
#include "util/params.h"
|
||||
|
||||
class gparams {
|
||||
struct imp;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -20,7 +20,7 @@ Revision History:
|
|||
#define HASH_H_
|
||||
|
||||
#include<algorithm>
|
||||
#include"util.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#define mix(a,b,c) \
|
||||
{ \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -16,7 +16,7 @@ Author:
|
|||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"lbool.h"
|
||||
#include "util/lbool.h"
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, lbool b) {
|
||||
switch(b) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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> &);
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
@ -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>();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
67
src/util/lp/lp_bound_propagator.cpp
Normal file
67
src/util/lp/lp_bound_propagator.cpp
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue