3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

Merge branch 'master' into polysat

This commit is contained in:
Jakob Rath 2023-07-10 09:45:55 +02:00
commit 59c3234fb8
196 changed files with 4705 additions and 4168 deletions

View file

@ -370,7 +370,7 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) {
if (is_real) {
return m_manager->mk_func_decl(symbol("^0"), m_real_decl, m_real_decl, m_real_decl, func_decl_info(m_family_id, OP_POWER0));
}
return m_manager->mk_func_decl(symbol("^0"), m_int_decl, m_int_decl, m_int_decl, func_decl_info(m_family_id, OP_POWER0));
return m_manager->mk_func_decl(symbol("^0"), m_int_decl, m_int_decl, m_real_decl, func_decl_info(m_family_id, OP_POWER0));
case OP_TO_REAL: return m_to_real_decl;
case OP_TO_INT: return m_to_int_decl;
case OP_IS_INT: return m_is_int_decl;
@ -834,7 +834,7 @@ bool arith_util::is_considered_uninterpreted(func_decl* f, unsigned n, expr* con
func_decl* arith_util::mk_ipower0() {
sort* s = mk_int();
sort* rs[2] = { s, s };
return m_manager.mk_func_decl(arith_family_id, OP_POWER0, 0, nullptr, 2, rs, s);
return m_manager.mk_func_decl(arith_family_id, OP_POWER0, 0, nullptr, 2, rs, mk_real());
}
func_decl* arith_util::mk_rpower0() {

View file

@ -1378,6 +1378,7 @@ void ast_manager::init() {
ENSURE(model_value_family_id == mk_family_id("model-value"));
ENSURE(user_sort_family_id == mk_family_id("user-sort"));
ENSURE(arith_family_id == mk_family_id("arith"));
ENSURE(poly_family_id == mk_family_id("polymorphic"));
basic_decl_plugin * plugin = alloc(basic_decl_plugin);
register_plugin(basic_family_id, plugin);
m_bool_sort = plugin->mk_bool_sort();
@ -2019,6 +2020,11 @@ sort * ast_manager::mk_uninterpreted_sort(symbol const & name, unsigned num_para
return plugin->mk_sort(kind, num_parameters, parameters);
}
sort * ast_manager::mk_type_var(symbol const& name) {
sort_info si(poly_family_id, 0);
return mk_sort(name, &si);
}
func_decl * ast_manager::mk_func_decl(symbol const & name, unsigned arity, sort * const * domain, sort * range,
bool assoc, bool comm, bool inj) {
func_decl_info info(null_family_id, null_decl_kind);

View file

@ -85,6 +85,7 @@ const family_id user_sort_family_id = 4;
const family_id last_builtin_family_id = 4;
const family_id arith_family_id = 5;
const family_id poly_family_id = 6;
// -----------------------------------
//
@ -622,6 +623,7 @@ public:
sort_size const & get_num_elements() const { return get_info()->get_num_elements(); }
void set_num_elements(sort_size const& s) { get_info()->set_num_elements(s); }
unsigned get_size() const { return get_obj_size(); }
bool is_type_var() const { return get_family_id() == poly_family_id; }
};
// -----------------------------------
@ -1709,6 +1711,8 @@ public:
sort * mk_uninterpreted_sort(symbol const & name) { return mk_uninterpreted_sort(name, 0, nullptr); }
sort * mk_type_var(symbol const& name);
sort * mk_sort(symbol const & name, sort_info const & info) {
if (info.get_family_id() == null_family_id) {
return mk_uninterpreted_sort(name);

View file

@ -651,7 +651,7 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
for (unsigned i = 0; i < num_args; ++i) {
if (args[i]->get_sort() != r->get_domain(i)) {
std::ostringstream buffer;
buffer << "Argument " << mk_pp(args[i], m) << " at position " << i << " has sort " << mk_pp(args[i]->get_sort(), m) << " it does does not match declaration " << mk_pp(r, m);
buffer << "Argument " << mk_pp(args[i], m) << " at position " << i << " has sort " << mk_pp(args[i]->get_sort(), m) << " it does not match declaration " << mk_pp(r, m);
m.raise_exception(buffer.str());
return nullptr;
}

View file

@ -96,7 +96,7 @@ enum bv_op_kind {
OP_BUMUL_OVFL, // unsigned multiplication overflow predicate (negation of OP_BUMUL_NO_OVFL)
OP_BSMUL_OVFL, // signed multiplication over/underflow predicate
OP_BSDIV_OVFL, // signed division overflow perdicate
OP_BSDIV_OVFL, // signed division overflow predicate
OP_BNEG_OVFL, // negation overflow predicate

View file

@ -7,7 +7,7 @@ Module Name:
Abstract:
char_plugin for unicode suppport
char_plugin for unicode support
Author:

View file

@ -7,7 +7,7 @@ Module Name:
Abstract:
char_plugin for unicode suppport
char_plugin for unicode support
Author:

View file

@ -78,7 +78,7 @@ public:
*
* x = t -> fresh
* x := if(fresh, t, diff(t))
* where diff is a diagnonalization function available in domains of size > 1.
* where diff is a diagonalization function available in domains of size > 1.
*
*/
@ -807,7 +807,7 @@ bool iexpr_inverter::uncnstr(unsigned num, expr * const * args) const {
/**
\brief Create a fresh variable for abstracting (f args[0] ... args[num-1])
Return true if it a new variable was created, and false if the variable already existed for this
Return true if a new variable was created, and false if the variable already existed for this
application. Store the variable in v
*/
void iexpr_inverter::mk_fresh_uncnstr_var_for(sort * s, expr_ref & v) {

View file

@ -275,7 +275,7 @@ namespace datatype {
}
parameter const & name = parameters[0];
if (!name.is_symbol()) {
TRACE("datatype", tout << "expected symol parameter at position " << 0 << " got: " << name << "\n";);
TRACE("datatype", tout << "expected symbol parameter at position " << 0 << " got: " << name << "\n";);
throw invalid_datatype();
}
for (unsigned i = 1; i < num_parameters; ++i) {

View file

@ -52,7 +52,7 @@ namespace datatype {
class accessor {
symbol m_name;
sort_ref m_range;
unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are procssed.
unsigned m_index; // reference to recursive data-type may only get resolved after all mutually recursive data-types are processed.
constructor* m_constructor{ nullptr };
public:
accessor(ast_manager& m, symbol const& n, sort* range):

View file

@ -19,7 +19,7 @@ Notes:
- data structures form the (legacy) SMT solver.
- it still uses eager path compression.
NB. The worklist is in reality inheritied from the legacy SMT solver.
NB. The worklist is in reality inherited from the legacy SMT solver.
It is claimed to have the same effect as delayed congruence table reconstruction from egg.
Similar to the legacy solver, parents are partially deduplicated.

View file

@ -16,7 +16,7 @@ Author:
Notes:
- congruence closure justifications are given a timestamp so it is easy to sort them.
See the longer descriptoin in euf_proof_checker.cpp
See the longer description in euf_proof_checker.cpp
--*/

View file

@ -65,7 +65,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, bool deps_valid, expr_de
// functions introduced within macros are Skolem functions
// To avoid unsound expansion of these as macros (because they
// appear in model conversions and are therefore not fully
// replacable) we prevent these from being treated as macro functions.
// replaceable) we prevent these from being treated as macro functions.
if (m_macro_manager.contains(f) || f->is_skolem())
return false;

View file

@ -32,7 +32,7 @@ Revision History:
where T[X] does not contain f.
This class is responsible for storing macros and expanding them.
It has support for backtracking and tagging declarations in an expression as forbidded for being macros.
It has support for backtracking and tagging declarations in an expression as forbidden for being macros.
*/
class macro_manager {
ast_manager & m;

View file

@ -207,7 +207,7 @@ void defined_names::impl::mk_definition(expr * e, app * n, sort_ref_buffer & var
// the instantiation rules for store(a, i, v) are:
// store(a, i, v)[j] = if i = j then v else a[j] with patterns {a[j], store(a, i, v)} { store(a, i, v)[j] }
// The first pattern is not included.
// TBD use a model-based scheme for exracting instantiations instead of
// TBD use a model-based scheme for extracting instantiations instead of
// using multi-patterns.
//

View file

@ -109,6 +109,7 @@ pattern_inference_cfg::pattern_inference_cfg(ast_manager & m, pattern_inference_
m_le(),
m_nested_arith_only(true),
m_block_loop_patterns(params.m_pi_block_loop_patterns),
m_decompose_patterns(params.m_pi_decompose_patterns),
m_candidates(m),
m_pattern_weight_lt(m_candidates_info),
m_collect(m, *this),
@ -407,6 +408,9 @@ bool pattern_inference_cfg::pattern_weight_lt::operator()(expr * n1, expr * n2)
app* pattern_inference_cfg::mk_pattern(app* candidate) {
if (!m_decompose_patterns)
return m.mk_pattern(candidate);
auto has_var_arg = [&](expr* e) {
if (!is_app(e))
return false;

View file

@ -20,6 +20,7 @@ Revision History:
#include "ast/ast.h"
#include "ast/rewriter/rewriter.h"
#include "ast/rewriter/rewriter_def.h"
#include "params/pattern_inference_params.h"
#include "util/vector.h"
#include "util/uint_set.h"
@ -69,6 +70,7 @@ class pattern_inference_cfg : public default_rewriter_cfg {
expr * const * m_no_patterns;
bool m_nested_arith_only;
bool m_block_loop_patterns;
bool m_decompose_patterns;
struct info {
uint_set m_free_vars;

View file

@ -260,7 +260,7 @@ class reduce_hypotheses {
{ cls.push_back(cls_fact->get_arg(i)); }
} else { cls.push_back(cls_fact); }
// construct new resovent
// construct new resolvent
ptr_buffer<expr> new_fact_cls;
bool found;
// XXX quadratic
@ -604,7 +604,7 @@ public:
// -- otherwise, the fact has not changed. nothing to simplify
SASSERT(m.get_fact(tmp) == m.get_fact(m.get_parent(p, i)));
parents.push_back(tmp);
// remember that we have this derivation while we have not poped the trail
// remember that we have this derivation while we have not popped the trail
// but only if the proof is closed (i.e., a real unit)
if (is_closed(tmp) && !m_units.contains(m.get_fact(tmp))) {
m_units.insert(m.get_fact(tmp), tmp);

View file

@ -1121,7 +1121,7 @@ bool arith_rewriter::divides(expr* num, expr* den, expr_ref& result) {
if (m_util.is_numeral(arg, num_r)) num_e = arg;
}
for (expr* arg : args2) {
// dont remove divisor on (div (* -1 x) (* -1 y)) because rewriting would diverge.
// don't remove divisor on (div (* -1 x) (* -1 y)) because rewriting would diverge.
if (mark.is_marked(arg) && (!m_util.is_numeral(arg, num_r) || !num_r.is_minus_one())) {
result = remove_divisor(arg, num, den);
return true;
@ -1569,21 +1569,48 @@ br_status arith_rewriter::mk_to_real_core(expr * arg, expr_ref & result) {
}
br_status arith_rewriter::mk_is_int(expr * arg, expr_ref & result) {
numeral a;
if (m_util.is_numeral(arg, a)) {
result = a.is_int() ? m.mk_true() : m.mk_false();
numeral n;
if (m_util.is_numeral(arg, n)) {
result = n.is_int() ? m.mk_true() : m.mk_false();
return BR_DONE;
}
else if (m_util.is_to_real(arg)) {
if (m_util.is_to_real(arg)) {
result = m.mk_true();
return BR_DONE;
}
else {
result = m.mk_eq(m.mk_app(get_fid(), OP_TO_REAL,
m.mk_app(get_fid(), OP_TO_INT, arg)),
arg);
return BR_REWRITE3;
ptr_buffer<expr> todo;
todo.push_back(arg);
expr_fast_mark1 mark;
for (unsigned i = 0; i < todo.size(); ++i) {
expr* e = todo[i];
if (mark.is_marked(e))
continue;
mark.mark(e, true);
if (m_util.is_to_real(e))
continue;
if (m_util.is_numeral(e, n)) {
if (n.is_int())
continue;
goto bail;
}
if (m_util.is_mul(e) || m_util.is_add(e) || m_util.is_sub(e) || m_util.is_uminus(e)) {
for (expr* a : *to_app(e))
todo.push_back(a);
continue;
}
goto bail;
}
result = m.mk_true();
return BR_DONE;
bail:
result = m.mk_eq(m.mk_app(get_fid(), OP_TO_REAL,
m.mk_app(get_fid(), OP_TO_INT, arg)),
arg);
return BR_REWRITE3;
}
br_status arith_rewriter::mk_abs_core(expr * arg, expr_ref & result) {
@ -1592,7 +1619,7 @@ br_status arith_rewriter::mk_abs_core(expr * arg, expr_ref & result) {
}
// Return true if t is of the form c*Pi where c is a numeral.
// Return true if t is of the form c*Pi where c is a numeral.
// Store c into k
bool arith_rewriter::is_pi_multiple(expr * t, rational & k) {
if (m_util.is_pi(t)) {
@ -1603,7 +1630,7 @@ bool arith_rewriter::is_pi_multiple(expr * t, rational & k) {
return m_util.is_mul(t, a, b) && m_util.is_pi(b) && m_util.is_numeral(a, k);
}
// Return true if t is of the form (+ s c*Pi) where c is a numeral.
// Return true if t is of the form (+ s c*Pi) where c is a numeral.
// Store c into k, and c*Pi into m.
bool arith_rewriter::is_pi_offset(expr * t, rational & k, expr * & m) {
if (m_util.is_add(t)) {
@ -1916,7 +1943,7 @@ br_status arith_rewriter::mk_tan_core(expr * arg, expr_ref & result) {
br_status arith_rewriter::mk_asin_core(expr * arg, expr_ref & result) {
// Remark: we assume that ForAll x : asin(-x) == asin(x).
// Mathematica uses this as an axiom. Although asin is an underspecified function for x < -1 or x > 1.
// Actually, in Mathematica, asin(x) is a total function that returns a complex number fo x < -1 or x > 1.
// Actually, in Mathematica, asin(x) is a total function that returns a complex number for x < -1 or x > 1.
rational k;
if (is_numeral(arg, k)) {
if (k.is_zero()) {

View file

@ -26,6 +26,7 @@ Notes:
void bool_rewriter::updt_params(params_ref const & _p) {
bool_rewriter_params p(_p);
m_flat_and_or = p.flat_and_or();
m_sort_disjunctions = p.sort_disjunctions();
m_elim_and = p.elim_and();
m_elim_ite = p.elim_ite();
m_local_ctx = p.local_ctx();
@ -183,7 +184,7 @@ br_status bool_rewriter::mk_flat_and_core(unsigned num_args, expr * const * args
}
br_status bool_rewriter::mk_nflat_or_core(unsigned num_args, expr * const * args, expr_ref & result) {
bool s = false;
bool s = false; // whether we have canceled some disjuncts or found some out or order
ptr_buffer<expr> buffer;
expr_fast_mark1 neg_lits;
expr_fast_mark2 pos_lits;
@ -292,8 +293,10 @@ br_status bool_rewriter::mk_nflat_or_core(unsigned num_args, expr * const * args
return st;
#endif
if (s) {
ast_lt lt;
std::sort(buffer.begin(), buffer.end(), lt);
if (m_sort_disjunctions) {
ast_lt lt;
std::sort(buffer.begin(), buffer.end(), lt);
}
result = m().mk_or(sz, buffer.data());
return BR_DONE;
}
@ -329,7 +332,7 @@ br_status bool_rewriter::mk_flat_or_core(unsigned num_args, expr * const * args,
}
}
if (mk_nflat_or_core(flat_args.size(), flat_args.data(), result) == BR_FAILED) {
if (!ordered) {
if (m_sort_disjunctions && !ordered) {
ast_lt lt;
std::sort(flat_args.begin(), flat_args.end(), lt);
}
@ -662,12 +665,19 @@ br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result)
SASSERT(m().is_value(val));
if (m().are_distinct(val, e)) {
mk_eq(t, val, result);
if (get_depth(t) < 500)
mk_eq(t, val, result);
else
result = m().mk_eq(t, val);
result = m().mk_and(result, cond);
return BR_REWRITE2;
}
if (m().are_distinct(val, t)) {
mk_eq(e, val, result);
if (get_depth(e) < 500)
mk_eq(e, val, result);
else
result = m().mk_eq(e, val);
result = m().mk_and(result, m().mk_not(cond));
return BR_REWRITE2;
}

View file

@ -53,6 +53,7 @@ class bool_rewriter {
ast_manager & m_manager;
hoist_rewriter m_hoist;
bool m_flat_and_or = false;
bool m_sort_disjunctions = true;
bool m_local_ctx = false;
bool m_elim_and = false;
bool m_blast_distinct = false;

View file

@ -307,7 +307,7 @@ namespace euf {
}
};
SASSERT(e);
if (num_scopes() > 0)
if (num_scopes() > 0 && m_canonical.size() > n->get_id())
m_trail.push(vtrail(m_canonical, n->get_id()));
m_canonical.setx(n->get_id(), e);
m_epochs.setx(n->get_id(), m_epoch, 0);