mirror of
https://github.com/Z3Prover/z3
synced 2025-06-21 13:23:39 +00:00
Merge branch 'unstable' of https://git01.codeplex.com/z3 into unstable
This commit is contained in:
commit
1317a71a1a
10 changed files with 300 additions and 245 deletions
|
@ -73,10 +73,12 @@ GMP=False
|
||||||
VS_PAR=False
|
VS_PAR=False
|
||||||
VS_PAR_NUM=8
|
VS_PAR_NUM=8
|
||||||
GPROF=False
|
GPROF=False
|
||||||
|
GIT_HASH=False
|
||||||
|
|
||||||
def git_hash():
|
def git_hash():
|
||||||
try:
|
try:
|
||||||
r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'HEAD'], shell=True).rstrip('\r\n')
|
branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'], shell=True).rstrip('\r\n')
|
||||||
|
r = subprocess.check_output(['git', 'show-ref', '--abbrev=12', 'refs/heads/%s' % branch], shell=True).rstrip('\r\n')
|
||||||
except:
|
except:
|
||||||
raise MKException("Failed to retrieve git hash")
|
raise MKException("Failed to retrieve git hash")
|
||||||
ls = r.split(' ')
|
ls = r.split(' ')
|
||||||
|
@ -371,6 +373,7 @@ def display_help(exit_code):
|
||||||
else:
|
else:
|
||||||
print(" --parallel=num use cl option /MP with 'num' parallel processes")
|
print(" --parallel=num use cl option /MP with 'num' parallel processes")
|
||||||
print(" -b <sudir>, --build=<subdir> subdirectory where Z3 will be built (default: build).")
|
print(" -b <sudir>, --build=<subdir> subdirectory where Z3 will be built (default: build).")
|
||||||
|
print(" --githash=hash include the given hash in the binaries.")
|
||||||
print(" -d, --debug compile Z3 in debug mode.")
|
print(" -d, --debug compile Z3 in debug mode.")
|
||||||
print(" -t, --trace enable tracing in release mode.")
|
print(" -t, --trace enable tracing in release mode.")
|
||||||
if IS_WINDOWS:
|
if IS_WINDOWS:
|
||||||
|
@ -401,12 +404,13 @@ def display_help(exit_code):
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
def parse_options():
|
def parse_options():
|
||||||
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
||||||
global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF
|
global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH
|
||||||
try:
|
try:
|
||||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||||
'b:dsxhmcvtnp:gj',
|
'b:dsxhmcvtnp:gj',
|
||||||
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
|
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
|
||||||
'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof'])
|
'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof',
|
||||||
|
'githash='])
|
||||||
except:
|
except:
|
||||||
print("ERROR: Invalid command line option")
|
print("ERROR: Invalid command line option")
|
||||||
display_help(1)
|
display_help(1)
|
||||||
|
@ -453,6 +457,8 @@ def parse_options():
|
||||||
JAVA_ENABLED = True
|
JAVA_ENABLED = True
|
||||||
elif opt == '--gprof':
|
elif opt == '--gprof':
|
||||||
GPROF = True
|
GPROF = True
|
||||||
|
elif opt == '--githash':
|
||||||
|
GIT_HASH=arg
|
||||||
else:
|
else:
|
||||||
print("ERROR: Invalid command line option '%s'" % opt)
|
print("ERROR: Invalid command line option '%s'" % opt)
|
||||||
display_help(1)
|
display_help(1)
|
||||||
|
@ -1290,18 +1296,23 @@ def mk_config():
|
||||||
'SO_EXT=.dll\n'
|
'SO_EXT=.dll\n'
|
||||||
'SLINK=cl\n'
|
'SLINK=cl\n'
|
||||||
'SLINK_OUT_FLAG=/Fe\n')
|
'SLINK_OUT_FLAG=/Fe\n')
|
||||||
|
extra_opt = ''
|
||||||
|
if GIT_HASH:
|
||||||
|
extra_opt = '%s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
|
||||||
if DEBUG_MODE:
|
if DEBUG_MODE:
|
||||||
config.write(
|
config.write(
|
||||||
'LINK_FLAGS=/nologo /MDd\n'
|
'LINK_FLAGS=/nologo /MDd\n'
|
||||||
'SLINK_FLAGS=/nologo /LDd\n')
|
'SLINK_FLAGS=/nologo /LDd\n')
|
||||||
if not VS_X64:
|
if not VS_X64:
|
||||||
config.write(
|
config.write(
|
||||||
'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n'
|
'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
|
||||||
|
config.write(
|
||||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||||
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||||
else:
|
else:
|
||||||
config.write(
|
config.write(
|
||||||
'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n'
|
'CXXFLAGS=/c /Zi /nologo /openmp /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt)
|
||||||
|
config.write(
|
||||||
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
|
||||||
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
|
||||||
else:
|
else:
|
||||||
|
@ -1309,9 +1320,8 @@ def mk_config():
|
||||||
config.write(
|
config.write(
|
||||||
'LINK_FLAGS=/nologo /MD\n'
|
'LINK_FLAGS=/nologo /MD\n'
|
||||||
'SLINK_FLAGS=/nologo /LD\n')
|
'SLINK_FLAGS=/nologo /LD\n')
|
||||||
extra_opt = ''
|
|
||||||
if TRACE:
|
if TRACE:
|
||||||
extra_opt = '/D _TRACE'
|
extra_opt = '%s /D _TRACE' % extra_opt
|
||||||
if not VS_X64:
|
if not VS_X64:
|
||||||
config.write(
|
config.write(
|
||||||
'CXXFLAGS=/nologo /c /Zi /openmp /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
|
'CXXFLAGS=/nologo /c /Zi /openmp /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
|
||||||
|
@ -1350,6 +1360,8 @@ def mk_config():
|
||||||
SLIBEXTRAFLAGS = '%s -lgmp' % SLIBEXTRAFLAGS
|
SLIBEXTRAFLAGS = '%s -lgmp' % SLIBEXTRAFLAGS
|
||||||
else:
|
else:
|
||||||
CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS
|
CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS
|
||||||
|
if GIT_HASH:
|
||||||
|
CPPFLAGS = '%s -DZ3GITHASH=%s' % (CPPFLAGS, GIT_HASH)
|
||||||
CXXFLAGS = '%s -c' % CXXFLAGS
|
CXXFLAGS = '%s -c' % CXXFLAGS
|
||||||
HAS_OMP = test_openmp(CXX)
|
HAS_OMP = test_openmp(CXX)
|
||||||
if HAS_OMP:
|
if HAS_OMP:
|
||||||
|
|
|
@ -101,6 +101,8 @@ def mk_build_dir(path, x64):
|
||||||
opts.append('--java')
|
opts.append('--java')
|
||||||
if x64:
|
if x64:
|
||||||
opts.append('-x')
|
opts.append('-x')
|
||||||
|
if GIT_HASH:
|
||||||
|
opts.append('--githash=%s' % mk_util.git_hash())
|
||||||
if subprocess.call(opts) != 0:
|
if subprocess.call(opts) != 0:
|
||||||
raise MKException("Failed to generate build directory at '%s'" % path)
|
raise MKException("Failed to generate build directory at '%s'" % path)
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,6 @@ public class Context extends IDisposable
|
||||||
initContext();
|
initContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Context(long ctx, long refCount)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
this.m_ctx = ctx;
|
|
||||||
this.m_refCount = refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new symbol using an integer. <remarks> Not all integers can be
|
* Creates a new symbol using an integer. <remarks> Not all integers can be
|
||||||
* passed to this function. The legal range of unsigned integers is 0 to
|
* passed to this function. The legal range of unsigned integers is 0 to
|
||||||
|
|
|
@ -128,7 +128,8 @@ public class Sort extends AST
|
||||||
|
|
||||||
static Sort create(Context ctx, long obj) throws Z3Exception
|
static Sort create(Context ctx, long obj) throws Z3Exception
|
||||||
{
|
{
|
||||||
switch (Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj)))
|
Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj));
|
||||||
|
switch (sk)
|
||||||
{
|
{
|
||||||
case Z3_ARRAY_SORT:
|
case Z3_ARRAY_SORT:
|
||||||
return new ArraySort(ctx, obj);
|
return new ArraySort(ctx, obj);
|
||||||
|
|
|
@ -82,9 +82,19 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class hilbert_basis::weight_map {
|
class hilbert_basis::weight_map {
|
||||||
|
struct stats {
|
||||||
|
unsigned m_num_comparisons;
|
||||||
|
stats() { reset(); }
|
||||||
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
rational_heap m_heap;
|
rational_heap m_heap;
|
||||||
vector<unsigned_vector> m_offsets; // [index |-> offset-list]
|
vector<unsigned_vector> m_offsets; // [index |-> offset-list]
|
||||||
int_vector m_le; // recycled set of indices with lesser weights
|
int_vector m_le; // recycled set of indices with lesser weights
|
||||||
|
stats m_stats;
|
||||||
|
svector<offset_t>& m_found;
|
||||||
|
offset_refs_t& m_refs;
|
||||||
|
unsigned m_cost;
|
||||||
|
|
||||||
unsigned get_value(numeral const& w) {
|
unsigned get_value(numeral const& w) {
|
||||||
unsigned val;
|
unsigned val;
|
||||||
|
@ -99,7 +109,7 @@ class hilbert_basis::weight_map {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
weight_map() {}
|
weight_map(svector<offset_t>& found, offset_refs_t& refs): m_found(found), m_refs(refs) {}
|
||||||
|
|
||||||
void insert(offset_t idx, numeral const& w) {
|
void insert(offset_t idx, numeral const& w) {
|
||||||
unsigned val = get_value(w);
|
unsigned val = get_value(w);
|
||||||
|
@ -117,9 +127,12 @@ public:
|
||||||
m_le.reset();
|
m_le.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_find(offset_refs_t& refs, numeral const& w, offset_t idx, offset_t& found_idx, unsigned& cost) {
|
unsigned get_cost() const { return m_cost; }
|
||||||
//std::cout << "init find: " << w << "\n";
|
|
||||||
|
bool init_find(numeral const& w, offset_t idx) {
|
||||||
m_le.reset();
|
m_le.reset();
|
||||||
|
m_found.reset();
|
||||||
|
m_cost = 0;
|
||||||
unsigned val = get_value(w);
|
unsigned val = get_value(w);
|
||||||
// for positive values, the weights should be less or equal.
|
// for positive values, the weights should be less or equal.
|
||||||
// for non-positive values, the weights have to be the same.
|
// for non-positive values, the weights have to be the same.
|
||||||
|
@ -129,47 +142,53 @@ public:
|
||||||
else {
|
else {
|
||||||
m_le.push_back(val);
|
m_le.push_back(val);
|
||||||
}
|
}
|
||||||
bool found = false;
|
|
||||||
for (unsigned i = 0; i < m_le.size(); ++i) {
|
for (unsigned i = 0; i < m_le.size(); ++i) {
|
||||||
if (m_heap.u2r()[m_le[i]].is_zero() && w.is_pos()) {
|
if (m_heap.u2r()[m_le[i]].is_zero() && w.is_pos()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//std::cout << "insert init find: " << m_weights[m_le[i]] << "\n";
|
|
||||||
unsigned_vector const& offsets = m_offsets[m_le[i]];
|
unsigned_vector const& offsets = m_offsets[m_le[i]];
|
||||||
for (unsigned j = 0; j < offsets.size(); ++j) {
|
for (unsigned j = 0; j < offsets.size(); ++j) {
|
||||||
unsigned offs = offsets[j];
|
unsigned offs = offsets[j];
|
||||||
++cost;
|
++m_stats.m_num_comparisons;
|
||||||
|
++m_cost;
|
||||||
if (offs != idx.m_offset) {
|
if (offs != idx.m_offset) {
|
||||||
refs.insert(offs, 0);
|
m_refs.insert(offs, 0);
|
||||||
found_idx = offset_t(offs);
|
m_found.push_back(offset_t(offs));
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return !m_found.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update_find(offset_refs_t& refs, unsigned round, numeral const& w,
|
bool update_find(unsigned round, numeral const& w, offset_t idx) {
|
||||||
offset_t idx, offset_t& found_idx, unsigned& cost) {
|
|
||||||
//std::cout << "update find: " << w << "\n";
|
//std::cout << "update find: " << w << "\n";
|
||||||
|
m_found.reset();
|
||||||
m_le.reset();
|
m_le.reset();
|
||||||
|
m_cost = 0;
|
||||||
m_heap.find_le(w, m_le);
|
m_heap.find_le(w, m_le);
|
||||||
bool found = false;
|
|
||||||
unsigned vl;
|
unsigned vl;
|
||||||
for (unsigned i = 0; i < m_le.size(); ++i) {
|
for (unsigned i = 0; i < m_le.size(); ++i) {
|
||||||
//std::cout << "insert update find: " << m_weights[m_le[i]] << "\n";
|
//std::cout << "insert update find: " << m_weights[m_le[i]] << "\n";
|
||||||
unsigned_vector const& offsets = m_offsets[m_le[i]];
|
unsigned_vector const& offsets = m_offsets[m_le[i]];
|
||||||
for (unsigned j = 0; j < offsets.size(); ++j) {
|
for (unsigned j = 0; j < offsets.size(); ++j) {
|
||||||
unsigned offs = offsets[j];
|
unsigned offs = offsets[j];
|
||||||
++cost;
|
++m_stats.m_num_comparisons;
|
||||||
if (offs != idx.m_offset && refs.find(offs, vl) && vl == round) {
|
++m_cost;
|
||||||
refs.insert(offs, round + 1);
|
if (offs != idx.m_offset && m_refs.find(offs, vl) && vl == round) {
|
||||||
found_idx = offset_t(offs);
|
m_refs.insert(offs, round + 1);
|
||||||
found = true;
|
m_found.push_back(offset_t(offs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return !m_found.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void collect_statistics(statistics& st) const {
|
||||||
|
st.update("hb.index.num_comparisons", m_stats.m_num_comparisons);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_statistics() {
|
||||||
|
m_stats.reset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,13 +204,18 @@ class hilbert_basis::index {
|
||||||
stats() { reset(); }
|
stats() { reset(); }
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
hilbert_basis& hb;
|
||||||
|
offset_refs_t m_refs;
|
||||||
|
svector<offset_t> m_found;
|
||||||
ptr_vector<weight_map> m_values;
|
ptr_vector<weight_map> m_values;
|
||||||
weight_map m_weight;
|
weight_map m_weight;
|
||||||
offset_refs_t m_refs;
|
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
index(hilbert_basis& hb): hb(hb), m_weight(m_found, m_refs) {}
|
||||||
|
|
||||||
~index() {
|
~index() {
|
||||||
for (unsigned i = 0; i < m_values.size(); ++i) {
|
for (unsigned i = 0; i < m_values.size(); ++i) {
|
||||||
dealloc(m_values[i]);
|
dealloc(m_values[i]);
|
||||||
|
@ -201,34 +225,53 @@ public:
|
||||||
void init(unsigned num_vars) {
|
void init(unsigned num_vars) {
|
||||||
if (m_values.empty()) {
|
if (m_values.empty()) {
|
||||||
for (unsigned i = 0; i < num_vars; ++i) {
|
for (unsigned i = 0; i < num_vars; ++i) {
|
||||||
m_values.push_back(alloc(weight_map));
|
m_values.push_back(alloc(weight_map, m_found, m_refs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SASSERT(m_values.size() == num_vars);
|
SASSERT(m_values.size() == num_vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(offset_t idx, values vs, numeral const& weight) {
|
void insert(offset_t idx, values const& vs) {
|
||||||
++m_stats.m_num_insert;
|
++m_stats.m_num_insert;
|
||||||
|
#if 0
|
||||||
for (unsigned i = 0; i < m_values.size(); ++i) {
|
for (unsigned i = 0; i < m_values.size(); ++i) {
|
||||||
m_values[i]->insert(idx, vs[i]);
|
m_values[i]->insert(idx, vs[i]);
|
||||||
}
|
}
|
||||||
m_weight.insert(idx, weight);
|
#endif
|
||||||
|
m_weight.insert(idx, vs.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(offset_t idx, values vs, numeral const& weight) {
|
void remove(offset_t idx, values const& vs) {
|
||||||
|
#if 0
|
||||||
for (unsigned i = 0; i < m_values.size(); ++i) {
|
for (unsigned i = 0; i < m_values.size(); ++i) {
|
||||||
m_values[i]->remove(idx, vs[i]);
|
m_values[i]->remove(idx, vs[i]);
|
||||||
}
|
}
|
||||||
m_weight.remove(idx, weight);
|
#endif
|
||||||
|
m_weight.remove(idx, vs.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find(values vs, numeral const& weight, offset_t idx, offset_t& found_idx) {
|
bool find(values const& vs, offset_t idx, offset_t& found_idx) {
|
||||||
++m_stats.m_num_find;
|
++m_stats.m_num_find;
|
||||||
bool found = m_weight.init_find(m_refs, weight, idx, found_idx, m_stats.m_num_comparisons);
|
|
||||||
for (unsigned i = 0; found && i < m_values.size(); ++i) {
|
|
||||||
found = m_values[i]->update_find(m_refs, i, vs[i], idx, found_idx, m_stats.m_num_comparisons);
|
|
||||||
}
|
|
||||||
m_refs.reset();
|
m_refs.reset();
|
||||||
|
bool found = m_weight.init_find(vs.value(), idx);
|
||||||
|
TRACE("hilbert_basis", tout << "init: " << m_found.size() << " cost: " << m_weight.get_cost() << "\n";);
|
||||||
|
#if 0
|
||||||
|
for (unsigned i = 0; found && i < m_values.size(); ++i) {
|
||||||
|
found = m_values[i]->update_find(i, vs[i], idx);
|
||||||
|
TRACE("hilbert_basis", tout << "update " << i << ": " << m_found.size() << " cost: " << m_values[i]->get_cost() << "\n";);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (unsigned i = 0; i < m_found.size(); ++i) {
|
||||||
|
if (is_subsumed(idx, m_found[i])) {
|
||||||
|
found_idx = m_found[i];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
if (found) {
|
||||||
|
found_idx = m_found[0];
|
||||||
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,42 +284,77 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_statistics(statistics& st) const {
|
void collect_statistics(statistics& st) const {
|
||||||
st.update("hb.index.num_comparisons", m_stats.m_num_comparisons);
|
m_weight.collect_statistics(st);
|
||||||
|
for (unsigned i = 0; i < m_values.size(); ++i) {
|
||||||
|
m_values[i]->collect_statistics(st);
|
||||||
|
}
|
||||||
st.update("hb.index.num_find", m_stats.m_num_find);
|
st.update("hb.index.num_find", m_stats.m_num_find);
|
||||||
st.update("hb.index.num_insert", m_stats.m_num_insert);
|
st.update("hb.index.num_insert", m_stats.m_num_insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset_statistics() {
|
void reset_statistics() {
|
||||||
m_stats.reset();
|
m_stats.reset();
|
||||||
|
m_weight.reset_statistics();
|
||||||
|
for (unsigned i = 0; i < m_values.size(); ++i) {
|
||||||
|
m_values[i]->reset_statistics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// remains of a simpler index strucure:
|
/**
|
||||||
if (eval(idx).is_zero()) {
|
Vector v is subsumed by vector w if
|
||||||
for (unsigned i = 0; i < m_zero.size(); ++i) {
|
|
||||||
if (is_subsumed(idx, m_zero[i])) {
|
v[i] >= w[i] for each index i.
|
||||||
++m_stats.m_num_subsumptions;
|
|
||||||
return true;
|
a*v >= a*w for the evaluation of vectors with respect to a.
|
||||||
}
|
|
||||||
|
a*v < 0 => a*v = a*w
|
||||||
|
|
||||||
|
|
||||||
|
Justification:
|
||||||
|
|
||||||
|
let u := v - w, then
|
||||||
|
|
||||||
|
u[i] >= 0 for each index i
|
||||||
|
|
||||||
|
a*u = a*(v-w) >= 0
|
||||||
|
|
||||||
|
So v = u + w, where a*u >= 0, a*w >= 0.
|
||||||
|
|
||||||
|
If a*v >= a*w >= 0 then v and w are linear
|
||||||
|
solutions of e_i, and also v-w is a solution.
|
||||||
|
|
||||||
|
If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w).
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool is_subsumed(offset_t i, offset_t j) const {
|
||||||
|
values v = hb.vec(i);
|
||||||
|
values w = hb.vec(j);
|
||||||
|
numeral const& n = v.value();
|
||||||
|
numeral const& m = w.value();
|
||||||
|
bool r =
|
||||||
|
i.m_offset != j.m_offset &&
|
||||||
|
n >= m && (!m.is_neg() || n == m) &&
|
||||||
|
is_geq(v, w);
|
||||||
|
CTRACE("hilbert_basis", r,
|
||||||
|
hb.display(tout, i);
|
||||||
|
tout << " <= \n";
|
||||||
|
hb.display(tout, j);
|
||||||
|
tout << "\n";);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_geq(values v, values w) const {
|
||||||
|
unsigned nv = hb.get_num_vars();
|
||||||
|
for (unsigned i = 0; i < nv; ++i) {
|
||||||
|
if (v[i] < w[i]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; i < m_active.size(); ++i) {
|
}
|
||||||
if (is_subsumed(idx, m_active[i])) {
|
|
||||||
++m_stats.m_num_subsumptions;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
passive::iterator it = m_passive->begin();
|
|
||||||
passive::iterator end = m_passive->end();
|
|
||||||
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
if (is_subsumed(idx, *it)) {
|
|
||||||
++m_stats.m_num_subsumptions;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -377,7 +455,7 @@ public:
|
||||||
hilbert_basis::hilbert_basis():
|
hilbert_basis::hilbert_basis():
|
||||||
m_cancel(false)
|
m_cancel(false)
|
||||||
{
|
{
|
||||||
m_index = alloc(index);
|
m_index = alloc(index, *this);
|
||||||
m_passive = alloc(passive, *this);
|
m_passive = alloc(passive, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +477,6 @@ void hilbert_basis::reset() {
|
||||||
m_basis.reset();
|
m_basis.reset();
|
||||||
m_store.reset();
|
m_store.reset();
|
||||||
m_free_list.reset();
|
m_free_list.reset();
|
||||||
m_eval.reset();
|
|
||||||
m_active.reset();
|
m_active.reset();
|
||||||
m_passive->reset();
|
m_passive->reset();
|
||||||
m_zero.reset();
|
m_zero.reset();
|
||||||
|
@ -418,20 +495,36 @@ void hilbert_basis::reset_statistics() {
|
||||||
m_index->reset_statistics();
|
m_index->reset_statistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::add_ge(num_vector const& v) {
|
void hilbert_basis::add_ge(num_vector const& v, numeral const& b) {
|
||||||
SASSERT(m_ineqs.empty() || v.size() == get_num_vars());
|
SASSERT(m_ineqs.empty() || v.size() + 1 == get_num_vars());
|
||||||
|
num_vector w;
|
||||||
|
w.push_back(-b);
|
||||||
|
w.append(v);
|
||||||
if (m_ineqs.empty()) {
|
if (m_ineqs.empty()) {
|
||||||
m_index->init(v.size());
|
m_index->init(w.size());
|
||||||
}
|
}
|
||||||
m_ineqs.push_back(v);
|
m_ineqs.push_back(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::add_le(num_vector const& v) {
|
void hilbert_basis::add_le(num_vector const& v, numeral const& b) {
|
||||||
num_vector w(v);
|
num_vector w(v);
|
||||||
for (unsigned i = 0; i < w.size(); ++i) {
|
for (unsigned i = 0; i < w.size(); ++i) {
|
||||||
w[i].neg();
|
w[i].neg();
|
||||||
}
|
}
|
||||||
add_ge(w);
|
add_ge(w, -b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hilbert_basis::add_eq(num_vector const& v, numeral const& b) {
|
||||||
|
add_le(v, b);
|
||||||
|
add_ge(v, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hilbert_basis::add_ge(num_vector const& v) {
|
||||||
|
add_ge(v, numeral(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void hilbert_basis::add_le(num_vector const& v) {
|
||||||
|
add_le(v, numeral(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::add_eq(num_vector const& v) {
|
void hilbert_basis::add_eq(num_vector const& v) {
|
||||||
|
@ -449,24 +542,22 @@ unsigned hilbert_basis::get_num_vars() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
hilbert_basis::values hilbert_basis::vec(offset_t offs) const {
|
hilbert_basis::values hilbert_basis::vec(offset_t offs) const {
|
||||||
return m_store.c_ptr() + offs.m_offset;
|
return values(m_store.c_ptr() + offs.m_offset);
|
||||||
}
|
|
||||||
|
|
||||||
hilbert_basis::values_ref hilbert_basis::vec(offset_t offs) {
|
|
||||||
return m_store.c_ptr() + offs.m_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::init_basis() {
|
void hilbert_basis::init_basis() {
|
||||||
m_basis.reset();
|
m_basis.reset();
|
||||||
m_store.reset();
|
m_store.reset();
|
||||||
m_eval.reset();
|
|
||||||
m_free_list.reset();
|
m_free_list.reset();
|
||||||
unsigned num_vars = get_num_vars();
|
unsigned num_vars = get_num_vars();
|
||||||
for (unsigned i = 0; i < num_vars; ++i) {
|
for (unsigned i = 0; i < num_vars; ++i) {
|
||||||
num_vector w(num_vars, numeral(0));
|
num_vector w(num_vars, numeral(0));
|
||||||
w[i] = numeral(1);
|
w[i] = numeral(1);
|
||||||
offset_t idx = alloc_vector();
|
offset_t idx = alloc_vector();
|
||||||
set_value(idx, w.c_ptr());
|
values v = vec(idx);
|
||||||
|
for (unsigned i = 0; i < num_vars; ++i) {
|
||||||
|
v[i] = w[i];
|
||||||
|
}
|
||||||
m_basis.push_back(idx);
|
m_basis.push_back(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,10 +585,10 @@ lbool hilbert_basis::saturate(num_vector const& ineq) {
|
||||||
bool has_non_negative = false;
|
bool has_non_negative = false;
|
||||||
iterator it = begin();
|
iterator it = begin();
|
||||||
for (; it != end(); ++it) {
|
for (; it != end(); ++it) {
|
||||||
numeral n = eval(vec(*it), ineq);
|
values v = vec(*it);
|
||||||
eval(*it) = n;
|
set_eval(v, ineq);
|
||||||
add_goal(*it);
|
add_goal(*it);
|
||||||
if (n.is_nonneg()) {
|
if (v.value().is_nonneg()) {
|
||||||
has_non_negative = true;
|
has_non_negative = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -517,7 +608,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (unsigned i = 0; !m_cancel && i < m_active.size(); ++i) {
|
for (unsigned i = 0; !m_cancel && i < m_active.size(); ++i) {
|
||||||
if (get_sign(idx) != get_sign(m_active[i])) {
|
if (can_resolve(idx, m_active[i])) {
|
||||||
offset_t j = alloc_vector();
|
offset_t j = alloc_vector();
|
||||||
resolve(idx, m_active[i], j);
|
resolve(idx, m_active[i], j);
|
||||||
add_goal(j);
|
add_goal(j);
|
||||||
|
@ -530,7 +621,7 @@ lbool hilbert_basis::saturate(num_vector const& ineq) {
|
||||||
m_basis.append(m_zero);
|
m_basis.append(m_zero);
|
||||||
for (unsigned i = 0; i < m_active.size(); ++i) {
|
for (unsigned i = 0; i < m_active.size(); ++i) {
|
||||||
offset_t idx = m_active[i];
|
offset_t idx = m_active[i];
|
||||||
if (eval(idx).is_pos()) {
|
if (vec(idx).value().is_pos()) {
|
||||||
m_basis.push_back(idx);
|
m_basis.push_back(idx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -544,16 +635,8 @@ lbool hilbert_basis::saturate(num_vector const& ineq) {
|
||||||
return l_true;
|
return l_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hilbert_basis::set_value(offset_t offs, values v) {
|
|
||||||
unsigned nv = get_num_vars();
|
|
||||||
for (unsigned i = 0; i < nv; ++i) {
|
|
||||||
m_store[offs.m_offset+i] = v[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void hilbert_basis::recycle(offset_t idx) {
|
void hilbert_basis::recycle(offset_t idx) {
|
||||||
m_index->remove(idx, vec(idx), eval(idx));
|
m_index->remove(idx, vec(idx));
|
||||||
m_free_list.push_back(idx);
|
m_free_list.push_back(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,26 +644,25 @@ void hilbert_basis::resolve(offset_t i, offset_t j, offset_t r) {
|
||||||
++m_stats.m_num_resolves;
|
++m_stats.m_num_resolves;
|
||||||
values v = vec(i);
|
values v = vec(i);
|
||||||
values w = vec(j);
|
values w = vec(j);
|
||||||
values_ref u = vec(r);
|
values u = vec(r);
|
||||||
unsigned nv = get_num_vars();
|
unsigned nv = get_num_vars();
|
||||||
for (unsigned k = 0; k < nv; ++k) {
|
for (unsigned k = 0; k < nv; ++k) {
|
||||||
u[k] = v[k] + w[k];
|
u[k] = v[k] + w[k];
|
||||||
}
|
}
|
||||||
eval(r) = eval(i) + eval(j);
|
u.value() = v.value() + w.value();
|
||||||
TRACE("hilbert_basis_verbose",
|
TRACE("hilbert_basis_verbose",
|
||||||
display(tout, i);
|
display(tout, i);
|
||||||
display(tout, j);
|
display(tout, j);
|
||||||
display(tout, r);
|
display(tout, r);
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
hilbert_basis::offset_t hilbert_basis::alloc_vector() {
|
hilbert_basis::offset_t hilbert_basis::alloc_vector() {
|
||||||
if (m_free_list.empty()) {
|
if (m_free_list.empty()) {
|
||||||
unsigned num_vars = get_num_vars();
|
unsigned num_vars = get_num_vars();
|
||||||
unsigned idx = m_store.size();
|
unsigned idx = m_store.size();
|
||||||
m_store.resize(idx + get_num_vars());
|
m_store.resize(idx + 1 + get_num_vars());
|
||||||
m_eval.push_back(numeral(0));
|
|
||||||
return offset_t(idx);
|
return offset_t(idx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -590,10 +672,10 @@ hilbert_basis::offset_t hilbert_basis::alloc_vector() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void hilbert_basis::add_goal(offset_t idx) {
|
void hilbert_basis::add_goal(offset_t idx) {
|
||||||
m_index->insert(idx, vec(idx), eval(idx));
|
values v = vec(idx);
|
||||||
if (eval(idx).is_zero()) {
|
m_index->insert(idx, v);
|
||||||
|
if (v.value().is_zero()) {
|
||||||
if (!is_subsumed(idx)) {
|
if (!is_subsumed(idx)) {
|
||||||
m_zero.push_back(idx);
|
m_zero.push_back(idx);
|
||||||
}
|
}
|
||||||
|
@ -606,7 +688,7 @@ void hilbert_basis::add_goal(offset_t idx) {
|
||||||
bool hilbert_basis::is_subsumed(offset_t idx) {
|
bool hilbert_basis::is_subsumed(offset_t idx) {
|
||||||
|
|
||||||
offset_t found_idx;
|
offset_t found_idx;
|
||||||
if (m_index->find(vec(idx), eval(idx), idx, found_idx)) {
|
if (m_index->find(vec(idx), idx, found_idx)) {
|
||||||
TRACE("hilbert_basis",
|
TRACE("hilbert_basis",
|
||||||
display(tout, idx);
|
display(tout, idx);
|
||||||
tout << " <= \n";
|
tout << " <= \n";
|
||||||
|
@ -618,77 +700,30 @@ bool hilbert_basis::is_subsumed(offset_t idx) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bool hilbert_basis::can_resolve(offset_t i, offset_t j) const {
|
||||||
Vector v is subsumed by vector w if
|
sign_t s1 = get_sign(i);
|
||||||
|
sign_t s2 = get_sign(j);
|
||||||
v[i] >= w[i] for each index i.
|
return s1 != s2 && abs(vec(i)[0] + vec(j)[0]) <= numeral(1);
|
||||||
|
|
||||||
a*v >= a*w for the evaluation of vectors with respect to a.
|
|
||||||
|
|
||||||
a*v < 0 => a*v = a*w
|
|
||||||
|
|
||||||
|
|
||||||
Justification:
|
|
||||||
|
|
||||||
let u := v - w, then
|
|
||||||
|
|
||||||
u[i] >= 0 for each index i
|
|
||||||
|
|
||||||
a*u = a*(v-w) >= 0
|
|
||||||
|
|
||||||
So v = u + w, where a*u >= 0, a*w >= 0.
|
|
||||||
|
|
||||||
If a*v >= a*w >= 0 then v and w are linear
|
|
||||||
solutions of e_i, and also v-w is a solution.
|
|
||||||
|
|
||||||
If a*v = a*w < 0, then a*(v-w) = 0, so v can be obtained from w + (v - w).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool hilbert_basis::is_subsumed(offset_t i, offset_t j) const {
|
|
||||||
values v = vec(i);
|
|
||||||
values w = vec(j);
|
|
||||||
numeral const& n = eval(i);
|
|
||||||
numeral const& m = eval(j);
|
|
||||||
bool r =
|
|
||||||
i.m_offset != j.m_offset &&
|
|
||||||
n >= m && (!m.is_neg() || n == m) &&
|
|
||||||
is_geq(v, w);
|
|
||||||
CTRACE("hilbert_basis", r,
|
|
||||||
display(tout, i);
|
|
||||||
tout << " <= \n";
|
|
||||||
display(tout, j);
|
|
||||||
tout << "\n";);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hilbert_basis::is_geq(values v, values w) const {
|
|
||||||
unsigned nv = get_num_vars();
|
|
||||||
for (unsigned i = 0; i < nv; ++i) {
|
|
||||||
if (v[i] < w[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const {
|
hilbert_basis::sign_t hilbert_basis::get_sign(offset_t idx) const {
|
||||||
if (eval(idx).is_pos()) {
|
numeral val = vec(idx).value();
|
||||||
|
if (val.is_pos()) {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
if (eval(idx).is_neg()) {
|
if (val.is_neg()) {
|
||||||
return neg;
|
return neg;
|
||||||
}
|
}
|
||||||
return zero;
|
return zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
hilbert_basis::numeral hilbert_basis::eval(values val, num_vector const& ineq) const {
|
void hilbert_basis::set_eval(values& val, num_vector const& ineq) const {
|
||||||
numeral result(0);
|
numeral result(0);
|
||||||
unsigned num_vars = get_num_vars();
|
unsigned num_vars = get_num_vars();
|
||||||
for (unsigned i = 0; i < num_vars; ++i) {
|
for (unsigned i = 0; i < num_vars; ++i) {
|
||||||
result += val[i]*ineq[i];
|
result += val[i]*ineq[i];
|
||||||
}
|
}
|
||||||
return result;
|
val.value() = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::display(std::ostream& out) const {
|
void hilbert_basis::display(std::ostream& out) const {
|
||||||
|
@ -728,10 +763,10 @@ void hilbert_basis::display(std::ostream& out) const {
|
||||||
|
|
||||||
void hilbert_basis::display(std::ostream& out, offset_t o) const {
|
void hilbert_basis::display(std::ostream& out, offset_t o) const {
|
||||||
display(out, vec(o));
|
display(out, vec(o));
|
||||||
out << " -> " << eval(o) << "\n";
|
out << " -> " << vec(o).value() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_basis::display(std::ostream& out, values v) const {
|
void hilbert_basis::display(std::ostream& out, values const& v) const {
|
||||||
unsigned nv = get_num_vars();
|
unsigned nv = get_num_vars();
|
||||||
for (unsigned j = 0; j < nv; ++j) {
|
for (unsigned j = 0; j < nv; ++j) {
|
||||||
out << v[j] << " ";
|
out << v[j] << " ";
|
||||||
|
@ -762,21 +797,15 @@ void hilbert_basis::display_ineq(std::ostream& out, num_vector const& v) const {
|
||||||
out << " >= 0\n";
|
out << " >= 0\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void hilbert_sl_basis::add_le(num_vector const& v, numeral bound) {
|
|
||||||
num_vector w;
|
|
||||||
w.push_back(-bound);
|
|
||||||
w.append(v);
|
|
||||||
m_basis.add_le(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) {
|
void hilbert_isl_basis::add_le(num_vector const& v, numeral bound) {
|
||||||
unsigned sz = v.size();
|
unsigned sz = v.size();
|
||||||
num_vector w;
|
num_vector w;
|
||||||
|
w.push_back(-bound);
|
||||||
|
w.push_back(bound);
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
w.push_back(v[i]);
|
w.push_back(v[i]);
|
||||||
w.push_back(-v[i]);
|
w.push_back(-v[i]);
|
||||||
}
|
}
|
||||||
w.push_back(-bound);
|
|
||||||
w.push_back(bound);
|
|
||||||
m_basis.add_le(w);
|
m_basis.add_le(w);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,12 +53,18 @@ private:
|
||||||
stats() { reset(); }
|
stats() { reset(); }
|
||||||
void reset() { memset(this, 0, sizeof(*this)); }
|
void reset() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
typedef numeral const* values;
|
class values {
|
||||||
typedef numeral* values_ref;
|
numeral* m_values;
|
||||||
|
public:
|
||||||
|
values(numeral* v):m_values(v) {}
|
||||||
|
numeral& value() { return m_values[0]; } // value of a*x
|
||||||
|
numeral& operator[](unsigned i) { return m_values[i+1]; } // value of x_i
|
||||||
|
numeral const& value() const { return m_values[0]; } // value of a*x
|
||||||
|
numeral const& operator[](unsigned i) const { return m_values[i+1]; } // value of x_i
|
||||||
|
};
|
||||||
|
|
||||||
vector<num_vector> m_ineqs;
|
vector<num_vector> m_ineqs;
|
||||||
num_vector m_store;
|
num_vector m_store;
|
||||||
num_vector m_eval;
|
|
||||||
svector<offset_t> m_basis;
|
svector<offset_t> m_basis;
|
||||||
svector<offset_t> m_free_list;
|
svector<offset_t> m_free_list;
|
||||||
svector<offset_t> m_active;
|
svector<offset_t> m_active;
|
||||||
|
@ -84,12 +90,12 @@ private:
|
||||||
lbool saturate(num_vector const& ineq);
|
lbool saturate(num_vector const& ineq);
|
||||||
void init_basis();
|
void init_basis();
|
||||||
unsigned get_num_vars() const;
|
unsigned get_num_vars() const;
|
||||||
numeral eval(values val, num_vector const& ineq) const;
|
void set_eval(values& val, num_vector const& ineq) const;
|
||||||
bool is_subsumed(offset_t idx);
|
bool is_subsumed(offset_t idx);
|
||||||
bool is_subsumed(offset_t i, offset_t j) const;
|
bool is_subsumed(offset_t i, offset_t j) const;
|
||||||
bool is_geq(values v, values w) const;
|
|
||||||
void recycle(offset_t idx);
|
void recycle(offset_t idx);
|
||||||
sign_t hilbert_basis::get_sign(offset_t idx) const;
|
bool can_resolve(offset_t i, offset_t j) const;
|
||||||
|
sign_t get_sign(offset_t idx) const;
|
||||||
void add_goal(offset_t idx);
|
void add_goal(offset_t idx);
|
||||||
offset_t alloc_vector();
|
offset_t alloc_vector();
|
||||||
void resolve(offset_t i, offset_t j, offset_t r);
|
void resolve(offset_t i, offset_t j, offset_t r);
|
||||||
|
@ -97,18 +103,9 @@ private:
|
||||||
iterator end() const { return iterator(*this, m_basis.size()); }
|
iterator end() const { return iterator(*this, m_basis.size()); }
|
||||||
|
|
||||||
values vec(offset_t offs) const;
|
values vec(offset_t offs) const;
|
||||||
values_ref vec(offset_t offs);
|
|
||||||
numeral const& eval(offset_t o) const {
|
|
||||||
return m_eval[o.m_offset/get_num_vars()];
|
|
||||||
}
|
|
||||||
numeral& eval(offset_t o) {
|
|
||||||
return m_eval[o.m_offset/get_num_vars()];
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_value(offset_t offs, values v);
|
|
||||||
|
|
||||||
void display(std::ostream& out, offset_t o) const;
|
void display(std::ostream& out, offset_t o) const;
|
||||||
void display(std::ostream& out, values v) const;
|
void display(std::ostream& out, values const & v) const;
|
||||||
void display_ineq(std::ostream& out, num_vector const& v) const;
|
void display_ineq(std::ostream& out, num_vector const& v) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -118,14 +115,20 @@ public:
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
// add inequality v*x <= 0
|
|
||||||
// add inequality v*x >= 0
|
// add inequality v*x >= 0
|
||||||
|
// add inequality v*x <= 0
|
||||||
// add equality v*x = 0
|
// add equality v*x = 0
|
||||||
|
|
||||||
void add_le(num_vector const& v);
|
|
||||||
void add_ge(num_vector const& v);
|
void add_ge(num_vector const& v);
|
||||||
|
void add_le(num_vector const& v);
|
||||||
void add_eq(num_vector const& v);
|
void add_eq(num_vector const& v);
|
||||||
|
|
||||||
|
// add inequality v*x >= b
|
||||||
|
// add inequality v*x <= b
|
||||||
|
// add equality v*x = b
|
||||||
|
void add_ge(num_vector const& v, numeral const& b);
|
||||||
|
void add_le(num_vector const& v, numeral const& b);
|
||||||
|
void add_eq(num_vector const& v, numeral const& b);
|
||||||
|
|
||||||
lbool saturate();
|
lbool saturate();
|
||||||
|
|
||||||
void set_cancel(bool f) { m_cancel = f; }
|
void set_cancel(bool f) { m_cancel = f; }
|
||||||
|
@ -134,28 +137,8 @@ public:
|
||||||
|
|
||||||
void collect_statistics(statistics& st) const;
|
void collect_statistics(statistics& st) const;
|
||||||
void reset_statistics();
|
void reset_statistics();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class hilbert_sl_basis {
|
|
||||||
public:
|
|
||||||
typedef rational numeral;
|
|
||||||
typedef vector<numeral> num_vector;
|
|
||||||
private:
|
|
||||||
hilbert_basis m_basis;
|
|
||||||
public:
|
|
||||||
hilbert_sl_basis() {}
|
|
||||||
void reset() { m_basis.reset(); }
|
|
||||||
|
|
||||||
// add inequality v*x >= bound, x ranges over naturals
|
|
||||||
void add_le(num_vector const& v, numeral bound);
|
|
||||||
lbool saturate() { return m_basis.saturate(); }
|
|
||||||
void set_cancel(bool f) { m_basis.set_cancel(f); }
|
|
||||||
void display(std::ostream& out) const { m_basis.display(out); }
|
|
||||||
|
|
||||||
void collect_statistics(statistics& st) const { m_basis.collect_statistics(st); }
|
|
||||||
void reset_statistics() { m_basis.reset_statistics(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class hilbert_isl_basis {
|
class hilbert_isl_basis {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -50,14 +50,22 @@ void error(const char * msg) {
|
||||||
exit(ERR_CMD_LINE);
|
exit(ERR_CMD_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STRINGIZE(x) #x
|
||||||
|
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
|
||||||
|
|
||||||
void display_usage() {
|
void display_usage() {
|
||||||
std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER << " - ";
|
std::cout << "Z3 [version " << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "." << Z3_BUILD_NUMBER;
|
||||||
|
std::cout << " - ";
|
||||||
#ifdef _AMD64_
|
#ifdef _AMD64_
|
||||||
std::cout << "64";
|
std::cout << "64";
|
||||||
#else
|
#else
|
||||||
std::cout << "32";
|
std::cout << "32";
|
||||||
#endif
|
#endif
|
||||||
std::cout << " bit]. (C) Copyright 2006 Microsoft Corp.\n";
|
std::cout << " bit";
|
||||||
|
#ifdef Z3GITHASH
|
||||||
|
std::cout << " - build hashcode " << STRINGIZE_VALUE_OF(Z3GITHASH);
|
||||||
|
#endif
|
||||||
|
std::cout << "]. (C) Copyright 2006-2013 Microsoft Corp.\n";
|
||||||
std::cout << "Usage: z3 [options] [-file:]file\n";
|
std::cout << "Usage: z3 [options] [-file:]file\n";
|
||||||
std::cout << "\nInput format:\n";
|
std::cout << "\nInput format:\n";
|
||||||
std::cout << " -smt use parser for SMT input format.\n";
|
std::cout << " -smt use parser for SMT input format.\n";
|
||||||
|
|
|
@ -20,6 +20,17 @@ static vector<rational> vec(int i, int j, int k, int l) {
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vector<rational> vec(int i, int j, int k, int l, int m) {
|
||||||
|
vector<rational> nv;
|
||||||
|
nv.resize(5);
|
||||||
|
nv[0] = rational(i);
|
||||||
|
nv[1] = rational(j);
|
||||||
|
nv[2] = rational(k);
|
||||||
|
nv[3] = rational(l);
|
||||||
|
nv[4] = rational(m);
|
||||||
|
return nv;
|
||||||
|
}
|
||||||
|
|
||||||
static vector<rational> vec(int i, int j, int k, int l, int x, int y, int z) {
|
static vector<rational> vec(int i, int j, int k, int l, int x, int y, int z) {
|
||||||
vector<rational> nv;
|
vector<rational> nv;
|
||||||
nv.resize(7);
|
nv.resize(7);
|
||||||
|
@ -33,26 +44,6 @@ static vector<rational> vec(int i, int j, int k, int l, int x, int y, int z) {
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void saturate_basis(hilbert_sl_basis& hb) {
|
|
||||||
lbool is_sat = hb.saturate();
|
|
||||||
|
|
||||||
switch(is_sat) {
|
|
||||||
case l_true:
|
|
||||||
std::cout << "sat\n";
|
|
||||||
hb.display(std::cout);
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
std::cout << "unsat\n";
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
std::cout << "undef\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
statistics st;
|
|
||||||
hb.collect_statistics(st);
|
|
||||||
st.display(std::cout);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void saturate_basis(hilbert_basis& hb) {
|
static void saturate_basis(hilbert_basis& hb) {
|
||||||
lbool is_sat = hb.saturate();
|
lbool is_sat = hb.saturate();
|
||||||
|
@ -113,7 +104,7 @@ static void tst3() {
|
||||||
|
|
||||||
// Sigma_1, table 1, Ajili, Contejean
|
// Sigma_1, table 1, Ajili, Contejean
|
||||||
static void tst4() {
|
static void tst4() {
|
||||||
hilbert_sl_basis hb;
|
hilbert_basis hb;
|
||||||
hb.add_le(vec( 0,-2, 1, 3, 2,-2, 3), R(3));
|
hb.add_le(vec( 0,-2, 1, 3, 2,-2, 3), R(3));
|
||||||
hb.add_le(vec(-1, 7, 0, 1, 3, 5,-4), R(2));
|
hb.add_le(vec(-1, 7, 0, 1, 3, 5,-4), R(2));
|
||||||
hb.add_le(vec( 0,-1, 1,-1,-1, 0, 0), R(2));
|
hb.add_le(vec( 0,-1, 1,-1,-1, 0, 0), R(2));
|
||||||
|
@ -129,7 +120,7 @@ static void tst4() {
|
||||||
|
|
||||||
// Sigma_2 table 1, Ajili, Contejean
|
// Sigma_2 table 1, Ajili, Contejean
|
||||||
static void tst5() {
|
static void tst5() {
|
||||||
hilbert_sl_basis hb;
|
hilbert_basis hb;
|
||||||
hb.add_le(vec( 1, 2,-1, 1), R(3));
|
hb.add_le(vec( 1, 2,-1, 1), R(3));
|
||||||
hb.add_le(vec( 2, 4, 1, 2), R(12));
|
hb.add_le(vec( 2, 4, 1, 2), R(12));
|
||||||
hb.add_le(vec( 1, 4, 2, 1), R(9));
|
hb.add_le(vec( 1, 4, 2, 1), R(9));
|
||||||
|
@ -142,7 +133,7 @@ static void tst5() {
|
||||||
|
|
||||||
// Sigma_3 table 1, Ajili, Contejean
|
// Sigma_3 table 1, Ajili, Contejean
|
||||||
static void tst6() {
|
static void tst6() {
|
||||||
hilbert_sl_basis hb;
|
hilbert_basis hb;
|
||||||
hb.add_le(vec( 4, 3, 0), R(6));
|
hb.add_le(vec( 4, 3, 0), R(6));
|
||||||
hb.add_le(vec(-3,-4, 0), R(-1));
|
hb.add_le(vec(-3,-4, 0), R(-1));
|
||||||
hb.add_le(vec( 4, 0,-3), R(3));
|
hb.add_le(vec( 4, 0,-3), R(3));
|
||||||
|
@ -154,7 +145,7 @@ static void tst6() {
|
||||||
|
|
||||||
// Sigma_4 table 1, Ajili, Contejean
|
// Sigma_4 table 1, Ajili, Contejean
|
||||||
static void tst7() {
|
static void tst7() {
|
||||||
hilbert_sl_basis hb;
|
hilbert_basis hb;
|
||||||
hb.add_le(vec( 2, 1, 0, 1), R(6));
|
hb.add_le(vec( 2, 1, 0, 1), R(6));
|
||||||
hb.add_le(vec( 1, 2, 1, 1), R(7));
|
hb.add_le(vec( 1, 2, 1, 1), R(7));
|
||||||
hb.add_le(vec( 1, 3,-1, 2), R(8));
|
hb.add_le(vec( 1, 3,-1, 2), R(8));
|
||||||
|
@ -164,15 +155,51 @@ static void tst7() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sigma_5 table 1, Ajili, Contejean
|
||||||
|
static void tst8() {
|
||||||
|
hilbert_basis hb;
|
||||||
|
hb.add_le(vec( 2, 1, 1), R(2));
|
||||||
|
hb.add_le(vec( 1, 2, 3), R(5));
|
||||||
|
hb.add_le(vec( 2, 2, 3), R(6));
|
||||||
|
hb.add_le(vec( 1,-1,-3), R(-2));
|
||||||
|
saturate_basis(hb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sigma_6 table 1, Ajili, Contejean
|
||||||
|
static void tst9() {
|
||||||
|
hilbert_basis hb;
|
||||||
|
hb.add_le(vec( 1, 2, 3), R(11));
|
||||||
|
hb.add_le(vec( 2, 2, 5), R(13));
|
||||||
|
hb.add_le(vec( 1,-1,-11), R(3));
|
||||||
|
saturate_basis(hb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sigma_7 table 1, Ajili, Contejean
|
||||||
|
static void tst10() {
|
||||||
|
hilbert_basis hb;
|
||||||
|
hb.add_le(vec( 1,-1,-1,-3), R(2));
|
||||||
|
hb.add_le(vec(-2, 3, 3, 5), R(3));
|
||||||
|
saturate_basis(hb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sigma_8 table 1, Ajili, Contejean
|
||||||
|
static void tst11() {
|
||||||
|
hilbert_basis hb;
|
||||||
|
hb.add_le(vec( 7,-2,11, 3, -5), R(5));
|
||||||
|
saturate_basis(hb);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_hilbert_basis() {
|
void tst_hilbert_basis() {
|
||||||
std::cout << "hilbert basis test\n";
|
std::cout << "hilbert basis test\n";
|
||||||
tst1();
|
tst1();
|
||||||
tst2();
|
tst2();
|
||||||
tst3();
|
tst3();
|
||||||
#if 0
|
|
||||||
tst4();
|
tst4();
|
||||||
tst5();
|
tst5();
|
||||||
tst6();
|
tst6();
|
||||||
tst7();
|
tst7();
|
||||||
#endif
|
tst8();
|
||||||
|
tst9();
|
||||||
|
tst10();
|
||||||
|
tst11();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ void tst_match(ast_manager & m, app * t, app * i) {
|
||||||
s.display(std::cout);
|
s.display(std::cout);
|
||||||
|
|
||||||
// create some dummy term to test for applying the substitution.
|
// create some dummy term to test for applying the substitution.
|
||||||
sort_ref S( m.mk_sort(symbol("S")), m);
|
sort_ref S( m.mk_uninterpreted_sort(symbol("S")), m);
|
||||||
sort * domain[3] = {S, S, S};
|
sort * domain[3] = {S, S, S};
|
||||||
func_decl_ref r( m.mk_func_decl(symbol("r"), 3, domain, S), m);
|
func_decl_ref r( m.mk_func_decl(symbol("r"), 3, domain, S), m);
|
||||||
expr_ref x1( m.mk_var(0, S), m);
|
expr_ref x1( m.mk_var(0, S), m);
|
||||||
|
@ -75,7 +75,7 @@ void tst_match(ast_manager & m, app * t, app * i) {
|
||||||
void tst1() {
|
void tst1() {
|
||||||
ast_manager m;
|
ast_manager m;
|
||||||
reg_decl_plugins(m);
|
reg_decl_plugins(m);
|
||||||
sort_ref s( m.mk_sort(symbol("S")), m);
|
sort_ref s( m.mk_uninterpreted_sort(symbol("S")), m);
|
||||||
func_decl_ref g( m.mk_func_decl(symbol("g"), s, s), m);
|
func_decl_ref g( m.mk_func_decl(symbol("g"), s, s), m);
|
||||||
func_decl_ref h( m.mk_func_decl(symbol("h"), s, s), m);
|
func_decl_ref h( m.mk_func_decl(symbol("h"), s, s), m);
|
||||||
sort * domain[2] = {s, s};
|
sort * domain[2] = {s, s};
|
||||||
|
|
|
@ -62,7 +62,7 @@ void tst_subst(ast_manager& m) {
|
||||||
obj_ref<var, ast_manager> x(m), y(m), z(m), u(m), v(m);
|
obj_ref<var, ast_manager> x(m), y(m), z(m), u(m), v(m);
|
||||||
expr_ref e1(m), e2(m), e3(m);
|
expr_ref e1(m), e2(m), e3(m);
|
||||||
expr_ref t1(m), t2(m), t3(m);
|
expr_ref t1(m), t2(m), t3(m);
|
||||||
s = m.mk_sort(symbol("S"));
|
s = m.mk_uninterpreted_sort(symbol("S"));
|
||||||
sort* ss[2] = { s.get(), s.get() };
|
sort* ss[2] = { s.get(), s.get() };
|
||||||
symbol names[2] = { symbol("y"), symbol("x") };
|
symbol names[2] = { symbol("y"), symbol("x") };
|
||||||
p = m.mk_func_decl(symbol("p"), 2, ss, m.mk_bool_sort());
|
p = m.mk_func_decl(symbol("p"), 2, ss, m.mk_bool_sort());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue