mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
Reorganizing the code
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
492484c5aa
commit
aa949693d4
13 changed files with 0 additions and 78 deletions
208
src/dead/array_property_expander.cpp
Normal file
208
src/dead/array_property_expander.cpp
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_expander.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Expand array operations for the array property fragment formulas.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"array_property_expander.h"
|
||||
#include"obj_hashtable.h"
|
||||
#include"var_subst.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
array_property_expander::array_property_expander(ast_manager& m):
|
||||
m_manager(m) {
|
||||
}
|
||||
|
||||
namespace array_property_exp {
|
||||
class proc {
|
||||
ast_manager& m_manager;
|
||||
unsigned& m_offset;
|
||||
expr_ref_vector m_trail;
|
||||
family_id m_fid;
|
||||
array_util m_util;
|
||||
obj_map<expr, expr*> m_mem;
|
||||
|
||||
|
||||
void insert(expr* a, expr* b) {
|
||||
m_trail.push_back(b);
|
||||
m_mem.insert(a, b);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
proc(ast_manager& m, unsigned& offset) :
|
||||
m_manager(m),
|
||||
m_offset(offset),
|
||||
m_trail(m),
|
||||
m_fid(m.get_family_id("array")),
|
||||
m_util(m)
|
||||
{}
|
||||
|
||||
expr* find(expr* e) {
|
||||
expr* result = 0;
|
||||
VERIFY(m_mem.find(e, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void operator()(var* n) { insert(n, n); }
|
||||
|
||||
void operator()(quantifier* q) {
|
||||
expr* e = find(q->get_expr());
|
||||
quantifier* q2 = m_manager.update_quantifier(q, e);
|
||||
insert(q, q2);
|
||||
}
|
||||
|
||||
void operator()(app* n) {
|
||||
ast_manager& m = m_manager;
|
||||
unsigned num_args = n->get_num_args();
|
||||
ptr_buffer<expr> args;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
args.push_back(find(n->get_arg(i)));
|
||||
}
|
||||
if (m_manager.is_eq(n) && m_util.is_array(args[0])) {
|
||||
visit_eq(n);
|
||||
return;
|
||||
}
|
||||
if (m_manager.is_distinct(n) && num_args > 0 && m_util.is_array(args[0])) {
|
||||
ptr_buffer<expr> eqs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
for (unsigned j = i + 1; j < num_args; ++j) {
|
||||
eqs.push_back(m.mk_not(m.mk_eq(args[i], args[j])));
|
||||
}
|
||||
}
|
||||
insert(n, m.mk_and(eqs.size(), eqs.c_ptr()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_util.is_select(n)) {
|
||||
SASSERT(num_args > 0);
|
||||
|
||||
// select(store(A,i,v),j) -> ite(i = j, v, select(A,j))
|
||||
if (m_util.is_store(args[0])) {
|
||||
app* a = to_app(args[0]);
|
||||
expr* b = find(a->get_arg(0));
|
||||
expr* v = find(a->get_arg(a->get_num_args()-1));
|
||||
ptr_buffer<expr> eqs;
|
||||
SASSERT(num_args + 1 == a->get_num_args());
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
eqs.push_back(m.mk_eq(args[i], find(a->get_arg(i))));
|
||||
}
|
||||
expr* r = m.mk_ite(m.mk_and(eqs.size(), eqs.c_ptr()), v, mk_select(b, num_args-1, args.c_ptr()+1));
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(ite(a,b,c),i) -> ite(a, select(b,i), select(c, i))
|
||||
if (m.is_ite(args[0])) {
|
||||
app* k = to_app(args[0]);
|
||||
expr* a = k->get_arg(0);
|
||||
expr* b = mk_select(k->get_arg(1), args.size()-1, args.c_ptr()+1);
|
||||
expr* c = mk_select(k->get_arg(2), args.size()-1, args.c_ptr()+1);
|
||||
expr* r = m.mk_ite(a, b, c);
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(map_f(A,B),i) -> f(select(A,i), select(B,i))
|
||||
if (m_util.is_map(args[0])) {
|
||||
app* a = to_app(args[0]);
|
||||
func_decl* f = a->get_decl();
|
||||
SASSERT(f->get_num_parameters() == 1);
|
||||
SASSERT(f->get_parameter(0).is_ast());
|
||||
SASSERT(is_func_decl(f->get_parameter(0).get_ast()));
|
||||
parameter p = f->get_parameter(0);
|
||||
func_decl* d = to_func_decl(p.get_ast());
|
||||
ptr_buffer<expr> args2;
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
args2.push_back(mk_select(find(a->get_arg(i)), args.size()-1, args.c_ptr()+1));
|
||||
}
|
||||
expr* r = m.mk_app(d, args2.size(), args2.c_ptr());
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(const v, i) -> v
|
||||
if (m_util.is_const(args[0])) {
|
||||
insert(n, to_app(args[0])->get_arg(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
expr* r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr());
|
||||
insert(n, r);
|
||||
}
|
||||
|
||||
private:
|
||||
void visit_eq(app* eq) {
|
||||
ast_manager& m = m_manager;
|
||||
SASSERT(m.is_eq(eq));
|
||||
sort* s = m.get_sort(eq->get_arg(0));
|
||||
SASSERT(is_sort_of(s, m_fid, ARRAY_SORT));
|
||||
// sort* rng = get_array_range(s);
|
||||
unsigned arity = get_array_arity(s);
|
||||
shift_vars sh(m);
|
||||
expr_ref e1(m), e2(m);
|
||||
sh(find(eq->get_arg(0)), arity, e1);
|
||||
sh(find(eq->get_arg(1)), arity, e2);
|
||||
expr_ref_vector args(m);
|
||||
buffer<symbol> names;
|
||||
ptr_buffer<sort> sorts;
|
||||
args.push_back(e1);
|
||||
for (unsigned i = 0; i < arity; ++i) {
|
||||
args.push_back(m.mk_var(i, get_array_domain(s, i)));
|
||||
sorts.push_back(get_array_domain(s, arity - i - 1));
|
||||
names.push_back(symbol(m_offset++));
|
||||
}
|
||||
e1 = mk_select(args.size(), args.c_ptr());
|
||||
args[0] = e2;
|
||||
e2 = mk_select(args.size(), args.c_ptr());
|
||||
e1 = m.mk_eq(e1, e2);
|
||||
|
||||
e1 = m.mk_quantifier(true, arity, sorts.c_ptr(), names.c_ptr(), e1, 1);
|
||||
insert(eq, e1);
|
||||
}
|
||||
|
||||
app* mk_select(unsigned n, expr* const* args) {
|
||||
return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, n, args);
|
||||
}
|
||||
|
||||
app* mk_select(expr* a, unsigned n, expr* const* args) {
|
||||
ptr_buffer<expr> args2;
|
||||
args2.push_back(a);
|
||||
args2.append(n, args);
|
||||
return mk_select(n+1, args2.c_ptr());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void array_property_expander::operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result) {
|
||||
ast_manager& m = m_manager;
|
||||
unsigned offset = 0;
|
||||
for (unsigned i = 0; i < num_fmls; ++i) {
|
||||
bool change = false;
|
||||
expr_ref e(m);
|
||||
result.push_back(fmls[i]);
|
||||
do {
|
||||
array_property_exp::proc p(m, offset);
|
||||
e = result[i].get();
|
||||
for_each_expr(p, e);
|
||||
result[i] = p.find(e);
|
||||
change = e != result[i].get();
|
||||
}
|
||||
while (change);
|
||||
}
|
||||
}
|
||||
|
33
src/dead/array_property_expander.h
Normal file
33
src/dead/array_property_expander.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_expander.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Expand array operations for the array property fragment formulas.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARRAY_PROPERTY_EXPANDER_H_
|
||||
#define _ARRAY_PROPERTY_EXPANDER_H_
|
||||
|
||||
#include"ast.h"
|
||||
|
||||
class array_property_expander {
|
||||
ast_manager& m_manager;
|
||||
public:
|
||||
array_property_expander(ast_manager& m);
|
||||
void operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ARRAY_PROPERTY_EXPANDER_H_ */
|
||||
|
103
src/dead/array_property_recognizer.cpp
Normal file
103
src/dead/array_property_recognizer.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_recognizer.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"array_decl_plugin.h"
|
||||
#include"array_property_recognizer.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
|
||||
array_property_recognizer::array_property_recognizer(ast_manager& m):
|
||||
m_manager(m) {}
|
||||
|
||||
namespace is_array_property_ns {
|
||||
struct bad {};
|
||||
class proc {
|
||||
ast_manager& m_manager;
|
||||
family_id m_fid;
|
||||
bool m_has_quantifier;
|
||||
|
||||
void check_array_sort(expr* n) {
|
||||
if (is_sort_of(m_manager.get_sort(n), m_fid, ARRAY_SORT)) {
|
||||
throw bad();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
proc(ast_manager& m) :
|
||||
m_manager(m),
|
||||
m_fid(m.get_family_id("array")),
|
||||
m_has_quantifier(false) {}
|
||||
|
||||
bool has_quantifier() const { return m_has_quantifier; }
|
||||
|
||||
void operator()(var* n) {
|
||||
check_array_sort(n);
|
||||
}
|
||||
|
||||
void operator()(quantifier * ) {
|
||||
m_has_quantifier = true;
|
||||
}
|
||||
|
||||
void operator()(app* n) {
|
||||
unsigned num_args = n->get_num_args();
|
||||
if (m_manager.is_eq(n) || m_manager.is_distinct(n)) {
|
||||
return;
|
||||
}
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m_fid) {
|
||||
switch(n->get_decl_kind()) {
|
||||
case OP_STORE:
|
||||
for (unsigned i = 1; i + 1 < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
return;
|
||||
case OP_SELECT:
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
return;
|
||||
case OP_CONST_ARRAY:
|
||||
case OP_ARRAY_MAP:
|
||||
return;
|
||||
default:
|
||||
throw bad();
|
||||
}
|
||||
}
|
||||
// arrays cannot be arguments of other functions.
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
bool array_property_recognizer::operator()(unsigned num_fmls, expr* const* fmls) {
|
||||
is_array_property_ns::proc p(m_manager);
|
||||
try {
|
||||
for (unsigned i = 0; i < num_fmls; ++i) {
|
||||
for_each_expr(p, fmls[i]);
|
||||
}
|
||||
}
|
||||
catch (is_array_property_ns::bad) {
|
||||
return false;
|
||||
}
|
||||
return p.has_quantifier();
|
||||
}
|
||||
|
||||
|
33
src/dead/array_property_recognizer.h
Normal file
33
src/dead/array_property_recognizer.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_recognizer.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARRAY_PROPERTY_RECOGNIZER_H_
|
||||
#define _ARRAY_PROPERTY_RECOGNIZER_H_
|
||||
|
||||
#include"ast.h"
|
||||
|
||||
class array_property_recognizer {
|
||||
ast_manager& m_manager;
|
||||
public:
|
||||
array_property_recognizer(ast_manager& m);
|
||||
bool operator()(unsigned num_fmls, expr* const* fmls);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ARRAY_PROPERTY_RECOGNIZER_H_ */
|
||||
|
33
src/dead/big_rational.h
Normal file
33
src/dead/big_rational.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
big_rational.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Big rational numbers
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2006-09-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _BIG_RATIONAL_H_
|
||||
#define _BIG_RATIONAL_H_
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include"..\msbig_rational\msbig_rational.h"
|
||||
#else
|
||||
#ifdef NO_GMP
|
||||
#include"dummy_big_rational.h"
|
||||
#else
|
||||
#include"gmp_big_rational.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _BIG_RATIONAL_H_ */
|
||||
|
54
src/dead/dummy_big_rational.h
Normal file
54
src/dead/dummy_big_rational.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dummy_big_rational.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Dummy big rational
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2006-09-26.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _DUMMY_BIG_RATIONAL_H_
|
||||
#define _DUMMY_BIG_RATIONAL_H_
|
||||
|
||||
#include<string>
|
||||
#include"debug.h"
|
||||
|
||||
class big_rational {
|
||||
public:
|
||||
big_rational() { }
|
||||
big_rational(int n) {}
|
||||
~big_rational() {}
|
||||
void reset() {}
|
||||
unsigned hash() const { return 0; }
|
||||
void set(int num, int den) { UNREACHABLE(); }
|
||||
void set(const char * str) { UNREACHABLE(); }
|
||||
bool is_int() const { UNREACHABLE(); return false; }
|
||||
long get_int() const { UNREACHABLE(); return 0; }
|
||||
void neg() { UNREACHABLE(); }
|
||||
big_rational & operator=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
bool operator==(const big_rational & r) const { UNREACHABLE(); return false; }
|
||||
bool operator<(const big_rational & r) const { UNREACHABLE(); return false; }
|
||||
big_rational & operator+=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
big_rational & operator-=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
big_rational & operator*=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
big_rational & operator/=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
big_rational & operator%=(const big_rational & r) { UNREACHABLE(); return *this; }
|
||||
friend void div(const big_rational & r1, const big_rational & r2, big_rational & result) { UNREACHABLE(); }
|
||||
void get_numerator(big_rational & result) { UNREACHABLE(); }
|
||||
void get_denominator(big_rational & result) { UNREACHABLE(); }
|
||||
void get_floor(big_rational & result) { UNREACHABLE(); }
|
||||
std::string to_string() const { UNREACHABLE(); return std::string(""); }
|
||||
};
|
||||
|
||||
#endif /* _DUMMY_BIG_RATIONAL_H_ */
|
||||
|
1047
src/dead/gl_tactic.cpp
Normal file
1047
src/dead/gl_tactic.cpp
Normal file
File diff suppressed because it is too large
Load diff
29
src/dead/gl_tactic.h
Normal file
29
src/dead/gl_tactic.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gl_tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
A T-function/Goldreich Levin-based heuristic.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj (nbjorner) 2011-12-18
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _GL_TACTIC_H_
|
||||
#define _GL_TACTIC_H_
|
||||
|
||||
#include"tactic.h"
|
||||
|
||||
namespace gl {
|
||||
tactic * mk_tactic(ast_manager& m, params_ref const& p);
|
||||
};
|
||||
|
||||
#endif
|
117
src/dead/gmp_big_rational.cpp
Normal file
117
src/dead/gmp_big_rational.cpp
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gmp_big_rational.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Big rationals using GMP
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2006-09-26.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<limits.h>
|
||||
|
||||
#include"gmp_big_rational.h"
|
||||
#include"trace.h"
|
||||
#include"buffer.h"
|
||||
|
||||
#ifndef NO_GMP
|
||||
mpz_t big_rational::m_tmp;
|
||||
bool big_rational::m_tmp_initialized = false;
|
||||
mpz_t big_rational::m_int_min;
|
||||
mpz_t big_rational::m_int_max;
|
||||
mpz_t big_rational::m_uint_max;
|
||||
mpz_t big_rational::m_two32;
|
||||
mpz_t big_rational::m_int64_min;
|
||||
mpz_t big_rational::m_int64_max;
|
||||
mpz_t big_rational::m_uint64_max;
|
||||
bool big_rational::m_has_limits = false;
|
||||
|
||||
void big_rational::init_limits() {
|
||||
mpz_init(m_int_min);
|
||||
mpz_init(m_int_max);
|
||||
mpz_init(m_uint_max);
|
||||
mpz_init(m_two32);
|
||||
mpz_init(m_int64_min);
|
||||
mpz_init(m_int64_max);
|
||||
mpz_init(m_uint64_max);
|
||||
mpz_set_si(m_int_min, INT_MIN);
|
||||
mpz_set_si(m_int_max, INT_MAX);
|
||||
mpz_set_ui(m_uint_max, UINT_MAX);
|
||||
mpz_set_ui(m_two32, UINT_MAX);
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpz_set_si(tmp, 1);
|
||||
mpz_add(m_two32, m_two32, tmp);
|
||||
unsigned max_l = static_cast<unsigned>(INT64_MAX % static_cast<int64>(UINT_MAX));
|
||||
unsigned max_h = static_cast<unsigned>(INT64_MAX / static_cast<int64>(UINT_MAX));
|
||||
mpz_set_ui(m_int64_max, max_h);
|
||||
mpz_mul(m_int64_max, m_uint_max, m_int64_max);
|
||||
mpz_set_ui(tmp, max_l);
|
||||
mpz_add(m_int64_max, tmp, m_int64_max);
|
||||
mpz_neg(m_int64_min, m_int64_max);
|
||||
mpz_set_si(tmp, -1);
|
||||
mpz_add(m_int64_min, m_int64_min, tmp);
|
||||
mpz_set(m_uint64_max, m_int64_max);
|
||||
mpz_set_si(tmp, 2);
|
||||
mpz_mul(m_uint64_max, m_uint64_max, tmp);
|
||||
mpz_set_si(tmp, 1);
|
||||
mpz_add(m_uint64_max, m_uint64_max, tmp);
|
||||
m_has_limits = true;
|
||||
}
|
||||
|
||||
std::string big_rational::to_string() const {
|
||||
size_t sz = mpz_sizeinbase(mpq_numref(m_data), 10) + mpz_sizeinbase(mpq_numref(m_data), 10) + 3;
|
||||
buffer<char> b(sz, 0);
|
||||
mpq_get_str(b.c_ptr(), 10, m_data);
|
||||
std::string result(b.c_ptr());
|
||||
return result;
|
||||
}
|
||||
|
||||
int64 big_rational::get_int64() const {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
SASSERT(is_int64());
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
if (sizeof(int64) == sizeof(long) || mpz_fits_slong_p(tmp)) {
|
||||
return mpz_get_si(tmp);
|
||||
}
|
||||
else {
|
||||
mpz_mod(tmp, tmp, two32());
|
||||
int64 r = static_cast<int64>(mpz_get_ui(tmp));
|
||||
mpq_get_num(tmp, m_data);
|
||||
mpz_div(tmp, tmp, two32());
|
||||
r += static_cast<int64>(mpz_get_si(tmp)) << static_cast<int64>(32);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 big_rational::get_uint64() const {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
SASSERT(is_uint64());
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
if (sizeof(uint64) == sizeof(unsigned long) || mpz_fits_ulong_p(tmp)) {
|
||||
return mpz_get_ui(tmp);
|
||||
}
|
||||
else {
|
||||
mpz_mod(tmp, tmp, two32());
|
||||
uint64 r = static_cast<uint64>(mpz_get_ui(tmp));
|
||||
mpq_get_num(tmp, m_data);
|
||||
mpz_div(tmp, tmp, two32());
|
||||
r += static_cast<uint64>(mpz_get_ui(tmp)) << static_cast<uint64>(32);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
193
src/dead/gmp_big_rational.h
Normal file
193
src/dead/gmp_big_rational.h
Normal file
|
@ -0,0 +1,193 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gmp_big_rational.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Big rationals using gmp
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2006-09-26.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _GMP_BIG_RATIONAL_H_
|
||||
#define _GMP_BIG_RATIONAL_H_
|
||||
|
||||
#ifndef NO_GMP
|
||||
|
||||
#include<string>
|
||||
#include<gmp.h>
|
||||
#include"util.h"
|
||||
#include"debug.h"
|
||||
#include"trace.h"
|
||||
|
||||
class big_rational {
|
||||
mpq_t m_data;
|
||||
static mpz_t m_tmp;
|
||||
static bool m_tmp_initialized;
|
||||
static mpz_t & get_tmp() {
|
||||
if (!m_tmp_initialized) {
|
||||
mpz_init(m_tmp);
|
||||
m_tmp_initialized = true;
|
||||
}
|
||||
return m_tmp;
|
||||
}
|
||||
static mpz_t m_int_min;
|
||||
static mpz_t m_int_max;
|
||||
static mpz_t m_uint_max;
|
||||
static mpz_t m_two32;
|
||||
static mpz_t m_int64_min;
|
||||
static mpz_t m_int64_max;
|
||||
static mpz_t m_uint64_max;
|
||||
static bool m_has_limits;
|
||||
static void init_limits();
|
||||
|
||||
static mpz_t & int64_min() {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
return m_int64_min;
|
||||
}
|
||||
|
||||
static mpz_t & int64_max() {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
return m_int64_max;
|
||||
}
|
||||
|
||||
static mpz_t & uint64_max() {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
return m_uint64_max;
|
||||
}
|
||||
|
||||
static mpz_t & uint_max() {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
return m_uint_max;
|
||||
}
|
||||
|
||||
static mpz_t & two32() {
|
||||
if (!m_has_limits) {
|
||||
init_limits();
|
||||
}
|
||||
return m_two32;
|
||||
}
|
||||
|
||||
public:
|
||||
big_rational() { mpq_init(m_data); reset(); }
|
||||
big_rational(int n) { mpq_init(m_data); mpq_set_si(m_data, n, 1); }
|
||||
~big_rational() { mpq_clear(m_data); }
|
||||
void reset() { mpq_set_si(m_data, 0, 1); }
|
||||
unsigned hash() const { return mpz_get_si(mpq_numref(m_data)); }
|
||||
void set(int num, int den) {
|
||||
mpq_set_si(m_data, num, den);
|
||||
mpq_canonicalize(m_data);
|
||||
}
|
||||
void setu(unsigned num) {
|
||||
mpq_set_ui(m_data, num, 1);
|
||||
mpq_canonicalize(m_data);
|
||||
}
|
||||
void set(const char * str) {
|
||||
mpq_set_str(m_data, str, 10);
|
||||
}
|
||||
bool is_int() const {
|
||||
return mpz_cmp_ui(mpq_denref(m_data), 1) == 0;
|
||||
}
|
||||
bool is_even() const {
|
||||
if (!is_int()) {
|
||||
return false;
|
||||
}
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
return mpz_even_p(tmp) != 0;
|
||||
}
|
||||
bool is_int64() const {
|
||||
if (!is_int()) {
|
||||
return false;
|
||||
}
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
return mpz_fits_slong_p(tmp) ||
|
||||
(mpz_cmp(tmp, int64_min()) >= 0 && mpz_cmp(tmp, int64_max()) <= 0);
|
||||
}
|
||||
bool is_uint64() const {
|
||||
if (!is_int()) {
|
||||
return false;
|
||||
}
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
return mpz_sgn(tmp) >= 0 && (mpz_fits_ulong_p(tmp) || mpz_cmp(tmp, uint64_max()) <= 0);
|
||||
}
|
||||
int64 get_int64() const;
|
||||
uint64 get_uint64() const;
|
||||
void neg() { mpq_neg(m_data, m_data); }
|
||||
big_rational & operator=(const big_rational & r) {
|
||||
mpq_set(m_data, r.m_data);
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const big_rational & r) const { return mpq_equal(m_data, r.m_data) != 0; }
|
||||
bool operator<(const big_rational & r) const { return mpq_cmp(m_data, r.m_data) < 0; }
|
||||
big_rational & operator+=(const big_rational & r) {
|
||||
mpq_add(m_data, m_data, r.m_data);
|
||||
return *this;
|
||||
}
|
||||
big_rational & operator-=(const big_rational & r) {
|
||||
mpq_sub(m_data, m_data, r.m_data);
|
||||
return *this;
|
||||
}
|
||||
big_rational & operator*=(const big_rational & r) {
|
||||
mpq_mul(m_data, m_data, r.m_data);
|
||||
return *this;
|
||||
}
|
||||
big_rational & operator/=(const big_rational & r) {
|
||||
mpq_div(m_data, m_data, r.m_data);
|
||||
return *this;
|
||||
}
|
||||
big_rational & operator%=(const big_rational & r) {
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpz_tdiv_r(tmp, mpq_numref(m_data), mpq_numref(r.m_data));
|
||||
mpq_set_z(m_data, tmp);
|
||||
return *this;
|
||||
}
|
||||
friend void div(const big_rational & r1, const big_rational & r2, big_rational & result) {
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpz_tdiv_q(tmp, mpq_numref(r1.m_data), mpq_numref(r2.m_data));
|
||||
mpq_set_z(result.m_data, tmp);
|
||||
}
|
||||
void get_numerator(big_rational & result) {
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_num(tmp, m_data);
|
||||
mpq_set_z(result.m_data, tmp);
|
||||
}
|
||||
void get_denominator(big_rational & result) {
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpq_get_den(tmp, m_data);
|
||||
mpq_set_z(result.m_data, tmp);
|
||||
}
|
||||
void get_floor(big_rational & result) {
|
||||
mpz_t & tmp = get_tmp();
|
||||
mpz_fdiv_q(tmp, mpq_numref(m_data), mpq_denref(m_data));
|
||||
mpq_set_z(result.m_data, tmp);
|
||||
}
|
||||
std::string to_string() const;
|
||||
#ifdef Z3DEBUG
|
||||
static void test() {
|
||||
init_limits();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _GMP_BIG_RATIONAL_H_ */
|
||||
|
26
src/old_params/arith_simplifier_params.cpp
Normal file
26
src/old_params/arith_simplifier_params.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
arith_simplifier_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-05-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"arith_simplifier_params.h"
|
||||
|
||||
void arith_simplifier_params::register_params(ini_params & p) {
|
||||
p.register_bool_param("ARITH_EXPAND_EQS", m_arith_expand_eqs);
|
||||
p.register_bool_param("ARITH_PROCESS_ALL_EQS", m_arith_process_all_eqs);
|
||||
}
|
||||
|
145
src/rewriter/rewriter.txt
Normal file
145
src/rewriter/rewriter.txt
Normal file
|
@ -0,0 +1,145 @@
|
|||
|
||||
|
||||
The following classes implement theory specific rewriting rules:
|
||||
- bool_rewriter
|
||||
- arith_rewriter
|
||||
- bv_rewriter
|
||||
- array_rewriter
|
||||
- datatype_rewriter
|
||||
|
||||
Each of the provide the method
|
||||
br_status mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result)
|
||||
where
|
||||
- f is expected to be a func_decl of the given theory
|
||||
- If the return value if different from BR_FAILED, the result is stored in result.
|
||||
|
||||
The template rewriter_tpl<Cfg> can be instantiated to implement
|
||||
rewriters that traverse ASTs applying some kind of transformation/simplification.
|
||||
The parameter Cfg is expected to be a class with the following methods:
|
||||
bool cache_all_results() const;
|
||||
bool cache_results() const;
|
||||
bool flat_assoc(func_decl * f) const;
|
||||
bool rewrite_patterns() const;
|
||||
bool max_scopes_exceeded(unsigned num_scopes) const;
|
||||
bool max_frames_exceeded(unsigned num_frames) const;
|
||||
bool max_steps_exceeded(unsigned num_steps) const;
|
||||
bool pre_visit(expr * t);
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr);
|
||||
bool reduce_quantifier(quantifier * old_q,
|
||||
expr * new_body,
|
||||
expr * const * new_patterns,
|
||||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr);
|
||||
bool get_macro(func_decl * d, expr * & def, quantifier * & q, proof * & def_pr);
|
||||
bool get_subst(expr * s, expr * & t, proof * & t_pr);
|
||||
void reset();
|
||||
void cleanup();
|
||||
|
||||
The class default_rewriter_cfg provides a default implementation for these methods.
|
||||
|
||||
The method reduce_app is the most important one. When implementing new rewriter,
|
||||
we usually redefine this method.
|
||||
We should return BR_FAILED, if we do not want to apply a "simplification" to
|
||||
(f args[0] ... args[num-1])
|
||||
This is very important for performance reasons, since the rewriter tries to
|
||||
reuse AST when BR_FAILED is returned.
|
||||
If one wants to simply (f args[0] ... args[num-1]) to t, then use:
|
||||
result = t;
|
||||
return BR_DONE;
|
||||
Sometimes, by applying a simplification rule we may create new opportunites for
|
||||
rewriting. One can instruct the rewriter to revisit the result by returning:
|
||||
BR_REWRITE1, // rewrite the result (bounded by depth 1)
|
||||
BR_REWRITE2, // rewrite the result (bounded by depth 2)
|
||||
BR_REWRITE3, // rewrite the result (bounded by depth 3)
|
||||
BR_REWRITE_FULL, // rewrite the result unbounded
|
||||
Example:
|
||||
Suppose one wants to implement the rewriting rule
|
||||
(= (ite c t e) v) --> (ite c (= t v) (= e v))
|
||||
This rule may create new opportunites for simplification since
|
||||
it creates the equalities (= t v) and (= e v).
|
||||
So, to force the rewriter to process these new equalities,
|
||||
BR_REWRITE2 should be returned.
|
||||
It is also correct (but unnecessary) to return BR_REWRITE3 and BR_REWRITE_FULL.
|
||||
|
||||
To instantiate a new rewriter, one should
|
||||
1) Define a new configuration class.
|
||||
class mycfg : public default_rewriter_cfg {
|
||||
...
|
||||
}
|
||||
2) Force template instantiation using the new cfg.
|
||||
templace class rewriter_tpl<mycfg>;
|
||||
|
||||
3) Define a subclass of rewriter_tpl<mycfg> that
|
||||
owns the new cfg.
|
||||
|
||||
class myrewriter : public rewriter_tpl<mycfg> {
|
||||
mycfg m_cfg;
|
||||
public:
|
||||
myrewriter(ast_manager & m):
|
||||
rewriter_tpl<mycfg>(m, m.proofs_enabled(), m_cfg),
|
||||
m_cfg(...) {
|
||||
}
|
||||
};
|
||||
|
||||
The rewriter_tpl template supports proof production.
|
||||
It can be disabled even when proof productions is
|
||||
enabled in the ast_manager.
|
||||
|
||||
Examples of rewriter_tpl instances:
|
||||
- th_rewriter.cpp
|
||||
- assertion_set_bit_blaster.cpp
|
||||
- model_evaluator.cpp
|
||||
- elim_distinct.cpp
|
||||
|
||||
Notes for additional Cfg methods:
|
||||
- bool rewrite_patterns() const;
|
||||
If false is returned, then the rewriter will ignore patterns.
|
||||
- bool pre_visit(expr * t);
|
||||
If false is returned, then the rewriter will not process t.
|
||||
This is very useful, for example, for implementing rewriters that will only
|
||||
"process" the Boolean skeleton.
|
||||
- bool max_steps_exceeded(unsigned num_steps) const;
|
||||
If false, it interrupts the execution of the rewriter.
|
||||
The interruption is performed by throwing an exception.
|
||||
One can also used this callback to check whether the
|
||||
amount of memory used is still reasonable.
|
||||
- bool cache_all_results() const;
|
||||
By default, the rewriter only caches the results of
|
||||
non-atomic shared ASTs (get_ref_count() > 1). If true,
|
||||
is returned, the rewriter will cache all intermediate results.
|
||||
- bool flat_assoc(func_decl * f) const;
|
||||
If true is returned, then the rewriter will do flattening of
|
||||
non-shared nodes. For example,
|
||||
(+ a (+ b (+ c d)))
|
||||
will be treated as (+ a b c d)
|
||||
Shared nodes are not considered. Thus, exponential blowup
|
||||
in the rewriter stack is avoided.
|
||||
So, when implementing
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr);
|
||||
one should not assume that for an associative f, there is not
|
||||
f-application in args when true is returned by flat_assoc.
|
||||
|
||||
when implementing
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr);
|
||||
If result_pr is set to 0, and proofs are enabled, then the rewriter will use a generic
|
||||
"rewrite" proof step for justifying that (f args[0] ... args[num-1]) is equal to result.
|
||||
|
||||
The th_rewriter takes care of flattening. So, in principle, there is
|
||||
not need to return true in flat_assoc.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue