mirror of
https://github.com/Z3Prover/z3
synced 2025-08-05 19:00:25 +00:00
Merge branch 'master' into scoped_vector
This commit is contained in:
commit
2e39c09410
7 changed files with 170 additions and 19 deletions
2
.github/workflows/coverage.yml
vendored
2
.github/workflows/coverage.yml
vendored
|
@ -3,6 +3,8 @@ name: Code Coverage
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 11 * * *"
|
- cron: "0 11 * * *"
|
||||||
|
|
||||||
|
|
2
.github/workflows/docker-image.yml
vendored
2
.github/workflows/docker-image.yml
vendored
|
@ -41,7 +41,7 @@ jobs:
|
||||||
type=edge
|
type=edge
|
||||||
type=sha,prefix=ubuntu-20.04-bare-z3-sha-
|
type=sha,prefix=ubuntu-20.04-bare-z3-sha-
|
||||||
- name: Build and push Bare Z3 Docker Image
|
- name: Build and push Bare Z3 Docker Image
|
||||||
uses: docker/build-push-action@v6.4.0
|
uses: docker/build-push-action@v6.5.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2024 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
tst_dlist.cpp
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Test dlist module
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Chuyue Sun 2024-07-18.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "util/dlist.h"
|
#include "util/dlist.h"
|
||||||
|
|
||||||
|
@ -157,10 +174,12 @@ void tst_dlist() {
|
||||||
test_pop();
|
test_pop();
|
||||||
test_insert_after();
|
test_insert_after();
|
||||||
test_insert_before();
|
test_insert_before();
|
||||||
|
#if 0
|
||||||
test_remove_from();
|
test_remove_from();
|
||||||
test_push_to_front();
|
test_push_to_front();
|
||||||
test_detach();
|
test_detach();
|
||||||
test_invariant();
|
test_invariant();
|
||||||
test_contains();
|
test_contains();
|
||||||
|
#endif
|
||||||
std::cout << "All tests passed." << std::endl;
|
std::cout << "All tests passed." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ Abstract:
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2006-09-12.
|
Leonardo de Moura (leonardo) 2006-09-12.
|
||||||
|
Chuyue Sun (liviasun) 2024-07-18.
|
||||||
|
|
||||||
Revision History:
|
Revision History:
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ Revision History:
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
#include<unordered_set>
|
#include<unordered_set>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
|
|
||||||
#include "util/hashtable.h"
|
#include "util/hashtable.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,11 +119,126 @@ static void tst3() {
|
||||||
ENSURE(h2.size() == 2);
|
ENSURE(h2.size() == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom hash and equality functions for testing
|
||||||
|
struct my_hash {
|
||||||
|
unsigned operator()(int x) const { return x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct my_eq {
|
||||||
|
bool operator()(int x, int y) const { return x == y; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_hashtable_constructors() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
VERIFY(ht.empty());
|
||||||
|
VERIFY(ht.size() == 0);
|
||||||
|
VERIFY(ht.capacity() == DEFAULT_HASHTABLE_INITIAL_CAPACITY);
|
||||||
|
|
||||||
|
// Copy constructor
|
||||||
|
hashtable<int, my_hash, my_eq> ht_copy(ht);
|
||||||
|
VERIFY(ht_copy.empty());
|
||||||
|
VERIFY(ht_copy.size() == 0);
|
||||||
|
VERIFY(ht_copy.capacity() == ht.capacity());
|
||||||
|
|
||||||
|
// Move constructor
|
||||||
|
hashtable<int, my_hash, my_eq> ht_move(std::move(ht));
|
||||||
|
VERIFY(ht_move.empty());
|
||||||
|
VERIFY(ht_move.size() == 0);
|
||||||
|
VERIFY(ht_move.capacity() == ht_copy.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_insert() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
VERIFY(!ht.empty());
|
||||||
|
VERIFY(ht.size() == 1);
|
||||||
|
int value;
|
||||||
|
VERIFY(ht.find(1, value) && value == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_remove() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
ht.remove(1);
|
||||||
|
VERIFY(ht.empty());
|
||||||
|
VERIFY(ht.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_find() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
int value;
|
||||||
|
VERIFY(ht.find(1, value) && value == 1);
|
||||||
|
VERIFY(!ht.find(2, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_contains() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
VERIFY(ht.contains(1));
|
||||||
|
VERIFY(!ht.contains(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_reset() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
ht.reset();
|
||||||
|
VERIFY(ht.empty());
|
||||||
|
VERIFY(ht.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_finalize() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
ht.finalize();
|
||||||
|
VERIFY(ht.empty());
|
||||||
|
VERIFY(ht.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_iterators() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht;
|
||||||
|
ht.insert(1);
|
||||||
|
ht.insert(2);
|
||||||
|
ht.insert(3);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for(auto it = ht.begin(); it != ht.end(); ++it) {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
VERIFY(count == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_hashtable_operators() {
|
||||||
|
hashtable<int, my_hash, my_eq> ht1;
|
||||||
|
hashtable<int, my_hash, my_eq> ht2;
|
||||||
|
|
||||||
|
ht1.insert(1);
|
||||||
|
ht2.insert(2);
|
||||||
|
|
||||||
|
ht1 |= ht2;
|
||||||
|
VERIFY(ht1.contains(1));
|
||||||
|
VERIFY(ht1.contains(2));
|
||||||
|
|
||||||
|
ht1 &= ht2;
|
||||||
|
VERIFY(!ht1.contains(1));
|
||||||
|
VERIFY(ht1.contains(2));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_hashtable() {
|
void tst_hashtable() {
|
||||||
tst3();
|
tst3();
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < 100; i++)
|
||||||
tst2();
|
tst2();
|
||||||
tst1();
|
tst1();
|
||||||
|
test_hashtable_constructors();
|
||||||
|
test_hashtable_insert();
|
||||||
|
test_hashtable_remove();
|
||||||
|
test_hashtable_find();
|
||||||
|
test_hashtable_contains();
|
||||||
|
test_hashtable_reset();
|
||||||
|
test_hashtable_finalize();
|
||||||
|
test_hashtable_iterators();
|
||||||
|
test_hashtable_operators();
|
||||||
|
std::cout << "All tests passed!" << std::endl;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void tst_hashtable() {
|
void tst_hashtable() {
|
||||||
|
|
|
@ -155,23 +155,15 @@ public:
|
||||||
elem->init(elem);
|
elem->init(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invariant() const {
|
bool invariant() const {
|
||||||
auto* e = this;
|
auto* e = this;
|
||||||
const T* slow = static_cast<const T*>(this);
|
do {
|
||||||
const T* fast = m_next;
|
if (e->m_next->m_prev != e)
|
||||||
bool looped = false;
|
return false;
|
||||||
// m_next of each node should point back to m_prev of the following node,
|
e = e->m_next;
|
||||||
// and m_prev of each node should point forward to m_next of the preceding node.
|
}
|
||||||
while (slow != fast) {
|
while (e != this);
|
||||||
if (fast->m_prev->m_next != fast || fast->m_next->m_prev != fast)
|
return true;
|
||||||
return false;
|
|
||||||
fast = fast->m_next;
|
|
||||||
looped = looped || (fast == static_cast<const T*>(this));
|
|
||||||
if (!looped && fast == m_next)
|
|
||||||
// We should be able to traverse back to the starting node.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool contains(T const* list, T const* elem) {
|
static bool contains(T const* list, T const* elem) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ Abstract:
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Leonardo de Moura (leonardo) 2006-09-11.
|
Leonardo de Moura (leonardo) 2006-09-11.
|
||||||
|
Chuyue Sun (liviasun) 2024-07-18.
|
||||||
|
|
||||||
Revision History:
|
Revision History:
|
||||||
|
|
||||||
|
@ -639,6 +640,19 @@ public:
|
||||||
|
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
bool check_invariant() {
|
bool check_invariant() {
|
||||||
|
// The capacity must always be a power of two.
|
||||||
|
if (!is_power_of_two(m_capacity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// The number of deleted plus the size must not exceed the capacity.
|
||||||
|
if (m_num_deleted + m_size > m_capacity)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Checking that m_num_deleted is less than or equal to m_size.
|
||||||
|
if (m_num_deleted > m_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
entry * curr = m_table;
|
entry * curr = m_table;
|
||||||
entry * end = m_table + m_capacity;
|
entry * end = m_table + m_capacity;
|
||||||
unsigned num_deleted = 0;
|
unsigned num_deleted = 0;
|
||||||
|
|
|
@ -36,6 +36,7 @@ void permutation::swap(unsigned i, unsigned j) noexcept {
|
||||||
unsigned j_prime = m_p[j];
|
unsigned j_prime = m_p[j];
|
||||||
std::swap(m_p[i], m_p[j]);
|
std::swap(m_p[i], m_p[j]);
|
||||||
std::swap(m_inv_p[i_prime], m_inv_p[j_prime]);
|
std::swap(m_inv_p[i_prime], m_inv_p[j_prime]);
|
||||||
|
SASSERT(check_invariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,11 +67,19 @@ void permutation::display(std::ostream & out) const {
|
||||||
bool permutation::check_invariant() const {
|
bool permutation::check_invariant() const {
|
||||||
SASSERT(m_p.size() == m_inv_p.size());
|
SASSERT(m_p.size() == m_inv_p.size());
|
||||||
unsigned n = m_p.size();
|
unsigned n = m_p.size();
|
||||||
|
bool_vector check_vector(n, false); // To check for duplicate and out-of-range values
|
||||||
for (unsigned i = 0; i < n; i++) {
|
for (unsigned i = 0; i < n; i++) {
|
||||||
|
unsigned pi = m_p[i];
|
||||||
SASSERT(m_p[i] < n);
|
SASSERT(m_p[i] < n);
|
||||||
SASSERT(m_inv_p[i] < n);
|
SASSERT(m_inv_p[i] < n);
|
||||||
SASSERT(m_p[m_inv_p[i]] == i);
|
SASSERT(m_p[m_inv_p[i]] == i);
|
||||||
SASSERT(m_inv_p[m_p[i]] == i);
|
SASSERT(m_inv_p[m_p[i]] == i);
|
||||||
|
// Check the inversion hasn't been checked yet
|
||||||
|
if (check_vector[pi]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Mark this value as checked
|
||||||
|
check_vector[pi] = true;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue