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

Merge remote-tracking branch 'origin/master' into poly

This commit is contained in:
Jakob Rath 2024-02-26 11:46:22 +01:00
commit 183e911a79
260 changed files with 4131 additions and 3248 deletions

View file

@ -161,8 +161,12 @@ protected:
unsigned curr_cellar = (m_capacity - m_slots);
unsigned new_slots = m_slots * 2;
unsigned new_cellar = curr_cellar * 2;
if (new_slots < m_slots || new_cellar < curr_cellar)
throw default_exception("table overflow");
while (true) {
unsigned new_capacity = new_slots + new_cellar;
if (new_capacity < new_slots)
throw default_exception("table overflow");
cell * new_table = alloc_table(new_capacity);
cell * next_cell = copy_table(m_table, m_slots, m_capacity,
new_table, new_slots, new_capacity,
@ -179,6 +183,8 @@ protected:
return;
}
dealloc_vect(new_table, new_capacity);
if (2*new_cellar < new_cellar)
throw default_exception("table overflow");
new_cellar *= 2;
}
}

View file

@ -188,14 +188,14 @@ class dll_iterator {
dll_iterator(T const* elem, bool first): m_elem(elem), m_first(first) { }
public:
static dll_iterator mk_begin(T const* elem) {
// Setting first==(bool)elem makes this also work for elem==nullptr;
static dll_iterator mk_begin(T const* list) {
// Setting first==(bool)list makes this also work for list==nullptr;
// but we can't implement top-level begin/end for pointers because it clashes with the definition for arrays.
return {elem, (bool)elem};
return {list, (bool)list};
}
static dll_iterator mk_end(T const* elem) {
return {elem, false};
static dll_iterator mk_end(T const* list) {
return {list, false};
}
using value_type = T;
@ -232,18 +232,17 @@ public:
dll_iterator<T> end() const { return dll_iterator<T>::mk_end(m_list); }
};
template < typename T
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
>
dll_iterator<T> begin(T const& elem) {
return dll_iterator<T>::mk_begin(&elem);
dll_iterator<T> begin(T const& list) {
return dll_iterator<T>::mk_begin(&list);
}
template < typename T
, typename U = std::enable_if_t<std::is_base_of_v<dll_base<T>, T>> // should only match if T actually inherits from dll_base<T>
>
dll_iterator<T> end(T const& elem)
dll_iterator<T> end(T const& list)
{
return dll_iterator<T>::mk_end(&elem);
return dll_iterator<T>::mk_end(&list);
}

View file

@ -21,24 +21,20 @@ Revision History:
#include "util/buffer.h"
#include "util/mpn.h"
#define max(a,b) (((a) > (b)) ? (a) : (b))
typedef uint64_t mpn_double_digit;
static_assert(sizeof(mpn_double_digit) == 2 * sizeof(mpn_digit), "size alignment");
const mpn_digit mpn_manager::zero = 0;
int mpn_manager::compare(mpn_digit const * a, unsigned lnga,
mpn_digit const * b, unsigned lngb) const {
int res = 0;
trace(a, lnga);
unsigned j = max(lnga, lngb);
unsigned j = std::max(lnga, lngb);
for (; j-- > 0 && res == 0;) {
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
if (u_j > v_j)
mpn_digit u_j = (j < lnga) ? a[j] : 0;
mpn_digit v_j = (j < lngb) ? b[j] : 0;
if (u_j > v_j)
res = 1;
else if (u_j < v_j)
res = -1;
@ -56,14 +52,14 @@ bool mpn_manager::add(mpn_digit const * a, unsigned lnga,
unsigned * plngc) const {
trace(a, lnga, b, lngb, "+");
// Essentially Knuth's Algorithm A
unsigned len = max(lnga, lngb);
unsigned len = std::max(lnga, lngb);
SASSERT(lngc_alloc == len+1 && len > 0);
mpn_digit k = 0;
mpn_digit r;
bool c1, c2;
for (unsigned j = 0; j < len; j++) {
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
mpn_digit u_j = (j < lnga) ? a[j] : 0;
mpn_digit v_j = (j < lngb) ? b[j] : 0;
r = u_j + v_j; c1 = r < u_j;
c[j] = r + k; c2 = c[j] < r;
k = c1 | c2;
@ -81,13 +77,13 @@ bool mpn_manager::sub(mpn_digit const * a, unsigned lnga,
mpn_digit * c, mpn_digit * pborrow) const {
trace(a, lnga, b, lngb, "-");
// Essentially Knuth's Algorithm S
unsigned len = max(lnga, lngb);
unsigned len = std::max(lnga, lngb);
mpn_digit & k = *pborrow; k = 0;
mpn_digit r;
bool c1, c2;
for (unsigned j = 0; j < len; j++) {
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
mpn_digit u_j = (j < lnga) ? a[j] : 0;
mpn_digit v_j = (j < lngb) ? b[j] : 0;
r = u_j - v_j; c1 = r > u_j;
c[j] = r - k; c2 = c[j] > r;
k = c1 | c2;
@ -112,14 +108,14 @@ bool mpn_manager::mul(mpn_digit const * a, unsigned lnga,
c[i] = 0;
for (unsigned j = 0; j < lngb; j++) {
mpn_digit const & v_j = b[j];
mpn_digit v_j = b[j];
if (v_j == 0) { // This branch may be omitted according to Knuth.
c[j+lnga] = 0;
}
else {
k = 0;
for (i = 0; i < lnga; i++) {
mpn_digit const & u_i = a[i];
mpn_digit u_i = a[i];
mpn_double_digit t;
t = ((mpn_double_digit)u_i * (mpn_double_digit)v_j) +
(mpn_double_digit) c[i+j] +
@ -156,15 +152,6 @@ bool mpn_manager::div(mpn_digit const * numer, unsigned lnum,
return false;
}
bool all_zero = true;
for (unsigned i = 0; i < lden && all_zero; i++)
if (denom[i] != zero) all_zero = false;
if (all_zero) {
UNREACHABLE();
return res;
}
SASSERT(denom[lden-1] != 0);
if (lnum == 1 && lden == 1) {

View file

@ -53,7 +53,6 @@ public:
private:
using mpn_sbuffer = sbuffer<mpn_digit>;
static const mpn_digit zero;
void display_raw(std::ostream & out, mpn_digit const * a, unsigned lng) const;
unsigned div_normalize(mpn_digit const * numer, unsigned lnum,

View file

@ -47,7 +47,7 @@ class mpq_manager : public mpz_manager<SYNCH> {
void reset_denominator(mpq & a) {
del(a.m_den);
a.m_den.m_val = 1;
a.m_den.set(1);
}
void normalize(mpq & a) {

View file

@ -84,6 +84,7 @@ class mpz {
#else
typedef mpz_t mpz_type;
#endif
protected:
int m_val;
unsigned m_kind:1;
unsigned m_owner:1;
@ -116,6 +117,17 @@ public:
unsigned o = m_owner; m_owner = other.m_owner; other.m_owner = o;
unsigned k = m_kind; m_kind = other.m_kind; other.m_kind = k;
}
void set(int v) {
m_val = v;
m_kind = mpz_small;
}
inline bool is_small() const { return m_kind == mpz_small; }
inline int value() const { SASSERT(is_small()); return m_val; }
inline int sign() const { SASSERT(!is_small()); return m_val; }
};
#ifndef _MP_GMP
@ -242,14 +254,13 @@ class mpz_manager {
mpz m_two64;
static int64_t i64(mpz const & a) { return static_cast<int64_t>(a.m_val); }
static int64_t i64(mpz const & a) { return static_cast<int64_t>(a.value()); }
void set_big_i64(mpz & c, int64_t v);
void set_i64(mpz & c, int64_t v) {
if (v >= INT_MIN && v <= INT_MAX) {
c.m_val = static_cast<int>(v);
c.m_kind = mpz_small;
c.set(static_cast<int>(v));
}
else {
set_big_i64(c, v);
@ -306,25 +317,25 @@ class mpz_manager {
void get_sign_cell(mpz const & a, int & sign, mpz_cell * & cell, mpz_cell* reserve) {
if (is_small(a)) {
if (a.m_val == INT_MIN) {
if (a.value() == INT_MIN) {
sign = -1;
cell = m_int_min.m_ptr;
}
else {
cell = reserve;
cell->m_size = 1;
if (a.m_val < 0) {
if (a.value() < 0) {
sign = -1;
cell->m_digits[0] = -a.m_val;
cell->m_digits[0] = -a.value();
}
else {
sign = 1;
cell->m_digits[0] = a.m_val;
cell->m_digits[0] = a.value();
}
}
}
else {
sign = a.m_val;
sign = a.sign();
cell = a.m_ptr;
}
}
@ -398,7 +409,7 @@ public:
~mpz_manager();
static bool is_small(mpz const & a) { return a.m_kind == mpz_small; }
static bool is_small(mpz const & a) { return a.is_small(); }
static mpz mk_z(int val) { return mpz(val); }
@ -461,7 +472,7 @@ public:
bool eq(mpz const & a, mpz const & b) {
if (is_small(a) && is_small(b)) {
return a.m_val == b.m_val;
return a.value() == b.value();
}
else {
return big_compare(a, b) == 0;
@ -470,7 +481,7 @@ public:
bool lt(mpz const& a, int b) {
if (is_small(a)) {
return a.m_val < b;
return a.value() < b;
}
else {
return lt(a, mpz(b));
@ -479,7 +490,7 @@ public:
bool lt(mpz const & a, mpz const & b) {
if (is_small(a) && is_small(b)) {
return a.m_val < b.m_val;
return a.value() < b.value();
}
else {
return big_compare(a, b) < 0;
@ -526,8 +537,7 @@ public:
void set(mpz & target, mpz const & source) {
if (is_small(source)) {
target.m_val = source.m_val;
target.m_kind = mpz_small;
target.set(source.value());
}
else {
big_set(target, source);
@ -535,8 +545,7 @@ public:
}
void set(mpz & a, int val) {
a.m_val = val;
a.m_kind = mpz_small;
a.set(val);
}
void set(mpz & a, unsigned val) {
@ -554,8 +563,7 @@ public:
void set(mpz & a, uint64_t val) {
if (val < INT_MAX) {
a.m_val = static_cast<int>(val);
a.m_kind = mpz_small;
a.set(static_cast<int>(val));
}
else {
set_big_ui64(a, val);
@ -574,10 +582,7 @@ public:
void reset(mpz & a);
void swap(mpz & a, mpz & b) noexcept {
std::swap(a.m_val, b.m_val);
std::swap(a.m_ptr, b.m_ptr);
auto o = a.m_owner; a.m_owner = b.m_owner; b.m_owner = o;
auto k = a.m_kind; a.m_kind = b.m_kind; b.m_kind = k;
a.swap(b);
}
bool is_uint64(mpz const & a) const;
@ -624,20 +629,20 @@ public:
static bool is_one(mpz const & a) {
#ifndef _MP_GMP
return is_small(a) && a.m_val == 1;
return is_small(a) && a.value() == 1;
#else
if (is_small(a))
return a.m_val == 1;
return a.value() == 1;
return mpz_cmp_si(*a.m_ptr, 1) == 0;
#endif
}
static bool is_minus_one(mpz const & a) {
#ifndef _MP_GMP
return is_small(a) && a.m_val == -1;
return is_small(a) && a.value() == -1;
#else
if (is_small(a))
return a.m_val == -1;
return a.value() == -1;
return mpz_cmp_si(*a.m_ptr, -1) == 0;
#endif
}
@ -712,7 +717,7 @@ public:
bool is_even(mpz const & a) {
if (is_small(a))
return !(a.m_val & 0x1);
return !(a.value() & 0x1);
#ifndef _MP_GMP
return !(0x1 & digits(a)[0]);
#else

View file

@ -99,25 +99,24 @@ struct param_descrs::imp {
return CPK_INVALID;
}
bool split_name(symbol const& name, symbol & prefix, symbol & suffix) const {
bool split_name(symbol const& name, std::string_view & prefix, symbol & suffix) const {
if (name.is_numerical()) return false;
char const* str = name.bare_str();
char const* period = strchr(str,'.');
if (!period) return false;
svector<char> prefix_((unsigned)(period-str), str);
prefix_.push_back(0);
prefix = symbol(prefix_.data());
prefix = std::string_view(str, period - str);
suffix = symbol(period + 1);
return true;
}
param_kind get_kind_in_module(symbol & name) const {
param_kind k = get_kind(name);
symbol prefix, suffix;
std::string_view prefix;
symbol suffix;
if (k == CPK_INVALID && split_name(name, prefix, suffix)) {
k = get_kind(suffix);
if (k != CPK_INVALID) {
if (symbol(get_module(suffix)) == prefix) {
if (get_module(suffix) == prefix) {
name = suffix;
}
else {
@ -170,8 +169,8 @@ struct param_descrs::imp {
if (names.empty())
return;
if (markdown) {
out << " Parameter | Type | Description | Default\n";
out << " ----------|------|-------------|--------\n";
out << " Parameter | Type | Description | Default\n"
" ----------|------|-------------|--------\n";
}
for (symbol const& name : names) {
for (unsigned i = 0; i < indent; i++) out << " ";
@ -197,16 +196,14 @@ struct param_descrs::imp {
else
out << " (" << d.m_kind << ")";
if (markdown) {
out << " | ";
std::string desc;
for (auto ch : std::string(d.m_descr)) {
out << " | ";
for (auto ch : std::string_view(d.m_descr)) {
switch (ch) {
case '<': desc += "&lt;"; break;
case '>': desc += "&gt;"; break;
default: desc.push_back(ch);
case '<': out << "&lt;"; break;
case '>': out << "&gt;"; break;
default: out << ch; break;
}
}
out << " " << desc;
}
else if (include_descr)
out << " " << d.m_descr;
@ -549,8 +546,7 @@ params_ref::~params_ref() {
m_params->dec_ref();
}
params_ref::params_ref(params_ref const & p):
m_params(nullptr) {
params_ref::params_ref(params_ref const & p) {
set(p);
}

View file

@ -32,12 +32,12 @@ class param_descrs;
class params_ref {
static params_ref g_empty_params_ref;
params * m_params;
params * m_params = nullptr;
void init();
void copy_core(params const * p);
void set(params_ref const& p);
public:
params_ref():m_params(nullptr) {}
params_ref() = default;
params_ref(params_ref const & p);
~params_ref();

View file

@ -30,6 +30,10 @@ class rational {
static synch_mpq_manager & m() { return *g_mpq_manager; }
void display_hex(std::ostream & out, unsigned num_bits) const { SASSERT(is_int()); m().display_hex(out, m_val.numerator(), num_bits); }
void display_bin(std::ostream& out, unsigned num_bits) const { SASSERT(is_int()); m().display_bin(out, m_val.numerator(), num_bits); }
public:
static void initialize();
static void finalize();
@ -96,7 +100,20 @@ public:
void display_smt2(std::ostream & out) const { return m().display_smt2(out, m_val, false); }
void display_hex(std::ostream & out, unsigned num_bits) const { SASSERT(is_int()); return m().display_hex(out, m_val.numerator(), num_bits); }
struct as_hex_wrapper {
rational const& r;
unsigned bw;
};
as_hex_wrapper as_hex(unsigned bw) const { return as_hex_wrapper{*this, bw}; }
friend inline std::ostream& operator<<(std::ostream& out, as_hex_wrapper const& ab) {
ab.r.display_hex(out, ab.bw);
return out;
}
struct as_bin_wrapper {
rational const& r;
@ -110,7 +127,6 @@ public:
return out;
}
std::ostream& display_bin(std::ostream& out, unsigned num_bits) const { SASSERT(is_int()); m().display_bin(out, m_val.numerator(), num_bits); return out; }
bool is_uint64() const { return m().is_uint64(m_val); }

View file

@ -30,7 +30,7 @@ namespace sat {
typedef svector<bool_var> bool_var_vector;
const bool_var null_bool_var = UINT_MAX >> 1;
inline constexpr bool_var null_bool_var = UINT_MAX >> 1;
/**
\brief The literal b is represented by the value 2*b, and
@ -39,9 +39,7 @@ namespace sat {
class literal {
unsigned m_val;
public:
literal():m_val(null_bool_var << 1) {
SASSERT(var() == null_bool_var && !sign());
}
constexpr literal(): m_val(null_bool_var << 1) { }
explicit literal(bool_var v, bool _sign = false):
m_val((v << 1) + static_cast<unsigned>(_sign)) {
@ -49,11 +47,11 @@ namespace sat {
SASSERT(sign() == _sign);
}
bool_var var() const {
constexpr bool_var var() const {
return m_val >> 1;
}
bool sign() const {
constexpr bool sign() const {
return m_val & 1ul;
}
@ -86,7 +84,10 @@ namespace sat {
friend bool operator!=(literal const & l1, literal const & l2);
};
const literal null_literal;
inline constexpr literal null_literal;
static_assert(null_literal.var() == null_bool_var);
static_assert(!null_literal.sign());
using literal_hash = obj_hash<literal>;
inline literal to_literal(unsigned x) { literal l; l.m_val = x; return l; }

View file

@ -28,8 +28,8 @@ private:
numeral m_num;
public:
_scoped_numeral(Manager & m):m_manager(m) {}
_scoped_numeral(_scoped_numeral const & n):m_manager(n.m_manager) { m().set(m_num, n.m_num); }
_scoped_numeral(_scoped_numeral &&) = default;
_scoped_numeral(_scoped_numeral const& n) :m_manager(n.m_manager) { m().set(m_num, n.m_num); }
_scoped_numeral(_scoped_numeral && n) noexcept: m_manager(n.m_manager) { m().swap(m_num, n.m_num); }
~_scoped_numeral() { m_manager.del(m_num); }
Manager & m() const { return m_manager; }

View file

@ -26,11 +26,11 @@ Notes:
#endif
struct sexpr_composite : public sexpr {
unsigned m_num_chilren;
unsigned m_num_children;
sexpr * m_children[0];
sexpr_composite(unsigned num_children, sexpr * const * children, unsigned line, unsigned pos):
sexpr(kind_t::COMPOSITE, line, pos),
m_num_chilren(num_children) {
m_num_children(num_children) {
for (unsigned i = 0; i < num_children; i++) {
m_children[i] = children[i];
children[i]->inc_ref();
@ -107,7 +107,7 @@ std::string const & sexpr::get_string() const {
unsigned sexpr::get_num_children() const {
SASSERT(is_composite());
return static_cast<sexpr_composite const *>(this)->m_num_chilren;
return static_cast<sexpr_composite const *>(this)->m_num_children;
}
sexpr * sexpr::get_child(unsigned idx) const {

View file

@ -1,31 +0,0 @@
/*
Copyright (c) 2018 Microsoft Corporation
Module Name:
nat_set.h
Abstract:
Wrapper for sstream.
Author:
Leonardo de Moura (leonardo) 2013
Revision History:
*/
#pragma once
#include <sstream>
#include <string>
namespace lean {
/** \brief Wrapper for std::ostringstream */
class sstream {
std::ostringstream m_strm;
public:
std::string str() const { return m_strm.str(); }
template<typename T> sstream & operator<<(T const & t) { m_strm << t; return *this; }
};
}

View file

@ -142,12 +142,8 @@ void tbv_manager::set(tbv& dst, rational const& r, unsigned hi, unsigned lo) {
set(dst, r.get_uint64(), hi, lo);
return;
}
for (unsigned i = 0; i < hi - lo + 1; ++i) {
if (bitwise_and(r, rational::power_of_two(i)).is_zero())
set(dst, lo + i, BIT_0);
else
set(dst, lo + i, BIT_1);
}
for (unsigned i = 0; i < hi - lo + 1; ++i)
set(dst, lo + i, r.get_bit(i) ? BIT_1 : BIT_0);
}
void tbv_manager::set(tbv& dst, tbv const& other, unsigned hi, unsigned lo) {

View file

@ -21,6 +21,7 @@ Revision History:
#include <cstdint>
#include "util/machine.h"
#include "util/debug.h"
#define TAG_SHIFT PTR_ALIGNMENT
#define ALIGNMENT_VALUE (1 << PTR_ALIGNMENT)
@ -42,4 +43,22 @@ Revision History:
#define UNBOXINT(PTR) static_cast<int>(reinterpret_cast<uintptr_t>(PTR) >> PTR_ALIGNMENT)
template <typename U, typename T>
U unbox(T* ptr) {
return static_cast<U>(reinterpret_cast<std::uintptr_t>(ptr) >> PTR_ALIGNMENT);
}
template <typename T>
unsigned get_tag(T* ptr) {
return reinterpret_cast<std::uintptr_t>(ptr) & TAG_MASK;
}
template <typename T, typename U>
T* box(U val, std::uintptr_t tag = 0) {
static_assert( sizeof(T*) >= sizeof(U) + PTR_ALIGNMENT );
SASSERT_EQ(tag & PTR_MASK, 0);
T* ptr = reinterpret_cast<T*>((static_cast<std::uintptr_t>(val) << PTR_ALIGNMENT) | tag);
SASSERT_EQ(val, unbox<U>(ptr)); // roundtrip of conversion integer -> pointer -> integer is not actually guaranteed by the C++ standard (but seems fine in practice, as indicated by previous usage of BOXINT/UNBOXINT)
SASSERT_EQ(tag, get_tag(ptr));
return ptr;
}

View file

@ -35,7 +35,7 @@ private:
_trail_stack m_stack;
};
template<typename Ctx = union_find_default_ctx, typename StackCtx = Ctx>
template<typename Ctx = union_find_default_ctx>
class union_find {
Ctx & m_ctx;
trail_stack & m_trail_stack;

View file

@ -30,6 +30,7 @@ Revision History:
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>
#include "util/memory_manager.h"
#include "util/hash.h"
#include "util/z3_exception.h"
@ -563,7 +564,7 @@ public:
for(; pos != e; ++pos, ++prev) {
*prev = std::move(*pos);
}
reinterpret_cast<SZ *>(m_data)[SIZE_IDX]--;
pop_back();
}
void erase(T const & elem) {
@ -573,6 +574,20 @@ public:
}
}
/** Erase all elements that satisfy the given predicate. Returns the number of erased elements. */
template <typename UnaryPredicate>
SZ erase_if(UnaryPredicate should_erase) {
iterator i = begin();
iterator const e = end();
for (iterator j = begin(); j != e; ++j)
if (!should_erase(std::as_const(*j)))
*(i++) = std::move(*j);
SZ const count = e - i;
SASSERT_EQ(i - begin(), size() - count);
shrink(size() - count);
return count;
}
void shrink(SZ s) {
if (m_data) {
SASSERT(s <= reinterpret_cast<SZ *>(m_data)[SIZE_IDX]);
@ -762,7 +777,8 @@ using bool_vector = svector<bool>;
template<typename T>
inline std::ostream& operator<<(std::ostream& out, svector<T> const& v) {
for (unsigned u : v) out << u << " ";
for (auto const& x : v)
out << x << " ";
return out;
}

View file

@ -152,7 +152,7 @@ std::string zstring::encode() const {
unsigned ch = m_buffer[i];
if (ch < 32 || ch >= 128 || ('\\' == ch && i + 1 < m_buffer.size() && 'u' == m_buffer[i+1])) {
_flush();
strm << "\\u{" << std::hex << ch << std::dec << "}";
strm << "\\u{" << std::hex << ch << std::dec << '}';
}
else {
if (offset == 99)
@ -161,7 +161,7 @@ std::string zstring::encode() const {
}
}
_flush();
return strm.str();
return std::move(strm).str();
}
bool zstring::suffixof(zstring const& other) const {