mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 20:18:18 +00:00
merge with master
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
50c93d1ad4
commit
c963f6f2df
|
@ -1,40 +0,0 @@
|
||||||
echo "Build"
|
|
||||||
md build
|
|
||||||
cd build
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
|
||||||
cmake -DBUILD_DOTNET_BINDINGS=True -DBUILD_JAVA_BINDINGS=True -DBUILD_PYTHON_BINDINGS=True -G "NMake Makefiles" ../
|
|
||||||
nmake
|
|
||||||
rem TBD: test error level
|
|
||||||
|
|
||||||
echo "Test python bindings"
|
|
||||||
pushd python
|
|
||||||
python z3test.py z3
|
|
||||||
python z3test.py z3num
|
|
||||||
popd
|
|
||||||
|
|
||||||
echo "Build and run examples"
|
|
||||||
nmake cpp_example
|
|
||||||
examples\cpp_example_build_dir\cpp_example.exe
|
|
||||||
|
|
||||||
nmake c_example
|
|
||||||
examples\c_example_build_dir\c_example.exe
|
|
||||||
|
|
||||||
rem nmake java_example
|
|
||||||
rem java_example.exe
|
|
||||||
|
|
||||||
rem nmake dotnet_example
|
|
||||||
rem dotnet_example.exe
|
|
||||||
|
|
||||||
echo "Build and run unit tests"
|
|
||||||
nmake test-z3
|
|
||||||
rem TBD: test error level
|
|
||||||
rem test-z3.exe -a
|
|
||||||
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
echo "Run regression tests"
|
|
||||||
git clone https://github.com/z3prover/z3test z3test
|
|
||||||
echo "test-benchmarks"
|
|
||||||
python z3test\scripts\test_benchmarks.py build\z3.exe z3test\regressions\smt2
|
|
||||||
echo "benchmarks tested"
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ extern "C" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initialized = to_solver(s)->m_solver.get() != 0;
|
bool initialized = to_solver(s)->m_solver.get() != nullptr;
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
init_solver(c, s);
|
init_solver(c, s);
|
||||||
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
|
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
|
||||||
|
|
|
@ -1,496 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2007 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
arith_simplifier_plugin.cpp
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Simplifier for the arithmetic family.
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo (leonardo) 2008-01-08
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#include"arith_simplifier_plugin.h"
|
|
||||||
#include"ast_pp.h"
|
|
||||||
#include"ast_ll_pp.h"
|
|
||||||
#include"ast_smt2_pp.h"
|
|
||||||
|
|
||||||
arith_simplifier_plugin::~arith_simplifier_plugin() {
|
|
||||||
}
|
|
||||||
|
|
||||||
arith_simplifier_plugin::arith_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, arith_simplifier_params & p):
|
|
||||||
poly_simplifier_plugin(symbol("arith"), m, OP_ADD, OP_MUL, OP_UMINUS, OP_SUB, OP_NUM),
|
|
||||||
m_params(p),
|
|
||||||
m_util(m),
|
|
||||||
m_bsimp(b),
|
|
||||||
m_int_zero(m),
|
|
||||||
m_real_zero(m) {
|
|
||||||
m_int_zero = m_util.mk_numeral(rational(0), true);
|
|
||||||
m_real_zero = m_util.mk_numeral(rational(0), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Return true if the first monomial of t is negative.
|
|
||||||
*/
|
|
||||||
bool arith_simplifier_plugin::is_neg_poly(expr * t) const {
|
|
||||||
if (m_util.is_add(t)) {
|
|
||||||
t = to_app(t)->get_arg(0);
|
|
||||||
}
|
|
||||||
if (m_util.is_mul(t)) {
|
|
||||||
t = to_app(t)->get_arg(0);
|
|
||||||
rational r;
|
|
||||||
if (is_numeral(t, r))
|
|
||||||
return r.is_neg();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::get_monomial_gcd(expr_ref_vector& monomials, numeral& g) {
|
|
||||||
g = numeral::zero();
|
|
||||||
numeral n;
|
|
||||||
for (unsigned i = 0; !g.is_one() && i < monomials.size(); ++i) {
|
|
||||||
expr* e = monomials[i].get();
|
|
||||||
if (is_numeral(e, n)) {
|
|
||||||
g = gcd(abs(n), g);
|
|
||||||
}
|
|
||||||
else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) {
|
|
||||||
g = gcd(abs(n), g);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
g = numeral::one();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (g.is_zero()) {
|
|
||||||
g = numeral::one();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::div_monomial(expr_ref_vector& monomials, numeral const& g) {
|
|
||||||
numeral n;
|
|
||||||
for (unsigned i = 0; i < monomials.size(); ++i) {
|
|
||||||
expr* e = monomials[i].get();
|
|
||||||
if (is_numeral(e, n)) {
|
|
||||||
SASSERT((n/g).is_int());
|
|
||||||
monomials[i] = mk_numeral(n/g);
|
|
||||||
}
|
|
||||||
else if (is_mul(e) && is_numeral(to_app(e)->get_arg(0), n)) {
|
|
||||||
SASSERT((n/g).is_int());
|
|
||||||
monomials[i] = mk_mul(n/g, to_app(e)->get_arg(1));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::gcd_reduce_monomial(expr_ref_vector& monomials, numeral& k) {
|
|
||||||
numeral g, n;
|
|
||||||
|
|
||||||
get_monomial_gcd(monomials, g);
|
|
||||||
g = gcd(abs(k), g);
|
|
||||||
|
|
||||||
if (g.is_one()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SASSERT(g.is_pos());
|
|
||||||
|
|
||||||
k = k / g;
|
|
||||||
div_monomial(monomials, g);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<arith_simplifier_plugin::op_kind Kind>
|
|
||||||
void arith_simplifier_plugin::mk_le_ge_eq_core(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
set_curr_sort(arg1);
|
|
||||||
bool is_int = m_curr_sort->get_decl_kind() == INT_SORT;
|
|
||||||
expr_ref_vector monomials(m_manager);
|
|
||||||
rational k;
|
|
||||||
TRACE("arith_eq_bug", tout << mk_ismt2_pp(arg1, m_manager) << "\n" << mk_ismt2_pp(arg2, m_manager) << "\n";);
|
|
||||||
process_sum_of_monomials(false, arg1, monomials, k);
|
|
||||||
process_sum_of_monomials(true, arg2, monomials, k);
|
|
||||||
k.neg();
|
|
||||||
if (is_int) {
|
|
||||||
numeral g;
|
|
||||||
get_monomial_gcd(monomials, g);
|
|
||||||
if (!g.is_one()) {
|
|
||||||
div_monomial(monomials, g);
|
|
||||||
switch(Kind) {
|
|
||||||
case LE:
|
|
||||||
//
|
|
||||||
// g*monmials' <= k
|
|
||||||
// <=>
|
|
||||||
// monomials' <= floor(k/g)
|
|
||||||
//
|
|
||||||
k = floor(k/g);
|
|
||||||
break;
|
|
||||||
case GE:
|
|
||||||
//
|
|
||||||
// g*monmials' >= k
|
|
||||||
// <=>
|
|
||||||
// monomials' >= ceil(k/g)
|
|
||||||
//
|
|
||||||
k = ceil(k/g);
|
|
||||||
break;
|
|
||||||
case EQ:
|
|
||||||
k = k/g;
|
|
||||||
if (!k.is_int()) {
|
|
||||||
result = m_manager.mk_false();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expr_ref lhs(m_manager);
|
|
||||||
mk_sum_of_monomials(monomials, lhs);
|
|
||||||
if (m_util.is_numeral(lhs)) {
|
|
||||||
SASSERT(lhs == mk_zero());
|
|
||||||
if (( Kind == LE && numeral::zero() <= k) ||
|
|
||||||
( Kind == GE && numeral::zero() >= k) ||
|
|
||||||
( Kind == EQ && numeral::zero() == k))
|
|
||||||
result = m_manager.mk_true();
|
|
||||||
else
|
|
||||||
result = m_manager.mk_false();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if (is_neg_poly(lhs)) {
|
|
||||||
expr_ref neg_lhs(m_manager);
|
|
||||||
mk_uminus(lhs, neg_lhs);
|
|
||||||
lhs = neg_lhs;
|
|
||||||
k.neg();
|
|
||||||
expr * rhs = m_util.mk_numeral(k, is_int);
|
|
||||||
switch (Kind) {
|
|
||||||
case LE:
|
|
||||||
result = m_util.mk_ge(lhs, rhs);
|
|
||||||
break;
|
|
||||||
case GE:
|
|
||||||
result = m_util.mk_le(lhs, rhs);
|
|
||||||
break;
|
|
||||||
case EQ:
|
|
||||||
result = m_manager.mk_eq(lhs, rhs);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
expr * rhs = m_util.mk_numeral(k, is_int);
|
|
||||||
switch (Kind) {
|
|
||||||
case LE:
|
|
||||||
result = m_util.mk_le(lhs, rhs);
|
|
||||||
break;
|
|
||||||
case GE:
|
|
||||||
result = m_util.mk_ge(lhs, rhs);
|
|
||||||
break;
|
|
||||||
case EQ:
|
|
||||||
result = m_manager.mk_eq(lhs, rhs);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_arith_eq(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
mk_le_ge_eq_core<EQ>(arg1, arg2, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_le(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
mk_le_ge_eq_core<LE>(arg1, arg2, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_ge(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
mk_le_ge_eq_core<GE>(arg1, arg2, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_lt(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
expr_ref tmp(m_manager);
|
|
||||||
mk_le(arg2, arg1, tmp);
|
|
||||||
m_bsimp.mk_not(tmp, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_gt(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
expr_ref tmp(m_manager);
|
|
||||||
mk_le(arg1, arg2, tmp);
|
|
||||||
m_bsimp.mk_not(tmp, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::gcd_normalize(numeral & coeff, expr_ref& term) {
|
|
||||||
if (!abs(coeff).is_one()) {
|
|
||||||
set_curr_sort(term);
|
|
||||||
SASSERT(m_curr_sort->get_decl_kind() == INT_SORT);
|
|
||||||
expr_ref_vector monomials(m_manager);
|
|
||||||
rational k;
|
|
||||||
monomials.push_back(mk_numeral(numeral(coeff), true));
|
|
||||||
process_sum_of_monomials(false, term, monomials, k);
|
|
||||||
gcd_reduce_monomial(monomials, k);
|
|
||||||
numeral coeff1;
|
|
||||||
if (!is_numeral(monomials[0].get(), coeff1)) {
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
if (coeff1 == coeff) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
monomials[0] = mk_numeral(k, true);
|
|
||||||
coeff = coeff1;
|
|
||||||
mk_sum_of_monomials(monomials, term);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_div(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
set_curr_sort(arg1);
|
|
||||||
numeral v1, v2;
|
|
||||||
bool is_int;
|
|
||||||
if (m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) {
|
|
||||||
SASSERT(!is_int);
|
|
||||||
if (m_util.is_numeral(arg1, v1, is_int))
|
|
||||||
result = m_util.mk_numeral(v1/v2, false);
|
|
||||||
else {
|
|
||||||
numeral k(1);
|
|
||||||
k /= v2;
|
|
||||||
|
|
||||||
expr_ref inv_arg2(m_util.mk_numeral(k, false), m_manager);
|
|
||||||
mk_mul(inv_arg2, arg1, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = m_util.mk_div(arg1, arg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_idiv(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
set_curr_sort(arg1);
|
|
||||||
numeral v1, v2;
|
|
||||||
bool is_int;
|
|
||||||
if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero())
|
|
||||||
result = m_util.mk_numeral(div(v1, v2), is_int);
|
|
||||||
else if (divides(arg2, arg1, result)) {
|
|
||||||
result = m_util.mk_mul(result, m_util.mk_idiv(arg2, arg2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = m_util.mk_idiv(arg1, arg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arith_simplifier_plugin::divides(expr* d, expr* n, expr_ref& quot) {
|
|
||||||
ast_manager& m = m_manager;
|
|
||||||
if (d == n) {
|
|
||||||
quot = m_util.mk_numeral(rational(1), m_util.is_int(d));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (m_util.is_mul(n)) {
|
|
||||||
expr_ref_vector muls(m);
|
|
||||||
muls.push_back(n);
|
|
||||||
expr* n1, *n2;
|
|
||||||
rational r1, r2;
|
|
||||||
for (unsigned i = 0; i < muls.size(); ++i) {
|
|
||||||
if (m_util.is_mul(muls[i].get(), n1, n2)) {
|
|
||||||
muls[i] = n1;
|
|
||||||
muls.push_back(n2);
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_util.is_numeral(d, r1) && !r1.is_zero()) {
|
|
||||||
for (unsigned i = 0; i < muls.size(); ++i) {
|
|
||||||
if (m_util.is_numeral(muls[i].get(), r2) && (r2 / r1).is_int()) {
|
|
||||||
muls[i] = m_util.mk_numeral(r2 / r1, m_util.is_int(d));
|
|
||||||
quot = m_util.mk_mul(muls.size(), muls.c_ptr());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (unsigned i = 0; i < muls.size(); ++i) {
|
|
||||||
if (d == muls[i].get()) {
|
|
||||||
muls[i] = muls.back();
|
|
||||||
muls.pop_back();
|
|
||||||
quot = m_util.mk_mul(muls.size(), muls.c_ptr());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::prop_mod_const(expr * e, unsigned depth, numeral const& k, expr_ref& result) {
|
|
||||||
SASSERT(m_util.is_int(e));
|
|
||||||
SASSERT(k.is_int() && k.is_pos());
|
|
||||||
numeral n;
|
|
||||||
bool is_int;
|
|
||||||
|
|
||||||
if (depth == 0) {
|
|
||||||
result = e;
|
|
||||||
}
|
|
||||||
else if (is_add(e) || is_mul(e)) {
|
|
||||||
expr_ref_vector args(m_manager);
|
|
||||||
expr_ref tmp(m_manager);
|
|
||||||
app* a = to_app(e);
|
|
||||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
|
||||||
prop_mod_const(a->get_arg(i), depth - 1, k, tmp);
|
|
||||||
args.push_back(tmp);
|
|
||||||
}
|
|
||||||
reduce(a->get_decl(), args.size(), args.c_ptr(), result);
|
|
||||||
}
|
|
||||||
else if (m_util.is_numeral(e, n, is_int) && is_int) {
|
|
||||||
result = mk_numeral(mod(n, k), true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_mod(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
set_curr_sort(arg1);
|
|
||||||
numeral v1, v2;
|
|
||||||
bool is_int;
|
|
||||||
if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) {
|
|
||||||
result = m_util.mk_numeral(mod(v1, v2), is_int);
|
|
||||||
}
|
|
||||||
else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_one()) {
|
|
||||||
result = m_util.mk_numeral(numeral(0), true);
|
|
||||||
}
|
|
||||||
else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_pos()) {
|
|
||||||
expr_ref tmp(m_manager);
|
|
||||||
prop_mod_const(arg1, 5, v2, tmp);
|
|
||||||
result = m_util.mk_mod(tmp, arg2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = m_util.mk_mod(arg1, arg2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_rem(expr * arg1, expr * arg2, expr_ref & result) {
|
|
||||||
set_curr_sort(arg1);
|
|
||||||
numeral v1, v2;
|
|
||||||
bool is_int;
|
|
||||||
if (m_util.is_numeral(arg1, v1, is_int) && m_util.is_numeral(arg2, v2, is_int) && !v2.is_zero()) {
|
|
||||||
numeral m = mod(v1, v2);
|
|
||||||
//
|
|
||||||
// rem(v1,v2) = if v2 >= 0 then mod(v1,v2) else -mod(v1,v2)
|
|
||||||
//
|
|
||||||
if (v2.is_neg()) {
|
|
||||||
m.neg();
|
|
||||||
}
|
|
||||||
result = m_util.mk_numeral(m, is_int);
|
|
||||||
}
|
|
||||||
else if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_one()) {
|
|
||||||
result = m_util.mk_numeral(numeral(0), true);
|
|
||||||
}
|
|
||||||
else if (m_util.is_numeral(arg2, v2, is_int) && is_int && !v2.is_zero()) {
|
|
||||||
expr_ref tmp(m_manager);
|
|
||||||
prop_mod_const(arg1, 5, v2, tmp);
|
|
||||||
result = m_util.mk_mod(tmp, arg2);
|
|
||||||
if (v2.is_neg()) {
|
|
||||||
result = m_util.mk_uminus(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = m_util.mk_rem(arg1, arg2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_to_real(expr * arg, expr_ref & result) {
|
|
||||||
numeral v;
|
|
||||||
if (m_util.is_numeral(arg, v))
|
|
||||||
result = m_util.mk_numeral(v, false);
|
|
||||||
else
|
|
||||||
result = m_util.mk_to_real(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_to_int(expr * arg, expr_ref & result) {
|
|
||||||
numeral v;
|
|
||||||
if (m_util.is_numeral(arg, v))
|
|
||||||
result = m_util.mk_numeral(floor(v), true);
|
|
||||||
else if (m_util.is_to_real(arg))
|
|
||||||
result = to_app(arg)->get_arg(0);
|
|
||||||
else
|
|
||||||
result = m_util.mk_to_int(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_is_int(expr * arg, expr_ref & result) {
|
|
||||||
numeral v;
|
|
||||||
if (m_util.is_numeral(arg, v))
|
|
||||||
result = v.is_int()?m_manager.mk_true():m_manager.mk_false();
|
|
||||||
else if (m_util.is_to_real(arg))
|
|
||||||
result = m_manager.mk_true();
|
|
||||||
else
|
|
||||||
result = m_util.mk_is_int(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arith_simplifier_plugin::reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
|
|
||||||
set_reduce_invoked();
|
|
||||||
SASSERT(f->get_family_id() == m_fid);
|
|
||||||
TRACE("arith_simplifier_plugin", tout << mk_pp(f, m_manager) << "\n";
|
|
||||||
for (unsigned i = 0; i < num_args; i++) tout << mk_pp(args[i], m_manager) << "\n";);
|
|
||||||
arith_op_kind k = static_cast<arith_op_kind>(f->get_decl_kind());
|
|
||||||
switch (k) {
|
|
||||||
case OP_NUM: return false;
|
|
||||||
case OP_LE: if (m_presimp) return false; SASSERT(num_args == 2); mk_le(args[0], args[1], result); break;
|
|
||||||
case OP_GE: if (m_presimp) return false; SASSERT(num_args == 2); mk_ge(args[0], args[1], result); break;
|
|
||||||
case OP_LT: if (m_presimp) return false; SASSERT(num_args == 2); mk_lt(args[0], args[1], result); break;
|
|
||||||
case OP_GT: if (m_presimp) return false; SASSERT(num_args == 2); mk_gt(args[0], args[1], result); break;
|
|
||||||
case OP_ADD: mk_add(num_args, args, result); break;
|
|
||||||
case OP_SUB: mk_sub(num_args, args, result); break;
|
|
||||||
case OP_UMINUS: SASSERT(num_args == 1); mk_uminus(args[0], result); break;
|
|
||||||
case OP_MUL:
|
|
||||||
mk_mul(num_args, args, result);
|
|
||||||
TRACE("arith_simplifier_plugin", tout << mk_pp(result, m_manager) << "\n";);
|
|
||||||
break;
|
|
||||||
case OP_DIV: SASSERT(num_args == 2); mk_div(args[0], args[1], result); break;
|
|
||||||
case OP_IDIV: SASSERT(num_args == 2); mk_idiv(args[0], args[1], result); break;
|
|
||||||
case OP_REM: SASSERT(num_args == 2); mk_rem(args[0], args[1], result); break;
|
|
||||||
case OP_MOD: SASSERT(num_args == 2); mk_mod(args[0], args[1], result); break;
|
|
||||||
case OP_TO_REAL: SASSERT(num_args == 1); mk_to_real(args[0], result); break;
|
|
||||||
case OP_TO_INT: SASSERT(num_args == 1); mk_to_int(args[0], result); break;
|
|
||||||
case OP_IS_INT: SASSERT(num_args == 1); mk_is_int(args[0], result); break;
|
|
||||||
case OP_POWER: return false;
|
|
||||||
case OP_ABS: SASSERT(num_args == 1); mk_abs(args[0], result); break;
|
|
||||||
case OP_IRRATIONAL_ALGEBRAIC_NUM: return false;
|
|
||||||
case OP_DIV_0: return false;
|
|
||||||
case OP_IDIV_0: return false;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TRACE("arith_simplifier_plugin", tout << mk_pp(result.get(), m_manager) << "\n";);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void arith_simplifier_plugin::mk_abs(expr * arg, expr_ref & result) {
|
|
||||||
expr_ref c(m_manager);
|
|
||||||
expr_ref m_arg(m_manager);
|
|
||||||
mk_uminus(arg, m_arg);
|
|
||||||
mk_ge(arg, m_util.mk_numeral(rational(0), m_util.is_int(arg)), c);
|
|
||||||
m_bsimp.mk_ite(c, arg, m_arg, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arith_simplifier_plugin::is_arith_term(expr * n) const {
|
|
||||||
return n->get_kind() == AST_APP && to_app(n)->get_family_id() == m_fid;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool arith_simplifier_plugin::reduce_eq(expr * lhs, expr * rhs, expr_ref & result) {
|
|
||||||
TRACE("reduce_eq_bug", tout << mk_ismt2_pp(lhs, m_manager) << "\n" << mk_ismt2_pp(rhs, m_manager) << "\n";);
|
|
||||||
set_reduce_invoked();
|
|
||||||
if (m_presimp) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (m_params.m_arith_expand_eqs) {
|
|
||||||
expr_ref le(m_manager), ge(m_manager);
|
|
||||||
mk_le_ge_eq_core<LE>(lhs, rhs, le);
|
|
||||||
mk_le_ge_eq_core<GE>(lhs, rhs, ge);
|
|
||||||
m_bsimp.mk_and(le, ge, result);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_params.m_arith_process_all_eqs || is_arith_term(lhs) || is_arith_term(rhs)) {
|
|
||||||
mk_arith_eq(lhs, rhs, result);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*++
|
|
||||||
Copyright (c) 2007 Microsoft Corporation
|
|
||||||
|
|
||||||
Module Name:
|
|
||||||
|
|
||||||
arith_simplifier_plugin.h
|
|
||||||
|
|
||||||
Abstract:
|
|
||||||
|
|
||||||
Simplifier for the arithmetic family.
|
|
||||||
|
|
||||||
Author:
|
|
||||||
|
|
||||||
Leonardo (leonardo) 2008-01-08
|
|
||||||
|
|
||||||
--*/
|
|
||||||
#ifndef ARITH_SIMPLIFIER_PLUGIN_H_
|
|
||||||
#define ARITH_SIMPLIFIER_PLUGIN_H_
|
|
||||||
|
|
||||||
#include"basic_simplifier_plugin.h"
|
|
||||||
#include"poly_simplifier_plugin.h"
|
|
||||||
#include"arith_decl_plugin.h"
|
|
||||||
#include"arith_simplifier_params.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Simplifier for the arith family.
|
|
||||||
*/
|
|
||||||
class arith_simplifier_plugin : public poly_simplifier_plugin {
|
|
||||||
public:
|
|
||||||
enum op_kind {
|
|
||||||
LE, GE, EQ
|
|
||||||
};
|
|
||||||
protected:
|
|
||||||
arith_simplifier_params & m_params;
|
|
||||||
arith_util m_util;
|
|
||||||
basic_simplifier_plugin & m_bsimp;
|
|
||||||
expr_ref m_int_zero;
|
|
||||||
expr_ref m_real_zero;
|
|
||||||
|
|
||||||
bool is_neg_poly(expr * t) const;
|
|
||||||
|
|
||||||
template<op_kind k>
|
|
||||||
void mk_le_ge_eq_core(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
|
|
||||||
void prop_mod_const(expr * e, unsigned depth, numeral const& k, expr_ref& result);
|
|
||||||
|
|
||||||
void gcd_reduce_monomial(expr_ref_vector& monomials, numeral& k);
|
|
||||||
|
|
||||||
void div_monomial(expr_ref_vector& monomials, numeral const& g);
|
|
||||||
void get_monomial_gcd(expr_ref_vector& monomials, numeral& g);
|
|
||||||
bool divides(expr* d, expr* n, expr_ref& quot);
|
|
||||||
|
|
||||||
public:
|
|
||||||
arith_simplifier_plugin(ast_manager & m, basic_simplifier_plugin & b, arith_simplifier_params & p);
|
|
||||||
~arith_simplifier_plugin();
|
|
||||||
arith_util & get_arith_util() { return m_util; }
|
|
||||||
virtual numeral norm(const numeral & n) { return n; }
|
|
||||||
virtual bool is_numeral(expr * n, rational & val) const { bool f; return m_util.is_numeral(n, val, f); }
|
|
||||||
bool is_numeral(expr * n) const { return m_util.is_numeral(n); }
|
|
||||||
virtual bool is_minus_one(expr * n) const { numeral tmp; return is_numeral(n, tmp) && tmp.is_minus_one(); }
|
|
||||||
virtual expr * get_zero(sort * s) const { return m_util.is_int(s) ? m_int_zero.get() : m_real_zero.get(); }
|
|
||||||
|
|
||||||
virtual app * mk_numeral(numeral const & n) { return m_util.mk_numeral(n, m_curr_sort->get_decl_kind() == INT_SORT); }
|
|
||||||
app * mk_numeral(numeral const & n, bool is_int) { return m_util.mk_numeral(n, is_int); }
|
|
||||||
bool is_int_sort(sort const * s) const { return m_util.is_int(s); }
|
|
||||||
bool is_real_sort(sort const * s) const { return m_util.is_real(s); }
|
|
||||||
bool is_arith_sort(sort const * s) const { return is_int_sort(s) || is_real_sort(s); }
|
|
||||||
bool is_int(expr const * n) const { return m_util.is_int(n); }
|
|
||||||
bool is_le(expr const * n) const { return m_util.is_le(n); }
|
|
||||||
bool is_ge(expr const * n) const { return m_util.is_ge(n); }
|
|
||||||
|
|
||||||
virtual bool is_le_ge(expr * n) const { return is_le(n) || is_ge(n); }
|
|
||||||
|
|
||||||
void mk_le(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_ge(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_lt(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_gt(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_arith_eq(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_div(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_idiv(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_mod(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_rem(expr * arg1, expr * arg2, expr_ref & result);
|
|
||||||
void mk_to_real(expr * arg, expr_ref & result);
|
|
||||||
void mk_to_int(expr * arg, expr_ref & result);
|
|
||||||
void mk_is_int(expr * arg, expr_ref & result);
|
|
||||||
void mk_abs(expr * arg, expr_ref & result);
|
|
||||||
|
|
||||||
virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result);
|
|
||||||
virtual bool reduce_eq(expr * lhs, expr * rhs, expr_ref & result);
|
|
||||||
|
|
||||||
bool is_arith_term(expr * n) const;
|
|
||||||
|
|
||||||
void gcd_normalize(numeral & coeff, expr_ref& term);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* ARITH_SIMPLIFIER_PLUGIN_H_ */
|
|
|
@ -619,7 +619,7 @@ public:
|
||||||
try {
|
try {
|
||||||
ctx.regular_stream() << gparams::get_value(opt) << std::endl;
|
ctx.regular_stream() << gparams::get_value(opt) << std::endl;
|
||||||
}
|
}
|
||||||
catch (const gparams::exception & ex) {
|
catch (const gparams::exception &) {
|
||||||
ctx.print_unsupported(opt, m_line, m_pos);
|
ctx.print_unsupported(opt, m_line, m_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1525,7 +1525,12 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
catch (z3_exception & ex) {
|
catch (z3_exception & ex) {
|
||||||
m_solver->set_reason_unknown(ex.msg());
|
if (m().canceled()) {
|
||||||
|
m_solver->set_reason_unknown(eh);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_solver->set_reason_unknown(ex.msg());
|
||||||
|
}
|
||||||
r = l_undef;
|
r = l_undef;
|
||||||
}
|
}
|
||||||
m_solver->set_status(r);
|
m_solver->set_status(r);
|
||||||
|
|
|
@ -64,7 +64,6 @@ Notes:
|
||||||
#include "opt/opt_params.hpp"
|
#include "opt/opt_params.hpp"
|
||||||
#include "opt/maxsmt.h"
|
#include "opt/maxsmt.h"
|
||||||
#include "opt/maxres.h"
|
#include "opt/maxres.h"
|
||||||
// #include "opt/mss.h"
|
|
||||||
|
|
||||||
using namespace opt;
|
using namespace opt;
|
||||||
|
|
||||||
|
|
|
@ -182,27 +182,6 @@ namespace opt {
|
||||||
void get_hard_constraints(expr_ref_vector& hard);
|
void get_hard_constraints(expr_ref_vector& hard);
|
||||||
expr_ref get_objective(unsigned i);
|
expr_ref get_objective(unsigned i);
|
||||||
|
|
||||||
#if 0
|
|
||||||
virtual void push();
|
|
||||||
virtual void pop(unsigned n);
|
|
||||||
virtual bool empty() { return m_scoped_state.m_objectives.empty(); }
|
|
||||||
virtual void set_hard_constraints(ptr_vector<expr> & hard);
|
|
||||||
virtual lbool optimize();
|
|
||||||
virtual void set_model(model_ref& _m) { m_model = _m; }
|
|
||||||
virtual void get_model_core(model_ref& _m);
|
|
||||||
virtual void get_box_model(model_ref& _m, unsigned index);
|
|
||||||
virtual void fix_model(model_ref& _m);
|
|
||||||
virtual void collect_statistics(statistics& stats) const;
|
|
||||||
virtual proof* get_proof() { return 0; }
|
|
||||||
virtual void get_labels(svector<symbol> & r);
|
|
||||||
virtual void get_unsat_core(ptr_vector<expr> & r);
|
|
||||||
virtual std::string reason_unknown() const;
|
|
||||||
virtual void set_reason_unknown(char const* msg) { m_unknown = msg; }
|
|
||||||
|
|
||||||
virtual void display_assignment(std::ostream& out);
|
|
||||||
virtual bool is_pareto() { return m_pareto.get() != 0; }
|
|
||||||
virtual void set_logic(symbol const& s) { m_logic = s; }
|
|
||||||
#endif
|
|
||||||
void push() override;
|
void push() override;
|
||||||
void pop(unsigned n) override;
|
void pop(unsigned n) override;
|
||||||
bool empty() override { return m_scoped_state.m_objectives.empty(); }
|
bool empty() override { return m_scoped_state.m_objectives.empty(); }
|
||||||
|
@ -244,16 +223,6 @@ namespace opt {
|
||||||
expr_ref mk_ge(unsigned i, model_ref& model) override;
|
expr_ref mk_ge(unsigned i, model_ref& model) override;
|
||||||
expr_ref mk_le(unsigned i, model_ref& model) override;
|
expr_ref mk_le(unsigned i, model_ref& model) override;
|
||||||
|
|
||||||
#if 0
|
|
||||||
virtual smt::context& smt_context() { return m_opt_solver->get_context(); }
|
|
||||||
virtual bool sat_enabled() const { return 0 != m_sat_solver.get(); }
|
|
||||||
virtual solver& get_solver();
|
|
||||||
virtual ast_manager& get_manager() const { return this->m; }
|
|
||||||
virtual params_ref& params() { return m_params; }
|
|
||||||
virtual void enable_sls(bool force);
|
|
||||||
virtual symbol const& maxsat_engine() const { return m_maxsat_engine; }
|
|
||||||
virtual void get_base_model(model_ref& _m);
|
|
||||||
#endif
|
|
||||||
generic_model_converter& fm() override { return *m_fm; }
|
generic_model_converter& fm() override { return *m_fm; }
|
||||||
smt::context& smt_context() override { return m_opt_solver->get_context(); }
|
smt::context& smt_context() override { return m_opt_solver->get_context(); }
|
||||||
bool sat_enabled() const override { return nullptr != m_sat_solver.get(); }
|
bool sat_enabled() const override { return nullptr != m_sat_solver.get(); }
|
||||||
|
|
|
@ -207,7 +207,7 @@ public:
|
||||||
}
|
}
|
||||||
catch (z3_exception& ex) {
|
catch (z3_exception& ex) {
|
||||||
if (get_manager().canceled()) {
|
if (get_manager().canceled()) {
|
||||||
set_reason_unknown(Z3_CANCELED_MSG);
|
throw;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_reason_unknown(ex.msg());
|
set_reason_unknown(ex.msg());
|
||||||
|
|
Loading…
Reference in a new issue