3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 21:03:39 +00:00

remove hassel table from unstable: does not compile under other plantforms

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2013-05-31 17:48:19 -07:00
parent b670f0bb69
commit c0895e5548
21 changed files with 1070 additions and 2935 deletions

View file

@ -1,434 +0,0 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_hassel_common.cpp
Abstract:
<abstract>
Revision History:
--*/
#include "dl_hassel_common.h"
#include "dl_context.h"
#include <vector>
namespace datalog {
static void formula_to_dnf_aux(app *and, unsigned idx, std::set<expr*>& conjexpr, std::set<expr*>& toplevel, ast_manager& m) {
if (idx == and->get_num_args()) {
std::vector<expr*> v(conjexpr.begin(), conjexpr.end());
toplevel.insert(m.mk_and((unsigned)v.size(), &v[0]));
return;
}
expr *e = and->get_arg(idx);
if (is_app(e) && to_app(e)->get_decl_kind() == OP_OR) {
app *or = to_app(e);
// quick subsumption test: if any of the elements of the OR is already ANDed, then we skip this OR
for (unsigned i = 0; i < or->get_num_args(); ++i) {
if (conjexpr.count(or->get_arg(i))) {
formula_to_dnf_aux(and, idx+1, conjexpr, toplevel, m);
return;
}
}
for (unsigned i = 0; i < or->get_num_args(); ++i) {
std::set<expr*> conjexpr2(conjexpr);
conjexpr2.insert(or->get_arg(i));
formula_to_dnf_aux(and, idx+1, conjexpr2, toplevel, m);
}
} else {
conjexpr.insert(e);
formula_to_dnf_aux(and, idx+1, conjexpr, toplevel, m);
}
}
expr_ref formula_to_dnf(expr_ref f) {
app *a = to_app(f);
SASSERT(a->get_decl_kind() == OP_AND);
std::set<expr*> toplevel, conjexpr;
formula_to_dnf_aux(a, 0, conjexpr, toplevel, f.m());
if (toplevel.size() > 1) {
std::vector<expr*> v(toplevel.begin(), toplevel.end());
return expr_ref(f.m().mk_or((unsigned)v.size(), &v[0]), f.m());
} else {
return expr_ref(*toplevel.begin(), f.m());
}
}
bool bit_vector::contains(const bit_vector & other) const {
unsigned n = num_words();
if (n == 0)
return true;
for (unsigned i = 0; i < n - 1; ++i) {
if ((m_data[i] & other.m_data[i]) != other.m_data[i])
return false;
}
unsigned bit_rest = m_num_bits % 32;
unsigned mask = (1 << bit_rest) - 1;
if (mask == 0) mask = UINT_MAX;
unsigned other_data = other.m_data[n-1] & mask;
return (m_data[n-1] & other_data) == other_data;
}
bool bit_vector::contains(const bit_vector & other, unsigned idx) const {
// TODO: optimize this to avoid copy
return slice(idx, other.size()).contains(other);
}
bool bit_vector::contains_consecutive_zeros() const {
unsigned n = num_words();
if (n == 0)
return false;
for (unsigned i = 0; i < n - 1; ++i) {
if ((((m_data[i] << 1) | m_data[i]) & 0xAAAAAAAA) != 0xAAAAAAAA)
return true;
}
unsigned bit_rest = m_num_bits % 32;
unsigned mask = (1 << bit_rest) - 1;
if (mask == 0) mask = UINT_MAX;
mask &= 0xAAAAAAAA;
return ((((m_data[n-1] << 1) | m_data[n-1]) & mask) != mask);
}
bit_vector bit_vector::slice(unsigned idx, unsigned length) const {
bit_vector Res(length);
// TODO: optimize w/ memcpy when possible
for (unsigned i = idx; i < idx + length; ++i) {
Res.push_back(get(i));
}
SASSERT(Res.size() == length);
return Res;
}
void bit_vector::append(const bit_vector & other) {
if (other.empty())
return;
if ((m_num_bits % 32) == 0) {
unsigned prev_num_bits = m_num_bits;
resize(m_num_bits + other.m_num_bits);
memcpy(&get_bit_word(prev_num_bits), other.m_data, other.num_words() * sizeof(unsigned));
return;
}
// TODO: optimize the other cases.
for (unsigned i = 0; i < other.m_num_bits; ++i) {
push_back(other.get(i));
}
}
uint64 bit_vector::to_number(unsigned idx, unsigned length) const {
SASSERT(length <= 64);
uint64 r = 0;
for (unsigned i = 0; i < length; ++i) {
r = (r << 1) | (uint64)get(idx+i);
}
return r;
}
bool bit_vector::operator<(bit_vector const & other) const {
SASSERT(m_num_bits == other.m_num_bits);
unsigned n = num_words();
if (n == 0)
return false;
for (unsigned i = 0; i < n - 1; ++i) {
if (m_data[i] > other.m_data[i])
return false;
if (m_data[i] < other.m_data[i])
return true;
}
unsigned bit_rest = m_num_bits % 32;
unsigned mask = (1 << bit_rest) - 1;
if (mask == 0) mask = UINT_MAX;
return (m_data[n-1] & mask) < (other.m_data[n-1] & mask);
}
table_information::table_information(table_plugin & p, const table_signature& sig) :
m_column_info(sig.size()+1),
m_bv_util(p.get_context().get_manager()),
m_decl_util(p.get_context().get_manager()) {
unsigned column = 0;
for (unsigned i = 0; i < sig.size(); ++i) {
unsigned num_bits = uint64_log2(sig[i]);
SASSERT(num_bits == 64 || (1ULL << num_bits) == sig[i]);
m_column_info[i] = column;
column += num_bits;
}
m_column_info[sig.size()] = column;
}
void table_information::expand_column_vector(unsigned_vector& v, const table_information *other) const {
unsigned_vector orig;
orig.swap(v);
for (unsigned i = 0; i < orig.size(); ++i) {
unsigned col, limit;
if (orig[i] < get_num_cols()) {
col = column_idx(orig[i]);
limit = col + column_num_bits(orig[i]);
} else {
unsigned idx = orig[i] - get_num_cols();
col = get_num_bits() + other->column_idx(idx);
limit = col + other->column_num_bits(idx);
}
for (; col < limit; ++col) {
v.push_back(col);
}
}
}
void table_information::display(std::ostream & out) const {
out << '<';
for (unsigned i = 0; i < get_num_cols(); ++i) {
if (i > 0)
out << ", ";
out << column_num_bits(i);
}
out << ">\n";
}
ternary_bitvector::ternary_bitvector(unsigned size, bool full) :
bit_vector() {
resize(size, full);
}
ternary_bitvector::ternary_bitvector(uint64 n, unsigned num_bits) :
bit_vector(2 * num_bits) {
append_number(n, num_bits);
}
ternary_bitvector::ternary_bitvector(const table_fact& f, const table_information& t) :
bit_vector(2 * t.get_num_bits()) {
for (unsigned i = 0; i < f.size(); ++i) {
SASSERT(t.column_idx(i) == size());
append_number(f[i], t.column_num_bits(i));
}
SASSERT(size() == t.get_num_bits());
}
void ternary_bitvector::fill1() {
memset(m_data, 0xFF, m_capacity * sizeof(unsigned));
}
unsigned ternary_bitvector::get(unsigned idx) const {
idx *= 2;
return (bit_vector::get(idx) << 1) | (unsigned)bit_vector::get(idx+1);
}
void ternary_bitvector::set(unsigned idx, unsigned val) {
SASSERT(val == BIT_0 || val == BIT_1 || val == BIT_x);
idx *= 2;
bit_vector::set(idx, (val >> 1) != 0);
bit_vector::set(idx+1, (val & 1) != 0);
}
void ternary_bitvector::push_back(unsigned val) {
SASSERT(val == BIT_0 || val == BIT_1 || val == BIT_x);
bit_vector::push_back((val >> 1) != 0);
bit_vector::push_back((val & 1) != 0);
}
void ternary_bitvector::append_number(uint64 n, unsigned num_bits) {
SASSERT(num_bits <= 64);
for (int bit = num_bits-1; bit >= 0; --bit) {
if (n & (1ULL << bit)) {
push_back(BIT_1);
} else {
push_back(BIT_0);
}
}
}
void ternary_bitvector::mk_idx_eq(unsigned idx, ternary_bitvector& val) {
for (unsigned i = 0; i < val.size(); ++i) {
set(idx+i, val.get(i));
}
}
ternary_bitvector ternary_bitvector::and(const ternary_bitvector& other) const{
ternary_bitvector result(*this);
result &= other;
return result;
}
void ternary_bitvector::neg(union_ternary_bitvector<ternary_bitvector>& result) const {
ternary_bitvector negated;
negated.resize(size());
for (unsigned i = 0; i < size(); ++i) {
switch (get(i)) {
case BIT_0:
negated.fill1();
negated.set(i, BIT_1);
break;
case BIT_1:
negated.fill1();
negated.set(i, BIT_0);
break;
default:
continue;
}
result.add_fact(negated);
}
}
static void join_fix_eqs(ternary_bitvector& TBV, unsigned idx, unsigned col2_offset,
const unsigned_vector& cols1, const unsigned_vector& cols2,
union_ternary_bitvector<ternary_bitvector>& result) {
if (idx == cols1.size()) {
result.add_fact(TBV);
return;
}
unsigned idx1 = cols1[idx];
unsigned idx2 = cols2[idx] + col2_offset;
unsigned v1 = TBV.get(idx1);
unsigned v2 = TBV.get(idx2);
if (v1 == BIT_x) {
if (v2 == BIT_x) {
// both x: duplicate row
ternary_bitvector TBV2(TBV);
TBV2.set(idx1, BIT_0);
TBV2.set(idx2, BIT_0);
join_fix_eqs(TBV2, idx+1, col2_offset, cols1, cols2, result);
TBV.set(idx1, BIT_1);
TBV.set(idx2, BIT_1);
} else {
TBV.set(idx1, v2);
}
} else if (v2 == BIT_x) {
TBV.set(idx2, v1);
} else if (v1 != v2) {
// columns don't match
return;
}
join_fix_eqs(TBV, idx+1, col2_offset, cols1, cols2, result);
}
void ternary_bitvector::join(const ternary_bitvector& other,
const unsigned_vector& cols1,
const unsigned_vector& cols2,
union_ternary_bitvector<ternary_bitvector>& result) const {
ternary_bitvector TBV(*this);
TBV.append(other);
join_fix_eqs(TBV, 0, size(), cols1, cols2, result);
}
bool ternary_bitvector::project(const unsigned_vector& delcols, ternary_bitvector& result) const {
unsigned *rm_cols = delcols.c_ptr();
for (unsigned i = 0; i < size(); ++i) {
if (*rm_cols == i) {
++rm_cols;
continue;
}
result.push_back(get(i));
}
return true;
}
static void copy_column(ternary_bitvector& CopyTo, const ternary_bitvector& CopyFrom,
unsigned col_dst, unsigned col_src, const table_information& src_table,
const table_information& dst_table) {
unsigned idx_dst = dst_table.column_idx(col_dst);
unsigned idx_src = src_table.column_idx(col_src);
unsigned num_bits = dst_table.column_num_bits(col_dst);
SASSERT(num_bits == src_table.column_num_bits(col_src));
for (unsigned i = 0; i < num_bits; ++i) {
CopyTo.set(idx_dst+i, CopyFrom.get(idx_src+i));
}
}
void ternary_bitvector::rename(const unsigned_vector& cyclecols,
const unsigned_vector& out_of_cycle_cols,
const table_information& src_table,
const table_information& dst_table,
ternary_bitvector& result) const {
result.resize(dst_table.get_num_bits());
for (unsigned i = 1; i < cyclecols.size(); ++i) {
copy_column(result, *this, cyclecols[i-1], cyclecols[i], src_table, dst_table);
}
copy_column(result, *this, cyclecols[cyclecols.size()-1], cyclecols[0], src_table, dst_table);
for (unsigned i = 0; i < out_of_cycle_cols.size(); ++i) {
unsigned col = out_of_cycle_cols[i];
copy_column(result, *this, col, col, src_table, dst_table);
}
}
unsigned ternary_bitvector::size_in_bytes() const {
return sizeof(*this) + m_capacity;
}
void ternary_bitvector::display(std::ostream & out) const {
for (unsigned i = 0; i < size(); ++i) {
switch (get(i)) {
case BIT_0:
out << '0';
break;
case BIT_1:
out << '1';
break;
case BIT_x:
out << 'x';
break;
default:
UNREACHABLE();
}
}
}
#if Z3DEBUG
void ternary_bitvector::expand(std::set<bit_vector> & BVs) const {
bit_vector BV(m_num_bits);
expand(BVs, BV, 0);
}
void ternary_bitvector::expand(std::set<bit_vector> & BVs, bit_vector &BV, unsigned idx) const {
if (idx == size()) {
BVs.insert(BV);
return;
}
switch (get(idx)) {
case BIT_0:
BV.push_back(false);
expand(BVs, BV, idx+1);
break;
case BIT_1:
BV.push_back(true);
expand(BVs, BV, idx+1);
break;
case BIT_x: { // x: duplicate
bit_vector BV2(BV);
BV.push_back(false);
BV2.push_back(true);
expand(BVs, BV, idx+1);
expand(BVs, BV2, idx+1);
}
break;
default:
UNREACHABLE();
}
}
#endif
}

