/* * Test * - create values of type tau * - n: max number of fresh values to try (assumed positive) */ static void test_type(type_t tau, uint32_t n) { value_t v; uint32_t i; printf("==== Test fresh values of type "); print_type(stdout, &types, tau); printf(" ====\n"); printf("cardinality: %"PRIu32"\n\n", type_card(&types, tau)); i = 0; do { v = make_fresh_value(&maker, tau); if (v == null_value) break; i ++; printf("val[%"PRIu32"] = ", i); vtbl_print_object(stdout, &vtbl, v); printf("\n"); if (vtbl_queue_is_nonempty(&vtbl)) { vtbl_print_queued_functions(stdout, &vtbl, true); printf("\n"); } } while (i <n); printf("\n---> got %"PRIu32" fresh values\n\n", i); }
// same thing for a single type tau static tuple_counter_t *new_type_counter(type_table_t *types, type_t tau) { tuple_counter_t *tmp; tmp = (tuple_counter_t *) safe_malloc(sizeof(tuple_counter_t) + sizeof(type_t)); tmp->arity = 1; tmp->card = type_card(types, tau); tmp->count = 0; tmp->tau[0] = tau; return tmp; }
/* * TEST4: unary functions */ static void test_unary_functions(uint32_t threshold) { uint32_t i, j; type_t tau; printf("***************************\n" "* UNARY FUNCTION TYPES *\n" "***************************\n" "\n"); for (i=0; i<NUM_BASE_TYPES; i++) { for (j=0; j<NUM_BASE_TYPES; j++) { tau = fun_type1(base[i], base[j]); if (type_card(&types, tau) < threshold) { test_enum_type(tau); } } } }
/* * TEST2: pairs of base types * - skip any pair type of cardinaly >= threshold */ static void test_pairs(uint32_t threshold) { uint32_t i, j; type_t tau; printf("*****************\n" "* PAIR TYPES *\n" "*****************\n" "\n"); for (i=0; i<NUM_BASE_TYPES; i++) { for (j=0; j<NUM_BASE_TYPES; j++) { tau = pair_type(base[i], base[j]); if (type_card(&types, tau) < threshold) { test_enum_type(tau); } } } }
/* * TEST3: triples */ static void test_triples(uint32_t threshold) { uint32_t i, j, k; type_t tau; printf("*******************\n" "* TRIPLE TYPES *\n" "*******************\n" "\n"); for (i=0; i<NUM_BASE_TYPES; i++) { for (j=0; j<NUM_BASE_TYPES; j++) { for (k=0; k<NUM_BASE_TYPES; k++) { tau = triple_type(base[i], base[j], base[k]); if (type_card(&types, tau) < threshold) { test_enum_type(tau); } } } } }
static void test_enum_type(type_t tau) { uint32_t i, n; value_t x; assert(is_finite_type(&types, tau) && type_card_is_exact(&types, tau)); n = type_card(&types, tau); printf("==== Enumerating elements of type "); print_type(stdout, &types, tau); printf(" ====\n"); printf("cardinality: %"PRIu32"\n", n); for (i=0; i<n; i++) { x = vtbl_gen_object(&vtbl, tau, i); printf("elem[%"PRIu32"] = ", i); vtbl_print_object(stdout, &vtbl, x); printf("\n"); if (vtbl_queue_is_nonempty(&vtbl)) { vtbl_print_queued_functions(stdout, &vtbl, true); printf("\n"); } } printf("\n"); }
/* * Force maps map[0 ... n-1] to be all distinct by updating them. * - store = particle store to create fresh indices * - f = type descriptor for all the maps in the array * - n must be positive * * Technique used: * - create fresh indices i_1,..,i_k in the domain of f * - create c values a_1,..., a_c in the range of f * such that (c ^ k) >= n. * Update map[t] by adding [i_1 -> a_t1, ..., i_k -> a_tk] * in such a way that (t1, ...., tk) differ from (u1, ..., uk) when u/=t. * * Return false if that's not possible (i.e., the number of functions * of the type f is finite and smaller than n). */ bool force_maps_to_differ(pstore_t *store, function_type_t *f, uint32_t n, map_t **map) { type_table_t *types; particle_t *idx; particle_t *a; uint32_t *tuple; type_t tau; uint32_t i, j, k, c; types = store->types; tau = f->range; if (is_unit_type(types, tau)) { return false; } if (is_finite_type(types, tau)) { c = type_card(types, tau); k = ceil_log(c, n); } else { c = n; k = 1; } assert(k>0 && c>0 && upower32(c, k) >= n); // tuple + index array are of size k // a is of size c tuple = (uint32_t *) safe_malloc(k * sizeof(uint32_t)); idx = (particle_t *) safe_malloc(k * sizeof(particle_t)); a = (particle_t *) safe_malloc(c * sizeof(particle_t)); // initialize the idx array with fresh values if (f->ndom == 1) { for (i=0; i<k; i++) { idx[i] = get_new_particle(store, f->domain[0]); if (idx[i] == null_particle) goto failed; } } else { for (i=0; i<k; i++) { idx[i] = get_new_tuple(store, f->ndom, f->domain); if (idx[i] == null_particle) goto failed; } } // fill-in a with c distinct values of type tau for (i=0; i<c; i++) { a[i] = get_distinct_particle(store, tau, i, a); assert(a[i] != null_particle); } // initialize tuple = (0,...,0) for (i=0; i<k; i++) { tuple[i] = 0; } // update then normalize the maps i = 0; for (;;) { assert(i < n); for (j=0; j<k; j++) { assert(tuple[j] < c); add_elem_to_map(map[i], idx[j], a[tuple[j]]); } normalize_map(map[i]); i ++; if (i == n) break; tuple_successor(tuple, k, c); } safe_free(a); safe_free(idx); safe_free(tuple); return true; failed: safe_free(a); safe_free(idx); safe_free(tuple); return false; }