/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
- /*
- * This file is part of the Yices SMT Solver.
- * Copyright (C) 2017 SRI International.
- *
- * Yices is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Yices is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Yices. If not, see <http://www.gnu.org/licenses/>.
- */
- /*
- * Test of the arrays with push/pop
- */
- #include <inttypes.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include "utils/backtrack_arrays.h"
- #include "utils/memalloc.h"
- #ifdef MINGW
- static inline long int random(void) {
- return rand();
- }
- #endif
- /*
- * Test arrays:
- * - each array is randomly constructed
- * - size[i] = its length
- * - array[i] = the array proper
- * each element in array i is a pair (index, value)
- */
- typedef struct test_elem_s {
- int32_t index;
- uint8_t value;
- } test_elem_t;
- #define NUM_ARRAYS 50
- static uint32_t size[NUM_ARRAYS];
- static test_elem_t *array[NUM_ARRAYS];
- /*
- * Initialize n arrays with random data
- * - each array contains 20 pairs (index, value)
- * - indices are in the range [0 ... m-1]
- * - values are in the range [1 ... 255]
- */
- static void init_arrays(uint32_t n, uint32_t m) {
- test_elem_t *a;
- uint32_t i, j;
- assert(n <= NUM_ARRAYS && m > 0);
- for (i=0; i<n; i++) {
- a = (test_elem_t *) safe_malloc(20 * sizeof(test_elem_t));
- size[i] = 20;
- for (j=0; j<20; j++) {
- a[j].index = ((int32_t) random()) % m;
- a[j].value = 1 + ((uint8_t) (random() & 0xFF));
- }
- array[i] = a;
- }
- }
- /*
- * Delete array[0] ... array[n-1]
- */
- static void delete_arrays(uint32_t n) {
- uint32_t i;
- for (i=0; i<n; i++) {
- safe_free(array[i]);
- }
- }
- /*
- * Get the largest index in array[0] ... array[n]
- */
- static int32_t max_index(uint32_t n) {
- uint32_t i, j, p;
- test_elem_t *a;
- int32_t max;
- max = -1;
- for (i=0; i <= n; i++) {
- p = size[i];
- a = array[i];
- for (j=0; j<p; j++) {
- if (a[j].index > max) {
- max = a[j].index;
- }
- }
- }
- return max;
- }
- /*
- * Build an expanded array from the data in array[0] ... array[n-1]
- * - m = size of the expanded array
- */
- static uint8_t *expand_arrays(uint32_t n, uint32_t m) {
- uint8_t *tmp;
- test_elem_t *a;
- uint32_t i, j, p;
- int32_t idx;
- tmp = (uint8_t *) safe_malloc(m * sizeof(uint8_t));
- for (i=0; i<m; i++) {
- tmp[i] = 0; // default value
- }
- for (i=0; i <= n; i++) {
- p = size[i];
- a = array[i];
- for (j=0; j<p; j++) {
- idx = a[j].index;
- if (idx < m) {
- tmp[idx] = a[j].value;
- }
- }
- }
- return tmp;
- }
- /*
- * Check whether backtrackable array b matches expanded array a
- * - m = size of a
- */
- static bool equal_array(uint8_t *a, uint32_t m, uint8_array_t *b) {
- uint32_t i;
- for (i=0; i<m; i++) {
- if (a[i] != au8_read(b, i)) {
- return false;
- }
- }
- return true;
- }
- /*
- * Store array a into b
- * - n = number of records in a
- */
- static void write_array(test_elem_t *a, uint32_t n, uint8_array_t *b) {
- uint32_t i;
- for (i=0; i<n; i++) {
- au8_write(b, a[i].index, a[i].value);
- }
- }
- /*
- * Print array a:
- * - n = number of record in a
- */
- static void print_test_array(test_elem_t *a, uint32_t n) {
- uint32_t i;
- for (i=0; i<n; i++) {
- printf(" a[%"PRId32"] := %"PRIu8"\n", a[i].index, a[i].value);
- }
- }
- /*
- * Print content of array b
- */
- static void print_backtrackable_array(uint8_array_t *b) {
- uint32_t i, top;
- top = b->top;
- for (i=0; i<top; i++) {
- if (b->map[i] > 0) {
- printf(" b[%"PRId32"] = %"PRIu8"\n", i, b->map[i]);
- }
- }
- }
- /*
- * Print expanded array a of m elements
- */
- static void print_expanded_array(uint8_t *a, uint32_t m) {
- uint32_t i;
- for (i=0; i<m; i++) {
- if (a[i] > 0) {
- printf(" c[%"PRId32"] = %"PRIu8"\n", i, a[i]);
- }
- }
- }
- /*
- * Full test:
- * - successively store array[0 ... n-1] into b
- * - use indices in the range 0 ... m-1
- * - then check whether pop works
- */
- static void test_arrays(uint8_array_t *b, uint32_t n, uint32_t m) {
- uint32_t i;
- int32_t max;
- uint8_t *check;
- assert(n <= NUM_ARRAYS);
- reset_uint8_array(b);
- printf("Initial content\n");
- print_backtrackable_array(b);
- printf("\n\n");
- init_arrays(n, m);
- // phase 1: add arrays
- for (i=0; i<n; i++) {
- printf("Level %"PRIu32"\n", i);
- print_test_array(array[i], size[i]);
- printf("\n");
- write_array(array[i], size[i], b);
- printf("New content:\n");
- print_backtrackable_array(b);
- printf("\n");
- // double check
- max = max_index(i);
- assert(max >= 0);
- check = expand_arrays(i, max + 1);
- printf("Check:\n");
- print_expanded_array(check, max + 1);
- printf("\n");
- if (equal_array(check, max+1, b)) {
- printf("OK\n\n");
- } else {
- printf("BUG\n\n");
- abort();
- }
- safe_free(check);
- uint8_array_push(b);
- }
- // phase 2: backtrack to level n/2
- while (i > n/2) {
- i--;
- uint8_array_pop(b);
- printf("Backtracking to level %"PRIu32"\n", i);
- print_backtrackable_array(b);
- printf("\n");
- // double check
- max = max_index(i);
- assert(max >= 0);
- check = expand_arrays(i, max + 1);
- printf("Check:\n");
- print_expanded_array(check, max + 1);
- printf("\n");
- if (equal_array(check, max+1, b)) {
- printf("OK\n\n");
- } else {
- printf("BUG\n\n");
- abort();
- }
- safe_free(check);
- }
- // phase 3: rebuild all arrays until level n
- while (i < n) {
- printf("Level %"PRIu32"\n", i);
- print_test_array(array[i], size[i]);
- printf("\n");
- write_array(array[i], size[i], b);
- printf("New content:\n");
- print_backtrackable_array(b);
- printf("\n");
- // double check
- max = max_index(i);
- assert(max >= 0);
- check = expand_arrays(i, max + 1);
- printf("Check:\n");
- print_expanded_array(check, max + 1);
- printf("\n");
- if (equal_array(check, max+1, b)) {
- printf("OK\n\n");
- } else {
- printf("BUG\n\n");
- abort();
- }
- safe_free(check);
- uint8_array_push(b);
- i ++;
- }
- // phase 4: backtrack all the way
- while (i > 0) {
- i--;
- uint8_array_pop(b);
- printf("Backtracking to level %"PRIu32"\n", i);
- print_backtrackable_array(b);
- printf("\n");
- // double check
- max = max_index(i);
- assert(max >= 0);
- check = expand_arrays(i, max + 1);
- printf("Check:\n");
- print_expanded_array(check, max + 1);
- printf("\n");
- if (equal_array(check, max+1, b)) {
- printf("OK\n\n");
- } else {
- printf("BUG\n\n");
- abort();
- }
- safe_free(check);
- }
- delete_arrays(n);
- }
- /*
- * Global backtrackable array
- */
- static uint8_array_t tst;
- int main(void) {
- init_uint8_array(&tst, 0, 4);
- test_arrays(&tst, 50, 30);
- test_arrays(&tst, 50, 1000);
- delete_uint8_array(&tst);
- return 0;
- }