mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
tested network sorting
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
31e2d823c9
commit
c57594d463
3 changed files with 140 additions and 42 deletions
|
@ -7,7 +7,7 @@
|
|||
|
||||
template <typename Ext>
|
||||
class sorting_network {
|
||||
typename Ext::vector& m_es;
|
||||
typedef typename Ext::vector vect;
|
||||
Ext& m_ext;
|
||||
svector<unsigned> m_currentv;
|
||||
svector<unsigned> m_nextv;
|
||||
|
@ -17,21 +17,21 @@
|
|||
unsigned& current(unsigned i) { return (*m_current)[i]; }
|
||||
unsigned& next(unsigned i) { return (*m_next)[i]; }
|
||||
|
||||
void exchange(unsigned i, unsigned j) {
|
||||
void exchange(unsigned i, unsigned j, vect& out) {
|
||||
SASSERT(i <= j);
|
||||
if (i < j) {
|
||||
Ext::T ei = m_es.get(i);
|
||||
Ext::T ej = m_es.get(j);
|
||||
m_es.set(i, m_ext.mk_ite(m_ext.mk_le(ei, ej), ei, ej));
|
||||
m_es.set(j, m_ext.mk_ite(m_ext.mk_le(ej, ei), ei, ej));
|
||||
Ext::T ei = out.get(i);
|
||||
Ext::T ej = out.get(j);
|
||||
out.set(i, m_ext.mk_ite(m_ext.mk_le(ei, ej), ei, ej));
|
||||
out.set(j, m_ext.mk_ite(m_ext.mk_le(ej, ei), ei, ej));
|
||||
}
|
||||
}
|
||||
|
||||
void sort(unsigned k) {
|
||||
void sort(unsigned k, vect& out) {
|
||||
SASSERT(is_power_of2(k) && k > 0);
|
||||
if (k == 2) {
|
||||
for (unsigned i = 0; i < m_es.size()/2; ++i) {
|
||||
exchange(current(2*i), current(2*i+1));
|
||||
for (unsigned i = 0; i < out.size()/2; ++i) {
|
||||
exchange(current(2*i), current(2*i+1), out);
|
||||
next(2*i) = current(2*i);
|
||||
next(2*i+1) = current(2*i+1);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
|||
}
|
||||
else {
|
||||
|
||||
for (unsigned i = 0; i < m_es.size()/k; ++i) {
|
||||
for (unsigned i = 0; i < out.size()/k; ++i) {
|
||||
unsigned ki = k * i;
|
||||
for (unsigned j = 0; j < k / 2; ++j) {
|
||||
next(ki + j) = current(ki + (2 * j));
|
||||
|
@ -48,8 +48,8 @@
|
|||
}
|
||||
|
||||
std::swap(m_current, m_next);
|
||||
sort(k / 2);
|
||||
for (unsigned i = 0; i < m_es.size() / k; ++i) {
|
||||
sort(k / 2, out);
|
||||
for (unsigned i = 0; i < out.size() / k; ++i) {
|
||||
unsigned ki = k * i;
|
||||
for (unsigned j = 0; j < k / 2; ++j) {
|
||||
next(ki + (2 * j)) = current(ki + j);
|
||||
|
@ -57,7 +57,7 @@
|
|||
}
|
||||
|
||||
for (unsigned j = 0; j < (k / 2) - 1; ++j) {
|
||||
exchange(next(ki + (2 * j) + 1), next(ki + (2 * (j + 1))));
|
||||
exchange(next(ki + (2 * j) + 1), next(ki + (2 * (j + 1))), out);
|
||||
}
|
||||
}
|
||||
std::swap(m_current, m_next);
|
||||
|
@ -69,28 +69,28 @@
|
|||
}
|
||||
|
||||
public:
|
||||
sorting_network(Ext& ext, typename Ext::vector& es):
|
||||
sorting_network(Ext& ext):
|
||||
m_ext(ext),
|
||||
m_es(es),
|
||||
m_current(&m_currentv),
|
||||
m_next(&m_nextv)
|
||||
{}
|
||||
|
||||
void operator()(typename Ext::vector const& inputs) {
|
||||
if (inputs.size() <= 1) {
|
||||
void operator()(vect const& in, vect& out) {
|
||||
if (in.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
m_es.reset();
|
||||
m_es.append(inputs);
|
||||
while (!is_power_of2(m_es.size())) {
|
||||
m_es.push_back(m_ext.mk_default());
|
||||
out.reset();
|
||||
out.append(in);
|
||||
while (!is_power_of2(out.size())) {
|
||||
out.push_back(m_ext.mk_default());
|
||||
}
|
||||
for (unsigned i = 0; i < m_es.size(); ++i) {
|
||||
current(i) = i;
|
||||
for (unsigned i = 0; i < out.size(); ++i) {
|
||||
m_currentv.push_back(i);
|
||||
m_nextv.push_back(i);
|
||||
}
|
||||
unsigned k = 2;
|
||||
while (k <= m_es.size()) {
|
||||
sort(k);
|
||||
while (k <= out.size()) {
|
||||
sort(k, out);
|
||||
k *= 2;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue