mirror of
https://github.com/Z3Prover/z3
synced 2025-06-20 04:43:39 +00:00
adding simple sorting network
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
cf75a7743e
commit
e84c5e7e90
1 changed files with 95 additions and 203 deletions
|
@ -309,7 +309,12 @@ namespace smt {
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
class sorting {
|
class sorting_network {
|
||||||
|
ast_manager& m;
|
||||||
|
expr_ref_vector m_es;
|
||||||
|
expr_ref_vector* m_current;
|
||||||
|
expr_ref_vector* m_next;
|
||||||
|
|
||||||
void exchange(unsigned i, unsigned j, expr_ref_vector& es) {
|
void exchange(unsigned i, unsigned j, expr_ref_vector& es) {
|
||||||
SASSERT(i <= j);
|
SASSERT(i <= j);
|
||||||
if (i == j) {
|
if (i == j) {
|
||||||
|
@ -355,105 +360,99 @@ class sorting {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Term[] Merge(Term[] l1, Term[] l2)
|
expr_ref_vector merge(expr_ref_vector const& l1, expr_ref_vector& l2) {
|
||||||
{
|
if (l1.empty()) {
|
||||||
if (l1.Length == 0)
|
return l2;
|
||||||
{
|
|
||||||
return l2;
|
|
||||||
}
|
|
||||||
else if (l2.Length == 0)
|
|
||||||
{
|
|
||||||
return l1;
|
|
||||||
}
|
|
||||||
else if (l1.Length == 1 && l2.Length == 1)
|
|
||||||
{
|
|
||||||
var merged = new Term[2];
|
|
||||||
merged[0] = l1[0];
|
|
||||||
merged[1] = l2[0];
|
|
||||||
Exchange(0, 1, merged);
|
|
||||||
return merged;
|
|
||||||
}
|
|
||||||
|
|
||||||
var l1o = l1.Length / 2;
|
|
||||||
var l2o = l2.Length / 2;
|
|
||||||
var l1e = (l1.Length % 2 == 1) ? l1o + 1 : l1o;
|
|
||||||
var l2e = (l2.Length % 2 == 1) ? l2o + 1 : l2o;
|
|
||||||
|
|
||||||
Term[] evenl1 = new Term[l1e];
|
|
||||||
Term[] oddl1 = new Term[l1o];
|
|
||||||
for (int i = 0; i < l1.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
evenl1[i / 2] = l1[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oddl1[i / 2] = l1[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Term[] evenl2 = new Term[l2e];
|
|
||||||
Term[] oddl2 = new Term[l2o];
|
|
||||||
for (int i = 0; i < l2.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
evenl2[i / 2] = l2[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oddl2[i / 2] = l2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var even = Merge(evenl1, evenl2);
|
|
||||||
var odd = Merge(oddl1, oddl2);
|
|
||||||
|
|
||||||
Term[] merge = new Term[l1.Length + l2.Length];
|
|
||||||
|
|
||||||
for (int i = 0; i < merge.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
merge[i] = even[i / 2];
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
Exchange(i - 1, i, merge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i / 2 < odd.Length)
|
|
||||||
{
|
|
||||||
merge[i] = odd[i / 2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
merge[i] = even[(i / 2) + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return merge;
|
|
||||||
}
|
}
|
||||||
|
if (l2.empty()) {
|
||||||
|
return l1;
|
||||||
|
}
|
||||||
|
expr_ref_vector result(m);
|
||||||
|
if (l1.size() == 1 && l2.size() == 1) {
|
||||||
|
result.push_back(l1[0]);
|
||||||
|
result.push_back(l2[0]);
|
||||||
|
exchange(0, 1, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
unsigned l1o = l1.size()/2;
|
||||||
|
unsigned l2o = l2.size()/2;
|
||||||
|
unsigned l1e = (l1.size() % 2 == 1) ? l1o + 1 : l1o;
|
||||||
|
unsigned l2e = (l2.size() % 2 == 1) ? l2o + 1 : l2o;
|
||||||
|
expr_ref_vector evenl1(m, l1e);
|
||||||
|
expr_ref_vector oddl1(m, l1o);
|
||||||
|
expr_ref_vector evenl2(m, l2e);
|
||||||
|
expr_ref_vector oddl2(m, l2o);
|
||||||
|
for (unsigned i = 0; i < l1.size(); ++i) {
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
evenl1[i/2] = l1[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oddl1[i/2] = l1[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (unsigned i = 0; i < l2.size(); ++i) {
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
evenl2[i/2] = l2[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oddl2[i/2] = l2[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expr_ref_vector even = merge(evenl1, evenl2);
|
||||||
|
expr_ref_vector odd = merge(oddl1, oddl2);
|
||||||
|
|
||||||
|
result.resize(l1.size() + l2.size());
|
||||||
|
for (unsigned i = 0; i < result.size(); ++i) {
|
||||||
|
if (i % 2 == 0) {
|
||||||
|
result[i] = even[i/2].get();
|
||||||
|
if (i > 0) {
|
||||||
|
exchange(i - 1, i, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (i /2 < odd.size()) {
|
||||||
|
result[i] = odd[i/2].get();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result[i] = even[(i/2)+1].get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
sorting_network(ast_manager& m):
|
||||||
|
m(m),
|
||||||
|
m_es(m),
|
||||||
|
m_current(0),
|
||||||
|
m_next(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
expr_ref_vector operator()(expr_ref_vector const& inputs) {
|
||||||
|
if (inputs.size() <= 1) {
|
||||||
|
return inputs;
|
||||||
|
}
|
||||||
|
m_es.reset();
|
||||||
|
m_es.append(inputs);
|
||||||
|
while (!is_power_of2(m_es.size())) {
|
||||||
|
m_es.push_back(m.mk_false());
|
||||||
|
}
|
||||||
|
m_es.reverse();
|
||||||
|
for (unsigned i = 0; i < m_es.size(); ++i) {
|
||||||
|
current(i) = i;
|
||||||
|
}
|
||||||
|
unsigned k = 2;
|
||||||
|
while (k <= m_es.size()) {
|
||||||
|
sort(k);
|
||||||
|
// TBD
|
||||||
|
k *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Sorting networks used in Formula:
|
Sorting networks used in Formula:
|
||||||
|
|
||||||
namespace Microsoft.Formula.Execution
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics.Contracts;
|
|
||||||
using Microsoft.Z3;
|
|
||||||
|
|
||||||
internal class SortingNetwork
|
|
||||||
{
|
|
||||||
private Term[] elements;
|
|
||||||
private int[] current;
|
|
||||||
private int[] next;
|
|
||||||
|
|
||||||
public SortingNetwork(SymbolicState owner, Term[] inputs, Sort sortingDomain)
|
public SortingNetwork(SymbolicState owner, Term[] inputs, Sort sortingDomain)
|
||||||
{
|
{
|
||||||
Contract.Requires(owner != null && inputs != null && sortingDomain != null);
|
Contract.Requires(owner != null && inputs != null && sortingDomain != null);
|
||||||
|
@ -506,114 +505,7 @@ namespace Microsoft.Formula.Execution
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Term[] Outputs
|
|
||||||
{
|
|
||||||
get { return elements; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Size
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SymbolicState Owner
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void Swap()
|
|
||||||
{
|
|
||||||
var tmp = current;
|
|
||||||
current = next;
|
|
||||||
next = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Term[] Merge(Term[] l1, Term[] l2)
|
|
||||||
{
|
|
||||||
if (l1.Length == 0)
|
|
||||||
{
|
|
||||||
return l2;
|
|
||||||
}
|
|
||||||
else if (l2.Length == 0)
|
|
||||||
{
|
|
||||||
return l1;
|
|
||||||
}
|
|
||||||
else if (l1.Length == 1 && l2.Length == 1)
|
|
||||||
{
|
|
||||||
var merged = new Term[2];
|
|
||||||
merged[0] = l1[0];
|
|
||||||
merged[1] = l2[0];
|
|
||||||
Exchange(0, 1, merged);
|
|
||||||
return merged;
|
|
||||||
}
|
|
||||||
|
|
||||||
var l1o = l1.Length / 2;
|
|
||||||
var l2o = l2.Length / 2;
|
|
||||||
var l1e = (l1.Length % 2 == 1) ? l1o + 1 : l1o;
|
|
||||||
var l2e = (l2.Length % 2 == 1) ? l2o + 1 : l2o;
|
|
||||||
|
|
||||||
Term[] evenl1 = new Term[l1e];
|
|
||||||
Term[] oddl1 = new Term[l1o];
|
|
||||||
for (int i = 0; i < l1.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
evenl1[i / 2] = l1[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oddl1[i / 2] = l1[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Term[] evenl2 = new Term[l2e];
|
|
||||||
Term[] oddl2 = new Term[l2o];
|
|
||||||
for (int i = 0; i < l2.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
evenl2[i / 2] = l2[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
oddl2[i / 2] = l2[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var even = Merge(evenl1, evenl2);
|
|
||||||
var odd = Merge(oddl1, oddl2);
|
|
||||||
|
|
||||||
Term[] merge = new Term[l1.Length + l2.Length];
|
|
||||||
|
|
||||||
for (int i = 0; i < merge.Length; ++i)
|
|
||||||
{
|
|
||||||
if (i % 2 == 0)
|
|
||||||
{
|
|
||||||
merge[i] = even[i / 2];
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
Exchange(i - 1, i, merge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i / 2 < odd.Length)
|
|
||||||
{
|
|
||||||
merge[i] = odd[i / 2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
merge[i] = even[(i / 2) + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return merge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue