3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 02:15:19 +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

@ -399,4 +399,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>

View file

@ -1,23 +1,23 @@
This directory contains scripts to build the test application using
OCaml. You also need CamlIDL to be able to generate the OCaml API.
- To download OCaml:
http://caml.inria.fr/ocaml/
- To download CamlIDL:
http://forge.ocamlcore.org/projects/camlidl/
- One must build the OCaml library before compiling the example.
Go to directory ../ocaml
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
Remark: The OCaml and C compiler tool chains must be configured in your environment.
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
- The script 'exec.cmd' adds the bin directory to the path. So,
test_mlapi.exe can find z3.dll.
This directory contains scripts to build the test application using
OCaml. You also need CamlIDL to be able to generate the OCaml API.
- To download OCaml:
http://caml.inria.fr/ocaml/
- To download CamlIDL:
http://forge.ocamlcore.org/projects/camlidl/
- One must build the OCaml library before compiling the example.
Go to directory ../ocaml
- Use 'build-test.cmd' to build the test application using the OCaml compiler.
Remark: The OCaml and C compiler tool chains must be configured in your environment.
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
- The script 'exec.cmd' adds the bin directory to the path. So,
test_mlapi.exe can find z3.dll.

View file

@ -1,23 +1,23 @@
The OCaml API for Z3 was tested using OCaml 3.12.1.
You also need CamlIDL to be able to generate the OCaml API.
- To download OCaml:
http://caml.inria.fr/ocaml/
- To download CamlIDL:
http://forge.ocamlcore.org/projects/camlidl/
- To build the OCaml API for Z3:
.\build-lib.cmd
Remark: The OCaml and C compiler tool chains must be configured in your environment.
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
Remark: Building the OCaml API copies some pathnames into files,
so the OCaml API must be recompiled if the Z3 library files are moved.
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
Acknowledgements:
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg.
Many thanks to them!
The OCaml API for Z3 was tested using OCaml 3.12.1.
You also need CamlIDL to be able to generate the OCaml API.
- To download OCaml:
http://caml.inria.fr/ocaml/
- To download CamlIDL:
http://forge.ocamlcore.org/projects/camlidl/
- To build the OCaml API for Z3:
.\build-lib.cmd
Remark: The OCaml and C compiler tool chains must be configured in your environment.
Running from the Visual Studio Command Prompt configures the Microsoft C compiler.
Remark: Building the OCaml API copies some pathnames into files,
so the OCaml API must be recompiled if the Z3 library files are moved.
See ..\examples\ocaml\build-test.cmd for an example of how to compile and link with Z3.
Acknowledgements:
The OCaml interface for Z3 was written by Josh Berdine and Jakob Lichtenberg.
Many thanks to them!

View file

@ -1,3 +1,3 @@
@echo off
call .\compile_mlapi.cmd ..\include ..\bin ..\bin
@echo off
call .\compile_mlapi.cmd ..\include ..\bin ..\bin

View file

@ -1,19 +1,19 @@
@echo off
if not exist ..\..\ocaml\z3.cmxa (
echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
goto :EOF
)
REM ocaml (>= 3.11) calls the linker through flexlink
ocamlc -version >> ocaml_version
set /p OCAML_VERSION= <ocaml_version
if %OCAML_VERSION% GEQ 3.11 (
set XCFLAGS=
) else (
set XCFLAGS=/nologo /MT /DWIN32
)
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml
@echo off
if not exist ..\..\ocaml\z3.cmxa (
echo "YOU MUST BUILD OCAML API! Go to directory ..\ocaml"
goto :EOF
)
REM ocaml (>= 3.11) calls the linker through flexlink
ocamlc -version >> ocaml_version
set /p OCAML_VERSION= <ocaml_version
if %OCAML_VERSION% GEQ 3.11 (
set XCFLAGS=
) else (
set XCFLAGS=/nologo /MT /DWIN32
)
ocamlc -w A -ccopt "%XCFLAGS%" -o test_mlapi_byte.exe -I ..\..\ocaml z3.cma test_mlapi.ml
ocamlopt -w A -ccopt "%XCFLAGS%" -o test_mlapi.exe -I ..\..\ocaml z3.cmxa test_mlapi.ml

View file

@ -1,5 +1,5 @@
@echo off
SETLOCAL
set PATH=..\..\bin;%PATH%
test_mlapi.exe
ENDLOCAL
@echo off
SETLOCAL
set PATH=..\..\bin;%PATH%
test_mlapi.exe
ENDLOCAL

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
Command context provides the infrastructure for executing commands in front-ends such as SMT-LIB 2.0.
It is also provides the solver abstraction to plugin solvers in this kind of front-end.
It is also provides the solver abstraction to plugin solvers in this kind of front-end.

View file

@ -1,2 +1,2 @@
Basic Euclidean solver for linear integer equations.
This solver generates "explanations".
This solver generates "explanations".

View file

@ -1,2 +1,2 @@
Template for interval arithmetic. The template can be instantiated using different numeral (integers/mpz, rationals/mpq, floating-point/mpf, etc) packages.
The class im_default_config defines a default configuration for the template that uses rationals. It also shows what is the expected signature used by the template.
The class im_default_config defines a default configuration for the template that uses rationals. It also shows what is the expected signature used by the template.

View file

@ -1,3 +1,3 @@
Polynomial manipulation package.
It contains support for univariate (upolynomial.*) and multivariate polynomials (polynomial.*).
Multivariate polynomial factorization does not work yet (polynomial_factorization.*), and it is disabled.
Multivariate polynomial factorization does not work yet (polynomial_factorization.*), and it is disabled.

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

@ -311,4 +311,4 @@
(= (?is (?select (?select (?asElems e) a) i)
(?elemtype (?typeof a))) 1)
:pats { (?select (?select (?asElems e) a) i) })
)
)

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,16 +688,33 @@ 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
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).
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.
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() {
unsigned_vector todo;
unsigned_vector todo;
unsigned sz = get_num_vars();
for (unsigned i = 0; i < sz; ++i) {
@ -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) {
zero_v.reset();
m_graph.compute_zero_succ(v2, zero_v);
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(
@ -764,10 +789,13 @@ namespace smt {
// models:
template<typename Ext>
void theory_utvpi<Ext>::init_model(model_generator & m) {
void theory_utvpi<Ext>::init_model(model_generator & m) {
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(););
}