1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
#include <stdio.h>
#include <stdlib.h>
#include "boolector.h"
#include "utils/btorutil.h"
int
main (int argc, char **argv)
{
int num_bits, num_bits_index, num_elements, i, num_iterations;
Btor *btor;
BoolectorNode **indices, *array, *eq, *ult, *ulte, *ugt, *temp, *read1;
BoolectorNode *read2, *formula, *val, *index, *found, *sorted, *low, *high;
BoolectorNode *two, *one, *mid, *sub, *udiv, *inc, *dec;
BoolectorSort sort_index, sort_elem, sort_array;
if (argc != 3)
{
printf ("Usage: ./binarysearch <num-bits> <num-elements>\n");
return 1;
}
num_bits = atoi (argv[1]);
if (num_bits <= 0)
{
printf ("Number of bits must be greater than zero\n");
return 1;
}
num_elements = atoi (argv[2]);
if (num_elements < 4)
{
printf ("Number of elements must be at least four\n");
return 1;
}
if (!btor_util_is_power_of_2 (num_elements))
{
printf ("Number of elements must be a power of two\n");
return 1;
}
num_bits_index = btor_util_log_2 (num_elements);
/* binary search needs log2(size(array)) + 1 iterations in the worst case */
num_iterations = num_bits_index + 1;
btor = boolector_new ();
sort_elem = boolector_bitvec_sort (btor, num_bits);
sort_index = boolector_bitvec_sort (btor, num_bits_index);
sort_array = boolector_array_sort (btor, sort_index, sort_elem);
boolector_set_opt (btor, BTOR_OPT_REWRITE_LEVEL, 0);
indices = (BoolectorNode **) malloc (sizeof (BtorNode *) * num_elements);
for (i = 0; i < num_elements; i++)
indices[i] = boolector_int (btor, i, sort_index);
array = boolector_array (btor, sort_array, "array");
/* we write arbitrary search value into array at an arbitrary index */
val = boolector_var (btor, sort_elem, "search_val");
index = boolector_var (btor, sort_index, "search_index");
temp = boolector_write (btor, array, index, val);
boolector_release (btor, array);
array = temp;
/* we assume that array is sorted */
sorted = boolector_const (btor, "1");
for (i = 0; i < num_elements - 1; i++)
{
read1 = boolector_read (btor, array, indices[i]);
read2 = boolector_read (btor, array, indices[i + 1]);
ulte = boolector_ulte (btor, read1, read2);
temp = boolector_and (btor, sorted, ulte);
boolector_release (btor, sorted);
sorted = temp;
boolector_release (btor, read1);
boolector_release (btor, read2);
boolector_release (btor, ulte);
}
/* binary search algorithm */
low = boolector_int (btor, 0, sort_index);
high = boolector_int (btor, num_elements - 1, sort_index);
two = boolector_int (btor, 2, sort_index);
one = boolector_int (btor, 1, sort_index);
found = boolector_const (btor, "0");
for (i = 0; i < num_iterations; i++)
{
/* compute mid */
sub = boolector_sub (btor, high, low);
udiv = boolector_udiv (btor, sub, two);
mid = boolector_add (btor, low, udiv);
/* read mid element */
read1 = boolector_read (btor, array, mid);
/* compare element with search val */
eq = boolector_eq (btor, val, read1);
ult = boolector_ult (btor, val, read1);
ugt = boolector_ugt (btor, val, read1);
/* found element ? */
temp = boolector_or (btor, found, eq);
boolector_release (btor, found);
found = temp;
/* adapt high (if necessary) */
dec = boolector_sub (btor, mid, one);
temp = boolector_cond (btor, ult, dec, high);
boolector_release (btor, high);
high = temp;
/* adapt low (if necessary) */
inc = boolector_add (btor, mid, one);
temp = boolector_cond (btor, ugt, inc, low);
boolector_release (btor, low);
low = temp;
boolector_release (btor, sub);
boolector_release (btor, udiv);
boolector_release (btor, mid);
boolector_release (btor, eq);
boolector_release (btor, ult);
boolector_release (btor, ugt);
boolector_release (btor, read1);
boolector_release (btor, inc);
boolector_release (btor, dec);
}
/* the array is sorted implies that we have found the element */
formula = boolector_implies (btor, sorted, found);
/* we negate the formula and show that it is unsatisfiable */
temp = boolector_not (btor, formula);
boolector_release (btor, formula);
formula = temp;
boolector_dump_btor_node (btor, stdout, formula);
/* clean up */
for (i = 0; i < num_elements; i++) boolector_release (btor, indices[i]);
boolector_release (btor, formula);
boolector_release (btor, index);
boolector_release (btor, val);
boolector_release (btor, found);
boolector_release (btor, array);
boolector_release (btor, sorted);
boolector_release (btor, low);
boolector_release (btor, high);
boolector_release (btor, two);
boolector_release (btor, one);
boolector_release_sort (btor, sort_index);
boolector_release_sort (btor, sort_elem);
boolector_release_sort (btor, sort_array);
boolector_delete (btor);
free (indices);
return 0;
}
|