File diff suppressed because it is too large Load diff

View file

@ -1,219 +0,0 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_hassel_diff_table.cpp
Abstract:
<abstract>
Revision History:
--*/
#include "ast_printer.h"
#include "dl_context.h"
#include "dl_util.h"
#include "dl_hassel_diff_table.h"
namespace datalog {
ternary_diff_bitvector::ternary_diff_bitvector(unsigned size, bool full) :
m_pos(size, full), m_neg(size) { }
ternary_diff_bitvector::ternary_diff_bitvector(uint64 n, unsigned num_bits) :
m_pos(n, num_bits), m_neg(num_bits) { }
ternary_diff_bitvector::ternary_diff_bitvector(const ternary_bitvector & tbv) :
m_pos(tbv), m_neg(tbv.size()) { }
bool ternary_diff_bitvector::contains(const ternary_diff_bitvector & other) const {
return m_pos.contains(other.m_pos) && other.m_neg.contains(m_neg);
}
bool ternary_diff_bitvector::is_empty() const {
if (m_pos.is_empty())
return true;
return m_neg.contains(m_pos);
}
ternary_diff_bitvector ternary_diff_bitvector::and(const ternary_diff_bitvector& other) const {
ternary_diff_bitvector result(m_pos.and(other.m_pos));
result.m_neg.swap(m_neg.or(other.m_neg));
return result;
}
void ternary_diff_bitvector::neg(union_ternary_bitvector<ternary_diff_bitvector>& result) const {
// not(A\B) <-> (T\A) U B
ternary_diff_bitvector negated(size(), true);
negated.m_neg.add_new_fact(m_pos);
result.add_fact(negated);
for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
E = m_neg.end(); I != E; ++I) {
result.add_fact(*I);
}
}
void ternary_diff_bitvector::subtract(const union_ternary_bitvector<ternary_diff_bitvector>& other,
union_ternary_bitvector<ternary_diff_bitvector>& result) const {
ternary_diff_bitvector newfact(*this);
for (union_ternary_bitvector<ternary_diff_bitvector>::const_iterator I = other.begin(),
E = other.end(); I != E; ++I) {
if (!I->m_neg.empty()) {
NOT_IMPLEMENTED_YET();
}
newfact.m_neg.add_fact(I->m_pos);
}
if (!newfact.is_empty())
result.add_fact(newfact);
}
void ternary_diff_bitvector::join(const ternary_diff_bitvector& other,
const unsigned_vector& cols1,
const unsigned_vector& cols2,
union_ternary_bitvector<ternary_diff_bitvector>& result) const {
unsigned new_size = size() + other.size();
ternary_diff_bitvector res(new_size);
res.m_pos = m_pos;
res.m_pos.append(other.m_pos);
for (unsigned i = 0; i < cols1.size(); ++i) {
unsigned idx1 = cols1[i];
unsigned idx2 = size() + cols2[i];
unsigned v1 = res.m_pos.get(idx1);
unsigned v2 = res.m_pos.get(idx2);
if (v1 == BIT_x) {
if (v2 == BIT_x) {
// add to subtracted TBVs: 1xx0 and 0xx1
{
ternary_bitvector r(new_size, true);
r.set(idx1, BIT_0);
r.set(idx2, BIT_1);
res.m_neg.add_new_fact(r);
}
{
ternary_bitvector r(new_size, true);
r.set(idx1, BIT_1);
r.set(idx2, BIT_0);
res.m_neg.add_new_fact(r);
}
} else {
res.m_pos.set(idx1, v2);
}
} else if (v2 == BIT_x) {
res.m_pos.set(idx2, v1);
} else if (v1 != v2) {
// columns don't match
return;
}
}
// handle subtracted TBVs: 1010 -> 1010xxx
if (!m_neg.empty()) {
ternary_bitvector padding(other.size(), true);
for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
E = m_neg.end(); I != E; ++I) {
ternary_bitvector BV(*I);
BV.append(padding);
res.m_neg.add_new_fact(BV);
}
}
if (!other.m_neg.empty()) {
ternary_bitvector padding(size(), true);
for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = other.m_neg.begin(),
E = other.m_neg.end(); I != E; ++I) {
ternary_bitvector BV(padding);
BV.append(*I);
res.m_neg.add_new_fact(BV);
}
}
result.add_fact(res);
}
bool ternary_diff_bitvector::project(const unsigned_vector& delcols, ternary_diff_bitvector& result) const {
m_pos.project(delcols, result.m_pos);
if (m_neg.empty())
return true;
ternary_bitvector newneg;
for (union_ternary_bitvector<ternary_bitvector>::const_iterator I = m_neg.begin(),
E = m_neg.end(); I != E; ++I) {
for (unsigned i = 0; i < delcols.size()-1; ++i) {
unsigned idx = delcols[i];
if (I->get(idx) != BIT_x && m_pos.get(idx) == BIT_x)
goto skip_row;
}
newneg.reset();
I->project(delcols, newneg);
result.m_neg.add_fact(newneg);
skip_row: ;
}
return !result.is_empty();
}
void ternary_diff_bitvector::rename(const unsigned_vector& cyclecols,
const unsigned_vector& out_of_cycle_cols,
const table_information& src_table,
const table_information& dst_table,
ternary_diff_bitvector& result) const {
m_pos.rename(cyclecols, out_of_cycle_cols, src_table, dst_table, result.m_pos);
m_neg.rename(cyclecols, out_of_cycle_cols, src_table, dst_table, result.m_neg);
}
unsigned ternary_diff_bitvector::get(unsigned idx) {
return m_pos.get(idx);
}
void ternary_diff_bitvector::set(unsigned idx, unsigned val) {
m_pos.set(idx, val);
}
void ternary_diff_bitvector::swap(ternary_diff_bitvector & other) {
m_pos.swap(other.m_pos);
m_neg.swap(other.m_neg);
}
void ternary_diff_bitvector::reset() {
m_pos.reset();
m_neg.reset();
}
void ternary_diff_bitvector::display(std::ostream & out) const {
m_pos.display(out);
if (!m_neg.empty()) {
out << " \\ ";
if (m_neg.num_disjs() > 1) out << '(';
m_neg.display(out);
if (m_neg.num_disjs() > 1) out << ')';
}
}
unsigned ternary_diff_bitvector::size_in_bytes() const {
return m_pos.size_in_bytes() + m_neg.num_bytes();
}
#if Z3DEBUG
void ternary_diff_bitvector::expand(std::set<bit_vector> & BVs) const {
m_pos.expand(BVs);
SASSERT(!BVs.empty());
std::set<bit_vector> NegBVs;
m_neg.expand(NegBVs);
BVs.erase(NegBVs.begin(), NegBVs.end());
}
#endif
hassel_diff_table_plugin::hassel_diff_table_plugin(relation_manager & manager)
: common_hassel_table_plugin(symbol("hassel_diff"), manager) {}
}

View file

@ -1,87 +0,0 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_hassel_diff_table.h
Abstract:
<abstract>
Revision History:
--*/
#ifndef _DL_HASSEL_DIFF_TABLE_H_
#define _DL_HASSEL_DIFF_TABLE_H_
#include "dl_hassel_common.h"
namespace datalog {
class hassel_diff_table;
class ternary_diff_bitvector {
// pos \ (neg0 \/ ... \/ negn)
ternary_bitvector m_pos;
union_ternary_bitvector<ternary_bitvector> m_neg;
public:
ternary_diff_bitvector() : m_pos(), m_neg(0) {}
ternary_diff_bitvector(unsigned size) : m_pos(size), m_neg(size) {}
ternary_diff_bitvector(unsigned size, bool full);
ternary_diff_bitvector(uint64 n, unsigned num_bits);
ternary_diff_bitvector(const ternary_bitvector & tbv);
bool contains(const ternary_diff_bitvector & other) const;
bool is_empty() const;
ternary_diff_bitvector and(const ternary_diff_bitvector& other) const;
void neg(union_ternary_bitvector<ternary_diff_bitvector>& result) const;
static bool has_subtract() { return true; }
void subtract(const union_ternary_bitvector<ternary_diff_bitvector>& other,
union_ternary_bitvector<ternary_diff_bitvector>& result) const;
void join(const ternary_diff_bitvector& other, const unsigned_vector& cols1,
const unsigned_vector& cols2, union_ternary_bitvector<ternary_diff_bitvector>& result) const;
bool project(const unsigned_vector& delcols, ternary_diff_bitvector& result) const;
void rename(const unsigned_vector& cyclecols, const unsigned_vector& out_of_cycle_cols,
const table_information& src_table, const table_information& dst_table,
ternary_diff_bitvector& result) const;
unsigned get(unsigned idx);
void set(unsigned idx, unsigned val);
void swap(ternary_diff_bitvector & other);
void reset();
unsigned size() const { return m_pos.size(); }
void display(std::ostream & out) const;
unsigned size_in_bytes() const;
#if Z3DEBUG
void expand(std::set<bit_vector> & BVs) const;
#endif
};
typedef union_ternary_bitvector<ternary_diff_bitvector> union_ternary_diff_bitvector;
class hassel_diff_table : public common_hassel_table<union_ternary_diff_bitvector> {
public:
hassel_diff_table(table_plugin & p, const table_signature & sig) :
common_hassel_table(p, sig) {}
};
class hassel_diff_table_plugin : public common_hassel_table_plugin<hassel_diff_table> {
public:
hassel_diff_table_plugin(relation_manager & manager);
};
}
#endif

View file

@ -1,27 +0,0 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_hassel_table.cpp
Abstract:
<abstract>
Revision History:
--*/
#include "ast_printer.h"
#include "dl_context.h"
#include "dl_util.h"
#include "dl_hassel_table.h"
namespace datalog {
hassel_table_plugin::hassel_table_plugin(relation_manager & manager)
: common_hassel_table_plugin(symbol("hassel"), manager) {}
}

View file

@ -1,39 +0,0 @@
/*++
Copyright (c) 2013 Microsoft Corporation
Module Name:
dl_hassel_table.h
Abstract:
<abstract>
Revision History:
--*/
#ifndef _DL_HASSEL_TABLE_H_
#define _DL_HASSEL_TABLE_H_
#include "dl_hassel_common.h"
namespace datalog {
class hassel_table;
typedef union_ternary_bitvector<ternary_bitvector> union_ternary_bitvectors;
class hassel_table : public common_hassel_table<union_ternary_bitvectors> {
public:
hassel_table(table_plugin & p, const table_signature & sig) :
common_hassel_table(p, sig) {}
};
class hassel_table_plugin : public common_hassel_table_plugin<hassel_table> {
public:
hassel_table_plugin(relation_manager & manager);
};
}
#endif

View file

@ -1561,15 +1561,16 @@ namespace pdr {
m_fparams.m_arith_auto_config_simplex = true;
m_fparams.m_arith_propagate_eqs = false;
m_fparams.m_arith_eager_eq_axioms = false;
if (classify.is_utvpi() && m_params.use_utvpi()) {
if (classify.is_dl()) {
m_fparams.m_arith_mode = AS_DIFF_LOGIC;
m_fparams.m_arith_expand_eqs = true;
}
else if (classify.is_utvpi() && m_params.use_utvpi()) {
IF_VERBOSE(1, verbose_stream() << "UTVPI\n";);
m_fparams.m_arith_mode = AS_UTVPI;
m_fparams.m_arith_expand_eqs = true;
}
else if (classify.is_dl()) {
m_fparams.m_arith_mode = AS_DIFF_LOGIC;
m_fparams.m_arith_expand_eqs = true;
}
}
if (!use_mc && m_params.use_inductive_generalizer()) {
m_core_generalizers.push_back(alloc(core_bool_inductive_generalizer, *this, 0));

View file

@ -19,7 +19,6 @@ Revision History:
--*/
#define Z3_HASSEL_TABLE
#include"rel_context.h"
#include"dl_context.h"
@ -33,10 +32,6 @@ Revision History:
#include"dl_mk_karr_invariants.h"
#include"dl_finite_product_relation.h"
#include"dl_sparse_table.h"
#ifdef Z3_HASSEL_TABLE
# include"dl_hassel_table.h"
# include"dl_hassel_diff_table.h"
#endif
#include"dl_table.h"
#include"dl_table_relation.h"
#include"aig_exporter.h"
@ -94,10 +89,6 @@ namespace datalog {
get_rmanager().register_plugin(alloc(bitvector_table_plugin, get_rmanager()));
get_rmanager().register_plugin(alloc(equivalence_table_plugin, get_rmanager()));
#ifdef Z3_HASSEL_TABLE
get_rmanager().register_plugin(alloc(hassel_table_plugin, get_rmanager()));
get_rmanager().register_plugin(alloc(hassel_diff_table_plugin, get_rmanager()));
#endif
// register plugins for builtin relations

View file

@ -418,9 +418,6 @@ namespace smt {
return FC_GIVEUP;
}
else {
m_graph.set_to_zero(to_var(m_zero_int), to_var(m_zero_real));
m_graph.set_to_zero(neg(to_var(m_zero_int)), neg(to_var(m_zero_real)));
m_graph.set_to_zero(to_var(m_zero_int), neg(to_var(m_zero_int)));
return FC_DONE;
}
}
@ -691,12 +688,29 @@ namespace smt {
\brief adjust values for variables in the difference graph
such that for variables of integer sort it is
the case that x^+ - x^- is even.
The informal justification for the procedure enforce_parity is that
the graph does not contain a strongly connected component where
The informal justification for the procedure enforce_parity relies
on a set of properties:
1. the graph does not contain a strongly connected component where
x^+ and x+- are connected. They can be independently changed.
Since we would like variables representing 0 (zero) map to 0,
we selectively update the subgraph that can be updated without
changing the value of zero (which should be 0).
This is checked prior to enforce_parity.
2. When x^+ - x^- is odd, the values are adjusted by first
decrementing the value of x^+, provided x^- is not 0-dependent.
Otherwise decrement x^-.
x^- is "0-dependent" if there is a set of tight
inequalities from x^+ to x^-.
3. The affinity to x^+ (the same component of x^+) ensures that
the parity is broken only a finite number of times when
traversing that component. Namely, suppose that the parity of y
gets broken when fixing 'x'. Then first note that 'y' cannot
be equal to 'x'. If it were, then we have a state where:
parity(x^+) != parity(x^-) and
parity(y^+) == parity(y^-)
but x^+ and y^+ are tightly connected and x^- and y^- are
also tightly connected using two copies of the same inequalities.
This is a contradiction.
Thus, 'y' cannot be equal to 'x' if 'y's parity gets broken when
repairing 'x'.
*/
template<typename Ext>
void theory_utvpi<Ext>::enforce_parity() {
@ -712,6 +726,8 @@ namespace smt {
if (todo.empty()) {
return;
}
IF_VERBOSE(2, verbose_stream() << "disparity: " << todo.size() << "\n";);
unsigned iter = 0;
while (!todo.empty()) {
unsigned i = todo.back();
todo.pop_back();
@ -720,21 +736,17 @@ namespace smt {
}
th_var v1 = to_var(i);
th_var v2 = neg(v1);
TRACE("utvpi", tout << "disparity: " << v1 << "\n";);
// IF_VERBOSE(1, verbose_stream() << "disparity: " << v1 << "\n";);
int_vector zero_v;
m_graph.compute_zero_succ(v1, zero_v);
bool found0 = false;
for (unsigned j = 0; !found0 && j < zero_v.size(); ++j) {
found0 =
(to_var(m_zero_int) == zero_v[j]) ||
(neg(to_var(m_zero_int)) == zero_v[j]);
}
// variables that are tightly connected
// to 0 should not have their values changed.
if (found0) {
for (unsigned j = 0; j < zero_v.size(); ++j) {
if (zero_v[j] == v2) {
zero_v.reset();
m_graph.compute_zero_succ(v2, zero_v);
}
}
TRACE("utvpi",
for (unsigned j = 0; j < zero_v.size(); ++j) {
tout << "decrement: " << zero_v[j] << "\n";
@ -745,10 +757,23 @@ namespace smt {
m_graph.acc_assignment(v, numeral(-1));
th_var k = from_var(v);
if (!is_parity_ok(k)) {
TRACE("utvpi", tout << "new disparity: " << k << "\n";);
// IF_VERBOSE(1, verbose_stream() << "new disparity: " << k << "\n";);
todo.push_back(k);
}
}
if (iter >= 10000) {
IF_VERBOSE(1,
verbose_stream() << "decrement: ";
for (unsigned j = 0; j < zero_v.size(); ++j) {
rational r = m_graph.get_assignment(zero_v[j]).get_rational();
verbose_stream() << zero_v[j] << " (" << r << ") ";
}
verbose_stream() << "\n";);
if (!is_parity_ok(i)) {
IF_VERBOSE(1, verbose_stream() << "Parity not fixed\n";);
}
}
++iter;
}
SASSERT(m_graph.is_feasible());
DEBUG_CODE(
@ -768,6 +793,9 @@ namespace smt {
m_factory = alloc(arith_factory, get_manager());
m.register_factory(m_factory);
enforce_parity();
m_graph.set_to_zero(to_var(m_zero_int), to_var(m_zero_real));
m_graph.set_to_zero(neg(to_var(m_zero_int)), neg(to_var(m_zero_real)));
m_graph.set_to_zero(to_var(m_zero_int), neg(to_var(m_zero_int)));
compute_delta();
DEBUG_CODE(validate_model(););
}