/tests/unit/test_uint8_arrays.c

https://github.com/SRI-CSL/yices2 · C · 365 lines · 219 code · 68 blank · 78 comment · 32 complexity · 6c41dde34f4686466f34a6280f8005ba MD5 · raw file

  1. /*
  2. * This file is part of the Yices SMT Solver.
  3. * Copyright (C) 2017 SRI International.
  4. *
  5. * Yices is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Yices is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Yices. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * Test of the arrays with push/pop
  20. */
  21. #include <inttypes.h>
  22. #include <stdio.h>
  23. #include <stdbool.h>
  24. #include "utils/backtrack_arrays.h"
  25. #include "utils/memalloc.h"
  26. #ifdef MINGW
  27. static inline long int random(void) {
  28. return rand();
  29. }
  30. #endif
  31. /*
  32. * Test arrays:
  33. * - each array is randomly constructed
  34. * - size[i] = its length
  35. * - array[i] = the array proper
  36. * each element in array i is a pair (index, value)
  37. */
  38. typedef struct test_elem_s {
  39. int32_t index;
  40. uint8_t value;
  41. } test_elem_t;
  42. #define NUM_ARRAYS 50
  43. static uint32_t size[NUM_ARRAYS];
  44. static test_elem_t *array[NUM_ARRAYS];
  45. /*
  46. * Initialize n arrays with random data
  47. * - each array contains 20 pairs (index, value)
  48. * - indices are in the range [0 ... m-1]
  49. * - values are in the range [1 ... 255]
  50. */
  51. static void init_arrays(uint32_t n, uint32_t m) {
  52. test_elem_t *a;
  53. uint32_t i, j;
  54. assert(n <= NUM_ARRAYS && m > 0);
  55. for (i=0; i<n; i++) {
  56. a = (test_elem_t *) safe_malloc(20 * sizeof(test_elem_t));
  57. size[i] = 20;
  58. for (j=0; j<20; j++) {
  59. a[j].index = ((int32_t) random()) % m;
  60. a[j].value = 1 + ((uint8_t) (random() & 0xFF));
  61. }
  62. array[i] = a;
  63. }
  64. }
  65. /*
  66. * Delete array[0] ... array[n-1]
  67. */
  68. static void delete_arrays(uint32_t n) {
  69. uint32_t i;
  70. for (i=0; i<n; i++) {
  71. safe_free(array[i]);
  72. }
  73. }
  74. /*
  75. * Get the largest index in array[0] ... array[n]
  76. */
  77. static int32_t max_index(uint32_t n) {
  78. uint32_t i, j, p;
  79. test_elem_t *a;
  80. int32_t max;
  81. max = -1;
  82. for (i=0; i <= n; i++) {
  83. p = size[i];
  84. a = array[i];
  85. for (j=0; j<p; j++) {
  86. if (a[j].index > max) {
  87. max = a[j].index;
  88. }
  89. }
  90. }
  91. return max;
  92. }
  93. /*
  94. * Build an expanded array from the data in array[0] ... array[n-1]
  95. * - m = size of the expanded array
  96. */
  97. static uint8_t *expand_arrays(uint32_t n, uint32_t m) {
  98. uint8_t *tmp;
  99. test_elem_t *a;
  100. uint32_t i, j, p;
  101. int32_t idx;
  102. tmp = (uint8_t *) safe_malloc(m * sizeof(uint8_t));
  103. for (i=0; i<m; i++) {
  104. tmp[i] = 0; // default value
  105. }
  106. for (i=0; i <= n; i++) {
  107. p = size[i];
  108. a = array[i];
  109. for (j=0; j<p; j++) {
  110. idx = a[j].index;
  111. if (idx < m) {
  112. tmp[idx] = a[j].value;
  113. }
  114. }
  115. }
  116. return tmp;
  117. }
  118. /*
  119. * Check whether backtrackable array b matches expanded array a
  120. * - m = size of a
  121. */
  122. static bool equal_array(uint8_t *a, uint32_t m, uint8_array_t *b) {
  123. uint32_t i;
  124. for (i=0; i<m; i++) {
  125. if (a[i] != au8_read(b, i)) {
  126. return false;
  127. }
  128. }
  129. return true;
  130. }
  131. /*
  132. * Store array a into b
  133. * - n = number of records in a
  134. */
  135. static void write_array(test_elem_t *a, uint32_t n, uint8_array_t *b) {
  136. uint32_t i;
  137. for (i=0; i<n; i++) {
  138. au8_write(b, a[i].index, a[i].value);
  139. }
  140. }
  141. /*
  142. * Print array a:
  143. * - n = number of record in a
  144. */
  145. static void print_test_array(test_elem_t *a, uint32_t n) {
  146. uint32_t i;
  147. for (i=0; i<n; i++) {
  148. printf(" a[%"PRId32"] := %"PRIu8"\n", a[i].index, a[i].value);
  149. }
  150. }
  151. /*
  152. * Print content of array b
  153. */
  154. static void print_backtrackable_array(uint8_array_t *b) {
  155. uint32_t i, top;
  156. top = b->top;
  157. for (i=0; i<top; i++) {
  158. if (b->map[i] > 0) {
  159. printf(" b[%"PRId32"] = %"PRIu8"\n", i, b->map[i]);
  160. }
  161. }
  162. }
  163. /*
  164. * Print expanded array a of m elements
  165. */
  166. static void print_expanded_array(uint8_t *a, uint32_t m) {
  167. uint32_t i;
  168. for (i=0; i<m; i++) {
  169. if (a[i] > 0) {
  170. printf(" c[%"PRId32"] = %"PRIu8"\n", i, a[i]);
  171. }
  172. }
  173. }
  174. /*
  175. * Full test:
  176. * - successively store array[0 ... n-1] into b
  177. * - use indices in the range 0 ... m-1
  178. * - then check whether pop works
  179. */
  180. static void test_arrays(uint8_array_t *b, uint32_t n, uint32_t m) {
  181. uint32_t i;
  182. int32_t max;
  183. uint8_t *check;
  184. assert(n <= NUM_ARRAYS);
  185. reset_uint8_array(b);
  186. printf("Initial content\n");
  187. print_backtrackable_array(b);
  188. printf("\n\n");
  189. init_arrays(n, m);
  190. // phase 1: add arrays
  191. for (i=0; i<n; i++) {
  192. printf("Level %"PRIu32"\n", i);
  193. print_test_array(array[i], size[i]);
  194. printf("\n");
  195. write_array(array[i], size[i], b);
  196. printf("New content:\n");
  197. print_backtrackable_array(b);
  198. printf("\n");
  199. // double check
  200. max = max_index(i);
  201. assert(max >= 0);
  202. check = expand_arrays(i, max + 1);
  203. printf("Check:\n");
  204. print_expanded_array(check, max + 1);
  205. printf("\n");
  206. if (equal_array(check, max+1, b)) {
  207. printf("OK\n\n");
  208. } else {
  209. printf("BUG\n\n");
  210. abort();
  211. }
  212. safe_free(check);
  213. uint8_array_push(b);
  214. }
  215. // phase 2: backtrack to level n/2
  216. while (i > n/2) {
  217. i--;
  218. uint8_array_pop(b);
  219. printf("Backtracking to level %"PRIu32"\n", i);
  220. print_backtrackable_array(b);
  221. printf("\n");
  222. // double check
  223. max = max_index(i);
  224. assert(max >= 0);
  225. check = expand_arrays(i, max + 1);
  226. printf("Check:\n");
  227. print_expanded_array(check, max + 1);
  228. printf("\n");
  229. if (equal_array(check, max+1, b)) {
  230. printf("OK\n\n");
  231. } else {
  232. printf("BUG\n\n");
  233. abort();
  234. }
  235. safe_free(check);
  236. }
  237. // phase 3: rebuild all arrays until level n
  238. while (i < n) {
  239. printf("Level %"PRIu32"\n", i);
  240. print_test_array(array[i], size[i]);
  241. printf("\n");
  242. write_array(array[i], size[i], b);
  243. printf("New content:\n");
  244. print_backtrackable_array(b);
  245. printf("\n");
  246. // double check
  247. max = max_index(i);
  248. assert(max >= 0);
  249. check = expand_arrays(i, max + 1);
  250. printf("Check:\n");
  251. print_expanded_array(check, max + 1);
  252. printf("\n");
  253. if (equal_array(check, max+1, b)) {
  254. printf("OK\n\n");
  255. } else {
  256. printf("BUG\n\n");
  257. abort();
  258. }
  259. safe_free(check);
  260. uint8_array_push(b);
  261. i ++;
  262. }
  263. // phase 4: backtrack all the way
  264. while (i > 0) {
  265. i--;
  266. uint8_array_pop(b);
  267. printf("Backtracking to level %"PRIu32"\n", i);
  268. print_backtrackable_array(b);
  269. printf("\n");
  270. // double check
  271. max = max_index(i);
  272. assert(max >= 0);
  273. check = expand_arrays(i, max + 1);
  274. printf("Check:\n");
  275. print_expanded_array(check, max + 1);
  276. printf("\n");
  277. if (equal_array(check, max+1, b)) {
  278. printf("OK\n\n");
  279. } else {
  280. printf("BUG\n\n");
  281. abort();
  282. }
  283. safe_free(check);
  284. }
  285. delete_arrays(n);
  286. }
  287. /*
  288. * Global backtrackable array
  289. */
  290. static uint8_array_t tst;
  291. int main(void) {
  292. init_uint8_array(&tst, 0, 4);
  293. test_arrays(&tst, 50, 30);
  294. test_arrays(&tst, 50, 1000);
  295. delete_uint8_array(&tst);
  296. return 0;
  297. }